Blame SOURCES/0001-linux-support-32-bit-PCI-domains-v3.patch

626095
From a167bd6474522a709ff3cbb00476c0e4309cb66f Mon Sep 17 00:00:00 2001
626095
From: Stephen Hemminger <stephen@networkplumber.org>
626095
Date: Mon, 18 Sep 2017 13:17:23 -0400
626095
Subject: [PATCH libpciaccess] linux: support 32 bit PCI domains (v3)
626095
626095
The PCI domain may be larger than 16 bits on Microsoft Azure and other
626095
virtual environments. PCI busses reported by ACPI are limited to 16
626095
bits, but in Azure the domain value for pass through devices is
626095
intentionally larger than 16 bits to avoid clashing with local devices.
626095
This is needed to support pass through of GPU devices.
626095
626095
v3: (ajax)
626095
Update FreeBSD and Solaris backends to preserve the full 32-bit domain
626095
number, since on those OSes it stands a chance of working already.
626095
Update NetBSD and OpenBSD backends to initialize domain_16 compatibly
626095
with older libpciaccess; neither backend appears to support more than a
626095
handful of domains to begin with though. Trivially update the generic
626095
x86 backend for source compatibility, though it still only supports one
626095
domain and will never be better.
626095
626095
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=101744
626095
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
626095
Reviewed-by: Eric Anholt <eric@anholt.net>
626095
---
626095
 include/pciaccess.h | 15 ++++++++++++++-
626095
 src/linux_sysfs.c   | 25 ++++++++++++-------------
626095
 src/netbsd_pci.c    |  4 ++++
626095
 src/openbsd_pci.c   |  4 ++++
626095
 src/solx_devfs.c    |  5 +++++
626095
 src/x86_pci.c       |  2 +-
626095
 6 files changed, 40 insertions(+), 15 deletions(-)
