Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request'…
Browse files Browse the repository at this point in the history
… into staging

x86 and CPU queue, 2016-10-24

x2APIC support to APIC code, cpu_exec_init() refactor on all
architectures, and other x86 changes.

# gpg: Signature made Mon 24 Oct 2016 20:51:14 BST
# gpg:                using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/x86-pull-request:
  exec: call cpu_exec_exit() from a CPU unrealize common function
  exec: move cpu_exec_init() calls to realize functions
  exec: split cpu_exec_init()
  pc: q35: Bump max_cpus to 288
  pc: Require IRQ remapping and EIM if there could be x2APIC CPUs
  pc: Add 'etc/boot-cpus' fw_cfg file for machine with more than 255 CPUs
  Increase MAX_CPUMASK_BITS from 255 to 288
  pc: Clarify FW_CFG_MAX_CPUS usage comment
  pc: kvm_apic: Pass APIC ID depending on xAPIC/x2APIC mode
  pc: apic_common: Reset APIC ID to initial ID when switching into x2APIC mode
  pc: apic_common: Restore APIC ID to initial ID on reset
  pc: apic_common: Extend APIC ID property to 32bit
  pc: Leave max apic_id_limit only in legacy cpu hotplug code
  acpi: cphp: Force switch to modern cpu hotplug if APIC ID > 254
  pc: acpi: x2APIC support for SRAT table
  pc: acpi: x2APIC support for MADT table and _MAT method

Conflicts:
	target-arm/cpu.c

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Oct 25, 2016
2 parents fe4c040 + 7bbc124 commit c43e853
Show file tree
Hide file tree
Showing 41 changed files with 427 additions and 237 deletions.
12 changes: 7 additions & 5 deletions exec.c
Expand Up @@ -630,7 +630,7 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
}
#endif

void cpu_exec_exit(CPUState *cpu)
void cpu_exec_unrealizefn(CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);

Expand All @@ -644,11 +644,8 @@ void cpu_exec_exit(CPUState *cpu)
}
}

void cpu_exec_init(CPUState *cpu, Error **errp)
void cpu_exec_initfn(CPUState *cpu)
{
CPUClass *cc ATTRIBUTE_UNUSED = CPU_GET_CLASS(cpu);
Error *local_err ATTRIBUTE_UNUSED = NULL;

cpu->as = NULL;
cpu->num_ases = 0;

Expand All @@ -669,6 +666,11 @@ void cpu_exec_init(CPUState *cpu, Error **errp)
cpu->memory = system_memory;
object_ref(OBJECT(cpu->memory));
#endif
}

void cpu_exec_realizefn(CPUState *cpu, Error **errp)
{
CPUClass *cc ATTRIBUTE_UNUSED = CPU_GET_CLASS(cpu);

cpu_list_add(cpu);

Expand Down
5 changes: 5 additions & 0 deletions hw/acpi/cpu.c
Expand Up @@ -531,6 +531,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
apic->flags = cpu_to_le32(1);
break;
}
case ACPI_APIC_LOCAL_X2APIC: {
AcpiMadtProcessorX2Apic *apic = (void *)madt_buf->data;
apic->flags = cpu_to_le32(1);
break;
}
default:
assert(0);
}
Expand Down
17 changes: 12 additions & 5 deletions hw/acpi/cpu_hotplug.c
Expand Up @@ -15,6 +15,7 @@
#include "qapi/error.h"
#include "qom/cpu.h"
#include "hw/i386/pc.h"
#include "qemu/error-report.h"

#define CPU_EJECT_METHOD "CPEJ"
#define CPU_MAT_METHOD "CPMA"
Expand Down Expand Up @@ -63,7 +64,8 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,

cpu_id = k->get_arch_id(cpu);
if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
object_property_set_bool(g->device, false, "cpu-hotplug-legacy",
&error_abort);
return;
}

Expand All @@ -85,13 +87,14 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
{
CPUState *cpu;

CPU_FOREACH(cpu) {
acpi_set_cpu_present_bit(gpe_cpu, cpu, &error_abort);
}
memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
memory_region_add_subregion(parent, base, &gpe_cpu->io);
gpe_cpu->device = owner;

CPU_FOREACH(cpu) {
acpi_set_cpu_present_bit(gpe_cpu, cpu, &error_abort);
}
}

