Re: [PATCH v12 11/46] arm64: RMI: Activate realm on first VCPU run

From: Steven Price

Date: Mon Mar 02 2026 - 11:38:00 EST


On 02/03/2026 14:40, Marc Zyngier wrote:
> On Wed, 17 Dec 2025 10:10:48 +0000,
> Steven Price <steven.price@xxxxxxx> wrote:
>>
>> When a VCPU migrates to another physical CPU check
>
> To another physical CPU?
>
> That's not what kvm_arch_vcpu_run_pid_change() tracks. It really is
> limited to a new PID being associated to the vpcu thread. Which is
> indeed the case when the vpcu runs for the first time, but that's
> about it.
>
> If you need to track the physical CPU, we have some tracking for it in
> vcpu_load(), but that'd need some rework.

Sorry that was just a complete brainfart when I wrote that commit
message. We don't care about physical CPUs - this is just catching the
first VCPU run. Thanks for catching that.

>> if this is the first
>> time the guest has run, and if so activate the realm.
>>
>> Before the realm can be activated it must first be created, this is a
>> stub in this patch and will be filled in by a later patch.
>>
>> Signed-off-by: Steven Price <steven.price@xxxxxxx>
>> ---
>> New patch for v12
>> ---
>> arch/arm64/include/asm/kvm_rmi.h | 1 +
>> arch/arm64/kvm/arm.c | 6 +++++
>> arch/arm64/kvm/rmi.c | 42 ++++++++++++++++++++++++++++++++
>> 3 files changed, 49 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_rmi.h
>> index cb7350f8a01a..e4534af06d96 100644
>> --- a/arch/arm64/include/asm/kvm_rmi.h
>> +++ b/arch/arm64/include/asm/kvm_rmi.h
>> @@ -69,6 +69,7 @@ void kvm_init_rmi(void);
>> u32 kvm_realm_ipa_limit(void);
>>
>> int kvm_init_realm_vm(struct kvm *kvm);
>> +int kvm_activate_realm(struct kvm *kvm);
>> void kvm_destroy_realm(struct kvm *kvm);
>> void kvm_realm_destroy_rtts(struct kvm *kvm);
>>
>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>> index 941d1bec8e77..542df37b9e82 100644
>> --- a/arch/arm64/kvm/arm.c
>> +++ b/arch/arm64/kvm/arm.c
>> @@ -951,6 +951,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
>> return ret;
>> }
>>
>> + if (kvm_is_realm(vcpu->kvm)) {
>> + ret = kvm_activate_realm(kvm);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> mutex_lock(&kvm->arch.config_lock);
>> set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags);
>> mutex_unlock(&kvm->arch.config_lock);
>> diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c
>> index e57e8b7eafa9..98929382c365 100644
>> --- a/arch/arm64/kvm/rmi.c
>> +++ b/arch/arm64/kvm/rmi.c
>> @@ -223,6 +223,48 @@ void kvm_realm_destroy_rtts(struct kvm *kvm)
>> WARN_ON(realm_tear_down_rtt_range(realm, 0, (1UL << ia_bits)));
>> }
>>
>> +static int realm_ensure_created(struct kvm *kvm)
>> +{
>> + /* Provided in later patch */
>> + return -ENXIO;
>> +}
>> +
>> +int kvm_activate_realm(struct kvm *kvm)
>> +{
>> + struct realm *realm = &kvm->arch.realm;
>> + int ret;
>> +
>> + if (!kvm_is_realm(kvm))
>> + return -ENXIO;
>
> nit: you already checked for this in caller.

Ack

>> +
>> + if (kvm_realm_state(kvm) == REALM_STATE_ACTIVE)
>> + return 0;
>
> You probably also want to return early once the realm has been marked
> as dead -- it shouldn't be able to be a zombie and die twice.

Indeed, >= would be a better check.

Thanks,
Steve

>> +
>> + guard(mutex)(&kvm->arch.config_lock);
>> + /* Check again with the lock held */
>> + if (kvm_realm_state(kvm) == REALM_STATE_ACTIVE)
>> + return 0;
>> +
>> + ret = realm_ensure_created(kvm);
>> + if (ret)
>> + return ret;
>> +
>> + /* Mark state as dead in case we fail */
>> + WRITE_ONCE(realm->state, REALM_STATE_DEAD);
>> +
>> + if (!irqchip_in_kernel(kvm)) {
>> + /* Userspace irqchip not yet supported with realms */
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + ret = rmi_realm_activate(virt_to_phys(realm->rd));
>> + if (ret)
>> + return -ENXIO;
>> +
>> + WRITE_ONCE(realm->state, REALM_STATE_ACTIVE);
>> + return 0;
>> +}
>> +
>> void kvm_destroy_realm(struct kvm *kvm)
>> {
>> struct realm *realm = &kvm->arch.realm;
>
> Thanks,
>
> M.
>