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

[RFC PATCH v1 06/26] xen/arm/cca: add Realm granule helpers


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Koichiro Den <den@xxxxxxxxxxxxx>
  • Date: Fri, 15 May 2026 13:07:52 +0900
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=valinux.co.jp; dmarc=pass action=none header.from=valinux.co.jp; dkim=pass header.d=valinux.co.jp; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=ihotna9f+5bqGkkQOWVVME5/dELv08SRAliM5aVHxjs=; b=V7VKBFZ7QWs9lqLvfnNHp58L2+D2Z521RAVHcJ6SX1UQFrPaOLsikmdCtdalTVC7gcvq8F5aC2r4TJq+eKizgEybYlpI+51EW8aZhl5dzRCgdbdAhN2Hdhk74/xgIuyb7JCQnWcgWHYAWWGhQg6ENxj+bXhCt6vpDZE/9h7s4S84n7vbotAEe2bZT0amYEQh03RYe7CiZxWQG4vJI0nI7qFRSwKG+AqXD05NjVuVH2aDoGMArPNWcnJeXObS7opRzTTJ53k8uVpgJFbDkh3F4e4vfI1jsaTiEDgGSBEVXV/bMfwdEmcy1c7qJ6w0CGYJpQd4Ot5/ceHEuLd8xwuNPQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LRKDfWZzRHBANJNy49uEbFMb3rLvwdeb57/irzeo6WdfiA3gxykkTse40rL0mm3XidTwi5cz5AeUFsJ+BhY86kuGX2gXTRa9fkcmzHRC9S+xUuE79DH27T4R3fMsp3EhmX+c6yVs+Y0ZXzivJ5EH1dYP6riRrVSfXnplSwvDPhGPlVMY+r7/70G1KWO38rnwURELXx2UI7x2Jw2F/uIPRtAOgDDXZqsEPjozXvVdr2u0fFXZ86IHfeJ8XKOpLq6sTC/Os4Rypi6b/SS7W0a+5y0+T5oR1LmWX0xqO0EhkImlAj4FEMXxMSVYholWVNmfZsw+CZZ9tGH4HjNCe13LZw==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=valinux.co.jp header.i="@valinux.co.jp" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=valinux.co.jp;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Fri, 15 May 2026 04:08:39 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Add the memory-tracking preflight and the single-granule delegate
helpers. Realm-owned pages have to come from fine, conventional
tracking regions.

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
 xen/arch/arm/cca/Makefile      |   1 +
 xen/arch/arm/cca/granule.c     | 150 +++++++++++++++++++++++++++++++++
 xen/arch/arm/include/asm/cca.h |   5 ++
 3 files changed, 156 insertions(+)
 create mode 100644 xen/arch/arm/cca/granule.c

diff --git a/xen/arch/arm/cca/Makefile b/xen/arch/arm/cca/Makefile
index aaa04e3b914b..7f20d43323c3 100644
--- a/xen/arch/arm/cca/Makefile
+++ b/xen/arch/arm/cca/Makefile
@@ -1,2 +1,3 @@
+obj-y += granule.o
 obj-y += rmi.o
 obj-y += state.o
