summaryrefslogtreecommitdiffstats
path: root/target-i386
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/cpu-qom.h1
-rw-r--r--target-i386/cpu.c17
-rw-r--r--target-i386/cpu.h1
-rw-r--r--target-i386/kvm.c13
-rw-r--r--target-i386/kvm_i386.h1
5 files changed, 28 insertions, 5 deletions
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e724004a78..7c9a07ae65 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -68,6 +68,7 @@ typedef struct X86CPUClass {
const char *model_description;
DeviceRealize parent_realize;
+ DeviceUnrealize parent_unrealize;
void (*parent_reset)(CPUState *cpu);
} X86CPUClass;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d95514c7dd..83998a85c1 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2945,7 +2945,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
OBJECT(cpu->apic_state), &error_abort);
object_unref(OBJECT(cpu->apic_state));
- qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
+ qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
/* TODO: convert to link<> */
apic = APIC_COMMON(cpu->apic_state);
apic->cpu = cpu;
@@ -3271,7 +3271,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
cpu->phys_bits = 32;
}
}
- cpu_exec_init(cs, &error_abort);
+ cpu_exec_realizefn(cs, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
+ }
if (tcg_enabled()) {
tcg_x86_init();
@@ -3352,6 +3356,8 @@ out:
static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
{
X86CPU *cpu = X86_CPU(dev);
+ X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
+ Error *local_err = NULL;
#ifndef CONFIG_USER_ONLY
cpu_remove_sync(CPU(dev));
@@ -3362,6 +3368,12 @@ static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
object_unparent(OBJECT(cpu->apic_state));
cpu->apic_state = NULL;
}
+
+ xcc->parent_unrealize(dev, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
+ }
}
typedef struct BitProperty {
@@ -3636,6 +3648,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
xcc->parent_realize = dc->realize;
+ xcc->parent_unrealize = dc->unrealize;
dc->realize = x86_cpu_realizefn;
dc->unrealize = x86_cpu_unrealizefn;
dc->props = x86_cpu_properties;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index e64569854f..6303d6593d 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -325,6 +325,7 @@
#define MSR_IA32_APICBASE 0x1b
#define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11)
+#define MSR_IA32_APICBASE_EXTD (1 << 10)
#define MSR_IA32_APICBASE_BASE (0xfffffU<<12)
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define MSR_TSC_ADJUST 0x0000003b
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0472f45fd0..86b41a9c21 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -129,9 +129,8 @@ static bool kvm_x2apic_api_set_flags(uint64_t flags)
return !kvm_vm_enable_cap(s, KVM_CAP_X2APIC_API, 0, flags);
}
-#define MEMORIZE(fn) \
+#define MEMORIZE(fn, _result) \
({ \
- static typeof(fn) _result; \
static bool _memorized; \
\
if (_memorized) { \
@@ -141,11 +140,19 @@ static bool kvm_x2apic_api_set_flags(uint64_t flags)
_result = fn; \
})
+static bool has_x2apic_api;
+
+bool kvm_has_x2apic_api(void)
+{
+ return has_x2apic_api;
+}
+
bool kvm_enable_x2apic(void)
{
return MEMORIZE(
kvm_x2apic_api_set_flags(KVM_X2APIC_API_USE_32BIT_IDS |
- KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK));
+ KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK),
+ has_x2apic_api);
}
static int kvm_get_tsc(CPUState *cs)
diff --git a/target-i386/kvm_i386.h b/target-i386/kvm_i386.h
index 5c369b1c5b..76079295b2 100644
--- a/target-i386/kvm_i386.h
+++ b/target-i386/kvm_i386.h
@@ -44,4 +44,5 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id);
void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
bool kvm_enable_x2apic(void);
+bool kvm_has_x2apic_api(void);
#endif