From patchwork Thu Apr 28 09:50:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 8967541 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 824B0BF29F for ; Thu, 28 Apr 2016 09:52:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 88A6C202A1 for ; Thu, 28 Apr 2016 09:52:34 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id A4A7D202D1 for ; Thu, 28 Apr 2016 09:52:28 +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 1aviab-0005el-7C; Thu, 28 Apr 2016 09:50:29 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aviaa-0005eE-7M for xen-devel@lists.xenproject.org; Thu, 28 Apr 2016 09:50:28 +0000 Received: from [85.158.137.68] by server-12.bemta-3.messagelabs.com id A4/C4-19343-3ECD1275; Thu, 28 Apr 2016 09:50:27 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrFIsWRWlGSWpSXmKPExsXS6fjDS/fRHcV wg/VPLCy+b5nM5MDocfjDFZYAxijWzLyk/IoE1oyr3/6xF3y1rfj5+D1rA2OjbhcjJ4eQQJ7E vBf3WUFsXgE7iYPPrrCA2BIChhL75q9i62Lk4GARUJV4tQ6snE1AXaLt2XZWkLCIgIHEuaNJI GFmgSiJvuVXmUBsYQETif979rBDTLeTuHXuEjtIOaeAvcSlyREgJq+AoMTfHcIQnXYSN3dvZJ /AyDMLITMLSQbC1pJ4+OsWC4StLbFs4WtmkHJmAWmJ5f84IMJOEg/2HmRGVQJi+0os7+phWsD IsYpRvTi1qCy1SNdQL6koMz2jJDcxM0fX0MBYLze1uDgxPTUnMalYLzk/dxMjMEwZgGAH4/KP TocYJTmYlER5uw4phgvxJeWnVGYkFmfEF5XmpBYfYpTh4FCS4P1/GygnWJSanlqRlpkDjBiYt AQHj5IIb8ItoDRvcUFibnFmOkTqFKOilDgvHzDOhARAEhmleXBtsCi9xCgrJczLCHSIEE9Bal FuZgmq/CtGcQ5GJWHeMyDbeTLzSuCmvwJazAS0WGAT2OKSRISUVAPjonMv9Vln7mo3+1oas45 rK4/91kVfbuh2cu2a5l2tof3XcXdWxJ9jO1fOTz3cfmXxrsUXMwNbe2eG3vqp8kJy1YHZou9n GOlqVifNsLu2wqxIWfy3mj/jteC1xQvv8T2uqD6+qnPp/bgVT5qnpL4oz/1Qtsu9gStPuyB1Z tMHPf10Z+9tbe6cSizFGYmGWsxFxYkAPma+r80CAAA= X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-14.tower-31.messagelabs.com!1461837025!37418586!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.34; banners=-,-,- X-VirusChecked: Checked Received: (qmail 49339 invoked from network); 28 Apr 2016 09:50:26 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-14.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 28 Apr 2016 09:50:26 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Thu, 28 Apr 2016 03:50:24 -0600 Message-Id: <5721F90402000078000E6B1B@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Thu, 28 Apr 2016 03:50:28 -0600 From: "Jan Beulich" To: "xen-devel" References: <5721F57C02000078000E6ACE@prv-mh.provo.novell.com> In-Reply-To: <5721F57C02000078000E6ACE@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Andrew Cooper , Paul Durrant Subject: [Xen-devel] [PATCH 3/3] x86/vMSI-X: also snoop REP MOVS 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: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 ... as at least certain versions of Windows use such to update the MSI-X table. However, to not overly complicate the logic for now - only EFLAGS.DF=0 is being handled, - only updates not crossing MSI-X table entry boundaries are handled. Signed-off-by: Jan Beulich x86/vMSI-X: also snoop REP MOVS ... as at least certain versions of Windows use such to update the MSI-X table. However, to not overly complicate the logic for now - only EFLAGS.DF=0 is being handled, - only updates not crossing MSI-X table entry boundaries are handled. Signed-off-by: Jan Beulich --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -351,9 +351,10 @@ static int msixtbl_range(struct vcpu *v, ASSERT(r->type == IOREQ_TYPE_COPY); if ( r->dir == IOREQ_WRITE ) { + unsigned int size = r->size; + if ( !r->data_is_ptr ) { - unsigned int size = r->size; uint64_t data = r->data; if ( size == 8 ) @@ -366,7 +367,22 @@ static int msixtbl_range(struct vcpu *v, ((addr & (PCI_MSIX_ENTRY_SIZE - 1)) == PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) && !(data & PCI_MSIX_VECTOR_BITMASK) ) + { v->arch.hvm_vcpu.hvm_io.msix_snoop_address = addr; + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa = 0; + } + } + else if ( (size == 4 || size == 8) && !r->df && + r->count && r->count <= PCI_MSIX_ENTRY_SIZE / size && + !((addr + (size * r->count)) & (PCI_MSIX_ENTRY_SIZE - 1)) ) + { + BUILD_BUG_ON((PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET + 4) & + (PCI_MSIX_ENTRY_SIZE - 1)); + + v->arch.hvm_vcpu.hvm_io.msix_snoop_address = + addr + size * r->count - 4; + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa = + r->data + size * r->count - 4; } } @@ -471,6 +487,7 @@ out: for_each_vcpu ( d, v ) { if ( (v->pause_flags & VPF_blocked_in_xen) && + !v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa && v->arch.hvm_vcpu.hvm_io.msix_snoop_address == (gtable + msi_desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + @@ -551,9 +568,29 @@ void msixtbl_pt_cleanup(struct domain *d void msix_write_completion(struct vcpu *v) { unsigned long ctrl_address = v->arch.hvm_vcpu.hvm_io.msix_unmask_address; + unsigned long snoop_addr = v->arch.hvm_vcpu.hvm_io.msix_snoop_address; v->arch.hvm_vcpu.hvm_io.msix_snoop_address = 0; + if ( !ctrl_address && snoop_addr && + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa ) + { + const struct msi_desc *desc; + uint32_t data; + + rcu_read_lock(&msixtbl_rcu_lock); + desc = msixtbl_addr_to_desc(msixtbl_find_entry(v, snoop_addr), + snoop_addr); + rcu_read_unlock(&msixtbl_rcu_lock); + + if ( desc && + hvm_copy_from_guest_phys(&data, + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa, + sizeof(data)) == HVMCOPY_okay && + !(data & PCI_MSIX_VECTOR_BITMASK) ) + ctrl_address = snoop_addr; + } + if ( !ctrl_address ) return; --- unstable.orig/xen/include/asm-x86/hvm/vcpu.h 2016-04-27 14:47:25.000000000 +0200 +++ unstable/xen/include/asm-x86/hvm/vcpu.h 2016-04-25 16:04:48.000000000 +0200 @@ -86,6 +86,7 @@ struct hvm_vcpu_io { unsigned long msix_unmask_address; unsigned long msix_snoop_address; + unsigned long msix_snoop_gpa; const struct g2m_ioport *g2m_ioport; }; --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -351,9 +351,10 @@ static int msixtbl_range(struct vcpu *v, ASSERT(r->type == IOREQ_TYPE_COPY); if ( r->dir == IOREQ_WRITE ) { + unsigned int size = r->size; + if ( !r->data_is_ptr ) { - unsigned int size = r->size; uint64_t data = r->data; if ( size == 8 ) @@ -366,7 +367,22 @@ static int msixtbl_range(struct vcpu *v, ((addr & (PCI_MSIX_ENTRY_SIZE - 1)) == PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) && !(data & PCI_MSIX_VECTOR_BITMASK) ) + { v->arch.hvm_vcpu.hvm_io.msix_snoop_address = addr; + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa = 0; + } + } + else if ( (size == 4 || size == 8) && !r->df && + r->count && r->count <= PCI_MSIX_ENTRY_SIZE / size && + !((addr + (size * r->count)) & (PCI_MSIX_ENTRY_SIZE - 1)) ) + { + BUILD_BUG_ON((PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET + 4) & + (PCI_MSIX_ENTRY_SIZE - 1)); + + v->arch.hvm_vcpu.hvm_io.msix_snoop_address = + addr + size * r->count - 4; + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa = + r->data + size * r->count - 4; } } @@ -471,6 +487,7 @@ out: for_each_vcpu ( d, v ) { if ( (v->pause_flags & VPF_blocked_in_xen) && + !v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa && v->arch.hvm_vcpu.hvm_io.msix_snoop_address == (gtable + msi_desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + @@ -551,9 +568,29 @@ void msixtbl_pt_cleanup(struct domain *d void msix_write_completion(struct vcpu *v) { unsigned long ctrl_address = v->arch.hvm_vcpu.hvm_io.msix_unmask_address; + unsigned long snoop_addr = v->arch.hvm_vcpu.hvm_io.msix_snoop_address; v->arch.hvm_vcpu.hvm_io.msix_snoop_address = 0; + if ( !ctrl_address && snoop_addr && + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa ) + { + const struct msi_desc *desc; + uint32_t data; + + rcu_read_lock(&msixtbl_rcu_lock); + desc = msixtbl_addr_to_desc(msixtbl_find_entry(v, snoop_addr), + snoop_addr); + rcu_read_unlock(&msixtbl_rcu_lock); + + if ( desc && + hvm_copy_from_guest_phys(&data, + v->arch.hvm_vcpu.hvm_io.msix_snoop_gpa, + sizeof(data)) == HVMCOPY_okay && + !(data & PCI_MSIX_VECTOR_BITMASK) ) + ctrl_address = snoop_addr; + } + if ( !ctrl_address ) return; --- unstable.orig/xen/include/asm-x86/hvm/vcpu.h 2016-04-27 14:47:25.000000000 +0200 +++ unstable/xen/include/asm-x86/hvm/vcpu.h 2016-04-25 16:04:48.000000000 +0200 @@ -86,6 +86,7 @@ struct hvm_vcpu_io { unsigned long msix_unmask_address; unsigned long msix_snoop_address; + unsigned long msix_snoop_gpa; const struct g2m_ioport *g2m_ioport; };