]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RISC-V: KVM: Read HGEIP CSR on the correct cpu
authorFangyu Yu <fangyu.yu@linux.alibaba.com>
Thu, 16 Oct 2025 01:26:59 +0000 (09:26 +0800)
committerAnup Patel <anup@brainfault.org>
Fri, 17 Oct 2025 07:40:01 +0000 (13:10 +0530)
When executing kvm_riscv_vcpu_aia_has_interrupts, the vCPU may have
migrated and the IMSIC VS-file have not been updated yet, currently
the HGEIP CSR should be read from the imsic->vsfile_cpu ( the pCPU
before migration ) via on_each_cpu_mask, but this will trigger an
IPI call and repeated IPI within a period of time is expensive in
a many-core systems.

Just let the vCPU execute and update the correct IMSIC VS-file via
kvm_riscv_vcpu_aia_imsic_update may be a simple solution.

Fixes: 4cec89db80ba ("RISC-V: KVM: Move HGEI[E|P] CSR access to IMSIC virtualization")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20251016012659.82998-1-fangyu.yu@linux.alibaba.com
Signed-off-by: Anup Patel <anup@brainfault.org>
arch/riscv/kvm/aia_imsic.c

index fda0346f0ea1fb1fb460f2fd04aa16dfd2b83477..11422cb95a64403cfa098c8e74d958a4d01df3f5 100644 (file)
@@ -689,8 +689,20 @@ bool kvm_riscv_vcpu_aia_imsic_has_interrupt(struct kvm_vcpu *vcpu)
         */
 
        read_lock_irqsave(&imsic->vsfile_lock, flags);
-       if (imsic->vsfile_cpu > -1)
-               ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
+       if (imsic->vsfile_cpu > -1) {
+               /*
+                * This function is typically called from kvm_vcpu_block() via
+                * kvm_arch_vcpu_runnable() upon WFI trap. The kvm_vcpu_block()
+                * can be preempted and the blocking VCPU might resume on a
+                * different CPU. This means it is possible that current CPU
+                * does not match the imsic->vsfile_cpu hence this function
+                * must check imsic->vsfile_cpu before accessing HGEIP CSR.
+                */
+               if (imsic->vsfile_cpu != vcpu->cpu)
+                       ret = true;
+               else
+                       ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei));
+       }
        read_unlock_irqrestore(&imsic->vsfile_lock, flags);
 
        return ret;