On 9/14/23 02:38, James Morse wrote:
ACPI has two ways of describing processors in the DSDT. Either as a device
object with HID ACPI0007, or as a type 'C' package inside a Processor
Container. The ACPI processor driver probes CPUs described as devices, but
not those described as packages.
Duplicate descriptions are not allowed, the ACPI processor driver already
parses the UID from both devices and containers. acpi_processor_get_info()
returns an error if the UID exists twice in the DSDT.
The missing probe for CPUs described as packages creates a problem for
moving the cpu_register() calls into the acpi_processor driver, as CPUs
described like this don't get registered, leading to errors from other
subsystems when they try to add new sysfs entries to the CPU node.
(e.g. topology_sysfs_init()'s use of topology_add_dev() via cpuhp)
To fix this, parse the processor container and call acpi_processor_add()
for each processor that is discovered like this. The processor container
handler is added with acpi_scan_add_handler(), so no detach call will
arrive.
Qemu TCG describes CPUs using packages in a processor container.
Signed-off-by: James Morse <james.morse@xxxxxxx>
---
drivers/acpi/acpi_processor.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
I don't understand the last sentence of the commit log. QEMU
always have "ACPI0007" for the processor devices.
#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007"
#define ACPI_PROCESSOR_OBJECT_HID "LNXCPU"
[gshan@gshan q]$ git grep ACPI0007
hw/acpi/cpu.c: aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
hw/arm/virt-acpi-build.c: aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
hw/riscv/virt-acpi-build.c: aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
[gshan@gshan q]$ git grep LNXCPU
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
index c0839bcf78c1..b4bde78121bb 100644
--- a/drivers/acpi/acpi_processor.c
+++ b/drivers/acpi/acpi_processor.c
@@ -625,9 +625,31 @@ static struct acpi_scan_handler processor_handler = {
},
};
+static acpi_status acpi_processor_container_walk(acpi_handle handle,
+ u32 lvl,
+ void *context,
+ void **rv)
+{
+ struct acpi_device *adev;
+ acpi_status status;
+
+ adev = acpi_get_acpi_dev(handle);
+ if (!adev)
+ return AE_ERROR;
+
+ status = acpi_processor_add(adev, &processor_device_ids[0]);
+ acpi_put_acpi_dev(adev);
+
+ return status;
+}
+
static int acpi_processor_container_attach(struct acpi_device *dev,
const struct acpi_device_id *id)
{
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, dev->handle,
+ ACPI_UINT32_MAX, acpi_processor_container_walk,
+ NULL, NULL, NULL);
+
return 1;
}
Thanks,
Gavin