aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-03-12 11:47:52 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-03-12 11:47:52 +0000
commit5df089564be6e6a6b1bc79207f74b5b7ed4e1277 (patch)
treeb0bacc6574524443680e0af4f2b27597d3c070de /target
parent12c06d6f967a63515399b9e1f6a40f5ce871a8b7 (diff)
parent076a0fc32a73a9b960e0f73f04a531bc1bd94308 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180309' into staging
target-arm queue: * i.MX: Add i.MX7 SOC implementation and i.MX7 Sabre board * Report the correct core count in A53 L2CTLR on the ZynqMP board * linux-user: preliminary SVE support work (signal handling) * hw/arm/boot: fix memory leak in case of error loading ELF file * hw/arm/boot: avoid reading off end of buffer if passed very small image file * hw/arm: Use more CONFIG switches for the object files * target/arm: Add "-cpu max" support * hw/arm/virt: Support -machine gic-version=max * hw/sd: improve debug tracing * hw/sd: sdcard: Add the Tuning Command (CMD 19) * MAINTAINERS: add Philippe as odd-fixes maintainer for SD # gpg: Signature made Fri 09 Mar 2018 17:24:23 GMT # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180309: (25 commits) MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard) sdhci: Fix a typo in comment sdcard: Add the Tuning Command (CMD19) sdcard: Display which protocol is used when tracing (SD or SPI) sdcard: Display command name when tracing CMD/ACMD sdcard: Do not trace CMD55, except when we already expect an ACMD hw/arm/virt: Support -machine gic-version=max hw/arm/virt: Add "max" to the list of CPU types "virt" supports target/arm: Make 'any' CPU just an alias for 'max' target/arm: Add "-cpu max" support target/arm: Move definition of 'host' cpu type into cpu.c target/arm: Query host CPU features on-demand at instance init arm: avoid heap-buffer-overflow in load_aarch64_image arm: fix load ELF error leak hw/arm: Use more CONFIG switches for the object files aarch64-linux-user: Add support for SVE signal frame records aarch64-linux-user: Add support for EXTRA signal frame records aarch64-linux-user: Remove struct target_aux_context aarch64-linux-user: Split out helpers for guest signal handling linux-user: Implement aarch64 PR_SVE_SET/GET_VL ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu-qom.h2
-rw-r--r--target/arm/cpu.c103
-rw-r--r--target/arm/cpu.h11
-rw-r--r--target/arm/cpu64.c113
-rw-r--r--target/arm/kvm.c51
-rw-r--r--target/arm/kvm32.c8
-rw-r--r--target/arm/kvm64.c8
-rw-r--r--target/arm/kvm_arm.h35
8 files changed, 236 insertions, 95 deletions
diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
index a42495bac9..d135ff8e06 100644
--- a/target/arm/cpu-qom.h
+++ b/target/arm/cpu-qom.h
@@ -33,6 +33,8 @@ struct arm_boot_info;
#define ARM_CPU_GET_CLASS(obj) \
OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
+#define TYPE_ARM_MAX_CPU "max-" TYPE_ARM_CPU
+
/**
* ARMCPUClass:
* @parent_realize: The parent class' realize handler.
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 6b77aaa445..022d8c5787 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -725,6 +725,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
int pagebits;
Error *local_err = NULL;
+ /* If we needed to query the host kernel for the CPU features
+ * then it's possible that might have failed in the initfn, but
+ * this is the first point where we can report it.
+ */
+ if (cpu->host_cpu_probe_failed) {
+ if (!kvm_enabled()) {
+ error_setg(errp, "The 'host' CPU type can only be used with KVM");
+ } else {
+ error_setg(errp, "Failed to retrieve host CPU features");
+ }
+ return;
+ }
+
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -939,6 +952,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cs->num_ases = 1;
}
cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
+
+ /* No core_count specified, default to smp_cpus. */
+ if (cpu->core_count == -1) {
+ cpu->core_count = smp_cpus;
+ }
#endif
qemu_init_vcpu(cs);
@@ -952,9 +970,19 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
ObjectClass *oc;
char *typename;
char **cpuname;
+ const char *cpunamestr;
cpuname = g_strsplit(cpu_model, ",", 1);
- typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
+ cpunamestr = cpuname[0];
+#ifdef CONFIG_USER_ONLY
+ /* For backwards compatibility usermode emulation allows "-cpu any",
+ * which has the same semantics as "-cpu max".
+ */
+ if (!strcmp(cpunamestr, "any")) {
+ cpunamestr = "max";
+ }
+#endif
+ typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpunamestr);
oc = object_class_by_name(typename);
g_strfreev(cpuname);
g_free(typename);
@@ -1684,22 +1712,37 @@ static void pxa270c5_initfn(Object *obj)
cpu->reset_sctlr = 0x00000078;
}
-#ifdef CONFIG_USER_ONLY
-static void arm_any_initfn(Object *obj)
+#ifndef TARGET_AARCH64
+/* -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-aarch64 is defined in cpu64.c;
+ * this only needs to handle 32 bits.
+ */
+static void arm_max_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
- set_feature(&cpu->env, ARM_FEATURE_V8);
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
- set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
- set_feature(&cpu->env, ARM_FEATURE_CRC);
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
- cpu->midr = 0xffffffff;
+
+ if (kvm_enabled()) {
+ kvm_arm_set_cpu_features_from_host(cpu);
+ } else {
+ cortex_a15_initfn(obj);
+#ifdef CONFIG_USER_ONLY
+ /* We don't set these in system emulation mode for the moment,
+ * since we don't correctly set the ID registers to advertise them,
+ */
+ set_feature(&cpu->env, ARM_FEATURE_V8);
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
+#endif
+ }
}
#endif
@@ -1751,8 +1794,11 @@ static const ARMCPUInfo arm_cpus[] = {
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
+#ifndef TARGET_AARCH64
+ { .name = "max", .initfn = arm_max_initfn },
+#endif
#ifdef CONFIG_USER_ONLY
- { .name = "any", .initfn = arm_any_initfn },
+ { .name = "any", .initfn = arm_max_initfn },
#endif
#endif
{ .name = NULL }
@@ -1765,6 +1811,7 @@ static Property arm_cpu_properties[] = {
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
mp_affinity, ARM64_AFFINITY_INVALID),
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
+ DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
DEFINE_PROP_END_OF_LIST()
};
@@ -1845,6 +1892,26 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
#endif
}
+#ifdef CONFIG_KVM
+static void arm_host_initfn(Object *obj)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+
+ kvm_arm_set_cpu_features_from_host(cpu);
+}
+
+static const TypeInfo host_arm_cpu_type_info = {
+ .name = TYPE_ARM_HOST_CPU,
+#ifdef TARGET_AARCH64
+ .parent = TYPE_AARCH64_CPU,
+#else
+ .parent = TYPE_ARM_CPU,
+#endif
+ .instance_init = arm_host_initfn,
+};
+
+#endif
+
static void cpu_register(const ARMCPUInfo *info)
{
TypeInfo type_info = {
@@ -1889,6 +1956,10 @@ static void arm_cpu_register_types(void)
cpu_register(info);
info++;
}
+
+#ifdef CONFIG_KVM
+ type_register_static(&host_arm_cpu_type_info);
+#endif
}
type_init(arm_cpu_register_types)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8dd6b788df..1e7e1f8a7e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -745,6 +745,16 @@ struct ARMCPU {
/* Uniprocessor system with MP extensions */
bool mp_is_up;
+ /* True if we tried kvm_arm_host_cpu_features() during CPU instance_init
+ * and the probe failed (so we need to report the error in realize)
+ */
+ bool host_cpu_probe_failed;
+
+ /* Specify the number of cores in this CPU cluster. Used for the L2CTLR
+ * register.
+ */
+ int32_t core_count;
+
/* The instance init functions for implementation-specific subclasses
* set these fields to specify the implementation-dependent values of
* various constant registers and reset values of non-constant
@@ -861,6 +871,7 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
#ifdef TARGET_AARCH64
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
#endif
target_ulong do_arm_semihosting(CPUARMState *env);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 4228713b19..991d764674 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -28,6 +28,7 @@
#include "hw/arm/arm.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
+#include "kvm_arm.h"
static inline void set_feature(CPUARMState *env, int feature)
{
@@ -42,8 +43,10 @@ static inline void unset_feature(CPUARMState *env, int feature)
#ifndef CONFIG_USER_ONLY
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
- /* Number of processors is in [25:24]; otherwise we RAZ */
- return (smp_cpus - 1) << 24;
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
+ /* Number of cores is in [25:24]; otherwise we RAZ */
+ return (cpu->core_count - 1) << 24;
}
#endif
@@ -212,31 +215,50 @@ static void aarch64_a53_initfn(Object *obj)
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
}
-#ifdef CONFIG_USER_ONLY
-static void aarch64_any_initfn(Object *obj)
+/* -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;
+ * this only needs to handle 64 bits.
+ */
+static void aarch64_max_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
- set_feature(&cpu->env, ARM_FEATURE_V8);
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
- set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
- set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
- set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
- set_feature(&cpu->env, ARM_FEATURE_CRC);
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
- cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
- cpu->dcz_blocksize = 7; /* 512 bytes */
-}
+ if (kvm_enabled()) {
+ kvm_arm_set_cpu_features_from_host(cpu);
+ } else {
+ aarch64_a57_initfn(obj);
+#ifdef CONFIG_USER_ONLY
+ /* We don't set these in system emulation mode for the moment,
+ * since we don't correctly set the ID registers to advertise them,
+ * and in some cases they're only available in AArch64 and not AArch32,
+ * whereas the architecture requires them to be present in both if
+ * present in either.
+ */
+ set_feature(&cpu->env, ARM_FEATURE_V8);
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
+ set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
+ /* For usermode -cpu max we can use a larger and more efficient DCZ
+ * blocksize since we don't have to follow what the hardware does.
+ */
+ cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
+ cpu->dcz_blocksize = 7; /* 512 bytes */
#endif
+ }
+}
typedef struct ARMCPUInfo {
const char *name;
@@ -247,9 +269,7 @@ typedef struct ARMCPUInfo {
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
-#ifdef CONFIG_USER_ONLY
- { .name = "any", .initfn = aarch64_any_initfn },
-#endif
+ { .name = "max", .initfn = aarch64_max_initfn },
{ .name = NULL }
};
@@ -366,3 +386,44 @@ static void aarch64_cpu_register_types(void)
}
type_init(aarch64_cpu_register_types)
+
+/* The manual says that when SVE is enabled and VQ is widened the
+ * implementation is allowed to zero the previously inaccessible
+ * portion of the registers. The corollary to that is that when
+ * SVE is enabled and VQ is narrowed we are also allowed to zero
+ * the now inaccessible portion of the registers.
+ *
+ * The intent of this is that no predicate bit beyond VQ is ever set.
+ * Which means that some operations on predicate registers themselves
+ * may operate on full uint64_t or even unrolled across the maximum
+ * uint64_t[4]. Performing 4 bits of host arithmetic unconditionally
+ * may well be cheaper than conditionals to restrict the operation
+ * to the relevant portion of a uint16_t[16].
+ *
+ * TODO: Need to call this for changes to the real system registers
+ * and EL state changes.
+ */
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
+{
+ int i, j;
+ uint64_t pmask;
+
+ assert(vq >= 1 && vq <= ARM_MAX_VQ);
+
+ /* Zap the high bits of the zregs. */
+ for (i = 0; i < 32; i++) {
+ memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
+ }
+
+ /* Zap the high bits of the pregs and ffr. */
+ pmask = 0;
+ if (vq & 3) {
+ pmask = ~(-1ULL << (16 * (vq & 3)));
+ }
+ for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
+ for (i = 0; i < 17; ++i) {
+ env->vfp.pregs[i].p[j] &= pmask;
+ }
+ pmask = 0;
+ }
+}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 1219d0062b..ecc39ac295 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -33,6 +33,8 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static bool cap_has_mp_state;
+static ARMHostCPUFeatures arm_host_cpu_features;
+
int kvm_arm_vcpu_init(CPUState *cs)
{
ARMCPU *cpu = ARM_CPU(cs);
@@ -129,44 +131,27 @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
}
}
-static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
{
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
+ CPUARMState *env = &cpu->env;
- /* All we really need to set up for the 'host' CPU
- * is the feature bits -- we rely on the fact that the
- * various ID register values in ARMCPU are only used for
- * TCG CPUs.
- */
- if (!kvm_arm_get_host_cpu_features(ahcc)) {
- fprintf(stderr, "Failed to retrieve host CPU features!\n");
- abort();
+ if (!arm_host_cpu_features.dtb_compatible) {
+ if (!kvm_enabled() ||
+ !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
+ /* We can't report this error yet, so flag that we need to
+ * in arm_cpu_realizefn().
+ */
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
+ cpu->host_cpu_probe_failed = true;
+ return;
+ }
}
-}
-static void kvm_arm_host_cpu_initfn(Object *obj)
-{
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
- ARMCPU *cpu = ARM_CPU(obj);
- CPUARMState *env = &cpu->env;
-
- cpu->kvm_target = ahcc->target;
- cpu->dtb_compatible = ahcc->dtb_compatible;
- env->features = ahcc->features;
+ cpu->kvm_target = arm_host_cpu_features.target;
+ cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
+ env->features = arm_host_cpu_features.features;
}
-static const TypeInfo host_arm_cpu_type_info = {
- .name = TYPE_ARM_HOST_CPU,
-#ifdef TARGET_AARCH64
- .parent = TYPE_AARCH64_CPU,
-#else
- .parent = TYPE_ARM_CPU,
-#endif
- .instance_init = kvm_arm_host_cpu_initfn,
- .class_init = kvm_arm_host_cpu_class_init,
- .class_size = sizeof(ARMHostCPUClass),
-};
-
int kvm_arch_init(MachineState *ms, KVMState *s)
{
/* For ARM interrupt delivery is always asynchronous,
@@ -182,8 +167,6 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
- type_register_static(&host_arm_cpu_type_info);
-
return 0;
}
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
index f77c9c494b..1740cda47d 100644
--- a/target/arm/kvm32.c
+++ b/target/arm/kvm32.c
@@ -28,7 +28,7 @@ static inline void set_feature(uint64_t *features, int feature)
*features |= 1ULL << feature;
}
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
* fill out the ARMHostCPUClass fields accordingly. To do this
@@ -74,13 +74,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
return false;
}
- ahcc->target = init.target;
+ ahcf->target = init.target;
/* This is not strictly blessed by the device tree binding docs yet,
* but in practice the kernel does not care about this string so
* there is no point maintaining an KVM_ARM_TARGET_* -> string table.
*/
- ahcc->dtb_compatible = "arm,arm-v7";
+ ahcf->dtb_compatible = "arm,arm-v7";
for (i = 0; i < ARRAY_SIZE(idregs); i++) {
ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
@@ -132,7 +132,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
set_feature(&features, ARM_FEATURE_VFP4);
}
- ahcc->features = features;
+ ahcf->features = features;
return true;
}
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index ac728494a4..e0b8246283 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -443,7 +443,7 @@ static inline void unset_feature(uint64_t *features, int feature)
*features &= ~(1ULL << feature);
}
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
/* Identify the feature bits corresponding to the host CPU, and
* fill out the ARMHostCPUClass fields accordingly. To do this
@@ -471,8 +471,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
return false;
}
- ahcc->target = init.target;
- ahcc->dtb_compatible = "arm,arm-v8";
+ ahcf->target = init.target;
+ ahcf->dtb_compatible = "arm,arm-v8";
kvm_arm_destroy_scratch_host_vcpu(fdarray);
@@ -486,7 +486,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
set_feature(&features, ARM_FEATURE_AARCH64);
set_feature(&features, ARM_FEATURE_PMU);
- ahcc->features = features;
+ ahcf->features = features;
return true;
}
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index cfb7e5af72..1e2364007d 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -152,20 +152,16 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
-#define ARM_HOST_CPU_CLASS(klass) \
- OBJECT_CLASS_CHECK(ARMHostCPUClass, (klass), TYPE_ARM_HOST_CPU)
-#define ARM_HOST_CPU_GET_CLASS(obj) \
- OBJECT_GET_CLASS(ARMHostCPUClass, (obj), TYPE_ARM_HOST_CPU)
-
-typedef struct ARMHostCPUClass {
- /*< private >*/
- ARMCPUClass parent_class;
- /*< public >*/
+/**
+ * ARMHostCPUFeatures: information about the host CPU (identified
+ * by asking the host kernel)
+ */
+typedef struct ARMHostCPUFeatures {
uint64_t features;
uint32_t target;
const char *dtb_compatible;
-} ARMHostCPUClass;
+} ARMHostCPUFeatures;
/**
* kvm_arm_get_host_cpu_features:
@@ -174,8 +170,16 @@ typedef struct ARMHostCPUClass {
* Probe the capabilities of the host kernel's preferred CPU and fill
* in the ARMHostCPUClass struct accordingly.
*/
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc);
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
+/**
+ * kvm_arm_set_cpu_features_from_host:
+ * @cpu: ARMCPU to set the features for
+ *
+ * Set up the ARMCPU struct fields up to match the information probed
+ * from the host CPU.
+ */
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
/**
* kvm_arm_sync_mpstate_to_kvm
@@ -200,6 +204,15 @@ void kvm_arm_pmu_init(CPUState *cs);
#else
+static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
+{
+ /* This should never actually be called in the "not KVM" case,
+ * but set up the fields to indicate an error anyway.
+ */
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
+ cpu->host_cpu_probe_failed = true;
+}
+
static inline int kvm_arm_vgic_probe(void)
{
return 0;