Commit 45515c64 authored by Bibo Mao's avatar Bibo Mao Committed by Huacai Chen
Browse files

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: 3956a52b ("LoongArch: KVM: Add EIOINTC read and write functions")
Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent c34bbc2c
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -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;