Commit a101950f authored by Cédric Le Goater's avatar Cédric Le Goater Committed by Michael Ellerman

powerpc/xive: Clear the page tables for the ESB IO mapping

Commit 1ca3dec2 ("powerpc/xive: Prevent page fault issues in the
machine crash handler") fixed an issue in the FW assisted dump of
machines using hash MMU and the XIVE interrupt mode under the POWER
hypervisor. It forced the mapping of the ESB page of interrupts being
mapped in the Linux IRQ number space to make sure the 'crash kexec'
sequence worked during such an event. But it didn't handle the
un-mapping.

This mapping is now blocking the removal of a passthrough IO adapter
under the POWER hypervisor because it expects the guest OS to have
cleared all page table entries related to the adapter. If some are
still present, the RTAS call which isolates the PCI slot returns error
9001 "valid outstanding translations".

Remove these mapping in the IRQ data cleanup routine.

Under KVM, this cleanup is not required because the ESB pages for the
adapter interrupts are un-mapped from the guest by the hypervisor in
the KVM XIVE native device. This is now redundant but it's harmless.

Fixes: 1ca3dec2 ("powerpc/xive: Prevent page fault issues in the machine crash handler")
Cc: stable@vger.kernel.org # v5.5+
Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200429075122.1216388-2-clg@kaod.org
parent 16ef9767
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/vmalloc.h>
#include <asm/debugfs.h> #include <asm/debugfs.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -1020,12 +1021,16 @@ EXPORT_SYMBOL_GPL(is_xive_irq); ...@@ -1020,12 +1021,16 @@ EXPORT_SYMBOL_GPL(is_xive_irq);
void xive_cleanup_irq_data(struct xive_irq_data *xd) void xive_cleanup_irq_data(struct xive_irq_data *xd)
{ {
if (xd->eoi_mmio) { if (xd->eoi_mmio) {
unmap_kernel_range((unsigned long)xd->eoi_mmio,
1u << xd->esb_shift);
iounmap(xd->eoi_mmio); iounmap(xd->eoi_mmio);
if (xd->eoi_mmio == xd->trig_mmio) if (xd->eoi_mmio == xd->trig_mmio)
xd->trig_mmio = NULL; xd->trig_mmio = NULL;
xd->eoi_mmio = NULL; xd->eoi_mmio = NULL;
} }
if (xd->trig_mmio) { if (xd->trig_mmio) {
unmap_kernel_range((unsigned long)xd->trig_mmio,
1u << xd->esb_shift);
iounmap(xd->trig_mmio); iounmap(xd->trig_mmio);
xd->trig_mmio = NULL; xd->trig_mmio = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment