From patchwork Mon Nov 10 06:31:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wu, Feng" X-Patchwork-Id: 5264221 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D74B39F3ED for ; Mon, 10 Nov 2014 06:40:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CE98420166 for ; Mon, 10 Nov 2014 06:40:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C85292015D for ; Mon, 10 Nov 2014 06:40:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752276AbaKJGkL (ORCPT ); Mon, 10 Nov 2014 01:40:11 -0500 Received: from mga09.intel.com ([134.134.136.24]:53495 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752272AbaKJGkJ (ORCPT ); Mon, 10 Nov 2014 01:40:09 -0500 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 09 Nov 2014 22:38:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,351,1413270000"; d="scan'208";a="605136303" Received: from unknown (HELO wf-hsw-desktop.bj.intel.com) ([10.238.154.53]) by orsmga001.jf.intel.com with ESMTP; 09 Nov 2014 22:40:05 -0800 From: Feng Wu To: pbonzini@redhat.com, rth@twiddle.net, mtosatti@redhat.com Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, Feng Wu Subject: [PATCH] x86: Update VT-d Posted-Interrupts related information Date: Mon, 10 Nov 2014 14:31:17 +0800 Message-Id: <1415601077-27890-2-git-send-email-feng.wu@intel.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1415601077-27890-1-git-send-email-feng.wu@intel.com> References: <1415601077-27890-1-git-send-email-feng.wu@intel.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP VT-d Posted-Interrupts(PI) is an enhancement to CPU side Posted-Interrupt. With VT-d Posted-Interrupts enabled, external interrupts from direct-assigned devices can be delivered to guests without VMM involvement when guest is running in non-root mode. If VT-d PI is supported by KVM, we need to update the IRTE with the new guest interrtup configuration. Signed-off-by: Feng Wu --- hw/i386/kvm/pci-assign.c | 24 ++++++++++++++++++++++++ linux-headers/linux/kvm.h | 2 ++ target-i386/kvm.c | 5 +++++ target-i386/kvm_i386.h | 1 + 4 files changed, 32 insertions(+), 0 deletions(-) diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index bb206da..e55a99b 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -1005,6 +1005,12 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev) assigned_dev->intx_route.mode = PCI_INTX_DISABLED; assigned_dev->intx_route.irq = -1; assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSI; + + if (kvm_check_extension(kvm_state, KVM_CAP_PI)) { + if (kvm_device_pi_update(kvm_state, assigned_dev->dev_id) < 0) { + perror("assigned_dev_update_msi: kvm_device_pi_update"); + } + } } else { Error *local_err = NULL; @@ -1029,6 +1035,12 @@ static void assigned_dev_update_msi_msg(PCIDevice *pci_dev) kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0], msi_get_message(pci_dev, 0)); + + if (kvm_check_extension(kvm_state, KVM_CAP_PI)) { + if (kvm_device_pi_update(kvm_state, assigned_dev->dev_id) < 0) { + perror("assigned_dev_update_msi_msg: kvm_device_pi_update"); + } + } } static bool assigned_dev_msix_masked(MSIXTableEntry *entry) @@ -1149,6 +1161,12 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev) perror("assigned_dev_enable_msix: assign irq"); return; } + + if (kvm_check_extension(kvm_state, KVM_CAP_PI)) { + if (kvm_device_pi_update(kvm_state, assigned_dev->dev_id) < 0) { + perror("assigned_dev_update_msix: kvm_device_pi_update"); + } + } } assigned_dev->intx_route.mode = PCI_INTX_DISABLED; assigned_dev->intx_route.irq = -1; @@ -1618,6 +1636,12 @@ static void assigned_dev_msix_mmio_write(void *opaque, hwaddr addr, if (ret) { error_report("Error updating irq routing entry (%d)", ret); } + if (kvm_check_extension(kvm_state, KVM_CAP_PI)) { + if (kvm_device_pi_update(kvm_state, adev->dev_id) < 0) { + perror("assigned_dev_update_msi_msg: " + "kvm_device_pi_update"); + } + } } } } diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 2669938..b34f3c4 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -765,6 +765,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_PPC_FIXUP_HCALL 103 #define KVM_CAP_PPC_ENABLE_HCALL 104 #define KVM_CAP_CHECK_EXTENSION_VM 105 +#define KVM_CAP_PI 106 #ifdef KVM_CAP_IRQ_ROUTING @@ -1020,6 +1021,7 @@ struct kvm_s390_ucas_mapping { #define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config) #define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data) #define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data) +#define KVM_ASSIGN_DEV_PI_UPDATE _IOR(KVMIO, 0x7d, __u32) /* Available with KVM_CAP_PIT_STATE2 */ #define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2) #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ccf36e8..3dd8e5e 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -2660,6 +2660,11 @@ int kvm_device_msi_assign(KVMState *s, uint32_t dev_id, int virq) KVM_DEV_IRQ_GUEST_MSI, virq); } +int kvm_device_pi_update(KVMState *s, uint32_t dev_id) +{ + return kvm_vm_ioctl(s, KVM_ASSIGN_DEV_PI_UPDATE, &dev_id); +} + int kvm_device_msi_deassign(KVMState *s, uint32_t dev_id) { return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSI | diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h index cac30fd..c119b3e 100644 --- a/target-i386/kvm_i386.h +++ b/target-i386/kvm_i386.h @@ -37,4 +37,5 @@ int kvm_device_msix_set_vector(KVMState *s, uint32_t dev_id, uint32_t vector, int kvm_device_msix_assign(KVMState *s, uint32_t dev_id); int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id); +int kvm_device_pi_update(KVMState *s, uint32_t dev_id); #endif