|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] tools/arm: exclude iomem from domU extended regions
commit 108308feeff4df92cec9191884ebb7b155bc8de5
Author: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
AuthorDate: Tue Jun 17 13:54:05 2025 -0400
Commit: Stefano Stabellini <stefano.stabellini@xxxxxxx>
CommitDate: Tue Jun 17 15:30:18 2025 -0700
tools/arm: exclude iomem from domU extended regions
When a device is passed through to a xl domU, the iomem ranges may
overlap with the extended regions. Remove iomem from extended regions.
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
Reviewed-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
tools/libs/light/libxl_arm.c | 110 +++++++++++++++++++++++++++++++++++--------
1 file changed, 91 insertions(+), 19 deletions(-)
diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
index afc62a5299..4a19a8d22b 100644
--- a/tools/libs/light/libxl_arm.c
+++ b/tools/libs/light/libxl_arm.c
@@ -798,6 +798,8 @@ static int make_timer_node(libxl__gc *gc, void *fdt,
return 0;
}
+#define MAX_NR_EXT_REGIONS 256
+
static int make_hypervisor_node(libxl__gc *gc, void *fdt,
const libxl_version_info *vers)
{
@@ -821,7 +823,7 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt,
*/
res = fdt_property_reg_placeholder(gc, fdt, GUEST_ROOT_ADDRESS_CELLS,
GUEST_ROOT_SIZE_CELLS,
- GUEST_RAM_BANKS + 1);
+ MAX_NR_EXT_REGIONS + 1);
if (res) return res;
/*
@@ -1517,17 +1519,29 @@ static void finalise_one_node(libxl__gc *gc, void *fdt,
const char *uname,
#define EXT_REGION_MIN_SIZE xen_mk_ullong(0x0004000000) /* 64MB */
-static int finalize_hypervisor_node(libxl__gc *gc, struct xc_dom_image *dom)
+static int compare_iomem(const void *a, const void *b)
+{
+ const libxl_iomem_range *x = a, *y = b;
+
+ if (x->gfn < y->gfn)
+ return -1;
+ if (x->gfn > y->gfn)
+ return 1;
+ return 0;
+}
+
+static int finalize_hypervisor_node(libxl__gc *gc,
+ libxl_domain_build_info *b_info,
+ struct xc_dom_image *dom)
{
void *fdt = dom->devicetree_blob;
- uint64_t region_size[GUEST_RAM_BANKS] = {0}, region_base[GUEST_RAM_BANKS],
- bankend[GUEST_RAM_BANKS];
+ uint64_t region_base[MAX_NR_EXT_REGIONS], region_size[MAX_NR_EXT_REGIONS];
uint32_t regs[(GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) *
- (GUEST_RAM_BANKS + 1)];
+ (MAX_NR_EXT_REGIONS + 1)];
be32 *cells = ®s[0];
const uint64_t bankbase[] = GUEST_RAM_BANK_BASES;
const uint64_t banksize[] = GUEST_RAM_BANK_SIZES;
- unsigned int i, len, nr_regions = 0;
+ unsigned int i, j, len, nr_regions = 0;
libxl_dominfo info;
int offset, rc;
@@ -1542,20 +1556,82 @@ static int finalize_hypervisor_node(libxl__gc *gc,
struct xc_dom_image *dom)
if (info.gpaddr_bits > 64)
return ERROR_INVAL;
+ qsort(b_info->iomem, b_info->num_iomem, sizeof(libxl_iomem_range),
+ compare_iomem);
+
/*
* Try to allocate separate 2MB-aligned extended regions from the first
* and second RAM banks taking into the account the maximum supported
* guest physical address space size and the amount of memory assigned
* to the guest.
*/
- for (i = 0; i < GUEST_RAM_BANKS; i++) {
- region_base[i] = bankbase[i] +
+ for (i = 0; i < GUEST_RAM_BANKS && nr_regions < MAX_NR_EXT_REGIONS; i++) {
+ struct {
+ uint64_t start;
+ uint64_t end; /* inclusive */
+ } unallocated;
+ uint64_t unallocated_size = 0;
+
+ unallocated.start = bankbase[i] +
ALIGN_UP_TO_2MB((uint64_t)dom->rambank_size[i] << XC_PAGE_SHIFT);
- bankend[i] = ~0ULL >> (64 - info.gpaddr_bits);
- bankend[i] = min(bankend[i], bankbase[i] + banksize[i] - 1);
- if (bankend[i] > region_base[i])
- region_size[i] = bankend[i] - region_base[i] + 1;
+ unallocated.end = ~0ULL >> (64 - info.gpaddr_bits);
+ unallocated.end = min(unallocated.end, bankbase[i] + banksize[i] - 1);
+
+ if (unallocated.end >= unallocated.start)
+ unallocated_size = unallocated.end - unallocated.start + 1;
+
+ if (unallocated_size < EXT_REGION_MIN_SIZE)
+ continue;
+
+ /* Exclude iomem */
+ for (j = 0; j < b_info->num_iomem && nr_regions < MAX_NR_EXT_REGIONS;
+ j++) {
+ struct {
+ uint64_t start;
+ uint64_t end; /* inclusive */
+ } iomem;
+
+ iomem.start = b_info->iomem[j].gfn << XC_PAGE_SHIFT;
+ iomem.end = ((b_info->iomem[j].gfn + b_info->iomem[j].number)
+ << XC_PAGE_SHIFT) - 1;
+
+ if (iomem.end >= unallocated.start
+ && iomem.start <= unallocated.end) {
+
+ if (iomem.start <= unallocated.start) {
+ unallocated.start = iomem.end + 1;
+
+ if (unallocated.start > unallocated.end)
+ break;
+ } else {
+ uint64_t size = iomem.start - unallocated.start;
+
+ if (size >= EXT_REGION_MIN_SIZE) {
+ region_base[nr_regions] = unallocated.start;
+ region_size[nr_regions] = size;
+ nr_regions++;
+ }
+
+ unallocated.start = iomem.end + 1;
+
+ if (unallocated.start > unallocated.end)
+ break;
+ }
+ }
+ }
+
+ if (unallocated.end >= unallocated.start
+ && nr_regions < MAX_NR_EXT_REGIONS)
+ {
+ uint64_t size = unallocated.end - unallocated.start + 1;
+
+ if (size >= EXT_REGION_MIN_SIZE) {
+ region_base[nr_regions] = unallocated.start;
+ region_size[nr_regions] = size;
+ nr_regions++;
+ }
+ }
}
/*
@@ -1565,16 +1641,12 @@ static int finalize_hypervisor_node(libxl__gc *gc,
struct xc_dom_image *dom)
set_range(&cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS,
GUEST_GNTTAB_BASE, GUEST_GNTTAB_SIZE);
- for (i = 0; i < GUEST_RAM_BANKS; i++) {
- if (region_size[i] < EXT_REGION_MIN_SIZE)
- continue;
-
+ for (i = 0; i < nr_regions; i++) {
LOG(DEBUG, "Extended region %u: %#"PRIx64"->%#"PRIx64"",
- nr_regions, region_base[i], region_base[i] + region_size[i]);
+ i, region_base[i], region_base[i] + region_size[i] - 1);
set_range(&cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS,
region_base[i], region_size[i]);
- nr_regions++;
}
if (!nr_regions)
@@ -1626,7 +1698,7 @@ int libxl__arch_domain_finalise_hw_description(libxl__gc
*gc,
}
- res = finalize_hypervisor_node(gc, dom);
+ res = finalize_hypervisor_node(gc, &d_config->b_info, dom);
if (res)
return res;
--
generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |