Introduce host_cpu_feature_supported() helper, returning
whether a ARM feature is supported by host hardware.

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

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 1b3d0244fd6..1742dd88443 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1612,6 +1612,14 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t 
address,
 
 void arm_log_exception(CPUState *cs);
 
+/**
+ * host_cpu_feature_supported:
+ * @feature: Feature to test for support
+ *
+ * Returns: whether @feature is supported by hardware accelerator or emulator
+ */
+bool host_cpu_feature_supported(enum arm_features feature);
+
 #endif /* !CONFIG_USER_ONLY */
 
 /*
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 48e86e62945..05fbd8f7fc9 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -547,6 +547,26 @@ static struct hvf_sreg_match hvf_sreg_match[] = {
     { HV_SYS_REG_SP_EL1, HVF_SYSREG(4, 1, 3, 4, 0) },
 };
 
+bool host_cpu_feature_supported(enum arm_features feature)
+{
+    if (!hvf_enabled()) {
+        return false;
+    }
+    switch (feature) {
+    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();
+    }
+}
+
 int hvf_get_registers(CPUState *cpu)
 {
     ARMCPU *arm_cpu = ARM_CPU(cpu);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 66723448554..93da9d67806 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 host_cpu_feature_supported(enum arm_features feature)
+{
+    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