Hi Salil,
On 09/09/2022 15:53, Salil Mehta wrote:
From: James Morse [mailto:james.morse@arm.com] Sent: Wednesday, August 31, 2022 12:09 PM To: linaro-open-discussions@op-lists.linaro.org Cc: Salil Mehta salil.mehta@huawei.com; james.morse@arm.com; lorenzo.pieralisi@linaro.org; Jean-Philippe Brucker jean-philippe@linaro.org Subject: [RFC PATCH v0.1 22/25] ACPI: add support to register CPUs based on the _STA enabled bit
acpi_processor_get_info() registers all present CPUs. Registering a CPU is what creates the sysfs entries and triggers the udev notifications.
arm64 virtual machines that support 'virtual cpu hotplug' use the enabled bit to indicate whether the CPU can be brought online, as the existing ACPI tables require all hardware to be described and present.
If firmware describes a CPU as present, but disabled, skip the registration. Such CPUs are present, but can't be brought online for whatever reason. (e.g. firmware/hypervisor policy).
Once firmware sets the enabled bit, the CPU can be registered and brought online by user-space. Online CPUs, or CPUs that are missing an _STA method must always be registered.
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 1bd6e4b8ab66..42521d89c378 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -194,6 +194,32 @@ static int acpi_processor_make_present(struct acpi_processor *pr) return ret; }
+static int acpi_processor_make_enabled(struct acpi_processor *pr) +{
- unsigned long long sta;
- acpi_status status;
- bool present, enabled;
- if (!acpi_has_method(pr->handle, "_STA"))
return arch_register_cpu(pr->id);
- status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
- if (ACPI_FAILURE(status))
return -ENODEV;
- present = sta & ACPI_STA_DEVICE_PRESENT;
- enabled = sta & ACPI_STA_DEVICE_ENABLED;
- if (cpu_online(pr->id) && (!present || !enabled)) {
pr_err_once(FW_BUG "CPU %u is online, but described as not present or
disabled!\n", pr->id);
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
- } else if (!present || !enabled) {
return -ENODEV;
- }
This change and setting all possible cpus as *present* in smp_prepare_cpus() will always cause all present == possible in the guest kernel.
This is quite deliberate. I don't want to redefine present without a machine that actually supports hotplug/package-hotadd. This stuff is the tip of an ill-defined iceberg in the ACPI spec. Once there is hardware that supports this, we will have a better idea of what needs changing. Until then: everything described by ACPI must be present.
I think we can avoid that by the trick which Jean-Phillipe exploited in his patch-set[1] sent earlier last year.
That was the other side of this: https://gitlab.arm.com/linux-arm/linux-jm/-/commit/3106cccf5b9f01f44789b748a...
This was an attempt to do all this without changes to the ACPI spec - it doesn't touch the present cpumask.
[..]
This shall ensure that we correctly reflect only present vcpus to the linux kernel although the sizing and initialization of the GICC/GICR would have already happened for the complete set for possible vcpus i.e. the ones with
[1] _STA[0] is set & _STA[1] bit is set and [2] Either GICC_flag_Intf_Flag.Enabled set OR GICC_flag.online_capable set
so effectively we are only deferring populating the cpu present mask for the disabled cpus but which are now online capable(or Hotplug capable in future?)
What is the user observable effect of the kernel knowing this CPUs are really present?
The intention of this series is to do this as pure policy.
I anticipate pressure on the "use the MADT GICR" line, even though ACPI doesn't say anything about the presence of MADT GICC's redistributor entry. If this happens, we'd depend on present meaning present.
All the hotplug/package-hotadd machinery is triggered by udev. We don't need to hack the cpu present mask to make that work.
Question: Q1: Current acpi_processor.c code is not using ACPI_STA_DEVICE_{ENABLED, UI} bits. Could it break other architecture if we use these bits but some of their legacy devices or firmware does not initialize these bits to their defaults?
Almost certainly! I'm pretty confident some vendors generate their ACPI tables using markov-models. (It boots! Ship it!)
The approach that used the UI bit to mean sysfs had to be hidden behind a Kconfig symbol, which is only marginally better than #ifdef CONFIG_ARM64.
This new version walks a fine line described in the cover-letter: any platform with firmware tables that get this wrong should get the same user-experience as there is no policy enforcement on x86, so the !online_capable CPUs can be detected as being online, and the policy stuff gets ignored.
I don't want to bring the UI bi back, as that would mean bringing back the #ifdeffery. I'm pretty sure that bit was only for Windows-95!
Thanks,
James
I am trying to test this change. If you don't have any apprehensions then we can include this change (both at the kernel and qemu) as well. Thoughts?