On Wed, 13 Dec 2023 12:50:54 +0000 Russell King (Oracle) <rmk+kernel@xxxxxxxxxxxxxxx> wrote: > From: James Morse <james.morse@xxxxxxx> > > Platform firmware can disabled a CPU, or make it not-present by making > an eject-request notification, then waiting for the os to make it offline OS > and call _EJx. After the firmware updates _STA with the new status. > > Not all operating systems support this. For arm64 making CPUs not-present > has never been supported. For all ACPI architectures, making CPUs disabled > has recently been added. Firmware can't know what the OS has support for. > > Add two new _OSC bits to advertise whether the OS supports the _STA enabled > or present bits being toggled for CPUs. This will be important for arm64 > if systems that support physical CPU hotplug ever appear as arm64 linux > doesn't currently support this, so firmware shouldn't try. > > Advertising this support to firmware is useful for cloud orchestrators > to know whether they can scale a particular VM by adding CPUs. > > Signed-off-by: James Morse <james.morse@xxxxxxx> > Tested-by: Miguel Luis <miguel.luis@xxxxxxxxxx> > Tested-by: Vishnu Pajjuri <vishnu@xxxxxxxxxxxxxxxxxxxxxx> > Tested-by: Jianyong Wu <jianyong.wu@xxxxxxx> I'm very much in favor of this _OSC but it hasn't been accepted yet I think... https://bugzilla.tianocore.org/show_bug.cgi?id=4481 Jose? Github suggests you are the proposer on this. btw v4 looks ok but v5 in the tianocore github seems to have lost the actual OSC part. Jonathan > --- > I'm assuming Loongarch machines do not support physical CPU hotplug. > > Changes since RFC v3: > * Drop ia64 changes > * Update James' comment below "---" to remove reference to ia64 > > Outstanding comment: > https://lore.kernel.org/r/20230914175021.000018fd@xxxxxxxxxx > --- > arch/x86/Kconfig | 1 + > drivers/acpi/Kconfig | 9 +++++++++ > drivers/acpi/acpi_processor.c | 14 +++++++++++++- > drivers/acpi/bus.c | 16 ++++++++++++++++ > include/linux/acpi.h | 4 ++++ > 5 files changed, 43 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index 64fc7c475ab0..33fc4dcd950c 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -60,6 +60,7 @@ config X86 > select ACPI_LEGACY_TABLES_LOOKUP if ACPI > select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI > select ACPI_HOTPLUG_PRESENT_CPU if ACPI_PROCESSOR && HOTPLUG_CPU > + select ACPI_HOTPLUG_IGNORE_OSC if ACPI && HOTPLUG_CPU > select ARCH_32BIT_OFF_T if X86_32 > select ARCH_CLOCKSOURCE_INIT > select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE > diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig > index 9c5a43d0aff4..020e7c0ab985 100644 > --- a/drivers/acpi/Kconfig > +++ b/drivers/acpi/Kconfig > @@ -311,6 +311,15 @@ config ACPI_HOTPLUG_PRESENT_CPU > depends on ACPI_PROCESSOR && HOTPLUG_CPU > select ACPI_CONTAINER > > +config ACPI_HOTPLUG_IGNORE_OSC > + bool > + depends on ACPI_HOTPLUG_PRESENT_CPU > + help > + Ignore whether firmware acknowledged support for toggling the CPU > + present bit in _STA. Some architectures predate the _OSC bits, so > + firmware doesn't know to do this. > + > + > config ACPI_PROCESSOR_AGGREGATOR > tristate "Processor Aggregator" > depends on ACPI_PROCESSOR > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c > index ea12e70dfd39..5bb207a7a1dd 100644 > --- a/drivers/acpi/acpi_processor.c > +++ b/drivers/acpi/acpi_processor.c > @@ -182,6 +182,18 @@ static void __init acpi_pcc_cpufreq_init(void) > static void __init acpi_pcc_cpufreq_init(void) {} > #endif /* CONFIG_X86 */ > > +static bool acpi_processor_hotplug_present_supported(void) > +{ > + if (!IS_ENABLED(CONFIG_ACPI_HOTPLUG_PRESENT_CPU)) > + return false; > + > + /* x86 systems pre-date the _OSC bit */ > + if (IS_ENABLED(CONFIG_ACPI_HOTPLUG_IGNORE_OSC)) > + return true; > + > + return osc_sb_hotplug_present_support_acked; > +} > + > /* Initialization */ > static int acpi_processor_make_present(struct acpi_processor *pr) > { > @@ -189,7 +201,7 @@ static int acpi_processor_make_present(struct acpi_processor *pr) > acpi_status status; > int ret; > > - if (!IS_ENABLED(CONFIG_ACPI_HOTPLUG_PRESENT_CPU)) { > + if (!acpi_processor_hotplug_present_supported()) { > pr_err_once("Changing CPU present bit is not supported\n"); > return -ENODEV; > } > diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c > index 72e64c0718c9..7122450739d6 100644 > --- a/drivers/acpi/bus.c > +++ b/drivers/acpi/bus.c > @@ -298,6 +298,13 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed); > > bool osc_sb_cppc2_support_acked; > > +/* > + * ACPI 6.? Proposed Operating System Capabilities for modifying CPU > + * present/enable. > + */ > +bool osc_sb_hotplug_enabled_support_acked; > +bool osc_sb_hotplug_present_support_acked; > + > static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; > static void acpi_bus_osc_negotiate_platform_control(void) > { > @@ -346,6 +353,11 @@ static void acpi_bus_osc_negotiate_platform_control(void) > > if (!ghes_disable) > capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT; > + > + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_ENABLED_SUPPORT; > + if (IS_ENABLED(CONFIG_ACPI_HOTPLUG_PRESENT_CPU)) > + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_PRESENT_SUPPORT; > + > if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) > return; > > @@ -383,6 +395,10 @@ static void acpi_bus_osc_negotiate_platform_control(void) > capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT; > osc_cpc_flexible_adr_space_confirmed = > capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE; > + osc_sb_hotplug_enabled_support_acked = > + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_HOTPLUG_ENABLED_SUPPORT; > + osc_sb_hotplug_present_support_acked = > + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_HOTPLUG_PRESENT_SUPPORT; > } > > kfree(context.ret.pointer); > diff --git a/include/linux/acpi.h b/include/linux/acpi.h > index 00be66683505..c572abac803c 100644 > --- a/include/linux/acpi.h > +++ b/include/linux/acpi.h > @@ -559,12 +559,16 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); > #define OSC_SB_NATIVE_USB4_SUPPORT 0x00040000 > #define OSC_SB_PRM_SUPPORT 0x00200000 > #define OSC_SB_FFH_OPR_SUPPORT 0x00400000 > +#define OSC_SB_HOTPLUG_ENABLED_SUPPORT 0x00800000 > +#define OSC_SB_HOTPLUG_PRESENT_SUPPORT 0x01000000 > > extern bool osc_sb_apei_support_acked; > extern bool osc_pc_lpi_support_confirmed; > extern bool osc_sb_native_usb4_support_confirmed; > extern bool osc_sb_cppc2_support_acked; > extern bool osc_cpc_flexible_adr_space_confirmed; > +extern bool osc_sb_hotplug_enabled_support_acked; > +extern bool osc_sb_hotplug_present_support_acked; > > /* USB4 Capabilities */ > #define OSC_USB_USB3_TUNNELING 0x00000001