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>
109 lines
4.3 KiB
Diff
109 lines
4.3 KiB
Diff
From a3097eed8b642dc6fe891112340821e869b90cc2 Mon Sep 17 00:00:00 2001
|
|
From: Keqian Zhu <zhukeqian1@huawei.com>
|
|
Date: Mon, 13 Jan 2020 19:02:20 +0800
|
|
Subject: [PATCH] acpi/madt: Factor out the building of MADT GICC struct
|
|
|
|
To realize CPU hotplug, the cpus aml within ACPI DSDT should contain
|
|
_MAT mathod, which is equal to the GICC struct in ACPI MADT. Factor
|
|
out the GICC building code from ACPI MADT and reuse it in build_cpus_aml.
|
|
|
|
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
|
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
|
---
|
|
hw/arm/virt-acpi-build.c | 51 +++++++++++++++++++++++-----------------
|
|
include/hw/arm/virt.h | 3 +++
|
|
2 files changed, 32 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
|
index f48733d9f2..4b6aace433 100644
|
|
--- a/hw/arm/virt-acpi-build.c
|
|
+++ b/hw/arm/virt-acpi-build.c
|
|
@@ -664,6 +664,34 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|
table_data->len - gtdt_start, 2, NULL, NULL);
|
|
}
|
|
|
|
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
|
+ const CPUArchIdList *possible_cpus, GArray *entry)
|
|
+{
|
|
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
|
|
+ const MemMapEntry *memmap = vms->memmap;
|
|
+ AcpiMadtGenericCpuInterface *gicc = acpi_data_push(entry, sizeof(*gicc));
|
|
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(uid));
|
|
+
|
|
+ gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
|
|
+ gicc->length = sizeof(*gicc);
|
|
+ if (vms->gic_version == 2) {
|
|
+ gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
|
|
+ gicc->gich_base_address = cpu_to_le64(memmap[VIRT_GIC_HYP].base);
|
|
+ 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->uid = cpu_to_le32(uid);
|
|
+ gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
|
|
+
|
|
+ if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
|
|
+ gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
|
|
+ }
|
|
+ if (vms->virt) {
|
|
+ gicc->vgic_interrupt = cpu_to_le32(PPI(ARCH_GIC_MAINT_IRQ));
|
|
+ }
|
|
+}
|
|
+
|
|
/* MADT */
|
|
static void
|
|
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|
@@ -686,28 +714,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|
gicd->version = vms->gic_version;
|
|
|
|
for (i = 0; i < vms->smp_cpus; i++) {
|
|
- AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
|
|
- sizeof(*gicc));
|
|
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
|
|
-
|
|
- gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
|
|
- gicc->length = sizeof(*gicc);
|
|
- if (vms->gic_version == 2) {
|
|
- gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
|
|
- gicc->gich_base_address = cpu_to_le64(memmap[VIRT_GIC_HYP].base);
|
|
- gicc->gicv_base_address = cpu_to_le64(memmap[VIRT_GIC_VCPU].base);
|
|
- }
|
|
- gicc->cpu_interface_number = cpu_to_le32(i);
|
|
- gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
|
|
- gicc->uid = cpu_to_le32(i);
|
|
- gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
|
|
-
|
|
- if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
|
|
- gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
|
|
- }
|
|
- if (vms->virt) {
|
|
- gicc->vgic_interrupt = cpu_to_le32(PPI(ARCH_GIC_MAINT_IRQ));
|
|
- }
|
|
+ virt_madt_cpu_entry(NULL, i, NULL, table_data);
|
|
}
|
|
|
|
if (vms->gic_version == 3) {
|
|
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
|
index 3dfefca93b..6b1f10b231 100644
|
|
--- a/include/hw/arm/virt.h
|
|
+++ b/include/hw/arm/virt.h
|
|
@@ -37,6 +37,7 @@
|
|
#include "hw/block/flash.h"
|
|
#include "sysemu/kvm.h"
|
|
#include "hw/intc/arm_gicv3_common.h"
|
|
+#include "hw/acpi/acpi_dev_interface.h"
|
|
|
|
#define NUM_GICV2M_SPIS 64
|
|
#define NUM_VIRTIO_TRANSPORTS 32
|
|
@@ -154,6 +155,8 @@ typedef struct {
|
|
OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
|
|
|
|
void virt_acpi_setup(VirtMachineState *vms);
|
|
+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
|
+ const CPUArchIdList *cpu_list, GArray *entry);
|
|
|
|
/* Return the number of used redistributor regions */
|
|
static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
|
|
--
|
|
2.19.1
|