|
|
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 |
|