]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Feb 2025 17:57:13 +0000 (18:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Feb 2025 17:57:13 +0000 (18:57 +0100)
added patches:
btrfs-output-the-reason-for-open_ctree-failure.patch
media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch
media-uvcvideo-fix-double-free-in-error-path.patch
mptcp-handle-fastopen-disconnect-correctly.patch
pps-fix-a-use-after-free.patch
remoteproc-core-fix-ida_free-call-while-not-allocated.patch
staging-media-max96712-fix-kernel-oops-when-removing-module.patch
usb-gadget-f_tcm-don-t-free-command-immediately.patch

queue-6.6/btrfs-output-the-reason-for-open_ctree-failure.patch [new file with mode: 0644]
queue-6.6/media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch [new file with mode: 0644]
queue-6.6/media-uvcvideo-fix-double-free-in-error-path.patch [new file with mode: 0644]
queue-6.6/mptcp-handle-fastopen-disconnect-correctly.patch [new file with mode: 0644]
queue-6.6/pps-fix-a-use-after-free.patch [new file with mode: 0644]
queue-6.6/remoteproc-core-fix-ida_free-call-while-not-allocated.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/staging-media-max96712-fix-kernel-oops-when-removing-module.patch [new file with mode: 0644]
queue-6.6/usb-gadget-f_tcm-don-t-free-command-immediately.patch [new file with mode: 0644]

diff --git a/queue-6.6/btrfs-output-the-reason-for-open_ctree-failure.patch b/queue-6.6/btrfs-output-the-reason-for-open_ctree-failure.patch
new file mode 100644 (file)
index 0000000..b1d53b8
--- /dev/null
@@ -0,0 +1,46 @@
+From d0f038104fa37380e2a725e669508e43d0c503e9 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 10 Dec 2024 15:23:06 +1030
+Subject: btrfs: output the reason for open_ctree() failure
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit d0f038104fa37380e2a725e669508e43d0c503e9 upstream.
+
+There is a recent ML report that mounting a large fs backed by hardware
+RAID56 controller (with one device missing) took too much time, and
+systemd seems to kill the mount attempt.
+
+In that case, the only error message is:
+
+  BTRFS error (device sdj): open_ctree failed
+
+There is no reason on why the failure happened, making it very hard to
+understand the reason.
+
+At least output the error number (in the particular case it should be
+-EINTR) to provide some clue.
+
+Link: https://lore.kernel.org/linux-btrfs/9b9c4d2810abcca2f9f76e32220ed9a90febb235.camel@scientia.org/
+Reported-by: Christoph Anton Mitterer <calestyo@scientia.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/super.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -1162,7 +1162,7 @@ static int btrfs_fill_super(struct super
+       err = open_ctree(sb, fs_devices, (char *)data);
+       if (err) {
+-              btrfs_err(fs_info, "open_ctree failed");
++              btrfs_err(fs_info, "open_ctree failed: %d", err);
+               return err;
+       }
diff --git a/queue-6.6/media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch b/queue-6.6/media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch
new file mode 100644 (file)
index 0000000..4357f49
--- /dev/null
@@ -0,0 +1,46 @@
+From 1378ffec30367233152b7dbf4fa6a25ee98585d1 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Thu, 17 Oct 2024 23:34:16 +0300
+Subject: media: imx-jpeg: Fix potential error pointer dereference in detach_pm()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit 1378ffec30367233152b7dbf4fa6a25ee98585d1 upstream.
+
+The proble is on the first line:
+
+       if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i]))
+
+If jpeg->pd_dev[i] is an error pointer, then passing it to
+pm_runtime_suspended() will lead to an Oops.  The other conditions
+check for both error pointers and NULL, but it would be more clear to
+use the IS_ERR_OR_NULL() check for that.
+
+Fixes: fd0af4cd35da ("media: imx-jpeg: Ensure power suppliers be suspended before detach them")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -2674,11 +2674,12 @@ static void mxc_jpeg_detach_pm_domains(s
+       int i;
+       for (i = 0; i < jpeg->num_domains; i++) {
+-              if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i]))
++              if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) &&
++                  !pm_runtime_suspended(jpeg->pd_dev[i]))
+                       pm_runtime_force_suspend(jpeg->pd_dev[i]);
+-              if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i]))
++              if (!IS_ERR_OR_NULL(jpeg->pd_link[i]))
+                       device_link_del(jpeg->pd_link[i]);
+-              if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i]))
++              if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]))
+                       dev_pm_domain_detach(jpeg->pd_dev[i], true);
+               jpeg->pd_dev[i] = NULL;
+               jpeg->pd_link[i] = NULL;
diff --git a/queue-6.6/media-uvcvideo-fix-double-free-in-error-path.patch b/queue-6.6/media-uvcvideo-fix-double-free-in-error-path.patch
new file mode 100644 (file)
index 0000000..dc3d94c
--- /dev/null
@@ -0,0 +1,36 @@
+From c6ef3a7fa97ec823a1e1af9085cf13db9f7b3bac Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Fri, 8 Nov 2024 01:51:30 +0200
+Subject: media: uvcvideo: Fix double free in error path
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit c6ef3a7fa97ec823a1e1af9085cf13db9f7b3bac upstream.
+
+If the uvc_status_init() function fails to allocate the int_urb, it will
+free the dev->status pointer but doesn't reset the pointer to NULL. This
+results in the kfree() call in uvc_status_cleanup() trying to
+double-free the memory. Fix it by resetting the dev->status pointer to
+NULL after freeing it.
+
+Fixes: a31a4055473b ("V4L/DVB:usbvideo:don't use part of buffer for USB transfer #4")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20241107235130.31372-1-laurent.pinchart@ideasonboard.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/usb/uvc/uvc_status.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/media/usb/uvc/uvc_status.c
++++ b/drivers/media/usb/uvc/uvc_status.c
+@@ -269,6 +269,7 @@ int uvc_status_init(struct uvc_device *d
+       dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!dev->int_urb) {
+               kfree(dev->status);
++              dev->status = NULL;
+               return -ENOMEM;
+       }
diff --git a/queue-6.6/mptcp-handle-fastopen-disconnect-correctly.patch b/queue-6.6/mptcp-handle-fastopen-disconnect-correctly.patch
new file mode 100644 (file)
index 0000000..8773917
--- /dev/null
@@ -0,0 +1,92 @@
+From 619af16b3b57a3a4ee50b9a30add9ff155541e71 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 23 Jan 2025 19:05:56 +0100
+Subject: mptcp: handle fastopen disconnect correctly
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 619af16b3b57a3a4ee50b9a30add9ff155541e71 upstream.
+
+Syzbot was able to trigger a data stream corruption:
+
+  WARNING: CPU: 0 PID: 9846 at net/mptcp/protocol.c:1024 __mptcp_clean_una+0xddb/0xff0 net/mptcp/protocol.c:1024
+  Modules linked in:
+  CPU: 0 UID: 0 PID: 9846 Comm: syz-executor351 Not tainted 6.13.0-rc2-syzkaller-00059-g00a5acdbf398 #0
+  Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 11/25/2024
+  RIP: 0010:__mptcp_clean_una+0xddb/0xff0 net/mptcp/protocol.c:1024
+  Code: fa ff ff 48 8b 4c 24 18 80 e1 07 fe c1 38 c1 0f 8c 8e fa ff ff 48 8b 7c 24 18 e8 e0 db 54 f6 e9 7f fa ff ff e8 e6 80 ee f5 90 <0f> 0b 90 4c 8b 6c 24 40 4d 89 f4 e9 04 f5 ff ff 44 89 f1 80 e1 07
+  RSP: 0018:ffffc9000c0cf400 EFLAGS: 00010293
+  RAX: ffffffff8bb0dd5a RBX: ffff888033f5d230 RCX: ffff888059ce8000
+  RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+  RBP: ffffc9000c0cf518 R08: ffffffff8bb0d1dd R09: 1ffff110170c8928
+  R10: dffffc0000000000 R11: ffffed10170c8929 R12: 0000000000000000
+  R13: ffff888033f5d220 R14: dffffc0000000000 R15: ffff8880592b8000
+  FS:  00007f6e866496c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00007f6e86f491a0 CR3: 00000000310e6000 CR4: 00000000003526f0
+  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+  Call Trace:
+   <TASK>
+   __mptcp_clean_una_wakeup+0x7f/0x2d0 net/mptcp/protocol.c:1074
+   mptcp_release_cb+0x7cb/0xb30 net/mptcp/protocol.c:3493
+   release_sock+0x1aa/0x1f0 net/core/sock.c:3640
+   inet_wait_for_connect net/ipv4/af_inet.c:609 [inline]
+   __inet_stream_connect+0x8bd/0xf30 net/ipv4/af_inet.c:703
+   mptcp_sendmsg_fastopen+0x2a2/0x530 net/mptcp/protocol.c:1755
+   mptcp_sendmsg+0x1884/0x1b10 net/mptcp/protocol.c:1830
+   sock_sendmsg_nosec net/socket.c:711 [inline]
+   __sock_sendmsg+0x1a6/0x270 net/socket.c:726
+   ____sys_sendmsg+0x52a/0x7e0 net/socket.c:2583
+   ___sys_sendmsg net/socket.c:2637 [inline]
+   __sys_sendmsg+0x269/0x350 net/socket.c:2669
+   do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+   do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+   entry_SYSCALL_64_after_hwframe+0x77/0x7f
+  RIP: 0033:0x7f6e86ebfe69
+  Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 b1 1f 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+  RSP: 002b:00007f6e86649168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+  RAX: ffffffffffffffda RBX: 00007f6e86f491b8 RCX: 00007f6e86ebfe69
+  RDX: 0000000030004001 RSI: 0000000020000080 RDI: 0000000000000003
+  RBP: 00007f6e86f491b0 R08: 00007f6e866496c0 R09: 0000000000000000
+  R10: 0000000000000000 R11: 0000000000000246 R12: 00007f6e86f491bc
+  R13: 000000000000006e R14: 00007ffe445d9420 R15: 00007ffe445d9508
+   </TASK>
+
+The root cause is the bad handling of disconnect() generated internally
+by the MPTCP protocol in case of connect FASTOPEN errors.
+
+Address the issue increasing the socket disconnect counter even on such
+a case, to allow other threads waiting on the same socket lock to
+properly error out.
+
+Fixes: c2b2ae3925b6 ("mptcp: handle correctly disconnect() failures")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+ebc0b8ae5d3590b2c074@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/67605870.050a0220.37aaf.0137.GAE@google.com
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/537
+Tested-by: syzbot+ebc0b8ae5d3590b2c074@syzkaller.appspotmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20250123-net-mptcp-syzbot-issues-v1-3-af73258a726f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -1768,8 +1768,10 @@ static int mptcp_sendmsg_fastopen(struct
+                * see mptcp_disconnect().
+                * Attempt it again outside the problematic scope.
+                */
+-              if (!mptcp_disconnect(sk, 0))
++              if (!mptcp_disconnect(sk, 0)) {
++                      sk->sk_disconnects++;
+                       sk->sk_socket->state = SS_UNCONNECTED;
++              }
+       }
+       inet_clear_bit(DEFER_CONNECT, sk);
diff --git a/queue-6.6/pps-fix-a-use-after-free.patch b/queue-6.6/pps-fix-a-use-after-free.patch
new file mode 100644 (file)
index 0000000..cd74702
--- /dev/null
@@ -0,0 +1,600 @@
+From c79a39dc8d060b9e64e8b0fa9d245d44befeefbe Mon Sep 17 00:00:00 2001
+From: Calvin Owens <calvin@wbinvd.org>
+Date: Mon, 11 Nov 2024 20:13:29 -0800
+Subject: pps: Fix a use-after-free
+
+From: Calvin Owens <calvin@wbinvd.org>
+
+commit c79a39dc8d060b9e64e8b0fa9d245d44befeefbe upstream.
+
+On a board running ntpd and gpsd, I'm seeing a consistent use-after-free
+in sys_exit() from gpsd when rebooting:
+
+    pps pps1: removed
+    ------------[ cut here ]------------
+    kobject: '(null)' (00000000db4bec24): is not initialized, yet kobject_put() is being called.
+    WARNING: CPU: 2 PID: 440 at lib/kobject.c:734 kobject_put+0x120/0x150
+    CPU: 2 UID: 299 PID: 440 Comm: gpsd Not tainted 6.11.0-rc6-00308-gb31c44928842 #1
+    Hardware name: Raspberry Pi 4 Model B Rev 1.1 (DT)
+    pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+    pc : kobject_put+0x120/0x150
+    lr : kobject_put+0x120/0x150
+    sp : ffffffc0803d3ae0
+    x29: ffffffc0803d3ae0 x28: ffffff8042dc9738 x27: 0000000000000001
+    x26: 0000000000000000 x25: ffffff8042dc9040 x24: ffffff8042dc9440
+    x23: ffffff80402a4620 x22: ffffff8042ef4bd0 x21: ffffff80405cb600
+    x20: 000000000008001b x19: ffffff8040b3b6e0 x18: 0000000000000000
+    x17: 0000000000000000 x16: 0000000000000000 x15: 696e6920746f6e20
+    x14: 7369203a29343263 x13: 205d303434542020 x12: 0000000000000000
+    x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
+    x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000
+    x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+    x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
+    Call trace:
+     kobject_put+0x120/0x150
+     cdev_put+0x20/0x3c
+     __fput+0x2c4/0x2d8
+     ____fput+0x1c/0x38
+     task_work_run+0x70/0xfc
+     do_exit+0x2a0/0x924
+     do_group_exit+0x34/0x90
+     get_signal+0x7fc/0x8c0
+     do_signal+0x128/0x13b4
+     do_notify_resume+0xdc/0x160
+     el0_svc+0xd4/0xf8
+     el0t_64_sync_handler+0x140/0x14c
+     el0t_64_sync+0x190/0x194
+    ---[ end trace 0000000000000000 ]---
+
+...followed by more symptoms of corruption, with similar stacks:
+
+    refcount_t: underflow; use-after-free.
+    kernel BUG at lib/list_debug.c:62!
+    Kernel panic - not syncing: Oops - BUG: Fatal exception
+
+This happens because pps_device_destruct() frees the pps_device with the
+embedded cdev immediately after calling cdev_del(), but, as the comment
+above cdev_del() notes, fops for previously opened cdevs are still
+callable even after cdev_del() returns. I think this bug has always
+been there: I can't explain why it suddenly started happening every time
+I reboot this particular board.
+
+In commit d953e0e837e6 ("pps: Fix a use-after free bug when
+unregistering a source."), George Spelvin suggested removing the
+embedded cdev. That seems like the simplest way to fix this, so I've
+implemented his suggestion, using __register_chrdev() with pps_idr
+becoming the source of truth for which minor corresponds to which
+device.
+
+But now that pps_idr defines userspace visibility instead of cdev_add(),
+we need to be sure the pps->dev refcount can't reach zero while
+userspace can still find it again. So, the idr_remove() call moves to
+pps_unregister_cdev(), and pps_idr now holds a reference to pps->dev.
+
+    pps_core: source serial1 got cdev (251:1)
+    <...>
+    pps pps1: removed
+    pps_core: unregistering pps1
+    pps_core: deallocating pps1
+
+Fixes: d953e0e837e6 ("pps: Fix a use-after free bug when unregistering a source.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Calvin Owens <calvin@wbinvd.org>
+Reviewed-by: Michal Schmidt <mschmidt@redhat.com>
+Link: https://lore.kernel.org/r/a17975fd5ae99385791929e563f72564edbcf28f.1731383727.git.calvin@wbinvd.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pps/clients/pps-gpio.c    |    4 -
+ drivers/pps/clients/pps-ktimer.c  |    4 -
+ drivers/pps/clients/pps-ldisc.c   |    6 -
+ drivers/pps/clients/pps_parport.c |    4 -
+ drivers/pps/kapi.c                |   10 +-
+ drivers/pps/kc.c                  |   10 +-
+ drivers/pps/pps.c                 |  127 +++++++++++++++++++-------------------
+ drivers/ptp/ptp_ocp.c             |    2 
+ include/linux/pps_kernel.h        |    3 
+ 9 files changed, 87 insertions(+), 83 deletions(-)
+
+--- a/drivers/pps/clients/pps-gpio.c
++++ b/drivers/pps/clients/pps-gpio.c
+@@ -214,8 +214,8 @@ static int pps_gpio_probe(struct platfor
+               return -EINVAL;
+       }
+-      dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n",
+-               data->irq);
++      dev_dbg(&data->pps->dev, "Registered IRQ %d as PPS source\n",
++              data->irq);
+       return 0;
+ }
+--- a/drivers/pps/clients/pps-ktimer.c
++++ b/drivers/pps/clients/pps-ktimer.c
+@@ -56,7 +56,7 @@ static struct pps_source_info pps_ktimer
+ static void __exit pps_ktimer_exit(void)
+ {
+-      dev_info(pps->dev, "ktimer PPS source unregistered\n");
++      dev_dbg(&pps->dev, "ktimer PPS source unregistered\n");
+       del_timer_sync(&ktimer);
+       pps_unregister_source(pps);
+@@ -74,7 +74,7 @@ static int __init pps_ktimer_init(void)
+       timer_setup(&ktimer, pps_ktimer_event, 0);
+       mod_timer(&ktimer, jiffies + HZ);
+-      dev_info(pps->dev, "ktimer PPS source registered\n");
++      dev_dbg(&pps->dev, "ktimer PPS source registered\n");
+       return 0;
+ }
+--- a/drivers/pps/clients/pps-ldisc.c
++++ b/drivers/pps/clients/pps-ldisc.c
+@@ -32,7 +32,7 @@ static void pps_tty_dcd_change(struct tt
+       pps_event(pps, &ts, active ? PPS_CAPTUREASSERT :
+                       PPS_CAPTURECLEAR, NULL);
+-      dev_dbg(pps->dev, "PPS %s at %lu\n",
++      dev_dbg(&pps->dev, "PPS %s at %lu\n",
+                       active ? "assert" : "clear", jiffies);
+ }
+@@ -69,7 +69,7 @@ static int pps_tty_open(struct tty_struc
+               goto err_unregister;
+       }
+-      dev_info(pps->dev, "source \"%s\" added\n", info.path);
++      dev_dbg(&pps->dev, "source \"%s\" added\n", info.path);
+       return 0;
+@@ -89,7 +89,7 @@ static void pps_tty_close(struct tty_str
+       if (WARN_ON(!pps))
+               return;
+-      dev_info(pps->dev, "removed\n");
++      dev_info(&pps->dev, "removed\n");
+       pps_unregister_source(pps);
+ }
+--- a/drivers/pps/clients/pps_parport.c
++++ b/drivers/pps/clients/pps_parport.c
+@@ -81,7 +81,7 @@ static void parport_irq(void *handle)
+       /* check the signal (no signal means the pulse is lost this time) */
+       if (!signal_is_set(port)) {
+               local_irq_restore(flags);
+-              dev_err(dev->pps->dev, "lost the signal\n");
++              dev_err(&dev->pps->dev, "lost the signal\n");
+               goto out_assert;
+       }
+@@ -98,7 +98,7 @@ static void parport_irq(void *handle)
+       /* timeout */
+       dev->cw_err++;
+       if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) {
+-              dev_err(dev->pps->dev, "disabled clear edge capture after %d"
++              dev_err(&dev->pps->dev, "disabled clear edge capture after %d"
+                               " timeouts\n", dev->cw_err);
+               dev->cw = 0;
+               dev->cw_err = 0;
+--- a/drivers/pps/kapi.c
++++ b/drivers/pps/kapi.c
+@@ -41,7 +41,7 @@ static void pps_add_offset(struct pps_kt
+ static void pps_echo_client_default(struct pps_device *pps, int event,
+               void *data)
+ {
+-      dev_info(pps->dev, "echo %s %s\n",
++      dev_info(&pps->dev, "echo %s %s\n",
+               event & PPS_CAPTUREASSERT ? "assert" : "",
+               event & PPS_CAPTURECLEAR ? "clear" : "");
+ }
+@@ -112,7 +112,7 @@ struct pps_device *pps_register_source(s
+               goto kfree_pps;
+       }
+-      dev_info(pps->dev, "new PPS source %s\n", info->name);
++      dev_dbg(&pps->dev, "new PPS source %s\n", info->name);
+       return pps;
+@@ -166,7 +166,7 @@ void pps_event(struct pps_device *pps, s
+       /* check event type */
+       BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0);
+-      dev_dbg(pps->dev, "PPS event at %lld.%09ld\n",
++      dev_dbg(&pps->dev, "PPS event at %lld.%09ld\n",
+                       (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec);
+       timespec_to_pps_ktime(&ts_real, ts->ts_real);
+@@ -188,7 +188,7 @@ void pps_event(struct pps_device *pps, s
+               /* Save the time stamp */
+               pps->assert_tu = ts_real;
+               pps->assert_sequence++;
+-              dev_dbg(pps->dev, "capture assert seq #%u\n",
++              dev_dbg(&pps->dev, "capture assert seq #%u\n",
+                       pps->assert_sequence);
+               captured = ~0;
+@@ -202,7 +202,7 @@ void pps_event(struct pps_device *pps, s
+               /* Save the time stamp */
+               pps->clear_tu = ts_real;
+               pps->clear_sequence++;
+-              dev_dbg(pps->dev, "capture clear seq #%u\n",
++              dev_dbg(&pps->dev, "capture clear seq #%u\n",
+                       pps->clear_sequence);
+               captured = ~0;
+--- a/drivers/pps/kc.c
++++ b/drivers/pps/kc.c
+@@ -43,11 +43,11 @@ int pps_kc_bind(struct pps_device *pps,
+                       pps_kc_hardpps_mode = 0;
+                       pps_kc_hardpps_dev = NULL;
+                       spin_unlock_irq(&pps_kc_hardpps_lock);
+-                      dev_info(pps->dev, "unbound kernel"
++                      dev_info(&pps->dev, "unbound kernel"
+                                       " consumer\n");
+               } else {
+                       spin_unlock_irq(&pps_kc_hardpps_lock);
+-                      dev_err(pps->dev, "selected kernel consumer"
++                      dev_err(&pps->dev, "selected kernel consumer"
+                                       " is not bound\n");
+                       return -EINVAL;
+               }
+@@ -57,11 +57,11 @@ int pps_kc_bind(struct pps_device *pps,
+                       pps_kc_hardpps_mode = bind_args->edge;
+                       pps_kc_hardpps_dev = pps;
+                       spin_unlock_irq(&pps_kc_hardpps_lock);
+-                      dev_info(pps->dev, "bound kernel consumer: "
++                      dev_info(&pps->dev, "bound kernel consumer: "
+                               "edge=0x%x\n", bind_args->edge);
+               } else {
+                       spin_unlock_irq(&pps_kc_hardpps_lock);
+-                      dev_err(pps->dev, "another kernel consumer"
++                      dev_err(&pps->dev, "another kernel consumer"
+                                       " is already bound\n");
+                       return -EINVAL;
+               }
+@@ -83,7 +83,7 @@ void pps_kc_remove(struct pps_device *pp
+               pps_kc_hardpps_mode = 0;
+               pps_kc_hardpps_dev = NULL;
+               spin_unlock_irq(&pps_kc_hardpps_lock);
+-              dev_info(pps->dev, "unbound kernel consumer"
++              dev_info(&pps->dev, "unbound kernel consumer"
+                               " on device removal\n");
+       } else
+               spin_unlock_irq(&pps_kc_hardpps_lock);
+--- a/drivers/pps/pps.c
++++ b/drivers/pps/pps.c
+@@ -25,7 +25,7 @@
+  * Local variables
+  */
+-static dev_t pps_devt;
++static int pps_major;
+ static struct class *pps_class;
+ static DEFINE_MUTEX(pps_idr_lock);
+@@ -62,7 +62,7 @@ static int pps_cdev_pps_fetch(struct pps
+       else {
+               unsigned long ticks;
+-              dev_dbg(pps->dev, "timeout %lld.%09d\n",
++              dev_dbg(&pps->dev, "timeout %lld.%09d\n",
+                               (long long) fdata->timeout.sec,
+                               fdata->timeout.nsec);
+               ticks = fdata->timeout.sec * HZ;
+@@ -80,7 +80,7 @@ static int pps_cdev_pps_fetch(struct pps
+       /* Check for pending signals */
+       if (err == -ERESTARTSYS) {
+-              dev_dbg(pps->dev, "pending signal caught\n");
++              dev_dbg(&pps->dev, "pending signal caught\n");
+               return -EINTR;
+       }
+@@ -98,7 +98,7 @@ static long pps_cdev_ioctl(struct file *
+       switch (cmd) {
+       case PPS_GETPARAMS:
+-              dev_dbg(pps->dev, "PPS_GETPARAMS\n");
++              dev_dbg(&pps->dev, "PPS_GETPARAMS\n");
+               spin_lock_irq(&pps->lock);
+@@ -114,7 +114,7 @@ static long pps_cdev_ioctl(struct file *
+               break;
+       case PPS_SETPARAMS:
+-              dev_dbg(pps->dev, "PPS_SETPARAMS\n");
++              dev_dbg(&pps->dev, "PPS_SETPARAMS\n");
+               /* Check the capabilities */
+               if (!capable(CAP_SYS_TIME))
+@@ -124,14 +124,14 @@ static long pps_cdev_ioctl(struct file *
+               if (err)
+                       return -EFAULT;
+               if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) {
+-                      dev_dbg(pps->dev, "capture mode unspecified (%x)\n",
++                      dev_dbg(&pps->dev, "capture mode unspecified (%x)\n",
+                                                               params.mode);
+                       return -EINVAL;
+               }
+               /* Check for supported capabilities */
+               if ((params.mode & ~pps->info.mode) != 0) {
+-                      dev_dbg(pps->dev, "unsupported capabilities (%x)\n",
++                      dev_dbg(&pps->dev, "unsupported capabilities (%x)\n",
+                                                               params.mode);
+                       return -EINVAL;
+               }
+@@ -144,7 +144,7 @@ static long pps_cdev_ioctl(struct file *
+               /* Restore the read only parameters */
+               if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
+                       /* section 3.3 of RFC 2783 interpreted */
+-                      dev_dbg(pps->dev, "time format unspecified (%x)\n",
++                      dev_dbg(&pps->dev, "time format unspecified (%x)\n",
+                                                               params.mode);
+                       pps->params.mode |= PPS_TSFMT_TSPEC;
+               }
+@@ -165,7 +165,7 @@ static long pps_cdev_ioctl(struct file *
+               break;
+       case PPS_GETCAP:
+-              dev_dbg(pps->dev, "PPS_GETCAP\n");
++              dev_dbg(&pps->dev, "PPS_GETCAP\n");
+               err = put_user(pps->info.mode, iuarg);
+               if (err)
+@@ -176,7 +176,7 @@ static long pps_cdev_ioctl(struct file *
+       case PPS_FETCH: {
+               struct pps_fdata fdata;
+-              dev_dbg(pps->dev, "PPS_FETCH\n");
++              dev_dbg(&pps->dev, "PPS_FETCH\n");
+               err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata));
+               if (err)
+@@ -206,7 +206,7 @@ static long pps_cdev_ioctl(struct file *
+       case PPS_KC_BIND: {
+               struct pps_bind_args bind_args;
+-              dev_dbg(pps->dev, "PPS_KC_BIND\n");
++              dev_dbg(&pps->dev, "PPS_KC_BIND\n");
+               /* Check the capabilities */
+               if (!capable(CAP_SYS_TIME))
+@@ -218,7 +218,7 @@ static long pps_cdev_ioctl(struct file *
+               /* Check for supported capabilities */
+               if ((bind_args.edge & ~pps->info.mode) != 0) {
+-                      dev_err(pps->dev, "unsupported capabilities (%x)\n",
++                      dev_err(&pps->dev, "unsupported capabilities (%x)\n",
+                                       bind_args.edge);
+                       return -EINVAL;
+               }
+@@ -227,7 +227,7 @@ static long pps_cdev_ioctl(struct file *
+               if (bind_args.tsformat != PPS_TSFMT_TSPEC ||
+                               (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 ||
+                               bind_args.consumer != PPS_KC_HARDPPS) {
+-                      dev_err(pps->dev, "invalid kernel consumer bind"
++                      dev_err(&pps->dev, "invalid kernel consumer bind"
+                                       " parameters (%x)\n", bind_args.edge);
+                       return -EINVAL;
+               }
+@@ -259,7 +259,7 @@ static long pps_cdev_compat_ioctl(struct
+               struct pps_fdata fdata;
+               int err;
+-              dev_dbg(pps->dev, "PPS_FETCH\n");
++              dev_dbg(&pps->dev, "PPS_FETCH\n");
+               err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat));
+               if (err)
+@@ -296,20 +296,36 @@ static long pps_cdev_compat_ioctl(struct
+ #define pps_cdev_compat_ioctl NULL
+ #endif
++static struct pps_device *pps_idr_get(unsigned long id)
++{
++      struct pps_device *pps;
++
++      mutex_lock(&pps_idr_lock);
++      pps = idr_find(&pps_idr, id);
++      if (pps)
++              get_device(&pps->dev);
++
++      mutex_unlock(&pps_idr_lock);
++      return pps;
++}
++
+ static int pps_cdev_open(struct inode *inode, struct file *file)
+ {
+-      struct pps_device *pps = container_of(inode->i_cdev,
+-                                              struct pps_device, cdev);
++      struct pps_device *pps = pps_idr_get(iminor(inode));
++
++      if (!pps)
++              return -ENODEV;
++
+       file->private_data = pps;
+-      kobject_get(&pps->dev->kobj);
+       return 0;
+ }
+ static int pps_cdev_release(struct inode *inode, struct file *file)
+ {
+-      struct pps_device *pps = container_of(inode->i_cdev,
+-                                              struct pps_device, cdev);
+-      kobject_put(&pps->dev->kobj);
++      struct pps_device *pps = file->private_data;
++
++      WARN_ON(pps->id != iminor(inode));
++      put_device(&pps->dev);
+       return 0;
+ }
+@@ -332,22 +348,13 @@ static void pps_device_destruct(struct d
+ {
+       struct pps_device *pps = dev_get_drvdata(dev);
+-      cdev_del(&pps->cdev);
+-
+-      /* Now we can release the ID for re-use */
+       pr_debug("deallocating pps%d\n", pps->id);
+-      mutex_lock(&pps_idr_lock);
+-      idr_remove(&pps_idr, pps->id);
+-      mutex_unlock(&pps_idr_lock);
+-
+-      kfree(dev);
+       kfree(pps);
+ }
+ int pps_register_cdev(struct pps_device *pps)
+ {
+       int err;
+-      dev_t devt;
+       mutex_lock(&pps_idr_lock);
+       /*
+@@ -364,40 +371,29 @@ int pps_register_cdev(struct pps_device
+               goto out_unlock;
+       }
+       pps->id = err;
+-      mutex_unlock(&pps_idr_lock);
+-
+-      devt = MKDEV(MAJOR(pps_devt), pps->id);
+-
+-      cdev_init(&pps->cdev, &pps_cdev_fops);
+-      pps->cdev.owner = pps->info.owner;
+-      err = cdev_add(&pps->cdev, devt, 1);
+-      if (err) {
+-              pr_err("%s: failed to add char device %d:%d\n",
+-                              pps->info.name, MAJOR(pps_devt), pps->id);
++      pps->dev.class = pps_class;
++      pps->dev.parent = pps->info.dev;
++      pps->dev.devt = MKDEV(pps_major, pps->id);
++      dev_set_drvdata(&pps->dev, pps);
++      dev_set_name(&pps->dev, "pps%d", pps->id);
++      err = device_register(&pps->dev);
++      if (err)
+               goto free_idr;
+-      }
+-      pps->dev = device_create(pps_class, pps->info.dev, devt, pps,
+-                                                      "pps%d", pps->id);
+-      if (IS_ERR(pps->dev)) {
+-              err = PTR_ERR(pps->dev);
+-              goto del_cdev;
+-      }
+       /* Override the release function with our own */
+-      pps->dev->release = pps_device_destruct;
++      pps->dev.release = pps_device_destruct;
+-      pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
+-                      MAJOR(pps_devt), pps->id);
++      pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major,
++               pps->id);
++      get_device(&pps->dev);
++      mutex_unlock(&pps_idr_lock);
+       return 0;
+-del_cdev:
+-      cdev_del(&pps->cdev);
+-
+ free_idr:
+-      mutex_lock(&pps_idr_lock);
+       idr_remove(&pps_idr, pps->id);
++      put_device(&pps->dev);
+ out_unlock:
+       mutex_unlock(&pps_idr_lock);
+       return err;
+@@ -407,7 +403,13 @@ void pps_unregister_cdev(struct pps_devi
+ {
+       pr_debug("unregistering pps%d\n", pps->id);
+       pps->lookup_cookie = NULL;
+-      device_destroy(pps_class, pps->dev->devt);
++      device_destroy(pps_class, pps->dev.devt);
++
++      /* Now we can release the ID for re-use */
++      mutex_lock(&pps_idr_lock);
++      idr_remove(&pps_idr, pps->id);
++      put_device(&pps->dev);
++      mutex_unlock(&pps_idr_lock);
+ }
+ /*
+@@ -427,6 +429,11 @@ void pps_unregister_cdev(struct pps_devi
+  * so that it will not be used again, even if the pps device cannot
+  * be removed from the idr due to pending references holding the minor
+  * number in use.
++ *
++ * Since pps_idr holds a reference to the device, the returned
++ * pps_device is guaranteed to be valid until pps_unregister_cdev() is
++ * called on it. But after calling pps_unregister_cdev(), it may be
++ * freed at any time.
+  */
+ struct pps_device *pps_lookup_dev(void const *cookie)
+ {
+@@ -449,13 +456,11 @@ EXPORT_SYMBOL(pps_lookup_dev);
+ static void __exit pps_exit(void)
+ {
+       class_destroy(pps_class);
+-      unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES);
++      __unregister_chrdev(pps_major, 0, PPS_MAX_SOURCES, "pps");
+ }
+ static int __init pps_init(void)
+ {
+-      int err;
+-
+       pps_class = class_create("pps");
+       if (IS_ERR(pps_class)) {
+               pr_err("failed to allocate class\n");
+@@ -463,8 +468,9 @@ static int __init pps_init(void)
+       }
+       pps_class->dev_groups = pps_groups;
+-      err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps");
+-      if (err < 0) {
++      pps_major = __register_chrdev(0, 0, PPS_MAX_SOURCES, "pps",
++                                    &pps_cdev_fops);
++      if (pps_major < 0) {
+               pr_err("failed to allocate char device region\n");
+               goto remove_class;
+       }
+@@ -477,8 +483,7 @@ static int __init pps_init(void)
+ remove_class:
+       class_destroy(pps_class);
+-
+-      return err;
++      return pps_major;
+ }
+ subsys_initcall(pps_init);
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -4055,7 +4055,7 @@ ptp_ocp_complete(struct ptp_ocp *bp)
+       pps = pps_lookup_dev(bp->ptp);
+       if (pps)
+-              ptp_ocp_symlink(bp, pps->dev, "pps");
++              ptp_ocp_symlink(bp, &pps->dev, "pps");
+       ptp_ocp_debugfs_add_device(bp);
+--- a/include/linux/pps_kernel.h
++++ b/include/linux/pps_kernel.h
+@@ -56,8 +56,7 @@ struct pps_device {
+       unsigned int id;                        /* PPS source unique ID */
+       void const *lookup_cookie;              /* For pps_lookup_dev() only */
+-      struct cdev cdev;
+-      struct device *dev;
++      struct device dev;
+       struct fasync_struct *async_queue;      /* fasync method */
+       spinlock_t lock;
+ };
diff --git a/queue-6.6/remoteproc-core-fix-ida_free-call-while-not-allocated.patch b/queue-6.6/remoteproc-core-fix-ida_free-call-while-not-allocated.patch
new file mode 100644 (file)
index 0000000..69290bd
--- /dev/null
@@ -0,0 +1,81 @@
+From 7378aeb664e5ebc396950b36a1f2dedf5aabec20 Mon Sep 17 00:00:00 2001
+From: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+Date: Fri, 22 Nov 2024 18:51:27 +0100
+Subject: remoteproc: core: Fix ida_free call while not allocated
+
+From: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+
+commit 7378aeb664e5ebc396950b36a1f2dedf5aabec20 upstream.
+
+In the rproc_alloc() function, on error, put_device(&rproc->dev) is
+called, leading to the call of the rproc_type_release() function.
+An error can occurs before ida_alloc is called.
+
+In such case in rproc_type_release(), the condition (rproc->index >= 0) is
+true as rproc->index has been  initialized to 0.
+ida_free() is called reporting a warning:
+[    4.181906] WARNING: CPU: 1 PID: 24 at lib/idr.c:525 ida_free+0x100/0x164
+[    4.186378] stm32-display-dsi 5a000000.dsi: Fixed dependency cycle(s) with /soc/dsi@5a000000/panel@0
+[    4.188854] ida_free called for id=0 which is not allocated.
+[    4.198256] mipi-dsi 5a000000.dsi.0: Fixed dependency cycle(s) with /soc/dsi@5a000000
+[    4.203556] Modules linked in: panel_orisetech_otm8009a dw_mipi_dsi_stm(+) gpu_sched dw_mipi_dsi stm32_rproc stm32_crc32 stm32_ipcc(+) optee(+)
+[    4.224307] CPU: 1 UID: 0 PID: 24 Comm: kworker/u10:0 Not tainted 6.12.0 #442
+[    4.231481] Hardware name: STM32 (Device Tree Support)
+[    4.236627] Workqueue: events_unbound deferred_probe_work_func
+[    4.242504] Call trace:
+[    4.242522]  unwind_backtrace from show_stack+0x10/0x14
+[    4.250218]  show_stack from dump_stack_lvl+0x50/0x64
+[    4.255274]  dump_stack_lvl from __warn+0x80/0x12c
+[    4.260134]  __warn from warn_slowpath_fmt+0x114/0x188
+[    4.265199]  warn_slowpath_fmt from ida_free+0x100/0x164
+[    4.270565]  ida_free from rproc_type_release+0x38/0x60
+[    4.275832]  rproc_type_release from device_release+0x30/0xa0
+[    4.281601]  device_release from kobject_put+0xc4/0x294
+[    4.286762]  kobject_put from rproc_alloc.part.0+0x208/0x28c
+[    4.292430]  rproc_alloc.part.0 from devm_rproc_alloc+0x80/0xc4
+[    4.298393]  devm_rproc_alloc from stm32_rproc_probe+0xd0/0x844 [stm32_rproc]
+[    4.305575]  stm32_rproc_probe [stm32_rproc] from platform_probe+0x5c/0xbc
+
+Calling ida_alloc earlier in rproc_alloc ensures that the rproc->index is
+properly set.
+
+Fixes: 08333b911f01 ("remoteproc: Directly use ida_alloc()/free()")
+Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20241122175127.2188037-1-arnaud.pouliquen@foss.st.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/remoteproc/remoteproc_core.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -2465,6 +2465,13 @@ struct rproc *rproc_alloc(struct device
+       rproc->dev.driver_data = rproc;
+       idr_init(&rproc->notifyids);
++      /* Assign a unique device index and name */
++      rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL);
++      if (rproc->index < 0) {
++              dev_err(dev, "ida_alloc failed: %d\n", rproc->index);
++              goto put_device;
++      }
++
+       rproc->name = kstrdup_const(name, GFP_KERNEL);
+       if (!rproc->name)
+               goto put_device;
+@@ -2475,13 +2482,6 @@ struct rproc *rproc_alloc(struct device
+       if (rproc_alloc_ops(rproc, ops))
+               goto put_device;
+-      /* Assign a unique device index and name */
+-      rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL);
+-      if (rproc->index < 0) {
+-              dev_err(dev, "ida_alloc failed: %d\n", rproc->index);
+-              goto put_device;
+-      }
+-
+       dev_set_name(&rproc->dev, "remoteproc%d", rproc->index);
+       atomic_set(&rproc->power, 0);
index aa7dc3d58870cbaf45b7a824c1840afcf7bdc01a..ad88ce164017dbb5ab1816f20961987cf16e13d6 100644 (file)
@@ -383,3 +383,11 @@ usb-dwc3-core-defer-the-probe-until-usb-power-supply-ready.patch
 usb-typec-tcpm-set-src_send_capabilities-timeout-to-pd_t_sender_response.patch
 usb-typec-tcpci-prevent-sink-disconnection-before-vppsshutdown-in-spr-pps.patch
 mptcp-consolidate-suboption-status.patch
+mptcp-handle-fastopen-disconnect-correctly.patch
+remoteproc-core-fix-ida_free-call-while-not-allocated.patch
+media-uvcvideo-fix-double-free-in-error-path.patch
+pps-fix-a-use-after-free.patch
+usb-gadget-f_tcm-don-t-free-command-immediately.patch
+staging-media-max96712-fix-kernel-oops-when-removing-module.patch
+media-imx-jpeg-fix-potential-error-pointer-dereference-in-detach_pm.patch
+btrfs-output-the-reason-for-open_ctree-failure.patch
diff --git a/queue-6.6/staging-media-max96712-fix-kernel-oops-when-removing-module.patch b/queue-6.6/staging-media-max96712-fix-kernel-oops-when-removing-module.patch
new file mode 100644 (file)
index 0000000..475f197
--- /dev/null
@@ -0,0 +1,113 @@
+From ee1b5046d5cd892a0754ab982aeaaad3702083a5 Mon Sep 17 00:00:00 2001
+From: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+Date: Tue, 17 Dec 2024 08:51:50 +0200
+Subject: staging: media: max96712: fix kernel oops when removing module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+
+commit ee1b5046d5cd892a0754ab982aeaaad3702083a5 upstream.
+
+The following kernel oops is thrown when trying to remove the max96712
+module:
+
+Unable to handle kernel paging request at virtual address 00007375746174db
+Mem abort info:
+  ESR = 0x0000000096000004
+  EC = 0x25: DABT (current EL), IL = 32 bits
+  SET = 0, FnV = 0
+  EA = 0, S1PTW = 0
+  FSC = 0x04: level 0 translation fault
+Data abort info:
+  ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+user pgtable: 4k pages, 48-bit VAs, pgdp=000000010af89000
+[00007375746174db] pgd=0000000000000000, p4d=0000000000000000
+Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+Modules linked in: crct10dif_ce polyval_ce mxc_jpeg_encdec flexcan
+    snd_soc_fsl_sai snd_soc_fsl_asoc_card snd_soc_fsl_micfil dwc_mipi_csi2
+    imx_csi_formatter polyval_generic v4l2_jpeg imx_pcm_dma can_dev
+    snd_soc_imx_audmux snd_soc_wm8962 snd_soc_imx_card snd_soc_fsl_utils
+    max96712(C-) rpmsg_ctrl rpmsg_char pwm_fan fuse
+    [last unloaded: imx8_isi]
+CPU: 0 UID: 0 PID: 754 Comm: rmmod
+           Tainted: G         C    6.12.0-rc6-06364-g327fec852c31 #17
+Tainted: [C]=CRAP
+Hardware name: NXP i.MX95 19X19 board (DT)
+pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : led_put+0x1c/0x40
+lr : v4l2_subdev_put_privacy_led+0x48/0x58
+sp : ffff80008699bbb0
+x29: ffff80008699bbb0 x28: ffff00008ac233c0 x27: 0000000000000000
+x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
+x23: ffff000080cf1170 x22: ffff00008b53bd00 x21: ffff8000822ad1c8
+x20: ffff000080ff5c00 x19: ffff00008b53be40 x18: 0000000000000000
+x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
+x14: 0000000000000004 x13: ffff0000800f8010 x12: 0000000000000000
+x11: ffff000082acf5c0 x10: ffff000082acf478 x9 : ffff0000800f8010
+x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff6364626d
+x5 : 8080808000000000 x4 : 0000000000000020 x3 : 00000000553a3dc1
+x2 : ffff00008ac233c0 x1 : ffff00008ac233c0 x0 : ff00737574617473
+Call trace:
+ led_put+0x1c/0x40
+ v4l2_subdev_put_privacy_led+0x48/0x58
+ v4l2_async_unregister_subdev+0x2c/0x1a4
+ max96712_remove+0x1c/0x38 [max96712]
+ i2c_device_remove+0x2c/0x9c
+ device_remove+0x4c/0x80
+ device_release_driver_internal+0x1cc/0x228
+ driver_detach+0x4c/0x98
+ bus_remove_driver+0x6c/0xbc
+ driver_unregister+0x30/0x60
+ i2c_del_driver+0x54/0x64
+ max96712_i2c_driver_exit+0x18/0x1d0 [max96712]
+ __arm64_sys_delete_module+0x1a4/0x290
+ invoke_syscall+0x48/0x10c
+ el0_svc_common.constprop.0+0xc0/0xe0
+ do_el0_svc+0x1c/0x28
+ el0_svc+0x34/0xd8
+ el0t_64_sync_handler+0x120/0x12c
+ el0t_64_sync+0x190/0x194
+Code: f9000bf3 aa0003f3 f9402800 f9402000 (f9403400)
+---[ end trace 0000000000000000 ]---
+
+This happens because in v4l2_i2c_subdev_init(), the i2c_set_cliendata()
+is called again and the data is overwritten to point to sd, instead of
+priv. So, in remove(), the wrong pointer is passed to
+v4l2_async_unregister_subdev(), leading to a crash.
+
+Fixes: 5814f32fef13 ("media: staging: max96712: Add basic support for MAX96712 GMSL2 deserializer")
+Signed-off-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/media/max96712/max96712.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/media/max96712/max96712.c
++++ b/drivers/staging/media/max96712/max96712.c
+@@ -402,7 +402,6 @@ static int max96712_probe(struct i2c_cli
+               return -ENOMEM;
+       priv->client = client;
+-      i2c_set_clientdata(client, priv);
+       priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap);
+       if (IS_ERR(priv->regmap))
+@@ -435,7 +434,8 @@ static int max96712_probe(struct i2c_cli
+ static void max96712_remove(struct i2c_client *client)
+ {
+-      struct max96712_priv *priv = i2c_get_clientdata(client);
++      struct v4l2_subdev *sd = i2c_get_clientdata(client);
++      struct max96712_priv *priv = container_of(sd, struct max96712_priv, sd);
+       v4l2_async_unregister_subdev(&priv->sd);
diff --git a/queue-6.6/usb-gadget-f_tcm-don-t-free-command-immediately.patch b/queue-6.6/usb-gadget-f_tcm-don-t-free-command-immediately.patch
new file mode 100644 (file)
index 0000000..c6e9557
--- /dev/null
@@ -0,0 +1,40 @@
+From c225d006a31949d673e646d585d9569bc28feeb9 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Wed, 11 Dec 2024 00:31:36 +0000
+Subject: usb: gadget: f_tcm: Don't free command immediately
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+commit c225d006a31949d673e646d585d9569bc28feeb9 upstream.
+
+Don't prematurely free the command. Wait for the status completion of
+the sense status. It can be freed then. Otherwise we will double-free
+the command.
+
+Fixes: cff834c16d23 ("usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/ae919ac431f16275e05ec819bdffb3ac5f44cbe1.1733876548.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_tcm.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_tcm.c
++++ b/drivers/usb/gadget/function/f_tcm.c
+@@ -1066,7 +1066,6 @@ static void usbg_cmd_work(struct work_st
+ out:
+       transport_send_check_condition_and_sense(se_cmd,
+                       TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+-      transport_generic_free_cmd(&cmd->se_cmd, 0);
+ }
+ static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu,
+@@ -1195,7 +1194,6 @@ static void bot_cmd_work(struct work_str
+ out:
+       transport_send_check_condition_and_sense(se_cmd,
+                               TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+-      transport_generic_free_cmd(&cmd->se_cmd, 0);
+ }
+ static int bot_submit_command(struct f_uas *fu,