Re: [PATCH] RISC-V: KVM: Avoid one-word masks for SBI v0.1 all-harts

Anup Patel <[email protected]>
Newsgroups org.infradead.lists.kvm-riscv,org.infradead.lists.linux-riscv,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <CAAhSdy1Mkfekf5ViagmynJMVii10kFZO=XbgNe14pM_f7Yi78A@mail.gmail.com>
On Sat, Jul 18, 2026 at 10:09 AM Pengpeng Hou <[email protected]> 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 <[email protected]>

LGTM.

Reviewed-by: Anup Patel <[email protected]>

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
>

-- 
kvm-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kvm-riscv
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.