From b36ad2cc9a74e50e2489f3b66d270c8162e8334a Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <383c464e74b19af5a4e1e18bb56df969e9d61c2a.1351776104.git.minovotn@redhat.com> References: <383c464e74b19af5a4e1e18bb56df969e9d61c2a.1351776104.git.minovotn@redhat.com> From: Eduardo Habkost Date: Mon, 29 Oct 2012 18:52:31 +0100 Subject: [PATCH 05/11] pc: set CPU APIC ID explicitly RH-Author: Eduardo Habkost Message-id: <1351536756-16475-6-git-send-email-ehabkost@redhat.com> Patchwork-id: 43756 O-Subject: [RHEL6.4 qemu-kvm PATCH 05/10] pc: set CPU APIC ID explicitly Bugzilla: 733720 RH-Acked-by: Laszlo Ersek RH-Acked-by: Igor Mammedov RH-Acked-by: Gleb Natapov Bugzilla: 733720 Related TestOnly BZs: 816804, 815958, 782648 Upstream status: equivalent version submitted Message-Id: <1351101001-14589-23-git-send-email-ehabkost@redhat.com> http://article.gmane.org/gmane.comp.emulators.qemu/177655 Upstream patch description: The PC code takes care of CPU topology, and CPU topology affect the CPU APIC ID. So the PC CPU initialization code needs to set the APIC ID explicitly. By now, keep the existing behavior but create a apic_id_for_cpu() function that will be changed later to implement appropriate topology-dependent behavior. The cpuid_apic_id field is used only at: - x86_cpu_apic_init(), called from x86_cpu_realize() - kvm_init_vcpu(), that is called from the VCPU thread created by qemu_init_vcpu(), called by x86_cpu_realize() - helper_cpuid(), called only when the VCPU is already running - kvm_arch_init_vcpu(), that's called by kvm_init_vcpu() So it's safe to change it before x86_cpu_realize() is called. The change was even simpler on RHEL, because the current code already initializes cpuid_apic_id on pc_new_cpu(). I am not going to pull the large PC initialization refactor code to RHEL, so the apic_id_for_cpu() function won't get a PCInitArgs argument. The compatibility mode will be implemented using a global variable instead. Signed-off-by: Eduardo Habkost --- hw/pc.c | 18 +++++++++++++++++- hw/pc.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) Signed-off-by: Michal Novotny --- hw/pc.c | 18 +++++++++++++++++- hw/pc.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/pc.c b/hw/pc.c index b7e7b79..0e7dee0 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -455,6 +455,21 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val) } } +/* Calculates initial APIC ID for a specific CPU index + * + * Currently we need to be able to calculate the APIC ID from the CPU index + * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have + * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of + * all CPUs up to max_cpus. + */ +uint32_t apic_id_for_cpu(int cpu_index) +{ + /* right now APIC ID == CPU index. this will eventually change to use + * the CPU topology configuration properly + */ + return cpu_index; +} + static void *bochs_bios_init(void) { void *fw_cfg; @@ -1002,7 +1017,8 @@ CPUState *pc_new_cpu(const char *cpu_model) } env->kvm_cpu_state.regs_modified = 1; if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) { - env->cpuid_apic_id = env->cpu_index; + env->cpuid_apic_id = apic_id_for_cpu(env->cpu_index); + /* APIC reset callback resets cpu */ apic_init(env); } else { diff --git a/hw/pc.h b/hw/pc.h index f0b0bb7..cdf3dd6 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -109,6 +109,7 @@ extern int fd_bootchk; void ioport_set_a20(int enable); int ioport_get_a20(void); CPUState *pc_new_cpu(const char *cpu_model); +uint32_t apic_id_for_cpu(int cpu_index); /* acpi.c */ extern int acpi_enabled; -- 1.7.11.7