[PATCH v22 23/23] KVM: arm64: CCA: Control user register access for Realms
Gavin Shan
gshan at redhat.com
Mon Oct 5 23:16:37 PDT 2026
On 10/6/26 4:01 PM, Suzuki K Poulose wrote:
> 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.
>
num_sve_regs() can be called for 3 cases: (a) non-finalized RECs; (b) finalized
RECs; (c) Other finalized vCPUs, correct? "if (kvm_vm_is_realm(vcpu->kvm))", which
would be "if (vcpu_is_rec(vcpu))", covers (a) and (b). We needn't the excessive
check "if (!kvm_arm_vcpu_sve_finalized(vcpu))". So the check would be something
as below after this series is applied:
/*
* KVM_REG_ARM64_SVE_VLS is visible on realm vCPU no matter if it
* has been finalized.
*/
if (vcpu_is_rec(vcpu))
return 1;
This check "if (vcpu_is_rec(vcpu))" belongs to PATCH[22]. Hope I make myself
clear this time :)
>>
>>> @@ -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
Thanks,
Gavin
More information about the linux-arm-kernel
mailing list