From patchwork Tue Oct 4 11:13:38 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfank@linux.vnet.com X-Patchwork-Id: 117602 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 85450B6F81 for ; Tue, 4 Oct 2011 22:14:51 +1100 (EST) Received: from localhost ([::1]:35290 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RB2xN-0002bG-Ih for incoming@patchwork.ozlabs.org; Tue, 04 Oct 2011 07:14:41 -0400 Received: from eggs.gnu.org ([140.186.70.92]:38420) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RB2x9-0002J5-F3 for qemu-devel@nongnu.org; Tue, 04 Oct 2011 07:14:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RB2x7-0000CK-Et for qemu-devel@nongnu.org; Tue, 04 Oct 2011 07:14:27 -0400 Received: from e23smtp01.au.ibm.com ([202.81.31.143]:36514) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RB2x6-0000Bq-TA for qemu-devel@nongnu.org; Tue, 04 Oct 2011 07:14:25 -0400 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [202.81.31.246]) by e23smtp01.au.ibm.com (8.14.4/8.13.1) with ESMTP id p94BClCb024649 for ; Tue, 4 Oct 2011 22:12:47 +1100 Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p94BCC4R2142356 for ; Tue, 4 Oct 2011 22:12:12 +1100 Received: from d23av03.au.ibm.com (loopback [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p94BEMcJ005369 for ; Tue, 4 Oct 2011 22:14:23 +1100 Received: from oc8440477808.ibm.com ([9.77.182.156]) by d23av03.au.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p94BE29J005048; Tue, 4 Oct 2011 22:14:20 +1100 From: pingfank@linux.vnet.com To: linux-acpi@vger.kernel.org, qemu-devel@nongnu.org Date: Tue, 4 Oct 2011 19:13:38 +0800 Message-Id: <1317726818-8514-4-git-send-email-pingfank@linux.vnet.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1317726818-8514-1-git-send-email-pingfank@linux.vnet.com> References: <1317726818-8514-1-git-send-email-pingfank@linux.vnet.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 202.81.31.143 Cc: aliguori@us.ibm.com, Liu Ping Fan , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, ryanh@us.ibm.com, shaohua.li@intel.com, lenb@kernel.org Subject: [Qemu-devel] [PATCH 2/2] LAPIC: make lapic support cpu hotplug 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: Liu Ping Fan Separate apic from qbus to icc bus which supports hotplug feature. And make the creation of apic as part of cpu initialization, so apic's state has been ready, before setting kvm_apic. Signed-off-by: Liu Ping Fan --- Makefile.target | 1 + hw/apic.c | 7 ++++- hw/apic.h | 1 + hw/icc_bus.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/icc_bus.h | 24 +++++++++++++++++++ hw/pc.c | 11 ++++----- target-i386/cpu.h | 1 + target-i386/helper.c | 7 +++++- target-i386/kvm.c | 1 - 9 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 hw/icc_bus.c create mode 100644 hw/icc_bus.h diff --git a/Makefile.target b/Makefile.target index 9011f28..5607c6d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -241,6 +241,7 @@ obj-i386-$(CONFIG_KVM) += kvmclock.o obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o obj-i386-y += testdev.o obj-i386-y += acpi.o acpi_piix4.o +obj-i386-y += icc_bus.o obj-i386-y += pcspk.o i8254.o obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o diff --git a/hw/apic.c b/hw/apic.c index 69d6ac5..95a1664 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -24,6 +24,7 @@ #include "sysbus.h" #include "trace.h" #include "kvm.h" +#include "icc_bus.h" /* APIC Local Vector Table */ #define APIC_LVT_TIMER 0 @@ -304,11 +305,13 @@ void cpu_set_apic_base(DeviceState *d, uint64_t val) if (!s) return; + if (kvm_enabled() && kvm_irqchip_in_kernel()) s->apicbase = val; else s->apicbase = (val & 0xfffff000) | (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE)); + /* if disabled, cannot be enabled again */ if (!(val & MSR_IA32_APICBASE_ENABLE)) { s->apicbase &= ~MSR_IA32_APICBASE_ENABLE; @@ -1075,7 +1078,7 @@ static const VMStateDescription vmstate_apic = { } }; -static void apic_reset(DeviceState *d) +void apic_reset(DeviceState *d) { APICState *s = DO_UPCAST(APICState, busdev.qdev, d); int bsp; @@ -1138,7 +1141,7 @@ static SysBusDeviceInfo apic_info = { static void apic_register_devices(void) { - sysbus_register_withprop(&apic_info); + iccbus_register(&apic_info); } device_init(apic_register_devices) diff --git a/hw/apic.h b/hw/apic.h index c857d52..e258efa 100644 --- a/hw/apic.h +++ b/hw/apic.h @@ -24,5 +24,6 @@ void apic_sipi(DeviceState *s); /* pc.c */ int cpu_is_bsp(CPUState *env); DeviceState *cpu_get_current_apic(void); +void apic_reset(DeviceState *d); #endif diff --git a/hw/icc_bus.c b/hw/icc_bus.c new file mode 100644 index 0000000..360ca2a --- /dev/null +++ b/hw/icc_bus.c @@ -0,0 +1,62 @@ +/* +*/ +#define ICC_BUS_PLUG +#ifdef ICC_BUS_PLUG +#include "icc_bus.h" + + + +struct icc_bus_info icc_info = { + .qinfo.name = "icc", + .qinfo.size = sizeof(struct icc_bus), + .qinfo.props = (Property[]) { + DEFINE_PROP_END_OF_LIST(), + } + +}; + + +static const VMStateDescription vmstate_icc_bus = { + .name = "icc_bus", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = NULL, + .post_load = NULL, +}; + +struct icc_bus *g_iccbus; + +struct icc_bus *icc_init_bus(DeviceState *parent, const char *name) +{ + struct icc_bus *bus; + + bus = FROM_QBUS(icc_bus, qbus_create(&icc_info.qinfo, parent, name)); + bus->qbus.allow_hotplug = 1; /* Yes, we can */ + bus->qbus.name = "icc"; + vmstate_register(NULL, -1, &vmstate_icc_bus, bus); + g_iccbus = bus; + return bus; +} + + + + + +static int iccbus_device_init(DeviceState *dev, DeviceInfo *base) +{ + SysBusDeviceInfo *info = container_of(base, SysBusDeviceInfo, qdev); + + return info->init(sysbus_from_qdev(dev)); +} + +void iccbus_register(SysBusDeviceInfo *info) +{ + info->qdev.init = iccbus_device_init; + info->qdev.bus_info = &icc_info.qinfo; + + assert(info->qdev.size >= sizeof(SysBusDevice)); + qdev_register(&info->qdev); +} + +#endif diff --git a/hw/icc_bus.h b/hw/icc_bus.h new file mode 100644 index 0000000..94d9242 --- /dev/null +++ b/hw/icc_bus.h @@ -0,0 +1,24 @@ +#ifndef QEMU_ICC_H +#define QEMU_ICC_H + +#include "qdev.h" +#include "sysbus.h" + +typedef struct icc_bus icc_bus; +typedef struct icc_bus_info icc_bus_info; + + +struct icc_bus { + BusState qbus; +}; + +struct icc_bus_info { + BusInfo qinfo; +}; + +extern struct icc_bus_info icc_info; +extern struct icc_bus *g_iccbus; +extern struct icc_bus *icc_init_bus(DeviceState *parent, const char *name); +extern void iccbus_register(SysBusDeviceInfo *info); + +#endif diff --git a/hw/pc.c b/hw/pc.c index 6b3662e..10371d8 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -24,6 +24,7 @@ #include "hw.h" #include "pc.h" #include "apic.h" +#include "icc_bus.h" #include "fdc.h" #include "ide.h" #include "pci.h" @@ -91,6 +92,7 @@ struct e820_table { static struct e820_table e820_table; struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; + void isa_irq_handler(void *opaque, int n, int level) { IsaIrqState *isa = (IsaIrqState *)opaque; @@ -872,13 +874,13 @@ DeviceState *cpu_get_current_apic(void) } } -static DeviceState *apic_init(void *env, uint8_t apic_id) +DeviceState *apic_init(void *env, uint8_t apic_id) { DeviceState *dev; SysBusDevice *d; static int apic_mapped; - dev = qdev_create(NULL, "apic"); + dev = qdev_create(&g_iccbus->qbus, "apic"); qdev_prop_set_uint8(dev, "id", apic_id); qdev_prop_set_ptr(dev, "cpu_env", env); qdev_init_nofail(dev); @@ -943,10 +945,6 @@ CPUState *pc_new_cpu(const char *cpu_model) fprintf(stderr, "Unable to find x86 CPU definition\n"); exit(1); } - if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) { - env->cpuid_apic_id = env->cpu_index; - env->apic_state = apic_init(env, env->cpuid_apic_id); - } qemu_register_reset(pc_cpu_reset, env); pc_cpu_reset(env); return env; @@ -956,6 +954,7 @@ void pc_cpus_init(const char *cpu_model) { int i; + icc_init_bus(NULL, "icc"); /* init CPUs */ for(i = 0; i < smp_cpus; i++) { pc_new_cpu(cpu_model); diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2a071f2..0160c55 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1062,4 +1062,5 @@ void svm_check_intercept(CPUState *env1, uint32_t type); uint32_t cpu_cc_compute_all(CPUState *env1, int op); +extern DeviceState *apic_init(void *env, uint8_t apic_id); #endif /* CPU_I386_H */ diff --git a/target-i386/helper.c b/target-i386/helper.c index 5df40d4..551a8a2 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -30,6 +30,7 @@ #include "monitor.h" #endif + //#define DEBUG_MMU /* NOTE: must be called outside the CPU execute loop */ @@ -1257,7 +1258,11 @@ CPUX86State *cpu_x86_init(const char *cpu_model) return NULL; } mce_init(env); - + if ((env->cpuid_features & CPUID_APIC) + || smp_cpus > 1) { + env->cpuid_apic_id = env->cpu_index; + env->apic_state = apic_init(env, env->cpuid_apic_id); + } qemu_init_vcpu(env); return env; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 571d792..407dba6 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -880,7 +880,6 @@ static int kvm_put_sregs(CPUState *env) sregs.cr8 = cpu_get_apic_tpr(env->apic_state); sregs.apic_base = cpu_get_apic_base(env->apic_state); - sregs.efer = env->efer; return kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);