|
|
9ae3a8 |
From acd0e88a7222dac83caf4d507a1bfce7cd0ea734 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Date: Fri, 29 Sep 2017 21:45:14 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 09/27] vfio: Add sysfsdev property for pci & platform
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Message-id: <20170929214514.16765.36252.stgit@gimli.home>
|
|
|
9ae3a8 |
Patchwork-id: 76768
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.5 qemu-kvm PATCH 09/16] vfio: Add sysfsdev property for pci & platform
|
|
|
9ae3a8 |
Bugzilla: 1494181
|
|
|
9ae3a8 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Upstream: 7df9381b7aa56c897e344f3bfe43bf5848bbd3e0
|
|
|
9ae3a8 |
RHEL: Dropped platform
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vfio-pci currently requires a host= parameter, which comes in the
|
|
|
9ae3a8 |
form of a PCI address in [domain:]<bus:slot.function> notation. We
|
|
|
9ae3a8 |
expect to find a matching entry in sysfs for that under
|
|
|
9ae3a8 |
/sys/bus/pci/devices/. vfio-platform takes a similar approach, but
|
|
|
9ae3a8 |
defines the host= parameter to be a string, which can be matched
|
|
|
9ae3a8 |
directly under /sys/bus/platform/devices/. On the PCI side, we have
|
|
|
9ae3a8 |
some interest in using vfio to expose vGPU devices. These are not
|
|
|
9ae3a8 |
actual discrete PCI devices, so they don't have a compatible host PCI
|
|
|
9ae3a8 |
bus address or a device link where QEMU wants to look for it. There's
|
|
|
9ae3a8 |
also really no requirement that vfio can only be used to expose
|
|
|
9ae3a8 |
physical devices, a new vfio bus and iommu driver could expose a
|
|
|
9ae3a8 |
completely emulated device. To fit within the vfio framework, it
|
|
|
9ae3a8 |
would need a kernel struct device and associated IOMMU group, but
|
|
|
9ae3a8 |
those are easy constraints to manage.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
To support such devices, which would include vGPUs, that honor the
|
|
|
9ae3a8 |
VFIO PCI programming API, but are not necessarily backed by a unique
|
|
|
9ae3a8 |
PCI address, add support for specifying any device in sysfs. The
|
|
|
9ae3a8 |
vfio API already has support for probing the device type to ensure
|
|
|
9ae3a8 |
compatibility with either vfio-pci or vfio-platform.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
With this, a vfio-pci device could either be specified as:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-device vfio-pci,host=02:00.0
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
or
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-device vfio-pci,sysfsdev=/sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
or even
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-device vfio-pci,sysfsdev=/sys/bus/pci/devices/0000:02:00.0
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
When vGPU support comes along, this might look something more like:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-device vfio-pci,sysfsdev=/sys/devices/virtual/intel-vgpu/vgpu0@0000:00:02.0
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
NB - This is only a made up example path
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The same change is made for vfio-platform, specifying sysfsdev has
|
|
|
9ae3a8 |
precedence over the old host option.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Tested-by: Eric Auger <eric.auger@linaro.org>
|
|
|
9ae3a8 |
Reviewed-by: Eric Auger <eric.auger@linaro.org>
|
|
|
9ae3a8 |
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/misc/vfio.c | 131 ++++++++++++++++++++++++---------------------------------
|
|
|
9ae3a8 |
1 file changed, 54 insertions(+), 77 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
|
|
|
9ae3a8 |
index 0d88313..64d4dc7 100644
|
|
|
9ae3a8 |
--- a/hw/misc/vfio.c
|
|
|
9ae3a8 |
+++ b/hw/misc/vfio.c
|
|
|
9ae3a8 |
@@ -187,6 +187,7 @@ typedef struct VFIODeviceOps VFIODeviceOps;
|
|
|
9ae3a8 |
typedef struct VFIODevice {
|
|
|
9ae3a8 |
QLIST_ENTRY(VFIODevice) next;
|
|
|
9ae3a8 |
struct VFIOGroup *group;
|
|
|
9ae3a8 |
+ char *sysfsdev;
|
|
|
9ae3a8 |
char *name;
|
|
|
9ae3a8 |
int fd;
|
|
|
9ae3a8 |
int type;
|
|
|
9ae3a8 |
@@ -1288,12 +1289,8 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
if (vdev->pdev.romfile || !vdev->pdev.rom_bar) {
|
|
|
9ae3a8 |
/* Since pci handles romfile, just print a message and return */
|
|
|
9ae3a8 |
if (vfio_blacklist_opt_rom(vdev) && vdev->pdev.romfile) {
|
|
|
9ae3a8 |
- error_printf("Warning : Device at %04x:%02x:%02x.%x "
|
|
|
9ae3a8 |
- "is known to cause system instability issues during "
|
|
|
9ae3a8 |
- "option rom execution. "
|
|
|
9ae3a8 |
- "Proceeding anyway since user specified romfile\n",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function);
|
|
|
9ae3a8 |
+ error_printf("Warning : Device at %s is known to cause system instability issues during option rom execution. Proceeding anyway since user specified romfile\n",
|
|
|
9ae3a8 |
+ vdev->vbasedev.name);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -1306,9 +1303,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
pwrite(fd, &size, 4, offset) != 4 ||
|
|
|
9ae3a8 |
pread(fd, &size, 4, offset) != 4 ||
|
|
|
9ae3a8 |
pwrite(fd, &orig, 4, offset) != 4) {
|
|
|
9ae3a8 |
- error_report("%s(%04x:%02x:%02x.%x) failed: %m",
|
|
|
9ae3a8 |
- __func__, vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
- vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
+ error_report("%s(%s) failed: %m", __func__, vdev->vbasedev.name);
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -1320,29 +1315,18 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (vfio_blacklist_opt_rom(vdev)) {
|
|
|
9ae3a8 |
if (dev->opts && qemu_opt_get(dev->opts, "rombar")) {
|
|
|
9ae3a8 |
- error_printf("Warning : Device at %04x:%02x:%02x.%x "
|
|
|
9ae3a8 |
- "is known to cause system instability issues during "
|
|
|
9ae3a8 |
- "option rom execution. "
|
|
|
9ae3a8 |
- "Proceeding anyway since user specified non zero value for "
|
|
|
9ae3a8 |
- "rombar\n",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function);
|
|
|
9ae3a8 |
+ error_printf("Warning : Device at %s is known to cause system instability issues during option rom execution. Proceeding anyway since user specified non zero value for rombar\n",
|
|
|
9ae3a8 |
+ vdev->vbasedev.name);
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
- error_printf("Warning : Rom loading for device at "
|
|
|
9ae3a8 |
- "%04x:%02x:%02x.%x has been disabled due to "
|
|
|
9ae3a8 |
- "system instability issues. "
|
|
|
9ae3a8 |
- "Specify rombar=1 or romfile to force\n",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function);
|
|
|
9ae3a8 |
+ error_printf("Warning : Rom loading for device at %s has been disabled due to system instability issues. Specify rombar=1 or romfile to force\n",
|
|
|
9ae3a8 |
+ vdev->vbasedev.name);
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
DPRINTF("%s ROM size 0x%x\n", vdev->vbasedev.name, size);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- snprintf(name, sizeof(name), "vfio[%04x:%02x:%02x.%x].rom",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function);
|
|
|
9ae3a8 |
+ snprintf(name, sizeof(name), "vfio[%s].rom", vdev->vbasedev.name);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
memory_region_init_io(&vdev->pdev.rom,
|
|
|
9ae3a8 |
&vfio_rom_ops, vdev, name, size);
|
|
|
9ae3a8 |
@@ -2112,9 +2096,8 @@ static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
|
|
|
9ae3a8 |
ret = pread(vdev->vbasedev.fd, &phys_val, len,
|
|
|
9ae3a8 |
vdev->config_offset + addr);
|
|
|
9ae3a8 |
if (ret != len) {
|
|
|
9ae3a8 |
- error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x) failed: %m",
|
|
|
9ae3a8 |
- __func__, vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
- vdev->host.slot, vdev->host.function, addr, len);
|
|
|
9ae3a8 |
+ error_report("%s(%s, 0x%x, 0x%x) failed: %m",
|
|
|
9ae3a8 |
+ __func__, vdev->vbasedev.name, addr, len);
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
phys_val = le32_to_cpu(phys_val);
|
|
|
9ae3a8 |
@@ -2140,9 +2123,8 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
|
|
|
9ae3a8 |
/* Write everything to VFIO, let it filter out what we can't write */
|
|
|
9ae3a8 |
if (pwrite(vdev->vbasedev.fd, &val_le, len, vdev->config_offset + addr)
|
|
|
9ae3a8 |
!= len) {
|
|
|
9ae3a8 |
- error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x, 0x%x) failed: %m",
|
|
|
9ae3a8 |
- __func__, vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
- vdev->host.slot, vdev->host.function, addr, val, len);
|
|
|
9ae3a8 |
+ error_report("%s(%s, 0x%x, 0x%x, 0x%x) failed: %m",
|
|
|
9ae3a8 |
+ __func__, vdev->vbasedev.name, addr, val, len);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* MSI/MSI-X Enabling/Disabling */
|
|
|
9ae3a8 |
@@ -2610,9 +2592,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- snprintf(name, sizeof(name), "VFIO %04x:%02x:%02x.%x BAR %d",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function, nr);
|
|
|
9ae3a8 |
+ snprintf(name, sizeof(name), "VFIO %s BAR %d", vdev->vbasedev.name, nr);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Determine what type of BAR this is for registration */
|
|
|
9ae3a8 |
ret = pread(vdev->vbasedev.fd, &pci_bar, sizeof(pci_bar),
|
|
|
9ae3a8 |
@@ -2946,9 +2926,8 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t pos)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (ret < 0) {
|
|
|
9ae3a8 |
- error_report("vfio: %04x:%02x:%02x.%x Error adding PCI capability "
|
|
|
9ae3a8 |
- "0x%x[0x%x]@0x%x: %d", vdev->host.domain,
|
|
|
9ae3a8 |
- vdev->host.bus, vdev->host.slot, vdev->host.function,
|
|
|
9ae3a8 |
+ error_report("vfio: %s Error adding PCI capability "
|
|
|
9ae3a8 |
+ "0x%x[0x%x]@0x%x: %d", vdev->vbasedev.name,
|
|
|
9ae3a8 |
cap_id, size, pos, ret);
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3010,11 +2989,14 @@ static void vfio_pci_post_reset(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
vfio_enable_intx(vdev);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-static bool vfio_pci_host_match(PCIHostDeviceAddress *host1,
|
|
|
9ae3a8 |
- PCIHostDeviceAddress *host2)
|
|
|
9ae3a8 |
+static bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- return (host1->domain == host2->domain && host1->bus == host2->bus &&
|
|
|
9ae3a8 |
- host1->slot == host2->slot && host1->function == host2->function);
|
|
|
9ae3a8 |
+ char tmp[13];
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ sprintf(tmp, "%04x:%02x:%02x.%1x", addr->domain,
|
|
|
9ae3a8 |
+ addr->bus, addr->slot, addr->function);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ return (strcmp(tmp, name) == 0);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
@@ -3040,9 +3022,8 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
if (ret && errno != ENOSPC) {
|
|
|
9ae3a8 |
ret = -errno;
|
|
|
9ae3a8 |
if (!vdev->has_pm_reset) {
|
|
|
9ae3a8 |
- error_report("vfio: Cannot reset device %04x:%02x:%02x.%x, "
|
|
|
9ae3a8 |
- "no available reset mechanism.", vdev->host.domain,
|
|
|
9ae3a8 |
- vdev->host.bus, vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
+ error_report("vfio: Cannot reset device %s, "
|
|
|
9ae3a8 |
+ "no available reset mechanism.", vdev->vbasedev.name);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
goto out_single;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3075,7 +3056,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
DPRINTF("\t%04x:%02x:%02x.%x group %d\n", host.domain,
|
|
|
9ae3a8 |
host.bus, host.slot, host.function, devices[i].group_id);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (vfio_pci_host_match(&host, &vdev->host)) {
|
|
|
9ae3a8 |
+ if (vfio_pci_host_match(&host, vdev->vbasedev.name)) {
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -3101,7 +3082,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev);
|
|
|
9ae3a8 |
- if (vfio_pci_host_match(&host, &tmp->host)) {
|
|
|
9ae3a8 |
+ if (vfio_pci_host_match(&host, tmp->vbasedev.name)) {
|
|
|
9ae3a8 |
if (single) {
|
|
|
9ae3a8 |
DPRINTF("vfio: found another in-use device "
|
|
|
9ae3a8 |
"%s\n", tmp->vbasedev.name);
|
|
|
9ae3a8 |
@@ -3165,7 +3146,7 @@ out:
|
|
|
9ae3a8 |
host.slot = PCI_SLOT(devices[i].devfn);
|
|
|
9ae3a8 |
host.function = PCI_FUNC(devices[i].devfn);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (vfio_pci_host_match(&host, &vdev->host)) {
|
|
|
9ae3a8 |
+ if (vfio_pci_host_match(&host, vdev->vbasedev.name)) {
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -3184,7 +3165,7 @@ out:
|
|
|
9ae3a8 |
continue;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev);
|
|
|
9ae3a8 |
- if (vfio_pci_host_match(&host, &tmp->host)) {
|
|
|
9ae3a8 |
+ if (vfio_pci_host_match(&host, tmp->vbasedev.name)) {
|
|
|
9ae3a8 |
vfio_pci_post_reset(tmp);
|
|
|
9ae3a8 |
break;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3683,10 +3664,7 @@ static void vfio_err_notifier_handler(void *opaque)
|
|
|
9ae3a8 |
* guest to contain the error.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- error_report("%s(%04x:%02x:%02x.%x) Unrecoverable error detected. "
|
|
|
9ae3a8 |
- "Please collect any data possible and then kill the guest",
|
|
|
9ae3a8 |
- __func__, vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
- vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
+ error_report("%s(%s) Unrecoverable error detected. Please collect any data possible and then kill the guest", __func__, vdev->vbasedev.name);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3867,7 +3845,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
|
|
9ae3a8 |
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
|
|
|
9ae3a8 |
VFIODevice *vbasedev_iter;
|
|
|
9ae3a8 |
VFIOGroup *group;
|
|
|
9ae3a8 |
- char path[PATH_MAX], iommu_group_path[PATH_MAX], *group_name;
|
|
|
9ae3a8 |
+ char *tmp, group_path[PATH_MAX], *group_name;
|
|
|
9ae3a8 |
ssize_t len;
|
|
|
9ae3a8 |
struct stat st;
|
|
|
9ae3a8 |
int groupid;
|
|
|
9ae3a8 |
@@ -3885,36 +3863,37 @@ static int vfio_initfn(PCIDevice *pdev)
|
|
|
9ae3a8 |
return -1;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- /* Check that the host device exists */
|
|
|
9ae3a8 |
- snprintf(path, sizeof(path),
|
|
|
9ae3a8 |
- "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function);
|
|
|
9ae3a8 |
- if (stat(path, &st) < 0) {
|
|
|
9ae3a8 |
- error_report("vfio: error: no such host device: %s", path);
|
|
|
9ae3a8 |
+ if (!vdev->vbasedev.sysfsdev) {
|
|
|
9ae3a8 |
+ vdev->vbasedev.sysfsdev =
|
|
|
9ae3a8 |
+ g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%01x",
|
|
|
9ae3a8 |
+ vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
+ vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (stat(vdev->vbasedev.sysfsdev, &st) < 0) {
|
|
|
9ae3a8 |
+ error_report("vfio: error: no such host device: %s",
|
|
|
9ae3a8 |
+ vdev->vbasedev.sysfsdev);
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ vdev->vbasedev.name = g_strdup(basename(vdev->vbasedev.sysfsdev));
|
|
|
9ae3a8 |
vdev->vbasedev.ops = &vfio_pci_ops;
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI;
|
|
|
9ae3a8 |
- vdev->vbasedev.name = g_strdup_printf("%04x:%02x:%02x.%01x",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
- vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1);
|
|
|
9ae3a8 |
+ tmp = g_strdup_printf("%s/iommu_group", vdev->vbasedev.sysfsdev);
|
|
|
9ae3a8 |
+ len = readlink(tmp, group_path, sizeof(group_path));
|
|
|
9ae3a8 |
+ g_free(tmp);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- len = readlink(path, iommu_group_path, sizeof(path));
|
|
|
9ae3a8 |
- if (len <= 0 || len >= sizeof(path)) {
|
|
|
9ae3a8 |
+ if (len <= 0 || len >= sizeof(group_path)) {
|
|
|
9ae3a8 |
error_report("vfio: error no iommu_group for device");
|
|
|
9ae3a8 |
return len < 0 ? -errno : -ENAMETOOLONG;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- iommu_group_path[len] = 0;
|
|
|
9ae3a8 |
- group_name = basename(iommu_group_path);
|
|
|
9ae3a8 |
+ group_path[len] = 0;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ group_name = basename(group_path);
|
|
|
9ae3a8 |
if (sscanf(group_name, "%d", &groupid) != 1) {
|
|
|
9ae3a8 |
- error_report("vfio: error reading %s: %m", path);
|
|
|
9ae3a8 |
+ error_report("vfio: error reading %s: %m", group_path);
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -3926,21 +3905,18 @@ static int vfio_initfn(PCIDevice *pdev)
|
|
|
9ae3a8 |
return -ENOENT;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- snprintf(path, sizeof(path), "%04x:%02x:%02x.%01x",
|
|
|
9ae3a8 |
- vdev->host.domain, vdev->host.bus, vdev->host.slot,
|
|
|
9ae3a8 |
- vdev->host.function);
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
|
|
|
9ae3a8 |
if (strcmp(vbasedev_iter->name, vdev->vbasedev.name) == 0) {
|
|
|
9ae3a8 |
- error_report("vfio: error: device %s is already attached", path);
|
|
|
9ae3a8 |
+ error_report("vfio: error: device %s is already attached",
|
|
|
9ae3a8 |
+ vdev->vbasedev.name);
|
|
|
9ae3a8 |
vfio_put_group(group);
|
|
|
9ae3a8 |
return -EBUSY;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = vfio_get_device(group, path, vdev);
|
|
|
9ae3a8 |
+ ret = vfio_get_device(group, vdev->vbasedev.name, vdev);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
- error_report("vfio: failed to get device %s", path);
|
|
|
9ae3a8 |
+ error_report("vfio: failed to get device %s", vdev->vbasedev.name);
|
|
|
9ae3a8 |
vfio_put_group(group);
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -4086,6 +4062,7 @@ post_reset:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
static Property vfio_pci_dev_properties[] = {
|
|
|
9ae3a8 |
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
|
|
|
9ae3a8 |
+ DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
|
|
|
9ae3a8 |
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIOPCIDevice,
|
|
|
9ae3a8 |
intx.mmap_timeout, 1100),
|
|
|
9ae3a8 |
DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|