@samitouri / QOSamiQemu / commits / 970ea8478c

target/arm: Allow 'aarch64=off' to be set for TCG CPUs

Allow the 'aarch64=off' property, which is currently KVM-only, to be set for TCG CPUs also. Note that we don't permit it on the qemu-aarch64 user-mode binary: this makes no sense as that executable can only handle AArch64 syscalls (and it would also assert at startup since it doesn't compile in the A32-specific GDB xml files like arm-neon.xml). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Clément Chigot <chigot@adacore.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260416165353.589569-3-peter.maydell@linaro.org

Peter Maydell committed Apr 16, 2026 at 17:53 UTC 970ea8478c059a7b753b21b60b4d7aa10944f120
4 files changed +45 -14
docs/system/arm/cpu-features.rst
+6 -4
@@ -23,10 +23,12 @@ not implement ARMv8-A, will not have the ``aarch64`` CPU property.
23 QEMU's support may be limited for some CPU features, only partially
24 supporting the feature or only supporting the feature under certain
25 configurations. For example, the ``aarch64`` CPU feature, which, when
26 -disabled, enables the optional AArch32 CPU feature, is only supported
27 -when using the KVM accelerator and when running on a host CPU type that
28 -supports the feature. While ``aarch64`` currently only works with KVM,
29 -it could work with TCG. CPU features that are specific to KVM are
26 +disabled, enables the optional AArch32 CPU feature, can only be set to
27 +``off`` on the TCG and KVM accelerators, and it cannot be set to
28 +``off`` under KVM unless running on a host CPU type that supports
29 +running guests in AArch32.
30 +
31 +CPU features that are inherently specific to KVM are
32 prefixed with "kvm-" and are described in "KVM VCPU Features".
33
34 CPU Feature Probing
target/arm/cpu-features.h
+5
@@ -1071,6 +1071,11 @@ static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id)
1071 return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL2) >= 2;
1072 }
1073
1074 +static inline bool isar_feature_aa64_aa32_el3(const ARMISARegisters *id)
1075 +{
1076 + return FIELD_EX64_IDREG(id, ID_AA64PFR0, EL3) >= 2;
1077 +}
1078 +
1079 static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
1080 {
1081 return FIELD_EX64_IDREG(id, ID_AA64PFR0, RAS) != 0;
target/arm/cpu.c
+32 -4
@@ -1244,10 +1244,38 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
1244 * uniform execution state like do_interrupt.
1245 */
1246 if (value == false) {
1247 - if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
1248 - error_setg(errp, "'aarch64' feature cannot be disabled "
1249 - "unless KVM is enabled and 32-bit EL1 "
1250 - "is supported");
1247 + if (kvm_enabled()) {
1248 + if (!kvm_arm_aarch32_supported()) {
1249 + error_setg(errp, "'aarch64' feature cannot be disabled for KVM "
1250 + "because this host does not support 32-bit EL1");
1251 + return;
1252 + }
1253 + } else if (tcg_enabled()) {
1254 +#ifdef CONFIG_USER_ONLY
1255 + error_setg(errp, "'aarch64' feature cannot be disabled for "
1256 + "usermode emulator qemu-aarch64; use qemu-arm instead");
1257 + return;
1258 +#else
1259 + bool aa32_at_highest_el;
1260 + if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
1261 + aa32_at_highest_el = cpu_isar_feature(aa64_aa32_el3, cpu);
1262 + } else if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
1263 + aa32_at_highest_el = cpu_isar_feature(aa64_aa32_el2, cpu);
1264 + } else {
1265 + aa32_at_highest_el = cpu_isar_feature(aa64_aa32_el1, cpu);
1266 + }
1267 +
1268 + if (!aa32_at_highest_el) {
1269 + error_setg(errp, "'aarch64' feature cannot be disabled for "
1270 + "this TCG CPU because it does not support 32-bit "
1271 + "execution at its highest implemented exception "
1272 + "level");
1273 + return;
1274 + }
1275 +#endif
1276 + } else {
1277 + error_setg(errp, "'aarch64' feature cannot be disabled for "
1278 + "this accelerator");
1279 return;
1280 }
1281 unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
tests/qtest/arm-cpu-features.c
+2 -6
@@ -493,12 +493,8 @@ static void test_query_cpu_model_expansion(const void *data)
493 sve_tests_default(qts, "max");
494 pauth_tests_default(qts, "max");
495
496 - /* Test that features that depend on KVM generate errors without. */
497 - assert_error(qts, "max",
498 - "'aarch64' feature cannot be disabled "
499 - "unless KVM is enabled and 32-bit EL1 "
500 - "is supported",
501 - "{ 'aarch64': false }");
496 + /* TCG allows us to turn off AArch64 on the 'max' CPU type */
497 + assert_set_feature(qts, "max", "aarch64", false);
498 }
499
500 qtest_quit(qts);