[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <E1qvJAq-00AqRS-7i@rmk-PC.armlinux.org.uk>
Date: Tue, 24 Oct 2023 16:18:28 +0100
From: Russell King (Oracle) <rmk+kernel@...linux.org.uk>
To: linux-pm@...r.kernel.org, loongarch@...ts.linux.dev,
linux-acpi@...r.kernel.org, linux-arch@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
linux-riscv@...ts.infradead.org, kvmarm@...ts.linux.dev,
x86@...nel.org, linux-csky@...r.kernel.org,
linux-doc@...r.kernel.org, linux-ia64@...r.kernel.org,
linux-parisc@...r.kernel.org
Cc: Salil Mehta <salil.mehta@...wei.com>,
Jean-Philippe Brucker <jean-philippe@...aro.org>,
jianyong.wu@....com, justin.he@....com,
James Morse <james.morse@....com>,
"Rafael J. Wysocki" <rafael@...nel.org>,
Len Brown <lenb@...nel.org>
Subject: [PATCH 27/39] ACPI: Check _STA present bit before making CPUs not
present
From: James Morse <james.morse@....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@....com>
---
drivers/acpi/acpi_processor.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
index b6f5005985c3..19fceb3ec4e2 100644
--- a/drivers/acpi/acpi_processor.c
+++ b/drivers/acpi/acpi_processor.c
@@ -457,13 +457,12 @@ static int acpi_processor_add(struct acpi_device *device,
return result;
}
-#ifdef CONFIG_ACPI_HOTPLUG_PRESENT_CPU
/* 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 (!device || !acpi_driver_data(device))
+ if (!IS_ENABLED(CONFIG_ACPI_HOTPLUG_PRESENT_CPU))
return;
pr = acpi_driver_data(device);
@@ -501,7 +500,29 @@ static void acpi_processor_post_eject(struct acpi_device *device)
free_cpumask_var(pr->throttling.shared_cpu_map);
kfree(pr);
}
-#endif /* CONFIG_ACPI_HOTPLUG_PRESENT_CPU */
+
+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)
@@ -626,9 +647,7 @@ static const struct acpi_device_id processor_device_ids[] = {
static struct acpi_scan_handler processor_handler = {
.ids = processor_device_ids,
.attach = acpi_processor_add,
-#ifdef CONFIG_ACPI_HOTPLUG_PRESENT_CPU
.post_eject = acpi_processor_post_eject,
-#endif
.hotplug = {
.enabled = true,
},
--
2.30.2
Powered by blists - more mailing lists