|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 17/18] tools: Introduce ARM32_SEPAR_MEM_SPLIT option
From: Iurii Mykhalskyi <iurii.mykhalskyi@xxxxxxxxxxxxxxx>
This option enables separate memory allocation in
low & over 4GB address space.
With this option enabled in domain config files
"memory" parameter are used to specify domain low memory
"memory_high" - to specify over 4GB allocated memory
If you didn't specify high memory with this option enabled,
domain memory will be limited to 4GB (zone 20)
Signed-off-by: Iurii Mykhalskyi <iurii.mykhalskyi@xxxxxxxxxxxxxxx>
Signed-off-by: Iurii Konovalenko <iurii.konovalenko@xxxxxxxxxxxxxxx>
---
tools/libxc/Makefile | 2 ++
tools/libxc/include/xc_dom.h | 24 +++++++++++--
tools/libxc/xc_dom_arm.c | 66 +++++++++++++++++++++++++++++++++++
tools/libxc/xc_dom_compat_linux.c | 5 +++
tools/libxc/xc_dom_core.c | 51 ++++++++++++++++++++++-----
tools/libxl/Makefile | 2 ++
tools/libxl/libxl_arm.c | 11 ++++++
tools/libxl/libxl_dom.c | 23 ++++++++++++
tools/libxl/libxl_types.idl | 1 +
tools/libxl/xl_cmdimpl.c | 5 +++
tools/xenstore/init-xenstore-domain.c | 5 +++
xen/arch/arm/domain_build.c | 11 +++++-
xen/common/memory.c | 16 ++++++++-
xen/common/page_alloc.c | 23 ++++++++++++
xen/include/public/memory.h | 6 ++++
xen/include/xen/mm.h | 6 ++++
16 files changed, 245 insertions(+), 12 deletions(-)
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index a0f899b..84d21b6 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -112,6 +112,8 @@ CFLAGS += -I. -I./include $(CFLAGS_xeninclude)
# Needed for posix_fadvise64() in xc_linux.c
CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE
+CFLAGS-$(ARM32_SEPAR_MEM_SPLIT) += -DARM32_SEPAR_MEM_SPLIT
+
CFLAGS += $(PTHREAD_CFLAGS)
CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 600aef6..10bb6ab 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -129,12 +129,22 @@ struct xc_dom_image {
* in rambase_pfn.
*/
xen_pfn_t rambase_pfn;
+#ifndef ARM32_SEPAR_MEM_SPLIT
xen_pfn_t total_pages;
+#else
+ xen_pfn_t low_mem_pages;
+ xen_pfn_t high_mem_pages;
+#endif
xen_pfn_t p2m_size; /* number of pfns covered by p2m */
struct xc_dom_phys *phys_pages;
int realmodearea_log;
#if defined (__arm__) || defined(__aarch64__)
+#ifndef ARM32_SEPAR_MEM_SPLIT
xen_pfn_t rambank_size[GUEST_RAM_BANKS];
+#else
+ xen_pfn_t rambank_size_low[GUEST_RAM_BANKS];
+ xen_pfn_t rambank_size_high[GUEST_RAM_BANKS];
+#endif
#endif
/* malloc memory pool */
@@ -181,6 +191,12 @@ struct xc_dom_image {
int (*allocate) (struct xc_dom_image * dom, xen_vaddr_t up_to);
};
+#ifndef ARM32_SEPAR_MEM_SPLIT
+#define XC_DOM_TOTAL_PAGES(dom) ((dom)->total_pages)
+#else
+#define XC_DOM_TOTAL_PAGES(dom) ((dom)->low_mem_pages + (dom)->high_mem_pages)
+#endif
+
/* --- pluggable kernel loader ------------------------------------- */
struct xc_dom_loader {
@@ -228,7 +244,11 @@ struct xc_dom_image *xc_dom_allocate(xc_interface *xch,
void xc_dom_release_phys(struct xc_dom_image *dom);
void xc_dom_release(struct xc_dom_image *dom);
int xc_dom_rambase_init(struct xc_dom_image *dom, uint64_t rambase);
+#ifndef ARM32_SEPAR_MEM_SPLIT
int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb);
+#else
+int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb_low,
unsigned int mem_mb_high);
+#endif
/* Set this larger if you have enormous ramdisks/kernels. Note that
* you should trust all kernels not to be maliciously large (e.g. to
@@ -379,7 +399,7 @@ static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image
*dom, xen_pfn_t pfn)
{
if (dom->shadow_enabled)
return pfn;
- if (pfn < dom->rambase_pfn || pfn >= dom->rambase_pfn + dom->total_pages)
+ if (pfn < dom->rambase_pfn || pfn >= dom->rambase_pfn +
XC_DOM_TOTAL_PAGES(dom))
return INVALID_MFN;
return dom->p2m_host[pfn - dom->rambase_pfn];
}
@@ -389,7 +409,7 @@ static inline xen_pfn_t xc_dom_p2m_guest(struct
xc_dom_image *dom,
{
if (xc_dom_feature_translated(dom))
return pfn;
- if (pfn < dom->rambase_pfn || pfn >= dom->rambase_pfn + dom->total_pages)
+ if (pfn < dom->rambase_pfn || pfn >= dom->rambase_pfn +
XC_DOM_TOTAL_PAGES(dom))
return INVALID_MFN;
return dom->p2m_host[pfn - dom->rambase_pfn];
}
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index 96df669..d995241 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -306,8 +306,19 @@ static int populate_one_size(struct xc_dom_image *dom, int
pfn_shift,
for ( i = 0 ; i < count ; i ++ )
extents[i] = base_pfn + (i<<pfn_shift);
+#ifdef ARM32_SEPAR_MEM_SPLIT
+ if (base_pfn < 0x100000) { /* base_pfn less then 4GB */
+ nr = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count,
+ pfn_shift, XENMEMF_only_low_mem, extents);
+ } else {
+ nr = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count,
+ pfn_shift, XENMEMF_only_high_mem, extents);
+ }
+#else
nr = xc_domain_populate_physmap(dom->xch, dom->guest_domid, count,
pfn_shift, 0, extents);
+#endif
+
if ( nr <= 0 ) return nr;
DOMPRINTF("%s: populated %#x/%#x entries with shift %d",
__FUNCTION__, nr, count, pfn_shift);
@@ -414,7 +425,11 @@ int arch_setup_meminit(struct xc_dom_image *dom)
xen_pfn_t pfn;
uint64_t modbase;
+#ifndef ARM32_SEPAR_MEM_SPLIT
uint64_t ramsize = (uint64_t)dom->total_pages << XC_PAGE_SHIFT;
+#else
+ uint64_t ramsize = (uint64_t)dom->low_mem_pages << XC_PAGE_SHIFT;
+#endif
uint64_t guest_rambase = (uint64_t)dom->rambase_pfn << XC_PAGE_SHIFT;
uint64_t guest_ramsize = (GUEST_RAM0_BASE + GUEST_RAM0_SIZE) -
guest_rambase;
@@ -471,12 +486,41 @@ int arch_setup_meminit(struct xc_dom_image *dom)
p2m_size = ( bankbase[i] + banksize - bankbase[0] ) >> XC_PAGE_SHIFT;
+#ifndef ARM32_SEPAR_MEM_SPLIT
dom->rambank_size[i] = banksize >> XC_PAGE_SHIFT;
+#else
+ dom->rambank_size_low[i] = banksize >> XC_PAGE_SHIFT;
+#endif
}
+#ifndef ARM32_SEPAR_MEM_SPLIT
assert(dom->rambank_size[0] != 0);
+#else
+ assert(dom->rambank_size_low[0] != 0);
+#endif
assert(ramsize == 0); /* Too much RAM is rejected above */
+
+#ifdef ARM32_SEPAR_MEM_SPLIT
+ ramsize = (uint64_t)dom->high_mem_pages << XC_PAGE_SHIFT;
+
+ if (ramsize) {
+ for ( i = 0; ramsize && i < GUEST_RAM_BANKS; i++ )
+ {
+ uint64_t banksize = ramsize > bankmax[i] ? bankmax[i] : ramsize;
+
+ ramsize -= banksize;
+ p2m_size += ( bankbase[1] + banksize - bankbase[1] ) >>
XC_PAGE_SHIFT;
+
+ dom->rambank_size_high[i] = banksize >> XC_PAGE_SHIFT;
+ DOMPRINTF("%s: rambank_size_high: %"PRIx64, __FUNCTION__,
dom->rambank_size_high[i]);
+ }
+
+ assert(ramsize == 0);
+ assert(dom->rambank_size_high[0] != 0);
+ }
+#endif
+
dom->p2m_size = p2m_size;
dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * p2m_size);
if ( dom->p2m_host == NULL )
@@ -485,6 +529,7 @@ int arch_setup_meminit(struct xc_dom_image *dom)
dom->p2m_host[pfn] = INVALID_P2M_ENTRY;
/* setup initial p2m and allocate guest memory */
+#ifndef ARM32_SEPAR_MEM_SPLIT
for ( i = 0; i < GUEST_RAM_BANKS && dom->rambank_size[i]; i++ )
{
if ((rc = populate_guest_memory(dom,
@@ -492,6 +537,23 @@ int arch_setup_meminit(struct xc_dom_image *dom)
dom->rambank_size[i])))
return rc;
}
+#else
+ for ( i = 0; i < GUEST_RAM_BANKS && dom->rambank_size_low[i]; i++ )
+ {
+ if ((rc = populate_guest_memory(dom,
+ bankbase[i] >> XC_PAGE_SHIFT,
+ dom->rambank_size_low[i])))
+ return rc;
+ }
+
+ for ( i = 0; i < GUEST_RAM_BANKS && dom->rambank_size_high[i]; i++ )
+ {
+ if ((rc = populate_guest_memory(dom,
+ bankbase[1] >> XC_PAGE_SHIFT,
+ dom->rambank_size_high[i])))
+ return rc;
+ }
+#endif
/*
* We try to place dtb+initrd at 128MB or if we have less RAM
@@ -501,7 +563,11 @@ int arch_setup_meminit(struct xc_dom_image *dom)
* If changing this then consider
* xen/arch/arm/kernel.c:place_modules as well.
*/
+#ifndef ARM32_SEPAR_MEM_SPLIT
bank0end = bankbase[0] + ((uint64_t)dom->rambank_size[0] << XC_PAGE_SHIFT);
+#else
+ bank0end = bankbase[0] + ((uint64_t)dom->rambank_size_low[0] <<
XC_PAGE_SHIFT);
+#endif
if ( bank0end >= ram128mb + modsize && kernend < ram128mb )
modbase = ram128mb;
diff --git a/tools/libxc/xc_dom_compat_linux.c
b/tools/libxc/xc_dom_compat_linux.c
index a3abb99..9f35126 100644
--- a/tools/libxc/xc_dom_compat_linux.c
+++ b/tools/libxc/xc_dom_compat_linux.c
@@ -53,8 +53,13 @@ static int xc_linux_build_internal(struct xc_dom_image *dom,
goto out;
if ( (rc = xc_dom_parse_image(dom)) != 0 )
goto out;
+#ifndef ARM32_SEPAR_MEM_SPLIT
if ( (rc = xc_dom_mem_init(dom, mem_mb)) != 0 )
goto out;
+#else
+ if ( (rc = xc_dom_mem_init(dom, mem_mb, 0)) != 0 )
+ goto out;
+#endif
if ( (rc = xc_dom_boot_mem_init(dom)) != 0 )
goto out;
if ( (rc = xc_dom_build_image(dom)) != 0 )
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index 8466677..5911b1d 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -437,12 +437,12 @@ void *xc_dom_pfn_to_ptr_retcount(struct xc_dom_image
*dom, xen_pfn_t pfn,
*count_out = 0;
offset = pfn - dom->rambase_pfn;
- if ( offset > dom->total_pages || /* multiple checks to avoid overflows */
- count > dom->total_pages ||
- offset > dom->total_pages - count )
+ if ( offset > XC_DOM_TOTAL_PAGES(dom) || /* multiple checks to avoid
overflows */
+ count > XC_DOM_TOTAL_PAGES(dom) ||
+ offset > XC_DOM_TOTAL_PAGES(dom) - count )
{
DOMPRINTF("%s: pfn %"PRI_xen_pfn" out of range (0x%" PRIpfn " > 0x%"
PRIpfn ")",
- __FUNCTION__, pfn, offset, dom->total_pages);
+ __FUNCTION__, pfn, offset, XC_DOM_TOTAL_PAGES(dom));
return NULL;
}
@@ -566,14 +566,14 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
pfn = (seg->vstart - dom->parms.virt_base) / page_size;
seg->pfn = pfn + dom->rambase_pfn;
- if ( pages > dom->total_pages || /* multiple test avoids overflow probs */
- pfn > dom->total_pages ||
- pages > dom->total_pages - pfn)
+ if ( pages > XC_DOM_TOTAL_PAGES(dom) || /* multiple test avoids overflow
probs */
+ pfn > XC_DOM_TOTAL_PAGES(dom) ||
+ pages > XC_DOM_TOTAL_PAGES(dom) - pfn)
{
xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
"%s: segment %s too large (0x%"PRIpfn" > "
"0x%"PRIpfn" - 0x%"PRIpfn" pages)",
- __FUNCTION__, name, pages, dom->total_pages, pfn);
+ __FUNCTION__, name, pages, XC_DOM_TOTAL_PAGES(dom), pfn);
return -1;
}
@@ -891,6 +891,7 @@ int xc_dom_rambase_init(struct xc_dom_image *dom, uint64_t
rambase)
return 0;
}
+#ifndef ARM32_SEPAR_MEM_SPLIT
int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb)
{
unsigned int page_shift;
@@ -916,6 +917,40 @@ int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int
mem_mb)
return 0;
}
+#else
+int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb_low,
unsigned int mem_mb_high)
+{
+ unsigned int page_shift;
+ xen_pfn_t nr_pages_low;
+ xen_pfn_t nr_pages_high;
+
+ dom->arch_hooks = xc_dom_find_arch_hooks(dom->xch, dom->guest_type);
+ if ( dom->arch_hooks == NULL )
+ {
+ xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: arch hooks not set",
+ __FUNCTION__);
+ return -1;
+ }
+
+ page_shift = XC_DOM_PAGE_SHIFT(dom);
+ nr_pages_low = mem_mb_low << (20 - page_shift);
+ nr_pages_high = mem_mb_high << (20 - page_shift);
+
+ DOMPRINTF("%s: mem %d MB, low pages 0x%" PRIpfn " pages, %dk each",
+ __FUNCTION__, mem_mb_low, nr_pages_low, 1 << (page_shift-10));
+
+ DOMPRINTF("%s: mem %d MB, high pages 0x%" PRIpfn " pages, %dk each",
+ __FUNCTION__, mem_mb_high, nr_pages_high, 1 << (page_shift-10));
+
+ dom->low_mem_pages = nr_pages_low;
+ dom->high_mem_pages = nr_pages_high;
+
+ DOMPRINTF("%s: Total pages 0x%" PRIpfn,
+ __FUNCTION__, XC_DOM_TOTAL_PAGES(dom));
+
+ return 0;
+}
+#endif
int xc_dom_update_guest_p2m(struct xc_dom_image *dom)
{
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index c5ecec1..7cf4985 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -36,6 +36,8 @@ CFLAGS_LIBXL += -Wshadow
LIBXL_LIBS-$(CONFIG_ARM) += -lfdt
+CFLAGS-$(ARM32_SEPAR_MEM_SPLIT) += -DARM32_SEPAR_MEM_SPLIT
+
CFLAGS += $(PTHREAD_CFLAGS)
LDFLAGS += $(PTHREAD_LDFLAGS)
LIBXL_LIBS += $(PTHREAD_LIBS)
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 7f9547b..340ecf9 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -916,7 +916,11 @@ int libxl__arch_domain_finalise_hw_description(libxl__gc
*gc,
struct xc_dom_image *dom)
{
void *fdt = dom->devicetree_blob;
+#ifndef ARM32_SEPAR_MEM_SPLIT
int i;
+#else
+ uint64_t size;
+#endif
uint64_t guest_rambase = (uint64_t)dom->rambase_pfn << XC_PAGE_SHIFT;
@@ -953,11 +957,18 @@ int libxl__arch_domain_finalise_hw_description(libxl__gc
*gc,
}
+#ifndef ARM32_SEPAR_MEM_SPLIT
for (i = 0; i < GUEST_RAM_BANKS; i++) {
const uint64_t size = (uint64_t)dom->rambank_size[i] << XC_PAGE_SHIFT;
finalise_one_memory_node(gc, fdt, bankbase[i], size);
}
+#else
+ size = (uint64_t)dom->rambank_size_low[0] << XC_PAGE_SHIFT;
+ finalise_one_memory_node(gc, fdt, bankbase[0], size);
+ size = (uint64_t)dom->rambank_size_high[0] << XC_PAGE_SHIFT;
+ finalise_one_memory_node(gc, fdt, bankbase[1], size);
+#endif
debug_dump_fdt(gc, fdt);
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index be6598f..09bb0fa 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -402,11 +402,19 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
}
}
+#ifndef ARM32_SEPAR_MEM_SPLIT
if (xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb +
LIBXL_MAXMEM_CONSTANT) < 0) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't set max memory");
return ERROR_FAIL;
}
+#else
+ if (xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb +
info->target_memkb_high +
+ LIBXL_MAXMEM_CONSTANT) < 0) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't set max memory");
+ return ERROR_FAIL;
+ }
+#endif
xs_domid = xs_read(ctx->xsh, XBT_NULL, "/tool/xenstored/domid", NULL);
state->store_domid = xs_domid ? atoi(xs_domid) : 0;
@@ -525,11 +533,19 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid,
? LIBXL_MAXMEM_CONSTANT : 0;
ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
+#ifndef ARM32_SEPAR_MEM_SPLIT
ents[0] = "memory/static-max";
ents[1] = GCSPRINTF("%"PRId64, info->max_memkb);
ents[2] = "memory/target";
ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb
- mem_target_fudge);
+#else
+ ents[0] = "memory/static-max";
+ ents[1] = GCSPRINTF("%"PRId64, info->max_memkb + info->target_memkb_high);
+ ents[2] = "memory/target";
+ ents[3] = GCSPRINTF("%"PRId64, info->target_memkb +
info->target_memkb_high - info->video_memkb
+ - mem_target_fudge);
+#endif
ents[4] = "memory/videoram";
ents[5] = GCSPRINTF("%"PRId64, info->video_memkb);
ents[6] = "domid";
@@ -717,10 +733,17 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
LOGE(ERROR, "libxl__arch_domain_init_hw_description failed");
goto out;
}
+#ifndef ARM32_SEPAR_MEM_SPLIT
if ( (ret = xc_dom_mem_init(dom, info->target_memkb / 1024)) != 0 ) {
LOGE(ERROR, "xc_dom_mem_init failed");
goto out;
}
+#else
+ if ( (ret = xc_dom_mem_init(dom, info->target_memkb / 1024,
info->target_memkb_high / 1024)) != 0 ) {
+ LOGE(ERROR, "xc_dom_mem_init failed");
+ goto out;
+ }
+#endif
if ( (ret = xc_dom_boot_mem_init(dom)) != 0 ) {
LOGE(ERROR, "xc_dom_boot_mem_init failed");
goto out;
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index b6cc8d2..cd12117 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -414,6 +414,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
("tsc_mode", libxl_tsc_mode),
("max_memkb", MemKB),
("target_memkb", MemKB),
+ ("target_memkb_high", MemKB, {'init_val': '0'}),
("video_memkb", MemKB),
("shadow_memkb", MemKB),
("rambase", uint64, {'init_val': 'LIBXL_INVALID_RAM_BASE'}),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 98a46bc..63a6b17 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1350,6 +1350,11 @@ static void parse_config_data(const char *config_source,
if (!xlu_cfg_get_long (config, "memory", &l, 0))
b_info->target_memkb = l * 1024;
+#ifdef ARM32_SEPAR_MEM_SPLIT
+ if (!xlu_cfg_get_long (config, "memory_high", &l, 0))
+ b_info->target_memkb_high = l * 1024;
+#endif
+
if (!xlu_cfg_get_long (config, "maxmem", &l, 0))
b_info->max_memkb = l * 1024;
diff --git a/tools/xenstore/init-xenstore-domain.c
b/tools/xenstore/init-xenstore-domain.c
index 0d12169..c759800 100644
--- a/tools/xenstore/init-xenstore-domain.c
+++ b/tools/xenstore/init-xenstore-domain.c
@@ -54,8 +54,13 @@ static int build(xc_interface *xch, int argc, char** argv)
if (rv) goto err;
rv = xc_dom_parse_image(dom);
if (rv) goto err;
+#ifndef ARM32_SEPAR_MEM_SPLIT
rv = xc_dom_mem_init(dom, maxmem);
if (rv) goto err;
+#else
+ rv = xc_dom_mem_init(dom, maxmem, 0);
+ if (rv) goto err;
+#endif
rv = xc_dom_boot_mem_init(dom);
if (rv) goto err;
rv = xc_dom_build_image(dom);
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index a63958b..0678ae7 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -349,6 +349,7 @@ static void allocate_memory_11(struct domain *d, struct
kernel_info *kinfo)
paddr_t mem_size = kinfo->unassigned_mem;
#else
unsigned int order = get_11_allocation_size(kinfo->unassigned_mem.low);
+ paddr_t mem_size = kinfo->unassigned_mem.low;
#endif
int i;
@@ -457,9 +458,12 @@ static void allocate_memory_11(struct domain *d, struct
kernel_info *kinfo)
(unsigned long)kinfo->unassigned_mem >> 20);
#else
order = get_11_allocation_size(kinfo->unassigned_mem.low);
+ if ( opt_dom0_rambase_pfn )
+ rambase_pfn += (mem_size - kinfo->unassigned_mem.low) >> PAGE_SHIFT;
+
while ( kinfo->unassigned_mem.low && kinfo->mem.nr_banks < NR_MEM_BANKS )
{
- pg = alloc_domheap_pages(d, order, lowmem ? MEMF_bits(32) : 0);
+ pg = alloc_domheap_pages_pfn(d, order, lowmem ? MEMF_bits(32) : 0,
rambase_pfn);
if ( !pg )
{
order --;
@@ -503,6 +507,11 @@ static void allocate_memory_11(struct domain *d, struct
kernel_info *kinfo)
* allocation possible.
*/
order = get_11_allocation_size(kinfo->unassigned_mem.low);
+ if ( opt_dom0_rambase_pfn )
+ {
+ rambase_pfn += (mem_size - kinfo->unassigned_mem.low) >>
PAGE_SHIFT;
+ mem_size = kinfo->unassigned_mem.low;
+ }
}
if ( kinfo->unassigned_mem.low )
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 8baed72..54d993a 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -169,7 +169,11 @@ static void populate_physmap(struct memop_args *a)
}
else
{
- if ( is_domain_direct_mapped(d) )
+ if ( is_domain_direct_mapped(d)
+#ifdef ARM32_SEPAR_MEM_SPLIT
+ && !(a->memflags & MEMF_only_high_mem)
+#endif
+ )
{
mfn = gpfn;
@@ -871,6 +875,16 @@ long do_memory_op(unsigned long cmd,
XEN_GUEST_HANDLE_PARAM(void) arg)
&& (reservation.mem_flags & XENMEMF_populate_on_demand) )
args.memflags |= MEMF_populate_on_demand;
+#ifdef ARM32_SEPAR_MEM_SPLIT
+ if ( op == XENMEM_populate_physmap
+ && ( reservation.mem_flags & XENMEMF_only_low_mem) )
+ args.memflags |= MEMF_only_low_mem;
+
+ if ( op == XENMEM_populate_physmap
+ && ( reservation.mem_flags & XENMEMF_only_high_mem) )
+ args.memflags |= MEMF_only_high_mem;
+#endif
+
if ( xsm_memory_adjust_reservation(XSM_TARGET, current->domain, d) )
{
rcu_unlock_domain(d);
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index d0c0fbb..437efbd 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -1718,6 +1718,9 @@ int assign_pages(
return -1;
}
+#ifdef ARM32_SEPAR_MEM_SPLIT
+#define ZONE_4G (20) /* flsl(4G) - PAGE_SHIFT */
+#endif
struct page_info *alloc_domheap_pages_pfn(
struct domain *d, unsigned int order, unsigned int memflags, xen_pfn_t pfn)
@@ -1739,11 +1742,31 @@ struct page_info *alloc_domheap_pages_pfn(
if ( dma_bitsize && ((dma_zone = bits_to_zone(dma_bitsize)) < zone_hi) )
pg = alloc_heap_pages_pfn(dma_zone + 1, zone_hi, order, memflags, d,
pfn);
+#ifdef ARM32_SEPAR_MEM_SPLIT
+ if ( pg == NULL) {
+ unsigned int low = MEMZONE_XEN + 1;
+ unsigned int high = zone_hi;
+
+ if ( memflags & MEMF_no_dma )
+ return NULL;
+
+ if ( memflags & MEMF_only_low_mem )
+ high = ZONE_4G;
+
+ if ( memflags & MEMF_only_high_mem )
+ low = ZONE_4G;
+
+ if ( (pg = alloc_heap_pages_pfn(low, high, order,
+ memflags, d, pfn)) == NULL )
+ return NULL;
+ }
+#else
if ( (pg == NULL) &&
((memflags & MEMF_no_dma) ||
((pg = alloc_heap_pages_pfn(MEMZONE_XEN + 1, zone_hi, order,
memflags, d, pfn)) == NULL)) )
return NULL;
+#endif
if ( d && !(memflags & MEMF_no_owner) &&
assign_pages(d, pg, order, memflags) )
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index dfc5171..ad7c55d 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -51,6 +51,12 @@
/* NUMA node to allocate from. */
#define XENMEMF_node(x) (((x) + 1) << 8)
#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu)
+#ifdef ARM32_SEPAR_MEM_SPLIT
+/* Flag to populate physmap only from low 4GB memory space */
+#define XENMEMF_only_low_mem (1<<6)
+/* Flag to populate physmap only from over 4GB memory space */
+#define XENMEMF_only_high_mem (1<<7)
+#endif
/* Flag to populate physmap with populate-on-demand entries */
#define XENMEMF_populate_on_demand (1<<16)
/* Flag to request allocation only from the node specified */
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index 83e4913..a74c7d4 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -178,6 +178,12 @@ struct npfec {
#define _MEMF_exact_node 4
#define MEMF_exact_node (1U<<_MEMF_exact_node)
#define _MEMF_no_owner 5
+#ifdef ARM32_SEPAR_MEM_SPLIT
+#define _MEMF_only_low_mem 6
+#define MEMF_only_low_mem (1U<<_MEMF_only_low_mem)
+#define _MEMF_only_high_mem 7
+#define MEMF_only_high_mem (1U<<_MEMF_only_high_mem)
+#endif
#define MEMF_no_owner (1U<<_MEMF_no_owner)
#define _MEMF_node 8
#define MEMF_node_mask ((1U << (8 * sizeof(nodeid_t))) - 1)
--
2.8.2
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |