Introduce arm_hw_accel_cpu_feature_supported() helper,
an accelerator implementation to return whether a ARM
feature is supported by host hardware. Allow optional
fallback on emulation.

Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org>
---
 target/arm/cpu.h     | 12 ++++++++++++
 target/arm/hvf/hvf.c | 20 ++++++++++++++++++++
 target/arm/kvm.c     | 22 ++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index dc9b6dce4c9..5136c4caabf 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2507,6 +2507,18 @@ static inline ARMSecuritySpace arm_secure_to_space(bool 
secure)
 }
 
 #if !defined(CONFIG_USER_ONLY)
+
+/**
+ * arm_hw_accel_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 arm_hw_accel_cpu_feature_supported(enum arm_features feat,
+                                        bool can_emulate);
+
 /**
  * arm_security_space_below_el3:
  * @env: cpu context
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 81dc4df686d..5174973991f 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -964,6 +964,26 @@ uint32_t hvf_arm_get_max_ipa_bit_size(void)
     return round_down_to_parange_bit_size(max_ipa_size);
 }
 
+bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool 
can_emulate)
+{
+    if (!hvf_enabled()) {
+        return false;
+    }
+    switch (feat) {
+    case ARM_FEATURE_V8:
+    case ARM_FEATURE_NEON:
+    case ARM_FEATURE_AARCH64:
+    case ARM_FEATURE_PMU:
+    case ARM_FEATURE_GENERIC_TIMER:
+        return true;
+    case ARM_FEATURE_EL2:
+    case ARM_FEATURE_EL3:
+        return false;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
 {
     if (!arm_host_cpu_features.dtb_compatible) {
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 66723448554..82853e68d8d 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1771,6 +1771,28 @@ void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error 
**errp)
     }
 }
 
+bool arm_hw_accel_cpu_feature_supported(enum arm_features feat, bool 
can_emulate)
+{
+    if (!kvm_enabled()) {
+        return false;
+    }
+    switch (feat) {
+    case ARM_FEATURE_V8:
+    case ARM_FEATURE_NEON:
+    case ARM_FEATURE_AARCH64:
+    case ARM_FEATURE_GENERIC_TIMER:
+        return true;
+    case ARM_FEATURE_PMU:
+        return kvm_arm_pmu_supported();
+    case ARM_FEATURE_EL2:
+        return kvm_arm_el2_supported();
+    case ARM_FEATURE_EL3:
+        return false;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 bool kvm_arm_aarch32_supported(void)
 {
     return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
-- 
2.49.0


Reply via email to