Skip to content

Commit afdf955

Browse files
niklas88Vasily Gorbik
authored andcommitted
s390/pci: fix leak of DMA tables on hard unplug
commit f606b3e ("s390/pci: adapt events for zbus") removed the zpci_disable_device() call for a zPCI event with PEC 0x0304 because the device is already deconfigured by the platform. This however skips the Linux side of the disable in particular it leads to leaking the DMA tables and bitmaps because zpci_dma_exit_device() is never called on the device. If the device transitions to the Reserved state we call zpci_zdev_put() but zpci_release_device() will not call zpci_disable_device() because the state of the zPCI function is already ZPCI_FN_STATE_STANDBY. If the device is put into the Standby state, zpci_disable_device() is not called and the device is assumed to have been put in Standby through platform action. At this point the device may be removed by a subsequent event with PEC 0x0308 or 0x0306 which calls zpci_zdev_put() with the same problem as above or the device may be configured again in which case zpci_disable_device() is also not called. Fix this by calling zpci_disable_device() explicitly for PEC 0x0304 as before. To make it more clear that zpci_disable_device() may be called, even if the lower level device has already been disabled by the platform, add a comment to zpci_disable_device(). Cc: <[email protected]> # 5.8 Fixes: f606b3e ("s390/pci: adapt events for zbus") Signed-off-by: Niklas Schnelle <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent fcb2b70 commit afdf955

File tree

2 files changed

+6
-0
lines changed

2 files changed

+6
-0
lines changed

arch/s390/pci/pci.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,10 @@ EXPORT_SYMBOL_GPL(zpci_enable_device);
668668
int zpci_disable_device(struct zpci_dev *zdev)
669669
{
670670
zpci_dma_exit_device(zdev);
671+
/*
672+
* The zPCI function may already be disabled by the platform, this is
673+
* detected in clp_disable_fh() which becomes a no-op.
674+
*/
671675
return clp_disable_fh(zdev);
672676
}
673677
EXPORT_SYMBOL_GPL(zpci_disable_device);

arch/s390/pci/pci_event.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
143143
zpci_remove_device(zdev);
144144
}
145145

146+
zdev->fh = ccdf->fh;
147+
zpci_disable_device(zdev);
146148
zdev->state = ZPCI_FN_STATE_STANDBY;
147149
if (!clp_get_state(ccdf->fid, &state) &&
148150
state == ZPCI_FN_STATE_RESERVED) {

0 commit comments

Comments
 (0)