626095
626095
diff --git a/include/pciaccess.h b/include/pciaccess.h
626095
index 1d7aa4b..8167be6 100644
626095
--- a/include/pciaccess.h
626095
+++ b/include/pciaccess.h
626095
@@ -311,6 +311,10 @@ struct pci_mem_region {
626095
  * PCI device.
626095
  *
626095
  * Contains all of the information about a particular PCI device.
626095
+ *
626095
+ * This structure - like everything else in libpciaccess - is allocated
626095
+ * by the library itself. Do not embed this structure in other structs,
626095
+ * or otherwise allocate them yourself.
626095
  */
626095
 struct pci_device {
626095
     /**
626095
@@ -319,9 +323,12 @@ struct pci_device {
626095
      * Complete bus identification, including domain, of the device.  On
626095
      * platforms that do not support PCI domains (e.g., 32-bit x86 hardware),
626095
      * the domain will always be zero.
626095
+     *
626095
+     * The domain_16 field is provided for binary compatibility with older
626095
+     * libpciaccess.
626095
      */
626095
     /*@{*/
626095
-    uint16_t    domain;
626095
+    uint16_t    domain_16;
626095
     uint8_t     bus;
626095
     uint8_t     dev;
626095
     uint8_t     func;
626095
@@ -385,6 +392,12 @@ struct pci_device {
626095
       * Used by the VGA arbiter. Type of resource decoded by the device and
626095
       * the file descriptor (/dev/vga_arbiter). */
626095
     int vgaarb_rsrc;
626095
+
626095
+
626095
+    /**
626095
+     * PCI domain value (full 32 bits)
626095
+     */
626095
+    uint32_t    domain;
626095
 };
626095
 
626095
 
626095
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
626095
index dd8ef3e..a8bc2e1 100644
626095
--- a/src/linux_sysfs.c
626095
+++ b/src/linux_sysfs.c
626095
@@ -118,28 +118,18 @@ pci_system_linux_sysfs_create( void )
626095
 
626095
 
626095
 /**
626095
- * Filter out the names "." and ".." from the scanned sysfs entries, and
626095
- * domains requiring 32-bits.
626095
+ * Filter out the names "." and ".." from the scanned sysfs entries.
626095
  *
626095
  * \param d  Directory entry being processed by \c scandir.
626095
  *
626095
  * \return
626095
- * Zero if the entry name matches either "." or "..", or the domain requires
626095
- * 32 bits, non-zero otherwise.
626095
+ * Zero if the entry name matches either "." or ".."
626095
  *
626095
  * \sa scandir, populate_entries
626095
  */
626095
 static int
626095
 scan_sys_pci_filter( const struct dirent * d )
626095
 {
626095
-    if (d->d_name[0] != '.') {
626095
-        unsigned dom = 0;
626095
-
626095
-        sscanf(d->d_name, "%x:", &dom;;
626095
-        if (dom > USHRT_MAX)
626095
-            return 0;
626095
-    }
626095
-
626095
     return !((strcmp( d->d_name, "." ) == 0)
626095
 	     || (strcmp( d->d_name, ".." ) == 0));
626095
 }
626095
@@ -218,10 +208,19 @@ populate_entries( struct pci_system * p )
626095
 			(struct pci_device_private *) &p->devices[i];
626095
 
626095
 
626095
-		sscanf(devices[i]->d_name, "%04x:%02x:%02x.%1u",
626095
+		sscanf(devices[i]->d_name, "%x:%02x:%02x.%1u",
626095
 		       & dom, & bus, & dev, & func);
626095
 
626095
 		device->base.domain = dom;
626095
+		/*
626095
+		 * Applications compiled with older versions  do not expect
626095
+		 * 32-bit domain numbers. To keep them working, we keep a 16-bit
626095
+		 * version of the domain number at the previous location.
626095
+		 */
626095
+		if (dom > 0xffff)
626095
+		     device->base.domain_16 = 0xffff;
626095
+		else
626095
+		     device->base.domain_16 = dom;
626095
 		device->base.bus = bus;
626095
 		device->base.dev = dev;
626095
 		device->base.func = func;
626095
diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c
626095
index f972f94..1f3bcea 100644
626095
--- a/src/netbsd_pci.c
626095
+++ b/src/netbsd_pci.c
626095
@@ -959,6 +959,10 @@ pci_system_netbsd_create(void)
626095
 					continue;
626095
 
626095
 				device->base.domain = domain;
626095
+				if (domain > 0xffff)
626095
+				    device->base.domain_16 = 0xffff;
626095
+				else
626095
+				    device->base.domain_16 = domain & 0xffff;
626095
 				device->base.bus = bus;
626095
 				device->base.dev = dev;
626095
 				device->base.func = func;
626095
diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
626095
index b8ce318..c061fd8 100644
626095
--- a/src/openbsd_pci.c
626095
+++ b/src/openbsd_pci.c
626095
@@ -656,6 +656,10 @@ pci_system_openbsd_create(void)
626095
 						continue;
626095
 
626095
 					device->base.domain = domain;
626095
+					if (domain > 0xffff)
626095
+					    device->base.domain_16 = 0xffff;
626095
+					else
626095
+					    device->base.domain_16 = domain & 0xffff;
626095
 					device->base.bus = bus;
626095
 					device->base.dev = dev;
626095
 					device->base.func = func;
626095
diff --git a/src/solx_devfs.c b/src/solx_devfs.c
626095
index 46fc301..dc1464d 100644
626095
--- a/src/solx_devfs.c
626095
+++ b/src/solx_devfs.c
626095
@@ -213,6 +213,11 @@ probe_device_node(di_node_t node, void *arg)
626095
     pci_base->dev = PCI_REG_DEV_G(retbuf[0]);
626095
     pci_base->func  = PCI_REG_FUNC_G(retbuf[0]);
626095
 
626095
+    if (nexus->domain > 0xffff)
626095
+	pci_base->domain_16 = 0xffff;
626095
+    else
626095
+	pci_base->domain_16 = nexus->domain;
626095
+
626095
     /* Get property values */
626095
     for (i = 0; i < NUM_PROPERTIES; i++) {
626095
 	len = di_prop_lookup_ints(DDI_DEV_T_ANY, node,
626095
diff --git a/src/x86_pci.c b/src/x86_pci.c
626095
index 32daa04..6b6a026 100644
626095
--- a/src/x86_pci.c
626095
+++ b/src/x86_pci.c
626095
@@ -915,7 +915,7 @@ pci_system_x86_create(void)
626095
 		if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
626095
 		    PCI_VENDOR(reg) == 0)
626095
 		    continue;
626095
-		device->base.domain = 0;
626095
+		device->base.domain = device->base.domain_16 = 0;
626095
 		device->base.bus = bus;
626095
 		device->base.dev = dev;
626095
 		device->base.func = func;
626095
-- 
626095
2.14.2
626095