From patchwork Mon Jun 13 13:09:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Xu X-Patchwork-Id: 634651 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rSv5f23Wlz9sxb for ; Mon, 13 Jun 2016 23:39:34 +1000 (AEST) Received: from localhost ([::1]:56550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCS5U-0000VA-68 for incoming@patchwork.ozlabs.org; Mon, 13 Jun 2016 09:39:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49036) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCRf0-0000zV-Um for qemu-devel@nongnu.org; Mon, 13 Jun 2016 09:12:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCRey-0000U3-Fy for qemu-devel@nongnu.org; Mon, 13 Jun 2016 09:12:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42574) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCRey-0000Tq-74 for qemu-devel@nongnu.org; Mon, 13 Jun 2016 09:12:08 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D954880F6D; Mon, 13 Jun 2016 13:12:07 +0000 (UTC) Received: from pxdev.xzpeter.org (vpn1-6-63.pek2.redhat.com [10.72.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u5DD9iRa025046; Mon, 13 Jun 2016 09:12:02 -0400 From: Peter Xu To: qemu-devel@nongnu.org Date: Mon, 13 Jun 2016 21:09:39 +0800 Message-Id: <1465823381-23602-24-git-send-email-peterx@redhat.com> In-Reply-To: <1465823381-23602-1-git-send-email-peterx@redhat.com> References: <1465823381-23602-1-git-send-email-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 13 Jun 2016 13:12:07 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v9 23/25] kvm-irqchip: x86: add msi route notify fn X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, jasowang@redhat.com, rkrcmar@redhat.com, peterx@redhat.com, alex.williamson@redhat.com, jan.kiszka@web.de, wexu@redhat.com, pbonzini@redhat.com, marcel@redhat.com, imammedo@redhat.com, davidkiarie4@gmail.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 --- 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 f3a4604..1261bf8 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2553,6 +2553,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 fd42934..e608967 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -786,4 +786,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 00c680d..9420e01 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1247,15 +1247,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 2ab19f6..ff167ab 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" @@ -3362,9 +3363,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) { @@ -3381,6 +3399,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 99199dc..1d1953d 100644 --- a/trace-events +++ b/trace-events @@ -2168,3 +2168,4 @@ e1000e_vm_state_stopped(void) "VM state is stopped" 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"