From: Cédric Le Goater <clg@kaod.org> Date: 2020-06-17 17:26:30
Hello,
When a passthrough IO adapter is removed from a pseries machine using
hash MMU and the XIVE interrupt mode, the POWER hypervisor expects the
guest OS to clear 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" and the removal of
the IO adapter fails. This is because when the PHBs are scanned, Linux
maps automatically some interrupts in the Linux interrupt number space
but these are never removed.
To solve this problem, we introduce a PPC platform specific
pcibios_remove_bus() routine which clears all interrupt mappings when
the bus is removed. This also clears the associated page table entries
of the ESB pages when using XIVE.
For this purpose, we record the logical interrupt numbers of the
mapped interrupt under the PHB structure and let pcibios_remove_bus()
do the clean up.
Tested on :
- PowerNV with PCI, OpenCAPI, CAPI and GPU adapters. I don't know
how to inject a failure on a PHB but that would be a good test.
- KVM P8+P9 guests with passthrough PCI adapters, but PHBs can not
be removed under QEMU/KVM.
- PowerVM with passthrough PCI adapters (main target)
Thanks,
C.
Changes since v1:
- extended the removal to interrupts other than the legacy INTx.
Cédric Le Goater (2):
powerpc/pci: unmap legacy INTx interrupts when a PHB is removed
powerpc/pci: unmap all interrupts when a PHB is removed
arch/powerpc/include/asm/pci-bridge.h | 6 ++
arch/powerpc/kernel/pci-common.c | 114 ++++++++++++++++++++++++++
2 files changed, 120 insertions(+)
--
2.25.4
From: Cédric Le Goater <clg@kaod.org> Date: 2020-06-17 16:49:46
When a passthrough IO adapter is removed from a pseries machine using
hash MMU and the XIVE interrupt mode, the POWER hypervisor expects the
guest OS to clear 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" and the removal of
the IO adapter fails. This is because when the PHBs are scanned, Linux
maps automatically the INTx interrupts in the Linux interrupt number
space but these are never removed.
To solve this problem, we introduce a PPC platform specific
pcibios_remove_bus() routine which clears all interrupt mappings when
the bus is removed. This also clears the associated page table entries
of the ESB pages when using XIVE.
For this purpose, we record the logical interrupt numbers of the
mapped interrupt under the PHB structure and let pcibios_remove_bus()
do the clean up.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/include/asm/pci-bridge.h | 6 +++
arch/powerpc/kernel/pci-common.c | 67 +++++++++++++++++++++++++++
2 files changed, 73 insertions(+)
@@ -127,6 +130,9 @@ struct pci_controller {void*private_data;structnpu*npu;++unsignedintirq_count;+unsignedint*irq_map;};/* These are used for config access before all the PCI probing
@@ -401,6 +463,8 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)pci_dev->irq=virq;+/* Record all interrut mappings for later removal of a PHB */+pci_irq_map_register(pci_dev,virq);return0;}
@@ -1554,6 +1618,9 @@ void pcibios_scan_phb(struct pci_controller *hose)pr_debug("PCI: Scanning PHB %pOF\n",node);+/* Allocate interrupt mappings array */+pcibios_irq_map_init(hose);+/* Get some IO space for the new PHB */pcibios_setup_phb_io_space(hose);
From: Cédric Le Goater <clg@kaod.org> Date: 2020-06-17 17:11:08
Some PCI adapters, like GPUs, use the "interrupt-map" property to
describe interrupt mappings other than the legacy INTx interrupts.
There can be more than 4 mappings.
To clear all interrupts when a PHB is removed, we need to increase the
'irq_map' array in which mappings are recorded. Compute the number of
interrupt mappings from the "interrupt-map" property and allocate a
bigger 'irq_map' array.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/kernel/pci-common.c | 49 +++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
From: Cédric Le Goater <clg@kaod.org> Date: 2020-06-18 14:02:11
On 6/17/20 6:29 PM, Cédric Le Goater wrote:
Hello,
When a passthrough IO adapter is removed from a pseries machine using
hash MMU and the XIVE interrupt mode, the POWER hypervisor expects the
guest OS to clear 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" and the removal of
the IO adapter fails. This is because when the PHBs are scanned, Linux
maps automatically some interrupts in the Linux interrupt number space
but these are never removed.
To solve this problem, we introduce a PPC platform specific
pcibios_remove_bus() routine which clears all interrupt mappings when
the bus is removed. This also clears the associated page table entries
of the ESB pages when using XIVE.
For this purpose, we record the logical interrupt numbers of the
mapped interrupt under the PHB structure and let pcibios_remove_bus()
do the clean up.
Tested on :
- PowerNV with PCI, OpenCAPI, CAPI and GPU adapters. I don't know
how to inject a failure on a PHB but that would be a good test.
I found out that powering down the slot is enough :
echo 0 > /sys/bus/pci/slots/<slot name>/power
The IRQ cleanup is done as expected on baremetal also.
Cheers,
C.
- KVM P8+P9 guests with passthrough PCI adapters, but PHBs can not
be removed under QEMU/KVM.
- PowerVM with passthrough PCI adapters (main target)
Thanks,
C.
Changes since v1:
- extended the removal to interrupts other than the legacy INTx.
Cédric Le Goater (2):
powerpc/pci: unmap legacy INTx interrupts when a PHB is removed
powerpc/pci: unmap all interrupts when a PHB is removed
arch/powerpc/include/asm/pci-bridge.h | 6 ++
arch/powerpc/kernel/pci-common.c | 114 ++++++++++++++++++++++++++
2 files changed, 120 insertions(+)
Some PCI adapters, like GPUs, use the "interrupt-map" property to
describe interrupt mappings other than the legacy INTx interrupts.
There can be more than 4 mappings.
To clear all interrupts when a PHB is removed, we need to increase the
'irq_map' array in which mappings are recorded. Compute the number of
interrupt mappings from the "interrupt-map" property and allocate a
bigger 'irq_map' array.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/kernel/pci-common.c | 49 +++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
I wonder if
int of_irq_count(struct device_node *dev)
could work here too. If it does not, then never mind.
Other than that, the only other comment is - merge this one into 1/2 as
1/2 alone won't properly fix the problem but it may look like that it does:
for phyp, the test machine just happens to have 4 entries in the map but
this is the phyp implementation detail;
for qemu, there are more but we only unregister 4 but kvm does not care
in general so it is ok which is also implementation detail;
and 2/2 just makes these details not matter. Thanks,
From: Cédric Le Goater <clg@kaod.org> Date: 2020-08-07 10:04:52
On 8/7/20 8:01 AM, Alexey Kardashevskiy wrote:
On 18/06/2020 02:29, Cédric Le Goater wrote:
quoted
Some PCI adapters, like GPUs, use the "interrupt-map" property to
describe interrupt mappings other than the legacy INTx interrupts.
There can be more than 4 mappings.
To clear all interrupts when a PHB is removed, we need to increase the
'irq_map' array in which mappings are recorded. Compute the number of
interrupt mappings from the "interrupt-map" property and allocate a
bigger 'irq_map' array.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/kernel/pci-common.c | 49 +++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
I wonder if
int of_irq_count(struct device_node *dev)
could work here too. If it does not, then never mind.
I wished it would, but no.
Other than that, the only other comment is - merge this one into 1/2 as
1/2 alone won't properly fix the problem but it may look like that it does:
for phyp, the test machine just happens to have 4 entries in the map but
this is the phyp implementation detail;
yes
for qemu, there are more but we only unregister 4 but kvm does not care
in general so it is ok which is also implementation detail;
and 2/2 just makes these details not matter. Thanks,
OK. It will ease backport. Sending a v2.
Thanks for the review Alexey !
C.