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
This commit is contained in:
commit
398973fe1f
4
cpus.c
4
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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-"
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
|
@ -1870,11 +1883,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|||
/* XXX: The physical address space is limited to 42 bits in exec.c. */
|
||||
*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;
|
||||
*edx = 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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue