All of lore.kernel.org
 help / color / mirror / Atom feed
From: Haozhong Zhang <haozhong.zhang@intel.com>
To: xen-devel@lists.xen.org
Cc: Konrad Rzeszutek Wilk <konrad@darnok.org>,
	Dan Williams <dan.j.williams@intel.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Jan Beulich <jbeulich@suse.com>,
	Haozhong Zhang <haozhong.zhang@intel.com>
Subject: [RFC XEN PATCH v2 03/15] xen/x86: allow customizing locations of extended frametable & M2P
Date: Mon, 20 Mar 2017 08:09:37 +0800	[thread overview]
Message-ID: <20170320000949.24675-4-haozhong.zhang@intel.com> (raw)
In-Reply-To: <20170320000949.24675-1-haozhong.zhang@intel.com>

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 <haozhong.zhang@intel.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>

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;
-- 
2.12.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  parent reply	other threads:[~2017-03-20  0:09 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-20  0:09 [RFC XEN PATCH v2 00/15] Add vNVDIMM support to HVM domains Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 01/15] xen/common: add Kconfig item for pmem support Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 02/15] xen: probe pmem regions via ACPI NFIT Haozhong Zhang
2017-03-20  0:09 ` Haozhong Zhang [this message]
2017-03-20  0:09 ` [RFC XEN PATCH v2 04/15] xen/x86: add XEN_SYSCTL_nvdimm_pmem_setup to setup host pmem Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 05/15] xen/x86: add XENMEM_populate_pmem_map to map host pmem pages to HVM domain Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 06/15] tools: reserve guest memory for ACPI from device model Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 07/15] tools/libacpi: expose the minimum alignment used by mem_ops.alloc Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 08/15] tools/libacpi: add callback acpi_ctxt.p2v to get a pointer from physical address Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 09/15] tools/libacpi: add callbacks to access XenStore Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 10/15] tools/libacpi: add a simple AML builder Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 11/15] tools/libacpi: load ACPI built by the device model Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 12/15] tools/libxl: build qemu options from xl vNVDIMM configs Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 13/15] tools/libxl: add support to map host pmem device to guests Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 14/15] tools/libxl: initiate pmem mapping via qmp callback Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 15/15] tools/misc: add xen-ndctl Haozhong Zhang
2017-03-30  4:11   ` Dan Williams
2017-03-30  7:58     ` Haozhong Zhang
2017-04-01 11:55       ` Konrad Rzeszutek Wilk
2017-03-30  4:20 ` [RFC XEN PATCH v2 00/15] Add vNVDIMM support to HVM domains Dan Williams
2017-03-30  8:21   ` Haozhong Zhang
2017-03-30 16:01     ` Dan Williams
2017-04-01 11:54       ` Konrad Rzeszutek Wilk
2017-04-01 15:45         ` Dan Williams
2017-04-04 17:00           ` Konrad Rzeszutek Wilk
2017-04-04 17:16             ` Dan Williams
2017-04-04 17:34               ` Konrad Rzeszutek Wilk
2017-04-04 17:59                 ` Dan Williams
2017-04-04 18:05                   ` Konrad Rzeszutek Wilk
2017-04-04 18:59                     ` Dan Williams
2017-04-11 17:48                       ` Konrad Rzeszutek Wilk
2017-04-01 12:24 ` Konrad Rzeszutek Wilk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170320000949.24675-4-haozhong.zhang@intel.com \
    --to=haozhong.zhang@intel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dan.j.williams@intel.com \
    --cc=jbeulich@suse.com \
    --cc=konrad@darnok.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.