xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Andrii Anisov <andrii.anisov@globallogic.com>
To: embedded-pv-devel@lists.xenproject.org
Cc: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>,
	xen-devel@lists.xen.org
Subject: [PATCH RFC 16/18] xen: Add dom0_mem_high option & over 4GB memory allocation for Dom0
Date: Wed, 18 May 2016 19:32:39 +0300	[thread overview]
Message-ID: <1463589161-4153-17-git-send-email-andrii.anisov@globallogic.com> (raw)
In-Reply-To: <1463589161-4153-1-git-send-email-andrii.anisov@globallogic.com>

From: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>

Add support of custom allocation of over 4GB memory for Dom0. Requested
memory size might be specified by passing dom0_mem_high option in Xen
cmdline

Signed-off-by: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>
---
 xen/Rules.mk                |   1 +
 xen/arch/arm/domain_build.c | 189 +++++++++++++++++++++++++++++++++++++++++++-
 xen/arch/arm/kernel.h       |   9 +++
 3 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/xen/Rules.mk b/xen/Rules.mk
index fbd34a5..51f7124 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -65,6 +65,7 @@ CFLAGS-$(HAS_IOPORTS)   += -DHAS_IOPORTS
 CFLAGS-$(HAS_PDX)       += -DHAS_PDX
 CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER
 CFLAGS-$(ARM32_RELOCATE_OVER_4GB) += -DARM32_RELOCATE_OVER_4GB
+CFLAGS-$(ARM32_SEPAR_MEM_SPLIT) += -DARM32_SEPAR_MEM_SPLIT
 
 ifneq ($(max_phys_cpus),)
 CFLAGS-y                += -DMAX_PHYS_CPUS=$(max_phys_cpus)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index f06792e..a63958b 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -35,6 +35,11 @@ int dom0_11_mapping = 1;
 #define DOM0_MEM_DEFAULT 0x8000000 /* 128 MiB */
 static u64 __initdata dom0_mem = DOM0_MEM_DEFAULT;
 
+#ifdef ARM32_SEPAR_MEM_SPLIT
+#define DOM0_MEM_HIGH_DEFAULT 0x0 /* 0 MiB */
+static u64 __initdata dom0_mem_high = DOM0_MEM_HIGH_DEFAULT;
+#endif
+
 static void __init parse_dom0_mem(const char *s)
 {
     dom0_mem = parse_size_and_unit(s, &s);
@@ -43,6 +48,14 @@ static void __init parse_dom0_mem(const char *s)
 }
 custom_param("dom0_mem", parse_dom0_mem);
 
+#ifdef ARM32_SEPAR_MEM_SPLIT
+static void __init parse_dom0_mem_high(const char *s)
+{
+    dom0_mem_high = parse_size_and_unit(s, &s);
+}
+custom_param("dom0_mem_high", parse_dom0_mem_high);
+#endif
+
 //#define DEBUG_DT
 
 #ifdef DEBUG_DT
