From patchwork Mon Mar 20 00:09:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 9632867 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 1504F60326 for ; Mon, 20 Mar 2017 00:15:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 08BB227F8C for ; Mon, 20 Mar 2017 00:15:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F1D1327FBC; Mon, 20 Mar 2017 00:15:39 +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 58B3A27F9F for ; Mon, 20 Mar 2017 00:15:39 +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 1cpkwi-0006Tm-OO; Mon, 20 Mar 2017 00:13:12 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cpkwh-0006SK-Tp for xen-devel@lists.xen.org; Mon, 20 Mar 2017 00:13:12 +0000 Received: from [85.158.139.211] by server-7.bemta-5.messagelabs.com id F6/A3-24850-79E1FC85; Mon, 20 Mar 2017 00:13:11 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrFLMWRWlGSWpSXmKPExsVywNykWHea3Pk Ig4YrQhZLPi5mcWD0OLr7N1MAYxRrZl5SfkUCa8b7qcfYChZZVrya8pWxgfGJZhcjJweLwC0m iWl/YrsYuTiEBKYzSrz6vZkZJCEhwCtxZNkMVgjbT+L70/csILaQQC+jxKdmMJtNQF9ixeODY DUiAtIS1z5fZgQZxCxwkVFi2+3N7CAJYYFkiWOT/zB1MXIAbVOV2P2KCyTMK2ArcbbjAyPEfH mJC1dPgc3kFLCTWHPpNjvELluJ/bemsU1g5FvAyLCKUaM4tagstUjXyEQvqSgzPaMkNzEzR9f QwFQvN7W4ODE9NScxqVgvOT93EyMwTOoZGBh3MN6c7HeIUZKDSUmUV0XwRIQQX1J+SmVGYnFG fFFpTmrxIUYZDg4lCd65rUA5waLU9NSKtMwcYMDCpCU4eJREeG+CpHmLCxJzizPTIVKnGBWlx Hm3gCQEQBIZpXlwbbAoucQoKyXMy8jAwCDEU5BalJtZgir/ilGcg1FJmFeuDWgKT2ZeCdz0V0 CLmYAWJ/48ArK4JBEhJdXAGOBUeuZp4kz1LcePhhXbWm5NPhW39oesTGBTZLDztaDGjbPK6z4 qy8iqR/a3uKs5e5mekzjo0+DPuTS182xni+mO38bTNaeHnj/T80d15oSEf2onbxyeGbLtIAP/ tPvNtyXKtf1kWhQq5WN/bm0w3eZ5Ouw929XlT4u/nmE89/w646pX0W/mKLEUZyQaajEXFScCA AI1YrONAgAA X-Env-Sender: haozhong.zhang@intel.com X-Msg-Ref: server-5.tower-206.messagelabs.com!1489968787!88643043!1 X-Originating-IP: [192.55.52.115] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 59272 invoked from network); 20 Mar 2017 00:13:10 -0000 Received: from mga14.intel.com (HELO mga14.intel.com) (192.55.52.115) by server-5.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 20 Mar 2017 00:13:10 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1489968790; x=1521504790; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=ILi+aU+Cirk6QNg5AQD3rAw9XBsaoVH4Dtskkuq6E+0=; b=D2RNEZjWFE45g0UcRmP2atqXnKYz0WXdNkKGPazZvDdtUCACq3aB/JPr a38PZkeGyeruYaxBaC+kvgrdQ0BNGw==; Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Mar 2017 17:13:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,191,1486454400"; d="scan'208";a="78799165" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.159.153]) by fmsmga006.fm.intel.com with ESMTP; 19 Mar 2017 17:13:06 -0700 From: Haozhong Zhang To: xen-devel@lists.xen.org Date: Mon, 20 Mar 2017 08:09:37 +0800 Message-Id: <20170320000949.24675-4-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20170320000949.24675-1-haozhong.zhang@intel.com> References: <20170320000949.24675-1-haozhong.zhang@intel.com> Cc: Konrad Rzeszutek Wilk , Dan Williams , Andrew Cooper , Jan Beulich , Haozhong Zhang Subject: [Xen-devel] [RFC XEN PATCH v2 03/15] xen/x86: allow customizing locations of extended frametable & M2P 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 Xen is not aware which portions of pmem can be used to store its frametable and M2P table. Instead, it will rely on users or system admins in Dom0 to specify the location. For the regular RAM, no functional change is introduced. Signed-off-by: Haozhong Zhang --- Cc: Jan Beulich Cc: Andrew Cooper Changes in v2: * Merge v1 patch 1 (for frametable) and v1 patch 2 (for M2P). * Add const to some parameters. * Explain new parameters of extend_frame_table() and setup_m2p_table(). --- xen/arch/x86/x86_64/mm.c | 80 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 34f3250fd7..0f1ceacc6a 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -111,15 +111,27 @@ int hotadd_mem_valid(unsigned long pfn, struct mem_hotadd_info *info) return (pfn < info->epfn && pfn >= info->spfn); } +/* + * Allocate pages in the PFN range from info->spfn to info->epfn. The + * first free page is indicated by info->cur. The allocation unit is + * (1 << PAGETABLE_ORDER) pages. + * + * On success, return PFN of the first allocated page. Otherwise, return + * mfn_x(INVALID_MFN). + */ +typedef unsigned long (*mfns_alloc_fn_t)(struct mem_hotadd_info *info); + static unsigned long alloc_hotadd_mfn(struct mem_hotadd_info *info) { - unsigned mfn; + unsigned long mfn; - ASSERT((info->cur + ( 1UL << PAGETABLE_ORDER) < info->epfn) && - info->cur >= info->spfn); + if ( (info->cur + (1UL << PAGETABLE_ORDER) >= info->epfn) || + info->cur < info->spfn ) + return mfn_x(INVALID_MFN); mfn = info->cur; info->cur += (1UL << PAGETABLE_ORDER); + return mfn; } @@ -313,11 +325,13 @@ void destroy_m2p_mapping(struct mem_hotadd_info *info) } /* - * Allocate and map the compatibility mode machine-to-phys table. - * spfn/epfn: the pfn ranges to be setup - * free_s/free_e: the pfn ranges that is free still + * Allocate and map the compatibility mode machine-to-phys table for + * pages info->spfn ~ info->epfn. M2P is placed in pages allocated + * by alloc_fn from the range alloc_info->cur ~ alloc_info->epfn. */ -static int setup_compat_m2p_table(struct mem_hotadd_info *info) +static int setup_compat_m2p_table(const struct mem_hotadd_info *info, + mfns_alloc_fn_t alloc_fn, + struct mem_hotadd_info *alloc_info) { unsigned long i, va, smap, emap, rwva, epfn = info->epfn, mfn; unsigned int n; @@ -371,7 +385,12 @@ static int setup_compat_m2p_table(struct mem_hotadd_info *info) if ( n == CNT ) continue; - mfn = alloc_hotadd_mfn(info); + mfn = alloc_fn(alloc_info); + if ( mfn == mfn_x(INVALID_MFN) ) + { + err = -ENOMEM; + break; + } err = map_pages_to_xen(rwva, mfn, 1UL << PAGETABLE_ORDER, PAGE_HYPERVISOR); if ( err ) @@ -389,9 +408,14 @@ static int setup_compat_m2p_table(struct mem_hotadd_info *info) /* * Allocate and map the machine-to-phys table. - * The L3 for RO/RWRW MPT and the L2 for compatible MPT should be setup already + * The L3 for RO/RWRW MPT and the L2 for compatible MPT should be setup already. + * + * M2P is placed in pages allocated by alloc_fn from the range + * alloc_info->cur ~ alloc_info->epfn. */ -static int setup_m2p_table(struct mem_hotadd_info *info) +static int setup_m2p_table(const struct mem_hotadd_info *info, + mfns_alloc_fn_t alloc_fn, + struct mem_hotadd_info *alloc_info) { unsigned long i, va, smap, emap; unsigned int n; @@ -440,7 +464,13 @@ static int setup_m2p_table(struct mem_hotadd_info *info) break; if ( n < CNT ) { - unsigned long mfn = alloc_hotadd_mfn(info); + unsigned long mfn = alloc_fn(alloc_info); + + if ( mfn == mfn_x(INVALID_MFN) ) + { + ret = -ENOMEM; + goto error; + } ret = map_pages_to_xen( RDWR_MPT_VIRT_START + i * sizeof(unsigned long), @@ -485,7 +515,7 @@ static int setup_m2p_table(struct mem_hotadd_info *info) #undef CNT #undef MFN - ret = setup_compat_m2p_table(info); + ret = setup_compat_m2p_table(info, alloc_fn, alloc_info); error: return ret; } @@ -769,7 +799,8 @@ void cleanup_frame_table(struct mem_hotadd_info *info) } static int setup_frametable_chunk(void *start, void *end, - struct mem_hotadd_info *info) + mfns_alloc_fn_t alloc_fn, + struct mem_hotadd_info *alloc_info) { unsigned long s = (unsigned long)start; unsigned long e = (unsigned long)end; @@ -781,7 +812,9 @@ static int setup_frametable_chunk(void *start, void *end, for ( ; s < e; s += (1UL << L2_PAGETABLE_SHIFT)) { - mfn = alloc_hotadd_mfn(info); + mfn = alloc_fn(alloc_info); + if ( mfn == mfn_x(INVALID_MFN) ) + return -ENOMEM; err = map_pages_to_xen(s, mfn, 1UL << PAGETABLE_ORDER, PAGE_HYPERVISOR); if ( err ) @@ -792,7 +825,14 @@ static int setup_frametable_chunk(void *start, void *end, return 0; } -static int extend_frame_table(struct mem_hotadd_info *info) +/* + * Create and map the frame table for page ranges info->spfn ~ + * info->epfn. The frame table is placed in pages allocated by + * alloc_fn from page range alloc_info->cur ~ alloc_info->epfn. + */ +static int extend_frame_table(const struct mem_hotadd_info *info, + mfns_alloc_fn_t alloc_fn, + struct mem_hotadd_info *alloc_info) { unsigned long cidx, nidx, eidx, spfn, epfn; @@ -818,9 +858,9 @@ static int extend_frame_table(struct mem_hotadd_info *info) nidx = find_next_bit(pdx_group_valid, eidx, cidx); if ( nidx >= eidx ) nidx = eidx; - err = setup_frametable_chunk(pdx_to_page(cidx * PDX_GROUP_COUNT ), + err = setup_frametable_chunk(pdx_to_page(cidx * PDX_GROUP_COUNT), pdx_to_page(nidx * PDX_GROUP_COUNT), - info); + alloc_fn, alloc_info); if ( err ) return err; @@ -1422,7 +1462,8 @@ int memory_add(unsigned long spfn, unsigned long epfn, unsigned int pxm) info.epfn = epfn; info.cur = spfn; - ret = extend_frame_table(&info); + /* Place the frame table at the beginning of hotplugged memory. */ + ret = extend_frame_table(&info, alloc_hotadd_mfn, &info); if (ret) goto destroy_frametable; @@ -1435,7 +1476,8 @@ int memory_add(unsigned long spfn, unsigned long epfn, unsigned int pxm) total_pages += epfn - spfn; set_pdx_range(spfn, epfn); - ret = setup_m2p_table(&info); + /* Place M2P in the hotplugged memory after the frame table. */ + ret = setup_m2p_table(&info, alloc_hotadd_mfn, &info); if ( ret ) goto destroy_m2p;