Skip to content

Commit ae6c1fd

Browse files
committed
s390/pci: Fix handling of isolated VFs
jira LE-4076 Rebuild_History Non-Buildable kernel-6.12.0-55.30.1.el10_0 commit-author Niklas Schnelle <[email protected]> commit 2844ddb In contrast to the commit message of the fixed commit VFs whose parent PF is not configured are not always isolated, that is put on their own PCI domain. This is because for VFs to be added to an existing PCI domain it is enough for that PCI domain to share the same topology ID or PCHID. Such a matching PCI domain without a parent PF may exist when a PF from the same PCI card created the domain with the VF being a child of a different, non accessible, PF. While not causing technical issues it makes the rules which VFs are isolated inconsistent. Fix this by explicitly checking that the parent PF exists on the PCI domain determined by the topology ID or PCHID before registering the VF. This works because a parent PF which is under control of this Linux instance must be enabled and configured at the point where its child VFs appear because otherwise SR-IOV could not have been enabled on the parent. Fixes: 25f39d3 ("s390/pci: Ignore RID for isolated VFs") Cc: [email protected] Reviewed-by: Halil Pasic <[email protected]> Signed-off-by: Niklas Schnelle <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]> (cherry picked from commit 2844ddb) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 032c1f1 commit ae6c1fd

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

arch/s390/pci/pci_bus.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,17 @@ static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)
331331
return rc;
332332
}
333333

334+
static bool zpci_bus_is_isolated_vf(struct zpci_bus *zbus, struct zpci_dev *zdev)
335+
{
336+
struct pci_dev *pdev;
337+
338+
pdev = zpci_iov_find_parent_pf(zbus, zdev);
339+
if (!pdev)
340+
return true;
341+
pci_dev_put(pdev);
342+
return false;
343+
}
344+
334345
int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
335346
{
336347
bool topo_is_tid = zdev->tid_avail;
@@ -345,6 +356,15 @@ int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
345356

346357
topo = topo_is_tid ? zdev->tid : zdev->pchid;
347358
zbus = zpci_bus_get(topo, topo_is_tid);
359+
/*
360+
* An isolated VF gets its own domain/bus even if there exists
361+
* a matching domain/bus already
362+
*/
363+
if (zbus && zpci_bus_is_isolated_vf(zbus, zdev)) {
364+
zpci_bus_put(zbus);
365+
zbus = NULL;
366+
}
367+
348368
if (!zbus) {
349369
zbus = zpci_bus_alloc(topo, topo_is_tid);
350370
if (!zbus)

arch/s390/pci/pci_iov.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, in
7474
* found. If the function is not a VF or has no RequesterID information,
7575
* NULL is returned as well.
7676
*/
77-
static struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev)
77+
struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev)
7878
{
7979
int i, vfid, devfn, cand_devfn;
8080
struct pci_dev *pdev;

arch/s390/pci/pci_iov.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ void zpci_iov_map_resources(struct pci_dev *pdev);
1717

1818
int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn);
1919

20+
struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev);
21+
2022
#else /* CONFIG_PCI_IOV */
2123
static inline void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn) {}
2224

@@ -26,5 +28,10 @@ static inline int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *v
2628
{
2729
return 0;
2830
}
31+
32+
static inline struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev)
33+
{
34+
return NULL;
35+
}
2936
#endif /* CONFIG_PCI_IOV */
3037
#endif /* __S390_PCI_IOV_h */

0 commit comments

Comments
 (0)