@@ -130,7 +143,11 @@ static bool_t insert_11_bank(struct domain *d,
     if ( res )
         panic("Failed map pages to DOM0: %d", res);
 
+#ifndef ARM32_SEPAR_MEM_SPLIT
     kinfo->unassigned_mem -= size;
+#else
+    kinfo->unassigned_mem.low -= size;
+#endif
 
     if ( kinfo->mem.nr_banks == 0 )
     {
@@ -192,6 +209,82 @@ fail:
     return false;
 }
 
+#ifdef ARM32_SEPAR_MEM_SPLIT
+static void allocate_dom0_high_memory(struct domain *d, struct kernel_info *kinfo)
+{
+    int i, res, st_banks = kinfo->mem.nr_banks;
+    struct page_info *pg = NULL;
+    int bits;
+    unsigned int order = get_11_allocation_size(dom0_mem_high);
+    const unsigned int min_order = get_order_from_bytes(MB(4));
+    paddr_t spfn;
+    paddr_t start, size;
+    struct membank *bank = NULL;
+
+    if (dom0_mem_high == 0)
+        return;
+
+    printk("Allocating %ldMB of high memory region for dom0\n",
+            (unsigned long)(dom0_mem_high >> 20));
+
+    while ( kinfo->unassigned_mem.high && kinfo->mem.nr_banks < NR_MEM_BANKS )
+    {
+        for (bits = PADDR_BITS ; bits >= min_order; bits-- )
+        {
+            pg = alloc_domheap_pages(d, order, MEMF_bits(bits));
+            if ( pg != NULL )
+                break;
+        }
+
+        if ( !pg )
+        {
+            order --;
+            if ( order >= min_order )
+                continue;
+
+            /* No more we can do */
+            break;
+        }
+
+        spfn = page_to_mfn(pg);
+        start = pfn_to_paddr(spfn);
+        size = pfn_to_paddr((1 << order));
+
+        res = guest_physmap_add_page(d, spfn, spfn, order);
+        if ( res )
+            panic("Failed map pages to DOM0: %d", res);
+
+        kinfo->unassigned_mem.high -= size;
+
+        bank = &kinfo->mem.bank[kinfo->mem.nr_banks];
+
+        bank->start = start;
+        bank->size = size;
+        kinfo->mem.nr_banks++;
+
+        /*
+         * Success, next time around try again to get the largest order
+         * allocation possible.
+         */
+
+        order = get_11_allocation_size(kinfo->unassigned_mem.high);
+     }
+
+    if(kinfo->unassigned_mem.high)
+        panic("Unable to allocate high memory bank");
+
+    for( i = st_banks; i < kinfo->mem.nr_banks; i++ )
+    {
+        printk("BANK[%d] %#"PRIpaddr"-%#"PRIpaddr" (%ldMB)\n",
+               i,
+               kinfo->mem.bank[i].start,
+               kinfo->mem.bank[i].start + kinfo->mem.bank[i].size,
+               /* Don't want format this as PRIpaddr (16 digit hex) */
+               (unsigned long)(kinfo->mem.bank[i].size >> 20));
+    }
+}
+#endif
+
 /*
  * This is all pretty horrible.
  *
@@ -250,9 +343,13 @@ static void allocate_memory_11(struct domain *d, struct kernel_info *kinfo)
         get_11_allocation_size(min_t(paddr_t, dom0_mem, MB(128)));
     const unsigned int min_order = get_order_from_bytes(MB(4));
     struct page_info *pg;
-    unsigned int order = get_11_allocation_size(kinfo->unassigned_mem);
     u64 rambase_pfn = opt_dom0_rambase_pfn;
+#ifndef ARM32_SEPAR_MEM_SPLIT
+    unsigned int order = get_11_allocation_size(kinfo->unassigned_mem);
     paddr_t mem_size = kinfo->unassigned_mem;
+#else
+    unsigned int order = get_11_allocation_size(kinfo->unassigned_mem.low);
+#endif
     int i;
 
     bool_t lowmem = is_32bit_domain(d);
@@ -260,7 +357,11 @@ static void allocate_memory_11(struct domain *d, struct kernel_info *kinfo)
 
     printk("Allocating 1:1 mappings totalling %ldMB for dom0:\n",
            /* Don't want format this as PRIpaddr (16 digit hex) */
+#ifndef ARM32_SEPAR_MEM_SPLIT
            (unsigned long)(kinfo->unassigned_mem >> 20));
+#else
+           (unsigned long)(kinfo->unassigned_mem.low >> 20));
+#endif
 
     kinfo->mem.nr_banks = 0;
 
@@ -288,6 +389,7 @@ static void allocate_memory_11(struct domain *d, struct kernel_info *kinfo)
 
     /* Now allocate more memory and fill in additional banks */
 
+#ifndef ARM32_SEPAR_MEM_SPLIT
     order = get_11_allocation_size(kinfo->unassigned_mem);
     if ( opt_dom0_rambase_pfn )
         rambase_pfn += (mem_size - kinfo->unassigned_mem) >> PAGE_SHIFT;
