[PATCH] RISC-V: KVM: Avoid one-word masks for SBI v0.1 all-harts
Anup Patel
anup at brainfault.org
Sat Aug 8 01:22:27 PDT 2026
On Sat, Jul 18, 2026 at 10:09 AM Pengpeng Hou <pengpeng at iscas.ac.cn> wrote:
>
> KVM already treats a NULL hart-mask pointer in SBI v0.1 calls as all
> harts, matching OpenSBI's legacy handling. The current handler builds that
> target set as (1UL << online_vcpus) - 1 before iterating the mask.
>
> That expression shifts by the type width once the VM has BITS_PER_LONG
> online vCPUs, and a single word cannot represent larger VMs. A count-based
> mask also selects the wrong IDs when vCPU IDs are sparse.
>
> Handle SEND_IPI with a NULL hart-mask by iterating all online vCPUs
> directly. For remote fence calls, use the existing hbase == -1UL
> convention so the common fence request helper targets the whole VM
> without consulting hmask.
>
> Non-NULL guest hart masks keep the existing v0.1 behavior.
>
> Fixes: a046c2d8578c ("RISC-V: KVM: Reorganize SBI code by moving SBI v0.1 to its own file")
> Signed-off-by: Pengpeng Hou <pengpeng at iscas.ac.cn>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Queued this patch for Linux-7.3
Thanks,
Anup
> ---
> arch/riscv/kvm/vcpu_sbi_v01.c | 52 ++++++++++++++++++++---------------
> 1 file changed, 30 insertions(+), 22 deletions(-)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c
> index c9c323d4577a9..de544ea3f28dc 100644
> --- a/arch/riscv/kvm/vcpu_sbi_v01.c
> +++ b/arch/riscv/kvm/vcpu_sbi_v01.c
> @@ -16,8 +16,9 @@
> static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> struct kvm_vcpu_sbi_return *retdata)
> {
> - ulong hmask;
> - int i, ret = 0;
> + ulong hbase = 0, hmask;
> + unsigned long i;
> + int ret = 0;
> u64 next_cycle;
> struct kvm_vcpu *rvcpu;
> struct kvm *kvm = vcpu->kvm;
> @@ -46,20 +47,25 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> ret = kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_SOFT);
> break;
> case SBI_EXT_0_1_SEND_IPI:
> - if (cp->a0)
> + if (cp->a0) {
> hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, utrap);
> - else
> - hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1;
> - if (utrap->scause)
> - break;
> -
> - for_each_set_bit(i, &hmask, BITS_PER_LONG) {
> - rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i);
> - if (!rvcpu)
> - continue;
> - ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT);
> - if (ret < 0)
> + if (utrap->scause)
> break;
> +
> + for_each_set_bit(i, &hmask, BITS_PER_LONG) {
> + rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i);
> + if (!rvcpu)
> + continue;
> + ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT);
> + if (ret < 0)
> + break;
> + }
> + } else {
> + kvm_for_each_vcpu(i, rvcpu, kvm) {
> + ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT);
> + if (ret < 0)
> + break;
> + }
> }
> break;
> case SBI_EXT_0_1_SHUTDOWN:
> @@ -70,29 +76,31 @@ static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
> case SBI_EXT_0_1_REMOTE_FENCE_I:
> case SBI_EXT_0_1_REMOTE_SFENCE_VMA:
> case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID:
> - if (cp->a0)
> + if (cp->a0) {
> hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, utrap);
> - else
> - hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1;
> + } else {
> + hbase = -1UL;
> + hmask = 0;
> + }
> if (utrap->scause)
> break;
>
> if (cp->a7 == SBI_EXT_0_1_REMOTE_FENCE_I)
> - kvm_riscv_fence_i(vcpu->kvm, 0, hmask);
> + kvm_riscv_fence_i(vcpu->kvm, hbase, hmask);
> else if (cp->a7 == SBI_EXT_0_1_REMOTE_SFENCE_VMA) {
> vmid = READ_ONCE(vcpu->kvm->arch.vmid.vmid);
> if (cp->a1 == 0 && cp->a2 == 0)
> - kvm_riscv_hfence_vvma_all(vcpu->kvm, 0, hmask, vmid);
> + kvm_riscv_hfence_vvma_all(vcpu->kvm, hbase, hmask, vmid);
> else
> - kvm_riscv_hfence_vvma_gva(vcpu->kvm, 0, hmask, cp->a1,
> + kvm_riscv_hfence_vvma_gva(vcpu->kvm, hbase, hmask, cp->a1,
> cp->a2, PAGE_SHIFT, vmid);
> } else {
> vmid = READ_ONCE(vcpu->kvm->arch.vmid.vmid);
> if (cp->a1 == 0 && cp->a2 == 0)
> - kvm_riscv_hfence_vvma_asid_all(vcpu->kvm, 0, hmask,
> + kvm_riscv_hfence_vvma_asid_all(vcpu->kvm, hbase, hmask,
> cp->a3, vmid);
> else
> - kvm_riscv_hfence_vvma_asid_gva(vcpu->kvm, 0, hmask,
> + kvm_riscv_hfence_vvma_asid_gva(vcpu->kvm, hbase, hmask,
> cp->a1, cp->a2, PAGE_SHIFT,
> cp->a3, vmid);
> }
> --
> 2.43.0
>
More information about the kvm-riscv
mailing list