[PATCH v22 23/23] KVM: arm64: CCA: Control user register access for Realms
Gavin Shan
gshan at redhat.com
Tue Oct 6 15:00:45 PDT 2026
On 10/6/26 10:36 PM, Suzuki K Poulose wrote:
> On 06/10/2026 07:16, Gavin Shan wrote:
>> 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 */
>>>>> +
>
> This could be vcpu_is_rec().
vcpu_is_rec() is preferred here.
>>>>> 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 :)
>
> Sure, these two patches are closely related and may be even could be
> folded in. I split it out to make it easier to review.
>
> 22: Allow exposing SVE_VLS for unfinalized VCPU RECs
> 23: Control register accesses includingthe SVE_VLS, but prevent
> everything else
>
> Does it help ?
>
I would suggest to fold PATCH[22] into PATCH[23].
Thanks,
Gavin
> Cheers
> Suzuki
>
>
>>
>>>>
>>>>> @@ -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