diff mbox series

[SRU,F,1/12] s390/pci: Improve handling of unset UID

Message ID 20200518182438.392269-2-frank.heimes@canonical.com
State New
Headers show
Series s390x/pci: enumerate pci functions per physical adapter (LP: 1874056) | expand

Commit Message

Frank Heimes May 18, 2020, 6:24 p.m. UTC
From: Niklas Schnelle <schnelle@linux.ibm.com>

BugLink: https://bugs.launchpad.net/bugs/1874056

When UID checking is enabled a UID value of 0 is invalid and can not be
set by the user. On z/VM it is however used to indicate an unset UID.
Until now, this lead to the behavior that one PCI function could be
attached with UID 0 after which z/VM would prohibit further attachment.

Now if the user then turns off UID checking in z/VM the user could
seemingly attach additional PCI functions that would however not show up
in Linux as that would not be informed of the change in UID checking
mode. This is unexpected and confusing and lead to bug reports against
Linux.

Instead now, if we encounter an unset UID value of 0 treat it as
indicating that UID checking was turned off, switch to automatic domain
allocation, and warn the user of the possible misconfiguration.

Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
(backported from commit 7a11c67a1ff9b0231eaaaa6a28294776d55b569a)
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
---
 arch/s390/include/asm/pci.h | 3 +++
 arch/s390/pci/pci.c         | 8 ++++++++
 arch/s390/pci/pci_clp.c     | 2 +-
 3 files changed, 12 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 7850e8c8c79a..abce7aa6c8cb 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -190,6 +190,9 @@  int clp_enable_fh(struct zpci_dev *, u8);
 int clp_disable_fh(struct zpci_dev *);
 int clp_get_state(u32 fid, enum zpci_state *state);
 
+/* UID */
+void update_uid_checking(bool new);
+
 /* IOMMU Interface */
 int zpci_init_iommu(struct zpci_dev *zdev);
 void zpci_destroy_iommu(struct zpci_dev *zdev);
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 0af46683dd66..c0f80e896d7b 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -662,6 +662,13 @@  static int zpci_alloc_domain(struct zpci_dev *zdev)
 
 	if (zpci_unique_uid) {
 		zdev->domain = (u16) zdev->uid;
+		if (zdev->domain == 0) {
+			pr_warn("UID checking is active but no UID is set for PCI function %08x, so automatic domain allocation is used instead\n",
+				zdev->fid);
+			update_uid_checking(false);
+			goto auto_allocate;
+		}
+
 		if (test_bit(zdev->domain, zpci_domain)) {
 			spin_unlock(&zpci_domain_lock);
 			pr_err("Adding PCI function %08x failed because domain %04x is already assigned\n",
@@ -673,6 +680,7 @@  static int zpci_alloc_domain(struct zpci_dev *zdev)
 		spin_unlock(&zpci_domain_lock);
 		return 0;
 	}
+auto_allocate:
 	/*
 	 * We can always auto allocate domains below ZPCI_NR_DEVICES.
 	 * There is either a free domain or we have reached the maximum in
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index 281e0dd4c614..cfc9ae9df85d 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -24,7 +24,7 @@ 
 
 bool zpci_unique_uid;
 
-static void update_uid_checking(bool new)
+void update_uid_checking(bool new)
 {
 	if (zpci_unique_uid != new)
 		zpci_dbg(1, "uid checking:%d\n", new);