[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