[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v7 16/16] hw/vfio/platform: add forwarded irq suppor
From: |
Eric Auger |
Subject: |
[Qemu-devel] [PATCH v7 16/16] hw/vfio/platform: add forwarded irq support |
Date: |
Fri, 31 Oct 2014 14:05:50 +0000 |
Tests whether the forwarded IRQ modality is available.
In the positive device IRQs are forwarded. This control is
achieved with KVM-VFIO device. with such a modality injection
still is handled through irqfds. However end of interrupt is
not trapped anymore. As soon as the guest completes its virtual
IRQ, the corresponding physical IRQ is completed and the same
physical IRQ can hit again.
A new x-forward property enables to force forwarding off although
enabled by the kernel.
Signed-off-by: Eric Auger <address@hidden>
---
hw/vfio/platform.c | 52 +++++++++++++++++++++++++++++++++++++++++
include/hw/vfio/vfio-platform.h | 2 ++
trace-events | 1 +
3 files changed, 55 insertions(+)
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index bdd5c93..f7ed209 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -237,6 +237,52 @@ static int vfio_start_eventfd_injection(VFIOINTp *intp)
}
/*
+ * Functions used with forwarding capability
+ */
+
+#ifdef CONFIG_KVM
+
+static bool has_kvm_vfio_forward_capability(void)
+{
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_DEVICE,
+ .attr = KVM_DEV_VFIO_DEVICE_FORWARD_IRQ};
+
+ if (ioctl(vfio_kvm_device_fd, KVM_HAS_DEVICE_ATTR, &attr) == 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static int vfio_set_forwarding(VFIOINTp *intp)
+{
+ int ret;
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_DEVICE,
+ .attr = KVM_DEV_VFIO_DEVICE_FORWARD_IRQ};
+
+ intp->fwd_irq = g_malloc0(sizeof(*intp->fwd_irq));
+ intp->fwd_irq->fd = intp->vdev->vbasedev.fd;
+ intp->fwd_irq->index = intp->pin;
+ intp->fwd_irq->gsi = intp->virtualID;
+
+ attr.addr = (uint64_t)(unsigned long)intp->fwd_irq;
+
+ if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+ error_report("Failed to forward IRQ %d through KVM VFIO device",
+ intp->pin);
+ g_free(intp->fwd_irq);
+ return -errno;
+ }
+ trace_vfio_start_fwd_injection(intp->pin);
+
+ return ret;
+}
+
+#endif
+
+/*
* Functions used for irqfd
*/
@@ -288,6 +334,11 @@ static int vfio_start_irqfd_injection(VFIOINTp *intp)
.flags = KVM_IRQFD_FLAG_RESAMPLE,
};
+ if (has_kvm_vfio_forward_capability() &&
+ intp->vdev->forward_allowed) {
+ vfio_set_forwarding(intp);
+ }
+
if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, &irqfd)) {
error_report("vfio: Error: Failed to assign the irqfd: %m");
goto fail_irqfd;
@@ -737,6 +788,7 @@ static Property vfio_platform_dev_properties[] = {
DEFINE_PROP_UINT32("mmap-timeout-ms", VFIOPlatformDevice,
mmap_timeout, 1100),
DEFINE_PROP_BOOL("x-irqfd", VFIOPlatformDevice, irqfd_allowed, true),
+ DEFINE_PROP_BOOL("x-forward", VFIOPlatformDevice, forward_allowed, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h
index 26ddba7..d22eb0e 100644
--- a/include/hw/vfio/vfio-platform.h
+++ b/include/hw/vfio/vfio-platform.h
@@ -42,6 +42,7 @@ typedef struct VFIOINTp {
bool kvm_accel; /* set when QEMU bypass through KVM enabled */
uint8_t pin; /* index */
uint8_t virtualID; /* virtual IRQ */
+ struct kvm_arch_forwarded_irq *fwd_irq;
} VFIOINTp;
typedef int (*start_irq_fn_t)(VFIOINTp *intp);
@@ -59,6 +60,7 @@ typedef struct VFIOPlatformDevice {
start_irq_fn_t start_irq_fn;
QemuMutex intp_mutex;
bool irqfd_allowed; /* debug option to force irqfd on/off */
+ bool forward_allowed; /* debug option to force forwarding on/off */
} VFIOPlatformDevice;
diff --git a/trace-events b/trace-events
index a05ed80..df3b71b 100644
--- a/trace-events
+++ b/trace-events
@@ -1429,6 +1429,7 @@ vfio_get_device(const char * name, unsigned int flags,
unsigned int num_regions,
vfio_put_base_device(int fd) "close vdev->fd=%d"
# hw/vfio/platform.c
+vfio_start_fwd_injection(int pin) "forwarding set for IRQ pin %d"
vfio_platform_eoi(int pin, int fd) "EOI IRQ pin %d (fd=%d)"
vfio_platform_mmap_set_enabled(bool enabled) "fast path = %d"
vfio_platform_intp_mmap_enable(int pin) "IRQ #%d still active, stay in slow
path"
--
1.8.3.2
- [Qemu-devel] [PATCH v7 00/16] KVM platform device passthrough, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 09/16] hw/vfio/platform: add vfio-platform support, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 16/16] hw/vfio/platform: add forwarded irq support,
Eric Auger <=
- [Qemu-devel] [PATCH v7 15/16] hw/vfio/common: vfio_kvm_device_fd moved in the common header, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 13/16] hw/vfio/platform: Add irqfd support, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 14/16] linux-headers: Update KVM headers from linux-next tag ToBeFilled, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 12/16] hw/arm/sysbus-fdt: enable vfio-calxeda-xgmac dynamic instantiation, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 10/16] hw/vfio: calxeda xgmac device, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 11/16] hw/arm/virt: add support for VFIO devices, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 06/16] hw/vfio/pci: rename group_list into vfio_group_list, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 05/16] hw/vfio/pci: split vfio_get_device, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 08/16] hw/vfio: create common module, Eric Auger, 2014/10/31
- [Qemu-devel] [PATCH v7 03/16] hw/vfio/pci: introduce VFIODevice, Eric Auger, 2014/10/31