void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
Expand Down Expand Up @@ -234,7 +237,11 @@ void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
/* The current AML generator can cover the APIC ID range [0..255],
* inclusive, for VCPU hotplug. */
QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);
if (pcms->apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {
error_report("max_cpus is too large. APIC ID of last CPU is %u",
pcms->apic_id_limit - 1);
exit(1);
}

/* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
Expand Down
2 changes: 1 addition & 1 deletion hw/arm/virt.c
Expand Up @@ -1494,7 +1494,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
* it later in machvirt_init, where we have more information about the
* configuration of the particular instance.
*/
mc->max_cpus = MAX_CPUMASK_BITS;
mc->max_cpus = 255;
mc->has_dynamic_sysbus = true;
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
Expand Down
112 changes: 78 additions & 34 deletions hw/i386/acpi-build.c
Expand Up @@ -340,24 +340,38 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
CPUArchIdList *apic_ids, GArray *entry)
{
int apic_id;
AcpiMadtProcessorApic *apic = acpi_data_push(entry, sizeof *apic);

apic_id = apic_ids->cpus[uid].arch_id;
apic->type = ACPI_APIC_PROCESSOR;
apic->length = sizeof(*apic);
apic->processor_id = uid;
apic->local_apic_id = apic_id;
if (apic_ids->cpus[uid].cpu != NULL) {
apic->flags = cpu_to_le32(1);
uint32_t apic_id = apic_ids->cpus[uid].arch_id;

/* ACPI spec says that LAPIC entry for non present
* CPU may be omitted from MADT or it must be marked
* as disabled. However omitting non present CPU from
* MADT breaks hotplug on linux. So possible CPUs
* should be put in MADT but kept disabled.
*/
if (apic_id < 255) {
AcpiMadtProcessorApic *apic = acpi_data_push(entry, sizeof *apic);

apic->type = ACPI_APIC_PROCESSOR;
apic->length = sizeof(*apic);
apic->processor_id = uid;
apic->local_apic_id = apic_id;
if (apic_ids->cpus[uid].cpu != NULL) {
apic->flags = cpu_to_le32(1);
} else {
apic->flags = cpu_to_le32(0);
}
} else {
/* ACPI spec says that LAPIC entry for non present
* CPU may be omitted from MADT or it must be marked
* as disabled. However omitting non present CPU from
* MADT breaks hotplug on linux. So possible CPUs
* should be put in MADT but kept disabled.
*/
apic->flags = cpu_to_le32(0);
AcpiMadtProcessorX2Apic *apic = acpi_data_push(entry, sizeof *apic);

apic->type = ACPI_APIC_LOCAL_X2APIC;
apic->length = sizeof(*apic);
apic->uid = cpu_to_le32(uid);
apic->x2apic_id = cpu_to_le32(apic_id);
if (apic_ids->cpus[uid].cpu != NULL) {
apic->flags = cpu_to_le32(1);
} else {
apic->flags = cpu_to_le32(0);
}
}
}

Expand All @@ -369,11 +383,11 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
int madt_start = table_data->len;
AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(pcms->acpi_dev);
AcpiDeviceIf *adev = ACPI_DEVICE_IF(pcms->acpi_dev);
bool x2apic_mode = false;

AcpiMultipleApicTable *madt;
AcpiMadtIoApic *io_apic;
AcpiMadtIntsrcovr *intsrcovr;
AcpiMadtLocalNmi *local_nmi;
int i;

madt = acpi_data_push(table_data, sizeof *madt);
Expand All @@ -382,6 +396,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)

for (i = 0; i < apic_ids->len; i++) {
adevc->madt_cpu(adev, i, apic_ids, table_data);
if (apic_ids->cpus[i].arch_id > 254) {
x2apic_mode = true;
}
}
g_free(apic_ids);

Expand Down Expand Up @@ -414,12 +431,25 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
intsrcovr->flags = cpu_to_le16(0xd); /* active high, level triggered */
}

