[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH qom-next 07/12] target-i386: move cpu halted dec
From: |
Andreas Färber |
Subject: |
Re: [Qemu-devel] [PATCH qom-next 07/12] target-i386: move cpu halted decision into x86_cpu_reset |
Date: |
Wed, 30 May 2012 14:11:07 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120421 Thunderbird/12.0 |
Am 30.05.2012 00:10, schrieb Igor Mammedov:
> From: Igor Mammedov <address@hidden>
>
> 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
>
> v2:
> - fix build for i386-linux-user
> spotted-by: Peter Maydell <address@hidden>
>
> Signed-off-by: Igor Mammedov <address@hidden>
> ---
> hw/apic.h | 2 +-
> hw/apic_common.c | 18 ++++++++++++------
> hw/pc.c | 9 ---------
> target-i386/cpu.c | 9 +++++++++
> target-i386/helper.c | 1 -
> target-i386/kvm.c | 5 +++--
> 6 files changed, 25 insertions(+), 19 deletions(-)
>
> diff --git a/hw/apic.h b/hw/apic.h
> index 62179ce..d961ed4 100644
> --- a/hw/apic.h
> +++ b/hw/apic.h
> @@ -20,9 +20,9 @@ void apic_init_reset(DeviceState *s);
> void apic_sipi(DeviceState *s);
> void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
> TPRAccess access);
> +void apic_designate_bsp(DeviceState *d);
>
> /* pc.c */
> -int cpu_is_bsp(CPUX86State *env);
> DeviceState *cpu_get_current_apic(void);
>
> #endif
> diff --git a/hw/apic_common.c b/hw/apic_common.c
> index 46a9ff7..98ad6f0 100644
> --- a/hw/apic_common.c
> +++ b/hw/apic_common.c
> @@ -43,8 +43,8 @@ uint64_t cpu_get_apic_base(DeviceState *d)
> trace_cpu_get_apic_base((uint64_t)s->apicbase);
> return s->apicbase;
> } else {
> - trace_cpu_get_apic_base(0);
> - return 0;
> + trace_cpu_get_apic_base(MSR_IA32_APICBASE_BSP);
> + return MSR_IA32_APICBASE_BSP;
> }
> }
>
> @@ -201,22 +201,28 @@ void apic_init_reset(DeviceState *d)
> s->timer_expiry = -1;
> }
>
> +void apic_designate_bsp(DeviceState *d)
> +{
> + if (d) {
This check looks odd. The function call is already guarded with
cpu_index == 0. What other case would lead to d == NULL and can't we
check that at the call site?
> + APICCommonState *s = APIC_COMMON(d);
If this is a QOM cast macro, it will implicitly assert d != NULL, no?
Andreas
> + s->apicbase |= MSR_IA32_APICBASE_BSP;
> + }
> +}
> +
> static void apic_reset_common(DeviceState *d)
> {
> APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
> APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
> - bool bsp;
>
> - bsp = cpu_is_bsp(&s->cpu->env);
> s->apicbase = 0xfee00000 |
> - (bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
> + (s->apicbase & MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
>
> s->vapic_paddr = 0;
> info->vapic_base_update(s);
>
> apic_init_reset(d);
>
> - if (bsp) {
> + if (s->apicbase & MSR_IA32_APICBASE_BSP) {
> /*
> * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
> * time typically by BIOS, so PIC interrupt can be delivered to the
> diff --git a/hw/pc.c b/hw/pc.c
> index 6bb3d2a..2f681db 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -870,12 +870,6 @@ void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
> nb_ne2k++;
> }
>
> -int cpu_is_bsp(CPUX86State *env)
> -{
> - /* We hard-wire the BSP to the first CPU. */
> - return env->cpu_index == 0;
> -}
> -
> DeviceState *cpu_get_current_apic(void)
> {
> if (cpu_single_env) {
> @@ -942,10 +936,7 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int
> level)
> static void pc_cpu_reset(void *opaque)
> {
> X86CPU *cpu = opaque;
> - CPUX86State *env = &cpu->env;
> -
> cpu_reset(CPU(cpu));
> - env->halted = !cpu_is_bsp(env);
> }
>
> static X86CPU *pc_new_cpu(const char *cpu_model)
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 41a0436..f029f2a 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -1704,6 +1704,15 @@ 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_get_apic_base(env->apic_state) &
> MSR_IA32_APICBASE_BSP);
> +#endif
> }
>
> static void mce_init(X86CPU *cpu)
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index a94be0a..fd20fd4 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -1179,7 +1179,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 0d0d8f6..09621e5 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -583,8 +583,9 @@ void kvm_arch_reset_vcpu(CPUX86State *env)
> env->interrupt_injected = -1;
> env->xcr0 = 1;
> if (kvm_irqchip_in_kernel()) {
> - env->mp_state = cpu_is_bsp(env) ? KVM_MP_STATE_RUNNABLE :
> - KVM_MP_STATE_UNINITIALIZED;
> + env->mp_state =
> + cpu_get_apic_base(env->apic_state) & MSR_IA32_APICBASE_BSP ?
> + KVM_MP_STATE_RUNNABLE : KVM_MP_STATE_UNINITIALIZED;
> } else {
> env->mp_state = KVM_MP_STATE_RUNNABLE;
> }
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
- Re: [Qemu-devel] [PATCH qom-next 01/12] store prev_debug_excp_handler globaly and not per target, (continued)
- [Qemu-devel] [PATCH qom-next 02/12] target-xtensa: use global prev_debug_excp_handler instead of local one, Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 03/12] target-i386: use global prev_debug_excp_handler instead of local one, Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 04/12] target-i386: move tcg initialization into x86_cpu_initfn(), Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 05/12] pc: Add CPU as /machine/cpu[n], Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 06/12] apic: Replace cpu_env pointer by X86CPU link, Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 07/12] target-i386: move cpu halted decision into x86_cpu_reset, Igor Mammedov, 2012/05/29
- Re: [Qemu-devel] [PATCH qom-next 07/12] target-i386: move cpu halted decision into x86_cpu_reset,
Andreas Färber <=
- [Qemu-devel] [PATCH qom-next 09/12] target-i386: make cpu a child of /machine right after it's created, Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 12/12] target-i386: move reset callback to cpu.c and call cpu_reset() in x86_cpu_realize(), Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 08/12] target-i386: introduce cpu-model property for x86_cpu, Igor Mammedov, 2012/05/29
- [Qemu-devel] [PATCH qom-next 11/12] target-i386: initialize APIC at CPU level, Igor Mammedov, 2012/05/29