From patchwork Fri Nov 18 01:57:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wu, Feng" X-Patchwork-Id: 9435671 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 3521F60238 for ; Fri, 18 Nov 2016 02:32:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 294E02972B for ; Fri, 18 Nov 2016 02:32:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1E39C29732; Fri, 18 Nov 2016 02:32:52 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 02C0929735 for ; Fri, 18 Nov 2016 02:32:51 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c7Ywg-00046B-6A; Fri, 18 Nov 2016 02:30:30 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c7Ywe-00045e-KN for xen-devel@lists.xen.org; Fri, 18 Nov 2016 02:30:28 +0000 Received: from [193.109.254.147] by server-1.bemta-6.messagelabs.com id 16/2E-22836-3C76E285; Fri, 18 Nov 2016 02:30:27 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrPLMWRWlGSWpSXmKPExsVywNykWPdwul6 EwZYp3BZLPi5mcWD0OLr7N1MAYxRrZl5SfkUCa8a52XMZC066V+w6coatgXGmWRcjJ4eQQKXE y+sTmEFsCQFeiSPLZrBC2AESl/Z2MHYxcgHV9DFKbJ71nA0kwSagKHHw4iGwIhEBaYlrny+DF TELLGCUaLx4FGySsECYxOJZf1hAbBYBVYlbs1aBNfAKOErc3nMDapucxIbd/xlBbE4BJ4njq2 +zQFzkKLF/6geWCYy8CxgZVjFqFKcWlaUW6Roa6SUVZaZnlOQmZuboGhqY6eWmFhcnpqfmJCY V6yXn525iBAYEAxDsYLy8MeAQoyQHk5Iob3u0XoQQX1J+SmVGYnFGfFFpTmrxIUYZDg4lCd5P aUA5waLU9NSKtMwcYGjCpCU4eJREeG+kAqV5iwsSc4sz0yFSpxgVpcR5e0D6BEASGaV5cG2we LjEKCslzMsIdIgQT0FqUW5mCar8K0ZxDkYlYd4tIFN4MvNK4Ka/AlrMBLR4j4AOyOKSRISUVA PjlpRXXh/39bOfv1/aEHHkUFdq6pSIc1/mXa7Umn3Shvdjg3DA73yDoxw85yMsxLd91Z99+Ya jy0/5Ds3kNeejHi53DtzO2lIok7Rdq1hTr19lbY3YVf5X7ZdWK4sETmrrNpz03feiabaY+3ZL 3p3BeWZhVrq2N9pSVBgfTJP1F1RZnJK7zkGJpTgj0VCLuag4EQC83H6nggIAAA== X-Env-Sender: feng.wu@intel.com X-Msg-Ref: server-14.tower-27.messagelabs.com!1479436221!60052313!4 X-Originating-IP: [192.55.52.115] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.0.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 58866 invoked from network); 18 Nov 2016 02:30:26 -0000 Received: from mga14.intel.com (HELO mga14.intel.com) (192.55.52.115) by server-14.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 18 Nov 2016 02:30:26 -0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 17 Nov 2016 18:30:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.31,655,1473145200"; d="scan'208"; a="1070084861" Received: from unknown (HELO feng-bdw-de-pi.bj.intel.com) ([10.238.154.55]) by fmsmga001.fm.intel.com with ESMTP; 17 Nov 2016 18:30:22 -0800 From: Feng Wu To: xen-devel@lists.xen.org Date: Fri, 18 Nov 2016 09:57:21 +0800 Message-Id: <1479434244-10223-5-git-send-email-feng.wu@intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1479434244-10223-1-git-send-email-feng.wu@intel.com> References: <1479434244-10223-1-git-send-email-feng.wu@intel.com> Cc: kevin.tian@intel.com, Feng Wu , george.dunlap@eu.citrix.com, andrew.cooper3@citrix.com, dario.faggioli@citrix.com, jbeulich@suse.com Subject: [Xen-devel] [PATCH v8 4/7] VT-d: Use one function to update both remapped and posted IRTE X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Use one function to update both remapped IRTE and posted IRET. Signed-off-by: Feng Wu --- v8: - Newly added xen/drivers/passthrough/vtd/intremap.c | 162 ++++++++++++++------------------- 1 file changed, 66 insertions(+), 96 deletions(-) diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c index bfd468b..fd2a49a 100644 --- a/xen/drivers/passthrough/vtd/intremap.c +++ b/xen/drivers/passthrough/vtd/intremap.c @@ -420,7 +420,7 @@ void io_apic_write_remap_rte( __ioapic_write_entry(apic, ioapic_pin, 1, old_rte); } -static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire) +static void set_msi_source_id(const struct pci_dev *pdev, struct iremap_entry *ire) { u16 seg; u8 bus, devfn, secbus; @@ -548,11 +548,12 @@ static int remap_entry_to_msi_msg( } static int msi_msg_to_remap_entry( - struct iommu *iommu, struct pci_dev *pdev, - struct msi_desc *msi_desc, struct msi_msg *msg) + struct iommu *iommu, const struct pci_dev *pdev, + struct msi_desc *msi_desc, struct msi_msg *msg, + const struct pi_desc *pi_desc, const uint8_t gvec) { struct iremap_entry *iremap_entry = NULL, *iremap_entries; - struct iremap_entry new_ire; + struct iremap_entry new_ire, old_ire; struct msi_msg_remap_entry *remap_rte; unsigned int index, i, nr = 1; unsigned long flags; @@ -597,31 +598,50 @@ static int msi_msg_to_remap_entry( memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry)); - /* Set interrupt remapping table entry */ - new_ire.remap.fpd = 0; - new_ire.remap.dm = (msg->address_lo >> MSI_ADDR_DESTMODE_SHIFT) & 0x1; - new_ire.remap.tm = (msg->data >> MSI_DATA_TRIGGER_SHIFT) & 0x1; - new_ire.remap.dlm = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x1; - /* Hardware require RH = 1 for LPR delivery mode */ - new_ire.remap.rh = (new_ire.remap.dlm == dest_LowestPrio); - new_ire.remap.avail = 0; - new_ire.remap.res_1 = 0; - new_ire.remap.vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & - MSI_DATA_VECTOR_MASK; - new_ire.remap.res_2 = 0; - if ( x2apic_enabled ) - new_ire.remap.dst = msg->dest32; + if ( !pi_desc ) + { + /* Set interrupt remapping table entry */ + new_ire.remap.fpd = 0; + new_ire.remap.dm = (msg->address_lo >> MSI_ADDR_DESTMODE_SHIFT) & 0x1; + new_ire.remap.tm = (msg->data >> MSI_DATA_TRIGGER_SHIFT) & 0x1; + new_ire.remap.dlm = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x1; + /* Hardware require RH = 1 for LPR delivery mode */ + new_ire.remap.rh = (new_ire.remap.dlm == dest_LowestPrio); + new_ire.remap.avail = 0; + new_ire.remap.res_1 = 0; + new_ire.remap.vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & + MSI_DATA_VECTOR_MASK; + new_ire.remap.res_2 = 0; + if ( x2apic_enabled ) + new_ire.remap.dst = msg->dest32; + else + new_ire.remap.dst = ((msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) + & 0xff) << 8; + + new_ire.remap.res_3 = 0; + new_ire.remap.res_4 = 0; + new_ire.remap.p = 1; /* finally, set present bit */ + } else - new_ire.remap.dst = ((msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) - & 0xff) << 8; + { + new_ire.post.fpd = 0; + new_ire.post.res_1 = 0; + new_ire.post.res_2 = 0; + new_ire.post.urg = 0; + new_ire.post.im = 1; + new_ire.post.vector = gvec; + new_ire.post.res_3 = 0; + new_ire.post.res_4 = 0; + new_ire.post.res_5 = 0; + new_ire.post.pda_l = virt_to_maddr(pi_desc) >> (32 - PDA_LOW_BIT); + new_ire.post.pda_h = virt_to_maddr(pi_desc) >> 32; + new_ire.post.p = 1; /* finally, set present bit */ + } if ( pdev ) set_msi_source_id(pdev, &new_ire); else set_hpet_source_id(msi_desc->hpet_id, &new_ire); - new_ire.remap.res_3 = 0; - new_ire.remap.res_4 = 0; - new_ire.remap.p = 1; /* finally, set present bit */ /* now construct new MSI/MSI-X rte entry */ remap_rte = (struct msi_msg_remap_entry *)msg; @@ -637,7 +657,23 @@ static int msi_msg_to_remap_entry( remap_rte->address_hi = 0; remap_rte->data = index - i; - memcpy(iremap_entry, &new_ire, sizeof(struct iremap_entry)); + if ( !pi_desc ) + memcpy(iremap_entry, &new_ire, sizeof(struct iremap_entry)); + else + { + __uint128_t ret; + + old_ire = *iremap_entry; + ret = cmpxchg16b(iremap_entry, &old_ire, &new_ire); + + /* + * In the above, we use cmpxchg16 to atomically update the 128-bit IRTE, + * and the hardware cannot update the IRTE behind us, so the return value + * of cmpxchg16 should be the same as old_ire. This ASSERT validate it. + */ + ASSERT(ret == old_ire.val); + } + iommu_flush_cache_entry(iremap_entry, sizeof(struct iremap_entry)); iommu_flush_iec_index(iommu, 0, index); @@ -668,7 +704,8 @@ int msi_msg_write_remap_rte( drhd = pdev ? acpi_find_matched_drhd_unit(pdev) : hpet_to_drhd(msi_desc->hpet_id); - return drhd ? msi_msg_to_remap_entry(drhd->iommu, pdev, msi_desc, msg) + return drhd ? msi_msg_to_remap_entry(drhd->iommu, pdev, + msi_desc, msg, NULL, 0) : -EINVAL; } @@ -902,42 +939,6 @@ void iommu_disable_x2apic_IR(void) disable_qinval(drhd->iommu); } -static void setup_posted_irte( - struct iremap_entry *new_ire, const struct iremap_entry *old_ire, - const struct pi_desc *pi_desc, const uint8_t gvec) -{ - memset(new_ire, 0, sizeof(*new_ire)); - - /* - * 'im' filed decides whether the irte is in posted format (with value 1) - * or remapped format (with value 0), if the old irte is in remapped format, - * we copy things from remapped part in 'struct iremap_entry', otherwise, - * we copy from posted part. - */ - if ( !old_ire->remap.im ) - { - new_ire->post.p = old_ire->remap.p; - new_ire->post.fpd = old_ire->remap.fpd; - new_ire->post.sid = old_ire->remap.sid; - new_ire->post.sq = old_ire->remap.sq; - new_ire->post.svt = old_ire->remap.svt; - } - else - { - new_ire->post.p = old_ire->post.p; - new_ire->post.fpd = old_ire->post.fpd; - new_ire->post.sid = old_ire->post.sid; - new_ire->post.sq = old_ire->post.sq; - new_ire->post.svt = old_ire->post.svt; - new_ire->post.urg = old_ire->post.urg; - } - - new_ire->post.im = 1; - new_ire->post.vector = gvec; - new_ire->post.pda_l = virt_to_maddr(pi_desc) >> (32 - PDA_LOW_BIT); - new_ire->post.pda_h = virt_to_maddr(pi_desc) >> 32; -} - /* * This function is used to update the IRTE for posted-interrupt * when guest changes MSI/MSI-X information. @@ -946,17 +947,12 @@ int pi_update_irte(const struct vcpu *v, const struct pirq *pirq, const uint8_t gvec) { struct irq_desc *desc; - const struct msi_desc *msi_desc; - int remap_index; + struct msi_desc *msi_desc; int rc = 0; const struct pci_dev *pci_dev; const struct acpi_drhd_unit *drhd; struct iommu *iommu; - struct ir_ctrl *ir_ctrl; - struct iremap_entry *iremap_entries = NULL, *p = NULL; - struct iremap_entry new_ire, old_ire; const struct pi_desc *pi_desc = &v->arch.hvm_vmx.pi_desc; - __uint128_t ret; desc = pirq_spin_lock_irq_desc(pirq, NULL); if ( !desc ) @@ -976,8 +972,6 @@ int pi_update_irte(const struct vcpu *v, const struct pirq *pirq, goto unlock_out; } - remap_index = msi_desc->remap_index; - spin_unlock_irq(&desc->lock); ASSERT(pcidevs_locked()); @@ -992,35 +986,11 @@ int pi_update_irte(const struct vcpu *v, const struct pirq *pirq, return -ENODEV; iommu = drhd->iommu; - ir_ctrl = iommu_ir_ctrl(iommu); - if ( !ir_ctrl ) + if ( !iommu_ir_ctrl(iommu) ) return -ENODEV; - spin_lock_irq(&ir_ctrl->iremap_lock); - - GET_IREMAP_ENTRY(ir_ctrl->iremap_maddr, remap_index, iremap_entries, p); - - old_ire = *p; - - /* Setup/Update interrupt remapping table entry. */ - setup_posted_irte(&new_ire, &old_ire, pi_desc, gvec); - ret = cmpxchg16b(p, &old_ire, &new_ire); - - /* - * In the above, we use cmpxchg16 to atomically update the 128-bit IRTE, - * and the hardware cannot update the IRTE behind us, so the return value - * of cmpxchg16 should be the same as old_ire. This ASSERT validate it. - */ - ASSERT(ret == old_ire.val); - - iommu_flush_cache_entry(p, sizeof(*p)); - iommu_flush_iec_index(iommu, 0, remap_index); - - unmap_vtd_domain_page(iremap_entries); - - spin_unlock_irq(&ir_ctrl->iremap_lock); - - return 0; + return msi_msg_to_remap_entry(iommu, pci_dev, msi_desc, &msi_desc->msg, + pi_desc, gvec); unlock_out: spin_unlock_irq(&desc->lock);