From patchwork Tue Sep 19 14:14:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Stefan ISAILA X-Patchwork-Id: 9959151 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 A7CC26056A for ; Tue, 19 Sep 2017 14:17:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 71F89284C4 for ; Tue, 19 Sep 2017 14:17:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6655128614; Tue, 19 Sep 2017 14:17:20 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID 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 4BC0428538 for ; Tue, 19 Sep 2017 14:17:17 +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 1duJIg-0006Lw-BI; Tue, 19 Sep 2017 14:14:58 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1duJIf-0006LV-BC for xen-devel@lists.xen.org; Tue, 19 Sep 2017 14:14:57 +0000 Received: from [85.158.143.35] by server-7.bemta-6.messagelabs.com id 48/C0-03610-06621C95; Tue, 19 Sep 2017 14:14:56 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrIIsWRWlGSWpSXmKPExsUSfTyjVTdG7WC kQdM6WYslHxezODB6HN39mymAMYo1My8pvyKBNaNr9UL2goUWFR8uLmFvYPym1sXIycEsYC3R +6+ZsYuRi4NFYBaLxLQzZ5ggnAksEm9PvGQDqRIS8JDofPKSHSQhJLCAUeJxzxJWmMTLlbcZI RLLGCWmLt7MApJgEzCQePX1GyOILSIgLXHt82WwImaBr0wSmxrXMIMkhAW8JVY8fQxmswioSm x8854dxOYVcJP4/m4p2AYJATmJm+c6wWo4BdwlJn79BHQSB9A2N4mjH8wmMAKdw7CKUaM4tag stUjX2FgvqSgzPaMkNzEzR9fQwEwvN7W4ODE9NScxqVgvOT93EyMwuBiAYAfjzvWBhxglOZiU RHlvqRyMFOJLyk+pzEgszogvKs1JLT7EKMPBoSTB+xwkJ1iUmp5akZaZAwxzmLQEB4+SCG+sK lCat7ggMbc4Mx0idYpRl6Pj5t0/TEIsefl5qVLivGYgRQIgRRmleXAjYDF3iVFWSpiXEegoIZ 6C1KLczBJU+VeM4hyMSsK85iBTeDLzSuA2vQI6ggnoiOwNB0COKElESEk1MJ49+vT7it/xLk2 31XaJ2KzJrlhy4taha0u5bwplKxxLz+TfqOgx51QUFxv7XLcZr4KCU36znHPUtp8670vp1PrW Wymnkq7dfrKjqm+1xhOpzMJvE9t+hf9PS9Y23JHpwjVp29R0mQPFC69+CnrknvRckdUloPbbp pscUU+uJkzg2DtLpO6l/24lluKMREMt5qLiRAAQIwzftAIAAA== X-Env-Sender: aisaila@bitdefender.com X-Msg-Ref: server-15.tower-21.messagelabs.com!1505830491!83448009!1 X-Originating-IP: [91.199.104.133] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 48406 invoked from network); 19 Sep 2017 14:14:52 -0000 Received: from mx02.bbu.dsd.mx.bitdefender.com (HELO mx02.buh.bitdefender.com) (91.199.104.133) by server-15.tower-21.messagelabs.com with DHE-RSA-AES128-GCM-SHA256 encrypted SMTP; 19 Sep 2017 14:14:52 -0000 Comment: DomainKeys? See http://domainkeys.sourceforge.net/ DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=bitdefender.com; b=G5ZyXCckRrkZsObogQ3ehxPAwwq+xCFXtSLBRpctNAOVJ7QhCwP12JlxwzGIf2ckE51rnNW6lso1LnaBH/BZu34py49EYfdrYQDZsPknUy+U5PbyHrNEZvGBw/K7j1N8w/HXdJ0jzAmwpHCLK11dh9GE3OsfWfNY+MhavadeRVvs7w2E9sIfhO6giJb3KlVV/wQ6x2yTfDj9H+JQRkqxFgfKSFJxl2VA2IgfFYDLosQIPnbWaAQW7Xkug3G5vWdbqxPpYAIvlh0cEoGNei6EsWPQik7oX8Xbr5XS9/WMVJqOt88KW3xvITVz0D9g5LJGsLxIhzItkPSpavpY6tprTg==; h=Received:Received:Received:Received:From:To:Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References; DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=bitdefender.com; h=from:to :cc:subject:date:message-id:in-reply-to:references; s=default; bh=yXk7JeJKA5zhAzWPutjfV7pk9gA=; b=V5RI694fECP00RzOZbeH2sfyL5Hc GyvIUj2Q4ryXMQv3Q2S1IzFZcXoaYgsAOejpEJMgVXR3RBnb73Vq4HTerxtwF6kJ j9uCfn4LALNzAaVUbAz9aWShBeI8KFIE5EpqTOCUQuWwXyDwprXUTjE0kCx9xkpF 01IyPDRP+TiH90XnpYTBrfXz36tDAckjLQNcvhbsx8XfxmK7LtE9rOS1wex8FFWA sSvyY8/3RX+FIKjNhXiv8SPU1ukU3a/tvFvFROTSGrhJGpRCpdO4Gc3Vh+dfKspE bz2IcBBqAiNw9aiBhqZItHuShVgnDmJg9fYiqzy/mk12q0pKYBTbbfGxbw== Received: (qmail 13809 invoked from network); 19 Sep 2017 17:14:44 +0300 Received: from mx01robo.bbu.dsd.mx.bitdefender.com (10.17.80.60) by mx02.buh.bitdefender.com with AES128-GCM-SHA256 encrypted SMTP; 19 Sep 2017 17:14:44 +0300 Received: (qmail 27682 invoked from network); 19 Sep 2017 17:14:44 +0300 Received: from unknown (HELO aisaila-Latitude-E5570.dsd.bitdefender.biz) (10.10.195.54) by mx01robo.bbu.dsd.mx.bitdefender.com with SMTP; 19 Sep 2017 17:14:44 +0300 From: Alexandru Isaila To: xen-devel@lists.xen.org Date: Tue, 19 Sep 2017 17:14:10 +0300 Message-Id: <1505830451-1868-3-git-send-email-aisaila@bitdefender.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505830451-1868-1-git-send-email-aisaila@bitdefender.com> References: <1505830451-1868-1-git-send-email-aisaila@bitdefender.com> Cc: jun.nakajima@intel.com, kevin.tian@intel.com, sstabellini@kernel.org, wei.liu2@citrix.com, suravee.suthikulpanit@amd.com, george.dunlap@eu.citrix.com, andrew.cooper3@citrix.com, tim@xen.org, paul.durrant@citrix.com, jbeulich@suse.com, Alexandru Isaila , boris.ostrovsky@oracle.com, ian.jackson@eu.citrix.com Subject: [Xen-devel] [PATCH v3 2/3] x86/hvm: Break out __hvm_copy()'s translation logic 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 From: Andrew Cooper It will be reused by later changes. Signed-off-by: Andrew Cooper Signed-off-by: Alexandru Isaila Reviewed-by: Paul Durrant Acked-by: Jan Beulich --- Changes since V2: - Changed _gfn() to gaddr_to_gfn - Changed gfn_x to gfn_to_gaddr --- xen/arch/x86/hvm/hvm.c | 144 +++++++++++++++++++++++--------------- xen/include/asm-x86/hvm/support.h | 12 ++++ 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 488acbf..93394c1 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3069,6 +3069,83 @@ void hvm_task_switch( hvm_unmap_entry(nptss_desc); } +enum hvm_translation_result hvm_translate_get_page( + struct vcpu *v, unsigned long addr, bool linear, uint32_t pfec, + pagefault_info_t *pfinfo, struct page_info **page_p, + gfn_t *gfn_p, p2m_type_t *p2mt_p) +{ + struct page_info *page; + p2m_type_t p2mt; + gfn_t gfn; + + if ( linear ) + { + gfn = _gfn(paging_gva_to_gfn(v, addr, &pfec)); + + if ( gfn_eq(gfn, INVALID_GFN) ) + { + if ( pfec & PFEC_page_paged ) + return HVMTRANS_gfn_paged_out; + + if ( pfec & PFEC_page_shared ) + return HVMTRANS_gfn_shared; + + if ( pfinfo ) + { + pfinfo->linear = addr; + pfinfo->ec = pfec & ~PFEC_implicit; + } + + return HVMTRANS_bad_linear_to_gfn; + } + } + else + { + gfn = gaddr_to_gfn(addr); + ASSERT(!pfinfo); + } + + /* + * No need to do the P2M lookup for internally handled MMIO, benefiting + * - 32-bit WinXP (& older Windows) on AMD CPUs for LAPIC accesses, + * - newer Windows (like Server 2012) for HPET accesses. + */ + if ( v == current + && !nestedhvm_vcpu_in_guestmode(v) + && hvm_mmio_internal(gfn_to_gaddr(gfn)) ) + return HVMTRANS_bad_gfn_to_mfn; + + page = get_page_from_gfn(v->domain, gfn_x(gfn), &p2mt, P2M_UNSHARE); + + if ( !page ) + return HVMTRANS_bad_gfn_to_mfn; + + if ( p2m_is_paging(p2mt) ) + { + put_page(page); + p2m_mem_paging_populate(v->domain, gfn_x(gfn)); + return HVMTRANS_gfn_paged_out; + } + if ( p2m_is_shared(p2mt) ) + { + put_page(page); + return HVMTRANS_gfn_shared; + } + if ( p2m_is_grant(p2mt) ) + { + put_page(page); + return HVMTRANS_unhandleable; + } + + *page_p = page; + if ( gfn_p ) + *gfn_p = gfn; + if ( p2mt_p ) + *p2mt_p = p2mt; + + return HVMTRANS_okay; +} + #define HVMCOPY_from_guest (0u<<0) #define HVMCOPY_to_guest (1u<<0) #define HVMCOPY_phys (0u<<2) @@ -3077,7 +3154,7 @@ static enum hvm_translation_result __hvm_copy( void *buf, paddr_t addr, int size, struct vcpu *v, unsigned int flags, uint32_t pfec, pagefault_info_t *pfinfo) { - unsigned long gfn; + gfn_t gfn; struct page_info *page; p2m_type_t p2mt; char *p; @@ -3103,65 +3180,15 @@ static enum hvm_translation_result __hvm_copy( while ( todo > 0 ) { + enum hvm_translation_result res; paddr_t gpa = addr & ~PAGE_MASK; count = min_t(int, PAGE_SIZE - gpa, todo); - if ( flags & HVMCOPY_linear ) - { - gfn = paging_gva_to_gfn(v, addr, &pfec); - if ( gfn == gfn_x(INVALID_GFN) ) - { - if ( pfec & PFEC_page_paged ) - return HVMTRANS_gfn_paged_out; - if ( pfec & PFEC_page_shared ) - return HVMTRANS_gfn_shared; - if ( pfinfo ) - { - pfinfo->linear = addr; - pfinfo->ec = pfec & ~PFEC_implicit; - } - return HVMTRANS_bad_linear_to_gfn; - } - gpa |= (paddr_t)gfn << PAGE_SHIFT; - } - else - { - gfn = addr >> PAGE_SHIFT; - gpa = addr; - } - - /* - * No need to do the P2M lookup for internally handled MMIO, benefiting - * - 32-bit WinXP (& older Windows) on AMD CPUs for LAPIC accesses, - * - newer Windows (like Server 2012) for HPET accesses. - */ - if ( v == current - && !nestedhvm_vcpu_in_guestmode(v) - && hvm_mmio_internal(gpa) ) - return HVMTRANS_bad_gfn_to_mfn; - - page = get_page_from_gfn(v->domain, gfn, &p2mt, P2M_UNSHARE); - - if ( !page ) - return HVMTRANS_bad_gfn_to_mfn; - - if ( p2m_is_paging(p2mt) ) - { - put_page(page); - p2m_mem_paging_populate(v->domain, gfn); - return HVMTRANS_gfn_paged_out; - } - if ( p2m_is_shared(p2mt) ) - { - put_page(page); - return HVMTRANS_gfn_shared; - } - if ( p2m_is_grant(p2mt) ) - { - put_page(page); - return HVMTRANS_unhandleable; - } + res = hvm_translate_get_page(v, addr, flags & HVMCOPY_linear, + pfec, pfinfo, &page, &gfn, &p2mt); + if ( res != HVMTRANS_okay ) + return res; p = (char *)__map_domain_page(page) + (addr & ~PAGE_MASK); @@ -3170,10 +3197,11 @@ static enum hvm_translation_result __hvm_copy( if ( p2m_is_discard_write(p2mt) ) { static unsigned long lastpage; - if ( xchg(&lastpage, gfn) != gfn ) + + if ( xchg(&lastpage, gfn_x(gfn)) != gfn_x(gfn) ) dprintk(XENLOG_G_DEBUG, "%pv attempted write to read-only gfn %#lx (mfn=%#lx)\n", - v, gfn, page_to_mfn(page)); + v, gfn_x(gfn), page_to_mfn(page)); } else { diff --git a/xen/include/asm-x86/hvm/support.h b/xen/include/asm-x86/hvm/support.h index e3b035d..d784fc1 100644 --- a/xen/include/asm-x86/hvm/support.h +++ b/xen/include/asm-x86/hvm/support.h @@ -24,6 +24,7 @@ #include #include #include +#include #ifndef NDEBUG #define DBG_LEVEL_0 (1 << 0) @@ -103,6 +104,17 @@ enum hvm_translation_result hvm_fetch_from_guest_linear( void *buf, unsigned long addr, int size, uint32_t pfec, pagefault_info_t *pfinfo); +/* + * Get a reference on the page under an HVM physical or linear address. If + * linear, a pagewalk is performed using pfec (fault details optionally in + * pfinfo). + * On success, returns HVMTRANS_okay with a reference taken on **_page. + */ +enum hvm_translation_result hvm_translate_get_page( + struct vcpu *v, unsigned long addr, bool linear, uint32_t pfec, + pagefault_info_t *pfinfo, struct page_info **page_p, + gfn_t *gfn_p, p2m_type_t *p2mt_p); + #define HVM_HCALL_completed 0 /* hypercall completed - no further action */ #define HVM_HCALL_preempted 1 /* hypercall preempted - re-execute VMCALL */ int hvm_hypercall(struct cpu_user_regs *regs);