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
|