[RFC PATCH 06/11] target/arm: Introduce host_cpu_feature_supported()

Philippe Mathieu-Daudé posted 11 patches 3 months ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>, Alexander Graf <agraf@csgraf.de>, Mads Ynddal <mads@ynddal.dk>, Paolo Bonzini <pbonzini@redhat.com>
There is a newer version of this series
[RFC PATCH 06/11] target/arm: Introduce host_cpu_feature_supported()
Posted by Philippe Mathieu-Daudé 3 months ago
host_cpu_feature_supported() is the generic method which
dispatch to the host accelerator implementation, taking
care to cache supported features.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/arm/cpu.h          | 11 +++++++++++
 target/arm/arm_hw_accel.c | 27 +++++++++++++++++++++++++++
 target/arm/meson.build    |  2 +-
 3 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 target/arm/arm_hw_accel.c

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 5136c4caabf..aff60cef6da 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2508,6 +2508,16 @@ static inline ARMSecuritySpace arm_secure_to_space(bool secure)
 
 #if !defined(CONFIG_USER_ONLY)
 
+/**
+ * host_cpu_feature_supported:
+ * @feat: Feature to test for support
+ * @can_emulate: Whether Allow to fall back to emulation if @feat is not
+ *               supported by hardware accelerator
+ *
+ * Hardware accelerator implementation of cpu_feature_supported().
+ */
+bool host_cpu_feature_supported(enum arm_features feature, bool can_emulate);
+
 /**
  * arm_hw_accel_cpu_feature_supported:
  * @feat: Feature to test for support
@@ -2515,6 +2525,7 @@ static inline ARMSecuritySpace arm_secure_to_space(bool secure)
  *               supported by hardware accelerator
  *
  * Hardware accelerator implementation of cpu_feature_supported().
+ * Common code should use the generic host_cpu_feature_supported() equivalent.
  */
 bool arm_hw_accel_cpu_feature_supported(enum arm_features feat,
                                         bool can_emulate);
diff --git a/target/arm/arm_hw_accel.c b/target/arm/arm_hw_accel.c
new file mode 100644
index 00000000000..3a8ff007599
--- /dev/null
+++ b/target/arm/arm_hw_accel.c
@@ -0,0 +1,27 @@
+/*
+ * QEMU helpers for ARM hardware accelerators
+ *
+ *  Copyright (c) Linaro
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+bool host_cpu_feature_supported(enum arm_features feat, bool can_emulate)
+{
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
+    static enum { F_UNKN, F_SUPP, F_UNSUPP } supported[64] = { };
+
+    assert(feat < ARRAY_SIZE(supported));
+    if (supported[feat] == F_UNKN) {
+        supported[feat] = arm_hw_accel_cpu_feature_supported(feat, can_emulate);
+    }
+    return supported[feat] == F_SUPP;
+#elif defined(CONFIG_TCG)
+    return can_emulate;
+#else
+#error
+#endif
+}
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 07d9271aa4d..37718c85666 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -11,7 +11,7 @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
 arm_system_ss = ss.source_set()
 arm_common_system_ss = ss.source_set()
 arm_system_ss.add(files(
-  'arm-qmp-cmds.c',
+  'arm-qmp-cmds.c', 'arm_hw_accel.c',
 ))
 arm_system_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'))
 arm_system_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c'))
-- 
2.49.0


Re: [RFC PATCH 06/11] target/arm: Introduce host_cpu_feature_supported()
Posted by Richard Henderson 3 months ago
On 8/12/25 03:06, Philippe Mathieu-Daudé wrote:
> +bool host_cpu_feature_supported(enum arm_features feat, bool can_emulate)
> +{
> +#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
> +    static enum { F_UNKN, F_SUPP, F_UNSUPP } supported[64] = { };
> +
> +    assert(feat < ARRAY_SIZE(supported));
> +    if (supported[feat] == F_UNKN) {
> +        supported[feat] = arm_hw_accel_cpu_feature_supported(feat, can_emulate);
> +    }
> +    return supported[feat] == F_SUPP;
> +#elif defined(CONFIG_TCG)
> +    return can_emulate;
> +#else
> +#error
> +#endif
> +}

How much startup time is saved by this cache?
This feels like premature optimization.

r~

Re: [RFC PATCH 06/11] target/arm: Introduce host_cpu_feature_supported()
Posted by Philippe Mathieu-Daudé 3 months ago
On 12/8/25 02:44, Richard Henderson wrote:
> On 8/12/25 03:06, Philippe Mathieu-Daudé wrote:
>> +bool host_cpu_feature_supported(enum arm_features feat, bool 
>> can_emulate)
>> +{
>> +#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
>> +    static enum { F_UNKN, F_SUPP, F_UNSUPP } supported[64] = { };
>> +
>> +    assert(feat < ARRAY_SIZE(supported));
>> +    if (supported[feat] == F_UNKN) {
>> +        supported[feat] = arm_hw_accel_cpu_feature_supported(feat, 
>> can_emulate);
>> +    }
>> +    return supported[feat] == F_SUPP;
>> +#elif defined(CONFIG_TCG)
>> +    return can_emulate;
>> +#else
>> +#error
>> +#endif
>> +}
> 
> How much startup time is saved by this cache?
> This feels like premature optimization.

It is called for each PSCI call here:

https://lore.kernel.org/qemu-devel/20250808070137.48716-6-mohamed@unpredictable.fr/

+static int hvf_psci_get_target_el(void)
+{
+    if (hvf_arm_el2_enabled()) {
+        return 2;
+    }
+    return 1;
+}

But as you mentioned in patch #9 "by the time we get [here] we have
already detected the host cpu features and have updated env to match",
so checking with:

   arm_feature(env, ARM_FEATURE_EL2)

should be sufficient.