* [Qemu-devel] [RFC][PATCH 01/11] msix: Factor out msix_get_message
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 02/11] msix: Invoke msix_handle_mask_update on msix_mask_all Jan Kiszka
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
This helper will also be used by the upcoming config notifier.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/msix.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/hw/msix.c b/hw/msix.c
index 3835eaa..3197465 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -35,6 +35,15 @@
#define MSIX_PAGE_PENDING (MSIX_PAGE_SIZE / 2)
#define MSIX_MAX_ENTRIES 32
+static MSIMessage msix_get_message(PCIDevice *dev, unsigned vector)
+{
+ uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE;
+ MSIMessage msg;
+
+ msg.address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
+ msg.data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
+ return msg;
+}
/* Add MSI-X capability to the config space for the device. */
/* Given a bar and its size, add MSI-X table on top of it
@@ -352,9 +361,7 @@ uint32_t msix_bar_size(PCIDevice *dev)
/* Send an MSI-X message */
void msix_notify(PCIDevice *dev, unsigned vector)
{
- uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE;
- uint64_t address;
- uint32_t data;
+ MSIMessage msg;
if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
return;
@@ -363,9 +370,9 @@ void msix_notify(PCIDevice *dev, unsigned vector)
return;
}
- address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
- data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
- stl_le_phys(address, data);
+ msg = msix_get_message(dev, vector);
+
+ stl_le_phys(msg.address, msg.data);
}
void msix_reset(PCIDevice *dev)
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 02/11] msix: Invoke msix_handle_mask_update on msix_mask_all
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 01/11] msix: Factor out msix_get_message Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 03/11] msix: Introduce vector notifiers Jan Kiszka
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
In preparation of firing vector notifiers on mask changes, call
msix_handle_mask_update also from msix_mask_all. So far, this will have
no real effect.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/msix.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/hw/msix.c b/hw/msix.c
index 3197465..e1a7d92 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -231,10 +231,14 @@ static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar)
static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
{
int vector;
+
for (vector = 0; vector < nentries; ++vector) {
unsigned offset =
vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
+ bool was_masked = msix_is_masked(dev, vector);
+
dev->msix_table_page[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
+ msix_handle_mask_update(dev, vector, was_masked);
}
}
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 03/11] msix: Introduce vector notifiers
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 01/11] msix: Factor out msix_get_message Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 02/11] msix: Invoke msix_handle_mask_update on msix_mask_all Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-15 13:31 ` [Qemu-devel] [PATCH 12/11] msix: Trigger vector mask update check after vmload Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 04/11] kvm: Rename kvm_irqchip_add_route to kvm_irqchip_add_irq_route Jan Kiszka
` (7 subsequent siblings)
10 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Vector notifiers shall be triggered by the MSI/MSI-X core whenever a
relevant configuration change is programmed by the guest. In case of
MSI-X, changes are reported when the effective mask (global &&
per-vector) alters its state. On unmask, the current vector
configuration is included in the event report. This allows users - e.g.
virtio-pci layer - to transfer this information to external MSI-X
routing subsystems - like vhost + KVM in-kernel irqchip.
This implementation only provides MSI-X support, but extension to MSI is
feasible and will be provided later on when adding support for KVM PCI
device assignment.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/msix.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/msix.h | 4 +++
hw/pci.h | 8 +++++
3 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/hw/msix.c b/hw/msix.c
index e1a7d92..c6968aa 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -139,13 +139,34 @@ static bool msix_is_masked(PCIDevice *dev, int vector)
return msix_vector_masked(dev, vector, dev->msix_function_masked);
}
+static void msix_fire_vector_notifier(PCIDevice *dev,
+ unsigned int vector, bool is_masked)
+{
+ MSIMessage msg;
+ int ret;
+
+ if (!dev->msix_vector_use_notifier) {
+ return;
+ }
+ if (is_masked) {
+ dev->msix_vector_release_notifier(dev, vector);
+ } else {
+ msg = msix_get_message(dev, vector);
+ ret = dev->msix_vector_use_notifier(dev, vector, msg);
+ assert(ret >= 0);
+ }
+}
+
static void msix_handle_mask_update(PCIDevice *dev, int vector, bool was_masked)
{
bool is_masked = msix_is_masked(dev, vector);
+
if (is_masked == was_masked) {
return;
}
+ msix_fire_vector_notifier(dev, vector, is_masked);
+
if (!is_masked && msix_is_pending(dev, vector)) {
msix_clr_pending(dev, vector);
msix_notify(dev, vector);
@@ -425,3 +446,70 @@ void msix_unuse_all_vectors(PCIDevice *dev)
return;
msix_free_irq_entries(dev);
}
+
+static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector)
+{
+ MSIMessage msg;
+
+ if (msix_is_masked(dev, vector)) {
+ return 0;
+ }
+ msg = msix_get_message(dev, vector);
+ return dev->msix_vector_use_notifier(dev, vector, msg);
+}
+
+static void msix_unset_notifier_for_vector(PCIDevice *dev, unsigned int vector)
+{
+ if (msix_is_masked(dev, vector)) {
+ return;
+ }
+ dev->msix_vector_release_notifier(dev, vector);
+}
+
+int msix_set_vector_notifiers(PCIDevice *dev,
+ MSIVectorUseNotifier use_notifier,
+ MSIVectorReleaseNotifier release_notifier)
+{
+ int vector, ret;
+
+ assert(use_notifier && release_notifier);
+
+ dev->msix_vector_use_notifier = use_notifier;
+ dev->msix_vector_release_notifier = release_notifier;
+
+ if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
+ (MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
+ for (vector = 0; vector < dev->msix_entries_nr; vector++) {
+ ret = msix_set_notifier_for_vector(dev, vector);
+ if (ret < 0) {
+ goto undo;
+ }
+ }
+ }
+ return 0;
+
+undo:
+ while (--vector >= 0) {
+ msix_unset_notifier_for_vector(dev, vector);
+ }
+ dev->msix_vector_use_notifier = NULL;
+ dev->msix_vector_release_notifier = NULL;
+ return ret;
+}
+
+void msix_unset_vector_notifiers(PCIDevice *dev)
+{
+ int vector;
+
+ assert(dev->msix_vector_use_notifier &&
+ dev->msix_vector_release_notifier);
+
+ if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
+ (MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
+ for (vector = 0; vector < dev->msix_entries_nr; vector++) {
+ msix_unset_notifier_for_vector(dev, vector);
+ }
+ }
+ dev->msix_vector_use_notifier = NULL;
+ dev->msix_vector_release_notifier = NULL;
+}
diff --git a/hw/msix.h b/hw/msix.h
index 5aba22b..f33f18b 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -29,4 +29,8 @@ void msix_notify(PCIDevice *dev, unsigned vector);
void msix_reset(PCIDevice *dev);
+int msix_set_vector_notifiers(PCIDevice *dev,
+ MSIVectorUseNotifier use_notifier,
+ MSIVectorReleaseNotifier release_notifier);
+void msix_unset_vector_notifiers(PCIDevice *dev);
#endif
diff --git a/hw/pci.h b/hw/pci.h
index 8d0aa49..c3cacce 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -173,6 +173,10 @@ typedef struct PCIDeviceClass {
const char *romfile;
} PCIDeviceClass;
+typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector,
+ MSIMessage msg);
+typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector);
+
struct PCIDevice {
DeviceState qdev;
/* PCI config space */
@@ -243,6 +247,10 @@ struct PCIDevice {
bool has_rom;
MemoryRegion rom;
uint32_t rom_bar;
+
+ /* MSI-X notifiers */
+ MSIVectorUseNotifier msix_vector_use_notifier;
+ MSIVectorReleaseNotifier msix_vector_release_notifier;
};
void pci_register_bar(PCIDevice *pci_dev, int region_num,
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 12/11] msix: Trigger vector mask update check after vmload
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 03/11] msix: Introduce vector notifiers Jan Kiszka
@ 2012-05-15 13:31 ` Jan Kiszka
0 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-15 13:31 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
In case we load a PCI device with active vectors, we have to process
them and invoke potential notifiers.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
This amends the QEMU series but should be equally relevant as bug fix
for qemu-kvm.
hw/msix.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/hw/msix.c b/hw/msix.c
index 2114b99..59c7a83 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -351,6 +351,7 @@ void msix_save(PCIDevice *dev, QEMUFile *f)
void msix_load(PCIDevice *dev, QEMUFile *f)
{
unsigned n = dev->msix_entries_nr;
+ unsigned int vector;
if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
return;
@@ -360,6 +361,10 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
msix_update_function_masked(dev);
+
+ for (vector = 0; vector < n; vector++) {
+ msix_handle_mask_update(dev, vector, true);
+ }
}
/* Does device support MSI-X? */
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 04/11] kvm: Rename kvm_irqchip_add_route to kvm_irqchip_add_irq_route
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (2 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 03/11] msix: Introduce vector notifiers Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 05/11] kvm: Introduce kvm_irqchip_add_msi_route Jan Kiszka
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
We will add kvm_irqchip_add_msi_route, so let's make the difference
clearer.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/pc_piix.c | 8 ++++----
kvm-all.c | 2 +-
kvm.h | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 6a75718..c17f906 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -63,17 +63,17 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
if (i == 2) {
continue;
}
- kvm_irqchip_add_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
+ kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
}
for (i = 8; i < 16; ++i) {
- kvm_irqchip_add_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
+ kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
}
if (pci_enabled) {
for (i = 0; i < 24; ++i) {
if (i == 0) {
- kvm_irqchip_add_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
+ kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
} else if (i != 2) {
- kvm_irqchip_add_route(s, i, KVM_IRQCHIP_IOAPIC, i);
+ kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i);
}
}
}
diff --git a/kvm-all.c b/kvm-all.c
index 8f8cec5..8ab83db 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -935,7 +935,7 @@ static void kvm_add_routing_entry(KVMState *s,
set_gsi(s, entry->gsi);
}
-void kvm_irqchip_add_route(KVMState *s, int irq, int irqchip, int pin)
+void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
{
struct kvm_irq_routing_entry e;
diff --git a/kvm.h b/kvm.h
index 7857dbf..8b061bd 100644
--- a/kvm.h
+++ b/kvm.h
@@ -134,7 +134,7 @@ void kvm_arch_init_irq_routing(KVMState *s);
int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
-void kvm_irqchip_add_route(KVMState *s, int gsi, int irqchip, int pin);
+void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
int kvm_irqchip_commit_routes(KVMState *s);
void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 05/11] kvm: Introduce kvm_irqchip_add_msi_route
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (3 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 04/11] kvm: Rename kvm_irqchip_add_route to kvm_irqchip_add_irq_route Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 06/11] kvm: Publicize kvm_release_gsi as kvm_irqchip_release_virq Jan Kiszka
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Add a service that establishes a static route from a virtual IRQ line to
an MSI message. Will be used for IRQFD and device assignment. As we will
use this service outside of CONFIG_KVM protected code, stub it properly.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
kvm-all.c | 31 +++++++++++++++++++++++++++++++
kvm-stub.c | 8 ++++++++
kvm.h | 10 ++++++----
3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index 8ab83db..f45b852 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1080,6 +1080,32 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
return kvm_irqchip_set_irq(s, route->kroute.gsi, 1);
}
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+{
+ struct kvm_irq_routing_entry kroute;
+ int gsi;
+
+ if (!kvm_irqchip_in_kernel()) {
+ return -ENOSYS;
+ }
+
+ gsi = kvm_get_pseudo_gsi(s);
+ if (gsi < 0) {
+ return gsi;
+ }
+
+ kroute.gsi = gsi;
+ kroute.type = KVM_IRQ_ROUTING_MSI;
+ kroute.flags = 0;
+ kroute.u.msi.address_lo = (uint32_t)msg.address;
+ kroute.u.msi.address_hi = msg.address >> 32;
+ kroute.u.msi.data = msg.data;
+
+ kvm_add_routing_entry(s, &kroute);
+
+ return gsi;
+}
+
#else /* !KVM_CAP_IRQ_ROUTING */
static void kvm_init_irq_routing(KVMState *s)
@@ -1090,6 +1116,11 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
{
abort();
}
+
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+{
+ abort();
+}
#endif /* !KVM_CAP_IRQ_ROUTING */
static int kvm_irqchip_create(KVMState *s)
diff --git a/kvm-stub.c b/kvm-stub.c
index 47c573d..db3a7dc 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -12,10 +12,13 @@
#include "qemu-common.h"
#include "hw/hw.h"
+#include "hw/msi.h"
#include "cpu.h"
#include "gdbstub.h"
#include "kvm.h"
+KVMState *kvm_state;
+
int kvm_init_vcpu(CPUArchState *env)
{
return -ENOSYS;
@@ -128,3 +131,8 @@ int kvm_on_sigbus(int code, void *addr)
{
return 1;
}
+
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+{
+ return -ENOSYS;
+}
diff --git a/kvm.h b/kvm.h
index 8b061bd..67df1f1 100644
--- a/kvm.h
+++ b/kvm.h
@@ -44,6 +44,10 @@ typedef struct KVMCapabilityInfo {
#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
#define KVM_CAP_LAST_INFO { NULL, 0 }
+struct KVMState;
+typedef struct KVMState KVMState;
+extern KVMState *kvm_state;
+
/* external API */
int kvm_init(void);
@@ -88,10 +92,6 @@ int kvm_on_sigbus(int code, void *addr);
/* internal API */
-struct KVMState;
-typedef struct KVMState KVMState;
-extern KVMState *kvm_state;
-
int kvm_ioctl(KVMState *s, int type, ...);
int kvm_vm_ioctl(KVMState *s, int type, ...);
@@ -213,4 +213,6 @@ int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign,
uint32_t size);
int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
+
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
#endif
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 06/11] kvm: Publicize kvm_release_gsi as kvm_irqchip_release_virq
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (4 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 05/11] kvm: Introduce kvm_irqchip_add_msi_route Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 07/11] kvm: Make kvm_irqchip_commit_routes an internal service Jan Kiszka
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
This allows to drop routes created by kvm_irqchip_add_irq/msi_route
again.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
kvm-all.c | 8 ++++----
kvm-stub.c | 4 ++++
kvm.h | 1 +
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index f45b852..e3ffc91 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -955,19 +955,19 @@ int kvm_irqchip_commit_routes(KVMState *s)
return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
}
-static void kvm_release_gsi(KVMState *s, int gsi)
+void kvm_irqchip_release_virq(KVMState *s, int virq)
{
struct kvm_irq_routing_entry *e;
int i;
for (i = 0; i < s->irq_routes->nr; i++) {
e = &s->irq_routes->entries[i];
- if (e->gsi == gsi) {
+ if (e->gsi == virq) {
s->irq_routes->nr--;
*e = s->irq_routes->entries[s->irq_routes->nr];
}
}
- clear_gsi(s, gsi);
+ clear_gsi(s, virq);
}
static unsigned int kvm_hash_msi(uint32_t data)
@@ -984,7 +984,7 @@ static void kvm_flush_dynamic_msi_routes(KVMState *s)
for (hash = 0; hash < KVM_MSI_HASHTAB_SIZE; hash++) {
QTAILQ_FOREACH_SAFE(route, &s->msi_hashtab[hash], entry, next) {
- kvm_release_gsi(s, route->kroute.gsi);
+ kvm_irqchip_release_virq(s, route->kroute.gsi);
QTAILQ_REMOVE(&s->msi_hashtab[hash], route, entry);
g_free(route);
}
diff --git a/kvm-stub.c b/kvm-stub.c
index db3a7dc..ec351d9 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -136,3 +136,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
{
return -ENOSYS;
}
+
+void kvm_irqchip_release_virq(KVMState *s, int virq)
+{
+}
diff --git a/kvm.h b/kvm.h
index 67df1f1..1779e73 100644
--- a/kvm.h
+++ b/kvm.h
@@ -215,4 +215,5 @@ int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign,
int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
+void kvm_irqchip_release_virq(KVMState *s, int virq);
#endif
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 07/11] kvm: Make kvm_irqchip_commit_routes an internal service
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (5 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 06/11] kvm: Publicize kvm_release_gsi as kvm_irqchip_release_virq Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 08/11] kvm: Introduce kvm_irqchip_add/remove_irqfd Jan Kiszka
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Automatically commit route changes after kvm_add_routing_entry and
kvm_irqchip_release_virq. There is no performance relevant use case for
which collecting multiple route changes is beneficial. This makes
kvm_irqchip_commit_routes an internal service which assert()s that the
corresponding IOCTL will always succeed.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/pc_piix.c | 6 +-----
kvm-all.c | 26 ++++++++++++++------------
kvm.h | 1 -
3 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c17f906..044dfcb 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -56,7 +56,7 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
{
#ifdef CONFIG_KVM
KVMState *s = kvm_state;
- int ret, i;
+ int i;
if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
for (i = 0; i < 8; ++i) {
@@ -77,10 +77,6 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
}
}
}
- ret = kvm_irqchip_commit_routes(s);
- if (ret < 0) {
- hw_error("KVM IRQ routing setup failed");
- }
}
#endif /* CONFIG_KVM */
}
diff --git a/kvm-all.c b/kvm-all.c
index e3ffc91..24027a4 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -908,6 +908,15 @@ static void kvm_init_irq_routing(KVMState *s)
kvm_arch_init_irq_routing(s);
}
+static void kvm_irqchip_commit_routes(KVMState *s)
+{
+ int ret;
+
+ s->irq_routes->flags = 0;
+ ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
+ assert(ret == 0);
+}
+
static void kvm_add_routing_entry(KVMState *s,
struct kvm_irq_routing_entry *entry)
{
@@ -933,6 +942,8 @@ static void kvm_add_routing_entry(KVMState *s,
new->u = entry->u;
set_gsi(s, entry->gsi);
+
+ kvm_irqchip_commit_routes(s);
}
void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
@@ -949,12 +960,6 @@ void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
kvm_add_routing_entry(s, &e);
}
-int kvm_irqchip_commit_routes(KVMState *s)
-{
- s->irq_routes->flags = 0;
- return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
-}
-
void kvm_irqchip_release_virq(KVMState *s, int virq)
{
struct kvm_irq_routing_entry *e;
@@ -968,6 +973,8 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
}
}
clear_gsi(s, virq);
+
+ kvm_irqchip_commit_routes(s);
}
static unsigned int kvm_hash_msi(uint32_t data)
@@ -1049,7 +1056,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
route = kvm_lookup_msi_route(s, msg);
if (!route) {
- int gsi, ret;
+ int gsi;
gsi = kvm_get_pseudo_gsi(s);
if (gsi < 0) {
@@ -1068,11 +1075,6 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route,
entry);
-
- ret = kvm_irqchip_commit_routes(s);
- if (ret < 0) {
- return ret;
- }
}
assert(route->kroute.type == KVM_IRQ_ROUTING_MSI);
diff --git a/kvm.h b/kvm.h
index 1779e73..f0d0c53 100644
--- a/kvm.h
+++ b/kvm.h
@@ -135,7 +135,6 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
-int kvm_irqchip_commit_routes(KVMState *s);
void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 08/11] kvm: Introduce kvm_irqchip_add/remove_irqfd
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (6 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 07/11] kvm: Make kvm_irqchip_commit_routes an internal service Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 09/11] kvm: Enable use of kvm_irqchip_in_kernel in hwlib code Jan Kiszka
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Add services to associate an eventfd file descriptor as input with an
IRQ line as output. Such a line can be an input pin of an in-kernel
irqchip or a virtual line returned by kvm_irqchip_add_route.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
kvm-all.c | 30 ++++++++++++++++++++++++++++++
kvm-stub.c | 10 ++++++++++
kvm.h | 3 +++
3 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index 24027a4..4d2dbc6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1108,6 +1108,21 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
return gsi;
}
+static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
+{
+ struct kvm_irqfd irqfd = {
+ .fd = fd,
+ .gsi = virq,
+ .flags = assign ? 0 : KVM_IRQFD_FLAG_DEASSIGN,
+ };
+
+ if (!kvm_irqchip_in_kernel()) {
+ return -ENOSYS;
+ }
+
+ return kvm_vm_ioctl(s, KVM_IRQFD, &irqfd);
+}
+
#else /* !KVM_CAP_IRQ_ROUTING */
static void kvm_init_irq_routing(KVMState *s)
@@ -1123,8 +1138,23 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
{
abort();
}
+
+static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
+{
+ abort();
+}
#endif /* !KVM_CAP_IRQ_ROUTING */
+int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq)
+{
+ return kvm_irqchip_assign_irqfd(s, fd, virq, true);
+}
+
+int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq)
+{
+ return kvm_irqchip_assign_irqfd(s, fd, virq, false);
+}
+
static int kvm_irqchip_create(KVMState *s)
{
QemuOptsList *list = qemu_find_opts("machine");
diff --git a/kvm-stub.c b/kvm-stub.c
index ec351d9..b4cf03f 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -140,3 +140,13 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
void kvm_irqchip_release_virq(KVMState *s, int virq)
{
}
+
+int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq)
+{
+ return -ENOSYS;
+}
+
+int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq)
+{
+ return -ENOSYS;
+}
diff --git a/kvm.h b/kvm.h
index f0d0c53..9c7b0ea 100644
--- a/kvm.h
+++ b/kvm.h
@@ -215,4 +215,7 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
void kvm_irqchip_release_virq(KVMState *s, int virq);
+
+int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq);
+int kvm_irqchip_remove_irqfd(KVMState *s, int fd, int virq);
#endif
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 09/11] kvm: Enable use of kvm_irqchip_in_kernel in hwlib code
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (7 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 08/11] kvm: Introduce kvm_irqchip_add/remove_irqfd Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 10/11] msix: Add msix_nr_vectors_allocated Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 11/11] virtio/vhost: Add support for KVM in-kernel MSI injection Jan Kiszka
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Provide a dummy kvm_kernel_irqchip so that kvm_irqchip_in_kernel can be
used by code that is not under CONFIG_KVM protection.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
kvm-stub.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/kvm-stub.c b/kvm-stub.c
index b4cf03f..ec9a364 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -18,6 +18,7 @@
#include "kvm.h"
KVMState *kvm_state;
+bool kvm_kernel_irqchip;
int kvm_init_vcpu(CPUArchState *env)
{
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 10/11] msix: Add msix_nr_vectors_allocated
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (8 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 09/11] kvm: Enable use of kvm_irqchip_in_kernel in hwlib code Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 11/11] virtio/vhost: Add support for KVM in-kernel MSI injection Jan Kiszka
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Analogously to msi_nr_vectors_allocated, add a service for MSI-X. Will
be used by the virtio-pci layer.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/msix.c | 5 +++++
hw/msix.h | 2 ++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/hw/msix.c b/hw/msix.c
index c6968aa..2114b99 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -447,6 +447,11 @@ void msix_unuse_all_vectors(PCIDevice *dev)
msix_free_irq_entries(dev);
}
+unsigned int msix_nr_vectors_allocated(const PCIDevice *dev)
+{
+ return dev->msix_entries_nr;
+}
+
static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector)
{
MSIMessage msg;
diff --git a/hw/msix.h b/hw/msix.h
index f33f18b..50aee82 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -13,6 +13,8 @@ void msix_write_config(PCIDevice *pci_dev, uint32_t address,
int msix_uninit(PCIDevice *d, MemoryRegion *bar);
+unsigned int msix_nr_vectors_allocated(const PCIDevice *dev);
+
void msix_save(PCIDevice *dev, QEMUFile *f);
void msix_load(PCIDevice *dev, QEMUFile *f);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RFC][PATCH 11/11] virtio/vhost: Add support for KVM in-kernel MSI injection
2012-05-14 21:07 [Qemu-devel] [RFC][PATCH 00/11] uq/master: irqfd-based interrupt injection for virtio/vhost Jan Kiszka
` (9 preceding siblings ...)
2012-05-14 21:07 ` [Qemu-devel] [RFC][PATCH 10/11] msix: Add msix_nr_vectors_allocated Jan Kiszka
@ 2012-05-14 21:07 ` Jan Kiszka
10 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2012-05-14 21:07 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Michael S. Tsirkin
Make use of the new vector notifier to track changes of the MSI-X
configuration of virtio PCI devices. On enabling events, we establish
the required virtual IRQ to MSI-X message route and link the signaling
eventfd file descriptor to this vIRQ line. That way, vhost-generated
interrupts can be directly delivered to an in-kernel MSI-X consumer like
the x86 APIC.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
hw/virtio-pci.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/virtio-pci.h | 6 +++
2 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 4a4413d..01f5b92 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -24,6 +24,7 @@
#include "virtio-scsi.h"
#include "pci.h"
#include "qemu-error.h"
+#include "msi.h"
#include "msix.h"
#include "net.h"
#include "loader.h"
@@ -539,6 +540,107 @@ static void virtio_pci_guest_notifier_read(void *opaque)
}
}
+static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
+ unsigned int queue_no,
+ unsigned int vector,
+ MSIMessage msg)
+{
+ VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
+ VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+ int fd, ret;
+
+ fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vq));
+
+ if (irqfd->users == 0) {
+ ret = kvm_irqchip_add_msi_route(kvm_state, msg);
+ if (ret < 0) {
+ return ret;
+ }
+ irqfd->virq = ret;
+ }
+ irqfd->users++;
+
+ ret = kvm_irqchip_add_irqfd(kvm_state, fd, irqfd->virq);
+ if (ret < 0) {
+ if (--irqfd->users == 0) {
+ kvm_irqchip_release_virq(kvm_state, irqfd->virq);
+ }
+ return ret;
+ }
+
+ qemu_set_fd_handler(fd, NULL, NULL, NULL);
+
+ return 0;
+}
+
+static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
+ unsigned int queue_no,
+ unsigned int vector)
+{
+ VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
+ VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+ int fd, ret;
+
+ fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vq));
+
+ ret = kvm_irqchip_remove_irqfd(kvm_state, fd, irqfd->virq);
+ assert(ret == 0);
+
+ if (--irqfd->users == 0) {
+ kvm_irqchip_release_virq(kvm_state, irqfd->virq);
+ }
+
+ qemu_set_fd_handler(fd, virtio_pci_guest_notifier_read, NULL, vq);
+}
+
+static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
+ MSIMessage msg)
+{
+ VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+ VirtIODevice *vdev = proxy->vdev;
+ int ret, queue_no;
+
+ for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
+ if (!virtio_queue_get_num(vdev, queue_no)) {
+ break;
+ }
+ if (virtio_queue_vector(vdev, queue_no) != vector) {
+ continue;
+ }
+ ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
+ if (ret < 0) {
+ goto undo;
+ }
+ }
+ return 0;
+
+undo:
+ while (--queue_no >= 0) {
+ if (virtio_queue_vector(vdev, queue_no) != vector) {
+ continue;
+ }
+ kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
+ }
+ return ret;
+}
+
+static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
+{
+ VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
+ VirtIODevice *vdev = proxy->vdev;
+ int queue_no;
+
+ for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
+ if (!virtio_queue_get_num(vdev, queue_no)) {
+ break;
+ }
+ if (virtio_queue_vector(vdev, queue_no) != vector) {
+ continue;
+ }
+ kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
+ }
+}
+
static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
{
VirtIOPCIProxy *proxy = opaque;
@@ -555,6 +657,9 @@ static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
} else {
qemu_set_fd_handler(event_notifier_get_fd(notifier),
NULL, NULL, NULL);
+ /* Test and clear notifier before closing it,
+ * in case poll callback didn't have time to run. */
+ virtio_pci_guest_notifier_read(vq);
event_notifier_cleanup(notifier);
}
@@ -573,6 +678,13 @@ static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
VirtIODevice *vdev = proxy->vdev;
int r, n;
+ /* Must unset vector notifier while guest notifier is still assigned */
+ if (kvm_irqchip_in_kernel() && !assign) {
+ msix_unset_vector_notifiers(&proxy->pci_dev);
+ g_free(proxy->vector_irqfd);
+ proxy->vector_irqfd = NULL;
+ }
+
for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
if (!virtio_queue_get_num(vdev, n)) {
break;
@@ -584,10 +696,24 @@ static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
}
}
+ /* Must set vector notifier after guest notifier has been assigned */
+ if (kvm_irqchip_in_kernel() && assign) {
+ proxy->vector_irqfd =
+ g_malloc0(sizeof(*proxy->vector_irqfd) *
+ msix_nr_vectors_allocated(&proxy->pci_dev));
+ r = msix_set_vector_notifiers(&proxy->pci_dev,
+ kvm_virtio_pci_vector_use,
+ kvm_virtio_pci_vector_release);
+ if (r < 0) {
+ goto assign_error;
+ }
+ }
+
return 0;
assign_error:
/* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
+ assert(assign);
while (--n >= 0) {
virtio_pci_set_guest_notifier(opaque, n, !assign);
}
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index e560428..8d28d4b 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -25,6 +25,11 @@
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
typedef struct {
+ int virq;
+ unsigned int users;
+} VirtIOIRQFD;
+
+typedef struct {
PCIDevice pci_dev;
VirtIODevice *vdev;
MemoryRegion bar;
@@ -44,6 +49,7 @@ typedef struct {
VirtIOSCSIConf scsi;
bool ioeventfd_disabled;
bool ioeventfd_started;
+ VirtIOIRQFD *vector_irqfd;
} VirtIOPCIProxy;
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
--
1.7.3.4
^ permalink raw reply related [flat|nested] 13+ messages in thread