summaryrefslogtreecommitdiff
path: root/target-i386/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386/cpu.c')
-rw-r--r--target-i386/cpu.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index cd350cb8e4..42c5de034e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -35,8 +35,6 @@
#include "qapi/visitor.h"
#include "sysemu/arch_init.h"
-#include "hyperv.h"
-
#include "hw/hw.h"
#if defined(CONFIG_KVM)
#include <linux/kvm_para.h>
@@ -1475,9 +1473,11 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, err);
}
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
+static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_def,
+ const char *name)
{
x86_def_t *def;
+ Error *err = NULL;
int i;
if (name == NULL) {
@@ -1485,6 +1485,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
}
if (kvm_enabled() && strcmp(name, "host") == 0) {
kvm_cpu_fill_host(x86_cpu_def);
+ object_property_set_bool(OBJECT(cpu), true, "pmu", &err);
+ assert_no_error(err);
return 0;
}
@@ -1587,12 +1589,19 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
} else if (!strcmp(featurestr, "hv-spinlocks")) {
char *err;
+ const int min = 0xFFF;
numvalue = strtoul(val, &err, 0);
if (!*val || *err) {
error_setg(errp, "bad numerical value %s", val);
goto out;
}
- hyperv_set_spinlock_retries(numvalue);
+ if (numvalue < min) {
+ fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
+ ", fixup will be removed in future versions\n",
+ min);
+ numvalue = min;
+ }
+ cpu->hyperv_spinlock_attempts = numvalue;
} else {
error_setg(errp, "unrecognized feature %s", featurestr);
goto out;
@@ -1602,9 +1611,9 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
} else if (!strcmp(featurestr, "enforce")) {
check_cpuid = enforce_cpuid = 1;
} else if (!strcmp(featurestr, "hv_relaxed")) {
- hyperv_enable_relaxed_timing(true);
+ cpu->hyperv_relaxed_timing = true;
} else if (!strcmp(featurestr, "hv_vapic")) {
- hyperv_enable_vapic_recommended(true);
+ cpu->hyperv_vapic = true;
} else {
error_setg(errp, "feature string `%s' not in format (+feature|"
"-feature|feature=xyz)", featurestr);
@@ -1742,7 +1751,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
memset(def, 0, sizeof(*def));
- if (cpu_x86_find_by_name(def, name) < 0) {
+ if (cpu_x86_find_by_name(cpu, def, name) < 0) {
error_setg(errp, "Unable to find CPU definition: %s", name);
return;
}
@@ -1820,7 +1829,11 @@ X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
}
out:
- error_propagate(errp, error);
+ if (error != NULL) {
+ error_propagate(errp, error);
+ object_unref(OBJECT(cpu));
+ cpu = NULL;
+ }
g_strfreev(model_pieces);
return cpu;
}
@@ -1839,7 +1852,7 @@ X86CPU *cpu_x86_init(const char *cpu_model)
out:
if (error) {
- fprintf(stderr, "%s\n", error_get_pretty(error));
+ error_report("%s", error_get_pretty(error));
error_free(error);
if (cpu != NULL) {
object_unref(OBJECT(cpu));
@@ -2016,7 +2029,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0xA:
/* Architectural Performance Monitoring Leaf */
- if (kvm_enabled()) {
+ if (kvm_enabled() && cpu->enable_pmu) {
KVMState *s = cs->kvm_state;
*eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
@@ -2333,6 +2346,7 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
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;
@@ -2387,12 +2401,13 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
#endif
mce_init(cpu);
+ qemu_init_vcpu(cs);
x86_cpu_apic_realize(cpu, &local_err);
if (local_err != NULL) {
goto out;
}
- cpu_reset(CPU(cpu));
+ cpu_reset(cs);
xcc->parent_realize(dev, &local_err);
out:
@@ -2479,6 +2494,7 @@ static void x86_cpu_initfn(Object *obj)
x86_cpu_get_feature_words,
NULL, NULL, (void *)cpu->filtered_features, NULL);
+ cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
/* init various static tables used in TCG mode */
@@ -2520,6 +2536,11 @@ static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
cpu->env.eip = tb->pc - tb->cs_base;
}
+static Property x86_cpu_properties[] = {
+ DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
+ DEFINE_PROP_END_OF_LIST()
+};
+
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
{
X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -2529,6 +2550,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
xcc->parent_realize = dc->realize;
dc->realize = x86_cpu_realizefn;
dc->bus_type = TYPE_ICC_BUS;
+ dc->props = x86_cpu_properties;
xcc->parent_reset = cc->reset;
cc->reset = x86_cpu_reset;
@@ -2538,6 +2560,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->dump_state = x86_cpu_dump_state;
cc->set_pc = x86_cpu_set_pc;
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
+ cc->gdb_read_register = x86_cpu_gdb_read_register;
+ cc->gdb_write_register = x86_cpu_gdb_write_register;
cc->get_arch_id = x86_cpu_get_arch_id;
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
#ifndef CONFIG_USER_ONLY
@@ -2549,6 +2573,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
cc->vmsd = &vmstate_x86_cpu;
#endif
+ cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
}
static const TypeInfo x86_cpu_type_info = {