|
|
9ae3a8 |
From ec24bb3a66429e7b1d086ab6f3597c550099831d Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Date: Fri, 29 Sep 2017 21:44:30 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 04/27] hw/vfio/pci: introduce minimalist VFIODevice with fd
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
Message-id: <20170929214430.16765.39580.stgit@gimli.home>
|
|
|
9ae3a8 |
Patchwork-id: 76762
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.5 qemu-kvm PATCH 04/16] hw/vfio/pci: introduce minimalist VFIODevice with fd
|
|
|
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 |
From: Eric Auger <eric.auger@linaro.org>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Upstream: 5546a621a8801351601537b311539486b9b3ee79
|
|
|
9ae3a8 |
RHEL: Include request notifier
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Introduce a new base VFIODevice strcut that will be used by both PCI
|
|
|
9ae3a8 |
and Platform VFIO device. Move VFIOPCIDevice fd field there. Obviously
|
|
|
9ae3a8 |
other fields from VFIOPCIDevice will be moved there but this patch
|
|
|
9ae3a8 |
file is introduced to ease the review.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Also vfio_mask_single_irqindex, vfio_unmask_single_irqindex,
|
|
|
9ae3a8 |
vfio_disable_irqindex now take a VFIODevice handle as argument.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-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 | 123 +++++++++++++++++++++++++++++++--------------------------
|
|
|
9ae3a8 |
1 file changed, 66 insertions(+), 57 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
|
|
|
9ae3a8 |
index ed9b8c4..340d967 100644
|
|
|
9ae3a8 |
--- a/hw/misc/vfio.c
|
|
|
9ae3a8 |
+++ b/hw/misc/vfio.c
|
|
|
9ae3a8 |
@@ -174,9 +174,13 @@ typedef struct VFIOMSIXInfo {
|
|
|
9ae3a8 |
void *mmap;
|
|
|
9ae3a8 |
} VFIOMSIXInfo;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+typedef struct VFIODevice {
|
|
|
9ae3a8 |
+ int fd;
|
|
|
9ae3a8 |
+} VFIODevice;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
typedef struct VFIOPCIDevice {
|
|
|
9ae3a8 |
PCIDevice pdev;
|
|
|
9ae3a8 |
- int fd;
|
|
|
9ae3a8 |
+ VFIODevice vbasedev;
|
|
|
9ae3a8 |
VFIOINTx intx;
|
|
|
9ae3a8 |
unsigned int config_size;
|
|
|
9ae3a8 |
uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian */
|
|
|
9ae3a8 |
@@ -272,7 +276,7 @@ static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
|
|
|
9ae3a8 |
/*
|
|
|
9ae3a8 |
* Common VFIO interrupt disable
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
-static void vfio_disable_irqindex(VFIOPCIDevice *vdev, int index)
|
|
|
9ae3a8 |
+static void vfio_disable_irqindex(VFIODevice *vbasedev, int index)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
struct vfio_irq_set irq_set = {
|
|
|
9ae3a8 |
.argsz = sizeof(irq_set),
|
|
|
9ae3a8 |
@@ -282,13 +286,13 @@ static void vfio_disable_irqindex(VFIOPCIDevice *vdev, int index)
|
|
|
9ae3a8 |
.count = 0,
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
|
|
|
9ae3a8 |
+ ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/*
|
|
|
9ae3a8 |
* INTx
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
-static void vfio_unmask_single_irqindex(VFIOPCIDevice *vdev, int index)
|
|
|
9ae3a8 |
+static void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
struct vfio_irq_set irq_set = {
|
|
|
9ae3a8 |
.argsz = sizeof(irq_set),
|
|
|
9ae3a8 |
@@ -298,11 +302,11 @@ static void vfio_unmask_single_irqindex(VFIOPCIDevice *vdev, int index)
|
|
|
9ae3a8 |
.count = 1,
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
|
|
|
9ae3a8 |
+ ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#ifdef CONFIG_KVM /* Unused outside of CONFIG_KVM code */
|
|
|
9ae3a8 |
-static void vfio_mask_single_irqindex(VFIOPCIDevice *vdev, int index)
|
|
|
9ae3a8 |
+static void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
struct vfio_irq_set irq_set = {
|
|
|
9ae3a8 |
.argsz = sizeof(irq_set),
|
|
|
9ae3a8 |
@@ -312,7 +316,7 @@ static void vfio_mask_single_irqindex(VFIOPCIDevice *vdev, int index)
|
|
|
9ae3a8 |
.count = 1,
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
|
|
|
9ae3a8 |
+ ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -376,7 +380,7 @@ static void vfio_eoi(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vdev->intx.pending = false;
|
|
|
9ae3a8 |
qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
|
|
|
9ae3a8 |
- vfio_unmask_single_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
@@ -399,7 +403,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Get to a known interrupt state */
|
|
|
9ae3a8 |
qemu_set_fd_handler(irqfd.fd, NULL, NULL, vdev);
|
|
|
9ae3a8 |
- vfio_mask_single_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_mask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
vdev->intx.pending = false;
|
|
|
9ae3a8 |
qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -429,7 +433,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
*pfd = irqfd.resamplefd;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
g_free(irq_set);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: Error: Failed to setup INTx unmask fd: %m");
|
|
|
9ae3a8 |
@@ -437,7 +441,7 @@ static void vfio_enable_intx_kvm(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Let'em rip */
|
|
|
9ae3a8 |
- vfio_unmask_single_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vdev->intx.kvm_accel = true;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -454,7 +458,7 @@ fail_irqfd:
|
|
|
9ae3a8 |
event_notifier_cleanup(&vdev->intx.unmask);
|
|
|
9ae3a8 |
fail:
|
|
|
9ae3a8 |
qemu_set_fd_handler(irqfd.fd, vfio_intx_interrupt, NULL, vdev);
|
|
|
9ae3a8 |
- vfio_unmask_single_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -475,7 +479,7 @@ static void vfio_disable_intx_kvm(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
* Get to a known state, hardware masked, QEMU ready to accept new
|
|
|
9ae3a8 |
* interrupts, QEMU IRQ de-asserted.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
- vfio_mask_single_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_mask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
vdev->intx.pending = false;
|
|
|
9ae3a8 |
qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -493,7 +497,7 @@ static void vfio_disable_intx_kvm(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
vdev->intx.kvm_accel = false;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* If we've missed an event, let it re-fire through QEMU */
|
|
|
9ae3a8 |
- vfio_unmask_single_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
DPRINTF("%s(%04x:%02x:%02x.%x) KVM INTx accel disabled\n",
|
|
|
9ae3a8 |
__func__, vdev->host.domain, vdev->host.bus,
|
|
|
9ae3a8 |
@@ -580,7 +584,7 @@ static int vfio_enable_intx(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
*pfd = event_notifier_get_fd(&vdev->intx.interrupt);
|
|
|
9ae3a8 |
qemu_set_fd_handler(*pfd, vfio_intx_interrupt, NULL, vdev);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
g_free(irq_set);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: Error: Failed to setup INTx fd: %m");
|
|
|
9ae3a8 |
@@ -605,7 +609,7 @@ static void vfio_disable_intx(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
qemu_del_timer(vdev->intx.mmap_timer);
|
|
|
9ae3a8 |
vfio_disable_intx_kvm(vdev);
|
|
|
9ae3a8 |
- vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
|
|
|
9ae3a8 |
vdev->intx.pending = false;
|
|
|
9ae3a8 |
qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
|
|
|
9ae3a8 |
vfio_mmap_set_enabled(vdev, true);
|
|
|
9ae3a8 |
@@ -695,7 +699,7 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix)
|
|
|
9ae3a8 |
fds[i] = fd;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
g_free(irq_set);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -792,7 +796,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
|
|
9ae3a8 |
* increase them as needed.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
if (vdev->nr_vectors < nr + 1) {
|
|
|
9ae3a8 |
- vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
|
|
|
9ae3a8 |
vdev->nr_vectors = nr + 1;
|
|
|
9ae3a8 |
ret = vfio_enable_vectors(vdev, true);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
@@ -820,7 +824,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
|
|
9ae3a8 |
*pfd = event_notifier_get_fd(&vector->interrupt);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
g_free(irq_set);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: failed to modify vector, %d", ret);
|
|
|
9ae3a8 |
@@ -871,7 +875,7 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
*pfd = event_notifier_get_fd(&vector->interrupt);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
g_free(irq_set);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -1030,7 +1034,7 @@ static void vfio_disable_msix(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (vdev->nr_vectors) {
|
|
|
9ae3a8 |
- vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vfio_disable_msi_common(vdev);
|
|
|
9ae3a8 |
@@ -1041,7 +1045,7 @@ static void vfio_disable_msix(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
static void vfio_disable_msi(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
- vfio_disable_irqindex(vdev, VFIO_PCI_MSI_IRQ_INDEX);
|
|
|
9ae3a8 |
+ vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSI_IRQ_INDEX);
|
|
|
9ae3a8 |
vfio_disable_msi_common(vdev);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
|
|
|
9ae3a8 |
@@ -1187,7 +1191,7 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
off_t off = 0;
|
|
|
9ae3a8 |
size_t bytes;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info)) {
|
|
|
9ae3a8 |
+ if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, ®_info)) {
|
|
|
9ae3a8 |
error_report("vfio: Error getting ROM info: %m");
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -1217,7 +1221,8 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
memset(vdev->rom, 0xff, size);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
while (size) {
|
|
|
9ae3a8 |
- bytes = pread(vdev->fd, vdev->rom + off, size, vdev->rom_offset + off);
|
|
|
9ae3a8 |
+ bytes = pread(vdev->vbasedev.fd, vdev->rom + off,
|
|
|
9ae3a8 |
+ size, vdev->rom_offset + off);
|
|
|
9ae3a8 |
if (bytes == 0) {
|
|
|
9ae3a8 |
break;
|
|
|
9ae3a8 |
} else if (bytes > 0) {
|
|
|
9ae3a8 |
@@ -1290,6 +1295,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
off_t offset = vdev->config_offset + PCI_ROM_ADDRESS;
|
|
|
9ae3a8 |
DeviceState *dev = DEVICE(vdev);
|
|
|
9ae3a8 |
char name[32];
|
|
|
9ae3a8 |
+ int fd = vdev->vbasedev.fd;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (vdev->pdev.romfile || !vdev->pdev.rom_bar) {
|
|
|
9ae3a8 |
/* Since pci handles romfile, just print a message and return */
|
|
|
9ae3a8 |
@@ -1308,10 +1314,10 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
* Use the same size ROM BAR as the physical device. The contents
|
|
|
9ae3a8 |
* will get filled in later when the guest tries to read it.
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
- if (pread(vdev->fd, &orig, 4, offset) != 4 ||
|
|
|
9ae3a8 |
- pwrite(vdev->fd, &size, 4, offset) != 4 ||
|
|
|
9ae3a8 |
- pread(vdev->fd, &size, 4, offset) != 4 ||
|
|
|
9ae3a8 |
- pwrite(vdev->fd, &orig, 4, offset) != 4) {
|
|
|
9ae3a8 |
+ if (pread(fd, &orig, 4, offset) != 4 ||
|
|
|
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 |
@@ -2123,7 +2129,8 @@ static uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
|
|
|
9ae3a8 |
if (~emu_bits & (0xffffffffU >> (32 - len * 8))) {
|
|
|
9ae3a8 |
ssize_t ret;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = pread(vdev->fd, &phys_val, len, vdev->config_offset + addr);
|
|
|
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 |
@@ -2153,7 +2160,8 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
|
|
|
9ae3a8 |
vdev->host.function, addr, val, len);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Write everything to VFIO, let it filter out what we can't write */
|
|
|
9ae3a8 |
- if (pwrite(vdev->fd, &val_le, len, vdev->config_offset + addr) != len) {
|
|
|
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 |
@@ -2389,7 +2397,7 @@ static int vfio_setup_msi(VFIOPCIDevice *vdev, int pos)
|
|
|
9ae3a8 |
bool msi_64bit, msi_maskbit;
|
|
|
9ae3a8 |
int ret, entries;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (pread(vdev->fd, &ctrl, sizeof(ctrl),
|
|
|
9ae3a8 |
+ if (pread(vdev->vbasedev.fd, &ctrl, sizeof(ctrl),
|
|
|
9ae3a8 |
vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -2428,23 +2436,24 @@ static int vfio_early_setup_msix(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
uint8_t pos;
|
|
|
9ae3a8 |
uint16_t ctrl;
|
|
|
9ae3a8 |
uint32_t table, pba;
|
|
|
9ae3a8 |
+ int fd = vdev->vbasedev.fd;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
pos = pci_find_capability(&vdev->pdev, PCI_CAP_ID_MSIX);
|
|
|
9ae3a8 |
if (!pos) {
|
|
|
9ae3a8 |
return 0;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (pread(vdev->fd, &ctrl, sizeof(ctrl),
|
|
|
9ae3a8 |
+ if (pread(fd, &ctrl, sizeof(ctrl),
|
|
|
9ae3a8 |
vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (pread(vdev->fd, &table, sizeof(table),
|
|
|
9ae3a8 |
+ if (pread(fd, &table, sizeof(table),
|
|
|
9ae3a8 |
vdev->config_offset + pos + PCI_MSIX_TABLE) != sizeof(table)) {
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (pread(vdev->fd, &pba, sizeof(pba),
|
|
|
9ae3a8 |
+ if (pread(fd, &pba, sizeof(pba),
|
|
|
9ae3a8 |
vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) {
|
|
|
9ae3a8 |
return -errno;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -2628,7 +2637,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
|
|
|
9ae3a8 |
vdev->host.function, nr);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Determine what type of BAR this is for registration */
|
|
|
9ae3a8 |
- ret = pread(vdev->fd, &pci_bar, sizeof(pci_bar),
|
|
|
9ae3a8 |
+ ret = pread(vdev->vbasedev.fd, &pci_bar, sizeof(pci_bar),
|
|
|
9ae3a8 |
vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr));
|
|
|
9ae3a8 |
if (ret != sizeof(pci_bar)) {
|
|
|
9ae3a8 |
error_report("vfio: Failed to read BAR %d (%m)", nr);
|
|
|
9ae3a8 |
@@ -3054,7 +3063,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
info = g_malloc0(sizeof(*info));
|
|
|
9ae3a8 |
info->argsz = sizeof(*info);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
|
|
|
9ae3a8 |
if (ret && errno != ENOSPC) {
|
|
|
9ae3a8 |
ret = -errno;
|
|
|
9ae3a8 |
if (!vdev->has_pm_reset) {
|
|
|
9ae3a8 |
@@ -3070,7 +3079,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
info->argsz = sizeof(*info) + (count * sizeof(*devices));
|
|
|
9ae3a8 |
devices = &info->devices[0];
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
ret = -errno;
|
|
|
9ae3a8 |
error_report("vfio: hot reset info failed: %m");
|
|
|
9ae3a8 |
@@ -3165,7 +3174,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Bus reset! */
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_PCI_HOT_RESET, reset);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_PCI_HOT_RESET, reset);
|
|
|
9ae3a8 |
g_free(reset);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
DPRINTF("%04x:%02x:%02x.%x hot reset: %s\n", vdev->host.domain,
|
|
|
9ae3a8 |
@@ -3516,12 +3525,12 @@ static int vfio_get_device(VFIOGroup *group, const char *name,
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- vdev->fd = ret;
|
|
|
9ae3a8 |
+ vdev->vbasedev.fd = ret;
|
|
|
9ae3a8 |
vdev->group = group;
|
|
|
9ae3a8 |
QLIST_INSERT_HEAD(&group->device_list, vdev, next);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Sanity check device */
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_INFO, &dev_info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_INFO, &dev_info);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: error getting device info: %m");
|
|
|
9ae3a8 |
goto error;
|
|
|
9ae3a8 |
@@ -3551,7 +3560,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name,
|
|
|
9ae3a8 |
for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX; i++) {
|
|
|
9ae3a8 |
reg_info.index = i;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: Error getting region %d info: %m", i);
|
|
|
9ae3a8 |
goto error;
|
|
|
9ae3a8 |
@@ -3565,14 +3574,14 @@ static int vfio_get_device(VFIOGroup *group, const char *name,
|
|
|
9ae3a8 |
vdev->bars[i].flags = reg_info.flags;
|
|
|
9ae3a8 |
vdev->bars[i].size = reg_info.size;
|
|
|
9ae3a8 |
vdev->bars[i].fd_offset = reg_info.offset;
|
|
|
9ae3a8 |
- vdev->bars[i].fd = vdev->fd;
|
|
|
9ae3a8 |
+ vdev->bars[i].fd = vdev->vbasedev.fd;
|
|
|
9ae3a8 |
vdev->bars[i].nr = i;
|
|
|
9ae3a8 |
QLIST_INIT(&vdev->bars[i].quirks);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
reg_info.index = VFIO_PCI_CONFIG_REGION_INDEX;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: Error getting config info: %m");
|
|
|
9ae3a8 |
goto error;
|
|
|
9ae3a8 |
@@ -3596,7 +3605,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name,
|
|
|
9ae3a8 |
.index = VFIO_PCI_VGA_REGION_INDEX,
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &vga_info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_REGION_INFO, &vga_info);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report(
|
|
|
9ae3a8 |
"vfio: Device does not support requested feature x-vga");
|
|
|
9ae3a8 |
@@ -3613,7 +3622,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name,
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vdev->vga.fd_offset = vga_info.offset;
|
|
|
9ae3a8 |
- vdev->vga.fd = vdev->fd;
|
|
|
9ae3a8 |
+ vdev->vga.fd = vdev->vbasedev.fd;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
vdev->vga.region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
|
|
|
9ae3a8 |
vdev->vga.region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
|
|
|
9ae3a8 |
@@ -3632,7 +3641,7 @@ static int vfio_get_device(VFIOGroup *group, const char *name,
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
/* This can fail for an old kernel or legacy PCI dev */
|
|
|
9ae3a8 |
DPRINTF("VFIO_DEVICE_GET_IRQ_INFO failure: %m\n");
|
|
|
9ae3a8 |
@@ -3650,7 +3659,7 @@ error:
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
QLIST_REMOVE(vdev, next);
|
|
|
9ae3a8 |
vdev->group = NULL;
|
|
|
9ae3a8 |
- close(vdev->fd);
|
|
|
9ae3a8 |
+ close(vdev->vbasedev.fd);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3659,8 +3668,8 @@ static void vfio_put_device(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
QLIST_REMOVE(vdev, next);
|
|
|
9ae3a8 |
vdev->group = NULL;
|
|
|
9ae3a8 |
- DPRINTF("vfio_put_device: close vdev->fd\n");
|
|
|
9ae3a8 |
- close(vdev->fd);
|
|
|
9ae3a8 |
+ DPRINTF("vfio_put_device: close vdev->vbasedev.fd\n");
|
|
|
9ae3a8 |
+ close(vdev->vbasedev.fd);
|
|
|
9ae3a8 |
if (vdev->msix) {
|
|
|
9ae3a8 |
g_free(vdev->msix);
|
|
|
9ae3a8 |
vdev->msix = NULL;
|
|
|
9ae3a8 |
@@ -3729,7 +3738,7 @@ static void vfio_register_err_notifier(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
*pfd = event_notifier_get_fd(&vdev->err_notifier);
|
|
|
9ae3a8 |
qemu_set_fd_handler(*pfd, vfio_err_notifier_handler, NULL, vdev);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: Failed to set up error notification");
|
|
|
9ae3a8 |
qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
|
|
|
9ae3a8 |
@@ -3762,7 +3771,7 @@ static void vfio_unregister_err_notifier(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
pfd = (int32_t *)&irq_set->data;
|
|
|
9ae3a8 |
*pfd = -1;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
+ ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
error_report("vfio: Failed to de-assign error fd: %m");
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3795,7 +3804,7 @@ static void vfio_register_req_notifier(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (ioctl(vdev->fd,
|
|
|
9ae3a8 |
+ if (ioctl(vdev->vbasedev.fd,
|
|
|
9ae3a8 |
VFIO_DEVICE_GET_IRQ_INFO, &irq_info) < 0 || irq_info.count < 1) {
|
|
|
9ae3a8 |
return;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -3819,7 +3828,7 @@ static void vfio_register_req_notifier(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
*pfd = event_notifier_get_fd(&vdev->req_notifier);
|
|
|
9ae3a8 |
qemu_set_fd_handler(*pfd, vfio_req_notifier_handler, NULL, vdev);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
|
|
|
9ae3a8 |
+ if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
|
|
|
9ae3a8 |
error_report("vfio: Failed to set up device request notification");
|
|
|
9ae3a8 |
qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
|
|
|
9ae3a8 |
event_notifier_cleanup(&vdev->req_notifier);
|
|
|
9ae3a8 |
@@ -3852,7 +3861,7 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev)
|
|
|
9ae3a8 |
pfd = (int32_t *)&irq_set->data;
|
|
|
9ae3a8 |
*pfd = -1;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
|
|
|
9ae3a8 |
+ if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
|
|
|
9ae3a8 |
error_report("vfio: Failed to de-assign device request fd: %m");
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
g_free(irq_set);
|
|
|
9ae3a8 |
@@ -3944,7 +3953,7 @@ static int vfio_initfn(PCIDevice *pdev)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Get a copy of config space */
|
|
|
9ae3a8 |
- ret = pread(vdev->fd, vdev->pdev.config,
|
|
|
9ae3a8 |
+ ret = pread(vdev->vbasedev.fd, vdev->pdev.config,
|
|
|
9ae3a8 |
MIN(pci_config_size(&vdev->pdev), vdev->config_size),
|
|
|
9ae3a8 |
vdev->config_offset);
|
|
|
9ae3a8 |
if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) {
|
|
|
9ae3a8 |
@@ -4061,7 +4070,7 @@ static void vfio_pci_reset(DeviceState *dev)
|
|
|
9ae3a8 |
vfio_pci_pre_reset(vdev);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (vdev->reset_works && (vdev->has_flr || !vdev->has_pm_reset) &&
|
|
|
9ae3a8 |
- !ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
|
|
|
9ae3a8 |
+ !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
|
|
|
9ae3a8 |
DPRINTF("%04x:%02x:%02x.%x FLR/VFIO_DEVICE_RESET\n", vdev->host.domain,
|
|
|
9ae3a8 |
vdev->host.bus, vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
goto post_reset;
|
|
|
9ae3a8 |
@@ -4074,7 +4083,7 @@ static void vfio_pci_reset(DeviceState *dev)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* If nothing else works and the device supports PM reset, use it */
|
|
|
9ae3a8 |
if (vdev->reset_works && vdev->has_pm_reset &&
|
|
|
9ae3a8 |
- !ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
|
|
|
9ae3a8 |
+ !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
|
|
|
9ae3a8 |
DPRINTF("%04x:%02x:%02x.%x PCI PM Reset\n", vdev->host.domain,
|
|
|
9ae3a8 |
vdev->host.bus, vdev->host.slot, vdev->host.function);
|
|
|
9ae3a8 |
goto post_reset;
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|