diff mbox series

[v2,6/8] xen/arm: remove shm holes for extended regions

Message ID 20230223054105.2357217-7-Penny.Zheng@arm.com (mailing list archive)
State New, archived
Headers show
Series Follow-up static shared memory PART I | expand

Commit Message

Penny Zheng Feb. 23, 2023, 5:41 a.m. UTC
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(-)

Comments

Stewart Hildebrand April 13, 2023, 7:56 p.m. UTC | #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
> 
>
diff mbox series

Patch

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,