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