@@ -353,7 +455,62 @@ static void allocate_memory_11(struct domain *d, struct kernel_info *kinfo)
                /* Don't want format this as PRIpaddr (16 digit hex) */
                " %ldMB unallocated\n",
                (unsigned long)kinfo->unassigned_mem >> 20);
+#else
+    order = get_11_allocation_size(kinfo->unassigned_mem.low);
+    while ( kinfo->unassigned_mem.low && kinfo->mem.nr_banks < NR_MEM_BANKS )
+    {
+        pg = alloc_domheap_pages(d, order, lowmem ? MEMF_bits(32) : 0);
+        if ( !pg )
+        {
+            order --;
+
+            if ( lowmem && order < min_low_order)
+            {
+                D11PRINT("Failed at min_low_order, allow high allocations\n");
+                order = get_11_allocation_size(kinfo->unassigned_mem.low);
+                lowmem = false;
+                continue;
+            }
+            if ( order >= min_order )
+                continue;
+
+            /* No more we can do */
+            break;
+        }
+
+        if ( !insert_11_bank(d, kinfo, pg, order) )
+        {
+            if ( kinfo->mem.nr_banks == NR_MEM_BANKS )
+                /* Nothing more we can do. */
+                break;
+
+            if ( lowmem )
+            {
+                D11PRINT("Allocation below bank 0, allow high allocations\n");
+                order = get_11_allocation_size(kinfo->unassigned_mem.low);
+                lowmem = false;
+                continue;
+            }
+            else
+            {
+                D11PRINT("Allocation below bank 0\n");
+                break;
+            }
+        }
+
+        /*
+         * Success, next time around try again to get the largest order
+         * allocation possible.
+         */
+        order = get_11_allocation_size(kinfo->unassigned_mem.low);
+    }
 
