diff options
author | Igor Mammedov <imammedo@redhat.com> | 2012-07-23 15:22:27 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-08-01 08:45:06 -0500 |
commit | dd673288a8ff73ad77fcc1c255486d2466a772e1 (patch) | |
tree | 57efd58332d97309c098f7862c44bb947aa73d98 /target-i386 | |
parent | fb5b0c6d5cea2d05a5e4e81390a4b6c4c70c6668 (diff) |
target-i386: move cpu halted decision into x86_cpu_reset
MP initialization protocol differs between cpu families, and for P6 and
onward models it is up to CPU to decide if it will be BSP using this
protocol, so try to model this. However there is no point in implementing
MP initialization protocol in qemu. Thus first CPU is always marked as BSP.
This patch:
- moves decision to designate BSP from board into cpu, making cpu
self-sufficient in this regard. Later it will allow to cleanup hw/pc.c
and remove cpu_reset and wrappers from there.
- stores flag that CPU is BSP in IA32_APIC_BASE to model behavior
described in Inted SDM vol 3a part 1 chapter 8.4.1
- uses MSR_IA32_APICBASE_BSP flag in apic_base for checking if cpu is BSP
patch is based on Jan Kiszka's proposal:
http://thread.gmane.org/gmane.comp.emulators.qemu/100806
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.c | 16 | ||||
-rw-r--r-- | target-i386/helper.c | 1 | ||||
-rw-r--r-- | target-i386/kvm.c | 4 |
3 files changed, 19 insertions, 2 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 6b9659f9e7..365c2ffae9 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1686,8 +1686,24 @@ static void x86_cpu_reset(CPUState *s) env->dr[7] = DR7_FIXED_1; cpu_breakpoint_remove_all(env, BP_CPU); cpu_watchpoint_remove_all(env, BP_CPU); + +#if !defined(CONFIG_USER_ONLY) + /* We hard-wire the BSP to the first CPU. */ + if (env->cpu_index == 0) { + apic_designate_bsp(env->apic_state); + } + + env->halted = !cpu_is_bsp(cpu); +#endif } +#ifndef CONFIG_USER_ONLY +bool cpu_is_bsp(X86CPU *cpu) +{ + return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP; +} +#endif + static void mce_init(X86CPU *cpu) { CPUX86State *cenv = &cpu->env; diff --git a/target-i386/helper.c b/target-i386/helper.c index d3af6eaf71..b748d90063 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1191,7 +1191,6 @@ void do_cpu_init(X86CPU *cpu) env->interrupt_request = sipi; env->pat = pat; apic_init_reset(env->apic_state); - env->halted = !cpu_is_bsp(env); } void do_cpu_sipi(X86CPU *cpu) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index e53c2f6bdf..4cfb3faf01 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -584,11 +584,13 @@ int kvm_arch_init_vcpu(CPUX86State *env) void kvm_arch_reset_vcpu(CPUX86State *env) { + X86CPU *cpu = x86_env_get_cpu(env); + env->exception_injected = -1; env->interrupt_injected = -1; env->xcr0 = 1; if (kvm_irqchip_in_kernel()) { - env->mp_state = cpu_is_bsp(env) ? KVM_MP_STATE_RUNNABLE : + env->mp_state = cpu_is_bsp(cpu) ? KVM_MP_STATE_RUNNABLE : KVM_MP_STATE_UNINITIALIZED; } else { env->mp_state = KVM_MP_STATE_RUNNABLE; |