Re: [PATCH v22 22/23] KVM: arm64: CCA: Expose SVE VL register before VCPU finalization
From: Suzuki K Poulose
Date: Tue Oct 06 2026 - 01:57:50 EST
On 06/10/2026 06:35, Gavin Shan wrote:
On 10/5/26 7:07 PM, Suzuki K Poulose wrote:
From: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
Userspace must configure the SVE vector length before the Realm is created
(as it is part of the parameter for Realm creation), but the Realm VCPUs
cannot be finalized until after the Realm Descriptor has been created.
KVM_GET_REG_LIST currently rejects the unfinalized VCPUs, which prevents
the userspace from discovering and configuring the VLs for the Realm.
Allow KVM_GET_REG_LIST for unfinalized RECs and make the SVE register
enumeration handle the unfinalized case explicitly. i.e., only expose
KVM_REG_ARM64_SVE_VLS before SVE is finalized.
One adverse side effect of this change is that a KVM_GET_REG_LIST call that
only probes for the array size will now succeed even if SVE is not
finalized, but that seems harmless since the following KVM_GET_REG_LIST
with the full array will fail.
Signed-off-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
Signed-off-by: Steven Price <steven.price@xxxxxxx>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
---
arch/arm64/kvm/arm.c | 15 ++++++++++++++-
arch/arm64/kvm/guest.c | 10 +++++-----
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index fe707a0c47308..d99e7818f5894 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2004,6 +2004,19 @@ static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
return __kvm_arm_vcpu_set_events(vcpu, events);
}
+/*
+ * Realm VCPUs can be finalized only after the Realm descriptor is created.
+ * But in order to seal the SVE VL, we need to allow the userspace to read/write
+ * to the SVE_VL, before everything is finalized.
+ * Allow the register list for RECs before the VCPUs are finalized.
+ */
+static bool kvm_arm_vcpu_reg_list_allowed(struct kvm_vcpu *vcpu)
+{
+ if (kvm_arm_vcpu_is_finalized(vcpu))
+ return true;
+ return vcpu_is_rec(vcpu);
+}
+
Needn't to keep this helper, and the code can be integrated to kvm_arch_vcpu_ioctl(),
see below.
long kvm_arch_vcpu_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -2059,7 +2072,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
break;
r = -EPERM;
- if (!kvm_arm_vcpu_is_finalized(vcpu))
+ if (!kvm_arm_vcpu_reg_list_allowed(vcpu))
break;
Needn't to keep the helper kvm_arm_vcpu_reg_list_allowed() after its logic is
combined to kvm_arch_vcpu_ioctl().
/*
* Realm vCPUs can be finalized only after the Realm descriptor is created.
* We need to allow access KVM_REG_ARM64_SVE_VLS before that so that the
* register can be sealed.
*/
if (!(vcpu_is_rec(vcpu) || kvm_arm_vcpu_is_finalized(vcpu))
break;
Wanted to keep the ioctl handling section cleaner and easier to read.
Hence the wrapper. The name is intuitive enough and compiler can do
away with inlining.
r = -EFAULT;
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index b01d6622b8720..c3ca369882273 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -598,8 +598,8 @@ static unsigned long num_sve_regs(const struct kvm_vcpu *vcpu)
if (!vcpu_has_sve(vcpu))
return 0;
- /* Policed by KVM_GET_REG_LIST: */
- WARN_ON(!kvm_arm_vcpu_sve_finalized(vcpu));
+ if (!kvm_arm_vcpu_sve_finalized(vcpu))
+ return 1; /* KVM_REG_ARM64_SVE_VLS */
Question: After a (Rec) vCPU is finalized, the returned number of registers won't
be 1. Is this expected? Otherwise, we need to use vcpu_is_rec() here.
/*
* KVM_REG_ARM64_SVE_VLS is visible for realm vCPUs no matter if
* they have been finalized.
*/
if (vcpu_is_rec(vcpu))
return 1;
This is addressed in the next patch.
Cheers
Suzuki