LoongArch: KVM: Check interrupt route from physical CPU

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: 3956a52bc0 ("LoongArch: KVM: Add EIOINTC read and write functions")
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
Bibo Mao 2025-06-27 18:27:44 +08:00 committed by Huacai Chen
parent c34bbc2c99
commit 45515c643d

View 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;