]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
LoongArch: KVM: Check interrupt route from physical CPU
authorBibo Mao <maobibo@loongson.cn>
Fri, 27 Jun 2025 10:27:44 +0000 (18:27 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Fri, 27 Jun 2025 10:27:44 +0000 (18:27 +0800)
With EIOINTC interrupt controller, physical CPU ID is set for irq route.
However the function kvm_get_vcpu() is used to get destination vCPU when
delivering irq. With API kvm_get_vcpu(), the logical CPU ID is used.

With API kvm_get_vcpu_by_cpuid(), vCPU ID can be searched from physical
CPU ID.

Cc: stable@vger.kernel.org
Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions")
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kvm/intc/eiointc.c

index 8d3f48e2a7f07d188790d33d99914ae5a8c05a10..644fb7785c0752f2741f0240b0a99b42897a4952 100644 (file)
@@ -9,7 +9,8 @@
 
 static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 {
-       int ipnum, cpu, irq_index, irq_mask, irq;
+       int ipnum, cpu, cpuid, irq_index, irq_mask, irq;
+       struct kvm_vcpu *vcpu;
 
        for (irq = 0; irq < EIOINTC_IRQS; irq++) {
                ipnum = s->ipmap.reg_u8[irq / 32];
@@ -20,7 +21,12 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
                irq_index = irq / 32;
                irq_mask = BIT(irq & 0x1f);
 
-               cpu = s->coremap.reg_u8[irq];
+               cpuid = s->coremap.reg_u8[irq];
+               vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
+               if (!vcpu)
+                       continue;
+
+               cpu = vcpu->vcpu_id;
                if (!!(s->coreisr.reg_u32[cpu][irq_index] & irq_mask))
                        set_bit(irq, s->sw_coreisr[cpu][ipnum]);
                else
@@ -68,17 +74,23 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s,
                                        int irq, u64 val, u32 len, bool notify)
 {
-       int i, cpu;
+       int i, cpu, cpuid;
+       struct kvm_vcpu *vcpu;
 
        for (i = 0; i < len; i++) {
-               cpu = val & 0xff;
+               cpuid = val & 0xff;
                val = val >> 8;
 
                if (!(s->status & BIT(EIOINTC_ENABLE_CPU_ENCODE))) {
-                       cpu = ffs(cpu) - 1;
-                       cpu = (cpu >= 4) ? 0 : cpu;
+                       cpuid = ffs(cpuid) - 1;
+                       cpuid = (cpuid >= 4) ? 0 : cpuid;
                }
 
+               vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
+               if (!vcpu)
+                       continue;
+
+               cpu = vcpu->vcpu_id;
                if (s->sw_coremap[irq + i] == cpu)
                        continue;