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