Re: [PATCH v12 27/46] KVM: arm64: Handle Realm PSCI requests
From: Marc Zyngier
Date: Mon Mar 02 2026 - 11:46:14 EST
On Wed, 17 Dec 2025 10:11:04 +0000,
Steven Price <steven.price@xxxxxxx> wrote:
>
> The RMM needs to be informed of the target REC when a PSCI call is made
> with an MPIDR argument. Expose an ioctl to the userspace in case the PSCI
> is handled by it.
>
> Co-developed-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
> Signed-off-by: Steven Price <steven.price@xxxxxxx>
> Reviewed-by: Gavin Shan <gshan@xxxxxxxxxx>
> ---
> Changes since v11:
> * RMM->RMI renaming.
> Changes since v6:
> * Use vcpu_is_rec() rather than kvm_is_realm(vcpu->kvm).
> * Minor renaming/formatting fixes.
> ---
> arch/arm64/include/asm/kvm_rmi.h | 3 +++
> arch/arm64/kvm/arm.c | 25 +++++++++++++++++++++++++
> arch/arm64/kvm/psci.c | 30 ++++++++++++++++++++++++++++++
> arch/arm64/kvm/rmi.c | 14 ++++++++++++++
> 4 files changed, 72 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_rmi.h
> index bfe6428eaf16..77da297ca09d 100644
> --- a/arch/arm64/include/asm/kvm_rmi.h
> +++ b/arch/arm64/include/asm/kvm_rmi.h
> @@ -118,6 +118,9 @@ int realm_map_non_secure(struct realm *realm,
> kvm_pfn_t pfn,
> unsigned long size,
> struct kvm_mmu_memory_cache *memcache);
> +int realm_psci_complete(struct kvm_vcpu *source,
> + struct kvm_vcpu *target,
> + unsigned long status);
>
> static inline bool kvm_realm_is_private_address(struct realm *realm,
> unsigned long addr)
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 06070bc47ee3..fb04d032504e 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1797,6 +1797,22 @@ static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
> return __kvm_arm_vcpu_set_events(vcpu, events);
> }
>
> +static int kvm_arm_vcpu_rmi_psci_complete(struct kvm_vcpu *vcpu,
> + struct kvm_arm_rmi_psci_complete *arg)
> +{
> + struct kvm_vcpu *target = kvm_mpidr_to_vcpu(vcpu->kvm, arg->target_mpidr);
> +
> + if (!target)
> + return -EINVAL;
> +
> + /*
> + * RMM v1.0 only supports PSCI_RET_SUCCESS or PSCI_RET_DENIED
> + * for the status. But, let us leave it to the RMM to filter
> + * for making this future proof.
> + */
> + return realm_psci_complete(vcpu, target, arg->psci_status);
> +}
> +
> long kvm_arch_vcpu_ioctl(struct file *filp,
> unsigned int ioctl, unsigned long arg)
> {
> @@ -1925,6 +1941,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>
> return kvm_arm_vcpu_finalize(vcpu, what);
> }
> + case KVM_ARM_VCPU_RMI_PSCI_COMPLETE: {
> + struct kvm_arm_rmi_psci_complete req;
> +
> + if (!vcpu_is_rec(vcpu))
> + return -EPERM;
Same remark as for the other ioctl: EPERM is not quite describing the
problem.
> + if (copy_from_user(&req, argp, sizeof(req)))
> + return -EFAULT;
> + return kvm_arm_vcpu_rmi_psci_complete(vcpu, &req);
> + }
> default:
> r = -EINVAL;
> }
> diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
> index 3b5dbe9a0a0e..a68f3c1878a5 100644
> --- a/arch/arm64/kvm/psci.c
> +++ b/arch/arm64/kvm/psci.c
> @@ -103,6 +103,12 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>
> reset_state->reset = true;
> kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
> + /*
> + * Make sure we issue PSCI_COMPLETE before the VCPU can be
> + * scheduled.
> + */
> + if (vcpu_is_rec(vcpu))
> + realm_psci_complete(source_vcpu, vcpu, PSCI_RET_SUCCESS);
>
I really think in-kernel PSCI should be for NS VMs only. The whole
reason for moving to userspace support was to stop adding features to
an already complex infrastructure, and CCA is exactly the sort of
things we want userspace to deal with.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.