aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2013-04-16 10:28:36 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2013-04-16 10:28:36 -0500
commit398973fe1f92e65f39f6a26dacc07baa0da632fc (patch)
tree5322bc672479a04956717b7502b8a72409e8647d
parent095b9c4860b1351e4a0322e43708f39c79c1f34b (diff)
parentb21bfeead284cf212d88dfa25171fee122407bc2 (diff)
Merge remote-tracking branch 'afaerber/qom-cpu' into staging
# By Igor Mammedov (8) and others # Via Andreas Färber * afaerber/qom-cpu: target-cris: Override do_interrupt for pre-v32 CPU cores qdev: Set device's parent before calling realize() down inheritance chain cpu: Pass CPUState to *cpu_synchronize_post*() target-i386: Split out CPU creation and features parsing target-i386/cpu.c: Coding style fixes ioapic: Replace FROM_SYSBUS() with QOM type cast kvmvapic: Replace FROM_SYSBUS() with QOM type cast target-i386: Split APIC creation from initialization in x86_cpu_realizefn() target-i386: Consolidate error propagation in x86_cpu_realizefn() qdev: Add qdev property for bool type target-i386: Improve -cpu ? features output target-i386: Fix including "host" in -cpu ? output
-rw-r--r--cpus.c4
-rw-r--r--hw/core/qdev-properties.c33
-rw-r--r--hw/core/qdev.c8
-rw-r--r--hw/i386/kvmvapic.c7
-rw-r--r--hw/intc/ioapic_common.c2
-rw-r--r--include/hw/qdev-properties.h10
-rw-r--r--include/sysemu/kvm.h12
-rw-r--r--kvm-all.c8
-rw-r--r--kvm-stub.c4
-rw-r--r--target-cris/cpu-qom.h1
-rw-r--r--target-cris/cpu.c8
-rw-r--r--target-cris/helper.c14
-rw-r--r--target-i386/cpu.c89
-rw-r--r--target-i386/cpu.h1
14 files changed, 145 insertions, 56 deletions
diff --git a/cpus.c b/cpus.c
index 97e9ab4c07..c15ff6c5fe 100644
--- a/cpus.c
+++ b/cpus.c
@@ -419,7 +419,7 @@ void cpu_synchronize_all_post_reset(void)
CPUArchState *cpu;
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
- cpu_synchronize_post_reset(cpu);
+ cpu_synchronize_post_reset(ENV_GET_CPU(cpu));
}
}
@@ -428,7 +428,7 @@ void cpu_synchronize_all_post_init(void)
CPUArchState *cpu;
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
- cpu_synchronize_post_init(cpu);
+ cpu_synchronize_post_init(ENV_GET_CPU(cpu));
}
}
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index ddde18e6b4..ca1739ec84 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -120,6 +120,39 @@ PropertyInfo qdev_prop_bit = {
.set = set_bit,
};
+/* --- bool --- */
+
+static void get_bool(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ bool *ptr = qdev_get_prop_ptr(dev, prop);
+
+ visit_type_bool(v, ptr, name, errp);
+}
+
+static void set_bool(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ bool *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_bool(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_bool = {
+ .name = "boolean",
+ .get = get_bool,
+ .set = set_bool,
+};
+
/* --- 8bit integer --- */
static void get_uint8(Object *obj, Visitor *v, void *opaque,
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index bab4ed7bf7..4eb01345df 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -684,10 +684,6 @@ static void device_set_realized(Object *obj, bool value, Error **err)
Error *local_err = NULL;
if (value && !dev->realized) {
- if (dc->realize) {
- dc->realize(dev, &local_err);
- }
-
if (!obj->parent && local_err == NULL) {
static int unattached_count;
gchar *name = g_strdup_printf("device[%d]", unattached_count++);
@@ -698,6 +694,10 @@ static void device_set_realized(Object *obj, bool value, Error **err)
g_free(name);
}
+ if (dc->realize) {
+ dc->realize(dev, &local_err);
+ }
+
if (qdev_get_vmsd(dev) && local_err == NULL) {
vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
dev->instance_id_alias,
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index ed9b448d07..3a10c0710c 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -60,6 +60,9 @@ typedef struct VAPICROMState {
bool rom_mapped_writable;
} VAPICROMState;
+#define TYPE_VAPIC "kvmvapic"
+#define VAPIC(obj) OBJECT_CHECK(VAPICROMState, (obj), TYPE_VAPIC)
+
#define TPR_INSTR_ABS_MODRM 0x1
#define TPR_INSTR_MATCH_MODRM_REG 0x2
@@ -690,7 +693,7 @@ static const MemoryRegionOps vapic_ops = {
static int vapic_init(SysBusDevice *dev)
{
- VAPICROMState *s = FROM_SYSBUS(VAPICROMState, dev);
+ VAPICROMState *s = VAPIC(dev);
memory_region_init_io(&s->io, &vapic_ops, s, "kvmvapic", 2);
sysbus_add_io(dev, VAPIC_IO_PORT, &s->io);
@@ -806,7 +809,7 @@ static void vapic_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo vapic_type = {
- .name = "kvmvapic",
+ .name = TYPE_VAPIC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(VAPICROMState),
.class_init = vapic_class_init,
diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
index 42c7adc691..5c5bb3caaa 100644
--- a/hw/intc/ioapic_common.c
+++ b/hw/intc/ioapic_common.c
@@ -59,7 +59,7 @@ static int ioapic_dispatch_post_load(void *opaque, int version_id)
static int ioapic_init_common(SysBusDevice *dev)
{
- IOAPICCommonState *s = FROM_SYSBUS(IOAPICCommonState, dev);
+ IOAPICCommonState *s = IOAPIC_COMMON(dev);
IOAPICCommonClass *info;
static int ioapic_no;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index a37933998a..25dd1bb39a 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -6,6 +6,7 @@
/*** qdev-properties.c ***/
extern PropertyInfo qdev_prop_bit;
+extern PropertyInfo qdev_prop_bool;
extern PropertyInfo qdev_prop_uint8;
extern PropertyInfo qdev_prop_uint16;
extern PropertyInfo qdev_prop_uint32;
@@ -52,6 +53,15 @@ extern PropertyInfo qdev_prop_arraylen;
.defval = (bool)_defval, \
}
+#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) { \
+ .name = (_name), \
+ .info = &(qdev_prop_bool), \
+ .offset = offsetof(_state, _field) \
+ + type_check(bool, typeof_field(_state, _field)), \
+ .qtype = QTYPE_QBOOL, \
+ .defval = (bool)_defval, \
+ }
+
#define PROP_ARRAY_LEN_PREFIX "len-"
/**
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index f2d97b580d..495e6f8dbd 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -250,8 +250,8 @@ int kvm_check_extension(KVMState *s, unsigned int extension);
uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
uint32_t index, int reg);
void kvm_cpu_synchronize_state(CPUArchState *env);
-void kvm_cpu_synchronize_post_reset(CPUArchState *env);
-void kvm_cpu_synchronize_post_init(CPUArchState *env);
+void kvm_cpu_synchronize_post_reset(CPUState *cpu);
+void kvm_cpu_synchronize_post_init(CPUState *cpu);
/* generic hooks - to be moved/refactored once there are more users */
@@ -262,17 +262,17 @@ static inline void cpu_synchronize_state(CPUArchState *env)
}
}
-static inline void cpu_synchronize_post_reset(CPUArchState *env)
+static inline void cpu_synchronize_post_reset(CPUState *cpu)
{
if (kvm_enabled()) {
- kvm_cpu_synchronize_post_reset(env);
+ kvm_cpu_synchronize_post_reset(cpu);
}
}
-static inline void cpu_synchronize_post_init(CPUArchState *env)
+static inline void cpu_synchronize_post_init(CPUState *cpu)
{
if (kvm_enabled()) {
- kvm_cpu_synchronize_post_init(env);
+ kvm_cpu_synchronize_post_init(cpu);
}
}
diff --git a/kvm-all.c b/kvm-all.c
index 9b433d3163..fc4e17c8bb 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1510,18 +1510,14 @@ void kvm_cpu_synchronize_state(CPUArchState *env)
}
}
-void kvm_cpu_synchronize_post_reset(CPUArchState *env)
+void kvm_cpu_synchronize_post_reset(CPUState *cpu)
{
- CPUState *cpu = ENV_GET_CPU(env);
-
kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
cpu->kvm_vcpu_dirty = false;
}
-void kvm_cpu_synchronize_post_init(CPUArchState *env)
+void kvm_cpu_synchronize_post_init(CPUState *cpu)
{
- CPUState *cpu = ENV_GET_CPU(env);
-
kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
cpu->kvm_vcpu_dirty = false;
}
diff --git a/kvm-stub.c b/kvm-stub.c
index f6137d343a..723a813735 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -41,11 +41,11 @@ void kvm_cpu_synchronize_state(CPUArchState *env)
{
}
-void kvm_cpu_synchronize_post_reset(CPUArchState *env)
+void kvm_cpu_synchronize_post_reset(CPUState *cpu)
{
}
-void kvm_cpu_synchronize_post_init(CPUArchState *env)
+void kvm_cpu_synchronize_post_init(CPUState *cpu)
{
}
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index deea1d804b..03829bd243 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -74,5 +74,6 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
#define ENV_OFFSET offsetof(CRISCPU, env)
void cris_cpu_do_interrupt(CPUState *cpu);
+void crisv10_cpu_do_interrupt(CPUState *cpu);
#endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 95cbf399d9..67181e55a6 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -169,30 +169,38 @@ static void cris_cpu_initfn(Object *obj)
static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
{
+ CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 8;
+ cc->do_interrupt = crisv10_cpu_do_interrupt;
}
static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
{
+ CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 9;
+ cc->do_interrupt = crisv10_cpu_do_interrupt;
}
static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
{
+ CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 10;
+ cc->do_interrupt = crisv10_cpu_do_interrupt;
}
static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
{
+ CPUClass *cc = CPU_CLASS(oc);
CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
ccc->vr = 11;
+ cc->do_interrupt = crisv10_cpu_do_interrupt;
}
static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
diff --git a/target-cris/helper.c b/target-cris/helper.c
index e1ef7bcc0b..466cc2f9d5 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -45,6 +45,11 @@ void cris_cpu_do_interrupt(CPUState *cs)
env->pregs[PR_ERP] = env->pc;
}
+void crisv10_cpu_do_interrupt(CPUState *cs)
+{
+ cris_cpu_do_interrupt(cs);
+}
+
int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
int mmu_idx)
{
@@ -109,9 +114,10 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
return r;
}
-static void do_interruptv10(CPUCRISState *env)
+void crisv10_cpu_do_interrupt(CPUState *cs)
{
- D(CPUState *cs = CPU(cris_env_get_cpu(env)));
+ CRISCPU *cpu = CRIS_CPU(cs);
+ CPUCRISState *env = &cpu->env;
int ex_vec = -1;
D_LOG("exception index=%d interrupt_req=%d\n",
@@ -171,10 +177,6 @@ void cris_cpu_do_interrupt(CPUState *cs)
CPUCRISState *env = &cpu->env;
int ex_vec = -1;
- if (env->pregs[PR_VR] < 32) {
- return do_interruptv10(env);
- }
-
D_LOG("exception index=%d interrupt_req=%d\n",
env->exception_index,
cs->interrupt_request);
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6dd993f847..e2302d8b05 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1463,18 +1463,19 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
snprintf(buf, sizeof(buf), "%s", def->name);
(*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
}
- if (kvm_enabled()) {
- (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
- }
+#ifdef CONFIG_KVM
+ (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
+ "KVM processor with all supported host features "
+ "(only available in KVM mode)");
+#endif
+
(*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
- listflags(buf, sizeof(buf), (uint32_t)~0, feature_name, 1);
- (*cpu_fprintf)(f, " %s\n", buf);
- listflags(buf, sizeof(buf), (uint32_t)~0, ext_feature_name, 1);
- (*cpu_fprintf)(f, " %s\n", buf);
- listflags(buf, sizeof(buf), (uint32_t)~0, ext2_feature_name, 1);
- (*cpu_fprintf)(f, " %s\n", buf);
- listflags(buf, sizeof(buf), (uint32_t)~0, ext3_feature_name, 1);
- (*cpu_fprintf)(f, " %s\n", buf);
+ for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
+ FeatureWordInfo *fw = &feature_word_info[i];
+
+ listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
+ (*cpu_fprintf)(f, " %s\n", buf);
+ }
}
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
@@ -1562,7 +1563,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
}
-X86CPU *cpu_x86_init(const char *cpu_model)
+X86CPU *cpu_x86_create(const char *cpu_model, Error **errp)
{
X86CPU *cpu = NULL;
CPUX86State *env;
@@ -1592,13 +1593,25 @@ X86CPU *cpu_x86_init(const char *cpu_model)
goto out;
}
- object_property_set_bool(OBJECT(cpu), true, "realized", &error);
+out:
+ error_propagate(errp, error);
+ g_strfreev(model_pieces);
+ return cpu;
+}
+
+X86CPU *cpu_x86_init(const char *cpu_model)
+{
+ Error *error = NULL;
+ X86CPU *cpu;
+
+ cpu = cpu_x86_create(cpu_model, &error);
if (error) {
goto out;
}
+ object_property_set_bool(OBJECT(cpu), true, "realized", &error);
+
out:
- g_strfreev(model_pieces);
if (error) {
fprintf(stderr, "%s\n", error_get_pretty(error));
error_free(error);
@@ -1868,12 +1881,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
/* 64 bit processor */
/* XXX: The physical address space is limited to 42 bits in exec.c. */
- *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
+ *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
} else {
- if (env->cpuid_features & CPUID_PSE36)
+ if (env->cpuid_features & CPUID_PSE36) {
*eax = 0x00000024; /* 36 bits physical */
- else
+ } else {
*eax = 0x00000020; /* 32 bits physical */
+ }
}
*ebx = 0;
*ecx = 0;
@@ -2049,9 +2063,8 @@ static void mce_init(X86CPU *cpu)
}
#ifndef CONFIG_USER_ONLY
-static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
+static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
{
- static int apic_mapped;
CPUX86State *env = &cpu->env;
APICCommonState *apic;
const char *apic_type = "apic";
@@ -2074,6 +2087,16 @@ static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
/* TODO: convert to link<> */
apic = APIC_COMMON(env->apic_state);
apic->cpu = cpu;
+}
+
+static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
+{
+ CPUX86State *env = &cpu->env;
+ static int apic_mapped;
+
+ if (env->apic_state == NULL) {
+ return;
+ }
if (qdev_init(env->apic_state)) {
error_setg(errp, "APIC device '%s' could not be initialized",
@@ -2091,6 +2114,10 @@ static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
apic_mapped = 1;
}
}
+#else
+static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
+{
+}
#endif
static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
@@ -2098,9 +2125,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
X86CPU *cpu = X86_CPU(dev);
X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
CPUX86State *env = &cpu->env;
-#ifndef CONFIG_USER_ONLY
Error *local_err = NULL;
-#endif
if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) {
env->cpuid_level = 7;
@@ -2130,8 +2155,9 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
} else {
if (check_cpuid && kvm_check_features_against_host(cpu)
&& enforce_cpuid) {
- error_setg(errp, "Host's CPU doesn't support requested features");
- return;
+ error_setg(&local_err,
+ "Host's CPU doesn't support requested features");
+ goto out;
}
#ifdef CONFIG_KVM
filter_features_for_kvm(cpu);
@@ -2142,19 +2168,28 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) {
- x86_cpu_apic_init(cpu, &local_err);
+ x86_cpu_apic_create(cpu, &local_err);
if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
+ goto out;
}
}
#endif
mce_init(cpu);
qemu_init_vcpu(&cpu->env);
+
+ x86_cpu_apic_realize(cpu, &local_err);
+ if (local_err != NULL) {
+ goto out;
+ }
cpu_reset(CPU(cpu));
- xcc->parent_realize(dev, errp);
+ xcc->parent_realize(dev, &local_err);
+out:
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
+ }
}
/* Enables contiguous-apic-ID mode, for compatibility */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 2b4e3193f3..cf1b05c28c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -896,6 +896,7 @@ typedef struct CPUX86State {
#include "cpu-qom.h"
X86CPU *cpu_x86_init(const char *cpu_model);
+X86CPU *cpu_x86_create(const char *cpu_model, Error **errp);
int cpu_x86_exec(CPUX86State *s);
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
void x86_cpudef_setup(void);