]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 May 2025 10:34:42 +0000 (12:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 May 2025 10:34:42 +0000 (12:34 +0200)
added patches:
clocksource-i8253-use-raw_spinlock_irqsave-in-clockevent_i8253_disable.patch
memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch
module-ensure-that-kobject_put-is-safe-for-module-type-kobjects.patch
ocfs2-implement-handshaking-with-ocfs2-recovery-thread.patch
ocfs2-stop-quota-recovery-before-disabling-quotas.patch
ocfs2-switch-osb-disable_recovery-to-enum.patch
smb-client-avoid-race-in-open_cached_dir-with-lease-breaks.patch
usb-cdnsp-fix-issue-with-resuming-from-l1.patch
usb-cdnsp-fix-l1-resume-issue-for-rtl_revision_new_lpm-version.patch
usb-gadget-f_ecm-add-get_status-callback.patch
usb-gadget-tegra-xudc-ack-st_rc-after-clearing-ctrl_run.patch
usb-gadget-use-get_status-callback-to-set-remote-wakeup-capability.patch
usb-host-tegra-prevent-host-controller-crash-when-otg-port-is-used.patch
x86-microcode-consolidate-the-loader-enablement-checking.patch
xen-swiotlb-use-swiotlb-bouncing-if-kmalloc-allocation-demands-it.patch
xenbus-use-kref-to-track-req-lifetime.patch

17 files changed:
queue-6.6/clocksource-i8253-use-raw_spinlock_irqsave-in-clockevent_i8253_disable.patch [new file with mode: 0644]
queue-6.6/memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch [new file with mode: 0644]
queue-6.6/module-ensure-that-kobject_put-is-safe-for-module-type-kobjects.patch [new file with mode: 0644]
queue-6.6/ocfs2-implement-handshaking-with-ocfs2-recovery-thread.patch [new file with mode: 0644]
queue-6.6/ocfs2-stop-quota-recovery-before-disabling-quotas.patch [new file with mode: 0644]
queue-6.6/ocfs2-switch-osb-disable_recovery-to-enum.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/smb-client-avoid-race-in-open_cached_dir-with-lease-breaks.patch [new file with mode: 0644]
queue-6.6/usb-cdnsp-fix-issue-with-resuming-from-l1.patch [new file with mode: 0644]
queue-6.6/usb-cdnsp-fix-l1-resume-issue-for-rtl_revision_new_lpm-version.patch [new file with mode: 0644]
queue-6.6/usb-gadget-f_ecm-add-get_status-callback.patch [new file with mode: 0644]
queue-6.6/usb-gadget-tegra-xudc-ack-st_rc-after-clearing-ctrl_run.patch [new file with mode: 0644]
queue-6.6/usb-gadget-use-get_status-callback-to-set-remote-wakeup-capability.patch [new file with mode: 0644]
queue-6.6/usb-host-tegra-prevent-host-controller-crash-when-otg-port-is-used.patch [new file with mode: 0644]
queue-6.6/x86-microcode-consolidate-the-loader-enablement-checking.patch [new file with mode: 0644]
queue-6.6/xen-swiotlb-use-swiotlb-bouncing-if-kmalloc-allocation-demands-it.patch [new file with mode: 0644]
queue-6.6/xenbus-use-kref-to-track-req-lifetime.patch [new file with mode: 0644]

diff --git a/queue-6.6/clocksource-i8253-use-raw_spinlock_irqsave-in-clockevent_i8253_disable.patch b/queue-6.6/clocksource-i8253-use-raw_spinlock_irqsave-in-clockevent_i8253_disable.patch
new file mode 100644 (file)
index 0000000..11b6094
--- /dev/null
@@ -0,0 +1,53 @@
+From 94cff94634e506a4a44684bee1875d2dbf782722 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Fri, 4 Apr 2025 15:31:16 +0200
+Subject: clocksource/i8253: Use raw_spinlock_irqsave() in clockevent_i8253_disable()
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit 94cff94634e506a4a44684bee1875d2dbf782722 upstream.
+
+On x86 during boot, clockevent_i8253_disable() can be invoked via
+x86_late_time_init -> hpet_time_init() -> pit_timer_init() which happens
+with enabled interrupts.
+
+If some of the old i8253 hardware is actually used then lockdep will notice
+that i8253_lock is used in hard interrupt context. This causes lockdep to
+complain because it observed the lock being acquired with interrupts
+enabled and in hard interrupt context.
+
+Make clockevent_i8253_disable() acquire the lock with
+raw_spinlock_irqsave() to cure this.
+
+[ tglx: Massage change log and use guard() ]
+
+Fixes: c8c4076723dac ("x86/timer: Skip PIT initialization on modern chipsets")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20250404133116.p-XRWJXf@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clocksource/i8253.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/clocksource/i8253.c
++++ b/drivers/clocksource/i8253.c
+@@ -103,7 +103,7 @@ int __init clocksource_i8253_init(void)
+ #ifdef CONFIG_CLKEVT_I8253
+ void clockevent_i8253_disable(void)
+ {
+-      raw_spin_lock(&i8253_lock);
++      guard(raw_spinlock_irqsave)(&i8253_lock);
+       /*
+        * Writing the MODE register should stop the counter, according to
+@@ -132,8 +132,6 @@ void clockevent_i8253_disable(void)
+       outb_p(0, PIT_CH0);
+       outb_p(0x30, PIT_MODE);
+-
+-      raw_spin_unlock(&i8253_lock);
+ }
+ static int pit_shutdown(struct clock_event_device *evt)
diff --git a/queue-6.6/memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch b/queue-6.6/memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch
new file mode 100644 (file)
index 0000000..a4e58b7
--- /dev/null
@@ -0,0 +1,72 @@
+From da8bf5daa5e55a6af2b285ecda460d6454712ff4 Mon Sep 17 00:00:00 2001
+From: Tom Lendacky <thomas.lendacky@amd.com>
+Date: Thu, 8 May 2025 12:24:10 -0500
+Subject: memblock: Accept allocated memory before use in memblock_double_array()
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+commit da8bf5daa5e55a6af2b285ecda460d6454712ff4 upstream.
+
+When increasing the array size in memblock_double_array() and the slab
+is not yet available, a call to memblock_find_in_range() is used to
+reserve/allocate memory. However, the range returned may not have been
+accepted, which can result in a crash when booting an SNP guest:
+
+  RIP: 0010:memcpy_orig+0x68/0x130
+  Code: ...
+  RSP: 0000:ffffffff9cc03ce8 EFLAGS: 00010006
+  RAX: ff11001ff83e5000 RBX: 0000000000000000 RCX: fffffffffffff000
+  RDX: 0000000000000bc0 RSI: ffffffff9dba8860 RDI: ff11001ff83e5c00
+  RBP: 0000000000002000 R08: 0000000000000000 R09: 0000000000002000
+  R10: 000000207fffe000 R11: 0000040000000000 R12: ffffffff9d06ef78
+  R13: ff11001ff83e5000 R14: ffffffff9dba7c60 R15: 0000000000000c00
+  memblock_double_array+0xff/0x310
+  memblock_add_range+0x1fb/0x2f0
+  memblock_reserve+0x4f/0xa0
+  memblock_alloc_range_nid+0xac/0x130
+  memblock_alloc_internal+0x53/0xc0
+  memblock_alloc_try_nid+0x3d/0xa0
+  swiotlb_init_remap+0x149/0x2f0
+  mem_init+0xb/0xb0
+  mm_core_init+0x8f/0x350
+  start_kernel+0x17e/0x5d0
+  x86_64_start_reservations+0x14/0x30
+  x86_64_start_kernel+0x92/0xa0
+  secondary_startup_64_no_verify+0x194/0x19b
+
+Mitigate this by calling accept_memory() on the memory range returned
+before the slab is available.
+
+Prior to v6.12, the accept_memory() interface used a 'start' and 'end'
+parameter instead of 'start' and 'size', therefore the accept_memory()
+call must be adjusted to specify 'start + size' for 'end' when applying
+to kernels prior to v6.12.
+
+Cc: stable@vger.kernel.org # see patch description, needs adjustments for <= 6.11
+Fixes: dcdfdd40fa82 ("mm: Add support for unaccepted memory")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Link: https://lore.kernel.org/r/da1ac73bf4ded761e21b4e4bb5178382a580cd73.1746725050.git.thomas.lendacky@amd.com
+Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memblock.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -460,7 +460,14 @@ static int __init_memblock memblock_doub
+                               min(new_area_start, memblock.current_limit),
+                               new_alloc_size, PAGE_SIZE);
+-              new_array = addr ? __va(addr) : NULL;
++              if (addr) {
++                      /* The memory may not have been accepted, yet. */
++                      accept_memory(addr, new_alloc_size);
++
++                      new_array = __va(addr);
++              } else {
++                      new_array = NULL;
++              }
+       }
+       if (!addr) {
+               pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",
diff --git a/queue-6.6/module-ensure-that-kobject_put-is-safe-for-module-type-kobjects.patch b/queue-6.6/module-ensure-that-kobject_put-is-safe-for-module-type-kobjects.patch
new file mode 100644 (file)
index 0000000..c648f11
--- /dev/null
@@ -0,0 +1,43 @@
+From a6aeb739974ec73e5217c75a7c008a688d3d5cf1 Mon Sep 17 00:00:00 2001
+From: Dmitry Antipov <dmantipov@yandex.ru>
+Date: Wed, 7 May 2025 09:50:44 +0300
+Subject: module: ensure that kobject_put() is safe for module type kobjects
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+commit a6aeb739974ec73e5217c75a7c008a688d3d5cf1 upstream.
+
+In 'lookup_or_create_module_kobject()', an internal kobject is created
+using 'module_ktype'. So call to 'kobject_put()' on error handling
+path causes an attempt to use an uninitialized completion pointer in
+'module_kobject_release()'. In this scenario, we just want to release
+kobject without an extra synchronization required for a regular module
+unloading process, so adding an extra check whether 'complete()' is
+actually required makes 'kobject_put()' safe.
+
+Reported-by: syzbot+7fb8a372e1f6add936dd@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=7fb8a372e1f6add936dd
+Fixes: 942e443127e9 ("module: Fix mod->mkobj.kobj potentially freed too early")
+Cc: stable@vger.kernel.org
+Suggested-by: Petr Pavlu <petr.pavlu@suse.com>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Link: https://lore.kernel.org/r/20250507065044.86529-1-dmantipov@yandex.ru
+Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/params.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/params.c
++++ b/kernel/params.c
+@@ -945,7 +945,9 @@ struct kset *module_kset;
+ static void module_kobj_release(struct kobject *kobj)
+ {
+       struct module_kobject *mk = to_module_kobject(kobj);
+-      complete(mk->kobj_completion);
++
++      if (mk->kobj_completion)
++              complete(mk->kobj_completion);
+ }
+ const struct kobj_type module_ktype = {
diff --git a/queue-6.6/ocfs2-implement-handshaking-with-ocfs2-recovery-thread.patch b/queue-6.6/ocfs2-implement-handshaking-with-ocfs2-recovery-thread.patch
new file mode 100644 (file)
index 0000000..68b0f71
--- /dev/null
@@ -0,0 +1,139 @@
+From 8f947e0fd595951460f5a6e1ac29baa82fa02eab Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 24 Apr 2025 15:45:12 +0200
+Subject: ocfs2: implement handshaking with ocfs2 recovery thread
+
+From: Jan Kara <jack@suse.cz>
+
+commit 8f947e0fd595951460f5a6e1ac29baa82fa02eab upstream.
+
+We will need ocfs2 recovery thread to acknowledge transitions of
+recovery_state when disabling particular types of recovery.  This is
+similar to what currently happens when disabling recovery completely, just
+more general.  Implement the handshake and use it for exit from recovery.
+
+Link: https://lkml.kernel.org/r/20250424134515.18933-5-jack@suse.cz
+Fixes: 5f530de63cfc ("ocfs2: Use s_umount for quota recovery protection")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+Tested-by: Heming Zhao <heming.zhao@suse.com>
+Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Murad Masimov <m.masimov@mt-integration.ru>
+Cc: Shichangkuo <shi.changkuo@h3c.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/journal.c |   52 +++++++++++++++++++++++++++++++++++-----------------
+ fs/ocfs2/ocfs2.h   |    4 ++++
+ 2 files changed, 39 insertions(+), 17 deletions(-)
+
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -190,31 +190,48 @@ int ocfs2_recovery_init(struct ocfs2_sup
+       return 0;
+ }
+-/* we can't grab the goofy sem lock from inside wait_event, so we use
+- * memory barriers to make sure that we'll see the null task before
+- * being woken up */
+ static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)
+ {
+-      mb();
+       return osb->recovery_thread_task != NULL;
+ }
+-void ocfs2_recovery_exit(struct ocfs2_super *osb)
++static void ocfs2_recovery_disable(struct ocfs2_super *osb,
++                                 enum ocfs2_recovery_state state)
+ {
+-      struct ocfs2_recovery_map *rm;
+-
+-      /* disable any new recovery threads and wait for any currently
+-       * running ones to exit. Do this before setting the vol_state. */
+       mutex_lock(&osb->recovery_lock);
+-      osb->recovery_state = OCFS2_REC_DISABLED;
++      /*
++       * If recovery thread is not running, we can directly transition to
++       * final state.
++       */
++      if (!ocfs2_recovery_thread_running(osb)) {
++              osb->recovery_state = state + 1;
++              goto out_lock;
++      }
++      osb->recovery_state = state;
++      /* Wait for recovery thread to acknowledge state transition */
++      wait_event_cmd(osb->recovery_event,
++                     !ocfs2_recovery_thread_running(osb) ||
++                              osb->recovery_state >= state + 1,
++                     mutex_unlock(&osb->recovery_lock),
++                     mutex_lock(&osb->recovery_lock));
++out_lock:
+       mutex_unlock(&osb->recovery_lock);
+-      wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
+-      /* At this point, we know that no more recovery threads can be
+-       * launched, so wait for any recovery completion work to
+-       * complete. */
++      /*
++       * At this point we know that no more recovery work can be queued so
++       * wait for any recovery completion work to complete.
++       */
+       if (osb->ocfs2_wq)
+               flush_workqueue(osb->ocfs2_wq);
++}
++
++void ocfs2_recovery_exit(struct ocfs2_super *osb)
++{
++      struct ocfs2_recovery_map *rm;
++
++      /* disable any new recovery threads and wait for any currently
++       * running ones to exit. Do this before setting the vol_state. */
++      ocfs2_recovery_disable(osb, OCFS2_REC_WANT_DISABLE);
+       /*
+        * Now that recovery is shut down, and the osb is about to be
+@@ -1569,7 +1586,8 @@ bail:
+       ocfs2_free_replay_slots(osb);
+       osb->recovery_thread_task = NULL;
+-      mb(); /* sync with ocfs2_recovery_thread_running */
++      if (osb->recovery_state == OCFS2_REC_WANT_DISABLE)
++              osb->recovery_state = OCFS2_REC_DISABLED;
+       wake_up(&osb->recovery_event);
+       mutex_unlock(&osb->recovery_lock);
+@@ -1585,13 +1603,13 @@ void ocfs2_recovery_thread(struct ocfs2_
+       int was_set = -1;
+       mutex_lock(&osb->recovery_lock);
+-      if (osb->recovery_state < OCFS2_REC_DISABLED)
++      if (osb->recovery_state < OCFS2_REC_WANT_DISABLE)
+               was_set = ocfs2_recovery_map_set(osb, node_num);
+       trace_ocfs2_recovery_thread(node_num, osb->node_num,
+               osb->recovery_state, osb->recovery_thread_task, was_set);
+-      if (osb->recovery_state == OCFS2_REC_DISABLED)
++      if (osb->recovery_state >= OCFS2_REC_WANT_DISABLE)
+               goto out;
+       if (osb->recovery_thread_task)
+--- a/fs/ocfs2/ocfs2.h
++++ b/fs/ocfs2/ocfs2.h
+@@ -310,6 +310,10 @@ void ocfs2_initialize_journal_triggers(s
+ enum ocfs2_recovery_state {
+       OCFS2_REC_ENABLED = 0,
++      OCFS2_REC_WANT_DISABLE,
++      /*
++       * Must be OCFS2_REC_WANT_DISABLE + 1 for ocfs2_recovery_exit() to work
++       */
+       OCFS2_REC_DISABLED,
+ };
diff --git a/queue-6.6/ocfs2-stop-quota-recovery-before-disabling-quotas.patch b/queue-6.6/ocfs2-stop-quota-recovery-before-disabling-quotas.patch
new file mode 100644 (file)
index 0000000..521965c
--- /dev/null
@@ -0,0 +1,171 @@
+From fcaf3b2683b05a9684acdebda706a12025a6927a Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 24 Apr 2025 15:45:13 +0200
+Subject: ocfs2: stop quota recovery before disabling quotas
+
+From: Jan Kara <jack@suse.cz>
+
+commit fcaf3b2683b05a9684acdebda706a12025a6927a upstream.
+
+Currently quota recovery is synchronized with unmount using sb->s_umount
+semaphore.  That is however prone to deadlocks because
+flush_workqueue(osb->ocfs2_wq) called from umount code can wait for quota
+recovery to complete while ocfs2_finish_quota_recovery() waits for
+sb->s_umount semaphore.
+
+Grabbing of sb->s_umount semaphore in ocfs2_finish_quota_recovery() is
+only needed to protect that function from disabling of quotas from
+ocfs2_dismount_volume().  Handle this problem by disabling quota recovery
+early during unmount in ocfs2_dismount_volume() instead so that we can
+drop acquisition of sb->s_umount from ocfs2_finish_quota_recovery().
+
+Link: https://lkml.kernel.org/r/20250424134515.18933-6-jack@suse.cz
+Fixes: 5f530de63cfc ("ocfs2: Use s_umount for quota recovery protection")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reported-by: Shichangkuo <shi.changkuo@h3c.com>
+Reported-by: Murad Masimov <m.masimov@mt-integration.ru>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+Tested-by: Heming Zhao <heming.zhao@suse.com>
+Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/journal.c     |   20 ++++++++++++++++++--
+ fs/ocfs2/journal.h     |    1 +
+ fs/ocfs2/ocfs2.h       |    6 ++++++
+ fs/ocfs2/quota_local.c |    9 ++-------
+ fs/ocfs2/super.c       |    3 +++
+ 5 files changed, 30 insertions(+), 9 deletions(-)
+
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -225,6 +225,11 @@ out_lock:
+               flush_workqueue(osb->ocfs2_wq);
+ }
++void ocfs2_recovery_disable_quota(struct ocfs2_super *osb)
++{
++      ocfs2_recovery_disable(osb, OCFS2_REC_QUOTA_WANT_DISABLE);
++}
++
+ void ocfs2_recovery_exit(struct ocfs2_super *osb)
+ {
+       struct ocfs2_recovery_map *rm;
+@@ -1489,6 +1494,18 @@ static int __ocfs2_recovery_thread(void
+               }
+       }
+ restart:
++      if (quota_enabled) {
++              mutex_lock(&osb->recovery_lock);
++              /* Confirm that recovery thread will no longer recover quotas */
++              if (osb->recovery_state == OCFS2_REC_QUOTA_WANT_DISABLE) {
++                      osb->recovery_state = OCFS2_REC_QUOTA_DISABLED;
++                      wake_up(&osb->recovery_event);
++              }
++              if (osb->recovery_state >= OCFS2_REC_QUOTA_DISABLED)
++                      quota_enabled = 0;
++              mutex_unlock(&osb->recovery_lock);
++      }
++
+       status = ocfs2_super_lock(osb, 1);
+       if (status < 0) {
+               mlog_errno(status);
+@@ -1592,8 +1609,7 @@ bail:
+       mutex_unlock(&osb->recovery_lock);
+-      if (quota_enabled)
+-              kfree(rm_quota);
++      kfree(rm_quota);
+       return status;
+ }
+--- a/fs/ocfs2/journal.h
++++ b/fs/ocfs2/journal.h
+@@ -148,6 +148,7 @@ void ocfs2_wait_for_recovery(struct ocfs
+ int ocfs2_recovery_init(struct ocfs2_super *osb);
+ void ocfs2_recovery_exit(struct ocfs2_super *osb);
++void ocfs2_recovery_disable_quota(struct ocfs2_super *osb);
+ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
+ void ocfs2_free_replay_slots(struct ocfs2_super *osb);
+--- a/fs/ocfs2/ocfs2.h
++++ b/fs/ocfs2/ocfs2.h
+@@ -310,6 +310,12 @@ void ocfs2_initialize_journal_triggers(s
+ enum ocfs2_recovery_state {
+       OCFS2_REC_ENABLED = 0,
++      OCFS2_REC_QUOTA_WANT_DISABLE,
++      /*
++       * Must be OCFS2_REC_QUOTA_WANT_DISABLE + 1 for
++       * ocfs2_recovery_disable_quota() to work.
++       */
++      OCFS2_REC_QUOTA_DISABLED,
+       OCFS2_REC_WANT_DISABLE,
+       /*
+        * Must be OCFS2_REC_WANT_DISABLE + 1 for ocfs2_recovery_exit() to work
+--- a/fs/ocfs2/quota_local.c
++++ b/fs/ocfs2/quota_local.c
+@@ -453,8 +453,7 @@ out:
+ /* Sync changes in local quota file into global quota file and
+  * reinitialize local quota file.
+- * The function expects local quota file to be already locked and
+- * s_umount locked in shared mode. */
++ * The function expects local quota file to be already locked. */
+ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
+                                         int type,
+                                         struct ocfs2_quota_recovery *rec)
+@@ -585,7 +584,6 @@ int ocfs2_finish_quota_recovery(struct o
+ {
+       unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
+                                             LOCAL_GROUP_QUOTA_SYSTEM_INODE };
+-      struct super_block *sb = osb->sb;
+       struct ocfs2_local_disk_dqinfo *ldinfo;
+       struct buffer_head *bh;
+       handle_t *handle;
+@@ -597,7 +595,6 @@ int ocfs2_finish_quota_recovery(struct o
+       printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+-      down_read(&sb->s_umount);
+       for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
+               if (list_empty(&(rec->r_list[type])))
+                       continue;
+@@ -674,7 +671,6 @@ out_put:
+                       break;
+       }
+ out:
+-      up_read(&sb->s_umount);
+       kfree(rec);
+       return status;
+ }
+@@ -840,8 +836,7 @@ static int ocfs2_local_free_info(struct
+       ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
+       /*
+-       * s_umount held in exclusive mode protects us against racing with
+-       * recovery thread...
++       * ocfs2_dismount_volume() has already aborted quota recovery...
+        */
+       if (oinfo->dqi_rec) {
+               ocfs2_free_quota_recovery(oinfo->dqi_rec);
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1870,6 +1870,9 @@ static void ocfs2_dismount_volume(struct
+       /* Orphan scan should be stopped as early as possible */
+       ocfs2_orphan_scan_stop(osb);
++      /* Stop quota recovery so that we can disable quotas */
++      ocfs2_recovery_disable_quota(osb);
++
+       ocfs2_disable_quotas(osb);
+       /* All dquots should be freed by now */
diff --git a/queue-6.6/ocfs2-switch-osb-disable_recovery-to-enum.patch b/queue-6.6/ocfs2-switch-osb-disable_recovery-to-enum.patch
new file mode 100644 (file)
index 0000000..af2cf29
--- /dev/null
@@ -0,0 +1,107 @@
+From c0fb83088f0cc4ee4706e0495ee8b06f49daa716 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 24 Apr 2025 15:45:11 +0200
+Subject: ocfs2: switch osb->disable_recovery to enum
+
+From: Jan Kara <jack@suse.cz>
+
+commit c0fb83088f0cc4ee4706e0495ee8b06f49daa716 upstream.
+
+Patch series "ocfs2: Fix deadlocks in quota recovery", v3.
+
+This implements another approach to fixing quota recovery deadlocks.  We
+avoid grabbing sb->s_umount semaphore from ocfs2_finish_quota_recovery()
+and instead stop quota recovery early in ocfs2_dismount_volume().
+
+
+This patch (of 3):
+
+We will need more recovery states than just pure enable / disable to fix
+deadlocks with quota recovery.  Switch osb->disable_recovery to enum.
+
+Link: https://lkml.kernel.org/r/20250424134301.1392-1-jack@suse.cz
+Link: https://lkml.kernel.org/r/20250424134515.18933-4-jack@suse.cz
+Fixes: 5f530de63cfc ("ocfs2: Use s_umount for quota recovery protection")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+Tested-by: Heming Zhao <heming.zhao@suse.com>
+Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Murad Masimov <m.masimov@mt-integration.ru>
+Cc: Shichangkuo <shi.changkuo@h3c.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/journal.c |   14 ++++++++------
+ fs/ocfs2/ocfs2.h   |    7 ++++++-
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -174,7 +174,7 @@ int ocfs2_recovery_init(struct ocfs2_sup
+       struct ocfs2_recovery_map *rm;
+       mutex_init(&osb->recovery_lock);
+-      osb->disable_recovery = 0;
++      osb->recovery_state = OCFS2_REC_ENABLED;
+       osb->recovery_thread_task = NULL;
+       init_waitqueue_head(&osb->recovery_event);
+@@ -206,7 +206,7 @@ void ocfs2_recovery_exit(struct ocfs2_su
+       /* disable any new recovery threads and wait for any currently
+        * running ones to exit. Do this before setting the vol_state. */
+       mutex_lock(&osb->recovery_lock);
+-      osb->disable_recovery = 1;
++      osb->recovery_state = OCFS2_REC_DISABLED;
+       mutex_unlock(&osb->recovery_lock);
+       wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
+@@ -1582,14 +1582,16 @@ bail:
+ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
+ {
++      int was_set = -1;
++
+       mutex_lock(&osb->recovery_lock);
++      if (osb->recovery_state < OCFS2_REC_DISABLED)
++              was_set = ocfs2_recovery_map_set(osb, node_num);
+       trace_ocfs2_recovery_thread(node_num, osb->node_num,
+-              osb->disable_recovery, osb->recovery_thread_task,
+-              osb->disable_recovery ?
+-              -1 : ocfs2_recovery_map_set(osb, node_num));
++              osb->recovery_state, osb->recovery_thread_task, was_set);
+-      if (osb->disable_recovery)
++      if (osb->recovery_state == OCFS2_REC_DISABLED)
+               goto out;
+       if (osb->recovery_thread_task)
+--- a/fs/ocfs2/ocfs2.h
++++ b/fs/ocfs2/ocfs2.h
+@@ -308,6 +308,11 @@ enum ocfs2_journal_trigger_type {
+ void ocfs2_initialize_journal_triggers(struct super_block *sb,
+                                      struct ocfs2_triggers triggers[]);
++enum ocfs2_recovery_state {
++      OCFS2_REC_ENABLED = 0,
++      OCFS2_REC_DISABLED,
++};
++
+ struct ocfs2_journal;
+ struct ocfs2_slot_info;
+ struct ocfs2_recovery_map;
+@@ -370,7 +375,7 @@ struct ocfs2_super
+       struct ocfs2_recovery_map *recovery_map;
+       struct ocfs2_replay_map *replay_map;
+       struct task_struct *recovery_thread_task;
+-      int disable_recovery;
++      enum ocfs2_recovery_state recovery_state;
+       wait_queue_head_t checkpoint_event;
+       struct ocfs2_journal *journal;
+       unsigned long osb_commit_interval;
index dec339c55fa03b6c538a4ea1684814fa451e9f2b..2b6116fab120dc40673bf1745602bd3a0ae7e4d9 100644 (file)
@@ -55,3 +55,19 @@ drm-amdgpu-hdp5.2-use-memcfg-register-to-post-the-write-for-hdp-flush.patch
 drm-amdgpu-hdp5-use-memcfg-register-to-post-the-write-for-hdp-flush.patch
 drm-amdgpu-hdp6-use-memcfg-register-to-post-the-write-for-hdp-flush.patch
 usb-uhci-platform-make-the-clock-really-optional.patch
+smb-client-avoid-race-in-open_cached_dir-with-lease-breaks.patch
+xen-swiotlb-use-swiotlb-bouncing-if-kmalloc-allocation-demands-it.patch
+xenbus-use-kref-to-track-req-lifetime.patch
+clocksource-i8253-use-raw_spinlock_irqsave-in-clockevent_i8253_disable.patch
+memblock-accept-allocated-memory-before-use-in-memblock_double_array.patch
+module-ensure-that-kobject_put-is-safe-for-module-type-kobjects.patch
+x86-microcode-consolidate-the-loader-enablement-checking.patch
+ocfs2-switch-osb-disable_recovery-to-enum.patch
+ocfs2-implement-handshaking-with-ocfs2-recovery-thread.patch
+ocfs2-stop-quota-recovery-before-disabling-quotas.patch
+usb-cdnsp-fix-issue-with-resuming-from-l1.patch
+usb-cdnsp-fix-l1-resume-issue-for-rtl_revision_new_lpm-version.patch
+usb-gadget-f_ecm-add-get_status-callback.patch
+usb-gadget-tegra-xudc-ack-st_rc-after-clearing-ctrl_run.patch
+usb-gadget-use-get_status-callback-to-set-remote-wakeup-capability.patch
+usb-host-tegra-prevent-host-controller-crash-when-otg-port-is-used.patch
diff --git a/queue-6.6/smb-client-avoid-race-in-open_cached_dir-with-lease-breaks.patch b/queue-6.6/smb-client-avoid-race-in-open_cached_dir-with-lease-breaks.patch
new file mode 100644 (file)
index 0000000..1c823c3
--- /dev/null
@@ -0,0 +1,89 @@
+From 3ca02e63edccb78ef3659bebc68579c7224a6ca2 Mon Sep 17 00:00:00 2001
+From: Paul Aurich <paul@darkrain42.org>
+Date: Tue, 6 May 2025 22:28:09 -0700
+Subject: smb: client: Avoid race in open_cached_dir with lease breaks
+
+From: Paul Aurich <paul@darkrain42.org>
+
+commit 3ca02e63edccb78ef3659bebc68579c7224a6ca2 upstream.
+
+A pre-existing valid cfid returned from find_or_create_cached_dir might
+race with a lease break, meaning open_cached_dir doesn't consider it
+valid, and thinks it's newly-constructed. This leaks a dentry reference
+if the allocation occurs before the queued lease break work runs.
+
+Avoid the race by extending holding the cfid_list_lock across
+find_or_create_cached_dir and when the result is checked.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Henrique Carvalho <henrique.carvalho@suse.com>
+Signed-off-by: Paul Aurich <paul@darkrain42.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/cached_dir.c |   10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+--- a/fs/smb/client/cached_dir.c
++++ b/fs/smb/client/cached_dir.c
+@@ -29,7 +29,6 @@ static struct cached_fid *find_or_create
+ {
+       struct cached_fid *cfid;
+-      spin_lock(&cfids->cfid_list_lock);
+       list_for_each_entry(cfid, &cfids->entries, entry) {
+               if (!strcmp(cfid->path, path)) {
+                       /*
+@@ -38,25 +37,20 @@ static struct cached_fid *find_or_create
+                        * being deleted due to a lease break.
+                        */
+                       if (!cfid->time || !cfid->has_lease) {
+-                              spin_unlock(&cfids->cfid_list_lock);
+                               return NULL;
+                       }
+                       kref_get(&cfid->refcount);
+-                      spin_unlock(&cfids->cfid_list_lock);
+                       return cfid;
+               }
+       }
+       if (lookup_only) {
+-              spin_unlock(&cfids->cfid_list_lock);
+               return NULL;
+       }
+       if (cfids->num_entries >= max_cached_dirs) {
+-              spin_unlock(&cfids->cfid_list_lock);
+               return NULL;
+       }
+       cfid = init_cached_dir(path);
+       if (cfid == NULL) {
+-              spin_unlock(&cfids->cfid_list_lock);
+               return NULL;
+       }
+       cfid->cfids = cfids;
+@@ -74,7 +68,6 @@ static struct cached_fid *find_or_create
+        */
+       cfid->has_lease = true;
+-      spin_unlock(&cfids->cfid_list_lock);
+       return cfid;
+ }
+@@ -185,8 +178,10 @@ replay_again:
+       if (!utf16_path)
+               return -ENOMEM;
++      spin_lock(&cfids->cfid_list_lock);
+       cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs);
+       if (cfid == NULL) {
++              spin_unlock(&cfids->cfid_list_lock);
+               kfree(utf16_path);
+               return -ENOENT;
+       }
+@@ -195,7 +190,6 @@ replay_again:
+        * Otherwise, it is either a new entry or laundromat worker removed it
+        * from @cfids->entries.  Caller will put last reference if the latter.
+        */
+-      spin_lock(&cfids->cfid_list_lock);
+       if (cfid->has_lease && cfid->time) {
+               spin_unlock(&cfids->cfid_list_lock);
+               *ret_cfid = cfid;
diff --git a/queue-6.6/usb-cdnsp-fix-issue-with-resuming-from-l1.patch b/queue-6.6/usb-cdnsp-fix-issue-with-resuming-from-l1.patch
new file mode 100644 (file)
index 0000000..29541d4
--- /dev/null
@@ -0,0 +1,149 @@
+From 241e2ce88e5a494be7a5d44c0697592f1632fbee Mon Sep 17 00:00:00 2001
+From: Pawel Laszczak <pawell@cadence.com>
+Date: Fri, 18 Apr 2025 04:55:16 +0000
+Subject: usb: cdnsp: Fix issue with resuming from L1
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+commit 241e2ce88e5a494be7a5d44c0697592f1632fbee upstream.
+
+In very rare cases after resuming controller from L1 to L0 it reads
+registers before the clock UTMI have been enabled and as the result
+driver reads incorrect value.
+Most of registers are in APB domain clock but some of them (e.g. PORTSC)
+are in UTMI domain clock.
+After entering to L1 state the UTMI clock can be disabled.
+When controller transition from L1 to L0 the port status change event is
+reported and in interrupt runtime function driver reads PORTSC.
+During this read operation controller synchronize UTMI and APB domain
+but UTMI clock is still disabled and in result it reads 0xFFFFFFFF value.
+To fix this issue driver increases APB timeout value.
+
+The issue is platform specific and if the default value of APB timeout
+is not sufficient then this time should be set Individually for each
+platform.
+
+Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/PH7PR07MB953846C57973E4DB134CAA71DDBF2@PH7PR07MB9538.namprd07.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdnsp-gadget.c |   29 +++++++++++++++++++++++++++++
+ drivers/usb/cdns3/cdnsp-gadget.h |    3 +++
+ drivers/usb/cdns3/cdnsp-pci.c    |   12 ++++++++++--
+ drivers/usb/cdns3/core.h         |    3 +++
+ 4 files changed, 45 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/cdns3/cdnsp-gadget.c
++++ b/drivers/usb/cdns3/cdnsp-gadget.c
+@@ -138,6 +138,26 @@ static void cdnsp_clear_port_change_bit(
+              (portsc & PORT_CHANGE_BITS), port_regs);
+ }
++static void cdnsp_set_apb_timeout_value(struct cdnsp_device *pdev)
++{
++      struct cdns *cdns = dev_get_drvdata(pdev->dev);
++      __le32 __iomem *reg;
++      void __iomem *base;
++      u32 offset = 0;
++      u32 val;
++
++      if (!cdns->override_apb_timeout)
++              return;
++
++      base = &pdev->cap_regs->hc_capbase;
++      offset = cdnsp_find_next_ext_cap(base, offset, D_XEC_PRE_REGS_CAP);
++      reg = base + offset + REG_CHICKEN_BITS_3_OFFSET;
++
++      val  = le32_to_cpu(readl(reg));
++      val = CHICKEN_APB_TIMEOUT_SET(val, cdns->override_apb_timeout);
++      writel(cpu_to_le32(val), reg);
++}
++
+ static void cdnsp_set_chicken_bits_2(struct cdnsp_device *pdev, u32 bit)
+ {
+       __le32 __iomem *reg;
+@@ -1801,6 +1821,15 @@ static int cdnsp_gen_setup(struct cdnsp_
+       pdev->hci_version = HC_VERSION(pdev->hcc_params);
+       pdev->hcc_params = readl(&pdev->cap_regs->hcc_params);
++      /*
++       * Override the APB timeout value to give the controller more time for
++       * enabling UTMI clock and synchronizing APB and UTMI clock domains.
++       * This fix is platform specific and is required to fixes issue with
++       * reading incorrect value from PORTSC register after resuming
++       * from L1 state.
++       */
++      cdnsp_set_apb_timeout_value(pdev);
++
+       cdnsp_get_rev_cap(pdev);
+       /* Make sure the Device Controller is halted. */
+--- a/drivers/usb/cdns3/cdnsp-gadget.h
++++ b/drivers/usb/cdns3/cdnsp-gadget.h
+@@ -520,6 +520,9 @@ struct cdnsp_rev_cap {
+ #define REG_CHICKEN_BITS_2_OFFSET     0x48
+ #define CHICKEN_XDMA_2_TP_CACHE_DIS   BIT(28)
++#define REG_CHICKEN_BITS_3_OFFSET       0x4C
++#define CHICKEN_APB_TIMEOUT_SET(p, val) (((p) & ~GENMASK(21, 0)) | (val))
++
+ /* XBUF Extended Capability ID. */
+ #define XBUF_CAP_ID                   0xCB
+ #define XBUF_RX_TAG_MASK_0_OFFSET     0x1C
+--- a/drivers/usb/cdns3/cdnsp-pci.c
++++ b/drivers/usb/cdns3/cdnsp-pci.c
+@@ -33,6 +33,8 @@
+ #define CDNS_DRD_ID           0x0100
+ #define CDNS_DRD_IF           (PCI_CLASS_SERIAL_USB << 8 | 0x80)
++#define CHICKEN_APB_TIMEOUT_VALUE       0x1C20
++
+ static struct pci_dev *cdnsp_get_second_fun(struct pci_dev *pdev)
+ {
+       /*
+@@ -144,6 +146,14 @@ static int cdnsp_pci_probe(struct pci_de
+               cdnsp->otg_irq = pdev->irq;
+       }
++      /*
++       * Cadence PCI based platform require some longer timeout for APB
++       * to fixes domain clock synchronization issue after resuming
++       * controller from L1 state.
++       */
++      cdnsp->override_apb_timeout = CHICKEN_APB_TIMEOUT_VALUE;
++      pci_set_drvdata(pdev, cdnsp);
++
+       if (pci_is_enabled(func)) {
+               cdnsp->dev = dev;
+               cdnsp->gadget_init = cdnsp_gadget_init;
+@@ -153,8 +163,6 @@ static int cdnsp_pci_probe(struct pci_de
+                       goto free_cdnsp;
+       }
+-      pci_set_drvdata(pdev, cdnsp);
+-
+       device_wakeup_enable(&pdev->dev);
+       if (pci_dev_run_wake(pdev))
+               pm_runtime_put_noidle(&pdev->dev);
+--- a/drivers/usb/cdns3/core.h
++++ b/drivers/usb/cdns3/core.h
+@@ -79,6 +79,8 @@ struct cdns3_platform_data {
+  * @pdata: platform data from glue layer
+  * @lock: spinlock structure
+  * @xhci_plat_data: xhci private data structure pointer
++ * @override_apb_timeout: hold value of APB timeout. For value 0 the default
++ *                        value in CHICKEN_BITS_3 will be preserved.
+  * @gadget_init: pointer to gadget initialization function
+  */
+ struct cdns {
+@@ -117,6 +119,7 @@ struct cdns {
+       struct cdns3_platform_data      *pdata;
+       spinlock_t                      lock;
+       struct xhci_plat_priv           *xhci_plat_data;
++      u32                             override_apb_timeout;
+       int (*gadget_init)(struct cdns *cdns);
+ };
diff --git a/queue-6.6/usb-cdnsp-fix-l1-resume-issue-for-rtl_revision_new_lpm-version.patch b/queue-6.6/usb-cdnsp-fix-l1-resume-issue-for-rtl_revision_new_lpm-version.patch
new file mode 100644 (file)
index 0000000..a1533c2
--- /dev/null
@@ -0,0 +1,76 @@
+From 8614ecdb1570e4fffe87ebdc62b613ed66f1f6a6 Mon Sep 17 00:00:00 2001
+From: Pawel Laszczak <pawell@cadence.com>
+Date: Fri, 25 Apr 2025 05:55:40 +0000
+Subject: usb: cdnsp: fix L1 resume issue for RTL_REVISION_NEW_LPM version
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+commit 8614ecdb1570e4fffe87ebdc62b613ed66f1f6a6 upstream.
+
+The controllers with rtl version larger than
+RTL_REVISION_NEW_LPM (0x00002700) has bug which causes that controller
+doesn't resume from L1 state. It happens if after receiving LPM packet
+controller starts transitioning to L1 and in this moment the driver force
+resuming by write operation to PORTSC.PLS.
+It's corner case and happens when write operation to PORTSC occurs during
+device delay before transitioning to L1 after transmitting ACK
+time (TL1TokenRetry).
+
+Forcing transition from L1->L0 by driver for revision larger than
+RTL_REVISION_NEW_LPM is not needed, so driver can simply fix this issue
+through block call of cdnsp_force_l0_go function.
+
+Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/PH7PR07MB9538B55C3A6E71F9ED29E980DD842@PH7PR07MB9538.namprd07.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdnsp-gadget.c |    2 ++
+ drivers/usb/cdns3/cdnsp-gadget.h |    3 +++
+ drivers/usb/cdns3/cdnsp-ring.c   |    3 ++-
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/cdnsp-gadget.c
++++ b/drivers/usb/cdns3/cdnsp-gadget.c
+@@ -1796,6 +1796,8 @@ static void cdnsp_get_rev_cap(struct cdn
+       reg += cdnsp_find_next_ext_cap(reg, 0, RTL_REV_CAP);
+       pdev->rev_cap  = reg;
++      pdev->rtl_revision = readl(&pdev->rev_cap->rtl_revision);
++
+       dev_info(pdev->dev, "Rev: %08x/%08x, eps: %08x, buff: %08x/%08x\n",
+                readl(&pdev->rev_cap->ctrl_revision),
+                readl(&pdev->rev_cap->rtl_revision),
+--- a/drivers/usb/cdns3/cdnsp-gadget.h
++++ b/drivers/usb/cdns3/cdnsp-gadget.h
+@@ -1362,6 +1362,7 @@ struct cdnsp_port {
+  * @rev_cap: Controller Capabilities Registers.
+  * @hcs_params1: Cached register copies of read-only HCSPARAMS1
+  * @hcc_params: Cached register copies of read-only HCCPARAMS1
++ * @rtl_revision: Cached controller rtl revision.
+  * @setup: Temporary buffer for setup packet.
+  * @ep0_preq: Internal allocated request used during enumeration.
+  * @ep0_stage: ep0 stage during enumeration process.
+@@ -1416,6 +1417,8 @@ struct cdnsp_device {
+       __u32 hcs_params1;
+       __u32 hcs_params3;
+       __u32 hcc_params;
++      #define RTL_REVISION_NEW_LPM 0x2700
++      __u32 rtl_revision;
+       /* Lock used in interrupt thread context. */
+       spinlock_t lock;
+       struct usb_ctrlrequest setup;
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -308,7 +308,8 @@ static bool cdnsp_ring_ep_doorbell(struc
+       writel(db_value, reg_addr);
+-      cdnsp_force_l0_go(pdev);
++      if (pdev->rtl_revision < RTL_REVISION_NEW_LPM)
++              cdnsp_force_l0_go(pdev);
+       /* Doorbell was set. */
+       return true;
diff --git a/queue-6.6/usb-gadget-f_ecm-add-get_status-callback.patch b/queue-6.6/usb-gadget-f_ecm-add-get_status-callback.patch
new file mode 100644 (file)
index 0000000..3547a20
--- /dev/null
@@ -0,0 +1,47 @@
+From 8e3820271c517ceb89ab7442656ba49fa23ee1d0 Mon Sep 17 00:00:00 2001
+From: Prashanth K <prashanth.k@oss.qualcomm.com>
+Date: Tue, 22 Apr 2025 16:02:29 +0530
+Subject: usb: gadget: f_ecm: Add get_status callback
+
+From: Prashanth K <prashanth.k@oss.qualcomm.com>
+
+commit 8e3820271c517ceb89ab7442656ba49fa23ee1d0 upstream.
+
+When host sends GET_STATUS to ECM interface, handle the request
+from the function driver. Since the interface is wakeup capable,
+set the corresponding bit, and set RW bit if the function is
+already armed for wakeup by the host.
+
+Cc: stable <stable@kernel.org>
+Fixes: 481c225c4802 ("usb: gadget: Handle function suspend feature selector")
+Signed-off-by: Prashanth K <prashanth.k@oss.qualcomm.com>
+Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20250422103231.1954387-2-prashanth.k@oss.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_ecm.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/gadget/function/f_ecm.c
++++ b/drivers/usb/gadget/function/f_ecm.c
+@@ -892,6 +892,12 @@ static void ecm_resume(struct usb_functi
+       gether_resume(&ecm->port);
+ }
++static int ecm_get_status(struct usb_function *f)
++{
++      return (f->func_wakeup_armed ? USB_INTRF_STAT_FUNC_RW : 0) |
++              USB_INTRF_STAT_FUNC_RW_CAP;
++}
++
+ static void ecm_free(struct usb_function *f)
+ {
+       struct f_ecm *ecm;
+@@ -960,6 +966,7 @@ static struct usb_function *ecm_alloc(st
+       ecm->port.func.disable = ecm_disable;
+       ecm->port.func.free_func = ecm_free;
+       ecm->port.func.suspend = ecm_suspend;
++      ecm->port.func.get_status = ecm_get_status;
+       ecm->port.func.resume = ecm_resume;
+       return &ecm->port.func;
diff --git a/queue-6.6/usb-gadget-tegra-xudc-ack-st_rc-after-clearing-ctrl_run.patch b/queue-6.6/usb-gadget-tegra-xudc-ack-st_rc-after-clearing-ctrl_run.patch
new file mode 100644 (file)
index 0000000..22fed06
--- /dev/null
@@ -0,0 +1,40 @@
+From 59820fde001500c167342257650541280c622b73 Mon Sep 17 00:00:00 2001
+From: Wayne Chang <waynec@nvidia.com>
+Date: Fri, 18 Apr 2025 16:12:28 +0800
+Subject: usb: gadget: tegra-xudc: ACK ST_RC after clearing CTRL_RUN
+
+From: Wayne Chang <waynec@nvidia.com>
+
+commit 59820fde001500c167342257650541280c622b73 upstream.
+
+We identified a bug where the ST_RC bit in the status register was not
+being acknowledged after clearing the CTRL_RUN bit in the control
+register. This could lead to unexpected behavior in the USB gadget
+drivers.
+
+This patch resolves the issue by adding the necessary code to explicitly
+acknowledge ST_RC after clearing CTRL_RUN based on the programming
+sequence, ensuring proper state transition.
+
+Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Link: https://lore.kernel.org/r/20250418081228.1194779-1-waynec@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/tegra-xudc.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -1749,6 +1749,10 @@ static int __tegra_xudc_ep_disable(struc
+               val = xudc_readl(xudc, CTRL);
+               val &= ~CTRL_RUN;
+               xudc_writel(xudc, val, CTRL);
++
++              val = xudc_readl(xudc, ST);
++              if (val & ST_RC)
++                      xudc_writel(xudc, ST_RC, ST);
+       }
+       dev_info(xudc->dev, "ep %u disabled\n", ep->index);
diff --git a/queue-6.6/usb-gadget-use-get_status-callback-to-set-remote-wakeup-capability.patch b/queue-6.6/usb-gadget-use-get_status-callback-to-set-remote-wakeup-capability.patch
new file mode 100644 (file)
index 0000000..a2b3065
--- /dev/null
@@ -0,0 +1,63 @@
+From 5977a58dd5a4865198b0204b998adb0f634abe19 Mon Sep 17 00:00:00 2001
+From: Prashanth K <prashanth.k@oss.qualcomm.com>
+Date: Tue, 22 Apr 2025 16:02:30 +0530
+Subject: usb: gadget: Use get_status callback to set remote wakeup capability
+
+From: Prashanth K <prashanth.k@oss.qualcomm.com>
+
+commit 5977a58dd5a4865198b0204b998adb0f634abe19 upstream.
+
+Currently when the host sends GET_STATUS request for an interface,
+we use get_status callbacks to set/clear remote wakeup capability
+of that interface. And if get_status callback isn't present for
+that interface, then we assume its remote wakeup capability based
+on bmAttributes.
+
+Now consider a scenario, where we have a USB configuration with
+multiple interfaces (say ECM + ADB), here ECM is remote wakeup
+capable and as of now ADB isn't. And bmAttributes will indicate
+the device as wakeup capable. With the current implementation,
+when host sends GET_STATUS request for both interfaces, we will
+set FUNC_RW_CAP for both. This results in USB3 CV Chapter 9.15
+(Function Remote Wakeup Test) failures as host expects remote
+wakeup from both interfaces.
+
+The above scenario is just an example, and the failure can be
+observed if we use configuration with any interface except ECM.
+Hence avoid configuring remote wakeup capability from composite
+driver based on bmAttributes, instead use get_status callbacks
+and let the function drivers decide this.
+
+Cc: stable <stable@kernel.org>
+Fixes: 481c225c4802 ("usb: gadget: Handle function suspend feature selector")
+Signed-off-by: Prashanth K <prashanth.k@oss.qualcomm.com>
+Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20250422103231.1954387-3-prashanth.k@oss.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/composite.c |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -2011,15 +2011,13 @@ composite_setup(struct usb_gadget *gadge
+               if (f->get_status) {
+                       status = f->get_status(f);
++
+                       if (status < 0)
+                               break;
+-              } else {
+-                      /* Set D0 and D1 bits based on func wakeup capability */
+-                      if (f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP) {
+-                              status |= USB_INTRF_STAT_FUNC_RW_CAP;
+-                              if (f->func_wakeup_armed)
+-                                      status |= USB_INTRF_STAT_FUNC_RW;
+-                      }
++
++                      /* if D5 is not set, then device is not wakeup capable */
++                      if (!(f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP))
++                              status &= ~(USB_INTRF_STAT_FUNC_RW_CAP | USB_INTRF_STAT_FUNC_RW);
+               }
+               put_unaligned_le16(status & 0x0000ffff, req->buf);
diff --git a/queue-6.6/usb-host-tegra-prevent-host-controller-crash-when-otg-port-is-used.patch b/queue-6.6/usb-host-tegra-prevent-host-controller-crash-when-otg-port-is-used.patch
new file mode 100644 (file)
index 0000000..fb601a4
--- /dev/null
@@ -0,0 +1,66 @@
+From 732f35cf8bdfece582f6e4a9c659119036577308 Mon Sep 17 00:00:00 2001
+From: Jim Lin <jilin@nvidia.com>
+Date: Tue, 22 Apr 2025 19:40:01 +0800
+Subject: usb: host: tegra: Prevent host controller crash when OTG port is used
+
+From: Jim Lin <jilin@nvidia.com>
+
+commit 732f35cf8bdfece582f6e4a9c659119036577308 upstream.
+
+When a USB device is connected to the OTG port, the tegra_xhci_id_work()
+routine transitions the PHY to host mode and calls xhci_hub_control()
+with the SetPortFeature command to enable port power.
+
+In certain cases, the XHCI controller may be in a low-power state
+when this operation occurs. If xhci_hub_control() is invoked while
+the controller is suspended, the PORTSC register may return 0xFFFFFFFF,
+indicating a read failure. This causes xhci_hc_died() to be triggered,
+leading to host controller shutdown.
+
+Example backtrace:
+[  105.445736] Workqueue: events tegra_xhci_id_work
+[  105.445747]  dump_backtrace+0x0/0x1e8
+[  105.445759]  xhci_hc_died.part.48+0x40/0x270
+[  105.445769]  tegra_xhci_set_port_power+0xc0/0x240
+[  105.445774]  tegra_xhci_id_work+0x130/0x240
+
+To prevent this, ensure the controller is fully resumed before
+interacting with hardware registers by calling pm_runtime_get_sync()
+prior to the host mode transition and xhci_hub_control().
+
+Fixes: f836e7843036 ("usb: xhci-tegra: Add OTG support")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Jim Lin <jilin@nvidia.com>
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Link: https://lore.kernel.org/r/20250422114001.126367-1-waynec@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-tegra.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/host/xhci-tegra.c
++++ b/drivers/usb/host/xhci-tegra.c
+@@ -1363,6 +1363,7 @@ static void tegra_xhci_id_work(struct wo
+       tegra->otg_usb3_port = tegra_xusb_padctl_get_usb3_companion(tegra->padctl,
+                                                                   tegra->otg_usb2_port);
++      pm_runtime_get_sync(tegra->dev);
+       if (tegra->host_mode) {
+               /* switch to host mode */
+               if (tegra->otg_usb3_port >= 0) {
+@@ -1392,6 +1393,7 @@ static void tegra_xhci_id_work(struct wo
+               }
+               tegra_xhci_set_port_power(tegra, true, true);
++              pm_runtime_mark_last_busy(tegra->dev);
+       } else {
+               if (tegra->otg_usb3_port >= 0)
+@@ -1399,6 +1401,7 @@ static void tegra_xhci_id_work(struct wo
+               tegra_xhci_set_port_power(tegra, true, false);
+       }
++      pm_runtime_put_autosuspend(tegra->dev);
+ }
+ #if IS_ENABLED(CONFIG_PM) || IS_ENABLED(CONFIG_PM_SLEEP)
diff --git a/queue-6.6/x86-microcode-consolidate-the-loader-enablement-checking.patch b/queue-6.6/x86-microcode-consolidate-the-loader-enablement-checking.patch
new file mode 100644 (file)
index 0000000..0e5cd09
--- /dev/null
@@ -0,0 +1,228 @@
+From 5214a9f6c0f56644acb9d2cbb58facf1856d322b Mon Sep 17 00:00:00 2001
+From: "Borislav Petkov (AMD)" <bp@alien8.de>
+Date: Mon, 14 Apr 2025 11:59:33 +0200
+Subject: x86/microcode: Consolidate the loader enablement checking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+commit 5214a9f6c0f56644acb9d2cbb58facf1856d322b upstream.
+
+Consolidate the whole logic which determines whether the microcode loader
+should be enabled or not into a single function and call it everywhere.
+
+Well, almost everywhere - not in mk_early_pgtbl_32() because there the kernel
+is running without paging enabled and checking dis_ucode_ldr et al would
+require physical addresses and uglification of the code.
+
+But since this is 32-bit, the easier thing to do is to simply map the initrd
+unconditionally especially since that mapping is getting removed later anyway
+by zap_early_initrd_mapping() and avoid the uglification.
+
+In doing so, address the issue of old 486er machines without CPUID
+support, not booting current kernels.
+
+  [ mingo: Fix no previous prototype for ‘microcode_loader_disabled’ [-Wmissing-prototypes] ]
+
+Fixes: 4c585af7180c1 ("x86/boot/32: Temporarily map initrd for microcode loading")
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable@kernel.org>
+Link: https://lore.kernel.org/r/CANpbe9Wm3z8fy9HbgS8cuhoj0TREYEEkBipDuhgkWFvqX0UoVQ@mail.gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/microcode.h         |    2 +
+ arch/x86/kernel/cpu/microcode/amd.c      |    6 ++-
+ arch/x86/kernel/cpu/microcode/core.c     |   58 ++++++++++++++++++-------------
+ arch/x86/kernel/cpu/microcode/intel.c    |    2 -
+ arch/x86/kernel/cpu/microcode/internal.h |    1 
+ arch/x86/kernel/head32.c                 |    4 --
+ 6 files changed, 41 insertions(+), 32 deletions(-)
+
+--- a/arch/x86/include/asm/microcode.h
++++ b/arch/x86/include/asm/microcode.h
+@@ -17,10 +17,12 @@ struct ucode_cpu_info {
+ void load_ucode_bsp(void);
+ void load_ucode_ap(void);
+ void microcode_bsp_resume(void);
++bool __init microcode_loader_disabled(void);
+ #else
+ static inline void load_ucode_bsp(void)       { }
+ static inline void load_ucode_ap(void) { }
+ static inline void microcode_bsp_resume(void) { }
++static inline bool __init microcode_loader_disabled(void) { return false; }
+ #endif
+ extern unsigned long initrd_start_early;
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -1102,15 +1102,17 @@ static enum ucode_state load_microcode_a
+ static int __init save_microcode_in_initrd(void)
+ {
+-      unsigned int cpuid_1_eax = native_cpuid_eax(1);
+       struct cpuinfo_x86 *c = &boot_cpu_data;
+       struct cont_desc desc = { 0 };
++      unsigned int cpuid_1_eax;
+       enum ucode_state ret;
+       struct cpio_data cp;
+-      if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
++      if (microcode_loader_disabled() || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
+               return 0;
++      cpuid_1_eax = native_cpuid_eax(1);
++
+       if (!find_blobs_in_containers(&cp))
+               return -EINVAL;
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -43,8 +43,8 @@
+ #define DRIVER_VERSION        "2.2"
+-static struct microcode_ops   *microcode_ops;
+-bool dis_ucode_ldr = true;
++static struct microcode_ops *microcode_ops;
++static bool dis_ucode_ldr = false;
+ bool force_minrev = IS_ENABLED(CONFIG_MICROCODE_LATE_FORCE_MINREV);
+ module_param(force_minrev, bool, S_IRUSR | S_IWUSR);
+@@ -91,6 +91,9 @@ static bool amd_check_current_patch_leve
+       u32 lvl, dummy, i;
+       u32 *levels;
++      if (x86_cpuid_vendor() != X86_VENDOR_AMD)
++              return false;
++
+       native_rdmsr(MSR_AMD64_PATCH_LEVEL, lvl, dummy);
+       levels = final_levels;
+@@ -102,27 +105,29 @@ static bool amd_check_current_patch_leve
+       return false;
+ }
+-static bool __init check_loader_disabled_bsp(void)
++bool __init microcode_loader_disabled(void)
+ {
+-      static const char *__dis_opt_str = "dis_ucode_ldr";
+-      const char *cmdline = boot_command_line;
+-      const char *option  = __dis_opt_str;
++      if (dis_ucode_ldr)
++              return true;
+       /*
+-       * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not
+-       * completely accurate as xen pv guests don't see that CPUID bit set but
+-       * that's good enough as they don't land on the BSP path anyway.
++       * Disable when:
++       *
++       * 1) The CPU does not support CPUID.
++       *
++       * 2) Bit 31 in CPUID[1]:ECX is clear
++       *    The bit is reserved for hypervisor use. This is still not
++       *    completely accurate as XEN PV guests don't see that CPUID bit
++       *    set, but that's good enough as they don't land on the BSP
++       *    path anyway.
++       *
++       * 3) Certain AMD patch levels are not allowed to be
++       *    overwritten.
+        */
+-      if (native_cpuid_ecx(1) & BIT(31))
+-              return true;
+-
+-      if (x86_cpuid_vendor() == X86_VENDOR_AMD) {
+-              if (amd_check_current_patch_level())
+-                      return true;
+-      }
+-
+-      if (cmdline_find_option_bool(cmdline, option) <= 0)
+-              dis_ucode_ldr = false;
++      if (!have_cpuid_p() ||
++          native_cpuid_ecx(1) & BIT(31) ||
++          amd_check_current_patch_level())
++              dis_ucode_ldr = true;
+       return dis_ucode_ldr;
+ }
+@@ -132,7 +137,10 @@ void __init load_ucode_bsp(void)
+       unsigned int cpuid_1_eax;
+       bool intel = true;
+-      if (!have_cpuid_p())
++      if (cmdline_find_option_bool(boot_command_line, "dis_ucode_ldr") > 0)
++              dis_ucode_ldr = true;
++
++      if (microcode_loader_disabled())
+               return;
+       cpuid_1_eax = native_cpuid_eax(1);
+@@ -153,9 +161,6 @@ void __init load_ucode_bsp(void)
+               return;
+       }
+-      if (check_loader_disabled_bsp())
+-              return;
+-
+       if (intel)
+               load_ucode_intel_bsp(&early_data);
+       else
+@@ -166,6 +171,11 @@ void load_ucode_ap(void)
+ {
+       unsigned int cpuid_1_eax;
++      /*
++       * Can't use microcode_loader_disabled() here - .init section
++       * hell. It doesn't have to either - the BSP variant must've
++       * parsed cmdline already anyway.
++       */
+       if (dis_ucode_ldr)
+               return;
+@@ -817,7 +827,7 @@ static int __init microcode_init(void)
+       struct cpuinfo_x86 *c = &boot_cpu_data;
+       int error;
+-      if (dis_ucode_ldr)
++      if (microcode_loader_disabled())
+               return -EINVAL;
+       if (c->x86_vendor == X86_VENDOR_INTEL)
+--- a/arch/x86/kernel/cpu/microcode/intel.c
++++ b/arch/x86/kernel/cpu/microcode/intel.c
+@@ -389,7 +389,7 @@ static int __init save_builtin_microcode
+       if (xchg(&ucode_patch_va, NULL) != UCODE_BSP_LOADED)
+               return 0;
+-      if (dis_ucode_ldr || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
++      if (microcode_loader_disabled() || boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+               return 0;
+       uci.mc = get_microcode_blob(&uci, true);
+--- a/arch/x86/kernel/cpu/microcode/internal.h
++++ b/arch/x86/kernel/cpu/microcode/internal.h
+@@ -94,7 +94,6 @@ static inline unsigned int x86_cpuid_fam
+       return x86_family(eax);
+ }
+-extern bool dis_ucode_ldr;
+ extern bool force_minrev;
+ #ifdef CONFIG_CPU_SUP_AMD
+--- a/arch/x86/kernel/head32.c
++++ b/arch/x86/kernel/head32.c
+@@ -145,10 +145,6 @@ void __init __no_stack_protector mk_earl
+       *ptr = (unsigned long)ptep + PAGE_OFFSET;
+ #ifdef CONFIG_MICROCODE_INITRD32
+-      /* Running on a hypervisor? */
+-      if (native_cpuid_ecx(1) & BIT(31))
+-              return;
+-
+       params = (struct boot_params *)__pa_nodebug(&boot_params);
+       if (!params->hdr.ramdisk_size || !params->hdr.ramdisk_image)
+               return;
diff --git a/queue-6.6/xen-swiotlb-use-swiotlb-bouncing-if-kmalloc-allocation-demands-it.patch b/queue-6.6/xen-swiotlb-use-swiotlb-bouncing-if-kmalloc-allocation-demands-it.patch
new file mode 100644 (file)
index 0000000..8e9aae4
--- /dev/null
@@ -0,0 +1,42 @@
+From cd9c058489053e172a6654cad82ee936d1b09fab Mon Sep 17 00:00:00 2001
+From: John Ernberg <john.ernberg@actia.se>
+Date: Fri, 2 May 2025 11:40:55 +0000
+Subject: xen: swiotlb: Use swiotlb bouncing if kmalloc allocation demands it
+
+From: John Ernberg <john.ernberg@actia.se>
+
+commit cd9c058489053e172a6654cad82ee936d1b09fab upstream.
+
+Xen swiotlb support was missed when the patch set starting with
+4ab5f8ec7d71 ("mm/slab: decouple ARCH_KMALLOC_MINALIGN from
+ARCH_DMA_MINALIGN") was merged.
+
+When running Xen on iMX8QXP, a SoC without IOMMU, the effect was that USB
+transfers ended up corrupted when there was more than one URB inflight at
+the same time.
+
+Add a call to dma_kmalloc_needs_bounce() to make sure that allocations too
+small for DMA get bounced via swiotlb.
+
+Closes: https://lore.kernel.org/linux-usb/ab2776f0-b838-4cf6-a12a-c208eb6aad59@actia.se/
+Fixes: 4ab5f8ec7d71 ("mm/slab: decouple ARCH_KMALLOC_MINALIGN from ARCH_DMA_MINALIGN")
+Cc: stable@kernel.org # v6.5+
+Signed-off-by: John Ernberg <john.ernberg@actia.se>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Message-ID: <20250502114043.1968976-2-john.ernberg@actia.se>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/swiotlb-xen.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/xen/swiotlb-xen.c
++++ b/drivers/xen/swiotlb-xen.c
+@@ -216,6 +216,7 @@ static dma_addr_t xen_swiotlb_map_page(s
+        * buffering it.
+        */
+       if (dma_capable(dev, dev_addr, size, true) &&
++          !dma_kmalloc_needs_bounce(dev, size, dir) &&
+           !range_straddles_page_boundary(phys, size) &&
+               !xen_arch_need_swiotlb(dev, phys, dev_addr) &&
+               !is_swiotlb_force_bounce(dev))
diff --git a/queue-6.6/xenbus-use-kref-to-track-req-lifetime.patch b/queue-6.6/xenbus-use-kref-to-track-req-lifetime.patch
new file mode 100644 (file)
index 0000000..2b5bf13
--- /dev/null
@@ -0,0 +1,172 @@
+From 1f0304dfd9d217c2f8b04a9ef4b3258a66eedd27 Mon Sep 17 00:00:00 2001
+From: Jason Andryuk <jason.andryuk@amd.com>
+Date: Tue, 6 May 2025 17:09:33 -0400
+Subject: xenbus: Use kref to track req lifetime
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jason Andryuk <jason.andryuk@amd.com>
+
+commit 1f0304dfd9d217c2f8b04a9ef4b3258a66eedd27 upstream.
+
+Marek reported seeing a NULL pointer fault in the xenbus_thread
+callstack:
+BUG: kernel NULL pointer dereference, address: 0000000000000000
+RIP: e030:__wake_up_common+0x4c/0x180
+Call Trace:
+ <TASK>
+ __wake_up_common_lock+0x82/0xd0
+ process_msg+0x18e/0x2f0
+ xenbus_thread+0x165/0x1c0
+
+process_msg+0x18e is req->cb(req).  req->cb is set to xs_wake_up(), a
+thin wrapper around wake_up(), or xenbus_dev_queue_reply().  It seems
+like it was xs_wake_up() in this case.
+
+It seems like req may have woken up the xs_wait_for_reply(), which
+kfree()ed the req.  When xenbus_thread resumes, it faults on the zero-ed
+data.
+
+Linux Device Drivers 2nd edition states:
+"Normally, a wake_up call can cause an immediate reschedule to happen,
+meaning that other processes might run before wake_up returns."
+... which would match the behaviour observed.
+
+Change to keeping two krefs on each request.  One for the caller, and
+one for xenbus_thread.  Each will kref_put() when finished, and the last
+will free it.
+
+This use of kref matches the description in
+Documentation/core-api/kref.rst
+
+Link: https://lore.kernel.org/xen-devel/ZO0WrR5J0xuwDIxW@mail-itl/
+Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Fixes: fd8aa9095a95 ("xen: optimize xenbus driver for multiple concurrent xenstore accesses")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Message-ID: <20250506210935.5607-1-jason.andryuk@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/xen/xenbus/xenbus.h              |    2 ++
+ drivers/xen/xenbus/xenbus_comms.c        |    9 ++++-----
+ drivers/xen/xenbus/xenbus_dev_frontend.c |    2 +-
+ drivers/xen/xenbus/xenbus_xs.c           |   18 ++++++++++++++++--
+ 4 files changed, 23 insertions(+), 8 deletions(-)
+
+--- a/drivers/xen/xenbus/xenbus.h
++++ b/drivers/xen/xenbus/xenbus.h
+@@ -77,6 +77,7 @@ enum xb_req_state {
+ struct xb_req_data {
+       struct list_head list;
+       wait_queue_head_t wq;
++      struct kref kref;
+       struct xsd_sockmsg msg;
+       uint32_t caller_req_id;
+       enum xsd_sockmsg_type type;
+@@ -103,6 +104,7 @@ int xb_init_comms(void);
+ void xb_deinit_comms(void);
+ int xs_watch_msg(struct xs_watch_event *event);
+ void xs_request_exit(struct xb_req_data *req);
++void xs_free_req(struct kref *kref);
+ int xenbus_match(struct device *_dev, struct device_driver *_drv);
+ int xenbus_dev_probe(struct device *_dev);
+--- a/drivers/xen/xenbus/xenbus_comms.c
++++ b/drivers/xen/xenbus/xenbus_comms.c
+@@ -309,8 +309,8 @@ static int process_msg(void)
+                       virt_wmb();
+                       req->state = xb_req_state_got_reply;
+                       req->cb(req);
+-              } else
+-                      kfree(req);
++              }
++              kref_put(&req->kref, xs_free_req);
+       }
+       mutex_unlock(&xs_response_mutex);
+@@ -386,14 +386,13 @@ static int process_writes(void)
+       state.req->msg.type = XS_ERROR;
+       state.req->err = err;
+       list_del(&state.req->list);
+-      if (state.req->state == xb_req_state_aborted)
+-              kfree(state.req);
+-      else {
++      if (state.req->state != xb_req_state_aborted) {
+               /* write err, then update state */
+               virt_wmb();
+               state.req->state = xb_req_state_got_reply;
+               wake_up(&state.req->wq);
+       }
++      kref_put(&state.req->kref, xs_free_req);
+       mutex_unlock(&xb_write_mutex);
+--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
++++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
+@@ -406,7 +406,7 @@ void xenbus_dev_queue_reply(struct xb_re
+       mutex_unlock(&u->reply_mutex);
+       kfree(req->body);
+-      kfree(req);
++      kref_put(&req->kref, xs_free_req);
+       kref_put(&u->kref, xenbus_file_free);
+--- a/drivers/xen/xenbus/xenbus_xs.c
++++ b/drivers/xen/xenbus/xenbus_xs.c
+@@ -112,6 +112,12 @@ static void xs_suspend_exit(void)
+       wake_up_all(&xs_state_enter_wq);
+ }
++void xs_free_req(struct kref *kref)
++{
++      struct xb_req_data *req = container_of(kref, struct xb_req_data, kref);
++      kfree(req);
++}
++
+ static uint32_t xs_request_enter(struct xb_req_data *req)
+ {
+       uint32_t rq_id;
+@@ -237,6 +243,12 @@ static void xs_send(struct xb_req_data *
+       req->caller_req_id = req->msg.req_id;
+       req->msg.req_id = xs_request_enter(req);
++      /*
++       * Take 2nd ref.  One for this thread, and the second for the
++       * xenbus_thread.
++       */
++      kref_get(&req->kref);
++
+       mutex_lock(&xb_write_mutex);
+       list_add_tail(&req->list, &xb_write_list);
+       notify = list_is_singular(&xb_write_list);
+@@ -261,8 +273,8 @@ static void *xs_wait_for_reply(struct xb
+       if (req->state == xb_req_state_queued ||
+           req->state == xb_req_state_wait_reply)
+               req->state = xb_req_state_aborted;
+-      else
+-              kfree(req);
++
++      kref_put(&req->kref, xs_free_req);
+       mutex_unlock(&xb_write_mutex);
+       return ret;
+@@ -291,6 +303,7 @@ int xenbus_dev_request_and_reply(struct
+       req->cb = xenbus_dev_queue_reply;
+       req->par = par;
+       req->user_req = true;
++      kref_init(&req->kref);
+       xs_send(req, msg);
+@@ -319,6 +332,7 @@ static void *xs_talkv(struct xenbus_tran
+       req->num_vecs = num_vecs;
+       req->cb = xs_wake_up;
+       req->user_req = false;
++      kref_init(&req->kref);
+       msg.req_id = 0;
+       msg.tx_id = t.id;