Skip to content
/ linux Public

Commit 2c89064

Browse files
niklas88Sasha Levin
authored andcommitted
s390/pci: Handle futile config accesses of disabled devices directly
[ Upstream commit 84d875e ] On s390 PCI busses and slots with multiple functions may have holes because PCI functions are passed-through by the hypervisor on a per function basis and some functions may be in standby or reserved. This fact is indicated by returning true from the hypervisor_isolated_pci_functions() helper and triggers common code to scan all possible devfn values. Via pci_scan_single_device() this in turn causes config reads for the device and vendor IDs, even for PCI functions which are in standby and thereofore disabled. So far these futile config reads, as well as potentially writes, which can never succeed were handled by the PCI load/store instructions themselves. This works as the platform just returns an error for a disabled and thus not usable function handle. It does cause spamming of error logs and additional overhead though. Instead check if the used function handle is enabled in zpci_cfg_load() and zpci_cfg_write() and if not enable directly return -ENODEV. Also refactor zpci_cfg_load() and zpci_cfg_store() slightly to accommodate the new logic while meeting modern kernel style guidelines. Cc: stable@vger.kernel.org Fixes: a50297c ("s390/pci: separate zbus creation from scanning") Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> Reviewed-by: Benjamin Block <bblock@linux.ibm.com> Reviewed-by: Farhan Ali <alifm@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent b7bbd20 commit 2c89064

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

arch/s390/pci/pci.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,24 +232,33 @@ int zpci_fmb_disable_device(struct zpci_dev *zdev)
232232
static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
233233
{
234234
u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
235+
int rc = -ENODEV;
235236
u64 data;
236-
int rc;
237+
238+
if (!zdev_enabled(zdev))
239+
goto out_err;
237240

238241
rc = __zpci_load(&data, req, offset);
239-
if (!rc) {
240-
data = le64_to_cpu((__force __le64) data);
241-
data >>= (8 - len) * 8;
242-
*val = (u32) data;
243-
} else
244-
*val = 0xffffffff;
242+
if (rc)
243+
goto out_err;
244+
data = le64_to_cpu((__force __le64)data);
245+
data >>= (8 - len) * 8;
246+
*val = (u32)data;
247+
return 0;
248+
249+
out_err:
250+
PCI_SET_ERROR_RESPONSE(val);
245251
return rc;
246252
}
247253

248254
static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
249255
{
250256
u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
257+
int rc = -ENODEV;
251258
u64 data = val;
252-
int rc;
259+
260+
if (!zdev_enabled(zdev))
261+
return rc;
253262

254263
data <<= (8 - len) * 8;
255264
data = (__force u64) cpu_to_le64(data);

0 commit comments

Comments
 (0)