[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1 07/13] xen/arm: create shared memory nodes in guest device tree


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Penny Zheng <Penny.Zheng@xxxxxxx>
  • Date: Fri, 11 Mar 2022 14:11:17 +0800
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=umdxaC9M1LCNOYH4ZpD5ACrl2y60yzal5ReM8dSmiFw=; b=R7Ci329X43kgDR0HmX/5yjIkk7jFayhIQYVd7SqdjarX9yuKKZ5sqqI7rQM81ac7IdrQuqKvtAxk75k9Q9W8+GzrZ6Xd1qHy3ApzQhy0TzELqazUhQy5/exNmkznU3iFjsNHiGRENZDmpTzI+YEIOfbcgSgoWMopD93/hrQpt/bDgg3ItStFL/kr6fXOxu6KLwCybXIdMwqAe7VtoAIpqaNX/9Q+H+wi21y5VTfuiJgBYFK2HCXo/HHjjyeexcrkkHKT57H+CxckDtZXXssBJXJ412taxfoUKjGDt+YYORHYUjmInup78tLLHyXq6i2CnY47exnAoCFG1pDY+UDf0w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fTzOncaUWmi+9/BwTptUX8m9Z5SjS4Ni5WKs/96YjHCwQh/r63kAEbtW2s40+3QbmIeKSWB1eb0Y75MjK7bwBHWfAEfFwKUvurMHHk3eFN3YxFd8lhYsh41xKxuhrOK2PKpdhZF62/c22ijG7l+FSvXfOISps5uOvcf4oz5AETnmpyLlTqqkckdcwsvk962GY1cWfNudm1RLOnU1t5TA5YByI3eOWcatQhwvijLVojQXR0r2NmVWJ53XMzLBwJnNfVwbxFoRjjyY/pnGdH3oKgXPjydN2mWVJh9CIkRE17e9B1hmtos7YJ+ap5S8cfZiCZcHZLf2Qi9QSCsFgCdfZQ==
  • Cc: <nd@xxxxxxx>, Penny Zheng <penny.zheng@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Fri, 11 Mar 2022 06:13:00 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true

From: Penny Zheng <penny.zheng@xxxxxxx>

We expose the shared memory to the domU using the "xen,shared-memory-v1"
reserved-memory binding. See
Documentation/devicetree/bindings/reserved-memory/xen,shared-memory.txt
in Linux for the corresponding device tree binding.

To save the cost of re-parsing shared memory device tree configuration when
creating shared memory nodes in guest device tree, this commit adds new field
"shm_mem" to store shm-info per domain.

For each shared memory region, a range is exposed under
the /reserved-memory node as a child node. Each range sub-node is
named xen-shmem@<address> and has the following properties:
- compatible:
        compatible = "xen,shared-memory-v1"
- reg:
        the base guest physical address and size of the shared memory region
- xen,id:
        a string that identifies the shared memory region.

Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
---
 xen/arch/arm/domain_build.c       | 144 ++++++++++++++++++++++++++++++
 xen/arch/arm/include/asm/domain.h |   1 +
 xen/arch/arm/include/asm/setup.h  |   3 +
 3 files changed, 148 insertions(+)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 8cee5ffbd1..997df46ddd 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -840,6 +840,28 @@ static int __init guest_physmap_add_shm(struct domain *od, 
struct domain *bd,
     return ret;
 }
 
+static int __init append_shm_bank_to_domain(struct domain *d,
+                                            paddr_t start, paddr_t size,
+                                            u32 shm_id)
+{
+    /* Allocate memory at first insertion. */
+    if ( d->arch.shm_mem == NULL )
+    {
+        d->arch.shm_mem = xmalloc_bytes(sizeof(struct meminfo));
+        if ( d->arch.shm_mem == NULL )
+            return -ENOMEM;
+
+        memset(d->arch.shm_mem, 0, sizeof(struct meminfo));
+    }
+
+    d->arch.shm_mem->bank[d->arch.shm_mem->nr_banks].start = start;
+    d->arch.shm_mem->bank[d->arch.shm_mem->nr_banks].size = size;
+    d->arch.shm_mem->bank[d->arch.shm_mem->nr_banks].shm_id = shm_id;
+    d->arch.shm_mem->nr_banks++;
+
+    return 0;
+}
+
 static int __init process_shm(struct domain *d,
                               const struct dt_device_node *node)
 {
@@ -907,6 +929,14 @@ static int __init process_shm(struct domain *d,
                                     PFN_DOWN(gbase), PFN_DOWN(psize));
         if ( ret )
             return ret;
+
+        /*
+         * Record static shared memory region info for later setting
+         * up shm-node in guest device tree.
+         */
+        ret = append_shm_bank_to_domain(d, gbase, psize, shm_id);
+        if ( ret )
+            return ret;
     }
 
     return 0;
@@ -1237,6 +1267,115 @@ static int __init make_memory_node(const struct domain 
*d,
     return res;
 }
 
