diff options
Diffstat (limited to 'target-i386/cpu.c')
-rw-r--r-- | target-i386/cpu.c | 47 |
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 = { |