diff options
Diffstat (limited to 'target/arm/cpu64.c')
-rw-r--r-- | target/arm/cpu64.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index c7a1626bec..c690318a9b 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -559,6 +559,59 @@ static void cpu_arm_set_sve(Object *obj, bool value, Error **errp) cpu->isar.id_aa64pfr0 = t; } +#ifdef CONFIG_USER_ONLY +/* Mirror linux /proc/sys/abi/sve_default_vector_length. */ +static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + int32_t default_len, default_vq, remainder; + + if (!visit_type_int32(v, name, &default_len, errp)) { + return; + } + + /* Undocumented, but the kernel allows -1 to indicate "maximum". */ + if (default_len == -1) { + cpu->sve_default_vq = ARM_MAX_VQ; + return; + } + + default_vq = default_len / 16; + remainder = default_len % 16; + + /* + * Note that the 512 max comes from include/uapi/asm/sve_context.h + * and is the maximum architectural width of ZCR_ELx.LEN. + */ + if (remainder || default_vq < 1 || default_vq > 512) { + error_setg(errp, "cannot set sve-default-vector-length"); + if (remainder) { + error_append_hint(errp, "Vector length not a multiple of 16\n"); + } else if (default_vq < 1) { + error_append_hint(errp, "Vector length smaller than 16\n"); + } else { + error_append_hint(errp, "Vector length larger than %d\n", + 512 * 16); + } + return; + } + + cpu->sve_default_vq = default_vq; +} + +static void cpu_arm_get_sve_default_vec_len(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ARMCPU *cpu = ARM_CPU(obj); + int32_t value = cpu->sve_default_vq * 16; + + visit_type_int32(v, name, &value, errp); +} +#endif + void aarch64_add_sve_properties(Object *obj) { uint32_t vq; @@ -571,6 +624,13 @@ void aarch64_add_sve_properties(Object *obj) object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, cpu_arm_set_sve_vq, NULL, NULL); } + +#ifdef CONFIG_USER_ONLY + /* Mirror linux /proc/sys/abi/sve_default_vector_length. */ + object_property_add(obj, "sve-default-vector-length", "int32", + cpu_arm_get_sve_default_vec_len, + cpu_arm_set_sve_default_vec_len, NULL, NULL); +#endif } void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) |