aboutsummaryrefslogtreecommitdiff
path: root/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm')
-rw-r--r--target/arm/cpu.c3
-rw-r--r--target/arm/cpu.h2
-rw-r--r--target/arm/cpu64.c33
-rw-r--r--target/arm/kvm64.c14
4 files changed, 35 insertions, 17 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 17d1f2b..7a4ac93 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2670,6 +2670,9 @@ static void arm_host_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
kvm_arm_set_cpu_features_from_host(cpu);
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
+ aarch64_add_sve_properties(obj);
+ }
arm_cpu_post_init(obj);
}
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index a044d60..e1a66a2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -977,11 +977,13 @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64);
+void aarch64_add_sve_properties(Object *obj);
#else
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
static inline void aarch64_sve_change_el(CPUARMState *env, int o,
int n, bool a)
{ }
+static inline void aarch64_add_sve_properties(Object *obj) { }
#endif
#if !defined(CONFIG_TCG)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index c161a14..68baf04 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -594,6 +594,21 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
cpu->isar.id_aa64pfr0 = t;
}
+void aarch64_add_sve_properties(Object *obj)
+{
+ uint32_t vq;
+
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
+
+ for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
+ char name[8];
+ sprintf(name, "sve%d", vq * 128);
+ object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
+ cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
+ }
+}
+
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
* otherwise, a CPU with as many features enabled as our emulation supports.
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
@@ -602,17 +617,11 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
static void aarch64_max_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
- uint32_t vq;
- uint64_t t;
if (kvm_enabled()) {
kvm_arm_set_cpu_features_from_host(cpu);
- if (kvm_arm_sve_supported(CPU(cpu))) {
- t = cpu->isar.id_aa64pfr0;
- t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
- cpu->isar.id_aa64pfr0 = t;
- }
} else {
+ uint64_t t;
uint32_t u;
aarch64_a57_initfn(obj);
@@ -712,17 +721,9 @@ static void aarch64_max_initfn(Object *obj)
#endif
}
- object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
+ aarch64_add_sve_properties(obj);
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
-
- for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
- char name[8];
- sprintf(name, "sve%d", vq * 128);
- object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
- cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
- }
}
struct ARMCPUInfo {
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index c93bbee..876184b 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -488,7 +488,9 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* and then query that CPU for the relevant ID registers.
*/
int fdarray[3];
+ bool sve_supported;
uint64_t features = 0;
+ uint64_t t;
int err;
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
@@ -578,13 +580,23 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ARM64_SYS_REG(3, 0, 0, 3, 2));
}
+ sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
+
kvm_arm_destroy_scratch_host_vcpu(fdarray);
if (err < 0) {
return false;
}
- /* We can assume any KVM supporting CPU is at least a v8
+ /* Add feature bits that can't appear until after VCPU init. */
+ if (sve_supported) {
+ t = ahcf->isar.id_aa64pfr0;
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
+ ahcf->isar.id_aa64pfr0 = t;
+ }
+
+ /*
+ * We can assume any KVM supporting CPU is at least a v8
* with VFPv4+Neon; this in turn implies most of the other
* feature bits.
*/