[PATCH v6 38/43] arm64: RME: Configure max SVE vector length for a Realm
Gavin Shan
gshan at redhat.com
Sun Feb 2 15:26:28 PST 2025
On 12/13/24 1:56 AM, Steven Price wrote:
> From: Jean-Philippe Brucker <jean-philippe at linaro.org>
>
> Obtain the max vector length configured by userspace on the vCPUs, and
> write it into the Realm parameters. By default the vCPU is configured
> with the max vector length reported by RMM, and userspace can reduce it
> with a write to KVM_REG_ARM64_SVE_VLS.
>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Signed-off-by: Steven Price <steven.price at arm.com>
> ---
> arch/arm64/kvm/guest.c | 3 ++-
> arch/arm64/kvm/rme.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 429c8f10b76a..5562029368c5 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -363,7 +363,7 @@ static int set_sve_vls(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> if (!vcpu_has_sve(vcpu))
> return -ENOENT;
>
> - if (kvm_arm_vcpu_sve_finalized(vcpu))
> + if (kvm_arm_vcpu_sve_finalized(vcpu) || kvm_realm_is_created(vcpu->kvm))
> return -EPERM; /* too late! */
>
> if (WARN_ON(vcpu->arch.sve_state))
> @@ -825,6 +825,7 @@ static bool validate_realm_set_reg(struct kvm_vcpu *vcpu,
> switch (reg->id) {
> case KVM_REG_ARM_PMCR_EL0:
> case KVM_REG_ARM_ID_AA64DFR0_EL1:
> + case KVM_REG_ARM64_SVE_VLS:
> return true;
> }
> }
> diff --git a/arch/arm64/kvm/rme.c b/arch/arm64/kvm/rme.c
> index 39dbc19e4a42..3116ecee37a8 100644
> --- a/arch/arm64/kvm/rme.c
> +++ b/arch/arm64/kvm/rme.c
> @@ -297,6 +297,44 @@ static void realm_unmap_shared_range(struct kvm *kvm,
> }
> }
>
> +static int realm_init_sve_param(struct kvm *kvm, struct realm_params *params)
> +{
> + int ret = 0;
> + unsigned long i;
> + struct kvm_vcpu *vcpu;
> + int max_vl, realm_max_vl = -1;
> +
I would suggest to rename 'max_vl' and 'realm_max_vl' to 'vl' and 'last_vl'
since we're not looking for the maximal VLs. Instead, we're making sure the
VLs on all vCPUs are equal.
> + /*
> + * Get the preferred SVE configuration, set by userspace with the
> + * KVM_ARM_VCPU_SVE feature and KVM_REG_ARM64_SVE_VLS pseudo-register.
> + */
> + kvm_for_each_vcpu(i, vcpu, kvm) {
> + mutex_lock(&vcpu->mutex);
> + if (vcpu_has_sve(vcpu)) {
> + if (!kvm_arm_vcpu_sve_finalized(vcpu))
> + ret = -EINVAL;
> + max_vl = vcpu->arch.sve_max_vl;
> + } else {
> + max_vl = 0;
> + }
> + mutex_unlock(&vcpu->mutex);
> + if (ret)
> + return ret;
> +
> + /* We need all vCPUs to have the same SVE config */
> + if (realm_max_vl >= 0 && realm_max_vl != max_vl)
> + return -EINVAL;
> +
> + realm_max_vl = max_vl;
> + }
> +
> + if (realm_max_vl > 0) {
> + params->sve_vl = sve_vq_from_vl(realm_max_vl) - 1;
> + params->flags |= RMI_REALM_PARAM_FLAG_SVE;
> + }
> + return 0;
> +}
> +
> static int realm_create_rd(struct kvm *kvm)
> {
> struct realm *realm = &kvm->arch.realm;
> @@ -344,6 +382,10 @@ static int realm_create_rd(struct kvm *kvm)
> params->flags |= RMI_REALM_PARAM_FLAG_PMU;
> }
>
> + r = realm_init_sve_param(kvm, params);
> + if (r)
> + goto out_undelegate_tables;
> +
> params_phys = virt_to_phys(params);
>
> if (rmi_realm_create(rd_phys, params_phys)) {
Thanks,
Gavin
More information about the linux-arm-kernel
mailing list