From 601c61159791f4c80fe8b3d0b221a709532fbae9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 8 May 2016 19:20:00 +0200 Subject: [PATCH] 4.4-stable patches added patches: acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch --- ...-thermal-interrupt-handling-via-_osc.patch | 163 ++++++++++++++++++ ...kl-fix-dmc-load-on-skylake-j0-and-k0.patch | 36 ++++ ...ix-and-improve-string_get_size-tests.patch | 119 +++++++++++++ queue-4.4/series | 3 + 4 files changed, 321 insertions(+) create mode 100644 queue-4.4/acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch create mode 100644 queue-4.4/drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch create mode 100644 queue-4.4/lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch diff --git a/queue-4.4/acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch b/queue-4.4/acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch new file mode 100644 index 00000000000..6f9512b6e2c --- /dev/null +++ b/queue-4.4/acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch @@ -0,0 +1,163 @@ +From a21211672c9a1d730a39aa65d4a5b3414700adfb Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Wed, 23 Mar 2016 21:07:39 -0700 +Subject: ACPI / processor: Request native thermal interrupt handling via _OSC + +From: Srinivas Pandruvada + +commit a21211672c9a1d730a39aa65d4a5b3414700adfb upstream. + +There are several reports of freeze on enabling HWP (Hardware PStates) +feature on Skylake-based systems by the Intel P-states driver. The root +cause is identified as the HWP interrupts causing BIOS code to freeze. + +HWP interrupts use the thermal LVT which can be handled by Linux +natively, but on the affected Skylake-based systems SMM will respond +to it by default. This is a problem for several reasons: + - On the affected systems the SMM thermal LVT handler is broken (it + will crash when invoked) and a BIOS update is necessary to fix it. + - With thermal interrupt handled in SMM we lose all of the reporting + features of the arch/x86/kernel/cpu/mcheck/therm_throt driver. + - Some thermal drivers like x86-package-temp depend on the thermal + threshold interrupts signaled via the thermal LVT. + - The HWP interrupts are useful for debugging and tuning + performance (if the kernel can handle them). +The native handling of thermal interrupts needs to be enabled +because of that. + +This requires some way to tell SMM that the OS can handle thermal +interrupts. That can be done by using _OSC/_PDC in processor +scope very early during ACPI initialization. + +The meaning of _OSC/_PDC bit 12 in processor scope is whether or +not the OS supports native handling of interrupts for Collaborative +Processor Performance Control (CPPC) notifications. Since on +HWP-capable systems CPPC is a firmware interface to HWP, setting +this bit effectively tells the firmware that the OS will handle +thermal interrupts natively going forward. + +For details on _OSC/_PDC refer to: +http://www.intel.com/content/www/us/en/standards/processor-vendor-specific-acpi-specification.html + +To implement the _OSC/_PDC handshake as described, introduce a new +function, acpi_early_processor_osc(), that walks the ACPI +namespace looking for ACPI processor objects and invokes _OSC for +them with bit 12 in the capabilities buffer set and terminates the +namespace walk on the first success. + +Also modify intel_thermal_interrupt() to clear HWP status bits in +the HWP_STATUS MSR to acknowledge HWP interrupts (which prevents +them from firing continuously). + +Signed-off-by: Srinivas Pandruvada +[ rjw: Subject & changelog, function rename ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/mcheck/therm_throt.c | 3 + + drivers/acpi/acpi_processor.c | 52 +++++++++++++++++++++++++++++++ + drivers/acpi/bus.c | 3 + + drivers/acpi/internal.h | 6 +++ + 4 files changed, 64 insertions(+) + +--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c ++++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c +@@ -385,6 +385,9 @@ static void intel_thermal_interrupt(void + { + __u64 msr_val; + ++ if (static_cpu_has(X86_FEATURE_HWP)) ++ wrmsrl_safe(MSR_HWP_STATUS, 0); ++ + rdmsrl(MSR_IA32_THERM_STATUS, msr_val); + + /* Check for violation of core thermal thresholds*/ +--- a/drivers/acpi/acpi_processor.c ++++ b/drivers/acpi/acpi_processor.c +@@ -491,6 +491,58 @@ static void acpi_processor_remove(struct + } + #endif /* CONFIG_ACPI_HOTPLUG_CPU */ + ++#ifdef CONFIG_X86 ++static bool acpi_hwp_native_thermal_lvt_set; ++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, ++ .rev = 1, ++ .cap.length = 8, ++ .cap.pointer = capbuf, ++ }; ++ ++ if (acpi_hwp_native_thermal_lvt_set) ++ return AE_CTRL_TERMINATE; ++ ++ capbuf[0] = 0x0000; ++ capbuf[1] = 0x1000; /* set bit 12 */ ++ ++ if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) { ++ if (osc_context.ret.pointer && osc_context.ret.length > 1) { ++ u32 *capbuf_ret = osc_context.ret.pointer; ++ ++ if (capbuf_ret[1] & 0x1000) { ++ acpi_handle_info(handle, ++ "_OSC native thermal LVT Acked\n"); ++ acpi_hwp_native_thermal_lvt_set = true; ++ } ++ } ++ kfree(osc_context.ret.pointer); ++ } ++ ++ return AE_OK; ++} ++ ++void __init acpi_early_processor_osc(void) ++{ ++ if (boot_cpu_has(X86_FEATURE_HWP)) { ++ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ++ ACPI_UINT32_MAX, ++ acpi_hwp_native_thermal_lvt_osc, ++ NULL, NULL, NULL); ++ acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, ++ acpi_hwp_native_thermal_lvt_osc, ++ NULL, NULL); ++ } ++} ++#endif ++ + /* + * The following ACPI IDs are known to be suitable for representing as + * processor devices. +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -1004,6 +1004,9 @@ static int __init acpi_bus_init(void) + goto error1; + } + ++ /* Set capability bits for _OSC under processor scope */ ++ acpi_early_processor_osc(); ++ + /* + * _OSC method may exist in module level code, + * so it must be run after ACPI_FULL_INITIALIZATION +--- a/drivers/acpi/internal.h ++++ b/drivers/acpi/internal.h +@@ -130,6 +130,12 @@ void acpi_early_processor_set_pdc(void); + static inline void acpi_early_processor_set_pdc(void) {} + #endif + ++#ifdef CONFIG_X86 ++void acpi_early_processor_osc(void); ++#else ++static inline void acpi_early_processor_osc(void) {} ++#endif ++ + /* -------------------------------------------------------------------------- + Embedded Controller + -------------------------------------------------------------------------- */ diff --git a/queue-4.4/drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch b/queue-4.4/drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch new file mode 100644 index 00000000000..014f525737d --- /dev/null +++ b/queue-4.4/drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch @@ -0,0 +1,36 @@ +From a41c8882592fb80458959b10e37632ce030b68ca Mon Sep 17 00:00:00 2001 +From: Mat Martineau +Date: Thu, 28 Jan 2016 15:19:23 -0800 +Subject: drm/i915/skl: Fix DMC load on Skylake J0 and K0 + +From: Mat Martineau + +commit a41c8882592fb80458959b10e37632ce030b68ca upstream. + +The driver does not load firmware for unknown steppings, so these new +steppings must be added to the list. + +Cc: Rodrigo Vivi +Signed-off-by: Mat Martineau +Reviewed-by: Rodrigo Vivi +Signed-off-by: Rodrigo Vivi +Link: http://patchwork.freedesktop.org/patch/msgid/1454023163-25469-1-git-send-email-mathew.j.martineau@linux.intel.com +Cc: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_csr.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/intel_csr.c ++++ b/drivers/gpu/drm/i915/intel_csr.c +@@ -180,7 +180,8 @@ struct stepping_info { + static const struct stepping_info skl_stepping_info[] = { + {'A', '0'}, {'B', '0'}, {'C', '0'}, + {'D', '0'}, {'E', '0'}, {'F', '0'}, +- {'G', '0'}, {'H', '0'}, {'I', '0'} ++ {'G', '0'}, {'H', '0'}, {'I', '0'}, ++ {'J', '0'}, {'K', '0'} + }; + + static struct stepping_info bxt_stepping_info[] = { diff --git a/queue-4.4/lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch b/queue-4.4/lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch new file mode 100644 index 00000000000..78479d548b9 --- /dev/null +++ b/queue-4.4/lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch @@ -0,0 +1,119 @@ +From 72676bb53f33fd0ef3a1484fc1ecfd306dc6ff40 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Tue, 2 Feb 2016 16:57:18 -0800 +Subject: lib/test-string_helpers.c: fix and improve string_get_size() tests + +From: Vitaly Kuznetsov + +commit 72676bb53f33fd0ef3a1484fc1ecfd306dc6ff40 upstream. + +Recently added commit 564b026fbd0d ("string_helpers: fix precision loss +for some inputs") fixed precision issues for string_get_size() and broke +tests. + +Fix and improve them: test both STRING_UNITS_2 and STRING_UNITS_10 at a +time, better failure reporting, test small an huge values. + +Fixes: 564b026fbd0d28e9 ("string_helpers: fix precision loss for some inputs") +Signed-off-by: Vitaly Kuznetsov +Cc: Andy Shevchenko +Cc: Rasmus Villemoes +Cc: James Bottomley +Cc: James Bottomley +Cc: "James E.J. Bottomley" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + lib/test-string_helpers.c | 67 +++++++++++++++++++++++++++++++++------------- + 1 file changed, 49 insertions(+), 18 deletions(-) + +--- a/lib/test-string_helpers.c ++++ b/lib/test-string_helpers.c +@@ -327,36 +327,67 @@ out: + } + + #define string_get_size_maxbuf 16 +-#define test_string_get_size_one(size, blk_size, units, exp_result) \ ++#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2) \ + do { \ +- BUILD_BUG_ON(sizeof(exp_result) >= string_get_size_maxbuf); \ +- __test_string_get_size((size), (blk_size), (units), \ +- (exp_result)); \ ++ BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf); \ ++ BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf); \ ++ __test_string_get_size((size), (blk_size), (exp_result10), \ ++ (exp_result2)); \ + } while (0) + + +-static __init void __test_string_get_size(const u64 size, const u64 blk_size, +- const enum string_size_units units, +- const char *exp_result) ++static __init void test_string_get_size_check(const char *units, ++ const char *exp, ++ char *res, ++ const u64 size, ++ const u64 blk_size) + { +- char buf[string_get_size_maxbuf]; +- +- string_get_size(size, blk_size, units, buf, sizeof(buf)); +- if (!memcmp(buf, exp_result, strlen(exp_result) + 1)) ++ if (!memcmp(res, exp, strlen(exp) + 1)) + return; + +- buf[sizeof(buf) - 1] = '\0'; +- pr_warn("Test 'test_string_get_size_one' failed!\n"); +- pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %d\n", ++ res[string_get_size_maxbuf - 1] = '\0'; ++ ++ pr_warn("Test 'test_string_get_size' failed!\n"); ++ pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %s)\n", + size, blk_size, units); +- pr_warn("expected: '%s', got '%s'\n", exp_result, buf); ++ pr_warn("expected: '%s', got '%s'\n", exp, res); ++} ++ ++static __init void __test_string_get_size(const u64 size, const u64 blk_size, ++ const char *exp_result10, ++ const char *exp_result2) ++{ ++ char buf10[string_get_size_maxbuf]; ++ char buf2[string_get_size_maxbuf]; ++ ++ string_get_size(size, blk_size, STRING_UNITS_10, buf10, sizeof(buf10)); ++ string_get_size(size, blk_size, STRING_UNITS_2, buf2, sizeof(buf2)); ++ ++ test_string_get_size_check("STRING_UNITS_10", exp_result10, buf10, ++ size, blk_size); ++ ++ test_string_get_size_check("STRING_UNITS_2", exp_result2, buf2, ++ size, blk_size); + } + + static __init void test_string_get_size(void) + { +- test_string_get_size_one(16384, 512, STRING_UNITS_2, "8.00 MiB"); +- test_string_get_size_one(8192, 4096, STRING_UNITS_10, "32.7 MB"); +- test_string_get_size_one(1, 512, STRING_UNITS_10, "512 B"); ++ /* small values */ ++ test_string_get_size_one(0, 512, "0 B", "0 B"); ++ test_string_get_size_one(1, 512, "512 B", "512 B"); ++ test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB"); ++ ++ /* normal values */ ++ test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB"); ++ test_string_get_size_one(500118192, 512, "256 GB", "238 GiB"); ++ test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB"); ++ ++ /* weird block sizes */ ++ test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB"); ++ ++ /* huge values */ ++ test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB"); ++ test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB"); + } + + static int __init test_string_helpers_init(void) diff --git a/queue-4.4/series b/queue-4.4/series index 71f21baf375..db7b54e4b7e 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -62,3 +62,6 @@ drm-i915-ddi-fix-edp-vdd-handling-during-booting-and-suspend-resume.patch drm-i915-fix-edp-low-vswing-for-broadwell.patch drm-i915-make-rps-ei-thresholds-multiple-of-25-on-snb-bdw.patch drm-i915-fake-hdmi-live-status.patch +acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch +lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch +drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch -- 2.47.3