]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: PPC: Book3S HV: XICS: Fix mapping of passthrough interrupts
authorCédric Le Goater <clg@kaod.org>
Thu, 1 Jul 2021 13:27:48 +0000 (15:27 +0200)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 10 Aug 2021 13:15:01 +0000 (23:15 +1000)
PCI MSIs now live in an MSI domain but the underlying calls, which
will EOI the interrupt in real mode, need an HW IRQ number mapped in
the XICS IRQ domain. Grab it there.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210701132750.1475580-31-clg@kaod.org
arch/powerpc/kvm/book3s_hv.c

index 05b3a3548c188e4919c49f13b2713cd42f8d689c..f28f99805c4cb572613dc8eb9d96c24b8af510a8 100644 (file)
@@ -5328,6 +5328,7 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi)
        struct kvmppc_passthru_irqmap *pimap;
        struct irq_chip *chip;
        int i, rc = 0;
+       struct irq_data *host_data;
 
        if (!kvm_irq_bypass)
                return 1;
@@ -5392,7 +5393,14 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi)
         * the KVM real mode handler.
         */
        smp_wmb();
-       irq_map->r_hwirq = desc->irq_data.hwirq;
+
+       /*
+        * The 'host_irq' number is mapped in the PCI-MSI domain but
+        * the underlying calls, which will EOI the interrupt in real
+        * mode, need an HW IRQ number mapped in the XICS IRQ domain.
+        */
+       host_data = irq_domain_get_irq_data(irq_get_default_host(), host_irq);
+       irq_map->r_hwirq = (unsigned int)irqd_to_hwirq(host_data);
 
        if (i == pimap->n_mapped)
                pimap->n_mapped++;
@@ -5400,7 +5408,7 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi)
        if (xics_on_xive())
                rc = kvmppc_xive_set_mapped(kvm, guest_gsi, host_irq);
        else
-               kvmppc_xics_set_mapped(kvm, guest_gsi, desc->irq_data.hwirq);
+               kvmppc_xics_set_mapped(kvm, guest_gsi, irq_map->r_hwirq);
        if (rc)
                irq_map->r_hwirq = 0;