+#ifdef CONFIG_STATIC_SHM
+static int __init make_shm_memory_node(const struct domain *d,
+                                       void *fdt,
+                                       int addrcells, int sizecells,
+                                       struct meminfo *mem)
+{
+    unsigned long i = 0;
+    int res = 0;
+    int reg_size = addrcells + sizecells;
+
+    if ( mem->nr_banks == 0 )
+        return -ENOENT;
+
+    /*
+     * For each shared memory region, a range is exposed under
+     * the /reserved-memory node as a child node. Each range sub-node is
+     * named xen-shmem@<address>.
+     */
+    dt_dprintk("Create xen-shmem node\n");
+
+    for ( ; i < mem->nr_banks; i++ )
+    {
+        u64 start = mem->bank[i].start;
+        u64 size = mem->bank[i].size;
+        u32 shm_id = mem->bank[i].shm_id;
+        /* Placeholder for xen-shmem@ + a 64-bit number + \0 */
+        char buf[27];
+        const char compat[] = "xen,shared-memory-v1";
+        __be32 *reg, *cells;
+       unsigned int len;
+
+        snprintf(buf, sizeof(buf), "xen-shmem@%"PRIx64, mem->bank[i].start);
+        res = fdt_begin_node(fdt, buf);
+        if ( res )
+            return res;
+
+        res = fdt_property(fdt, "compatible", compat, sizeof(compat));
+        if ( res )
+            return res;
+
+       len = reg_size * sizeof(__be32);
+        reg = xmalloc_bytes(len);
+        if ( reg == NULL )
+            return -ENOMEM;
+        cells = reg;
+
+        dt_child_set_range(&cells, addrcells, sizecells, start, size);
+
+        res = fdt_property(fdt, "reg", reg, len);
+        xfree(reg);
+        if (res)
+            return res;
+
+        dt_dprintk("Shared memory bank %lu: %#"PRIx64"->%#"PRIx64"\n",
+                   i, start, start + size);
+
+        res = fdt_property_cell(fdt, "xen,id", shm_id);
+        if (res)
+            return res;
+
+        res = fdt_end_node(fdt);
+        if (res)
+            return res;
+    }
+
+    return res;
+}
+#else
+static int __init make_shm_memory_node(const struct domain *d,
+                                       void *fdt,
+                                       int addrcells, int sizecells,
+                                       struct meminfo *mem)
+{
+    ASSERT_UNREACHABLE();
+}
+#endif
+
+static int __init make_resv_memory_node(const struct domain *d,
+                                        void *fdt,
+                                        int addrcells, int sizecells,
+                                        struct meminfo *mem)
+{
+    int res = 0;
+    /* Placeholder for reserved-memory\0 */
+    char resvbuf[16] = "reserved-mem";
+
+    if ( mem == NULL )
+        /* No shared memory provided. */
+        return 0;
+
+    dt_dprintk("Create reserved-memory node\n");
+
+    res = fdt_begin_node(fdt, resvbuf);
+    if ( res )
+        return res;
+
+    res = fdt_property(fdt, "ranges", NULL, 0);
+    if ( res )
+        return res;
+
+    res = make_shm_memory_node(d, fdt, addrcells, sizecells, mem);
+    if ( res )
+        return res;
+
+    res = fdt_end_node(fdt);
+
+    return res;
+}
+
 static int __init add_ext_regions(unsigned long s, unsigned long e, void *data)
 {
     struct meminfo *ext_regions = data;
@@ -2974,6 +3113,11 @@ static int __init prepare_dtb_domU(struct domain *d, 
struct kernel_info *kinfo)
     if ( ret )
         goto err;
 
+    ret = make_resv_memory_node(d, kinfo->fdt, addrcells, sizecells,
+                                d->arch.shm_mem);
+    if ( ret )
+        goto err;
+
     /*
      * domain_handle_dtb_bootmodule has to be called before the rest of
      * the device tree is generated because it depends on the value of
diff --git a/xen/arch/arm/include/asm/domain.h 
b/xen/arch/arm/include/asm/domain.h
index ea7a7219a3..6df37d2c46 100644
--- a/xen/arch/arm/include/asm/domain.h
+++ b/xen/arch/arm/include/asm/domain.h
@@ -110,6 +110,7 @@ struct arch_domain
 #endif
 
     bool directmap;
+    struct meminfo *shm_mem;
 }  __cacheline_aligned;
 
 struct arch_vcpu
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index 7a1e1d6798..b6ff04889c 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -27,6 +27,9 @@ struct membank {
     paddr_t start;
     paddr_t size;
     bool xen_domain; /* whether the memory bank is bound to a Xen domain. */
+#ifdef CONFIG_STATIC_SHM
+    u32 shm_id ;     /* ID identifier of a static shared memory bank. */
+#endif
 };
 
 struct meminfo {
-- 
2.25.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.