[PATCH v22 23/23] KVM: arm64: CCA: Control user register access for Realms

Suzuki K Poulose suzuki.poulose at arm.com
Mon Oct 5 23:01:37 PDT 2026


On 06/10/2026 06:47, Gavin Shan wrote:
> On 10/5/26 7:07 PM, Suzuki K Poulose wrote:
>> From: Jean-Philippe Brucker <jean-philippe at linaro.org>
>>
>> The RMM restricts the access to the register states that the host can
>> read/modify for a given Realm.
>>
>> e.g., At VCPU creation, can modify GPRS (x0-x30) and PC.
>>        While servicing SMCCC calls via RSI_HOST_CALL or servicing PSCI
>>        requests.
>>        MMIO emulation in the unprotected space.
>>
>> Additionally we use the sysreg configuration to advertise/configure the
>> following Realm parameters, which are required before the Realm 
>> Descriptor
>> is created:
>>   - SVE Vector Length
>>   - Number of HW Breakpoints/Watchpoints
>>   - PMU Counters.
>>
>> Thus KVM also additionally allows access to ID_AA64DFR0_EL1 and 
>> SVE_VLS for
>> the configuration of Realm creation parameters. We don't support PMUs for
>> the Realm VMs yet, so PMCR is not exposed.
>>
>> The RMM makes similar restrictions for reading of the guest's registers
>> (this is *confidential* compute after all), however we don't impose the
>> restriction here. This allows the VMM to read (stale) values from the
>> registers which might be useful to read back the initial values even if
>> the RMM doesn't provide the latest version. For migration of a realm VM,
>> a new interface will be needed so that the VMM can receive an
>> (encrypted) blob of the VM's state.
>>
>> Reflect the above in KVM_GET_REG_LIST, KVM_SET_ONE_REG calls.

>>   static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, 
>> u64 off)
>>   {
>>       int size;
>> @@ -553,6 +572,9 @@ static int copy_core_reg_indices(const struct 
>> kvm_vcpu *vcpu,
>>           u64 reg = KVM_REG_ARM64 | KVM_REG_ARM_CORE | i;
>>           int size = core_reg_size_from_offset(vcpu, i);
>> +        if (vcpu_is_rec(vcpu) && !kvm_realm_validate_core_reg(i))
>> +            continue;
>> +
>>           if (size < 0)
>>               continue;
>> @@ -598,6 +620,9 @@ static unsigned long num_sve_regs(const struct 
>> kvm_vcpu *vcpu)
>>       if (!vcpu_has_sve(vcpu))
>>           return 0;
>> +    if (kvm_vm_is_realm(vcpu->kvm))
>> +        return 1; /* KVM_REG_ARM64_SVE_VLS */
>> +
>>       if (!kvm_arm_vcpu_sve_finalized(vcpu))
>>           return 1; /* KVM_REG_ARM64_SVE_VLS */
>>
> 
> Aren't above two checks conflicting to each other?

Do they? We allow SVE_VLS only for the Realms and we allow that
before the vCPUs are finalized. For normal VMs, depending on
whether the vcpus are finalized, we either send 1 or the full list.

> 
>> @@ -625,6 +650,10 @@ static int copy_sve_reg_indices(const struct 
>> kvm_vcpu *vcpu,
>>           return -EFAULT;
>>       ++num_regs;
>> +    /* For Realms only support SVE_VLS */
>> +    if (kvm_vm_is_realm(vcpu->kvm))
>> +        return num_regs;
>> +
>>       if (!kvm_arm_vcpu_sve_finalized(vcpu))
>>           return num_regs;
> 
> Same question here.

As above.

Suzuki



More information about the linux-arm-kernel mailing list