|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 1/2] xen/arm: exclude xen,reg from direct-map domU extended regions
Similarly to fba1b0974dd8, when a device is passed through to a
direct-map dom0less domU, the xen,reg ranges may overlap with the
extended regions. Remove xen,reg from direct-map domU extended regions.
Introduce rangeset_count_ranges().
Take the opportunity to update the comment ahead of find_memory_holes().
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
---
v2->v3:
* new patch
---
xen/arch/arm/domain_build.c | 57 +++++++++++++++++++++++++++++++++----
xen/common/rangeset.c | 14 +++++++++
xen/include/xen/rangeset.h | 2 ++
3 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index b189a7cfae9f..3cdf5839bc98 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -824,15 +824,17 @@ static int __init handle_pci_range(const struct
dt_device_node *dev,
}
/*
- * Find the holes in the Host DT which can be exposed to Dom0 as extended
- * regions for the special memory mappings. In order to calculate regions
- * we exclude every addressable memory region described by "reg" and "ranges"
- * properties from the maximum possible addressable physical memory range:
+ * Find the holes in the Host DT which can be exposed to Dom0 or a direct-map
+ * domU as extended regions for the special memory mappings. In order to
+ * calculate regions we exclude every addressable memory region described by
+ * "reg" and "ranges" properties from the maximum possible addressable physical
+ * memory range:
* - MMIO
* - Host RAM
* - PCI aperture
* - Static shared memory regions, which are described by special property
* "xen,shared-mem"
+ * - xen,reg mappings
*/
static int __init find_memory_holes(const struct kernel_info *kinfo,
struct membanks *ext_regions)
@@ -914,6 +916,13 @@ static int __init find_memory_holes(const struct
kernel_info *kinfo,
}
}
+ if ( kinfo->xen_reg_assigned )
+ {
+ res = rangeset_subtract(mem_holes, kinfo->xen_reg_assigned);
+ if ( res )
+ goto out;
+ }
+
start = 0;
end = (1ULL << p2m_ipa_bits) - 1;
res = rangeset_report_ranges(mem_holes, PFN_DOWN(start), PFN_DOWN(end),
@@ -994,11 +1003,30 @@ static int __init find_domU_holes(const struct
kernel_info *kinfo,
return res;
}
+static int __init rangeset_to_membank(unsigned long s_gfn, unsigned long e_gfn,
+ void *data)
+{
+ struct membanks *membank = data;
+ paddr_t s = pfn_to_paddr(s_gfn);
+ paddr_t e = pfn_to_paddr(e_gfn + 1) - 1;
+
+ if ( membank->nr_banks >= membank->max_banks )
+ return 0;
+
+ membank->bank[membank->nr_banks].start = s;
+ membank->bank[membank->nr_banks].size = e - s + 1;
+ membank->nr_banks++;
+
+ return 0;
+}
+
static int __init find_host_extended_regions(const struct kernel_info *kinfo,
struct membanks *ext_regions)
{
int res;
struct membanks *gnttab = membanks_xzalloc(1, MEMORY);
+ struct membanks *xen_reg = membanks_xzalloc(
+ max(1, rangeset_count_ranges(kinfo->xen_reg_assigned)), MEMORY);
/*
* Exclude the following regions:
@@ -1006,6 +1034,7 @@ static int __init find_host_extended_regions(const struct
kernel_info *kinfo,
* 2) Remove reserved memory
* 3) Grant table assigned to domain
* 4) Remove static shared memory (when the feature is enabled)
+ * 5) Remove xen,reg
*/
const struct membanks *mem_banks[] = {
kernel_info_get_mem_const(kinfo),
@@ -1014,12 +1043,27 @@ static int __init find_host_extended_regions(const
struct kernel_info *kinfo,
#ifdef CONFIG_STATIC_SHM
bootinfo_get_shmem(),
#endif
+ xen_reg,
};
dt_dprintk("Find unallocated memory for extended regions\n");
if ( !gnttab )
- return -ENOMEM;
+ {
+ res = -ENOMEM;
+ goto out;
+ }
+
+ if ( !xen_reg )
+ {
+ res = -ENOMEM;
+ goto out;
+ }
+
+ if ( kinfo->xen_reg_assigned )
+ rangeset_report_ranges(kinfo->xen_reg_assigned, 0,
+ PFN_DOWN((1ULL << p2m_ipa_bits) - 1),
+ rangeset_to_membank, xen_reg);
gnttab->nr_banks = 1;
gnttab->bank[0].start = kinfo->gnttab_start;
@@ -1027,6 +1071,9 @@ static int __init find_host_extended_regions(const struct
kernel_info *kinfo,
res = find_unallocated_memory(kinfo, mem_banks, ARRAY_SIZE(mem_banks),
ext_regions, add_ext_regions);
+
+ out:
+ xfree(xen_reg);
xfree(gnttab);
return res;
diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c
index b9e8912fb1c3..77b37ad9b196 100644
--- a/xen/common/rangeset.c
+++ b/xen/common/rangeset.c
@@ -433,6 +433,20 @@ bool rangeset_is_empty(
return ((r == NULL) || list_empty(&r->range_list));
}
+int rangeset_count_ranges(const struct rangeset *r)
+{
+ int nr = 0;
+ struct list_head *list;
+
+ if ( r == NULL )
+ return 0;
+
+ list_for_each( list, &r->range_list )
+ nr++;
+
+ return nr;
+}
+
struct rangeset *rangeset_new(
struct domain *d, const char *name, unsigned int flags)
{
diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h
index 817505badf6f..96cc0b5d7930 100644
--- a/xen/include/xen/rangeset.h
+++ b/xen/include/xen/rangeset.h
@@ -56,6 +56,8 @@ void rangeset_limit(
bool __must_check rangeset_is_empty(
const struct rangeset *r);
+int __must_check rangeset_count_ranges(const struct rangeset *r);
+
/* Add/claim/remove/query/purge a numeric range. */
int __must_check rangeset_add_range(
struct rangeset *r, unsigned long s, unsigned long e);
--
2.49.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |