Commit 362f33cb authored by James Morse's avatar James Morse Committed by liwei
Browse files

ACPI: Add _OSC bits to advertise OS support for toggling CPU present/enabled

maillist inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8XMTL


CVE: NA

---------------------------------

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
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: default avatarJames Morse <james.morse@arm.com>
Tested-by: default avatarMiguel Luis <miguel.luis@oracle.com>
Tested-by: default avatarVishnu Pajjuri <vishnu@os.amperecomputing.com>
Tested-by: default avatarJianyong Wu <jianyong.wu@arm.com>
Signed-off-by: default avatarliwei <liwei728@huawei.com>
parent 308c37e9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,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
+9 −0
Original line number Diff line number Diff line
@@ -310,6 +310,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
+13 −1
Original line number Diff line number Diff line
@@ -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;
	}
+16 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -579,12 +579,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