[PATCH RFC v3 10/21] ACPI: Check _STA present bit before making CPUs not present
Russell King (Oracle)
rmk+kernel at armlinux.org.uk
Wed Dec 13 04:50:02 PST 2023
From: James Morse <james.morse at arm.com>
When called acpi_processor_post_eject() unconditionally make a CPU
not-present and unregisters it.
To add support for AML events where the CPU has become disabled, but
remains present, the _STA method should be checked before calling
acpi_processor_remove().
Rename acpi_processor_post_eject() acpi_processor_remove_possible(), and
check the _STA before calling.
Adding the function prototype for arch_unregister_cpu() allows the
preprocessor guards to be removed.
After this change CPUs will remain registered and visible to
user-space as offline if buggy firmware triggers an eject-request,
but doesn't clear the corresponding _STA bits after _EJ0 has been
called.
Signed-off-by: James Morse <james.morse at arm.com>
Tested-by: Miguel Luis <miguel.luis at oracle.com>
Tested-by: Vishnu Pajjuri <vishnu at os.amperecomputing.com>
Tested-by: Jianyong Wu <jianyong.wu at arm.com>
---
Changes since RFC v3:
* Move IS_ENABLED(CONFIG_ACPI_HOTPLUG_PRESENT_CPU) into separate patch.
Outstanding comments:
https://lore.kernel.org/r/20230914153110.00003e38@Huawei.com
https://lore.kernel.org/r/518859b1-64a9-d723-963c-56c7f6fc2da1@redhat.com
This contains a repeat of the IS_ENABLED() issue which we don't think
is a problem - but there is another issue mentioned in that comment.
---
drivers/acpi/acpi_processor.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
index 01c460881662..19fceb3ec4e2 100644
--- a/drivers/acpi/acpi_processor.c
+++ b/drivers/acpi/acpi_processor.c
@@ -458,16 +458,13 @@ static int acpi_processor_add(struct acpi_device *device,
}
/* Removal */
-static void acpi_processor_post_eject(struct acpi_device *device)
+static void acpi_processor_make_not_present(struct acpi_device *device)
{
struct acpi_processor *pr;
if (!IS_ENABLED(CONFIG_ACPI_HOTPLUG_PRESENT_CPU))
return;
- if (!device || !acpi_driver_data(device))
- return;
-
pr = acpi_driver_data(device);
if (pr->id >= nr_cpu_ids)
goto out;
@@ -504,6 +501,29 @@ static void acpi_processor_post_eject(struct acpi_device *device)
kfree(pr);
}
+static void acpi_processor_post_eject(struct acpi_device *device)
+{
+ struct acpi_processor *pr;
+ unsigned long long sta;
+ acpi_status status;
+
+ if (!device)
+ return;
+
+ pr = acpi_driver_data(device);
+ if (!pr || pr->id >= nr_cpu_ids || invalid_phys_cpuid(pr->phys_id))
+ return;
+
+ status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
+ if (ACPI_FAILURE(status))
+ return;
+
+ if (cpu_present(pr->id) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
+ acpi_processor_make_not_present(device);
+ return;
+ }
+}
+
#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
bool __init processor_physically_present(acpi_handle handle)
{
--
2.30.2
More information about the linux-riscv
mailing list