Static shared memory acts as reserved memory in guest, so it shall be
excluded from extended regions.
Extended regions are taken care of under three different scenarios:
normal DomU, direct-map domain with iommu on, and direct-map domain
with iommu off.
For normal DomU, we create a new function "remove_shm_holes_for_domU", to
firstly transfer original outputs into the format of "struct rangeset",
then use "remove_shm_from_rangeset" to remove static shm from them.
For direct-map domain with iommu on, after we get guest shm info from "kinfo",
we use "remove_shm_from_rangeset" to remove static shm.
For direct-map domain with iommu off, as static shm has already been taken
care of through reserved memory banks, we do nothing.
Signed-off-by: Penny Zheng <penny.zheng@arm.com>
---
v1 -> v2:
- new commit
---
xen/arch/arm/domain_build.c | 94 ++++++++++++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 9b4aabaf22..4cd1e3d433 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1914,6 +1914,32 @@ static int __init handle_pci_range(const struct dt_device_node *dev,
return 0;
}
+static int __init remove_shm_from_rangeset(const struct kernel_info *kinfo,
+ struct rangeset *rangeset)
+{
+ unsigned int i;
+
+ /* Remove static shared memory regions */
+ for ( i = 0; i < kinfo->shminfo.nr_banks; i++ )
+ {
+ struct membank membank = kinfo->shminfo.bank[i].membank;
+ paddr_t start, end;
+ int res;
+
+ start = membank.start;
+ end = membank.start + membank.size - 1;
+ res = rangeset_remove_range(rangeset, start, end);
+ if ( res )
+ {
+ printk(XENLOG_ERR "Failed to remove: %#"PRIpaddr"->%#"PRIpaddr"\n",
+ start, end);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/*
* 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
@@ -1922,6 +1948,8 @@ static int __init handle_pci_range(const struct dt_device_node *dev,
* - MMIO
* - Host RAM
* - PCI aperture
+ * - Static shared memory regions, which are described by special property
+ * "xen,static-shm"
*/
static int __init find_memory_holes(const struct kernel_info *kinfo,
struct meminfo *ext_regions)
@@ -1997,6 +2025,14 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
}
}
+ /* Remove static shared memory regions */
+ if ( kinfo->shminfo.nr_banks != 0 )
+ {
+ res = remove_shm_from_rangeset(kinfo, mem_holes);
+ if ( res )
+ goto out;
+ }
+
start = 0;
end = (1ULL << p2m_ipa_bits) - 1;
res = rangeset_report_ranges(mem_holes, start, end,
@@ -2012,6 +2048,62 @@ out:
return res;
}
+static int __init remove_shm_holes_for_domU(const struct kernel_info *kinfo,
+ struct meminfo *orig_ext)
+{
+ struct rangeset *guest_holes;
+ unsigned int i = 0, tail;
+ int res;
+ paddr_t start, end;
+
+ /* No static shared memory region. */
+ if ( kinfo->shminfo.nr_banks == 0 )
+ return 0;
+
+ dt_dprintk("Remove static shared memory holes for extended regions of DomU\n");
+
+ guest_holes = rangeset_new(NULL, NULL, 0);
+ if ( !guest_holes )
+ return -ENOMEM;
+
+ for ( ; i < orig_ext->nr_banks; i++ )
+ {
+ start = orig_ext->bank[i].start;
+ end = start + orig_ext->bank[i].size - 1;
+
+ res = rangeset_add_range(guest_holes, start, end);
+ if ( res )
+ {
+ printk(XENLOG_ERR "Failed to add: %#"PRIpaddr"->%#"PRIpaddr"\n",
+ start, end);
+ goto out;
+ }
+ }
+
+ /* Remove static shared memory regions */
+ res = remove_shm_from_rangeset(kinfo, guest_holes);
+ if ( res )
+ goto out;
+
+ tail = orig_ext->nr_banks - 1;
+ start = orig_ext->bank[0].start;
+ end = orig_ext->bank[tail].start + orig_ext->bank[tail].size - 1;
+
+ /* Reset original extended regions to hold new value */
+ orig_ext->nr_banks = 0;
+ res = rangeset_report_ranges(guest_holes, start, end,
+ add_ext_regions, orig_ext);
+ if ( res )
+ orig_ext->nr_banks = 0;
+ else if ( !orig_ext->nr_banks )
+ res = -ENOENT;
+
+out:
+ rangeset_destroy(guest_holes);
+
+ return res;
+}
+
static int __init find_domU_holes(const struct kernel_info *kinfo,
struct meminfo *ext_regions)
{
@@ -2039,7 +2131,7 @@ static int __init find_domU_holes(const struct kernel_info *kinfo,
res = 0;
}
- return res;
+ return remove_shm_holes_for_domU(kinfo, ext_regions);
}
static int __init make_hypervisor_node(struct domain *d,
--
2.25.1
Hi Penny
On 2/23/23 00:41, Penny Zheng wrote:
> Static shared memory acts as reserved memory in guest, so it shall be
> excluded from extended regions.
>
> Extended regions are taken care of under three different scenarios:
> normal DomU, direct-map domain with iommu on, and direct-map domain
> with iommu off.
>
> For normal DomU, we create a new function "remove_shm_holes_for_domU", to
> firstly transfer original outputs into the format of "struct rangeset",
> then use "remove_shm_from_rangeset" to remove static shm from them.
>
> For direct-map domain with iommu on, after we get guest shm info from "kinfo",
> we use "remove_shm_from_rangeset" to remove static shm.
>
> For direct-map domain with iommu off, as static shm has already been taken
> care of through reserved memory banks, we do nothing.
>
> Signed-off-by: Penny Zheng <penny.zheng@arm.com>
> ---
> v1 -> v2:
> - new commit
> ---
> xen/arch/arm/domain_build.c | 94 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 93 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 9b4aabaf22..4cd1e3d433 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1914,6 +1914,32 @@ static int __init handle_pci_range(const struct dt_device_node *dev,
> return 0;
> }
>
> +static int __init remove_shm_from_rangeset(const struct kernel_info *kinfo,
> + struct rangeset *rangeset)
> +{
> + unsigned int i;
> +
> + /* Remove static shared memory regions */
> + for ( i = 0; i < kinfo->shminfo.nr_banks; i++ )
> + {
> + struct membank membank = kinfo->shminfo.bank[i].membank;
> + paddr_t start, end;
> + int res;
> +
> + start = membank.start;
> + end = membank.start + membank.size - 1;
> + res = rangeset_remove_range(rangeset, start, end);
> + if ( res )
> + {
> + printk(XENLOG_ERR "Failed to remove: %#"PRIpaddr"->%#"PRIpaddr"\n",
> + start, end);
> + return -EINVAL;
> + }
> + }
> +
> + return 0;
> +}
> +
> /*
> * 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
> @@ -1922,6 +1948,8 @@ static int __init handle_pci_range(const struct dt_device_node *dev,
> * - MMIO
> * - Host RAM
> * - PCI aperture
> + * - Static shared memory regions, which are described by special property
> + * "xen,static-shm"
> */
> static int __init find_memory_holes(const struct kernel_info *kinfo,
> struct meminfo *ext_regions)
> @@ -1997,6 +2025,14 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
> }
> }
>
> + /* Remove static shared memory regions */
> + if ( kinfo->shminfo.nr_banks != 0 )
> + {
> + res = remove_shm_from_rangeset(kinfo, mem_holes);
> + if ( res )
> + goto out;
> + }
> +
> start = 0;
> end = (1ULL << p2m_ipa_bits) - 1;
> res = rangeset_report_ranges(mem_holes, start, end,
> @@ -2012,6 +2048,62 @@ out:
> return res;
> }
>
> +static int __init remove_shm_holes_for_domU(const struct kernel_info *kinfo,
> + struct meminfo *orig_ext)
> +{
> + struct rangeset *guest_holes;
> + unsigned int i = 0, tail;
> + int res;
> + paddr_t start, end;
> +
> + /* No static shared memory region. */
> + if ( kinfo->shminfo.nr_banks == 0 )
> + return 0;
> +
> + dt_dprintk("Remove static shared memory holes for extended regions of DomU\n");
> +
> + guest_holes = rangeset_new(NULL, NULL, 0);
> + if ( !guest_holes )
> + return -ENOMEM;
> +
> + for ( ; i < orig_ext->nr_banks; i++ )
> + {
> + start = orig_ext->bank[i].start;
> + end = start + orig_ext->bank[i].size - 1;
> +
> + res = rangeset_add_range(guest_holes, start, end);
> + if ( res )
> + {
> + printk(XENLOG_ERR "Failed to add: %#"PRIpaddr"->%#"PRIpaddr"\n",
> + start, end);
> + goto out;
> + }
> + }
> +
> + /* Remove static shared memory regions */
> + res = remove_shm_from_rangeset(kinfo, guest_holes);
> + if ( res )
> + goto out;
> +
> + tail = orig_ext->nr_banks - 1;
> + start = orig_ext->bank[0].start;
> + end = orig_ext->bank[tail].start + orig_ext->bank[tail].size - 1;
> +
> + /* Reset original extended regions to hold new value */
> + orig_ext->nr_banks = 0;
> + res = rangeset_report_ranges(guest_holes, start, end,
> + add_ext_regions, orig_ext);
> + if ( res )
> + orig_ext->nr_banks = 0;
> + else if ( !orig_ext->nr_banks )
> + res = -ENOENT;
> +
> +out:
> + rangeset_destroy(guest_holes);
> +
> + return res;
> +}
> +
> static int __init find_domU_holes(const struct kernel_info *kinfo,
> struct meminfo *ext_regions)
> {
> @@ -2039,7 +2131,7 @@ static int __init find_domU_holes(const struct kernel_info *kinfo,
> res = 0;
> }
>
> - return res;
> + return remove_shm_holes_for_domU(kinfo, ext_regions);
We are no longer using "res" anywhere in this function, so the variable may be removed.
arch/arm/domain_build.c: In function ‘find_domU_holes’:
arch/arm/domain_build.c:2114:9: warning: variable ‘res’ set but not used [-Wunused-but-set-variable]
2114 | int res = -ENOENT;
| ^~~
> }
>
> static int __init make_hypervisor_node(struct domain *d,
> --
> 2.25.1
>
>
© 2016 - 2026 Red Hat, Inc.