From c5e4d05db8602acebb532a393f10fb4cc4761467 Mon Sep 17 00:00:00 2001 From: Michal Wilczynski Date: Mon, 10 Jul 2023 17:03:31 +0300 Subject: ACPI: processor: Refactor arch_acpi_set_pdc_bits() The capabilities buffer modified by the arch_acpi_set_pdc_bits() is not _PDC-specific, as it can be used by _OSC too. Change the name of that function to better reflect its independence from _PDC and make it take the capabilities buffer address as the argument directly, without any offset, as _OSC and _PDC use different capabilities buffer offsets. No intentional functional impact. Suggested-by: Rafael J. Wysocki Signed-off-by: Michal Wilczynski Reviewed-by: Andy Shevchenko [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/acpi.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/x86/include') diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 8eb74cf386db..6a498d1781e7 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -100,23 +100,23 @@ static inline bool arch_has_acpi_pdc(void) c->x86_vendor == X86_VENDOR_CENTAUR); } -static inline void arch_acpi_set_pdc_bits(u32 *buf) +static inline void arch_acpi_set_proc_cap_bits(u32 *cap) { struct cpuinfo_x86 *c = &cpu_data(0); - buf[2] |= ACPI_PDC_C_CAPABILITY_SMP; + *cap |= ACPI_PDC_C_CAPABILITY_SMP; if (cpu_has(c, X86_FEATURE_EST)) - buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; + *cap |= ACPI_PDC_EST_CAPABILITY_SWSMP; if (cpu_has(c, X86_FEATURE_ACPI)) - buf[2] |= ACPI_PDC_T_FFH; + *cap |= ACPI_PDC_T_FFH; /* * If mwait/monitor is unsupported, C2/C3_FFH will be disabled */ if (!cpu_has(c, X86_FEATURE_MWAIT)) - buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); + *cap &= ~(ACPI_PDC_C_C2C3_FFH); } static inline bool acpi_has_cpu_in_madt(void) -- cgit v1.2.3 From c9e6c5e64f0c00612dc429bc401da0ea673e5130 Mon Sep 17 00:00:00 2001 From: Michal Wilczynski Date: Mon, 10 Jul 2023 17:03:32 +0300 Subject: ACPI: processor: Rename ACPI_PDC symbols The prefix in the names of the ACPI_PDC symbols suggests that they are only relevant for _PDC, but in fact they can also be used in the _OSC. Change that prefix to a more generic ACPI_PROC_CAP that will better reflect the purpose of those symbols as they represent bits in a general processor capabilities buffer. Rename pdc_intel.h to proc_cap_intel.h to follow the change of the symbol name prefix. No intentional functional impact. Suggested-by: Rafael J. Wysocki Signed-off-by: Michal Wilczynski [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- arch/ia64/include/asm/acpi.h | 4 ++-- arch/x86/include/asm/acpi.h | 11 ++++++----- arch/x86/xen/enlighten_pv.c | 8 ++++---- drivers/acpi/processor_pdc.c | 2 +- include/acpi/pdc_intel.h | 36 ------------------------------------ include/acpi/proc_cap_intel.h | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 52 insertions(+), 48 deletions(-) delete mode 100644 include/acpi/pdc_intel.h create mode 100644 include/acpi/proc_cap_intel.h (limited to 'arch/x86/include') diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 43797cb44383..58500a964238 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -11,7 +11,7 @@ #ifdef __KERNEL__ -#include +#include #include #include @@ -71,7 +71,7 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; static inline bool arch_has_acpi_pdc(void) { return true; } static inline void arch_acpi_set_proc_cap_bits(u32 *cap) { - *cap |= ACPI_PDC_EST_CAPABILITY_SMP; + *cap |= ACPI_PROC_CAP_EST_CAPABILITY_SMP; } #ifdef CONFIG_ACPI_NUMA diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 6a498d1781e7..ce5ad6a496e6 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -6,7 +6,7 @@ * Copyright (C) 2001 Paul Diefenbaugh * Copyright (C) 2001 Patrick Mochel */ -#include +#include #include #include @@ -104,19 +104,20 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap) { struct cpuinfo_x86 *c = &cpu_data(0); - *cap |= ACPI_PDC_C_CAPABILITY_SMP; + *cap |= ACPI_PROC_CAP_C_CAPABILITY_SMP; if (cpu_has(c, X86_FEATURE_EST)) - *cap |= ACPI_PDC_EST_CAPABILITY_SWSMP; + *cap |= ACPI_PROC_CAP_EST_CAPABILITY_SWSMP; if (cpu_has(c, X86_FEATURE_ACPI)) - *cap |= ACPI_PDC_T_FFH; + *cap |= ACPI_PROC_CAP_T_FFH; /* * If mwait/monitor is unsupported, C2/C3_FFH will be disabled */ if (!cpu_has(c, X86_FEATURE_MWAIT)) - *cap &= ~(ACPI_PDC_C_C2C3_FFH); + *cap &= ~(ACPI_PROC_CAP_C_C2C3_FFH); + } static inline bool acpi_has_cpu_in_madt(void) diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 93b658248d01..a3864e2167a8 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -79,7 +79,7 @@ #ifdef CONFIG_ACPI #include #include -#include +#include #include #include #endif @@ -288,17 +288,17 @@ static bool __init xen_check_mwait(void) native_cpuid(&ax, &bx, &cx, &dx); - /* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so, + /* Ask the Hypervisor whether to clear ACPI_PROC_CAP_C_C2C3_FFH. If so, * don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3. */ buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; - buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP); + buf[2] = (ACPI_PROC_CAP_C_CAPABILITY_SMP | ACPI_PROC_CAP_EST_CAPABILITY_SWSMP); set_xen_guest_handle(op.u.set_pminfo.pdc, buf); if ((HYPERVISOR_platform_op(&op) == 0) && - (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) { + (buf[2] & (ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH))) { cpuid_leaf5_ecx_val = cx; cpuid_leaf5_edx_val = dx; } diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 9e7b5ddb9ec2..7948b5d41907 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -21,7 +21,7 @@ static void acpi_set_pdc_bits(u32 *buf) buf[1] = 1; /* Enable coordination with firmware's _TSD info */ - buf[2] = ACPI_PDC_SMP_T_SWCOORD; + buf[2] = ACPI_PROC_CAP_SMP_T_SWCOORD; /* Twiddle arch-specific bits needed for _PDC */ arch_acpi_set_proc_cap_bits(&buf[2]); diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h deleted file mode 100644 index 967c552d1cd3..000000000000 --- a/include/acpi/pdc_intel.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -/* _PDC bit definition for Intel processors */ - -#ifndef __PDC_INTEL_H__ -#define __PDC_INTEL_H__ - -#define ACPI_PDC_P_FFH (0x0001) -#define ACPI_PDC_C_C1_HALT (0x0002) -#define ACPI_PDC_T_FFH (0x0004) -#define ACPI_PDC_SMP_C1PT (0x0008) -#define ACPI_PDC_SMP_C2C3 (0x0010) -#define ACPI_PDC_SMP_P_SWCOORD (0x0020) -#define ACPI_PDC_SMP_C_SWCOORD (0x0040) -#define ACPI_PDC_SMP_T_SWCOORD (0x0080) -#define ACPI_PDC_C_C1_FFH (0x0100) -#define ACPI_PDC_C_C2C3_FFH (0x0200) -#define ACPI_PDC_SMP_P_HWCOORD (0x0800) - -#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ - ACPI_PDC_C_C1_HALT | \ - ACPI_PDC_P_FFH) - -#define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ - ACPI_PDC_C_C1_HALT | \ - ACPI_PDC_SMP_P_SWCOORD | \ - ACPI_PDC_SMP_P_HWCOORD | \ - ACPI_PDC_P_FFH) - -#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ - ACPI_PDC_SMP_C1PT | \ - ACPI_PDC_C_C1_HALT | \ - ACPI_PDC_C_C1_FFH | \ - ACPI_PDC_C_C2C3_FFH) - -#endif /* __PDC_INTEL_H__ */ diff --git a/include/acpi/proc_cap_intel.h b/include/acpi/proc_cap_intel.h new file mode 100644 index 000000000000..57e5e2628abb --- /dev/null +++ b/include/acpi/proc_cap_intel.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Vendor specific processor capabilities bit definition + * for Intel processors. Those bits are used to convey OSPM + * power management capabilities to the platform. + */ + +#ifndef __PROC_CAP_INTEL_H__ +#define __PROC_CAP_INTEL_H__ + +#define ACPI_PROC_CAP_P_FFH (0x0001) +#define ACPI_PROC_CAP_C_C1_HALT (0x0002) +#define ACPI_PROC_CAP_T_FFH (0x0004) +#define ACPI_PROC_CAP_SMP_C1PT (0x0008) +#define ACPI_PROC_CAP_SMP_C2C3 (0x0010) +#define ACPI_PROC_CAP_SMP_P_SWCOORD (0x0020) +#define ACPI_PROC_CAP_SMP_C_SWCOORD (0x0040) +#define ACPI_PROC_CAP_SMP_T_SWCOORD (0x0080) +#define ACPI_PROC_CAP_C_C1_FFH (0x0100) +#define ACPI_PROC_CAP_C_C2C3_FFH (0x0200) +#define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800) + +#define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \ + ACPI_PROC_CAP_C_C1_HALT | \ + ACPI_PROC_CAP_P_FFH) + +#define ACPI_PROC_CAP_EST_CAPABILITY_SWSMP (ACPI_PROC_CAP_SMP_C1PT | \ + ACPI_PROC_CAP_C_C1_HALT | \ + ACPI_PROC_CAP_SMP_P_SWCOORD | \ + ACPI_PROC_CAP_SMP_P_HWCOORD | \ + ACPI_PROC_CAP_P_FFH) + +#define ACPI_PROC_CAP_C_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C2C3 | \ + ACPI_PROC_CAP_SMP_C1PT | \ + ACPI_PROC_CAP_C_C1_HALT | \ + ACPI_PROC_CAP_C_C1_FFH | \ + ACPI_PROC_CAP_C_C2C3_FFH) + +#endif /* __PROC_CAP_INTEL_H__ */ -- cgit v1.2.3 From 4f37ab5e05df9a30d64663266c7f4ba3a1407c68 Mon Sep 17 00:00:00 2001 From: Michal Wilczynski Date: Mon, 10 Jul 2023 17:03:33 +0300 Subject: ACPI: processor: Clear C_C2C3_FFH and C_C1_FFH in arch_acpi_set_proc_cap_bits() Currently arch_acpi_set_proc_cap_bits() clears ACPI_PDC_C_C2C3_FFH bit in case MWAIT instruction is not supported. It should also clear ACPI_PDC_C_C1_FFH, as when MWAIT is not supported, C1 is entered by executing the HLT instruction. Quote from the C_C1_FFH description: "If set, OSPM is capable of performing native C State instructions (beyond halt) for the C1 handler in multi-processor configurations". As without MWAIT there is no native C-state instructions beyond HALT, this bit should be toggled off." Clear ACPI_PDC_C_C1_FFH and ACPI_PDC_C_C2C3_FFH in arch_acpi_set_proc_cap_bits() in case MWAIT is not supported or overridden. Remove setting those bits from the processor_pdc.c code. Suggested-by: Rafael J. Wysocki Signed-off-by: Michal Wilczynski [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/acpi.h | 9 +++++---- drivers/acpi/processor_pdc.c | 14 -------------- 2 files changed, 5 insertions(+), 18 deletions(-) (limited to 'arch/x86/include') diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index ce5ad6a496e6..d615238bcd78 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -113,11 +113,12 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap) *cap |= ACPI_PROC_CAP_T_FFH; /* - * If mwait/monitor is unsupported, C2/C3_FFH will be disabled + * If mwait/monitor is unsupported, C_C1_FFH and + * C2/C3_FFH will be disabled. */ - if (!cpu_has(c, X86_FEATURE_MWAIT)) - *cap &= ~(ACPI_PROC_CAP_C_C2C3_FFH); - + if (!cpu_has(c, X86_FEATURE_MWAIT) || + boot_option_idle_override == IDLE_NOMWAIT) + *cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH); } static inline bool acpi_has_cpu_in_madt(void) diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 7948b5d41907..3c6035262dc2 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -74,20 +74,6 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) { acpi_status status = AE_OK; - if (boot_option_idle_override == IDLE_NOMWAIT) { - /* - * If mwait is disabled for CPU C-states, the C2C3_FFH access - * mode will be disabled in the parameter of _PDC object. - * Of course C1_FFH access mode will also be disabled. - */ - union acpi_object *obj; - u32 *buffer = NULL; - - obj = pdc_in->pointer; - buffer = (u32 *)(obj->buffer.pointer); - buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); - - } status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); if (ACPI_FAILURE(status)) -- cgit v1.2.3 From b9e8d0168a7a85e05d031130b247099018e2194e Mon Sep 17 00:00:00 2001 From: Michal Wilczynski Date: Mon, 10 Jul 2023 17:03:34 +0300 Subject: ACPI: processor: Set CAP_SMP_T_SWCOORD in arch_acpi_set_proc_cap_bits() Currently, ACPI_PROC_CAP_SMP_T_SWCOORD is set in acpi_set_pdc_bits(), but it is not _PDC-specific. It should be set along with the other processor capability bits. Move the setting of ACPI_PROC_CAP_SMP_T_SWCOORD to arch_acpi_set_proc_cap_bits(). Suggested-by: Rafael J. Wysocki Signed-off-by: Michal Wilczynski [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/acpi.h | 3 +++ drivers/acpi/processor_pdc.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/x86/include') diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index d615238bcd78..6f6752a2ea36 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -106,6 +106,9 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap) *cap |= ACPI_PROC_CAP_C_CAPABILITY_SMP; + /* Enable coordination with firmware's _TSD info */ + *cap |= ACPI_PROC_CAP_SMP_T_SWCOORD; + if (cpu_has(c, X86_FEATURE_EST)) *cap |= ACPI_PROC_CAP_EST_CAPABILITY_SWSMP; diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 3c6035262dc2..1a8591e9a9bf 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -20,9 +20,6 @@ static void acpi_set_pdc_bits(u32 *buf) buf[0] = ACPI_PDC_REVISION_ID; buf[1] = 1; - /* Enable coordination with firmware's _TSD info */ - buf[2] = ACPI_PROC_CAP_SMP_T_SWCOORD; - /* Twiddle arch-specific bits needed for _PDC */ arch_acpi_set_proc_cap_bits(&buf[2]); } -- cgit v1.2.3 From 5ba30be7fd6e3fdff1e0b01f24173a5e6a3183b2 Mon Sep 17 00:00:00 2001 From: Michal Wilczynski Date: Mon, 10 Jul 2023 17:03:35 +0300 Subject: ACPI: processor: Introduce acpi_processor_osc() The processor _OSC method is already used for a workaround introduced in commit a21211672c9a ("ACPI / processor: Request native thermal interrupt handling via _OSC"), but in accordance with ACPI 6.5 (and earlier), it should be used for negotiating all of the processor capabilities instead of _PDC (which has been deprecated since ACPI 3.0 and got removed from ACPI 6.5 entirely). Create a new callback function called acpi_processor_osc() to be invoked for every processor object and processor device in the ACPI namespace, in analogy with the already existing acpi_hwp_native_thermal_lvt_osc(). Make this function implement the workaround mentioned above and convey all of the OSPM processor support information to the platform firmware by setting all of the appropriate processor capabilities bits before evaluating _OSC for the given processor. For this purpose, make it call arch_acpi_set_proc_cap_bits() and modify the latter to set ACPI_PROC_CAP_COLLAB_PROC_PERF along with the other processor capabilities bits. Suggested-by: Rafael J. Wysocki Signed-off-by: Michal Wilczynski Reviewed-by: Andy Shevchenko [ rjw: Subject and changelog edits, whitespace fixup ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/acpi.h | 3 +++ drivers/acpi/acpi_processor.c | 30 +++++++++++++++++++++++++++++- include/acpi/proc_cap_intel.h | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'arch/x86/include') diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 6f6752a2ea36..6c3af9486153 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -115,6 +115,9 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap) if (cpu_has(c, X86_FEATURE_ACPI)) *cap |= ACPI_PROC_CAP_T_FFH; + if (cpu_has(c, X86_FEATURE_HWP)) + *cap |= ACPI_PROC_CAP_COLLAB_PROC_PERF; + /* * If mwait/monitor is unsupported, C_C1_FFH and * C2/C3_FFH will be disabled. diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index ebb4efd3d0aa..163bd3d52acd 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -559,13 +559,41 @@ bool __init processor_physically_present(acpi_handle handle) return !invalid_logical_cpuid(cpuid); } +/* vendor specific UUID indicating an Intel platform */ +static u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; static bool acpi_hwp_native_thermal_lvt_set; + +static acpi_status __init acpi_processor_osc(acpi_handle handle, u32 lvl, + void *context, void **rv) +{ + u32 capbuf[2] = {}; + struct acpi_osc_context osc_context = { + .uuid_str = sb_uuid_str, + .rev = 1, + .cap.length = 8, + .cap.pointer = capbuf, + }; + acpi_status status; + + if (!processor_physically_present(handle)) + return AE_OK; + + arch_acpi_set_proc_cap_bits(&capbuf[OSC_SUPPORT_DWORD]); + + status = acpi_run_osc(handle, &osc_context); + if (ACPI_FAILURE(status)) + return status; + + kfree(osc_context.ret.pointer); + + return AE_OK; +} + static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, u32 lvl, void *context, void **rv) { - u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; u32 capbuf[2]; struct acpi_osc_context osc_context = { .uuid_str = sb_uuid_str, diff --git a/include/acpi/proc_cap_intel.h b/include/acpi/proc_cap_intel.h index 57e5e2628abb..ddcdc41d6c3e 100644 --- a/include/acpi/proc_cap_intel.h +++ b/include/acpi/proc_cap_intel.h @@ -19,6 +19,7 @@ #define ACPI_PROC_CAP_C_C1_FFH (0x0100) #define ACPI_PROC_CAP_C_C2C3_FFH (0x0200) #define ACPI_PROC_CAP_SMP_P_HWCOORD (0x0800) +#define ACPI_PROC_CAP_COLLAB_PROC_PERF (0x1000) #define ACPI_PROC_CAP_EST_CAPABILITY_SMP (ACPI_PROC_CAP_SMP_C1PT | \ ACPI_PROC_CAP_C_C1_HALT | \ -- cgit v1.2.3