local_nmi = acpi_data_push(table_data, sizeof *local_nmi);
local_nmi->type = ACPI_APIC_LOCAL_NMI;
local_nmi->length = sizeof(*local_nmi);
local_nmi->processor_id = 0xff; /* all processors */
local_nmi->flags = cpu_to_le16(0);
local_nmi->lint = 1; /* ACPI_LINT1 */
if (x2apic_mode) {
AcpiMadtLocalX2ApicNmi *local_nmi;

local_nmi = acpi_data_push(table_data, sizeof *local_nmi);
local_nmi->type = ACPI_APIC_LOCAL_X2APIC_NMI;
local_nmi->length = sizeof(*local_nmi);
local_nmi->uid = 0xFFFFFFFF; /* all processors */
local_nmi->flags = cpu_to_le16(0);
local_nmi->lint = 1; /* ACPI_LINT1 */
} else {
AcpiMadtLocalNmi *local_nmi;

local_nmi = acpi_data_push(table_data, sizeof *local_nmi);
local_nmi->type = ACPI_APIC_LOCAL_NMI;
local_nmi->length = sizeof(*local_nmi);
local_nmi->processor_id = 0xff; /* all processors */
local_nmi->flags = cpu_to_le16(0);
local_nmi->lint = 1; /* ACPI_LINT1 */
}

build_header(linker, table_data,
(void *)(table_data->data + madt_start), "APIC",
Expand Down Expand Up @@ -2391,7 +2421,6 @@ static void
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
AcpiSystemResourceAffinityTable *srat;
AcpiSratProcessorAffinity *core;
AcpiSratMemoryAffinity *numamem;

int i;
Expand All @@ -2411,18 +2440,33 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)

for (i = 0; i < apic_ids->len; i++) {
int j = numa_get_node_for_cpu(i);
int apic_id = apic_ids->cpus[i].arch_id;
uint32_t apic_id = apic_ids->cpus[i].arch_id;

core = acpi_data_push(table_data, sizeof *core);
core->type = ACPI_SRAT_PROCESSOR_APIC;
core->length = sizeof(*core);
core->local_apic_id = apic_id;
if (j < nb_numa_nodes) {
if (apic_id < 255) {
AcpiSratProcessorAffinity *core;

core = acpi_data_push(table_data, sizeof *core);
core->type = ACPI_SRAT_PROCESSOR_APIC;
core->length = sizeof(*core);
core->local_apic_id = apic_id;
if (j < nb_numa_nodes) {
core->proximity_lo = j;
}
memset(core->proximity_hi, 0, 3);
core->local_sapic_eid = 0;
core->flags = cpu_to_le32(1);
} else {
AcpiSratProcessorX2ApicAffinity *core;

core = acpi_data_push(table_data, sizeof *core);
core->type = ACPI_SRAT_PROCESSOR_x2APIC;
core->length = sizeof(*core);
core->x2apic_id = cpu_to_le32(apic_id);
if (j < nb_numa_nodes) {
core->proximity_domain = cpu_to_le32(j);
}
core->flags = cpu_to_le32(1);
}
memset(core->proximity_hi, 0, 3);
core->local_sapic_eid = 0;
core->flags = cpu_to_le32(1);
}


Expand Down
12 changes: 10 additions & 2 deletions hw/i386/kvm/apic.c
Expand Up @@ -34,7 +34,11 @@ static void kvm_put_apic_state(APICCommonState *s, struct kvm_lapic_state *kapic
int i;

memset(kapic, 0, sizeof(*kapic));
kvm_apic_set_reg(kapic, 0x2, s->id << 24);
if (kvm_has_x2apic_api() && s->apicbase & MSR_IA32_APICBASE_EXTD) {
kvm_apic_set_reg(kapic, 0x2, s->initial_apic_id);
} else {
kvm_apic_set_reg(kapic, 0x2, s->id << 24);
}
kvm_apic_set_reg(kapic, 0x8, s->tpr);
kvm_apic_set_reg(kapic, 0xd, s->log_dest << 24);
kvm_apic_set_reg(kapic, 0xe, s->dest_mode << 28 | 0x0fffffff);
Expand All @@ -59,7 +63,11 @@ void kvm_get_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic)
APICCommonState *s = APIC_COMMON(dev);
int i, v;

s->id = kvm_apic_get_reg(kapic, 0x2) >> 24;
if (kvm_has_x2apic_api() && s->apicbase & MSR_IA32_APICBASE_EXTD) {
assert(kvm_apic_get_reg(kapic, 0x2) == s->initial_apic_id);
} else {
s->id = kvm_apic_get_reg(kapic, 0x2) >> 24;
}
s->tpr = kvm_apic_get_reg(kapic, 0x8);
s->arb_id = kvm_apic_get_reg(kapic, 0x9);
s->log_dest = kvm_apic_get_reg(kapic, 0xd) >> 24;
Expand Down

0 comments on commit c43e853

Please sign in to comment.