@@ -682,6 +682,17 @@ static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *kinfo)
if ( kinfo->dom0less_feature & DOM0LESS_ENHANCED_NO_XS )
{
+ /*
+ * Find the guest magic region for 1:1 dom0less domU when the extended
+ * region is not enabled.
+ */
+ if ( !opt_ext_regions || is_32bit_domain(d) )
+ {
+ ret = find_11_domU_magic_region(d, kinfo);
+ if ( ret )
+ goto err;
+ }
+
ret = make_hypervisor_node(d, kinfo, addrcells, sizecells);
if ( ret )
goto err;
@@ -46,7 +46,7 @@ integer_param("dom0_max_vcpus", opt_dom0_max_vcpus);
* If true, the extended regions support is enabled for dom0 and
* dom0less domUs.
*/
-static bool __initdata opt_ext_regions = true;
+bool __initdata opt_ext_regions = true;
boolean_param("ext_regions", opt_ext_regions);
static u64 __initdata dom0_mem;
@@ -1196,6 +1196,28 @@ int __init make_hypervisor_node(struct domain *d,
printk(XENLOG_WARNING "%pd: failed to allocate extended regions\n",
d);
nr_ext_regions = ext_regions->nr_banks;
+
+ /*
+ * If extended region is enabled, carve out the 16MB guest magic page
+ * regions from the first bank of extended region (at least 64MB) for
+ * the 1:1 dom0less DomUs
+ */
+ if ( is_domain_direct_mapped(d) && !is_hardware_domain(d) )
+ {
+ struct mem_map_domain *mem_map = &d->arch.mem_map;
+
+ for ( i = 0; i < mem_map->nr_mem_regions; i++ )
+ {
+ if ( mem_map->regions[i].type == GUEST_MEM_REGION_MAGIC )
+ {
+ mem_map->regions[i].start = ext_regions->bank[0].start;
+ mem_map->regions[i].size = GUEST_MAGIC_SIZE;
+
+ ext_regions->bank[0].start += GUEST_MAGIC_SIZE;
+ ext_regions->bank[0].size -= GUEST_MAGIC_SIZE;
+ }
+ }
+ }
}
reg = xzalloc_array(__be32, (nr_ext_regions + 1) * (addrcells + sizecells));
@@ -4,6 +4,8 @@
#include <xen/sched.h>
#include <asm/kernel.h>
+extern bool opt_ext_regions;
+
typedef __be32 gic_interrupt_t[3];
bool allocate_bank_memory(struct domain *d, struct kernel_info *kinfo,
@@ -12,6 +12,7 @@ void allocate_static_memory(struct domain *d, struct kernel_info *kinfo,
void assign_static_memory_11(struct domain *d, struct kernel_info *kinfo,
const struct dt_device_node *node);
void init_staticmem_pages(void);
+int find_11_domU_magic_region(struct domain *d, struct kernel_info *kinfo);
#else /* !CONFIG_STATIC_MEMORY */
@@ -31,6 +32,12 @@ static inline void assign_static_memory_11(struct domain *d,
static inline void init_staticmem_pages(void) {};
+static inline int find_11_domU_magic_region(struct domain *d,
+ struct kernel_info *kinfo)
+{
+ return 0;
+}
+
#endif /* CONFIG_STATIC_MEMORY */
#endif /* __ASM_STATIC_MEMORY_H_ */
@@ -2,6 +2,7 @@
#include <xen/sched.h>
+#include <asm/domain_build.h>
#include <asm/static-memory.h>
static bool __init append_static_memory_to_bank(struct domain *d,
@@ -276,6 +277,44 @@ void __init init_staticmem_pages(void)
}
}
+int __init find_11_domU_magic_region(struct domain *d,
+ struct kernel_info *kinfo)
+{
+ if ( is_domain_direct_mapped(d) )
+ {
+ struct meminfo *magic_region = xzalloc(struct meminfo);
+ struct mem_map_domain *mem_map = &d->arch.mem_map;
+ unsigned int i;
+ int ret = 0;
+
+ if ( !magic_region )
+ return -ENOMEM;
+
+ ret = find_unused_regions(d, kinfo, magic_region, GUEST_MAGIC_SIZE);
+ if ( ret )
+ {
+ printk(XENLOG_WARNING
+ "%pd: failed to find a region for domain magic pages\n", d);
+ xfree(magic_region);
+ return -ENOENT;
+ }
+
+ /* Update the domain memory map. */
+ for ( i = 0; i < mem_map->nr_mem_regions; i++ )
+ {
+ if ( mem_map->regions[i].type == GUEST_MEM_REGION_MAGIC )
+ {
+ mem_map->regions[i].start = magic_region->bank[0].start;
+ mem_map->regions[i].size = GUEST_MAGIC_SIZE;
+ }
+ }
+
+ xfree(magic_region);
+ }
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
For 1:1 direct-mapped dom0less DomUs, the magic pages should not clash with any RAM region. To find a proper region for guest magic pages, we can reuse the logic of finding domain extended regions. If the extended region is enabled, since the extended region banks are at least 64MB, carve out the first 16MB from the first extended region bank for magic pages of direct-mapped domU. If the extended region is disabled, call the newly introduced helper find_11_domU_magic_region() to find a GUEST_MAGIC_SIZE sized unused region. Reported-by: Alec Kwapis <alec.kwapis@medtronic.com> Signed-off-by: Henry Wang <xin.wang2@amd.com> --- v3: - Extract the logic of finding unallocated spaces for magic pages of direct-mapped domU to a dedicated function in static-memory.c - Properly handle error and free memory in find_11_domU_magic_region() v2: - New patch --- xen/arch/arm/dom0less-build.c | 11 +++++++ xen/arch/arm/domain_build.c | 24 ++++++++++++++- xen/arch/arm/include/asm/domain_build.h | 2 ++ xen/arch/arm/include/asm/static-memory.h | 7 +++++ xen/arch/arm/static-memory.c | 39 ++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-)