]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jul 2026 14:57:11 +0000 (16:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jul 2026 14:57:11 +0000 (16:57 +0200)
added patches:
cpufreq-fix-hotplug-suspend-race-during-reboot.patch
cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch
hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch
hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch
hid-wacom-stop-hardware-after-post-start-probe-failures.patch
posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch
sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch

queue-5.10/cpufreq-fix-hotplug-suspend-race-during-reboot.patch [new file with mode: 0644]
queue-5.10/cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch [new file with mode: 0644]
queue-5.10/hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch [new file with mode: 0644]
queue-5.10/hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch [new file with mode: 0644]
queue-5.10/hid-wacom-stop-hardware-after-post-start-probe-failures.patch [new file with mode: 0644]
queue-5.10/posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch [new file with mode: 0644]
queue-5.10/sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/cpufreq-fix-hotplug-suspend-race-during-reboot.patch b/queue-5.10/cpufreq-fix-hotplug-suspend-race-during-reboot.patch
new file mode 100644 (file)
index 0000000..3e2b967
--- /dev/null
@@ -0,0 +1,62 @@
+From a9029dd55696c651ee46912afa2a166fa456bb3e Mon Sep 17 00:00:00 2001
+From: Tianxiang Chen <nanmu@xiaomi.com>
+Date: Wed, 8 Apr 2026 22:19:14 +0800
+Subject: cpufreq: Fix hotplug-suspend race during reboot
+
+From: Tianxiang Chen <nanmu@xiaomi.com>
+
+commit a9029dd55696c651ee46912afa2a166fa456bb3e upstream.
+
+During system reboot, cpufreq_suspend() is called via the
+kernel_restart() -> device_shutdown() path. Unlike the normal system
+suspend path, the reboot path does not call freeze_processes(), so
+userspace processes and kernel threads remain active.
+
+This allows CPU hotplug operations to run concurrently with
+cpufreq_suspend(). The original code has no synchronization with CPU
+hotplug, leading to a race condition where governor_data can be freed
+by the hotplug path while cpufreq_suspend() is still accessing it,
+resulting in a null pointer dereference:
+
+  Unable to handle kernel NULL pointer dereference
+  Call Trace:
+   do_kernel_fault+0x28/0x3c
+   cpufreq_suspend+0xdc/0x160
+   device_shutdown+0x18/0x200
+   kernel_restart+0x40/0x80
+   arm64_sys_reboot+0x1b0/0x200
+
+Fix this by adding cpus_read_lock()/cpus_read_unlock() to
+cpufreq_suspend() to block CPU hotplug operations while suspend is in
+progress.
+
+Fixes: 65650b35133f ("cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown")
+Signed-off-by: Tianxiang Chen <nanmu@xiaomi.com>
+Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
+Cc: All applicable <stable@vger.kernel.org>
+[ rjw: Changelog edits ]
+Link: https://patch.msgid.link/20260408141914.35281-1-nanmu@xiaomi.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cpufreq/cpufreq.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1872,6 +1872,7 @@ void cpufreq_suspend(void)
+       if (!cpufreq_driver)
+               return;
++      cpus_read_lock();
+       if (!has_target() && !cpufreq_driver->suspend)
+               goto suspend;
+@@ -1891,6 +1892,7 @@ void cpufreq_suspend(void)
+ suspend:
+       cpufreq_suspended = true;
++      cpus_read_unlock();
+ }
+ /**
diff --git a/queue-5.10/cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch b/queue-5.10/cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch
new file mode 100644 (file)
index 0000000..b32f9db
--- /dev/null
@@ -0,0 +1,43 @@
+From 266d3dd8b757b48a576e90f018b51f7b7563cc32 Mon Sep 17 00:00:00 2001
+From: Yuho Choi <dbgh9129@gmail.com>
+Date: Thu, 16 Apr 2026 10:46:21 -0400
+Subject: cpufreq: pcc: fix use-after-free and double free in _OSC evaluation
+
+From: Yuho Choi <dbgh9129@gmail.com>
+
+commit 266d3dd8b757b48a576e90f018b51f7b7563cc32 upstream.
+
+pcc_cpufreq_do_osc() calls acpi_evaluate_object() twice for the
+two-phase _OSC negotiation. Between the two calls it freed
+output.pointer but left output.length unchanged. Since
+acpi_evaluate_object() treats a non-zero length with a non-NULL
+pointer as an existing buffer to write into, the second call wrote
+into freed memory (use-after-free). The subsequent kfree(output.pointer)
+at out_free then freed the same pointer a second time (double free).
+
+Reset output.pointer to NULL and output.length to ACPI_ALLOCATE_BUFFER
+after freeing the first result, so ACPICA allocates a fresh buffer for
+each phase independently.
+
+Fixes: 0f1d683fb35d ("[CPUFREQ] Processor Clocking Control interface driver")
+Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
+Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
+Cc: All applicable <stable@vger.kernel.org>
+Link: https://patch.msgid.link/20260416144621.93964-1-dbgh9129@gmail.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cpufreq/pcc-cpufreq.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/cpufreq/pcc-cpufreq.c
++++ b/drivers/cpufreq/pcc-cpufreq.c
+@@ -351,6 +351,8 @@ static int __init pcc_cpufreq_do_osc(acp
+       }
+       kfree(output.pointer);
++      output.pointer = NULL;
++      output.length = ACPI_ALLOCATE_BUFFER;
+       capabilities[0] = 0x0;
+       capabilities[1] = 0x1;
diff --git a/queue-5.10/hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch b/queue-5.10/hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch
new file mode 100644 (file)
index 0000000..dbd8817
--- /dev/null
@@ -0,0 +1,68 @@
+From 7705b4140d188ce22656f6e541ae7ef834c7e11a Mon Sep 17 00:00:00 2001
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+Date: Thu, 18 Jun 2026 15:06:35 +0800
+Subject: HID: lg-g15: cancel pending work on remove to fix a use-after-free
+
+From: Maoyi Xie <maoyixie.tju@gmail.com>
+
+commit 7705b4140d188ce22656f6e541ae7ef834c7e11a upstream.
+
+lg_g15_data is allocated with devm and holds a work item. The report
+handlers schedule that work straight from device input.
+lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key,
+and lg_g510_leds_event() does it too. The worker dereferences the
+lg_g15_data back through container_of.
+
+The driver had no remove callback and never cancelled the work. So if a
+report scheduled the work and the keyboard was then unplugged, devres
+freed lg_g15_data while the work was still pending or running, and the
+worker touched freed memory. This is a use-after-free. It is reachable
+as a race on device unplug.
+
+Add a remove callback that cancels the work before devres frees the
+state. g15->work is only initialized for the models that schedule it
+(G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the
+cancel on g15->work.func to avoid cancelling a work that was never set
+up. The g15 NULL test mirrors the one already in lg_g15_raw_event().
+
+Fixes: 97b741aba918 ("HID: lg-g15: Add keyboard and LCD backlight control")
+Cc: stable@vger.kernel.org
+Suggested-by: Hans de Goede <hansg@kernel.org>
+Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-lg-g15.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/hid/hid-lg-g15.c
++++ b/drivers/hid/hid-lg-g15.c
+@@ -894,11 +894,27 @@ static const struct hid_device_id lg_g15
+ };
+ MODULE_DEVICE_TABLE(hid, lg_g15_devices);
++static void lg_g15_remove(struct hid_device *hdev)
++{
++      struct lg_g15_data *g15 = hid_get_drvdata(hdev);
++
++      /*
++       * g15->work is only initialized for the models that schedule it
++       * (G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so only
++       * cancel it when it was set up.
++       */
++      if (g15 && g15->work.func)
++              cancel_work_sync(&g15->work);
++
++      hid_hw_stop(hdev);
++}
++
+ static struct hid_driver lg_g15_driver = {
+       .name                   = "lg-g15",
+       .id_table               = lg_g15_devices,
+       .raw_event              = lg_g15_raw_event,
+       .probe                  = lg_g15_probe,
++      .remove                 = lg_g15_remove,
+ };
+ module_hid_driver(lg_g15_driver);
diff --git a/queue-5.10/hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch b/queue-5.10/hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch
new file mode 100644 (file)
index 0000000..e92c6c2
--- /dev/null
@@ -0,0 +1,179 @@
+From f784fcea450617055d2d12eec5b2f6e0e38bf878 Mon Sep 17 00:00:00 2001
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Date: Wed, 10 Jun 2026 16:29:09 +0800
+Subject: HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+commit f784fcea450617055d2d12eec5b2f6e0e38bf878 upstream.
+
+sensor_hub_input_attr_get_raw_value() is limited to returning a single
+32-bit value, which is insufficient for sensors that report data larger
+than 32 bits, such as a quaternion with four s16 elements.
+
+Add sensor_hub_input_attr_read_values() that accepts a caller-provided
+buffer and accumulates incoming data until the buffer is full. The two
+paths are distinguished in sensor_hub_raw_event() by pending.max_raw_size
+being non-zero, preserving backward compatibility.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Co-developed-by: Zhang Lixu <lixu.zhang@intel.com>
+Signed-off-by: Zhang Lixu <lixu.zhang@intel.com>
+Acked-by: Jiri Kosina <jkosina@suse.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-sensor-hub.c   |   77 +++++++++++++++++++++++++++++++++++++----
+ include/linux/hid-sensor-hub.h |   25 +++++++++++++
+ 2 files changed, 96 insertions(+), 6 deletions(-)
+
+--- a/drivers/hid/hid-sensor-hub.c
++++ b/drivers/hid/hid-sensor-hub.c
+@@ -287,6 +287,54 @@ done_proc:
+ }
+ EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
++int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev,
++                                    u32 usage_id, u32 attr_usage_id,
++                                    u32 report_id,
++                                    enum sensor_hub_read_flags flag,
++                                    u32 buffer_size, u8 *buffer)
++{
++      struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
++      struct hid_report *report;
++      unsigned long flags;
++      long cycles;
++      int ret;
++
++      report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT);
++      if (!report)
++              return -EINVAL;
++
++      mutex_lock(hsdev->mutex_ptr);
++      if (flag == SENSOR_HUB_SYNC) {
++              memset(&hsdev->pending, 0, sizeof(hsdev->pending));
++              init_completion(&hsdev->pending.ready);
++              hsdev->pending.usage_id = usage_id;
++              hsdev->pending.attr_usage_id = attr_usage_id;
++              hsdev->pending.max_raw_size = buffer_size;
++              hsdev->pending.raw_data = buffer;
++
++              spin_lock_irqsave(&data->lock, flags);
++              hsdev->pending.status = true;
++              spin_unlock_irqrestore(&data->lock, flags);
++      }
++      mutex_lock(&data->mutex);
++      hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
++      mutex_unlock(&data->mutex);
++      ret = 0;
++      if (flag == SENSOR_HUB_SYNC) {
++              cycles = wait_for_completion_interruptible_timeout(&hsdev->pending.ready,
++                                                                 HZ * 5);
++              if (cycles == 0)
++                      ret = -ETIMEDOUT;
++              else if (cycles < 0)
++                      ret = cycles;
++
++              hsdev->pending.status = false;
++      }
++      mutex_unlock(hsdev->mutex_ptr);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(sensor_hub_input_attr_read_values);
+ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
+                                       u32 usage_id,
+@@ -480,6 +528,8 @@ static int sensor_hub_raw_event(struct h
+       struct hid_collection *collection = NULL;
+       void *priv = NULL;
+       struct hid_sensor_hub_device *hsdev = NULL;
++      u32 copy_size;
++      u32 avail;
+       hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
+                        report->id, size, report->type);
+@@ -519,12 +569,27 @@ static int sensor_hub_raw_event(struct h
+                                             hsdev->pending.attr_usage_id ==
+                                             report->field[i]->logical)) {
+                       hid_dbg(hdev, "data was pending ...\n");
+-                      hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
+-                      if (hsdev->pending.raw_data)
+-                              hsdev->pending.raw_size = sz;
+-                      else
+-                              hsdev->pending.raw_size = 0;
+-                      complete(&hsdev->pending.ready);
++                      if (hsdev->pending.max_raw_size) {
++                              if (hsdev->pending.index < hsdev->pending.max_raw_size) {
++                                      avail = hsdev->pending.max_raw_size - hsdev->pending.index;
++                                      copy_size = clamp(sz, 0U, avail);
++
++                                      memcpy(hsdev->pending.raw_data + hsdev->pending.index,
++                                             ptr, copy_size);
++                                      hsdev->pending.index += copy_size;
++                                      if (hsdev->pending.index >= hsdev->pending.max_raw_size) {
++                                              hsdev->pending.raw_size = hsdev->pending.index;
++                                              complete(&hsdev->pending.ready);
++                                      }
++                              }
++                      } else {
++                              hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
++                              if (hsdev->pending.raw_data)
++                                      hsdev->pending.raw_size = sz;
++                              else
++                                      hsdev->pending.raw_size = 0;
++                              complete(&hsdev->pending.ready);
++                      }
+               }
+               if (callback->capture_sample) {
+                       if (report->field[i]->logical)
+--- a/include/linux/hid-sensor-hub.h
++++ b/include/linux/hid-sensor-hub.h
+@@ -43,6 +43,8 @@ struct hid_sensor_hub_attribute_info {
+  * @attr_usage_id:    Usage Id of a field, E.g. X-AXIS for a gyro.
+  * @raw_size:         Response size for a read request.
+  * @raw_data:         Place holder for received response.
++ * @index:            Current write index into raw_data for multi-byte reads.
++ * @max_raw_size:     Total buffer size for multi-byte reads; 0 for single-value reads.
+  */
+ struct sensor_hub_pending {
+       bool status;
+@@ -51,6 +53,8 @@ struct sensor_hub_pending {
+       u32 attr_usage_id;
+       int raw_size;
+       u8  *raw_data;
++      u32 index;
++      u32 max_raw_size;
+ };
+ /**
+@@ -183,6 +187,27 @@ int sensor_hub_input_attr_get_raw_value(
+ );
+ /**
++ * sensor_hub_input_attr_read_values() - Synchronous multi-byte read request
++ * @hsdev:            Hub device instance.
++ * @usage_id:         Attribute usage id of parent physical device as per spec
++ * @attr_usage_id:    Attribute usage id as per spec
++ * @report_id:                Report id to look for
++ * @flag:             Synchronous or asynchronous read
++ * @buffer_size:      Size of the buffer in bytes
++ * @buffer:           Buffer to store the read data
++ *
++ * Issues a synchronous or asynchronous read request for an input attribute,
++ * accumulating data into the provided buffer until it is full.
++ * Return: 0 on success, -ETIMEDOUT if the device did not respond, or a
++ * negative error code.
++ */
++int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev,
++                                    u32 usage_id, u32 attr_usage_id,
++                                    u32 report_id,
++                                    enum sensor_hub_read_flags flag,
++                                    u32 buffer_size, u8 *buffer);
++
++/**
+ * sensor_hub_set_feature() - Feature set request
+ * @hsdev:     Hub device instance.
+ * @report_id: Report id to look for
diff --git a/queue-5.10/hid-wacom-stop-hardware-after-post-start-probe-failures.patch b/queue-5.10/hid-wacom-stop-hardware-after-post-start-probe-failures.patch
new file mode 100644 (file)
index 0000000..6bd4b77
--- /dev/null
@@ -0,0 +1,80 @@
+From ec2612b8ad9e642596db011dd8b6568ef1edeaa1 Mon Sep 17 00:00:00 2001
+From: Myeonghun Pak <mhun512@gmail.com>
+Date: Thu, 4 Jun 2026 13:56:58 +0900
+Subject: HID: wacom: stop hardware after post-start probe failures
+
+From: Myeonghun Pak <mhun512@gmail.com>
+
+commit ec2612b8ad9e642596db011dd8b6568ef1edeaa1 upstream.
+
+wacom_parse_and_register() starts HID hardware before registering inputs
+and initializing pad LEDs/remotes. Those later steps can fail, but their
+error paths currently release Wacom resources without stopping the HID
+hardware.
+
+Route post-hid_hw_start() failures through hid_hw_stop() before
+releasing driver resources.
+
+This issue was identified during our ongoing static-analysis research while
+reviewing kernel code.
+
+Fixes: c1d6708bf0d3 ("HID: wacom: Do not register input devices until after hid_hw_start")
+Cc: stable@vger.kernel.org
+Co-developed-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Ijae Kim <ae878000@gmail.com>
+Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
+Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/wacom_sys.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/hid/wacom_sys.c
++++ b/drivers/hid/wacom_sys.c
+@@ -2427,16 +2427,16 @@ static int wacom_parse_and_register(stru
+       error = wacom_register_inputs(wacom);
+       if (error)
+-              goto fail;
++              goto fail_hw_stop;
+       if (wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD) {
+               error = wacom_initialize_leds(wacom);
+               if (error)
+-                      goto fail;
++                      goto fail_hw_stop;
+               error = wacom_initialize_remotes(wacom);
+               if (error)
+-                      goto fail;
++                      goto fail_hw_stop;
+       }
+       if (!wireless) {
+@@ -2450,14 +2450,14 @@ static int wacom_parse_and_register(stru
+               cancel_delayed_work_sync(&wacom->init_work);
+               _wacom_query_tablet_data(wacom);
+               error = -ENODEV;
+-              goto fail_quirks;
++              goto fail_hw_stop;
+       }
+       if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) {
+               error = hid_hw_open(hdev);
+               if (error) {
+                       hid_err(hdev, "hw open failed\n");
+-                      goto fail_quirks;
++                      goto fail_hw_stop;
+               }
+       }
+@@ -2466,7 +2466,7 @@ static int wacom_parse_and_register(stru
+       return 0;
+-fail_quirks:
++fail_hw_stop:
+       hid_hw_stop(hdev);
+ fail:
+       wacom_release_resources(wacom);
diff --git a/queue-5.10/posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch b/queue-5.10/posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch
new file mode 100644 (file)
index 0000000..a194a40
--- /dev/null
@@ -0,0 +1,40 @@
+From 87bd2ad568e15b90d5f7d4bcd70342d05dad649c Mon Sep 17 00:00:00 2001
+From: WenTao Liang <vulab@iscas.ac.cn>
+Date: Fri, 12 Jun 2026 00:17:38 +0800
+Subject: posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path
+
+From: WenTao Liang <vulab@iscas.ac.cn>
+
+commit 87bd2ad568e15b90d5f7d4bcd70342d05dad649c upstream.
+
+In do_cpu_nanosleep(), posix_cpu_timer_create() takes a pid reference
+via get_pid() and stores it in timer.it.cpu.pid. If the subsequent
+posix_cpu_timer_set() call fails, the function returns immediately
+without calling posix_cpu_timer_del() to release the pid reference,
+causing a leak.
+
+Fix it by calling posix_cpu_timer_del() before the unlock-and-return
+on the error path, consistent with the other exit paths in the same
+function.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260611161738.97043-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/time/posix-cpu-timers.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -1472,6 +1472,7 @@ static int do_cpu_nanosleep(const clocki
+               spin_lock_irq(&timer.it_lock);
+               error = posix_cpu_timer_set(&timer, flags, &it, NULL);
+               if (error) {
++                      posix_cpu_timer_del(&timer);
+                       spin_unlock_irq(&timer.it_lock);
+                       return error;
+               }
diff --git a/queue-5.10/sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch b/queue-5.10/sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch
new file mode 100644 (file)
index 0000000..22a80b4
--- /dev/null
@@ -0,0 +1,100 @@
+From dd29c017aed628076e915fe4cdfb5392fd4c5cab Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Fri, 15 May 2026 10:37:40 -0400
+Subject: sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit dd29c017aed628076e915fe4cdfb5392fd4c5cab upstream.
+
+RT migration is done aggressively. When a CPU schedules out a high
+priority RT task for a lower priority task, it will look to see if there's
+any RT tasks that are waiting to run on another CPU that is of higher
+priority than the task this CPU is about to run. If it finds one, it will
+pull that task over to the CPU and allow it to run there instead.
+
+Normally, this pulling is done by looking at the RT overloaded mask (rto)
+which contains all the CPUs in the scheduler domain with RT tasks that are
+waiting to run due to a higher priority RT task currently running on their
+CPU. The CPU that is about to schedule a lower priority task will grab the
+rq lock of the overloaded CPU and move the RT task from that CPU's runqueue
+to the local one and schedule the higher priority RT task.
+
+This caused issues when a lot of CPUs would schedule a lower priority task
+at the same time. They would all try to grab the same runqueue lock of
+the CPU with the overloaded RT tasks. Only the first CPU that got in will
+get that task. All the others would wait until they got the runqueue lock
+and see there's nothing to pull and do nothing. On systems with lots of
+CPUs, this caused a large latency (up to 500us) which is beyond what
+PREEMPT_RT is to allow.
+
+The solution to that was to create an RT_PUSH_IPI logic. When any CPU
+wanted to pull a task, instead of grabbing the runqueue lock of the
+overloaded CPU, it would start by sending an IPI to the overloaded CPU,
+and that IPI handler would have the CPU with the waiting RT task do a push
+instead. Then that handler would send an IPI to the next CPU with
+overloaded RT tasks, and so on. Note, after the first CPU starts this
+process, if another CPU wanted to do a pull, it would see that the process
+has already begun and would only increment a counter to have the IPIs
+continue again.
+
+The RT_PUSH_IPI solved the latency problem with PREEMPT_RT but could cause
+a new issue with non PREEMPT_RT. Namely, softirqs run in a threaded
+context on PREEMPT_RT but they can run in an interrupt context in non-RT.
+
+If an IPI lands on a CPU that has just woken up multiple RT tasks and the
+current CPU is running a non RT or a low priority RT task, instead of
+doing a push, it would simply do a schedule on that CPU. But if a softirq
+was also executing on this CPU, the schedule would need to wait until the
+softirq finished. Until then, the CPU would still be considered overloaded
+as there are RT tasks still waiting to run on it.
+
+A live lock occurred on a workload that was doing heavy networking traffic
+on a large machine where the softirqs would run 500us out of 750us. And it
+would also be waking up RT tasks, causing the RT pull logic to be
+constantly executed.
+
+When a softirq triggered on a CPU with RT tasks queued but not running
+yet, and the other CPUs would see this CPU as being overloaded, they would
+send an IPI over to it. The CPU would notice that the waiting RT tasks are
+of higher priority than the currently running task and simply schedule
+that CPU instead. But because the softirq was executing, before it could
+schedule, it would receive another IPI to do the same. The amount of IPIs
+would slow down the currently running softirq so much that before it could
+return back to task context, it would execute another softirq never
+allowing the CPU to schedule. This live locked that CPU.
+
+As RT_PUSH_IPI was created to help PREEMPT_RT, make it default off if
+PREEMPT_RT is not enabled.
+
+Fixes: b6366f048e0c ("sched/rt: Use IPI to trigger RT task push migration instead of pulling")
+Closes: https://lore.kernel.org/all/20260506235716.2530720-1-tj@kernel.org/
+Reported-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260515103740.25ccbed8@gandalf.local.home
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sched/features.h |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/kernel/sched/features.h
++++ b/kernel/sched/features.h
+@@ -73,8 +73,16 @@ SCHED_FEAT(WARN_DOUBLE_CLOCK, false)
+  * rq lock and possibly create a large contention, sending an
+  * IPI to that CPU and let that CPU push the RT task to where
+  * it should go may be a better scenario.
++ *
++ * This is best for PREEMPT_RT, but for non-RT it can cause issues
++ * when preemption is disabled for long periods of time. Have
++ * it only default enabled for PREEMPT_RT.
+  */
++# ifdef CONFIG_PREEMPT_RT
+ SCHED_FEAT(RT_PUSH_IPI, true)
++# else
++SCHED_FEAT(RT_PUSH_IPI, false)
++# endif
+ #endif
+ SCHED_FEAT(RT_RUNTIME_SHARE, false)
index 63e8f442f94dfacfda12eca804c767359c0b95b3..5108ade063f7b0b9a8ec1d88edca856424e9c6c1 100644 (file)
@@ -84,3 +84,10 @@ bluetooth-bnep-pin-l2cap-connection-during-netdev-registration.patch
 bluetooth-fix-uaf-in-bt_accept_dequeue.patch
 bluetooth-l2cap-validate-option-length-before-reading-conf-opt-value.patch
 net-drop-the-lock-in-skb_may_tx_timestamp.patch
+sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch
+cpufreq-fix-hotplug-suspend-race-during-reboot.patch
+cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch
+posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch
+hid-wacom-stop-hardware-after-post-start-probe-failures.patch
+hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch
+hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch