From patchwork Wed May 23 16:39:37 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Mammedov X-Patchwork-Id: 160970 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 96012B6FB9 for ; Thu, 24 May 2012 03:07:51 +1000 (EST) Received: from localhost ([::1]:48771 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXEc9-0003fX-95 for incoming@patchwork.ozlabs.org; Wed, 23 May 2012 12:40:45 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49411) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXEbR-0001hT-5x for qemu-devel@nongnu.org; Wed, 23 May 2012 12:40:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SXEbO-00083o-RJ for qemu-devel@nongnu.org; Wed, 23 May 2012 12:40:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:24511) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXEbO-00082i-IP for qemu-devel@nongnu.org; Wed, 23 May 2012 12:39:58 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q4NGdrIJ017686 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 23 May 2012 12:39:53 -0400 Received: from nial.brq.redhat.com (dhcp-1-247.brq.redhat.com [10.34.1.247]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q4NGdfEH020894; Wed, 23 May 2012 12:39:49 -0400 From: Igor Mammedov To: qemu-devel@nongnu.org Date: Wed, 23 May 2012 18:39:37 +0200 Message-Id: <1337791181-27446-3-git-send-email-imammedo@redhat.com> In-Reply-To: <1337791181-27446-1-git-send-email-imammedo@redhat.com> References: <1337791181-27446-1-git-send-email-imammedo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: peter.maydell@linaro.org, aliguori@us.ibm.com, wei.liu2@citrix.com, ehabkost@redhat.com, stefano.stabellini@eu.citrix.com, sw@weilnetz.de, mtosatti@redhat.com, agraf@suse.de, blauwirbel@gmail.com, avi@redhat.com, jan.kiszka@siemens.com, anthony.perard@citrix.com, pbonzini@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH qom-next 2/6] target-i386: move cpu halted decision into x86_cpu_reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Igor Mammedov 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 Signed-off-by: Igor Mammedov --- 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 60b8259..23d51e8 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) { + APICCommonState *s = APIC_COMMON(d); + 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 ad27f36..c609770 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) { @@ -926,10 +920,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 89b4ac7..14c0f64 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 2cc8097..3ceefad 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 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; }