[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 12/14] target/arm: Add sve-default-vector-length cpu property
From: |
Peter Maydell |
Subject: |
[PULL 12/14] target/arm: Add sve-default-vector-length cpu property |
Date: |
Tue, 27 Jul 2021 11:47:59 +0100 |
From: Richard Henderson <richard.henderson@linaro.org>
Mirror the behavour of /proc/sys/abi/sve_default_vector_length
under the real linux kernel. We have no way of passing along
a real default across exec like the kernel can, but this is a
decent way of adjusting the startup vector length of a process.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/482
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20210723203344.968563-4-richard.henderson@linaro.org
[PMM: tweaked docs formatting, document -1 special-case,
added fixup patch from RTH mentioning QEMU's maximum veclen.]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
docs/system/arm/cpu-features.rst | 15 ++++++++
target/arm/cpu.h | 5 +++
target/arm/cpu.c | 14 ++++++--
target/arm/cpu64.c | 60 ++++++++++++++++++++++++++++++++
4 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index c455442eaf5..11dce5c6037 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -376,3 +376,18 @@ verbose command lines. However, the recommended way to
select vector
lengths is to explicitly enable each desired length. Therefore only
example's (1), (4), and (6) exhibit recommended uses of the properties.
+SVE User-mode Default Vector Length Property
+--------------------------------------------
+
+For qemu-aarch64, the cpu property ``sve-default-vector-length=N`` is
+defined to mirror the Linux kernel parameter file
+``/proc/sys/abi/sve_default_vector_length``. The default length, ``N``,
+is in units of bytes and must be between 16 and 8192.
+If not specified, the default vector length is 64.
+
+If the default length is larger than the maximum vector length enabled,
+the actual vector length will be reduced. Note that the maximum vector
+length supported by QEMU is 256.
+
+If this property is set to ``-1`` then the default vector length
+is set to the maximum possible length.
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index be9a4dceae1..9f0a5f84d50 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1006,6 +1006,11 @@ struct ARMCPU {
/* Used to set the maximum vector length the cpu will support. */
uint32_t sve_max_vq;
+#ifdef CONFIG_USER_ONLY
+ /* Used to set the default vector length at process start. */
+ uint32_t sve_default_vq;
+#endif
+
/*
* In sve_vq_map each set bit is a supported vector length of
* (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 752b15bb797..2866dd76588 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -201,7 +201,8 @@ static void arm_cpu_reset(DeviceState *dev)
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
/* with reasonable vector length */
if (cpu_isar_feature(aa64_sve, cpu)) {
- env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3);
+ env->vfp.zcr_el[1] =
+ aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
}
/*
* Enable TBI0 but not TBI1.
@@ -1051,7 +1052,16 @@ static void arm_cpu_initfn(Object *obj)
QLIST_INIT(&cpu->pre_el_change_hooks);
QLIST_INIT(&cpu->el_change_hooks);
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+# ifdef TARGET_AARCH64
+ /*
+ * The linux kernel defaults to 512-bit vectors, when sve is supported.
+ * See documentation for /proc/sys/abi/sve_default_vector_length, and
+ * our corresponding sve-default-vector-length cpu property.
+ */
+ cpu->sve_default_vq = 4;
+# endif
+#else
/* Our inbound IRQ and FIQ lines */
if (kvm_enabled()) {
/* VIRQ and VFIQ are unused with KVM but we add them to maintain
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c7a1626bec2..c690318a9b6 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)
--
2.20.1
- [PULL 01/14] hw/arm/smmuv3: Check 31st bit to see if CD is valid, (continued)
- [PULL 01/14] hw/arm/smmuv3: Check 31st bit to see if CD is valid, Peter Maydell, 2021/07/27
- [PULL 04/14] target/arm: Add missing 'return's after calling v7m_exception_taken(), Peter Maydell, 2021/07/27
- [PULL 03/14] target/arm: Enforce that M-profile SP low 2 bits are always zero, Peter Maydell, 2021/07/27
- [PULL 02/14] qemu-options.hx: Fix formatting of -machine memory-backend option, Peter Maydell, 2021/07/27
- [PULL 07/14] hw/intc/armv7m_nvic: Correct size of ICSR.VECTPENDING, Peter Maydell, 2021/07/27
- [PULL 06/14] hw/intc/armv7m_nvic: ISCR.ISRPENDING is set for non-enabled pending interrupts, Peter Maydell, 2021/07/27
- [PULL 05/14] target/arm: Report M-profile alignment faults correctly to the guest, Peter Maydell, 2021/07/27
- [PULL 11/14] target/arm: Export aarch64_sve_zcr_get_valid_len, Peter Maydell, 2021/07/27
- [PULL 09/14] docs: Update path that mentions deprecated.rst, Peter Maydell, 2021/07/27
- [PULL 10/14] target/arm: Correctly bound length in sve_zcr_get_valid_len, Peter Maydell, 2021/07/27
- [PULL 12/14] target/arm: Add sve-default-vector-length cpu property,
Peter Maydell <=
- [PULL 13/14] hw/arm/nseries: Display hexadecimal value with '0x' prefix, Peter Maydell, 2021/07/27
- [PULL 08/14] hw/intc/armv7m_nvic: for v8.1M VECTPENDING hides S exceptions from NS, Peter Maydell, 2021/07/27
- [PULL 14/14] hw: aspeed_gpio: Fix memory size, Peter Maydell, 2021/07/27
- Re: [PULL 00/14] target-arm queue, Peter Maydell, 2021/07/27