[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH V3 3/3] libxl/arm: Add handling of extended regions for DomU
On Fri, 24 Sep 2021, Oleksandr Tyshchenko wrote: > From: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx> > > The extended region (safe range) is a region of guest physical > address space which is unused and could be safely used to create > grant/foreign mappings instead of wasting real RAM pages from > the domain memory for establishing these mappings. > > The extended regions are chosen at the domain creation time and > advertised to it via "reg" property under hypervisor node in > the guest device-tree. As region 0 is reserved for grant table > space (always present), the indexes for extended regions are 1...N. > If extended regions could not be allocated for some reason, > Xen doesn't fail and behaves as usual, so only inserts region 0. > > Please note the following limitations: > - The extended region feature is only supported for 64-bit domain > currently. > - The ACPI case is not covered. > > *** > > The algorithm to choose extended regions for non-direct mapped > DomU is simpler in comparison with the algorithm for direct mapped > Dom0. As we have a lot of unused space above 4GB, provide single > 2MB-aligned region from the second RAM bank taking into the account > the maximum supported guest address space size and the amount of > memory assigned to the guest. The maximum size of the region is 128GB. > The minimum size is 64MB. > > Suggested-by: Julien Grall <jgrall@xxxxxxxxxx> > Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> > --- > Changes RFC -> V2: > - update patch description > - drop uneeded "extended-region" DT property > - clear reg array in finalise_ext_region() and add a TODO > > Changes V2 -> V3: > - update patch description, comments in code > - only pick up regions with size >= 64MB > - move the region calculation to make_hypervisor_node() and drop > finalise_ext_region() > - extend the list of arguments for make_hypervisor_node() > - do not show warning for 32-bit domain > - change the region alignment from 1GB to 2MB > - move EXT_REGION_SIZE to public/arch-arm.h > --- > tools/libs/light/libxl_arm.c | 70 > +++++++++++++++++++++++++++++++++++++++---- > xen/include/public/arch-arm.h | 3 ++ > 2 files changed, 68 insertions(+), 5 deletions(-) > > diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c > index e3140a6..a67b68e 100644 > --- a/tools/libs/light/libxl_arm.c > +++ b/tools/libs/light/libxl_arm.c > @@ -598,9 +598,17 @@ static int make_timer_node(libxl__gc *gc, void *fdt, > return 0; > } > > +#define ALIGN_UP_TO_2MB(x) (((x) + MB(2) - 1) & (~(MB(2) - 1))) > + > static int make_hypervisor_node(libxl__gc *gc, void *fdt, > - const libxl_version_info *vers) > + const libxl_version_info *vers, > + const libxl_domain_build_info *b_info, > + const struct xc_dom_image *dom) > { > + uint64_t region_size = 0, region_base, ramsize, bank1size, > + bank1end_align, bank1end_max; > + uint8_t gpaddr_bits; > + libxl_physinfo physinfo; > int res; > gic_interrupt intr; > > @@ -615,9 +623,61 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt, > "xen,xen"); > if (res) return res; > > - /* reg 0 is grant table space */ > - res = fdt_property_regs(gc, fdt, GUEST_ROOT_ADDRESS_CELLS, > GUEST_ROOT_SIZE_CELLS, > - 1,GUEST_GNTTAB_BASE, GUEST_GNTTAB_SIZE); > + if (strcmp(dom->guest_type, "xen-3.0-aarch64")) { > + LOG(DEBUG, "The extended regions are only supported for 64-bit guest > currently"); > + goto out; > + } > + > + res = libxl_get_physinfo(CTX, &physinfo); > + assert(!res); > + > + gpaddr_bits = physinfo.gpaddr_bits; > + assert(gpaddr_bits >= 32 && gpaddr_bits <= 48); > + > + /* > + * Try to allocate single 2MB-aligned extended region from the second RAM > + * bank (above 4GB) taking into the account the maximum supported guest > + * address space size and the amount of memory assigned to the guest. > + * As the guest memory layout is not populated yet we cannot rely on > + * dom->rambank_size[1], so calculate the actual size of the second bank > + * using "max_memkb" value. > + */ > + bank1end_max = min(1ULL << gpaddr_bits, GUEST_RAM1_BASE + > GUEST_RAM1_SIZE); > + ramsize = b_info->max_memkb * 1024; > + if (ramsize <= GUEST_RAM0_SIZE) > + bank1size = 0; > + else > + bank1size = ramsize - GUEST_RAM0_SIZE; > + bank1end_align = GUEST_RAM1_BASE + ALIGN_UP_TO_2MB(bank1size); > + > + if (bank1end_max <= bank1end_align) { > + LOG(WARN, "The extended region cannot be allocated, not enough > space"); > + goto out; > + } > + > + if (bank1end_max - bank1end_align > GUEST_EXT_REGION_MAX_SIZE) { > + region_base = bank1end_max - GUEST_EXT_REGION_MAX_SIZE; > + region_size = GUEST_EXT_REGION_MAX_SIZE; > + } else { > + region_base = bank1end_align; > + region_size = bank1end_max - bank1end_align; > + } > + > +out: > + /* > + * The region 0 for grant table space must be always present. If we > managed > + * to allocate the extended region then insert it as region 1. > + */ > + if (region_size >= GUEST_EXT_REGION_MIN_SIZE) { > + LOG(DEBUG, "Extended region: %#"PRIx64"->%#"PRIx64"\n", > + region_base, region_base + region_size); > + > + res = fdt_property_regs(gc, fdt, GUEST_ROOT_ADDRESS_CELLS, > GUEST_ROOT_SIZE_CELLS, > + 2, GUEST_GNTTAB_BASE, GUEST_GNTTAB_SIZE, > + region_base, region_size); > + } else > + res = fdt_property_regs(gc, fdt, GUEST_ROOT_ADDRESS_CELLS, > GUEST_ROOT_SIZE_CELLS, > + 1, GUEST_GNTTAB_BASE, GUEST_GNTTAB_SIZE); > if (res) return res; > > /* > @@ -963,7 +1023,7 @@ next_resize: > } > > FDT( make_timer_node(gc, fdt, ainfo, state->clock_frequency) ); > - FDT( make_hypervisor_node(gc, fdt, vers) ); > + FDT( make_hypervisor_node(gc, fdt, vers, info, dom) ); > > if (info->arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) > FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom) ); > diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h > index 6b5a5f8..df59933 100644 > --- a/xen/include/public/arch-arm.h > +++ b/xen/include/public/arch-arm.h > @@ -449,6 +449,9 @@ typedef uint64_t xen_callback_t; > #define GUEST_RAM_BANK_BASES { GUEST_RAM0_BASE, GUEST_RAM1_BASE } > #define GUEST_RAM_BANK_SIZES { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE } > > +#define GUEST_EXT_REGION_MAX_SIZE xen_mk_ullong(0x2000000000) /* 128GB */ > +#define GUEST_EXT_REGION_MIN_SIZE xen_mk_ullong(0x0004000000) /* 64MB */ > + > /* Current supported guest VCPUs */ > #define GUEST_MAX_VCPUS 128 > > -- > 2.7.4 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |