This series is an attempt to provide CPU hotplug support on ARM virt platform. This is based on ACPI GED device. We should enable ACPI support, and use vGICv3 and 64bit CPU to support CPU hotplug. Under KVM accel, the KVM vCPUs is pre-created. Besides, vGIC IRIs is pre-created too. However, QEMU vCPU objects are defer-created. Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
96 lines
3.6 KiB
Diff
96 lines
3.6 KiB
Diff
From 0288d98f0ef4d17a73cf2bad1b928cd7c044e318 Mon Sep 17 00:00:00 2001
|
|
From: Keqian Zhu <zhukeqian1@huawei.com>
|
|
Date: Fri, 10 Apr 2020 13:40:44 +0800
|
|
Subject: [PATCH] acpi/madt: Add pre-sizing capability to MADT GICC struct
|
|
|
|
The count of possible CPUs is exposed to guest through the count
|
|
of MADT GICC struct, so we should pre-sizing MADT GICC too.
|
|
|
|
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
|
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
|
---
|
|
hw/arm/virt-acpi-build.c | 26 +++++++++++++++++++++-----
|
|
include/hw/acpi/acpi-defs.h | 1 +
|
|
2 files changed, 22 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
|
index dbe9acb148..efac788ba1 100644
|
|
--- a/hw/arm/virt-acpi-build.c
|
|
+++ b/hw/arm/virt-acpi-build.c
|
|
@@ -678,6 +678,13 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
|
const MemMapEntry *memmap = vms->memmap;
|
|
AcpiMadtGenericCpuInterface *gicc = acpi_data_push(entry, sizeof(*gicc));
|
|
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(uid));
|
|
+ static bool pmu;
|
|
+
|
|
+ if (uid == 0) {
|
|
+ pmu = arm_feature(&armcpu->env, ARM_FEATURE_PMU);
|
|
+ }
|
|
+ /* FEATURE_PMU should be all enabled or disabled for CPUs */
|
|
+ assert(!armcpu || arm_feature(&armcpu->env, ARM_FEATURE_PMU) == pmu);
|
|
|
|
gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
|
|
gicc->length = sizeof(*gicc);
|
|
@@ -687,11 +694,15 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
|
gicc->gicv_base_address = cpu_to_le64(memmap[VIRT_GIC_VCPU].base);
|
|
}
|
|
gicc->cpu_interface_number = cpu_to_le32(uid);
|
|
- gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
|
|
+ gicc->arm_mpidr = possible_cpus->cpus[uid].arch_id;
|
|
gicc->uid = cpu_to_le32(uid);
|
|
- gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
|
|
+ if (armcpu) {
|
|
+ gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
|
|
+ } else {
|
|
+ gicc->flags = cpu_to_le32(ACPI_MADT_GICC_DISABLED);
|
|
+ }
|
|
|
|
- if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
|
|
+ if (pmu) {
|
|
gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
|
|
}
|
|
if (vms->virt) {
|
|
@@ -704,12 +715,17 @@ static void
|
|
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|
{
|
|
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
|
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
|
|
+ MachineState *ms = MACHINE(vms);
|
|
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
|
|
int madt_start = table_data->len;
|
|
const MemMapEntry *memmap = vms->memmap;
|
|
const int *irqmap = vms->irqmap;
|
|
AcpiMultipleApicTable *madt;
|
|
AcpiMadtGenericDistributor *gicd;
|
|
AcpiMadtGenericMsiFrame *gic_msi;
|
|
+ /* The MADT GICC numbers */
|
|
+ int num_cpu = vms->smp_cpus;
|
|
int i;
|
|
|
|
madt = acpi_data_push(table_data, sizeof *madt);
|
|
@@ -720,8 +736,8 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
|
|
gicd->version = vms->gic_version;
|
|
|
|
- for (i = 0; i < vms->smp_cpus; i++) {
|
|
- virt_madt_cpu_entry(NULL, i, NULL, table_data);
|
|
+ for (i = 0; i < num_cpu; i++) {
|
|
+ virt_madt_cpu_entry(NULL, i, possible_cpus, table_data);
|
|
}
|
|
|
|
if (vms->gic_version == 3) {
|
|
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
|
|
index 39ae91d3b8..6bfa7f9152 100644
|
|
--- a/include/hw/acpi/acpi-defs.h
|
|
+++ b/include/hw/acpi/acpi-defs.h
|
|
@@ -306,6 +306,7 @@ typedef struct AcpiMadtGenericCpuInterface AcpiMadtGenericCpuInterface;
|
|
|
|
/* GICC CPU Interface Flags */
|
|
#define ACPI_MADT_GICC_ENABLED 1
|
|
+#define ACPI_MADT_GICC_DISABLED 0
|
|
|
|
struct AcpiMadtGenericDistributor {
|
|
ACPI_SUB_HEADER_DEF
|
|
--
|
|
2.19.1
|