diff --git a/xen/arch/arm/cca/granule.c b/xen/arch/arm/cca/granule.c
new file mode 100644
index 000000000000..d2be4d240f19
--- /dev/null
+++ b/xen/arch/arm/cca/granule.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/bootinfo.h>
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+
+#include <asm/cca.h>
+
+#include "rmi.h"
+
+static paddr_t __init arm_cca_l0gpt_size(unsigned long features1)
+{
+    unsigned long l0gptsz = arm_cca_rmi_field_get(
+        features1, ARM_CCA_RMI_FEATURE_REGISTER_1_L0GPTSZ_SHIFT,
+        ARM_CCA_RMI_FEATURE_REGISTER_1_L0GPTSZ_WIDTH);
+
+    return 1ULL << (30 + l0gptsz);
+}
+
+static int __init arm_cca_verify_memory_tracking(paddr_t start, paddr_t end)
+{
+    while ( start < end )
+    {
+        unsigned long category, state;
+        paddr_t next;
+        int rc;
+
+        rc = arm_cca_rmi_granule_tracking_get(start, end, &category, &state,
+                                              &next);
+        if ( rc != 0 )
+            return rc;
+
+        if ( category != ARM_CCA_RMI_MEM_CATEGORY_CONVENTIONAL ||
+             state != ARM_CCA_RMI_TRACKING_FINE ||
+             next <= start || next > end )
+        {
+            printk(XENLOG_ERR
+                   "ARM CCA: memory [%#" PRIpaddr ", %#" PRIpaddr
+                   ") is not fine-tracked conventional memory\n",
+                   start, end);
+            return -EOPNOTSUPP;
+        }
+
+        start = next;
+    }
+
+    return 0;
+}
+
+static int __init arm_cca_create_gpts(paddr_t start, paddr_t end,
+                                      paddr_t l0gpt_size)
+{
+    paddr_t base = ROUNDDOWN(start, l0gpt_size);
+    paddr_t stop = ROUNDUP(end, l0gpt_size);
+
+    while ( base < stop )
+    {
+        int rc = arm_cca_rmi_gpt_l1_create(base);
+
+        if ( rc != 0 )
+        {
+            printk(XENLOG_ERR
+                   "ARM CCA: failed to create GPT L1 for %#" PRIpaddr "\n",
+                   base);
+            return rc;
+        }
+
+        base += l0gpt_size;
+    }
+
+    return 0;
+}
+
+int __init arm_cca_prepare_host_memory(unsigned long features1)
+{
+    const struct membanks *mem = bootinfo_get_mem();
+    paddr_t l0gpt_size = arm_cca_l0gpt_size(features1);
+    unsigned int i;
+    int rc;
+
+    for ( i = 0; i < mem->nr_banks; i++ )
+    {
+        paddr_t start = mem->bank[i].start;
+        paddr_t end = start + mem->bank[i].size;
+
+        rc = arm_cca_verify_memory_tracking(start, end);
+        if ( rc != 0 )
+            return rc;
+
+        rc = arm_cca_create_gpts(start, end, l0gpt_size);
+        if ( rc != 0 )
+            return rc;
+    }
+
+    return 0;
+}
+
+static int arm_cca_process_granule_range(paddr_t start, paddr_t end,
+                                         bool delegate)
+{
+    paddr_t cur = start;
+    int rc;
+
+    /*
+     * arm_cca_prepare_host_memory() checks that host DRAM is fine-tracked and
+     * has GPT L1 metadata before any Realm-owned granule can be delegated.
+     */
+    if ( start >= end || !IS_ALIGNED(start, PAGE_SIZE) ||
+         !IS_ALIGNED(end, PAGE_SIZE) )
+        return -EINVAL;
+
+    while ( cur < end )
+    {
+        paddr_t out_top = INVALID_PADDR;
+
+        if ( delegate )
+            rc = arm_cca_rmi_granule_range_delegate(cur, end, &out_top);
+        else
+            rc = arm_cca_rmi_granule_range_undelegate(cur, end, &out_top);
+
+        if ( rc != 0 )
+            return rc;
+
+        if ( out_top <= cur || out_top > end )
+            return -EIO;
+
+        cur = out_top;
+    }
+
+    return 0;
+}
+
+/* DEN0137 2.0-bet1 - D1.1.1 Granule delegation flow. */
+int arm_cca_delegate_granule(paddr_t granule)
+{
+    if ( !IS_ALIGNED(granule, PAGE_SIZE) )
+        return -EINVAL;
+
+    return arm_cca_process_granule_range(granule, granule + PAGE_SIZE, true);
+}
+
+/* DEN0137 2.0-bet1 - D1.1.2 Granule undelegation flow. */
+int arm_cca_undelegate_granule(paddr_t granule)
+{
+    if ( !IS_ALIGNED(granule, PAGE_SIZE) )
+        return -EINVAL;
+
+    return arm_cca_process_granule_range(granule, granule + PAGE_SIZE, false);
+}
diff --git a/xen/arch/arm/include/asm/cca.h b/xen/arch/arm/include/asm/cca.h
index 6bf644fbcee5..c35d51f750a3 100644
--- a/xen/arch/arm/include/asm/cca.h
+++ b/xen/arch/arm/include/asm/cca.h
@@ -2,6 +2,7 @@
 #ifndef ARM_CCA_H
 #define ARM_CCA_H
 
+#include <xen/init.h>
 #include <xen/types.h>
 
 /*
@@ -79,4 +80,8 @@ void arm_cca_vcpu_destroy(struct vcpu *v);
 void *arm_cca_alloc_rec_run(void);
 void arm_cca_free_rec_run(void *run);
 
+int arm_cca_delegate_granule(paddr_t granule);
+int arm_cca_undelegate_granule(paddr_t granule);
+int arm_cca_prepare_host_memory(unsigned long features1) __init;
+
 #endif /* ARM_CCA_H */
-- 
2.51.0




 


Rackspace

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