+    if ( kinfo->unassigned_mem.low )
+        printk("WARNING: Failed to allocate requested dom0 memory."
+               /* Don't want format this as PRIpaddr (16 digit hex) */
+               " %ldMB unallocated\n",
+               (unsigned long)kinfo->unassigned_mem.low >> 20);
+#endif
     for( i = 0; i < kinfo->mem.nr_banks; i++ )
     {
         printk("BANK[%d] %#"PRIpaddr"-%#"PRIpaddr" (%ldMB)\n",
@@ -374,7 +531,19 @@ static void allocate_memory(struct domain *d, struct kernel_info *kinfo)
     unsigned int bank = 0;
 
     if ( dom0_11_mapping )
+#ifndef ARM32_SEPAR_MEM_SPLIT
         return allocate_memory_11(d, kinfo);
+#else
+    {
+        allocate_memory_11(d, kinfo);
+        return allocate_dom0_high_memory(d, kinfo);
+    }
+#endif
+
+#ifdef ARM32_SEPAR_MEM_SPLIT
+    if (dom0_mem_high != 0)
+        printk("***WARNING*** We don't implement dom0_mem_high option for non 1:1 mapped domains!\n");
+#endif
 
     while ( (memory = dt_find_node_by_type(memory, "memory")) )
     {
@@ -389,7 +558,11 @@ static void allocate_memory(struct domain *d, struct kernel_info *kinfo)
             panic("Memory node has no reg property");
 
         for ( l = 0;
+#ifndef ARM32_SEPAR_MEM_SPLIT
               kinfo->unassigned_mem > 0 && l + reg_size <= reg_len
+#else
+              kinfo->unassigned_mem.low > 0 && l + reg_size <= reg_len
+#endif
                   && kinfo->mem.nr_banks < NR_MEM_BANKS;
               l += reg_size )
         {
@@ -399,8 +572,13 @@ static void allocate_memory(struct domain *d, struct kernel_info *kinfo)
                 panic("Unable to retrieve the bank %u for %s",
                       bank, dt_node_full_name(memory));
 
+#ifndef ARM32_SEPAR_MEM_SPLIT
             if ( size > kinfo->unassigned_mem )
                 size = kinfo->unassigned_mem;
+#else
+            if ( size > kinfo->unassigned_mem.low )
+                size = kinfo->unassigned_mem.low;
+#endif
 
             printk("Populate P2M %#"PRIx64"->%#"PRIx64"\n",
                    start, start + size);
@@ -410,7 +588,11 @@ static void allocate_memory(struct domain *d, struct kernel_info *kinfo)
             kinfo->mem.bank[kinfo->mem.nr_banks].size = size;
             kinfo->mem.nr_banks++;
 
+#ifndef ARM32_SEPAR_MEM_SPLIT
             kinfo->unassigned_mem -= size;
+#else
+            kinfo->unassigned_mem.low -= size;
+#endif
         }
     }
 }
@@ -1521,7 +1703,12 @@ int construct_dom0(struct domain *d)
 
     d->max_pages = ~0U;
 
+#ifndef ARM32_SEPAR_MEM_SPLIT
     kinfo.unassigned_mem = dom0_mem;
+#else
+    kinfo.unassigned_mem.low = dom0_mem;
+    kinfo.unassigned_mem.high = dom0_mem_high;
+#endif
 
     rc = kernel_probe(&kinfo);
     if ( rc < 0 )
diff --git a/xen/arch/arm/kernel.h b/xen/arch/arm/kernel.h
index c1b07d4..83fa0ed 100644
--- a/xen/arch/arm/kernel.h
+++ b/xen/arch/arm/kernel.h
@@ -16,7 +16,16 @@ struct kernel_info {
 #endif
 
     void *fdt; /* flat device tree */
+
+#ifndef ARM32_SEPAR_MEM_SPLIT
     paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */
+#else
+    struct {
+        paddr_t low; /* Low RAM not (yet) assigned to a bank */
+        paddr_t high; /* High RAM not (yet) assigned to a bank */
+    } unassigned_mem;
+#endif
+
     struct meminfo mem;
 
     /* kernel entry point */
-- 
2.8.2


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

  parent reply	other threads:[~2016-05-18 16:32 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-18 16:32 [PATCH RFC 00/18] System adjustment to customer needs Andrii Anisov
2016-05-18 16:32 ` [PATCH RFC 01/18] xen/tools: Fix virtual disks helper scripts Andrii Anisov
2016-05-19 11:34   ` Wei Liu
2016-05-19 20:54     ` Andrii Anisov
2016-05-19 22:58       ` Wei Liu
2016-05-20  8:30         ` Andrii Anisov
2016-05-18 16:32 ` [PATCH RFC 02/18] kbdif: add raw events passing Andrii Anisov
2016-05-19  9:28   ` Jan Beulich
2016-05-18 16:32 ` [PATCH RFC 03/18] xen/arm: allow to allocate 1/128/256/512 Mb memory chunks Andrii Anisov
2016-05-19 11:10   ` Julien Grall
2016-05-18 16:32 ` [PATCH RFC 04/18] libxl: add ability to set rambase_pfn via cfg file Andrii Anisov
2016-05-19 11:34   ` Wei Liu
2016-05-19 11:36   ` Julien Grall
2016-05-18 16:32 ` [PATCH RFC 05/18] xen/arm: allow reassigning of hw interrupts to guest domain Andrii Anisov
2016-05-19 12:19   ` Julien Grall
2016-05-18 16:32 ` [PATCH RFC 06/18] libxl: parse config data during domain reboot Andrii Anisov
2016-05-19 11:35   ` Wei Liu
2016-05-18 16:32 ` [PATCH RFC 07/18] tools/misc: Modify Xen watchdog daemon Andrii Anisov
2016-05-19 11:35   ` Wei Liu
2016-05-18 16:32 ` [PATCH RFC 08/18] tools/misc: Set timeout value from " Andrii Anisov
2016-05-19 11:35   ` Wei Liu
2016-05-18 16:32 ` [PATCH RFC 09/18] tools: Allow to cross-compile xentop Andrii Anisov
2016-05-19 11:35   ` Wei Liu
2016-05-18 16:32 ` [PATCH RFC 10/18] xen: arm: add batch support to the XENMEM_p2m_lookup operation Andrii Anisov
2016-05-19  9:36   ` Jan Beulich
2016-05-18 16:32 ` [PATCH RFC 11/18] arm: Fix 1-to-1 Dom0 memory allocation of any size Andrii Anisov
2016-05-18 16:32 ` [PATCH RFC 12/18] libxl: Fix unneeded domain reboot during destroy routine Andrii Anisov
2016-05-19 11:35   ` Wei Liu
2016-05-18 16:32 ` [PATCH RFC 13/18] xen: introduce and use 'dom0_rambase_pfn' setting for kernel Dom0 Andrii Anisov
2016-05-19  9:41   ` Jan Beulich
2016-05-19 12:26     ` Julien Grall
2016-05-19 12:50       ` Jan Beulich
2016-05-19 13:39   ` Julien Grall
2016-05-19 13:58     ` Oleksandr Dmytryshyn
2016-05-19 14:34       ` Julien Grall
2016-05-20  8:39         ` Oleksandr Dmytryshyn
2016-05-19 14:36       ` Jan Beulich
2016-05-20  8:45         ` Oleksandr Dmytryshyn
2016-05-20  9:59           ` Jan Beulich
2016-05-20 14:19             ` Oleksandr Dmytryshyn
2016-05-20 15:04               ` Julien Grall
2016-05-20 16:05                 ` Edgar E. Iglesias
2016-05-23  9:52                   ` Oleksandr Dmytryshyn
2016-05-30 11:07                   ` Stefano Stabellini
2016-05-31 14:04                   ` Oleksandr Dmytryshyn
2016-06-01 14:01                     ` Edgar E. Iglesias
2016-05-18 16:32 ` [PATCH RFC 14/18] xen: flask: Add possiblity to forward irqs into domU domains Andrii Anisov
2016-05-18 16:32 ` [PATCH RFC 15/18] arm: Add ability to relocate Xen in over 4GB space Andrii Anisov
2016-05-19  9:42   ` Jan Beulich
2016-05-19 13:53   ` Julien Grall
2016-05-24 17:18   ` Julien Grall
2016-05-18 16:32 ` Andrii Anisov [this message]
2016-05-18 16:32 ` [PATCH RFC 17/18] tools: Introduce ARM32_SEPAR_MEM_SPLIT option Andrii Anisov
2016-05-19 11:35   ` Wei Liu
2016-05-18 16:32 ` [PATCH RFC 18/18] arm: Add ability to allocate Xen heap in lowmem Andrii Anisov
2016-05-18 17:26 ` [PATCH RFC 00/18] System adjustment to customer needs Julien Grall
2016-05-19 19:45   ` Andrii Anisov
2016-05-18 19:17 ` [Embedded-pv-devel] " Meng Xu
2016-05-19 11:00   ` Julien Grall
2016-05-19 21:28     ` Andrii Anisov
2016-05-20 10:33       ` Julien Grall
2016-05-20 16:24         ` Andrii Anisov
2016-05-23  9:19           ` Julien Grall
2016-05-20 17:09         ` Andrii Anisov
2016-05-23  9:13           ` Julien Grall
2016-05-19 22:08     ` Andrii Anisov
2016-05-19 21:53   ` Andrii Anisov
2016-05-20 15:21     ` Meng Xu
2016-05-20 17:23       ` Andrii Anisov
2016-05-20 17:28         ` Meng Xu
2016-05-21 14:32       ` Julien Grall
2016-05-21 14:52         ` Meng Xu

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=1463589161-4153-17-git-send-email-andrii.anisov@globallogic.com \
    --to=andrii.anisov@globallogic.com \
    --cc=embedded-pv-devel@lists.xenproject.org \
    --cc=iurii.mykhalskyi@globallogic.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).