Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
pc: Set CPU APIC ID explicitly
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.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is based on the patch that I have originally suybmitted as:
 Subject: pc: create apic_id_for_cpu() function (v3)

Changes v2:
 - Implement it without the PCInitArgs PC code refactor
 - cpu_index is now on CPUState
 - Use "apic-id" property
  • Loading branch information
ehabkost committed Jan 9, 2013
1 parent d90ee04 commit a79156d
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions hw/pc.c
Expand Up @@ -524,6 +524,21 @@ static void handle_a20_line_change(void *opaque, int irq, int level)
cpu_x86_set_a20(cpu, level);
}

/* 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.
*/
static 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;
}

int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
{
int index = le32_to_cpu(e820_table.count);
Expand Down Expand Up @@ -827,12 +842,26 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
static X86CPU *pc_cpu_init(const char *cpu_model)
{
X86CPU *cpu = NULL;
CPUState *cs;
Error *error = NULL;
uint32_t apic_id;

cpu = cpu_x86_create(cpu_model, &error);
if (error) {
goto error;
}
cs = CPU(cpu);

/* Override the default APIC set by the X86CPU init function.
* We need to do that because:
* - The APIC ID depends on the CPU topology;
* - The exact APIC ID used may depend on the machine-type init arguments.
*/
apic_id = apic_id_for_cpu(cs->cpu_index);
object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &error);
if (error) {
goto error;
}

x86_cpu_realize(OBJECT(cpu), &error);
if (error) {
Expand Down

0 comments on commit a79156d

Please sign in to comment.