Add option to specify SVE vector length for realms.
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
arm/aarch64/include/kvm/kvm-config-arch.h | 6 ++++--
arm/aarch64/kvm.c | 23 +++++++++++++++++++++++
arm/aarch64/realm.c | 21 +++++++++++++++++++++
arm/include/arm-common/kvm-arch.h | 1 +
arm/include/arm-common/kvm-config-arch.h | 1 +
5 files changed, 50 insertions(+), 2 deletions(-)
@@ -29,8 +29,10 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset);
"Realm Measurement algorithm, default: sha256"),\
OPT_STRING('\0', "realm-pv", &(cfg)->realm_pv, \
"personalisation value", \
- "Personalisation Value (only) for Realm VMs"),
-
+ "Personalisation Value (only) for Realm VMs"), \
+ OPT_U64('\0', "sve-vl", &(cfg)->sve_vl, \
+ "SVE Vector Length the VM" \
+ "(only supported for Realms)"),
#include "arm-common/kvm-config-arch.h"
@@ -51,13 +51,19 @@ static void validate_mem_cfg(struct kvm *kvm)
}
}
+#define SVE_VL_ALIGN 128
+
static void validate_realm_cfg(struct kvm *kvm)
{
+ u32 sve_vl;
+
if (!kvm->cfg.arch.is_realm) {
if (kvm->cfg.arch.measurement_algo)
die("--measurement-algo valid only with --realm");
if (kvm->cfg.arch.realm_pv)
die("--realm-pv valid only with --realm");
+ if (kvm->cfg.arch.sve_vl)
+ die("--sve-vl valid only with --realm");
return;
}
@@ -76,6 +82,23 @@ static void validate_realm_cfg(struct kvm *kvm)
kvm->arch.measurement_algo = KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA256;
}
+ sve_vl = kvm->cfg.arch.sve_vl;
+ if (sve_vl) {
+ if (kvm->cfg.arch.disable_sve)
+ die("SVE VL requested when SVE is disabled");
+ if (!IS_ALIGNED(sve_vl, SVE_VL_ALIGN))
+ die("SVE VL is not aligned to %dbit\n", SVE_VL_ALIGN);
+ kvm->arch.sve_vq = (sve_vl / SVE_VL_ALIGN) - 1;
+ } else {
+ /*
+ * Disable SVE for Realms, if a VL is not requested.
+ * The SVE VL will be measured as part of the parameter
+ * and we do not want to add an unknown entity to the
+ * measurement.
+ */
+ kvm->cfg.arch.disable_sve = true;
+ }
+
if (kvm->cfg.arch.realm_pv) {
if (strlen(kvm->cfg.arch.realm_pv) > KVM_CAP_ARM_RME_RPV_SIZE)
die("Invalid size for Realm Personalization Value\n");
@@ -42,10 +42,31 @@ static void realm_configure_rpv(struct kvm *kvm)
die_perror("KVM_CAP_RME(KVM_CAP_ARM_RME_CONFIG_REALM) RPV");
}
+static void realm_configure_sve(struct kvm *kvm)
+{
+ struct kvm_cap_arm_rme_config_item sve_cfg = {
+ .cfg = KVM_CAP_ARM_RME_CFG_SVE,
+ .sve_vq = kvm->arch.sve_vq,
+ };
+
+ struct kvm_enable_cap rme_config = {
+ .cap = KVM_CAP_ARM_RME,
+ .args[0] = KVM_CAP_ARM_RME_CONFIG_REALM,
+ .args[1] = (u64)&sve_cfg,
+ };
+
+ if (kvm->cfg.arch.disable_sve)
+ return;
+
+ if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &rme_config) < 0)
+ die_perror("KVM_CAP_RME(KVM_CAP_ARM_RME_CONFIG_REALM) SVE");
+}
+
static void realm_configure_parameters(struct kvm *kvm)
{
realm_configure_hash_algo(kvm);
realm_configure_rpv(kvm);
+ realm_configure_sve(kvm);
}
void kvm_arm_realm_create_realm_descriptor(struct kvm *kvm)
@@ -114,6 +114,7 @@ struct kvm_arch {
cpu_set_t *vcpu_affinity_cpuset;
u64 measurement_algo;
+ u64 sve_vq;
};
#endif /* ARM_COMMON__KVM_ARCH_H */
@@ -19,6 +19,7 @@ struct kvm_config_arch {
u64 fw_addr;
bool no_pvtime;
bool disable_sve;
+ u64 sve_vl;
};
int irqchip_parser(const struct option *opt, const char *arg, int unset);