diff options
-rw-r--r-- | SOURCES/0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch | 25 | ||||
-rw-r--r-- | SOURCES/0001-acpi-proc-idle-skip-dummy-wait.patch | 185 | ||||
-rw-r--r-- | SOURCES/0001-bump-the-sensitivity-of-AMD-SFH.patch | 450 | ||||
-rw-r--r-- | SOURCES/CVE-2024-44961.patch | 140 | ||||
-rw-r--r-- | SOURCES/v2-ally-suspend-fix.patch | 705 | ||||
-rw-r--r-- | SPECS/kernel.spec | 17 |
6 files changed, 653 insertions, 869 deletions
diff --git a/SOURCES/0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch b/SOURCES/0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch deleted file mode 100644 index 26e3ab7..0000000 --- a/SOURCES/0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 9179080ffaaf1d438db6e0a5a37bdf8dafe233a6 Mon Sep 17 00:00:00 2001 -From: Thomas Crider <gloriouseggroll@gmail.com> -Date: Mon, 27 Nov 2023 16:13:13 -0500 -Subject: [PATCH] Set amdgpu.ppfeaturemask=0xffffffff as default - ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -index e06009966..4e791eb8f 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c -@@ -158,7 +158,7 @@ bool enforce_isolation; - * OverDrive(bit 14) disabled by default - * GFX DCS(bit 19) disabled by default - */ --uint amdgpu_pp_feature_mask = 0xfff7bfff; -+uint amdgpu_pp_feature_mask = 0xffffffff; - uint amdgpu_force_long_training; - int amdgpu_lbpw = -1; - int amdgpu_compute_multipipe = -1; --- -2.43.0 - diff --git a/SOURCES/0001-acpi-proc-idle-skip-dummy-wait.patch b/SOURCES/0001-acpi-proc-idle-skip-dummy-wait.patch index eb3cf54..ef562c9 100644 --- a/SOURCES/0001-acpi-proc-idle-skip-dummy-wait.patch +++ b/SOURCES/0001-acpi-proc-idle-skip-dummy-wait.patch @@ -1,125 +1,74 @@ -Processors based on the Zen microarchitecture support IOPORT based deeper -C-states. The idle driver reads the acpi_gbl_FADT.xpm_timer_block.address -in the IOPORT based C-state exit path which is claimed to be a -"Dummy wait op" and has been around since ACPI introduction to Linux -dating back to Andy Grover's Mar 14, 2002 posting [1]. -The comment above the dummy operation was elaborated by Andreas Mohr back -in 2006 in commit b488f02156d3d ("ACPI: restore comment justifying 'extra' -P_LVLx access") [2] where the commit log claims: -"this dummy read was about: STPCLK# doesn't get asserted in time on -(some) chipsets, which is why we need to have a dummy I/O read to delay -further instruction processing until the CPU is fully stopped." - -However, sampling certain workloads with IBS on AMD Zen3 system shows -that a significant amount of time is spent in the dummy op, which -incorrectly gets accounted as C-State residency. A large C-State -residency value can prime the cpuidle governor to recommend a deeper -C-State during the subsequent idle instances, starting a vicious cycle, -leading to performance degradation on workloads that rapidly switch -between busy and idle phases. - -One such workload is tbench where a massive performance degradation can -be observed during certain runs. Following are some statistics gathered -by running tbench with 128 clients, on a dual socket (2 x 64C/128T) Zen3 -system with the baseline kernel, baseline kernel keeping C2 disabled, -and baseline kernel with this patch applied keeping C2 enabled: - -baseline kernel was tip:sched/core at -commit f3dd3f674555 ("sched: Remove the limitation of WF_ON_CPU on -wakelist if wakee cpu is idle") - -Kernel : baseline baseline + C2 disabled baseline + patch - -Min (MB/s) : 2215.06 33072.10 (+1393.05%) 33016.10 (+1390.52%) -Max (MB/s) : 32938.80 34399.10 34774.50 -Median (MB/s) : 32191.80 33476.60 33805.70 -AMean (MB/s) : 22448.55 33649.27 (+49.89%) 33865.43 (+50.85%) -AMean Stddev : 17526.70 680.14 880.72 -AMean CoefVar : 78.07% 2.02% 2.60% - -The data shows there are edge cases that can cause massive regressions -in case of tbench. Profiling the bad runs with IBS shows a significant -amount of time being spent in acpi_idle_do_entry method: - -Overhead Command Shared Object Symbol - 74.76% swapper [kernel.kallsyms] [k] acpi_idle_do_entry - 0.71% tbench [kernel.kallsyms] [k] update_sd_lb_stats.constprop.0 - 0.69% tbench_srv [kernel.kallsyms] [k] update_sd_lb_stats.constprop.0 - 0.49% swapper [kernel.kallsyms] [k] psi_group_change - ... - -Annotation of acpi_idle_do_entry method reveals almost all the time in -acpi_idle_do_entry is spent on the port I/O in wait_for_freeze(): - - 0.14 │ in (%dx),%al # <------ First "in" corresponding to inb(cx->address) - 0.51 │ mov 0x144d64d(%rip),%rax - 0.00 │ test $0x80000000,%eax - │ ↓ jne 62 # <------ Skip if running in guest - 0.00 │ mov 0x19800c3(%rip),%rdx - 99.33 │ in (%dx),%eax # <------ Second "in" corresponding to inl(acpi_gbl_FADT.xpm_timer_block.address) - 0.00 │62: mov -0x8(%rbp),%r12 - 0.00 │ leave - 0.00 │ ← ret - -This overhead is reflected in the C2 residency on the test system where -C2 is an IOPORT based C-State. The total C-state residency reported by -"cpupower idle-info" on CPU0 for good and bad case over the 80s tbench -run is as follows (all numbers are in microseconds): - - Good Run Bad Run - (Baseline) - -POLL: 43338 6231 (-85.62%) -C1 (MWAIT Based): 23576156 363861 (-98.45%) -C2 (IOPORT Based): 10781218 77027280 (+614.45%) - -The larger residency value in bad case leads to the system recommending -C2 state again for subsequent idle instances. The pattern lasts till the -end of the tbench run. Following is the breakdown of "entry_method" -passed to acpi_idle_do_entry during good run and bad run: - - Good Run Bad Run - (Baseline) - -Number of times acpi_idle_do_entry was called: 6149573 6149050 (-0.01%) - |-> Number of times entry_method was "ACPI_CSTATE_FFH": 6141494 88144 (-98.56%) - |-> Number of times entry_method was "ACPI_CSTATE_HALT": 0 0 (+0.00%) - |-> Number of times entry_method was "ACPI_CSTATE_SYSTEMIO": 8079 6060906 (+74920.49%) - -For processors based on the Zen microarchitecture, this dummy wait op is -unnecessary and can be skipped when choosing IOPORT based C-States to -avoid polluting the C-state residency information. - -Link: https://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux-fullhistory.git/commit/?id=972c16130d9dc182cedcdd408408d9eacc7d6a2d [1] -Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b488f02156d3deb08f5ad7816d565c370a8cc6f1 [2] - -Suggested-by: Calvin Ong <calvin.ong@amd.com> -Cc: stable@vger.kernel.org -Cc: regressions@lists.linux.dev -Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com> +From e400ad8b7e6a1b9102123c6240289a811501f7d9 Mon Sep 17 00:00:00 2001 +From: Dave Hansen <dave.hansen@intel.com> +Date: Thu, 22 Sep 2022 11:47:45 -0700 +Subject: [PATCH] ACPI: processor idle: Practically limit "Dummy wait" + workaround to old Intel systems + +Old, circa 2002 chipsets have a bug: they don't go idle when they are +supposed to. So, a workaround was added to slow the CPU down and +ensure that the CPU waits a bit for the chipset to actually go idle. +This workaround is ancient and has been in place in some form since +the original kernel ACPI implementation. + +But, this workaround is very painful on modern systems. The "inl()" +can take thousands of cycles (see Link: for some more detailed +numbers and some fun kernel archaeology). + +First and foremost, modern systems should not be using this code. +Typical Intel systems have not used it in over a decade because it is +horribly inferior to MWAIT-based idle. + +Despite this, people do seem to be tripping over this workaround on +AMD system today. + +Limit the "dummy wait" workaround to Intel systems. Keep Modern AMD +systems from tripping over the workaround. Remotely modern Intel +systems use intel_idle instead of this code and will, in practice, +remain unaffected by the dummy wait. + +Reported-by: K Prateek Nayak <kprateek.nayak@amd.com> +Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> +Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> +Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> +Link: https://lore.kernel.org/all/20220921063638.2489-1-kprateek.nayak@amd.com/ +Link: https://lkml.kernel.org/r/20220922184745.3252932-1-dave.hansen@intel.com --- - drivers/acpi/processor_idle.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) + drivers/acpi/processor_idle.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c -index 16a1663d02d4..18850aa2b79b 100644 +index 16a1663d02d460..9f40917c49efbf 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c -@@ -529,9 +529,11 @@ static __cpuidle void io_idle(unsigned long addr) - inb(addr); - - #ifdef CONFIG_X86 -- /* No delay is needed if we are in guest */ -- if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) -- return; +@@ -531,10 +531,27 @@ static void wait_for_freeze(void) + /* No delay is needed if we are in guest */ + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return; + /* -+ * No delay is needed if we are in guest or on a processor -+ * based on the Zen microarchitecture. ++ * Modern (>=Nehalem) Intel systems use ACPI via intel_idle, ++ * not this code. Assume that any Intel systems using this ++ * are ancient and may need the dummy wait. This also assumes ++ * that the motivating chipset issue was Intel-only. + */ -+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR) || boot_cpu_has(X86_FEATURE_ZEN)) - /* - * Modern (>=Nehalem) Intel systems use ACPI via intel_idle, - * not this code. Assume that any Intel systems using this - --- -2.25.1 ++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) ++ return; + #endif +- /* Dummy wait op - must do something useless after P_LVL2 read +- because chipsets cannot guarantee that STPCLK# signal +- gets asserted in time to freeze execution properly. */ ++ /* ++ * Dummy wait op - must do something useless after P_LVL2 read ++ * because chipsets cannot guarantee that STPCLK# signal gets ++ * asserted in time to freeze execution properly ++ * ++ * This workaround has been in place since the original ACPI ++ * implementation was merged, circa 2002. ++ * ++ * If a profile is pointing to this instruction, please first ++ * consider moving your system to a more modern idle ++ * mechanism. ++ */ + inl(acpi_gbl_FADT.xpm_timer_block.address); + } + diff --git a/SOURCES/0001-bump-the-sensitivity-of-AMD-SFH.patch b/SOURCES/0001-bump-the-sensitivity-of-AMD-SFH.patch deleted file mode 100644 index 092fab2..0000000 --- a/SOURCES/0001-bump-the-sensitivity-of-AMD-SFH.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 34423c936dd27c7f836823d3dfc0041607946ba0 Mon Sep 17 00:00:00 2001 -From: Jan200101 <sentrycraft123@gmail.com> -Date: Sat, 9 Mar 2024 20:00:58 +0100 -Subject: [PATCH] bump the sensitivity of AMD SFH - -Bumps the sensitivity of AMD sfh gyro and accelerometers by removing the division -operation and rebasing the units in the hid descriptor. -This helps with the gyro deadzone of the Legion Go. Should not affect existing -devices. - -Since most of the magic happens in firmware thej SFH 1.0 HID report descriptor is left untouched. - -Co-authored-by: antheas <git@antheas.dev> -Signed-off-by: Jan200101 <sentrycraft123@gmail.com> ---- - drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 29 +- - .../sfh1_1/amd_sfh_hid_report_desc1_1.h | 344 ++++++++++++++++++ - 2 files changed, 359 insertions(+), 14 deletions(-) - create mode 100644 drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_hid_report_desc1_1.h - -diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c -index 8a037de08e92..9426320a4a9c 100644 ---- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c -+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c -@@ -13,6 +13,7 @@ - #include "amd_sfh_interface.h" - #include "../hid_descriptor/amd_sfh_hid_desc.h" - #include "../hid_descriptor/amd_sfh_hid_report_desc.h" -+#include "amd_sfh_hid_report_desc1_1.h" - - #define SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41 - #define SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM 0x51 -@@ -30,14 +31,14 @@ static int get_report_desc(int sensor_idx, u8 *rep_desc) - { - switch (sensor_idx) { - case ACCEL_IDX: /* accelerometer */ -- memset(rep_desc, 0, sizeof(accel3_report_descriptor)); -- memcpy(rep_desc, accel3_report_descriptor, -- sizeof(accel3_report_descriptor)); -+ memset(rep_desc, 0, sizeof(accel3_report_descriptor1_1)); -+ memcpy(rep_desc, accel3_report_descriptor1_1, -+ sizeof(accel3_report_descriptor1_1)); - break; - case GYRO_IDX: /* gyroscope */ -- memset(rep_desc, 0, sizeof(gyro3_report_descriptor)); -- memcpy(rep_desc, gyro3_report_descriptor, -- sizeof(gyro3_report_descriptor)); -+ memset(rep_desc, 0, sizeof(gyro3_report_descriptor1_1)); -+ memcpy(rep_desc, gyro3_report_descriptor1_1, -+ sizeof(gyro3_report_descriptor1_1)); - break; - case MAG_IDX: /* magnetometer */ - memset(rep_desc, 0, sizeof(comp3_report_descriptor)); -@@ -201,9 +201,9 @@ - OFFSET_SENSOR_DATA_DEFAULT; - memcpy_fromio(&accel_data, sensoraddr, sizeof(struct sfh_accel_data)); - get_common_inputs(&acc_input.common_property, report_id); -- acc_input.in_accel_x_value = amd_sfh_float_to_int(accel_data.acceldata.x) / 100; -- acc_input.in_accel_y_value = amd_sfh_float_to_int(accel_data.acceldata.y) / 100; -- acc_input.in_accel_z_value = amd_sfh_float_to_int(accel_data.acceldata.z) / 100; -+ acc_input.in_accel_x_value = amd_sfh_float_to_int(accel_data.acceldata.x); -+ acc_input.in_accel_y_value = amd_sfh_float_to_int(accel_data.acceldata.y); -+ acc_input.in_accel_z_value = amd_sfh_float_to_int(accel_data.acceldata.z); - memcpy(input_report, &acc_input, sizeof(acc_input)); - report_size = sizeof(acc_input); - break; -@@ -212,9 +212,9 @@ - OFFSET_SENSOR_DATA_DEFAULT; - memcpy_fromio(&gyro_data, sensoraddr, sizeof(struct sfh_gyro_data)); - get_common_inputs(&gyro_input.common_property, report_id); -- gyro_input.in_angel_x_value = amd_sfh_float_to_int(gyro_data.gyrodata.x) / 1000; -- gyro_input.in_angel_y_value = amd_sfh_float_to_int(gyro_data.gyrodata.y) / 1000; -- gyro_input.in_angel_z_value = amd_sfh_float_to_int(gyro_data.gyrodata.z) / 1000; -+ gyro_input.in_angel_x_value = amd_sfh_float_to_int(gyro_data.gyrodata.x); -+ gyro_input.in_angel_y_value = amd_sfh_float_to_int(gyro_data.gyrodata.y); -+ gyro_input.in_angel_z_value = amd_sfh_float_to_int(gyro_data.gyrodata.z); - memcpy(input_report, &gyro_input, sizeof(gyro_input)); - report_size = sizeof(gyro_input); - break; -@@ -264,7 +265,7 @@ static u32 get_desc_size(int sensor_idx, int descriptor_name) - case ACCEL_IDX: - switch (descriptor_name) { - case descr_size: -- return sizeof(accel3_report_descriptor); -+ return sizeof(accel3_report_descriptor1_1); - case input_size: - return sizeof(struct accel3_input_report); - case feature_size: -@@ -274,7 +275,7 @@ static u32 get_desc_size(int sensor_idx, int descriptor_name) - case GYRO_IDX: - switch (descriptor_name) { - case descr_size: -- return sizeof(gyro3_report_descriptor); -+ return sizeof(gyro3_report_descriptor1_1); - case input_size: - return sizeof(struct gyro_input_report); - case feature_size: -diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_hid_report_desc1_1.h b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_hid_report_desc1_1.h -new file mode 100644 -index 000000000000..f54ae5be3d58 ---- /dev/null -+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_hid_report_desc1_1.h -@@ -0,0 +1,344 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * HID descriptor structures 1_1 copy -+ * Modified for better accuracy -+ * Copyright 2020-2021 Advanced Micro Devices, Inc. -+ * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com> -+ * Sandeep Singh <Sandeep.singh@amd.com> -+ * Basavaraj Natikar <Basavaraj.Natikar@amd.com> -+ */ -+ -+#ifndef AMD_SFH_HID_REPORT_DESCRIPTOR1_1_H -+#define AMD_SFH_HID_REPORT_DESCRIPTOR1_1_H -+ -+// Accelerometer 3D Sensor -+static const u8 accel3_report_descriptor1_1[] = { -+0x05, 0x20, /* Usage page */ -+0x09, 0x73, /* Motion type Accel 3D */ -+0xA1, 0x00, /* HID Collection (Physical) */ -+ -+//feature reports(xmit/receive) -+0x85, 1, /* HID Report ID */ -+0x05, 0x20, /* HID usage page sensor */ -+0x0A, 0x09, 0x03, /* Sensor property and sensor connection type */ -+0x15, 0, /* HID logical MIN_8(0) */ -+0x25, 2, /* HID logical MAX_8(2) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection (logical) */ -+0x0A, 0x30, 0x08, /* Sensor property connection type intergated sel*/ -+0x0A, 0x31, 0x08, /* Sensor property connection type attached sel */ -+0x0A, 0x32, 0x08, /* Sensor property connection type external sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x16, 0x03, /* HID usage sensor property reporting state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 5, /* HID logical Max_8(5) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection(logical) */ -+0x0A, 0x40, 0x08, /* Sensor property report state no events sel */ -+0x0A, 0x41, 0x08, /* Sensor property report state all events sel */ -+0x0A, 0x42, 0x08, /* Sensor property report state threshold events sel */ -+0x0A, 0x43, 0x08, /* Sensor property report state no events wake sel */ -+0x0A, 0x44, 0x08, /* Sensor property report state all events wake sel */ -+0x0A, 0x45, 0x08, /* Sensor property report state threshold events wake sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x19, 0x03, /* HID usage sensor property power state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 5, /* HID logical Max_8(5) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection(logical) */ -+0x0A, 0x50, 0x08, /* Sensor property power state undefined sel */ -+0x0A, 0x51, 0x08, /* Sensor property power state D0 full power sel */ -+0x0A, 0x52, 0x08, /* Sensor property power state D1 low power sel */ -+0x0A, 0x53, 0x08, /* Sensor property power state D2 standby with wake sel */ -+0x0A, 0x54, 0x08, /* Sensor property power state D3 sleep with wake sel */ -+0x0A, 0x55, 0x08, /* Sensor property power state D4 power off sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x01, 0x02, /* HID usage sensor state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 6, /* HID logical Max_8(6) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection(logical) */ -+0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ -+0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ -+0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ -+0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ -+0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ -+0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ -+0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x0E, 0x03, /* HID usage sensor property report interval */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x27, 0xFF, 0xFF, 0xFF, 0xFF, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0, /* HID unit exponent(0) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+0x0A, 0x52, 0x14, /* Sensor data motion accel and mod change sensitivity ABS) */ -+ -+0x15, 0, /* HID logical Min_8(0) */ -+0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ -+ -+0x75, 16, /* HID report size(16) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0x0E, /* HID unit exponent(0x0E) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+0x0A, 0x52, 0x24, /* HID usage sensor data (motion accel and mod max) */ -+ -+0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ -+ -+0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ -+ -+0x75, 16, /* HID report size(16) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0x0E, /* HID unit exponent(0x0E) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+0x0A, 0x52, 0x34, /* HID usage sensor data (motion accel and mod min) */ -+ -+0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ -+ -+0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ -+ -+0x75, 16, /* HID report size(16) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0x0E, /* HID unit exponent(0x0E) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+ -+//input report (transmit) -+0x05, 0x20, /* HID usage page sensors */ -+0x0A, 0x01, 0x02, /* HID usage sensor state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 6, /* HID logical Max_8(6) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count (1) */ -+0xA1, 0x02, /* HID end collection (logical) */ -+0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ -+0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ -+0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ -+0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ -+0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ -+0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ -+0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ -+0X81, 0x00, /* HID Input (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x02, 0x02, /* HID usage sensor event */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 5, /* HID logical Max_8(5) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count (1) */ -+0xA1, 0x02, /* HID end collection (logical) */ -+0x0A, 0x10, 0x08, /* HID usage sensor event unknown sel */ -+0x0A, 0x11, 0x08, /* HID usage sensor event state changed sel */ -+0x0A, 0x12, 0x08, /* HID usage sensor event property changed sel */ -+0x0A, 0x13, 0x08, /* HID usage sensor event data updated sel */ -+0x0A, 0x14, 0x08, /* HID usage sensor event poll response sel */ -+0x0A, 0x15, 0x08, /* HID usage sensor event change sensitivity sel */ -+0X81, 0x00, /* HID Input (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x53, 0x04, /* HID usage sensor data motion Acceleration X axis */ -+0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ -+ -+0x27, 0xFF, 0xff, 0XFF, 0XFF, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count (1) */ -+0x55, 0x0C, /* HID unit exponent(0x0C) modified */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+0x0A, 0x54, 0x04, /* HID usage sensor data motion Acceleration Y axis */ -+0x17, 0X00, 0X00, 0x01, 0x80, /* HID logical Min_32 */ -+ -+0x27, 0xFF, 0xFF, 0XFF, 0XFF, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count (1) */ -+0x55, 0x0C, /* HID unit exponent(0x0C) modified */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+0x0A, 0x55, 0x04, /* HID usage sensor data motion Acceleration Z axis */ -+0x17, 0X00, 0X00, 0x01, 0x80, /* HID logical Min_32 */ -+ -+0x27, 0XFF, 0XFF, 0xFF, 0x7F, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count (1) */ -+0x55, 0x0C, /* HID unit exponent(0x0C) modified */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+ -+0x0A, 0x51, 0x04, /* HID usage sensor data motion state */ -+0x15, 0, /* HID logical Min_8(0) False = Still*/ -+0x25, 1, /* HID logical Min_8(1) True = In motion */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count (1) */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+0xC0 /* HID end collection */ -+}; -+ -+static const u8 gyro3_report_descriptor1_1[] = { -+0x05, 0x20, /* Usage page */ -+0x09, 0x76, /* Motion type Gyro3D */ -+0xA1, 0x00, /* HID Collection (Physical) */ -+ -+0x85, 2, /* HID Report ID */ -+0x05, 0x20, /* HID usage page sensor */ -+0x0A, 0x09, 0x03, /* Sensor property and sensor connection type */ -+0x15, 0, /* HID logical MIN_8(0) */ -+0x25, 2, /* HID logical MAX_8(2) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection (logical) */ -+0x0A, 0x30, 0x08, /* Sensor property connection type intergated sel */ -+0x0A, 0x31, 0x08, /* Sensor property connection type attached sel */ -+0x0A, 0x32, 0x08, /* Sensor property connection type external sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x16, 0x03, /* HID usage sensor property reporting state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 5, /* HID logical Max_8(5) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection(logical) */ -+0x0A, 0x40, 0x08, /* Sensor reporting state no events sel */ -+0x0A, 0x41, 0x08, /* Sensor reporting state all events sel */ -+0x0A, 0x42, 0x08, /* Sensor reporting state threshold events sel */ -+0x0A, 0x43, 0x08, /* Sensor reporting state no events wake sel */ -+0x0A, 0x44, 0x08, /* Sensor reporting state all events wake sel */ -+0x0A, 0x45, 0x08, /* Sensor reporting state threshold events wake sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x19, 0x03, /* HID usage sensor property power state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 5, /* HID logical Max_8(5) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection(logical) */ -+0x0A, 0x50, 0x08, /* Sensor power state undefined sel */ -+0x0A, 0x51, 0x08, /* Sensor power state D0 full power sel */ -+0x0A, 0x52, 0x08, /* Sensor power state D1 low power sel */ -+0x0A, 0x53, 0x08, /* Sensor power state D2 standby with wake sel */ -+0x0A, 0x54, 0x08, /* Sensor power state D3 sleep with wake sel */ -+0x0A, 0x55, 0x08, /* Sensor power state D4 power off sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x01, 0x02, /* HID usage sensor state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 6, /* HID logical Max_8(6) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count(1) */ -+0xA1, 0x02, /* HID collection(logical) */ -+0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ -+0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ -+0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ -+0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ -+0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ -+0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ -+0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ -+0xB1, 0x00, /* HID feature (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x0E, 0x03, /* HID usage sensor property report interval */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x27, 0xFF, 0xFF, 0xFF, 0xFF, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0, /* HID unit exponent(0) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+0x0A, 0x56, 0x14, /* Angular velocity and mod change sensitivity ABS)*/ -+ -+0x15, 0, /* HID logical Min_8(0) */ -+0x26, 0xFF, 0xFF, /* HID logical Max_16(0xFF,0xFF) */ -+ -+0x75, 16, /* HID report size(16) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0x0E, /* HID unit exponent(0x0E) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+0x0A, 0x56, 0x24, /* Sensor data (motion angular velocity and mod max) */ -+ -+0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ -+ -+0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ -+ -+0x75, 16, /* HID report size(16) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0x0E, /* HID unit exponent(0x0E) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+0x0A, 0x56, 0x34, /* HID usage sensor data (motion accel and mod min) */ -+ -+0x16, 0x01, 0x80, /* HID logical Min_16(0x01,0x80) */ -+ -+0x26, 0xFF, 0x7F, /* HID logical Max_16(0xFF,0x7F) */ -+ -+0x75, 16, /* HID report size(16) */ -+0x95, 1, /* HID report count(1) */ -+0x55, 0x0E, /* HID unit exponent(0x0E) */ -+0xB1, 0x02, /* HID feature (Data_Arr_Abs) */ -+ -+//Input reports(transmit) -+0x05, 0x20, /* HID usage page sensors */ -+0x0A, 0x01, 0x02, /* HID usage sensor state */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 6, /* HID logical Max_8(6) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count (1) */ -+0xA1, 0x02, /* HID end collection (logical) */ -+0x0A, 0x00, 0x08, /* HID usage sensor state unknown sel */ -+0x0A, 0x01, 0x08, /* HID usage sensor state ready sel */ -+0x0A, 0x02, 0x08, /* HID usage sensor state not available sel */ -+0x0A, 0x03, 0x08, /* HID usage sensor state no data sel */ -+0x0A, 0x04, 0x08, /* HID usage sensor state initializing sel */ -+0x0A, 0x05, 0x08, /* HID usage sensor state access denied sel */ -+0x0A, 0x06, 0x08, /* HID usage sensor state error sel */ -+0X81, 0x00, /* HID Input (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x02, 0x02, /* HID usage sensor event */ -+0x15, 0, /* HID logical Min_8(0) */ -+0x25, 5, /* HID logical Max_8(5) */ -+0x75, 8, /* HID report size(8) */ -+0x95, 1, /* HID report count (1) */ -+0xA1, 0x02, /* HID end collection (logical) */ -+0x0A, 0x10, 0x08, /* HID usage sensor event unknown sel */ -+0x0A, 0x11, 0x08, /* HID usage sensor event state changed sel */ -+0x0A, 0x12, 0x08, /* HID usage sensor event property changed sel */ -+0x0A, 0x13, 0x08, /* HID usage sensor event data updated sel */ -+0x0A, 0x14, 0x08, /* HID usage sensor event poll response sel */ -+0x0A, 0x15, 0x08, /* HID usage sensor event change sensitivity sel */ -+0X81, 0x00, /* HID Input (Data_Arr_Abs) */ -+0xC0, /* HID end collection */ -+0x0A, 0x57, 0x04, /* Sensor data motion Angular velocity X axis */ -+0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ -+ -+0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count (1) */ -+0x55, 0x0B, /* HID unit exponent(0x0B) modified */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+0x0A, 0x58, 0x04, /* Sensor data motion Angular velocity Y axis */ -+0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ -+ -+0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count (1) */ -+0x55, 0x0B, /* HID unit exponent(0x0B) modified */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+0x0A, 0x59, 0x04, /* Sensor data motion Angular velocity Z axis */ -+0x17, 0x00, 0x00, 0x01, 0x80, /* HID logical Min_32 */ -+ -+0x27, 0xFF, 0xFF, 0xFF, 0x7F, /* HID logical Max_32 */ -+ -+0x75, 32, /* HID report size(32) */ -+0x95, 1, /* HID report count (1) */ -+0x55, 0x0B, /* HID unit exponent(0x0B) modified */ -+0X81, 0x02, /* HID Input (Data_Arr_Abs) */ -+ -+0xC0, /* HID end collection */ -+}; -+ -+#endif --- -2.44.0 - diff --git a/SOURCES/CVE-2024-44961.patch b/SOURCES/CVE-2024-44961.patch new file mode 100644 index 0000000..19e2808 --- /dev/null +++ b/SOURCES/CVE-2024-44961.patch @@ -0,0 +1,140 @@ +From git@z Thu Jan 1 00:00:00 1970 +Subject: [PATCH 1/2] drm/amdgpu: Pass amdgpu_job directly to + amdgpu_ring_soft_recovery +From: Joshua Ashton <joshua@froggi.es> +Date: Sat, 13 Jan 2024 14:02:03 +0000 +Message-Id: <20240113140206.2383133-1-joshua@froggi.es> +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +We will need this to change the karma in the future. + +Signed-off-by: Joshua Ashton <joshua@froggi.es> + +Cc: Friedrich Vock <friedrich.vock@gmx.de> +Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> +Cc: Christian König <christian.koenig@amd.com> +Cc: André Almeida <andrealmeid@igalia.com> +Cc: stable@vger.kernel.org +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 9 ++++----- + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 3 +-- + 3 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +index 78476bc75b4e..c1af7ca25912 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +@@ -52,7 +52,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) + adev->job_hang = true; + + if (amdgpu_gpu_recovery && +- amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { ++ amdgpu_ring_soft_recovery(ring, job)) { + DRM_ERROR("ring %s timeout, but soft recovered\n", + s_job->sched->name); + goto exit; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +index 45424ebf9681..25209ce54552 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +@@ -425,14 +425,13 @@ void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring, + * amdgpu_ring_soft_recovery - try to soft recover a ring lockup + * + * @ring: ring to try the recovery on +- * @vmid: VMID we try to get going again +- * @fence: timedout fence ++ * @job: the locked-up job + * + * Tries to get a ring proceeding again when it is stuck. + */ +-bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid, +- struct dma_fence *fence) ++bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, struct amdgpu_job *job) + { ++ struct dma_fence *fence = job->base.s_fence->parent; + unsigned long flags; + ktime_t deadline; + +@@ -452,7 +451,7 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid, + atomic_inc(&ring->adev->gpu_reset_counter); + while (!dma_fence_is_signaled(fence) && + ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0) +- ring->funcs->soft_recovery(ring, vmid); ++ ring->funcs->soft_recovery(ring, job->vmid); + + return dma_fence_is_signaled(fence); + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +index bbb53720a018..734df88f22d4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +@@ -354,8 +354,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring); + void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring, + uint32_t reg0, uint32_t val0, + uint32_t reg1, uint32_t val1); +-bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid, +- struct dma_fence *fence); ++bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, struct amdgpu_job *job); + + static inline void amdgpu_ring_set_preempt_cond_exec(struct amdgpu_ring *ring, + bool cond_exec) +-- +2.43.0 + +From git@z Thu Jan 1 00:00:00 1970 +Subject: [PATCH 2/2] drm/amdgpu: Mark ctx as guilty in ring_soft_recovery + path +From: Joshua Ashton <joshua@froggi.es> +Date: Sat, 13 Jan 2024 14:02:04 +0000 +Message-Id: <20240113140206.2383133-2-joshua@froggi.es> +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +We need to bump the karma of the drm_sched job in order for the context +that we just recovered to get correct feedback that it is guilty of +hanging. + +Without this feedback, the application may keep pushing through the soft +recoveries, continually hanging the system with jobs that timeout. + +There is an accompanying Mesa/RADV patch here +https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27050 +to properly handle device loss state when VRAM is not lost. + +With these, I was able to run Counter-Strike 2 and launch an application +which can fault the GPU in a variety of ways, and still have Steam + +Counter-Strike 2 + Gamescope (compositor) stay up and continue +functioning on Steam Deck. + +Signed-off-by: Joshua Ashton <joshua@froggi.es> + +Cc: Friedrich Vock <friedrich.vock@gmx.de> +Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> +Cc: Christian König <christian.koenig@amd.com> +Cc: André Almeida <andrealmeid@igalia.com> +Cc: stable@vger.kernel.org +Tested-by: Friedrich Vock <friedrich.vock@gmx.de> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +index 25209ce54552..e87cafb5b1c3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +@@ -448,6 +448,8 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, struct amdgpu_job *job) + dma_fence_set_error(fence, -ENODATA); + spin_unlock_irqrestore(fence->lock, flags); + ++ if (job->vm) ++ drm_sched_increase_karma(&job->base); + atomic_inc(&ring->adev->gpu_reset_counter); + while (!dma_fence_is_signaled(fence) && + ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0) +-- +2.43.0 + diff --git a/SOURCES/v2-ally-suspend-fix.patch b/SOURCES/v2-ally-suspend-fix.patch index 4084770..42d2182 100644 --- a/SOURCES/v2-ally-suspend-fix.patch +++ b/SOURCES/v2-ally-suspend-fix.patch @@ -1,231 +1,7 @@ -From 57632b4abbcf3f95278c1b71b9de5040463753fe Mon Sep 17 00:00:00 2001 -From: Antheas Kapenekakis <lkml@antheas.dev> -Date: Sun, 22 Sep 2024 12:15:57 +0200 -Subject: [PATCH v2 0/5] acpi/x86: s2idle: move Display off/on calls outside - suspend (fixes ROG Ally suspend) - -The following series moves the Display off/on calls outside of the suspend -sequence, as they are performed in Windows. This fixes certain issues that appear -in devices that use the calls and expect the kernel to be active during their -call (especially in the case of the ROG Ally devices) and opens the possibility -of implementing a "Screen Off" state in the future (which mirrors Windows). -In addition, it adds a quirk table that will allow for adding delays between -Modern Standby transitions, to help resolve racing conditions. - -This series requires a bit of background on how modern standby works in Windows. -Fundamentally, it is composed of four states: "Active", "Screen Off", "Sleep", -and "DRIPS". Here, I take the liberty of naming the state "Active", as it is -implied in Windows documentation. - -When the user actively interacts with a device, it is in the "Active" state. -The screen is on, all devices are connected, and desired software is running. -The other 3 stages play a role once the user stops interacting with the device. -This is triggered in two main ways: either by pressing the power button or by -inactivity. Once either of those targets is met, the system enters Modern Standby. - -Modern Standby consists of an orchestration of the "Screen Off", "Sleep", and -"DRIPS" states. Windows is free to move throughout these states until the user -interacts with the device again, where the device will transition to being -"Active". Moving between the states implies a transition, where Windows performs -a set of actions. In addition, Windows can only move between adjacent states -as follows: - -"Active" <-> "Screen Off" <-> "Sleep" <-> "DRIPS" - -"Screen Off" is the state where all active displays in the device (whether -*virtual* or real; this means unrelated to DRM) are off. The user might still -be interacting with the device or running programs (e.g., compiling a kernel). - -"Sleep" is a newer state, in which the device turns off its fan and pulses its -power button, but still supports running software activities. As part of this, -and to avoid overheating the device a lot of manufacturers lower the TDP (PLx) -of the device [3; _DSM 9 description]. - -Finally, DRIPS stands for Deepest Runtime Idle Power State, i.e. suspend. - -While Windows may transition from any state to any state, doing so implies -performing all transitions to reach that state. All states other than DRIPS -have a fully active kernel (Wifi, USB at least) and allow userspace activity. -What changes is the extent of the activity, and whether some power consuming -devices are turned off (this is done with Modern Standby aware drivers and -firmware notifications). The Windows kernel suspends during the transition from -the "Sleep" state to the "DRIPS" state. In all other states it is fully active. - -After finishing each transition, the kernel performs a firmware notification, -described in the _DSM document [3]. Moving from left to right with function num., -we have Display Off (3; Active -> Screen Off), Sleep Entry (7; Screen Off -> Sleep), -and Lowest Power State Entry Notification (5; LPSEN; Sleep -> DRIPS). Then, from -right to left, we have Lowest Power State Exit Notification (6; DRIPS -> Sleep), -Sleep Exit (8; Sleep -> Screen) and Display On (4; Screen Off -> Active). - -The Linux kernel is not currently Modern Standby aware but will still make these -calls. So, what is the problem? The kernel calls all of the firmware notifications -at the point LPSEN (5, 6) should be called, which is when the kernel is mostly -suspended. This is a clear deviation from Windows, and causes undesirable -behavior in certain devices, the main one focused in this patch series being -the ROG Ally. - -The ROG Ally is a Modern Standby capable device (uses Secure Core too; really -ticks all the MS boxes) and in it, the breakage is double: both Display 3,4 -calls and Sleep 7,8 calls cause issues. - -The Display 3,4 calls are responsible for the controller. The Display Off call -disconnects (if powersave is off) or powers off (if powersave is on and on DC -power) the MCU(s) responsible for the controller and deactivates the RGB of the -device. Display On powers on or reconnects the controller respectively. -This controller, in the Ally X, is composed of 6 HID devices that register to -the kernel. As can be inferred, the handling of the calls during the suspend -sequence leads to a set of undesirable outcomes, such as the controller -soft-locking or only half of the HID devices coming back after resume. - -The Sleep 7,8 calls, in general, are responsible for setting a low power state -that is safe to use while the device is sleeping, making the suspend light -pulse, and turning off the fan. Due to a variety of race conditions, there is -a rare occasion where the Ally EC can get stuck in its Sleep mode, where the -TDP is 5W, and prevent increasing it until the device reboots. The sleep entries -contain actions in the Ally, so there is a suspicion that calling them during -DRIPS is causing issues. However, this is not the subject of this patch and -has not been verified yet. - -This patch centers around moving the Display 3,4 calls outside the suspend -sequence (which is the transition from Sleep to DRIPS in Modern Standby terms), -and by implementing the proper locks necessary, opening up the possibility of -making these calls as part of a more elaborate "Modern Standby"-like userspace -suspend/wakelock implementation. As of this patch, they are only called before -the suspend sequence, including with the possibility of adding a delay. - -This makes the intent of this patch primarily compatibility focused, as it aims -to fix issues by the current implementation. And to that end it works. -After moving the calls outside of the suspend sequence, my ROG Ally X test unit -can suspend more than 50 times without rebooting, both with powersave on or off, -regardless of whether it is plugged/unplugged during suspend, and still have the -controller work with full reliability. Furthermore, in V2, after adding a slight -delay prior to the Display Off call, the controller RGB fades to off, prior the -device suspending and journalctl shows the controller disconnecting prior to -the suspend sequence. - -I will note here that as part of developing Handheld Daemon, I have seen the -suspend sequence of many devices. All of them disconnect the XInput controller -during suspend, and all of them have it show up in the logs after suspend. -The Ally controller after patch (3) is the first one to do it cleanly, before -suspend. Therefore, in my eyes, the quirk table is about to get a lot bigger. - -In addition, moving the calls outside of the suspend sequence (and the validation -work it implies) is an important first step in including "Modern Standby"-like -features in Linux. For example, consider an endpoint /sys/power/standby, that -allows for entering "active", "inactive" (for Screen Off; since the name causes -too much confusion), "sleep" values. Those values will then in turn call the -respective firmware notifications (and driver callbacks in the very future) -for all transitions required to reach the entered state. Here, the value -"suspend" (for DRIPS; another confusing name as it can refer to drivers) is -missing, as userspace will never be able to see it. The kernel should support -suspending at all standby states, orchestrating the required transitions to -reach suspend/DRIPS and after suspend returning to the last state. - -Therefore, if userspace is not standby aware, the kernel will work the same way -it works today. In addition, depending on hardware generation, certain power -states might not be supported. It is important to inform userspace of this, as -if the hardware does not support sleep, and userspace holds a wakelock for sleep, -it will just overheat and drain the device battery. - -This series is worth backing this up with sources, so as part of it I reference -Microsoft's documentation on Modern standby [1-3] that explains the whole -process, including a document by Dell [7] and how to prepare for them and attach a -repository of more than 15 device DSDT tables [4] from different manufacturers. -This repository also contains instructions on how to decode the DSDT tables on -a test laptop, to figure out what the _DSM calls will do on that device. - -Moreover, I conduct a short behavioral test in Windows with the Ally X to showcase -the documentation empirically. The Ally is great for such a test, as it contains -visual indicators for all Microsoft suspend points: "Display Off/On" calls are -indicated with the Controller RGB turning off/on, "Screen Off" is indicated with -the suspend light and fan being on, and Sleep is indicated with the suspend -light blinking. - -Unfortunately, as part of this testing, I never found how to see if the device -is actually suspended. As the ROG Ally X NOOPs on firmware notifications 5,6, -and even though I disabled a Mouse from waking up a device, it still would wake -up my Ally X dev unit. - -Referencing Microsoft's documentation, "Screen Off" is entered either through -inactivity or by pressing the power button, so I conduct two tests: one by pressing -the powerbutton, and one for entering Screen Off due to inactivity. - -1) Powerbutton test: -When pressing the powerbutton, the screen of the Ally turns off, and the RGB of -the controller faints to off within 1s. Following, depending on whether the -system is plugged in, the power light and fan stay on for 5 seconds to 10 minutes. -After this point, the power light begins to blink and the fan turns off, showing -that the system has entered the "Sleep" state. - -2) Inactivity test: -I set the Windows power settings to turn off the screen after 1 minute and wait. -After one minute, the display turns off, and after 5 seconds, the controller RGB -turns off. This indicates to me that "Screen Off" is not defined by the screen -being off, but is rather characterized by it. During those 5 seconds while the -RGB is on, I can use the controller to wake up the device. Afterwards it cannot. - -Those tests validate Microsoft's documentation and show that "Screen Off" -seems to more closely correlate to lockscreen behavior (button locks instantly, -inactivity after 5 seconds) than the screen being off. One other behavior I -notice is that, as I look at my Ally X dev right now, with its screen off, I -notice the RGB is still on, which is kind of bothersome, as in Windows the -device would turn the RGB off. Whether as a side effect or planned, it is still -a nice touch. - -This patch series is co-developed with help from Mario Limonciello, and, to be -bisection friendly, is structured based on a patch series he made connecting the -callbacks to the drm subsystem suspend [5]. It also references (already) -upstream work by Luke Jones on Asus-wmi for the Ally controller quirk that is -removed on patch (5) and an issue on amd-drm in 2023 in preparation for the -work in that quirk [6]. Since patch (3) now uses part of the dmi table removed -in patch (5), @Luke I can add you as Suggested-by. - -We will begin thorough testing on the patch series, and there will probably be -a V3, where testing acknowledgements are added. - -Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/prepare-hardware-for-modern-standby [1] -Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/prepare-software-for-modern-standby [2] -Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-firmware-notifications [3] -Link: https://github.com/hhd-dev/hwinfo/tree/master/devices [4] -Link: https://git.kernel.org/pub/scm/linux/kernel/git/superm1/linux.git/log/?h=superm1/dsm-screen-on-off [5] -Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2719 [6] -Link: https://dl.dell.com/manuals/all-products/esuprt_solutions_int/esuprt_solutions_int_solutions_resources/client-mobile-solution-resources_white-papers45_en-us.pdf [7] - -Changes in v2: - - Rewrote cover letter to better reflect the Windows Modern Standby sequence - - Renamed the "screen_" callbacks to "display_" to match Microsoft's naming - - Added attribution to Mario Limonciello and changed the text to reflect that - - Made the screen on/off callbacks warn and bail with -EINVAL if they are - called in the wrong order (currently impossible) - - Changed patch 2 to not bail the suspend sequence when receiving an error - (as these calls are not part of the suspend sequence and failing the - suspend sequence would cause a user visible fault) - - Fixed bug reported by Denis Benato by adding a quirk table in patch (3) - - The ROG controllers get a slight delay after the Display Off call - - Reworded patches to reflect that - -Antheas Kapenekakis (5): - acpi/x86: s2idle: add support for Display Off and Display On callbacks - acpi/x86: s2idle: handle Display On/Off calls outside of suspend - sequence - acpi/x86: s2idle: add quirk table for modern standby delays - acpi/x86: s2idle: call Display On/Off as part of callbacks and rename - platform/x86: asus-wmi: remove Ally (1st gen) and Ally X suspend quirk - - drivers/acpi/x86/s2idle.c | 89 +++++++++++++++++++++++---------- - drivers/platform/x86/asus-wmi.c | 54 -------------------- - include/linux/suspend.h | 10 ++++ - kernel/power/suspend.c | 62 +++++++++++++++++++++++ - 4 files changed, 134 insertions(+), 81 deletions(-) - --- -2.46.1 - From ff87284862db614a4067b2d7383ecb173e1454de Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis <lkml@antheas.dev> Date: Wed, 18 Sep 2024 23:53:53 +0200 -Subject: [PATCH v2 1/5] acpi/x86: s2idle: add support for Display Off and +Subject: [PATCH v3 01/10] acpi/x86: s2idle: add support for Display Off and Display On callbacks The Display Off and Display On firmware notifications are meant to signify @@ -301,14 +77,14 @@ index 09f8397bae15..c527dc0ae5ae 100644 { return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ? -- -2.46.1 +2.46.2 -From a48e63268c59847e5349d0f1d383be2fe60291e7 Mon Sep 17 00:00:00 2001 +From 0f25cd27999b0fe6c0382208452422fd1866da1e Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis <lkml@antheas.dev> Date: Thu, 19 Sep 2024 00:02:32 +0200 -Subject: [PATCH v2 2/5] acpi/x86: s2idle: handle Display On/Off calls outside - of suspend sequence +Subject: [PATCH v3 02/10] acpi/x86: s2idle: handle Display On/Off calls + outside of suspend sequence Currently, the Display On/Off calls are handled within the suspend sequence, which is a deviation from Windows. This causes issues with @@ -328,12 +104,12 @@ Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev> 1 file changed, 9 insertions(+) diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index c527dc0ae5ae..8f951cc0cb64 100644 +index c527dc0ae5ae..610f8ecaeebd 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c -@@ -507,6 +507,13 @@ int suspend_devices_and_enter(suspend_state_t state) - - pm_suspend_target_state = state; +@@ -589,6 +589,13 @@ static int enter_state(suspend_state_t state) + if (state == PM_SUSPEND_TO_IDLE) + s2idle_begin(); + /* + * Linux does not have the concept of a "Screen Off" state, so call @@ -342,26 +118,26 @@ index c527dc0ae5ae..8f951cc0cb64 100644 + */ + platform_suspend_display_off(); + - if (state == PM_SUSPEND_TO_IDLE) - pm_set_suspend_no_platform(); - -@@ -540,6 +547,8 @@ int suspend_devices_and_enter(suspend_state_t state) - Close: - platform_resume_end(state); - pm_suspend_target_state = PM_SUSPEND_ON; + if (sync_on_suspend_enabled) { + trace_suspend_resume(TPS("sync_filesystems"), 0, true); + ksys_sync_helper(); +@@ -616,6 +623,8 @@ static int enter_state(suspend_state_t state) + suspend_finish(); + Unlock: + mutex_unlock(&system_transition_mutex); + + platform_suspend_display_on(); return error; + } - Recover_platform: -- -2.46.1 +2.46.2 -From faa52b2b9af894ba3b752e1d35ac389fa2b915cc Mon Sep 17 00:00:00 2001 +From e0cad271a26ff16ea9456e0104ea10e1195f6d47 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis <lkml@antheas.dev> Date: Sun, 22 Sep 2024 11:47:29 +0200 -Subject: [PATCH v2 3/5] acpi/x86: s2idle: add quirk table for modern standby +Subject: [PATCH v3 03/10] acpi/x86: s2idle: add quirk table for modern standby delays Unfortunately, some modern standby systems, including the ROG Ally, rely @@ -394,7 +170,7 @@ index 8f33249cc067..d7e2a4d8ab0c 100644 extern suspend_state_t pm_suspend_target_state; extern suspend_state_t mem_sleep_current; diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index 8f951cc0cb64..af807e621f28 100644 +index 610f8ecaeebd..af2abdd2f8c3 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -11,6 +11,7 @@ @@ -436,11 +212,10 @@ index 8f951cc0cb64..af807e621f28 100644 /** * pm_suspend_default_s2idle - Check if suspend-to-idle is the default suspend. * -@@ -506,6 +531,18 @@ int suspend_devices_and_enter(suspend_state_t state) - return -ENOSYS; +@@ -589,12 +614,26 @@ static int enter_state(suspend_state_t state) + if (state == PM_SUSPEND_TO_IDLE) + s2idle_begin(); - pm_suspend_target_state = state; -+ + /* + * Windows transitions between Modern Standby states slowly, over multiple + * seconds. Certain manufacturers may rely on this, introducing race @@ -452,35 +227,35 @@ index 8f951cc0cb64..af807e621f28 100644 + ); + const struct platform_s2idle_quirks *s2idle_quirks = s2idle_sysid ? + s2idle_sysid->driver_data : NULL; - ++ /* * Linux does not have the concept of a "Screen Off" state, so call -@@ -513,6 +550,8 @@ int suspend_devices_and_enter(suspend_state_t state) + * the platform functions for Display On/Off prior to the suspend * sequence, mirroring Windows which calls them outside of it as well. */ platform_suspend_display_off(); + if (s2idle_quirks && s2idle_quirks->delay_display_off) + msleep(s2idle_quirks->delay_display_off); - if (state == PM_SUSPEND_TO_IDLE) - pm_set_suspend_no_platform(); -@@ -548,6 +587,8 @@ int suspend_devices_and_enter(suspend_state_t state) - platform_resume_end(state); - pm_suspend_target_state = PM_SUSPEND_ON; + if (sync_on_suspend_enabled) { + trace_suspend_resume(TPS("sync_filesystems"), 0, true); +@@ -624,6 +663,8 @@ static int enter_state(suspend_state_t state) + Unlock: + mutex_unlock(&system_transition_mutex); + if (s2idle_quirks && s2idle_quirks->delay_display_on) + msleep(s2idle_quirks->delay_display_on); platform_suspend_display_on(); return error; - + } -- -2.46.1 +2.46.2 -From 02137e51d6a558fccf7a4661ae31e8c019cae984 Mon Sep 17 00:00:00 2001 +From 230395bedb589220c3c126d7f33156edbb3dd1c7 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis <lkml@antheas.dev> Date: Thu, 19 Sep 2024 00:22:03 +0200 -Subject: [PATCH v2 4/5] acpi/x86: s2idle: call Display On/Off as part of +Subject: [PATCH v3 04/10] acpi/x86: s2idle: call Display On/Off as part of callbacks and rename Move the Display On/Off notifications into dedicated callbacks that gate @@ -667,14 +442,14 @@ index dd0b40b9bbe8..a17e28b91326 100644 void __init acpi_s2idle_setup(void) -- -2.46.1 +2.46.2 -From 57632b4abbcf3f95278c1b71b9de5040463753fe Mon Sep 17 00:00:00 2001 +From 69cdca368e53713088771d2866adc48ac19cbf29 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis <lkml@antheas.dev> Date: Thu, 19 Sep 2024 00:29:59 +0200 -Subject: [PATCH v2 5/5] platform/x86: asus-wmi: remove Ally (1st gen) and Ally - X suspend quirk +Subject: [PATCH v3 05/10] platform/x86: asus-wmi: remove Ally (1st gen) and + Ally X suspend quirk By moving the Display On/Off calls outside of the suspend sequence and introducing a slight delay after Display Off, the ROG Ally controller @@ -770,5 +545,405 @@ index 37636e5a38e3..2c9656e0afda 100644 /* Registration ***************************************************************/ -- -2.46.1 +2.46.2 + + +From 2d446e1e66be5ae07bb7c243a7c4383b49b1aa3e Mon Sep 17 00:00:00 2001 +From: Antheas Kapenekakis <lkml@antheas.dev> +Date: Wed, 25 Sep 2024 14:10:11 +0200 +Subject: [PATCH v3 06/10] acpi/x86: s2idle: add support for Sleep Entry and + Sleep Exit callbacks + +The Sleep Entry and Sleep Exit firmware notifications allow the platform +to enter Modern Standby. In this state, if supported, the platform turns +off auxiliary USB devices (e.g., the controllers of the Legion Go), +makes the power light of the device flash, and lowers the power envelope +to a minimum that still allows for software activity without affecting +battery life. + +Allow for entering this state prior to initiating the suspend sequence. +This fixes issues where the EC or the USB of the device need time to +power down before entering the suspend sequence, and allows for entering +this power state without suspending the device. + +Suggested-by: Mario Limonciello <mario.limonciello@amd.com> +Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev> +--- + include/linux/suspend.h | 4 ++++ + kernel/power/suspend.c | 12 ++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/include/linux/suspend.h b/include/linux/suspend.h +index d7e2a4d8ab0c..66c5b434334d 100644 +--- a/include/linux/suspend.h ++++ b/include/linux/suspend.h +@@ -133,6 +133,7 @@ struct platform_suspend_ops { + + struct platform_s2idle_ops { + int (*display_off)(void); ++ int (*sleep_entry)(void); + int (*begin)(void); + int (*prepare)(void); + int (*prepare_late)(void); +@@ -141,6 +142,7 @@ struct platform_s2idle_ops { + void (*restore_early)(void); + void (*restore)(void); + void (*end)(void); ++ int (*sleep_exit)(void); + int (*display_on)(void); + }; + +@@ -168,6 +170,8 @@ extern unsigned int pm_suspend_global_flags; + #define PM_SUSPEND_FLAG_NO_PLATFORM BIT(2) + + int platform_suspend_display_off(void); ++int platform_suspend_sleep_entry(void); ++int platform_suspend_sleep_exit(void); + int platform_suspend_display_on(void); + + static inline void pm_suspend_clear_flags(void) +diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c +index af2abdd2f8c3..dab299e28195 100644 +--- a/kernel/power/suspend.c ++++ b/kernel/power/suspend.c +@@ -285,6 +285,18 @@ int platform_suspend_display_off(void) + } + EXPORT_SYMBOL_GPL(platform_suspend_display_off); + ++int platform_suspend_sleep_entry(void) ++{ ++ return s2idle_ops && s2idle_ops->sleep_entry ? s2idle_ops->sleep_entry() : 0; ++} ++EXPORT_SYMBOL_GPL(platform_suspend_sleep_entry); ++ ++int platform_suspend_sleep_exit(void) ++{ ++ return s2idle_ops && s2idle_ops->sleep_exit ? s2idle_ops->sleep_exit() : 0; ++} ++EXPORT_SYMBOL_GPL(platform_suspend_sleep_exit); ++ + int platform_suspend_display_on(void) + { + return s2idle_ops && s2idle_ops->display_on ? s2idle_ops->display_on() : 0; +-- +2.46.2 + + +From ec33ea0c341d5b75a090910664c572d8d4793bbc Mon Sep 17 00:00:00 2001 +From: Antheas Kapenekakis <lkml@antheas.dev> +Date: Wed, 25 Sep 2024 14:19:00 +0200 +Subject: [PATCH v3 07/10] acpi/x86: s2idle: handle Sleep Entry/Exit calls + outside of suspend sequence + +As with Display On/Off, these calls should be made outside the suspend +sequence, to allow the EC and USB devices that are affected to complete +their power off sequence before the kernel suspends their power rails +and interrupts. + +Suggested-by: Mario Limonciello <mario.limonciello@amd.com> +Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev> +--- + kernel/power/suspend.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c +index dab299e28195..9dcdd5273318 100644 +--- a/kernel/power/suspend.c ++++ b/kernel/power/suspend.c +@@ -547,6 +547,13 @@ int suspend_devices_and_enter(suspend_state_t state) + if (state == PM_SUSPEND_TO_IDLE) + pm_set_suspend_no_platform(); + ++ /* ++ * Linux does not have the concept of a "Sleep" state. As with Display ++ * On/Off, call the platform functions for Sleep Entry/Exit prior to the ++ * suspend sequence. ++ */ ++ platform_suspend_sleep_entry(); ++ + error = platform_suspend_begin(state); + if (error) + goto Close; +@@ -577,6 +584,8 @@ int suspend_devices_and_enter(suspend_state_t state) + Close: + platform_resume_end(state); + pm_suspend_target_state = PM_SUSPEND_ON; ++ ++ platform_suspend_sleep_exit(); + return error; + + Recover_platform: +-- +2.46.2 + + +From 0825b095f26cbea829078f70d4c757ff9b2eab38 Mon Sep 17 00:00:00 2001 +From: Antheas Kapenekakis <lkml@antheas.dev> +Date: Wed, 25 Sep 2024 14:29:42 +0200 +Subject: [PATCH v3 08/10] acpi/x86: s2idle: update quirk table for Sleep + Entry/Exit + +Add delays between the Sleep Entry and Sleep Exit calls, to avoid issues +in devices that rely on them that need time to power off. + +Especially for the ROG Ally, this should allow its EC to suspend gracefully, +avoiding issues where it is stuck in its suspend state. Since the delays +are additive, steal some of the delay from Display On/Off. + +Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev> +--- + include/linux/suspend.h | 2 ++ + kernel/power/suspend.c | 21 +++++++++++++++++++-- + 2 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/include/linux/suspend.h b/include/linux/suspend.h +index 66c5b434334d..5b4d4d9ef65a 100644 +--- a/include/linux/suspend.h ++++ b/include/linux/suspend.h +@@ -148,6 +148,8 @@ struct platform_s2idle_ops { + + struct platform_s2idle_quirks { + int delay_display_off; ++ int delay_sleep_entry; ++ int delay_sleep_exit; + int delay_display_on; + }; + +diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c +index 9dcdd5273318..1352c4066822 100644 +--- a/kernel/power/suspend.c ++++ b/kernel/power/suspend.c +@@ -65,8 +65,11 @@ static DEFINE_RAW_SPINLOCK(s2idle_lock); + // The ROG Ally series disconnects its controllers on Display Off, without + // holding a lock, introducing a race condition. Add a delay to allow the + // controller to disconnect cleanly prior to suspend. ++// In addition, the EC of the device rarely (1/20 attempts) may get stuck ++// after suspend in an invalid state, where it mirros Sleep behavior. + static const struct platform_s2idle_quirks rog_ally_quirks = { +- .delay_display_off = 500, ++ .delay_display_off = 200, ++ .delay_sleep_entry = 300, + }; + + static const struct dmi_system_id platform_s2idle_quirks[] = { +@@ -548,11 +551,23 @@ int suspend_devices_and_enter(suspend_state_t state) + pm_set_suspend_no_platform(); + + /* +- * Linux does not have the concept of a "Sleep" state. As with Display ++ * Windows transitions between Modern Standby states slowly, as with ++ * Display On/Off, query the appropriate delays here for Sleep Entry/Exit. ++ */ ++ const struct dmi_system_id *s2idle_sysid = dmi_first_match( ++ platform_s2idle_quirks ++ ); ++ const struct platform_s2idle_quirks *s2idle_quirks = s2idle_sysid ? ++ s2idle_sysid->driver_data : NULL; ++ ++ /* ++ * Linux does not have the concept of a "Sleep" state. As done with Display + * On/Off, call the platform functions for Sleep Entry/Exit prior to the + * suspend sequence. + */ + platform_suspend_sleep_entry(); ++ if (s2idle_quirks && s2idle_quirks->delay_sleep_entry) ++ msleep(s2idle_quirks->delay_sleep_entry); + + error = platform_suspend_begin(state); + if (error) +@@ -585,6 +600,8 @@ int suspend_devices_and_enter(suspend_state_t state) + platform_resume_end(state); + pm_suspend_target_state = PM_SUSPEND_ON; + ++ if (s2idle_quirks && s2idle_quirks->delay_sleep_exit) ++ msleep(s2idle_quirks->delay_sleep_exit); + platform_suspend_sleep_exit(); + return error; + +-- +2.46.2 + + +From 49cafd9d1cf20250e31f34a849c505d205968ef5 Mon Sep 17 00:00:00 2001 +From: Antheas Kapenekakis <lkml@antheas.dev> +Date: Wed, 25 Sep 2024 14:41:03 +0200 +Subject: [PATCH v3 09/10] acpi/x86: s2idle: call Sleep Entry/Exit as part of + callbacks. + +Move the Sleep Entry/Exit notifications outside the suspend sequence, +with their own ACPI lock, as was done for Display On/Off. + +Suggested-by: Mario Limonciello <mario.limonciello@amd.com> +Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev> +--- + drivers/acpi/x86/s2idle.c | 69 ++++++++++++++++++++++++++++++--------- + 1 file changed, 53 insertions(+), 16 deletions(-) + +diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c +index a17e28b91326..6ff5e34c016e 100644 +--- a/drivers/acpi/x86/s2idle.c ++++ b/drivers/acpi/x86/s2idle.c +@@ -43,8 +43,8 @@ static const struct acpi_device_id lps0_device_ids[] = { + #define ACPI_LPS0_DISPLAY_ON 4 + #define ACPI_LPS0_ENTRY 5 + #define ACPI_LPS0_EXIT 6 +-#define ACPI_LPS0_MS_ENTRY 7 +-#define ACPI_LPS0_MS_EXIT 8 ++#define ACPI_LPS0_SLEEP_ENTRY 7 ++#define ACPI_LPS0_SLEEP_EXIT 8 + + /* AMD */ + #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" +@@ -61,6 +61,7 @@ static guid_t lps0_dsm_guid_microsoft; + static int lps0_dsm_func_mask_microsoft; + static int lps0_dsm_state; + static bool lsp0_dsm_in_display_off; ++static bool lsp0_dsm_in_sleep; + + /* Device constraint entry structure */ + struct lpi_device_info { +@@ -370,10 +371,10 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned int state) + return "lps0 entry"; + case ACPI_LPS0_EXIT: + return "lps0 exit"; +- case ACPI_LPS0_MS_ENTRY: +- return "lps0 ms entry"; +- case ACPI_LPS0_MS_EXIT: +- return "lps0 ms exit"; ++ case ACPI_LPS0_SLEEP_ENTRY: ++ return "lps0 sleep entry"; ++ case ACPI_LPS0_SLEEP_EXIT: ++ return "lps0 sleep exit"; + } + } else { + switch (state) { +@@ -567,6 +568,48 @@ static int acpi_s2idle_display_off(void) + return 0; + } + ++static int acpi_s2idle_sleep_entry(void) ++{ ++ if (!lps0_device_handle || sleep_no_lps0 || lps0_dsm_func_mask_microsoft <= 0) ++ return 0; ++ ++ if (WARN_ON(lsp0_dsm_in_sleep)) ++ return -EINVAL; ++ ++ lsp0_dsm_in_sleep = true; ++ acpi_scan_lock_acquire(); ++ ++ /* Modern Standby Sleep Entry */ ++ if (lps0_dsm_func_mask_microsoft > 0) ++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_ENTRY, ++ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); ++ ++ acpi_scan_lock_release(); ++ ++ return 0; ++} ++ ++static int acpi_s2idle_sleep_exit(void) ++{ ++ if (!lps0_device_handle || sleep_no_lps0 || lps0_dsm_func_mask_microsoft <= 0) ++ return 0; ++ ++ if (WARN_ON(!lsp0_dsm_in_sleep)) ++ return -EINVAL; ++ ++ lsp0_dsm_in_sleep = false; ++ acpi_scan_lock_acquire(); ++ ++ /* Modern Standby Sleep Exit */ ++ if (lps0_dsm_func_mask_microsoft > 0) ++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_EXIT, ++ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); ++ ++ acpi_scan_lock_release(); ++ ++ return 0; ++} ++ + static int acpi_s2idle_display_on(void) + { + if (!lps0_device_handle || sleep_no_lps0) +@@ -608,13 +651,9 @@ int acpi_s2idle_prepare_late(void) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD, + lps0_dsm_func_mask, lps0_dsm_guid); + +- if (lps0_dsm_func_mask_microsoft > 0) { +- /* Modern Standby entry */ +- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY, +- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); ++ if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, + lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); +- } + + if (lps0_dsm_func_mask > 0 && !acpi_s2idle_vendor_amd()) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, +@@ -659,17 +698,14 @@ void acpi_s2idle_restore_early(void) + ACPI_LPS0_EXIT, + lps0_dsm_func_mask, lps0_dsm_guid); + +- if (lps0_dsm_func_mask_microsoft > 0) { ++ if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT, + lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); +- /* Modern Standby exit */ +- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT, +- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); +- } + } + + static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { + .display_off = acpi_s2idle_display_off, ++ .sleep_entry = acpi_s2idle_sleep_entry, + .begin = acpi_s2idle_begin, + .prepare = acpi_s2idle_prepare, + .prepare_late = acpi_s2idle_prepare_late, +@@ -678,6 +714,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { + .restore_early = acpi_s2idle_restore_early, + .restore = acpi_s2idle_restore, + .end = acpi_s2idle_end, ++ .sleep_exit = acpi_s2idle_sleep_exit, + .display_on = acpi_s2idle_display_on, + }; + +-- +2.46.2 + + +From 93f8e91ade24bbf3c30c5633d57a3730d0f03a8a Mon Sep 17 00:00:00 2001 +From: Antheas Kapenekakis <lkml@antheas.dev> +Date: Wed, 25 Sep 2024 14:42:54 +0200 +Subject: [PATCH v3 10/10] [NOT FOR UPSTREAM] acpi/x86: s2idle: apply delay to + transitions for all devices + +For the purposes of testing, apply the suspend delay to all devices. +Before moving the sleep notifications outside of the suspend sequence, +the EC NOOPed in regards to the CPU of the system (e.g., did not lower +its TDP or had a race condition). Therefore, add this delay to see if +other Modern Standby systems are affected by the same quirk of the ROG +Ally. +--- + kernel/power/suspend.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c +index 1352c4066822..fa9e148f4e54 100644 +--- a/kernel/power/suspend.c ++++ b/kernel/power/suspend.c +@@ -85,6 +85,10 @@ static const struct dmi_system_id platform_s2idle_quirks[] = { + }, + .driver_data = (void *)&rog_ally_quirks + }, ++ { ++ .matches = {}, ++ .driver_data = (void *)&rog_ally_quirks ++ }, + {} + }; + +-- +2.46.2 diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec index ab84faa..93150b1 100644 --- a/SPECS/kernel.spec +++ b/SPECS/kernel.spec @@ -169,7 +169,7 @@ Summary: The Linux kernel # This is needed to do merge window version magic %define patchlevel 9 # This allows pkg_release to have configurable %%{?dist} tag -%define specrelease 207%{?buildid}%{?dist} +%define specrelease 208%{?buildid}%{?dist} # This defines the kabi tarball version %define kabiversion 6.9.12 @@ -994,8 +994,6 @@ Patch303: lenovo-legion-laptop.patch # workaround for i915 getting stuck during async page flips on Nvidia PRIME systems Patch308: 0001-drm-i915-quirks-disable-async-flipping-on-specific-d.patch Patch309: 0002-drm-i915-add-kernel-parameter-to-disable-async-page-.patch -# improve AMD SFH 1.1 gyro and accel sensitivity -Patch324: 0001-bump-the-sensitivity-of-AMD-SFH.patch # ROG Ally Patch316: rog-ally-audio-fix.patch Patch317: ROG-ALLY-NCT6775-PLATFORM.patch @@ -1035,11 +1033,8 @@ Patch334: platform-chrome-cros_ec_lpc-add-support-for-AMD-Framework-Laptops.patc # temporary patches Patch401: 0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch Patch405: mt76:-mt7921:-Disable-powersave-features-by-default.patch -Patch408: 0001-acpi-proc-idle-skip-dummy-wait.patch # Fixes the steam deck not coming back from hibernation Patch411: 0001-Revert-nvme-pci-drop-redundant-pci_enable_pcie_error.patch -# Allows corectl to work out of the box -Patch412: 0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch # fix https://gitlab.freedesktop.org/drm/amd/-/issues/3183 Patch413: amdgpu-ignore-min-pcap.patch # improve controller hiding @@ -1050,6 +1045,7 @@ Patch416: v0-oxp-sensors.patch Patch417: loki-mini-pro-hda-pin-fixes.patch Patch418: dcn32-dcn301-dcn321-mpo-reverts.patch Patch419: 0001-selinux-revert-our-use-of-vma_is_initial_heap.patch +Patch420: CVE-2024-44961.patch # Allow to set custom USB pollrate for specific devices like so: # usbcore.interrupt_interval_override=045e:00db:16,1bcf:0005:1 @@ -1900,8 +1896,6 @@ ApplyOptionalPatch lenovo-legion-laptop.patch # workaround for i915 getting stuck during async page flips on Nvidia PRIME systems ApplyOptionalPatch 0001-drm-i915-quirks-disable-async-flipping-on-specific-d.patch ApplyOptionalPatch 0002-drm-i915-add-kernel-parameter-to-disable-async-page-.patch -# improve AMD SFH 1.1 gyro and accel sensitivity -ApplyOptionalPatch 0001-bump-the-sensitivity-of-AMD-SFH.patch # ROG Ally- ApplyOptionalPatch rog-ally-audio-fix.patch ApplyOptionalPatch ROG-ALLY-NCT6775-PLATFORM.patch @@ -1942,11 +1936,8 @@ ApplyOptionalPatch platform-chrome-cros_ec_lpc-add-support-for-AMD-Framework-Lap ApplyOptionalPatch 0001-Revert-PCI-Add-a-REBAR-size-quirk-for-Sapphire-RX-56.patch # mediatek fixups ApplyOptionalPatch mt76:-mt7921:-Disable-powersave-features-by-default.patch -ApplyOptionalPatch 0001-acpi-proc-idle-skip-dummy-wait.patch # Fixes the steam deck not coming back from hibernation ApplyOptionalPatch 0001-Revert-nvme-pci-drop-redundant-pci_enable_pcie_error.patch -# enable full amd power control by default -ApplyOptionalPatch 0001-Set-amdgpu.ppfeaturemask-0xffffffff-as-default.patch # fix https://gitlab.freedesktop.org/drm/amd/-/issues/3183 ApplyOptionalPatch amdgpu-ignore-min-pcap.patch # improve controller hiding @@ -1957,6 +1948,7 @@ ApplyOptionalPatch v0-oxp-sensors.patch ApplyOptionalPatch loki-mini-pro-hda-pin-fixes.patch ApplyOptionalPatch dcn32-dcn301-dcn321-mpo-reverts.patch ApplyOptionalPatch 0001-selinux-revert-our-use-of-vma_is_initial_heap.patch +ApplyOptionalPatch CVE-2024-44961.patch # Allow to set custom USB pollrate for specific devices like so: # usbcore.interrupt_interval_override=045e:00db:16,1bcf:0005:1 @@ -4137,6 +4129,9 @@ fi\ # # %changelog +* Thu Sep 26 2024 Jan200101 <sentrycraft123@gmail.com> - 6.9.12-208.fsync +- kernel-fsync v6.9.12 cleaning + * Sun Sep 22 2024 Jan200101 <sentrycraft123@gmail.com> - 6.9.12-207.fsync - kernel-fsync v6.9.12 asus unscrew driver |