From patchwork Wed May 10 09:43:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Druzhinin X-Patchwork-Id: 9719621 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 7005960365 for ; Wed, 10 May 2017 09:45:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 647DC28471 for ; Wed, 10 May 2017 09:45:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58148284E3; Wed, 10 May 2017 09:45:54 +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 B58C228471 for ; Wed, 10 May 2017 09:45:53 +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 1d8O9R-00085y-AO; Wed, 10 May 2017 09:43:21 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d8O9Q-00085s-Bd for xen-devel@lists.xen.org; Wed, 10 May 2017 09:43:20 +0000 Received: from [193.109.254.147] by server-11.bemta-6.messagelabs.com id 55/D9-03587-7B0E2195; Wed, 10 May 2017 09:43:19 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrJLMWRWlGSWpSXmKPExsWyU9JRQnf7A6F IgwuHWC2WfFzM4sDocXT3b6YAxijWzLyk/IoE1owVFxczFnRIVMw41MrYwDhdqIuRk0NCwE/i 1u4OVhCbTcBA4tSmRSwgtoiArMTqrjnsXYxcHMwCmxklrvesBUsIC/hK/NjSwwhiswioStze0 cLWxcjBwSvgKXH0kCTETDmJm+c6mUFsXgFBiZMzn4C1MgtISBx88QIsLiSgJnG0axcLRH26xI F53xgnMPLMQtIyC0nLAkamVYwaxalFZalFukYmeklFmekZJbmJmTm6hgZmermpxcWJ6ak5iUn Fesn5uZsYgUHCAAQ7GPd9jDzEKMnBpCTKq7tLKFKILyk/pTIjsTgjvqg0J7X4EKMMB4eSBO+a +0A5waLU9NSKtMwcYLjCpCU4eJREeHeCpHmLCxJzizPTIVKnGBWlxHn1QBICIImM0jy4NliMX GKUlRLmZQQ6RIinILUoN7MEVf4VozgHo5Iw70aQKTyZeSVw018BLWYCWhzIIACyuCQRISXVwF h1S1Nt57+EC/6GdjrTu10/7z/JHGCnOvX/MbaSuYo/Evz2Fx9r55uoxMT5bGmnpklbYtyykgb BvI5shtedG5tU4ru9qyQbojSjW5NbFf7kL4n3elq/9YbOzck5LpeKBHL1JVI5t3xK6DVbxN26 vtyrMqL+97N5mQmHJ1rH7ZWv2+wXYr1NiaU4I9FQi7moOBEAH3oGr4wCAAA= X-Env-Sender: prvs=296f43a01=igor.druzhinin@citrix.com X-Msg-Ref: server-5.tower-27.messagelabs.com!1494409398!95803777!1 X-Originating-IP: [185.25.65.24] X-SpamReason: No, hits=0.0 required=7.0 tests=received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 45478 invoked from network); 10 May 2017 09:43:19 -0000 Received: from smtp.ctxuk.citrix.com (HELO SMTP.EU.CITRIX.COM) (185.25.65.24) by server-5.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 10 May 2017 09:43:19 -0000 X-IronPort-AV: E=Sophos;i="5.38,318,1491264000"; d="scan'208";a="45745988" From: Igor Druzhinin To: Date: Wed, 10 May 2017 10:43:05 +0100 Message-ID: <1494409385-13729-1-git-send-email-igor.druzhinin@citrix.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-ClientProxiedBy: FTLPEX02CAS01.citrite.net (10.13.99.120) To AMSPEX02CL03.citrite.net (10.69.22.127) Cc: Igor Druzhinin , kevin.tian@intel.com, jun.nakajima@intel.com, george.dunlap@eu.citrix.com, andrew.cooper3@citrix.com, jbeulich@suse.com Subject: [Xen-devel] [PATCH for-4.9] x86/mm: Fix incorrect unmapping of 2MB and 1GB pages 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-Virus-Scanned: ClamAV using ClamSMTP The same set of functions is used to set as well as to clean P2M entries, except that for clean operations INVALID_MFN (~0UL) is passed as a parameter. Unfortunately, when calculating an appropriate target order for a particular mapping INVALID_MFN is not taken into account which leads to 4K page target order being set each time even for 2MB and 1GB mappings. This eventually breaks down an EPT structure irreversibly into 4K mappings which prevents consecutive high order mappings to this area. Signed-off-by: Igor Druzhinin --- CC: Jun Nakajima CC: Kevin Tian CC: George Dunlap CC: Jan Beulich CC: Andrew Cooper Bugfix intended for 4.9 release. --- xen/arch/x86/mm/p2m-ept.c | 3 ++- xen/arch/x86/mm/p2m.c | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index f37a1f2..8d82097 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -681,6 +681,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, ept_entry_t *table, *ept_entry = NULL; unsigned long gfn_remainder = gfn; unsigned int i, target = order / EPT_TABLE_ORDER; + unsigned long mfn_mask = mfn_valid(mfn) ? mfn_x(mfn) : 0; int ret, rc = 0; bool_t entry_written = 0; bool_t direct_mmio = (p2mt == p2m_mmio_direct); @@ -701,7 +702,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, * 2. gfn not exceeding guest physical address width. * 3. passing a valid order. */ - if ( ((gfn | mfn_x(mfn)) & ((1UL << order) - 1)) || + if ( ((gfn | mfn_mask) & ((1UL << order) - 1)) || ((u64)gfn >> ((ept->wl + 1) * EPT_TABLE_ORDER)) || (order % EPT_TABLE_ORDER) ) return -EINVAL; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index ae70a92..fd57d41 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -536,6 +536,7 @@ int p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, struct domain *d = p2m->domain; unsigned long todo = 1ul << page_order; unsigned int order; + unsigned long mfn_mask; int set_rc, rc = 0; ASSERT(gfn_locked_by_me(p2m, gfn)); @@ -543,12 +544,15 @@ int p2m_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, while ( todo ) { if ( hap_enabled(d) ) - order = (!((gfn | mfn_x(mfn) | todo) & + { + mfn_mask = mfn_valid(mfn) ? mfn_x(mfn) : 0; + order = (!((gfn | mfn_mask | todo) & ((1ul << PAGE_ORDER_1G) - 1)) && hap_has_1gb) ? PAGE_ORDER_1G : - (!((gfn | mfn_x(mfn) | todo) & + (!((gfn | mfn_mask | todo) & ((1ul << PAGE_ORDER_2M) - 1)) && hap_has_2mb) ? PAGE_ORDER_2M : PAGE_ORDER_4K; + } else order = 0;