[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL v2 31/55] kvm-irqchip: x86: add msi route notify fn
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PULL v2 31/55] kvm-irqchip: x86: add msi route notify fn |
Date: |
Tue, 19 Jul 2016 20:53:31 +0300 |
From: Peter Xu <address@hidden>
One more IEC notifier is added to let msi routes know about the IEC
changes. When interrupt invalidation happens, all registered msi routes
will be updated for all PCI devices.
Since both vfio and vhost are possible gsi route consumers, this patch
will go one step further to keep them safe in split irqchip mode and
when irqfd is enabled.
Reviewed-by: Paolo Bonzini <address@hidden>
[move trace-events lines into target-i386/trace-events]
Signed-off-by: Peter Xu <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
include/hw/pci/pci.h | 2 ++
hw/pci/pci.c | 15 +++++++++++++++
kvm-all.c | 10 +---------
target-i386/kvm.c | 30 ++++++++++++++++++++++++++++++
target-i386/trace-events | 1 +
5 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 9ed1624..74d797d 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -805,4 +805,6 @@ extern const VMStateDescription vmstate_pci_device;
.offset = vmstate_offset_pointer(_state, _field, PCIDevice), \
}
+MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
+
#endif
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 149994b..728c6d4 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2596,6 +2596,21 @@ PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
}
}
+MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
+{
+ MSIMessage msg;
+ if (msix_enabled(dev)) {
+ msg = msix_get_message(dev, vector);
+ } else if (msi_enabled(dev)) {
+ msg = msi_get_message(dev, vector);
+ } else {
+ /* Should never happen */
+ error_report("%s: unknown interrupt type", __func__);
+ abort();
+ }
+ return msg;
+}
+
static const TypeInfo pci_device_type_info = {
.name = TYPE_PCI_DEVICE,
.parent = TYPE_DEVICE,
diff --git a/kvm-all.c b/kvm-all.c
index 69ff658..ca30a58 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1246,15 +1246,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, int vector,
PCIDevice *dev)
MSIMessage msg = {0, 0};
if (dev) {
- if (msix_enabled(dev)) {
- msg = msix_get_message(dev, vector);
- } else if (msi_enabled(dev)) {
- msg = msi_get_message(dev, vector);
- } else {
- /* Should never happen */
- error_report("%s: unknown interrupt type", __func__);
- abort();
- }
+ msg = pci_get_msi_message(dev, vector);
}
if (kvm_gsi_direct_mapping()) {
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 8875034..61f57f9 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -36,6 +36,7 @@
#include "hw/i386/apic_internal.h"
#include "hw/i386/apic-msidef.h"
#include "hw/i386/intel_iommu.h"
+#include "hw/i386/x86-iommu.h"
#include "exec/ioport.h"
#include "standard-headers/asm-x86/hyperv.h"
@@ -3413,9 +3414,26 @@ struct MSIRouteEntry {
static QLIST_HEAD(, MSIRouteEntry) msi_route_list = \
QLIST_HEAD_INITIALIZER(msi_route_list);
+static void kvm_update_msi_routes_all(void *private, bool global,
+ uint32_t index, uint32_t mask)
+{
+ int cnt = 0;
+ MSIRouteEntry *entry;
+ MSIMessage msg;
+ /* TODO: explicit route update */
+ QLIST_FOREACH(entry, &msi_route_list, list) {
+ cnt++;
+ msg = pci_get_msi_message(entry->dev, entry->vector);
+ kvm_irqchip_update_msi_route(kvm_state, entry->virq,
+ msg, entry->dev);
+ }
+ trace_kvm_x86_update_msi_routes(cnt);
+}
+
int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
int vector, PCIDevice *dev)
{
+ static bool notify_list_inited = false;
MSIRouteEntry *entry;
if (!dev) {
@@ -3432,6 +3450,18 @@ int kvm_arch_add_msi_route_post(struct
kvm_irq_routing_entry *route,
QLIST_INSERT_HEAD(&msi_route_list, entry, list);
trace_kvm_x86_add_msi_route(route->gsi);
+
+ if (!notify_list_inited) {
+ /* For the first time we do add route, add ourselves into
+ * IOMMU's IEC notify list if needed. */
+ X86IOMMUState *iommu = x86_iommu_get_default();
+ if (iommu) {
+ x86_iommu_iec_register_notifier(iommu,
+ kvm_update_msi_routes_all,
+ NULL);
+ }
+ notify_list_inited = true;
+ }
return 0;
}
diff --git a/target-i386/trace-events b/target-i386/trace-events
index 818058c..ccc49e3 100644
--- a/target-i386/trace-events
+++ b/target-i386/trace-events
@@ -4,3 +4,4 @@
kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI
%" PRIu32
kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
+kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
--
MST
- [Qemu-devel] [PULL v2 21/55] intel_iommu: Add support for PCI MSI remap, (continued)
- [Qemu-devel] [PULL v2 21/55] intel_iommu: Add support for PCI MSI remap, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 22/55] q35: ioapic: add support for emulated IOAPIC IR, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 23/55] ioapic: introduce ioapic_entry_parse() helper, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 24/55] intel_iommu: add support for split irqchip, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 25/55] x86-iommu: introduce IEC notifiers, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 26/55] ioapic: register IOMMU IEC notifier for ioapic, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 27/55] intel_iommu: Add support for Extended Interrupt Mode, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 28/55] intel_iommu: add SID validation for IR, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 29/55] kvm-irqchip: simplify kvm_irqchip_add_msi_route, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 30/55] kvm-irqchip: i386: add hook for add/remove virq, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 31/55] kvm-irqchip: x86: add msi route notify fn,
Michael S. Tsirkin <=
- [Qemu-devel] [PULL v2 32/55] kvm-irqchip: do explicit commit when update irq, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 33/55] intel_iommu: support all masks in interrupt entry cache invalidation, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 34/55] kvm-all: add trace events for kvm irqchip ops, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 35/55] intel_iommu: disallow kernel-irqchip=on with IR, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 36/55] virtio: Add typedef for handle_output, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 37/55] virtio: Introduce virtio_add_queue_aio, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 38/55] virtio-blk: Call virtio_add_queue_aio, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 39/55] virtio-scsi: Call virtio_add_queue_aio, Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 40/55] Revert "mirror: Workaround for unexpected iohandler events during completion", Michael S. Tsirkin, 2016/07/19
- [Qemu-devel] [PULL v2 41/55] virtio-scsi: Replace HandleOutput typedef, Michael S. Tsirkin, 2016/07/19