[PATCH v16 29/45] KVM: arm64: CCA: Support runtime faulting of memory
Catalin Marinas
catalin.marinas at arm.com
Tue Aug 11 08:42:28 PDT 2026
On Mon, Aug 03, 2026 at 02:43:45PM +0100, Steven Price wrote:
> At runtime if the realm guest accesses memory which hasn't yet been
> mapped then KVM needs to either populate the region or fault the guest.
>
> For memory in the lower (protected) region of IPA a fresh page is
> provided to the RMM which will zero the contents. For memory in the
> upper (shared) region of IPA, the memory from the memslot is mapped
> into the realm VM non secure.
Is this still true with in-place guestmem conversion?
> @@ -1693,7 +1709,14 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
> kvm_fault_lock(kvm);
> if (mmu_invalidate_retry(kvm, mmu_seq)) {
> ret = -EAGAIN;
> - goto out_unlock;
> + goto out_release_page;
> + }
> +
> + if (kvm_is_realm(kvm)) {
> + prot &= ~KVM_PGTABLE_PROT_X;
> + ret = realm_map_ipa(kvm, s2fd->fault_ipa, pfn,
> + PAGE_SIZE, prot, memcache);
> + goto out_release_page;
> }
[...]
> +int realm_map_ipa(struct kvm *kvm, phys_addr_t ipa,
> + kvm_pfn_t pfn, unsigned long map_size,
> + enum kvm_pgtable_prot prot,
> + struct kvm_mmu_memory_cache *memcache)
> +{
> + struct realm *realm = &kvm->arch.realm;
> +
> + ipa = ALIGN_DOWN(ipa, map_size);
> + if (!kvm_realm_is_private_address(realm, ipa)) {
> + return realm_map_non_secure(kvm, ipa, pfn, map_size, prot,
> + memcache);
> + }
> +
> + /* It's impossible to map protected pages read-only. */
> + if (WARN_ON(!(prot & KVM_PGTABLE_PROT_W)))
> + return -EFAULT;
> + return realm_map_protected(kvm, ipa, pfn, map_size, memcache);
> +}
I was trying to understand (with the help of some LLMs) to understand
whether we can end up on the do_gpf() path as a result of VMM actions.
The above kvm_realm_is_private_address() only checks for the IPA but
does not check against guestmem if the page is truly private. I probably
miss something but the scenario would be something like:
1. VMM creates the gmem region with GUEST_MEMFD_FLAG_MMAP |
GUEST_MEMFD_FLAG_INIT_SHARED, mmap()able and GUP-pinnable
2. VMM starts an O_DIRECT write() from that mapping; the block layer
FOLL_PINs the shared folio
3. VMM runs a vCPU so the realm touches the protected-IPA alias of the
same gfn. gmem_abort() delegates the pinned, still-shared page to
the RMM
4. The in-flight I/O then reads the now-Realm page from the kernel
linear map. That access takes a GPF at EL1, so do_gpf() ->
die_kernel_fault()
x86, IIUC, also checks kvm_gmem_is_private(). They also have
kvm_arch_gmem_make_private() triggered on the kvm_gmem_get_pfn() path
but I got lost in the call sites, not sure whether that's strictly
needed if we check both private IPA and kvm_gmem_is_private().
--
Catalin
More information about the linux-arm-kernel
mailing list