[PATCH v1 10/13] xen/arm: introduce "xen,offset" feature

Penny Zheng posted 13 patches 2 months, 2 weeks ago
[PATCH v1 10/13] xen/arm: introduce "xen,offset" feature
Posted by Penny Zheng 2 months, 2 weeks ago
We introduce "xen,offset" to handle the case where memory from the owner is
shared with multiple borrowers. Each borrower would have its own offset within
the region shared by the owner.

Add relative check when parsing static shared memory node, to make sure
that "xen,offset" could be only provided in borrower domain, and the value
must be smaller than size. And include according docs in booting.txt.

Signed-off-by: Penny Zheng <penny.zheng@arm.com>
---
 docs/misc/arm/device-tree/booting.txt | 19 ++++++++++++++--
 xen/arch/arm/bootfdt.c                | 32 ++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
index 287898ef03..183c41e3c2 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -577,6 +577,16 @@ communication.
     If not specified, the default value is "borrower" and owner is
     DOMID_IO, a system domain.
 
+- xen,offset (Optional)
+
+    A 64-bit integer specifying the offset within a shared memory region.
+    When "xen,offset" is provided, only partial shared memory will be
+    mapped to the borrower domain, starting at the offset and the size
+    being "size - offset".
+
+    "xen,offset" could be only provided in borrower domain, and the value
+    must be smaller than size.
+
 As an example:
 
 chosen {
@@ -660,6 +670,7 @@ chosen {
             xen,shm-id = "my-shared-mem-2";
             role = "borrower";
             xen,shared-mem = <0x90000000 0x20000000>;
+            xen,offset = <0x0 0x10000000>;
         };
 
         ......
@@ -686,5 +697,9 @@ address is not provided by user, Xen will automatically allocate 512MB
 from heap as static shared memory to be shared between DomU1 and DomU2.
 The automatically allocated static shared memory will get mapped at
 0x80000000 in DomU1 guest physical address space, and at 0x90000000 in DomU2
-guest physical address space. DomU1 is explicitly defined as the owner domain,
-and DomU2 is the borrower domain.
+guest physical address space.
+For borrower domain DomU2, only partial static shared memory region
+"my-shared-mem-2" gets mapped, starting at offset 0x10000000 with size of
+256MB.
+DomU1 is explicitly defined as the owner domain, and DomU2 is the borrower
+domain.
diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index efaf49fd56..e642e72f30 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -380,7 +380,7 @@ static int __init process_domain_node(const void *fdt, int node,
 static int __init process_shm_node(const void *fdt, int node,
                                    uint32_t address_cells, uint32_t size_cells)
 {
-    const struct fdt_property *prop, *prop_id, *prop_role;
+    const struct fdt_property *prop, *prop_id, *prop_role, *prop_offset;
     const __be32 *cell;
     paddr_t paddr, gaddr, size;
     struct meminfo *mem = &bootinfo.reserved_mem;
@@ -389,6 +389,7 @@ static int __init process_shm_node(const void *fdt, int node,
     int len;
     bool owner = false, paddr_assigned = true;
     const char *shm_id;
+    uint64_t offset;
 
     if ( address_cells < 1 || size_cells < 1 )
     {
@@ -464,6 +465,35 @@ static int __init process_shm_node(const void *fdt, int node,
         return -EINVAL;
     }
 
+    /*
+     * If "xen,offset" is provided, then only partial shared memory
+     * shall be mapped to borrower domain. The size will be
+     * "psize - offset".
+     * "xen,offset" is a 64-bit integer and an optional property
+     */
+    prop_offset = fdt_get_property(fdt, node, "xen,offset", NULL);
+    if ( prop_offset )
+    {
+        /*
+         * "xen,offset" could be only provided in borrower domain,
+         * and the offset must be smaller than size.
+         */
+        if ( prop_role && !strcmp(prop_role->data, "owner") )
+        {
+            printk("fdt: \"xen,offset\" could not be provided in owner domain\n");
+            return -EINVAL;
+        }
+
+        cell = (const __be32 *)prop_offset->data;
+        offset = dt_next_cell(2, &cell);
+
+        if ( offset >= size )
+        {
+            printk("fdt: invalid \"xen,offset\" value\n");
+            return -EINVAL;
+        }
+    }
+
     for ( i = 0; i < shm_mem->nr_banks; i++ )
     {
         /*
-- 
2.25.1