From patchwork Mon Sep 11 04:37:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 9946569 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 81212603F4 for ; Mon, 11 Sep 2017 04:41:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7740D28ABE for ; Mon, 11 Sep 2017 04:41:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6BEF928AD8; Mon, 11 Sep 2017 04:41:33 +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 EE34228ABE for ; Mon, 11 Sep 2017 04:41:32 +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 1drGUp-00017k-6V; Mon, 11 Sep 2017 04:38:55 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1drGUo-00016u-GU for xen-devel@lists.xen.org; Mon, 11 Sep 2017 04:38:54 +0000 Received: from [85.158.137.68] by server-9.bemta-3.messagelabs.com id 3E/17-02044-D5316B95; Mon, 11 Sep 2017 04:38:53 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmplkeJIrShJLcpLzFFi42Jpa+sQ0Y0V3hZ psPcfm8WSj4tZHBg9ju7+zRTAGMWamZeUX5HAmtH3NaDglGrFxsUt7A2MB6S7GLk4hASmM0rM +HeNrYuRk0NCgFfiyLIZrBB2gMS261/YIYp6GSXWvf7IDpJgE9CXWPH4IFiRiIC0xLXPlxlBb GaBBiaJt3+Luhg5OIQFQiReLtcECbMIqEpM/NQHNp9XwFZi+/IGRoj58hK72i6CjeEUsJM4+P IdM4gtBFSz4PQC1gmMvAsYGVYxahSnFpWlFukaWuolFWWmZ5TkJmbm6BoaGOvlphYXJ6an5iQ mFesl5+duYgQGQz0DA+MOxt/H/Q4xSnIwKYnyvju+JVKILyk/pTIjsTgjvqg0J7X4EKMMB4eS BK+K0LZIIcGi1PTUirTMHGBYwqQlOHiURHijQNK8xQWJucWZ6RCpU4yWHB037/5h4tgEJjd8f /CHSYglLz8vVUqcVw6kQQCkIaM0D24cLHYuMcpKCfMyMjAwCPEUpBblZpagyr9iFOdgVBLmlQ GZwpOZVwK39RXQQUxAB/Fc2gJyUEkiQkqqgXHfIvOXqTOvsEj+2qQ7ey8T06ICXanFk6z1Xvh 2x725dCNAMldqb3uEwD8p9kahesXLwpMPM7TcqgtKKtxbmbla2afQSGTvptYj3D3LZU3Tu9OP BB1vOt+rmHjkyHfzZcZiF1p7ru9t6V5yUOCDRPuWxSu/Sli/lOJ+8oJtTX3VotdR02/dUVViK c5INNRiLipOBAB3x1LCmAIAAA== X-Env-Sender: haozhong.zhang@intel.com X-Msg-Ref: server-7.tower-31.messagelabs.com!1505104730!106558789!1 X-Originating-IP: [134.134.136.20] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTM0LjEzNC4xMzYuMjAgPT4gMzU1MzU4\n X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23010 invoked from network); 11 Sep 2017 04:38:52 -0000 Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by server-7.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 11 Sep 2017 04:38:52 -0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Sep 2017 21:38:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.42,376,1500966000"; d="scan'208"; a="1217078248" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.159.142]) by fmsmga002.fm.intel.com with ESMTP; 10 Sep 2017 21:38:46 -0700 From: Haozhong Zhang To: xen-devel@lists.xen.org Date: Mon, 11 Sep 2017 12:37:44 +0800 Message-Id: <20170911043820.14617-4-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170911043820.14617-1-haozhong.zhang@intel.com> References: <20170911043820.14617-1-haozhong.zhang@intel.com> Cc: Haozhong Zhang , Andrew Cooper , Jan Beulich , Chao Peng , Dan Williams Subject: [Xen-devel] [RFC XEN PATCH v3 03/39] x86_64/mm: avoid cleaning the unmapped frame table 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 cleanup_frame_table() initializes the entire newly added frame table to all -1's. If it's called after extend_frame_table() failed to map the entire frame table, the initialization will hit a page fault. Move the cleanup of partially mapped frametable to extend_frame_table(), which has enough knowledge of the mapping status. Signed-off-by: Haozhong Zhang --- Cc: Jan Beulich Cc: Andrew Cooper --- xen/arch/x86/x86_64/mm.c | 51 ++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index c93383d7d9..f635e4bf70 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -710,15 +710,12 @@ void free_compat_arg_xlat(struct vcpu *v) PFN_UP(COMPAT_ARG_XLAT_SIZE)); } -static void cleanup_frame_table(struct mem_hotadd_info *info) +static void cleanup_frame_table(unsigned long spfn, unsigned long epfn) { + struct mem_hotadd_info info = { .spfn = spfn, .epfn = epfn, .cur = spfn }; unsigned long sva, eva; l3_pgentry_t l3e; l2_pgentry_t l2e; - unsigned long spfn, epfn; - - spfn = info->spfn; - epfn = info->epfn; sva = (unsigned long)mfn_to_page(spfn); eva = (unsigned long)mfn_to_page(epfn); @@ -744,7 +741,7 @@ static void cleanup_frame_table(struct mem_hotadd_info *info) if ( (l2e_get_flags(l2e) & (_PAGE_PRESENT | _PAGE_PSE)) == (_PAGE_PSE | _PAGE_PRESENT) ) { - if (hotadd_mem_valid(l2e_get_pfn(l2e), info)) + if ( hotadd_mem_valid(l2e_get_pfn(l2e), &info) ) destroy_xen_mappings(sva & ~((1UL << L2_PAGETABLE_SHIFT) - 1), ((sva & ~((1UL << L2_PAGETABLE_SHIFT) -1 )) + (1UL << L2_PAGETABLE_SHIFT) - 1)); @@ -769,28 +766,33 @@ static int setup_frametable_chunk(void *start, void *end, { unsigned long s = (unsigned long)start; unsigned long e = (unsigned long)end; - unsigned long mfn; - int err; + unsigned long cur, mfn; + int err = 0; ASSERT(!(s & ((1 << L2_PAGETABLE_SHIFT) - 1))); ASSERT(!(e & ((1 << L2_PAGETABLE_SHIFT) - 1))); - for ( ; s < e; s += (1UL << L2_PAGETABLE_SHIFT)) + for ( cur = s; cur < e; cur += (1UL << L2_PAGETABLE_SHIFT) ) { mfn = alloc_hotadd_mfn(info); - err = map_pages_to_xen(s, mfn, 1UL << PAGETABLE_ORDER, + err = map_pages_to_xen(cur, mfn, 1UL << PAGETABLE_ORDER, PAGE_HYPERVISOR); if ( err ) - return err; + break; } - memset(start, -1, s - (unsigned long)start); - return 0; + if ( !err ) + memset(start, -1, cur - s); + else + destroy_xen_mappings(s, cur); + + return err; } static int extend_frame_table(struct mem_hotadd_info *info) { unsigned long cidx, nidx, eidx, spfn, epfn; + int err = 0; spfn = info->spfn; epfn = info->epfn; @@ -809,8 +811,6 @@ static int extend_frame_table(struct mem_hotadd_info *info) while ( cidx < eidx ) { - int err; - nidx = find_next_bit(pdx_group_valid, eidx, cidx); if ( nidx >= eidx ) nidx = eidx; @@ -818,14 +818,19 @@ static int extend_frame_table(struct mem_hotadd_info *info) pdx_to_page(nidx * PDX_GROUP_COUNT), info); if ( err ) - return err; + break; cidx = find_next_zero_bit(pdx_group_valid, eidx, nidx); } - memset(mfn_to_page(spfn), 0, - (unsigned long)mfn_to_page(epfn) - (unsigned long)mfn_to_page(spfn)); - return 0; + if ( !err ) + memset(mfn_to_page(spfn), 0, + (unsigned long)mfn_to_page(epfn) - + (unsigned long)mfn_to_page(spfn)); + else + cleanup_frame_table(spfn, pdx_to_pfn(cidx * PDX_GROUP_COUNT)); + + return err; } void __init subarch_init_memory(void) @@ -1404,8 +1409,8 @@ int memory_add(unsigned long spfn, unsigned long epfn, unsigned int pxm) info.cur = spfn; ret = extend_frame_table(&info); - if (ret) - goto destroy_frametable; + if ( ret ) + goto restore_node_status; /* Set max_page as setup_m2p_table will use it*/ if (max_page < epfn) @@ -1448,8 +1453,8 @@ destroy_m2p: max_page = old_max; total_pages = old_total; max_pdx = pfn_to_pdx(max_page - 1) + 1; -destroy_frametable: - cleanup_frame_table(&info); + cleanup_frame_table(spfn, epfn); +restore_node_status: if ( !orig_online ) node_set_offline(node); NODE_DATA(node)->node_start_pfn = old_node_start;