[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v7 23/25] kvm-irqchip: x86: add msi route notify fn
From: |
Peter Xu |
Subject: |
[Qemu-devel] [PATCH v7 23/25] kvm-irqchip: x86: add msi route notify fn |
Date: |
Tue, 17 May 2016 15:15:51 +0800 |
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.
Signed-off-by: Peter Xu <address@hidden>
---
hw/pci/pci.c | 15 +++++++++++++++
include/hw/pci/pci.h | 2 ++
kvm-all.c | 10 +---------
target-i386/kvm.c | 30 ++++++++++++++++++++++++++++++
trace-events | 1 +
5 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 7430715..ec1928f 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2527,6 +2527,21 @@ uint16_t pci_requester_id(PCIDevice *dev)
return result;
}
+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/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 351266c..359c22e 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -779,4 +779,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/kvm-all.c b/kvm-all.c
index a984564..95f1df3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1186,15 +1186,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 3092e37..f7a428e 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -37,6 +37,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"
@@ -3369,9 +3370,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) {
@@ -3388,6 +3406,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/trace-events b/trace-events
index e223f57..3d30aee 100644
--- a/trace-events
+++ b/trace-events
@@ -1913,3 +1913,4 @@ aspeed_vic_write(uint64_t offset, unsigned size, uint32_t
data) "To 0x%" PRIx64
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"
--
2.4.11
- [Qemu-devel] [PATCH v7 13/25] q35: ioapic: add support for emulated IOAPIC IR, (continued)
- [Qemu-devel] [PATCH v7 13/25] q35: ioapic: add support for emulated IOAPIC IR, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 14/25] ioapic: introduce ioapic_entry_parse() helper, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 15/25] intel_iommu: add support for split irqchip, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 17/25] x86-iommu: introduce IEC notifiers, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 16/25] q35: add "intremap" parameter to enable IR, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 19/25] intel_iommu: Add support for Extended Interrupt Mode, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 20/25] intel_iommu: add SID validation for IR, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 18/25] ioapic: register IOMMU IEC notifier for ioapic, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 21/25] kvm-irqchip: simplify kvm_irqchip_add_msi_route, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 22/25] kvm-irqchip: i386: add hook for add/remove virq, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 23/25] kvm-irqchip: x86: add msi route notify fn,
Peter Xu <=
- [Qemu-devel] [PATCH v7 25/25] intel_iommu: support all masks in interrupt entry cache invalidation, Peter Xu, 2016/05/17
- [Qemu-devel] [PATCH v7 24/25] kvm-irqchip: do explicit commit when update irq, Peter Xu, 2016/05/17
- Re: [Qemu-devel] [PATCH v7 00/25] IOMMU: Enable interrupt remapping for Intel IOMMU, Peter Xu, 2016/05/17