@@ -7208,26 +7208,19 @@ static void x86_cpu_hyperv_realize(X86CPU *cpu)
cpu->hyperv_limits[2] = 0;
}
-static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+/*
+ * note: the call to the framework needs to happen after feature expansion,
+ * but before the checks/modifications to ucode_rev, mwait, phys_bits.
+ * These may be set by the accel-specific code,
+ * and the results are subsequently checked / assumed in x86_cpu_realizefn().
+ */
+static bool x86_cpu_verify_accel_features(CPUState *cs, Error **errp)
{
- CPUState *cs = CPU(dev);
- X86CPU *cpu = X86_CPU(dev);
- X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
+ X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
Error *local_err = NULL;
- static bool ht_warned;
unsigned requested_lbr_fmt;
- /* Use pc-relative instructions in system-mode */
-#ifndef CONFIG_USER_ONLY
- cs->tcg_cflags |= CF_PCREL;
-#endif
-
- if (cpu->apic_id == UNASSIGNED_APIC_ID) {
- error_setg(errp, "apic-id property was not initialized properly");
- return;
- }
-
/*
* Process Hyper-V enlightenments.
* Note: this currently has to happen before the expansion of CPU features.
@@ -7236,7 +7229,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
x86_cpu_expand_features(cpu, &local_err);
if (local_err) {
- goto out;
+ return false;
}
/*
@@ -7246,7 +7239,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
if ((cpu->lbr_fmt & PERF_CAP_LBR_FMT) != cpu->lbr_fmt) {
error_setg(errp, "invalid lbr-fmt");
- return;
+ return false;
}
env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
@@ -7265,13 +7258,13 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
if (!cpu->enable_pmu) {
error_setg(errp, "vPMU: LBR is unsupported without pmu=on");
- return;
+ return false;
}
if (requested_lbr_fmt != host_lbr_fmt) {
error_setg(errp, "vPMU: the lbr-fmt value (0x%x) does not match "
"the host value (0x%x).",
requested_lbr_fmt, host_lbr_fmt);
- return;
+ return false;
}
}
@@ -7282,7 +7275,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
accel_uses_host_cpuid() ?
"Host doesn't support requested features" :
"TCG doesn't support requested features");
- goto out;
+ return false;
}
/* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
@@ -7296,12 +7289,28 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
x86_cpu_set_sgxlepubkeyhash(env);
- /*
- * note: the call to the framework needs to happen after feature expansion,
- * but before the checks/modifications to ucode_rev, mwait, phys_bits.
- * These may be set by the accel-specific code,
- * and the results are subsequently checked / assumed in this function.
- */
+ return true;
+}
+
+static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+ CPUState *cs = CPU(dev);
+ X86CPU *cpu = X86_CPU(dev);
+ X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
+ CPUX86State *env = &cpu->env;
+ Error *local_err = NULL;
+ static bool ht_warned;
+
+ /* Use pc-relative instructions in system-mode */
+#ifndef CONFIG_USER_ONLY
+ cs->tcg_cflags |= CF_PCREL;
+#endif
+
+ if (cpu->apic_id == UNASSIGNED_APIC_ID) {
+ error_setg(errp, "apic-id property was not initialized properly");
+ return;
+ }
+
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -7950,6 +7959,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->class_by_name = x86_cpu_class_by_name;
cc->parse_features = x86_cpu_parse_featurestr;
+ cc->verify_accel_features = x86_cpu_verify_accel_features;
cc->has_work = x86_cpu_has_work;
cc->dump_state = x86_cpu_dump_state;
cc->set_pc = x86_cpu_set_pc;
When looking at the x86_cpu_realizefn() method, most of the code run before the cpu_exec_realizefn() call checks whether the requested CPU features are compatible with the requested accelerator. Extract this code to a dedicated handler matching our recently added CPUClass::verify_accel_features() handler. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- target/i386/cpu.c | 62 +++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 26 deletions(-)