Thread (90 messages) 90 messages, 8 authors, 2025-08-16

Re: [PATCH v9 15/43] arm64: RME: Allow VMM to set RIPAS

From: Steven Price <steven.price@arm.com>
Date: 2025-06-23 14:45:38
Also in: kvm, kvmarm, linux-coco, lkml

On 17/06/2025 13:56, zhuangyiwei wrote:
Hi Steven

On 2025/6/11 18:48, Steven Price wrote:
quoted
Each page within the protected region of the realm guest can be marked
as either RAM or EMPTY. Allow the VMM to control this before the guest
has started and provide the equivalent functions to change this (with
the guest's approval) at runtime.

When transitioning from RIPAS RAM (1) to RIPAS EMPTY (0) the memory is
unmapped from the guest and undelegated allowing the memory to be reused
by the host. When transitioning to RIPAS RAM the actual population of
the leaf RTTs is done later on stage 2 fault, however it may be
necessary to allocate additional RTTs to allow the RMM track the RIPAS
for the requested range.

When freeing a block mapping it is necessary to temporarily unfold the
RTT which requires delegating an extra page to the RMM, this page can
then be recovered once the contents of the block mapping have been
freed.

Signed-off-by: Steven Price <steven.price@arm.com>
---
[...]
quoted
diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
index 25705da6f153..fe75c41d6ac3 100644
--- a/arch/arm64/kvm/rme.c
+++ b/arch/arm64/kvm/rme.c
[...]
quoted
@@ -126,6 +206,40 @@ static int realm_rtt_destroy(struct realm *realm,
unsigned long addr,
      return ret;
  }
  +static int realm_create_rtt_levels(struct realm *realm,
+                   unsigned long ipa,
+                   int level,
+                   int max_level,
+                   struct kvm_mmu_memory_cache *mc)
+{
+    if (level == max_level)
+        return 0;
+
+    while (level++ < max_level) {
+        phys_addr_t rtt = alloc_rtt(mc);
+        int ret;
+
+        if (rtt == PHYS_ADDR_MAX)
+            return -ENOMEM;
+
+        ret = realm_rtt_create(realm, ipa, level, rtt);
+
+        if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT &&
+            RMI_RETURN_INDEX(ret) == level - 1) {
+            /* The RTT already exists, continue */
Should rtt be freed and undelegated in this branch?
Indeed it should! There's a missing call to free_rtt(). Thanks for spotting.
quoted
+            continue;
+        }
+        if (ret) {
+            WARN(1, "Failed to create RTT at level %d: %d\n",
+                 level, ret);
+            free_rtt(rtt);
+            return -ENXIO;
+        }
+    }
+
+    return 0;
+}
+
Thanks,
Steve
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help