Skip to content

Commit 6f38a8b

Browse files
ajdlinuxozbenh
authored andcommitted
cxl: use pcibios_free_controller_deferred() when removing vPHBs
When cxl removes a vPHB, it's possible that the pci_controller may be freed before all references to the devices on the vPHB have been released. This in turn causes an invalid memory access when the devices are eventually released, as pcibios_release_device() attempts to call the phb's release_device hook. In cxl_pci_vphb_remove(), remove the existing call to pcibios_free_controller(). Instead, use pcibios_free_controller_deferred() to free the pci_controller after all devices have been released. Export pci_set_host_bridge_release() so we can do this. Cc: stable@vger.kernel.org Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Reviewed-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
1 parent f5ed841 commit 6f38a8b

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

drivers/misc/cxl/vphb.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ int cxl_pci_vphb_add(struct cxl_afu *afu)
230230
if (phb->bus == NULL)
231231
return -ENXIO;
232232

233+
/* Set release hook on root bus */
234+
pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge),
235+
pcibios_free_controller_deferred,
236+
(void *) phb);
237+
233238
/* Claim resources. This might need some rework as well depending
234239
* whether we are doing probe-only or not, like assigning unassigned
235240
* resources etc...
@@ -256,7 +261,10 @@ void cxl_pci_vphb_remove(struct cxl_afu *afu)
256261
afu->phb = NULL;
257262

258263
pci_remove_root_bus(phb->bus);
259-
pcibios_free_controller(phb);
264+
/*
265+
* We don't free phb here - that's handled by
266+
* pcibios_free_controller_deferred()
267+
*/
260268
}
261269

262270
static bool _cxl_pci_is_vphb_device(struct pci_controller *phb)

drivers/pci/host-bridge.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
4444
bridge->release_fn = release_fn;
4545
bridge->release_data = release_data;
4646
}
47+
EXPORT_SYMBOL_GPL(pci_set_host_bridge_release);
4748

4849
void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
4950
struct resource *res)

0 commit comments

Comments
 (0)