Skip to content

Commit 3047766

Browse files
niklas88heicarst
authored andcommitted
s390/pci: fix enabling a reserved PCI function
In usual IPL or hot plug scenarios a zPCI function transitions directly from reserved (invisible to Linux) to configured state or is configured by Linux itself using an SCLP, however it can also first go from reserved to standby and then from standby to configured without Linux initiative. In this scenario we first get a PEC event 0x302 and then 0x301. This may happen for example when the device is deconfigured at another LPAR and made available for this LPAR. It may also happen under z/VM when a device is attached while in some inconsistent state. However when we get the 0x301 the device is already known to zPCI so calling zpci_create() will add it twice resulting in the below BUG. Instead we should only enable the existing device and finally scan it through the PCI subsystem. list_add double add: new=00000000ed5a9008, prev=00000000ed5a9008, next=0000000083502300. kernel BUG at lib/list_debug.c:31! Krnl PSW : 0704c00180000000 0000000082dc2db8 (__list_add_valid+0x70/0xa8) Call Trace: [<0000000082dc2db8>] __list_add_valid+0x70/0xa8 ([<0000000082dc2db4>] __list_add_valid+0x6c/0xa8) [<00000000828ea920>] zpci_create_device+0x60/0x1b0 [<00000000828ef04a>] zpci_event_availability+0x282/0x2f0 [<000000008315f848>] chsc_process_crw+0x2b8/0xa18 [<000000008316735c>] crw_collect_info+0x254/0x348 [<00000000829226ea>] kthread+0x14a/0x168 [<000000008319d5c0>] ret_from_fork+0x24/0x2c Fixes: f606b3e ("s390/pci: adapt events for zbus") Reported-by: Alexander Egorenkov <[email protected]> Tested-by: Alexander Egorenkov <[email protected]> Signed-off-by: Niklas Schnelle <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent 9ebcfad commit 3047766

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

arch/s390/pci/pci_event.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,18 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
9494
}
9595
zdev->fh = ccdf->fh;
9696
zdev->state = ZPCI_FN_STATE_CONFIGURED;
97-
zpci_create_device(zdev);
97+
ret = zpci_enable_device(zdev);
98+
if (ret)
99+
break;
100+
101+
pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn);
102+
if (!pdev)
103+
break;
104+
105+
pci_bus_add_device(pdev);
106+
pci_lock_rescan_remove();
107+
pci_bus_add_devices(zdev->zbus->bus);
108+
pci_unlock_rescan_remove();
98109
break;
99110
case 0x0302: /* Reserved -> Standby */
100111
if (!zdev) {

0 commit comments

Comments
 (0)