From: Marc Zyngier <maz@kernel.org>
To: Steven Price <steven.price@arm.com>
Cc: kvm@vger.kernel.org, kvmarm@lists.linux.dev,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, James Morse <james.morse@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Joey Gouly <joey.gouly@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Christoffer Dall <christoffer.dall@arm.com>,
Fuad Tabba <tabba@google.com>,
linux-coco@lists.linux.dev,
Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>,
Gavin Shan <gshan@redhat.com>,
Shanker Donthineni <sdonthineni@nvidia.com>,
Alper Gun <alpergun@google.com>,
"Aneesh Kumar K . V" <aneesh.kumar@kernel.org>,
Emi Kisanuki <fj0570is@fujitsu.com>,
Vishal Annapurve <vannapurve@google.com>,
WeiLin.Chang@arm.com, Lorenzo Pieralisi <lpieralisi@kernel.org>
Subject: Re: [PATCH v15 20/37] KVM: arm64: CCA: Allow populating initial contents
Date: Mon, 03 Aug 2026 13:43:29 +0100 [thread overview]
Message-ID: <861pcfcr2m.wl-maz@kernel.org> (raw)
In-Reply-To: <20260715142841.80544-21-steven.price@arm.com>
On Wed, 15 Jul 2026 15:28:22 +0100,
Steven Price <steven.price@arm.com> wrote:
>
> The VMM needs to populate the realm with some data before starting (e.g.
> a kernel and initrd). This is measured by the RMM and used as part of
> the attestation later on.
>
> Signed-off-by: Steven Price <steven.price@arm.com>
> ---
> Changes since v14:
> * Holding of locks slots_lock and config_lock have been moved up the
> callstack with lockdesp assertions placed in the lower functions.
> * Add overflow check into kvm_arm_rmi_populate().
> Changes since v13:
> * Rename realm_create_protected_data_page() to realm_data_map_init().
> Changes since v12:
> * The ioctl now updates the structure with the amount populated rather
> than returning this through the ioctl return code.
> * Use the new RMM v2.0 range based RMI calls.
> * Adapt to upstream changes in kvm_gmem_populate().
> Changes since v11:
> * The multiplex CAP is gone and there's a new ioctl which makes use of
> the generic kvm_gmem_populate() functionality.
> Changes since v7:
> * Improve the error codes.
> * Other minor changes from review.
> Changes since v6:
> * Handle host potentially having a larger page size than the RMM
> granule.
> * Drop historic "par" (protected address range) from
> populate_par_region() - it doesn't exist within the current
> architecture.
> * Add a cond_resched() call in kvm_populate_realm().
> Changes since v5:
> * Refactor to use PFNs rather than tracking struct page in
> realm_create_protected_data_page().
> * Pull changes from a later patch (in the v5 series) for accessing
> pages from a guest memfd.
> * Do the populate in chunks to avoid holding locks for too long and
> triggering RCU stall warnings.
> ---
> arch/arm64/include/asm/kvm_rmi.h | 4 ++
> arch/arm64/kvm/Kconfig | 1 +
> arch/arm64/kvm/arm.c | 13 ++++
> arch/arm64/kvm/rmi.c | 119 +++++++++++++++++++++++++++++++
> 4 files changed, 137 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_rmi.h
> index 5cb99c187202..fd0c57594a22 100644
> --- a/arch/arm64/include/asm/kvm_rmi.h
> +++ b/arch/arm64/include/asm/kvm_rmi.h
> @@ -105,6 +105,10 @@ int kvm_rec_enter(struct kvm_vcpu *vcpu);
> int kvm_rec_pre_enter(struct kvm_vcpu *vcpu);
> int handle_rec_exit(struct kvm_vcpu *vcpu, int rec_run_status);
>
> +struct kvm_arm_rmi_populate;
> +
> +int kvm_arm_rmi_populate(struct kvm *kvm,
> + struct kvm_arm_rmi_populate *arg);
> void kvm_realm_unmap_range(struct kvm *kvm,
> unsigned long ipa,
> unsigned long size,
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 189e8ad78b22..83b95e836b4d 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -37,6 +37,7 @@ menuconfig KVM
> select SCHED_INFO
> select GUEST_PERF_EVENTS if PERF_EVENTS
> select KVM_GUEST_MEMFD
> + select HAVE_KVM_ARCH_GMEM_POPULATE
> select ARM_RMM
> help
> Support hosting virtualized guest machines.
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index df33322b8fea..1558bb12b1b1 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -2153,6 +2153,19 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
> return -EFAULT;
> return kvm_vm_ioctl_get_reg_writable_masks(kvm, &range);
> }
> + case KVM_ARM_RMI_POPULATE: {
> + struct kvm_arm_rmi_populate req;
> + int ret;
> +
> + if (!kvm_is_realm(kvm))
> + return -ENXIO;
> + if (copy_from_user(&req, argp, sizeof(req)))
> + return -EFAULT;
> + ret = kvm_arm_rmi_populate(kvm, &req);
> + if (copy_to_user(argp, &req, sizeof(req)))
> + return -EFAULT;
> + return ret;
> + }
> default:
> return -EINVAL;
> }
> diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
> index 53b5b18f2275..e2b4c64e982d 100644
> --- a/arch/arm64/kvm/rmi.c
> +++ b/arch/arm64/kvm/rmi.c
> @@ -590,6 +590,76 @@ void kvm_realm_unmap_range(struct kvm *kvm, unsigned long start,
> realm_unmap_private_range(kvm, start, end, may_block);
> }
>
> +static int realm_data_map_init(struct kvm *kvm, unsigned long ipa,
> + kvm_pfn_t dst_pfn, kvm_pfn_t src_pfn,
> + unsigned long flags)
> +{
> + struct realm *realm = &kvm->arch.realm;
> + phys_addr_t rd = virt_to_phys(realm->rd);
> + phys_addr_t dst_phys, src_phys;
> + int ret;
> +
> + lockdep_assert_held(&kvm->slots_lock);
> + lockdep_assert_held(&kvm->arch.config_lock);
> +
> + dst_phys = __pfn_to_phys(dst_pfn);
> + src_phys = __pfn_to_phys(src_pfn);
> +
> + if (rmi_delegate_page(dst_phys))
> + return -ENXIO;
> +
> +retry:
> + ret = rmi_rtt_data_map_init(rd, dst_phys, ipa, src_phys, flags);
> + if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
> + /* Create missing RTTs and retry */
> + int level = RMI_RETURN_INDEX(ret);
> +
> + KVM_BUG_ON(level >= KVM_PGTABLE_LAST_LEVEL, kvm);
Surely you should break here and make it stop, right? The VM is bugged
anyway, so what's the point in continuing?
> +
> + ret = realm_create_rtt_levels(realm, ipa, level,
> + level + 1, NULL);
> + if (!ret)
> + goto retry;
> + }
> +
> + if (ret && WARN_ON(rmi_undelegate_page(dst_phys))) {
> + /* Leak the page if the undelegate fails */
> + get_page(pfn_to_page(dst_pfn));
Same here. The VM should be dead.
> + }
> +
> + return ret <= 0 ? ret : -ENXIO;
> +}
> +
> +static int populate_region_cb(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
> + struct page *src_page, void *opaque)
> +{
> + unsigned long data_flags = *(unsigned long *)opaque;
> + phys_addr_t ipa = gfn_to_gpa(gfn);
> +
> + return realm_data_map_init(kvm, ipa, pfn, page_to_pfn(src_page),
> + data_flags);
> +}
> +
> +static long populate_region(struct kvm *kvm,
> + gfn_t base_gfn,
> + unsigned long pages,
> + u64 uaddr,
> + unsigned long data_flags)
> +{
> + long ret = 0;
> +
> + lockdep_assert_held(&kvm->slots_lock);
> + lockdep_assert_held(&kvm->arch.config_lock);
> +
> + if (!uaddr)
> + return -EINVAL;
> +
> + ret = kvm_gmem_populate(kvm, base_gfn, u64_to_user_ptr(uaddr), pages,
> + false, populate_region_cb, &data_flags);
> +
> + return ret;
> +}
> +
> enum ripas_action {
> RIPAS_INIT,
> RIPAS_SET,
> @@ -705,6 +775,55 @@ static int realm_ensure_created(struct kvm *kvm)
> return realm_create_rd(kvm);
> }
>
> +int kvm_arm_rmi_populate(struct kvm *kvm,
> + struct kvm_arm_rmi_populate *args)
> +{
> + unsigned long data_flags = 0;
> + unsigned long ipa_start = args->base;
> + unsigned long ipa_end = ipa_start + args->size;
> + long pages_populated;
> + int ret;
> +
> + if (args->reserved ||
> + (args->flags & ~KVM_ARM_RMI_POPULATE_FLAGS_MEASURE) ||
> + args->base + args->size < args->base ||
More importantly, what checks that this is within the IPA range?
> + !IS_ALIGNED(ipa_start, PAGE_SIZE) ||
> + !IS_ALIGNED(ipa_end, PAGE_SIZE) ||
> + !IS_ALIGNED(args->source_uaddr, PAGE_SIZE))
> + return -EINVAL;
> +
> + if (args->flags & KVM_ARM_RMI_POPULATE_FLAGS_MEASURE)
> + data_flags |= RMI_MEASURE_CONTENT;
> +
> + mutex_lock(&kvm->slots_lock);
> + mutex_lock(&kvm->arch.config_lock);
> +
> + ret = realm_ensure_created(kvm);
> + if (ret)
> + goto out_unlock;
> +
> + if (args->size == 0)
> + goto out_unlock;
> +
> + pages_populated = populate_region(kvm, gpa_to_gfn(ipa_start),
> + args->size >> PAGE_SHIFT,
> + args->source_uaddr, data_flags);
> +
> + if (pages_populated < 0) {
> + ret = pages_populated;
> + goto out_unlock;
> + }
> +
> + args->size -= pages_populated << PAGE_SHIFT;
> + args->source_uaddr += pages_populated << PAGE_SHIFT;
> + args->base += pages_populated << PAGE_SHIFT;
> +
> +out_unlock:
> + mutex_unlock(&kvm->arch.config_lock);
> + mutex_unlock(&kvm->slots_lock);
> + return ret;
> +}
> +
> static void kvm_complete_ripas_change(struct kvm_vcpu *vcpu)
> {
> struct kvm *kvm = vcpu->kvm;
M.
--
Without deviation from the norm, progress is not possible.
next prev parent reply other threads:[~2026-08-03 12:43 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-15 14:28 [PATCH v15 00/37] arm64: Support for Arm CCA in KVM Steven Price
2026-07-15 14:28 ` [PATCH v15 01/37] KVM: arm64: Include kvm_emulate.h in kvm/arm_psci.h Steven Price
2026-07-15 14:28 ` [PATCH v15 02/37] KVM: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h Steven Price
2026-07-15 15:59 ` Marc Zyngier
2026-07-15 16:22 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 03/37] arm64: mm: Handle Granule Protection Faults (GPFs) Steven Price
2026-07-15 14:28 ` [PATCH v15 04/37] KVM: arm64: CCA: Check for RMI support at KVM init Steven Price
2026-07-15 14:28 ` [PATCH v15 05/37] KVM: arm64: CCA: Check for LPA2 support Steven Price
2026-07-16 9:23 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 06/37] KVM: arm64: CCA: Define the user ABI Steven Price
2026-07-16 9:40 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 07/37] KVM: arm64: CCA: Add basic infrastructure for creating a realm Steven Price
2026-07-15 14:28 ` [PATCH v15 08/37] KVM: arm64: CCA: Don't expose unsupported capabilities for realm guests Steven Price
2026-07-15 14:28 ` [PATCH v15 09/37] KVM: arm64: CCA: Allow passing the machine type in KVM creation Steven Price
2026-07-15 16:14 ` Marc Zyngier
2026-07-16 9:17 ` Steven Price
2026-07-16 9:37 ` Marc Zyngier
2026-07-15 14:28 ` [PATCH v15 10/37] KVM: arm64: CCA: Tear down RTTs Steven Price
2026-07-15 14:28 ` [PATCH v15 11/37] KVM: arm64: CCA: Allocate and free RECs to match vCPUs Steven Price
2026-07-15 14:28 ` [PATCH v15 12/37] KVM: arm64: CCA: Support the VGIC in realms Steven Price
2026-07-22 8:27 ` Kohei Enju
2026-07-22 9:27 ` Marc Zyngier
2026-07-23 6:38 ` Kohei Enju
2026-07-23 8:07 ` Marc Zyngier
2026-07-23 9:02 ` Kohei Enju
2026-07-22 13:31 ` Steven Price
2026-07-23 6:56 ` Kohei Enju
2026-07-23 14:46 ` Steven Price
2026-07-24 5:40 ` Kohei Enju
2026-07-15 14:28 ` [PATCH v15 13/37] KVM: arm64: CCA: Support timers in realm RECs Steven Price
2026-07-27 9:21 ` Marc Zyngier
2026-07-29 10:47 ` Steven Price
2026-07-29 10:58 ` Marc Zyngier
2026-07-30 8:47 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 14/37] KVM: arm64: CCA: Handle realm enter/exit Steven Price
2026-07-27 8:14 ` Kohei Enju
2026-07-30 13:58 ` Steven Price
2026-07-30 14:57 ` Suzuki K Poulose
2026-07-31 0:57 ` Kohei Enju
2026-07-27 15:01 ` Marc Zyngier
2026-07-30 16:17 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 15/37] KVM: arm64: CCA: Handle RMI_EXIT_RIPAS_CHANGE Steven Price
2026-08-03 11:09 ` Marc Zyngier
2026-08-03 14:04 ` Steven Price
2026-08-03 14:48 ` Marc Zyngier
2026-08-03 15:30 ` Suzuki K Poulose
2026-08-04 12:20 ` Fuad Tabba
2026-08-04 13:19 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 16/37] KVM: arm64: CCA: Handle realm MMIO emulation Steven Price
2026-08-03 11:27 ` Marc Zyngier
2026-08-03 14:57 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 17/37] KVM: arm64: Expose support for private memory Steven Price
2026-07-16 10:25 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 18/37] KVM: arm64: CCA: Create the realm descriptor Steven Price
2026-07-15 14:28 ` [PATCH v15 19/37] KVM: arm64: CCA: Activate realms on first vCPU run Steven Price
2026-08-03 12:29 ` Marc Zyngier
2026-08-03 15:18 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 20/37] KVM: arm64: CCA: Allow populating initial contents Steven Price
2026-08-03 12:43 ` Marc Zyngier [this message]
2026-08-03 15:30 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 21/37] KVM: arm64: CCA: Set RIPAS of initial memslots Steven Price
2026-07-15 14:28 ` [PATCH v15 22/37] KVM: arm64: CCA: Support runtime faulting of memory Steven Price
2026-07-15 14:28 ` [PATCH v15 23/37] KVM: arm64: CCA: Handle realm vCPU load Steven Price
2026-07-15 14:28 ` [PATCH v15 24/37] KVM: arm64: CCA: Validate register access for Realm VMs Steven Price
2026-07-15 14:28 ` [PATCH v15 25/37] KVM: arm64: CCA: Handle Realm PSCI requests Steven Price
2026-07-16 10:38 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 26/37] KVM: arm64: WARN on injected undef exceptions Steven Price
2026-07-15 15:46 ` Marc Zyngier
2026-07-15 16:15 ` Steven Price
2026-07-15 16:25 ` Marc Zyngier
2026-07-15 16:31 ` Steven Price
2026-07-15 16:43 ` Marc Zyngier
2026-07-16 9:17 ` Steven Price
2026-07-15 14:28 ` [PATCH v15 27/37] KVM: arm64: CCA: Allow userspace to inject aborts Steven Price
2026-07-16 10:19 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 28/37] KVM: arm64: CCA: Support RSI_HOST_CALL Steven Price
2026-07-16 10:22 ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 29/37] KVM: arm64: CCA: Allow checking SVE on VM instance Steven Price
2026-07-15 14:28 ` [PATCH v15 30/37] KVM: arm64: CCA: Prevent Device mappings for realms Steven Price
2026-07-15 14:28 ` [PATCH v15 31/37] KVM: arm64: CCA: Propagate breakpoint and watchpoint counts to userspace Steven Price
2026-07-15 14:28 ` [PATCH v15 32/37] KVM: arm64: CCA: Set breakpoint parameters through SET_ONE_REG Steven Price
2026-07-15 14:28 ` [PATCH v15 33/37] KVM: arm64: CCA: Propagate max SVE vector length from the RMM Steven Price
2026-07-15 14:28 ` [PATCH v15 34/37] KVM: arm64: CCA: Configure max SVE vector length for a Realm Steven Price
2026-07-15 14:28 ` [PATCH v15 35/37] KVM: arm64: CCA: Provide register list for unfinalized RECs Steven Price
2026-07-15 14:28 ` [PATCH v15 36/37] KVM: arm64: CCA: Provide an accurate register list Steven Price
2026-07-15 14:28 ` [PATCH v15 37/37] KVM: arm64: CCA: Enable realms to be created Steven Price
2026-07-16 8:36 ` [PATCH v15 00/37] arm64: Support for Arm CCA in KVM Marc Zyngier
2026-07-16 9:20 ` Steven Price
2026-07-16 9:42 ` Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=861pcfcr2m.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=WeiLin.Chang@arm.com \
--cc=alexandru.elisei@arm.com \
--cc=alpergun@google.com \
--cc=aneesh.kumar@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=christoffer.dall@arm.com \
--cc=fj0570is@fujitsu.com \
--cc=gankulkarni@os.amperecomputing.com \
--cc=gshan@redhat.com \
--cc=james.morse@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=sdonthineni@nvidia.com \
--cc=steven.price@arm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=vannapurve@google.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.