From patchwork Tue Jul 19 17:53:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 9237959 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6617D602F0 for ; Tue, 19 Jul 2016 17:55:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5D63926C2F for ; Tue, 19 Jul 2016 17:55:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 523B4275A2; Tue, 19 Jul 2016 17:55:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CD85D26C2F for ; Tue, 19 Jul 2016 17:55:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753526AbcGSRxm (ORCPT ); Tue, 19 Jul 2016 13:53:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40348 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753475AbcGSRxi (ORCPT ); Tue, 19 Jul 2016 13:53:38 -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 22E8C6439A; Tue, 19 Jul 2016 17:53:38 +0000 (UTC) Received: from redhat.com (vpn1-7-82.ams2.redhat.com [10.36.7.82]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id u6JHrWG6021735; Tue, 19 Jul 2016 13:53:33 -0400 Date: Tue, 19 Jul 2016 20:53:31 +0300 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Cc: Peter Maydell , Peter Xu , Paolo Bonzini , Marcel Apfelbaum , Marcelo Tosatti , Richard Henderson , Eduardo Habkost , kvm@vger.kernel.org Subject: [PULL v2 31/55] kvm-irqchip: x86: add msi route notify fn Message-ID: <20160719175331.GA351@redhat.com> References: <1468950176-31959-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1468950176-31959-1-git-send-email-mst@redhat.com> X-Mutt-Fcc: =sent 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.39]); Tue, 19 Jul 2016 17:53:38 +0000 (UTC) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Peter Xu 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 [move trace-events lines into target-i386/trace-events] Signed-off-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- 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"