From a1aab02fbd413760d798073db6e2d69ff645cc9a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Mar 2025 17:46:34 +0100 Subject: [PATCH] 6.13-stable patches added patches: bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch drm-xe-guc-fix-size_t-print-format.patch hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch sched_ext-selftests-dsp_local_on-fix-selftest-on-up-systems.patch tools-sched_ext-add-helper-to-check-task-migration-state.patch --- ...p-fix-corrupted-list-in-hci_chan_del.patch | 660 ++++++++++++++++++ .../drm-xe-guc-fix-size_t-print-format.patch | 57 ++ ...-fn-key-handling-on-the-omoton-kb066.patch | 72 ++ ...nsitions-to-handle-connectivity-loss.patch | 138 ++++ ..._local_on-fix-selftest-on-up-systems.patch | 31 + queue-6.13/series | 6 + ...helper-to-check-task-migration-state.patch | 40 ++ 7 files changed, 1004 insertions(+) create mode 100644 queue-6.13/bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch create mode 100644 queue-6.13/drm-xe-guc-fix-size_t-print-format.patch create mode 100644 queue-6.13/hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch create mode 100644 queue-6.13/nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch create mode 100644 queue-6.13/sched_ext-selftests-dsp_local_on-fix-selftest-on-up-systems.patch create mode 100644 queue-6.13/tools-sched_ext-add-helper-to-check-task-migration-state.patch diff --git a/queue-6.13/bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch b/queue-6.13/bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch new file mode 100644 index 0000000000..1d8e99ef05 --- /dev/null +++ b/queue-6.13/bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch @@ -0,0 +1,660 @@ +From ab4eedb790cae44313759b50fe47da285e2519d5 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Thu, 6 Feb 2025 15:54:45 -0500 +Subject: Bluetooth: L2CAP: Fix corrupted list in hci_chan_del + +From: Luiz Augusto von Dentz + +commit ab4eedb790cae44313759b50fe47da285e2519d5 upstream. + +This fixes the following trace by reworking the locking of l2cap_conn +so instead of only locking when changing the chan_l list this promotes +chan_lock to a general lock of l2cap_conn so whenever it is being held +it would prevents the likes of l2cap_conn_del to run: + +list_del corruption, ffff888021297e00->prev is LIST_POISON2 (dead000000000122) +------------[ cut here ]------------ +kernel BUG at lib/list_debug.c:61! +Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI +CPU: 1 UID: 0 PID: 5896 Comm: syz-executor213 Not tainted 6.14.0-rc1-next-20250204-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 12/27/2024 +RIP: 0010:__list_del_entry_valid_or_report+0x12c/0x190 lib/list_debug.c:59 +Code: 8c 4c 89 fe 48 89 da e8 32 8c 37 fc 90 0f 0b 48 89 df e8 27 9f 14 fd 48 c7 c7 a0 c0 60 8c 4c 89 fe 48 89 da e8 15 8c 37 fc 90 <0f> 0b 4c 89 e7 e8 0a 9f 14 fd 42 80 3c 2b 00 74 08 4c 89 e7 e8 cb +RSP: 0018:ffffc90003f6f998 EFLAGS: 00010246 +RAX: 000000000000004e RBX: dead000000000122 RCX: 01454d423f7fbf00 +RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 +RBP: dffffc0000000000 R08: ffffffff819f077c R09: 1ffff920007eded0 +R10: dffffc0000000000 R11: fffff520007eded1 R12: dead000000000122 +R13: dffffc0000000000 R14: ffff8880352248d8 R15: ffff888021297e00 +FS: 00007f7ace6686c0(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f7aceeeb1d0 CR3: 000000003527c000 CR4: 00000000003526f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + __list_del_entry_valid include/linux/list.h:124 [inline] + __list_del_entry include/linux/list.h:215 [inline] + list_del_rcu include/linux/rculist.h:168 [inline] + hci_chan_del+0x70/0x1b0 net/bluetooth/hci_conn.c:2858 + l2cap_conn_free net/bluetooth/l2cap_core.c:1816 [inline] + kref_put include/linux/kref.h:65 [inline] + l2cap_conn_put+0x70/0xe0 net/bluetooth/l2cap_core.c:1830 + l2cap_sock_shutdown+0xa8a/0x1020 net/bluetooth/l2cap_sock.c:1377 + l2cap_sock_release+0x79/0x1d0 net/bluetooth/l2cap_sock.c:1416 + __sock_release net/socket.c:642 [inline] + sock_close+0xbc/0x240 net/socket.c:1393 + __fput+0x3e9/0x9f0 fs/file_table.c:448 + task_work_run+0x24f/0x310 kernel/task_work.c:227 + ptrace_notify+0x2d2/0x380 kernel/signal.c:2522 + ptrace_report_syscall include/linux/ptrace.h:415 [inline] + ptrace_report_syscall_exit include/linux/ptrace.h:477 [inline] + syscall_exit_work+0xc7/0x1d0 kernel/entry/common.c:173 + syscall_exit_to_user_mode_prepare kernel/entry/common.c:200 [inline] + __syscall_exit_to_user_mode_work kernel/entry/common.c:205 [inline] + syscall_exit_to_user_mode+0x24a/0x340 kernel/entry/common.c:218 + do_syscall_64+0x100/0x230 arch/x86/entry/common.c:89 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f7aceeaf449 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 41 19 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:00007f7ace668218 EFLAGS: 00000246 ORIG_RAX: 000000000000002a +RAX: fffffffffffffffc RBX: 00007f7acef39328 RCX: 00007f7aceeaf449 +RDX: 000000000000000e RSI: 0000000020000100 RDI: 0000000000000004 +RBP: 00007f7acef39320 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003 +R13: 0000000000000004 R14: 00007f7ace668670 R15: 000000000000000b + +Modules linked in: +---[ end trace 0000000000000000 ]--- +RIP: 0010:__list_del_entry_valid_or_report+0x12c/0x190 lib/list_debug.c:59 +Code: 8c 4c 89 fe 48 89 da e8 32 8c 37 fc 90 0f 0b 48 89 df e8 27 9f 14 fd 48 c7 c7 a0 c0 60 8c 4c 89 fe 48 89 da e8 15 8c 37 fc 90 <0f> 0b 4c 89 e7 e8 0a 9f 14 fd 42 80 3c 2b 00 74 08 4c 89 e7 e8 cb +RSP: 0018:ffffc90003f6f998 EFLAGS: 00010246 +RAX: 000000000000004e RBX: dead000000000122 RCX: 01454d423f7fbf00 +RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 +RBP: dffffc0000000000 R08: ffffffff819f077c R09: 1ffff920007eded0 +R10: dffffc0000000000 R11: fffff520007eded1 R12: dead000000000122 +R13: dffffc0000000000 R14: ffff8880352248d8 R15: ffff888021297e00 +FS: 00007f7ace6686c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f7acef05b08 CR3: 000000003527c000 CR4: 00000000003526f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + +Reported-by: syzbot+10bd8fe6741eedd2be2e@syzkaller.appspotmail.com +Tested-by: syzbot+10bd8fe6741eedd2be2e@syzkaller.appspotmail.com +Fixes: b4f82f9ed43a ("Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman +--- + include/net/bluetooth/l2cap.h | 3 + net/bluetooth/l2cap_core.c | 138 ++++++++++++++---------------------------- + net/bluetooth/l2cap_sock.c | 15 ++-- + 3 files changed, 58 insertions(+), 98 deletions(-) + +--- a/include/net/bluetooth/l2cap.h ++++ b/include/net/bluetooth/l2cap.h +@@ -668,7 +668,7 @@ struct l2cap_conn { + struct l2cap_chan *smp; + + struct list_head chan_l; +- struct mutex chan_lock; ++ struct mutex lock; + struct kref ref; + struct list_head users; + }; +@@ -970,6 +970,7 @@ void l2cap_chan_del(struct l2cap_chan *c + void l2cap_send_conn_req(struct l2cap_chan *chan); + + struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); ++struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *conn); + void l2cap_conn_put(struct l2cap_conn *conn); + + int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -119,7 +119,6 @@ static struct l2cap_chan *l2cap_get_chan + { + struct l2cap_chan *c; + +- mutex_lock(&conn->chan_lock); + c = __l2cap_get_chan_by_scid(conn, cid); + if (c) { + /* Only lock if chan reference is not 0 */ +@@ -127,7 +126,6 @@ static struct l2cap_chan *l2cap_get_chan + if (c) + l2cap_chan_lock(c); + } +- mutex_unlock(&conn->chan_lock); + + return c; + } +@@ -140,7 +138,6 @@ static struct l2cap_chan *l2cap_get_chan + { + struct l2cap_chan *c; + +- mutex_lock(&conn->chan_lock); + c = __l2cap_get_chan_by_dcid(conn, cid); + if (c) { + /* Only lock if chan reference is not 0 */ +@@ -148,7 +145,6 @@ static struct l2cap_chan *l2cap_get_chan + if (c) + l2cap_chan_lock(c); + } +- mutex_unlock(&conn->chan_lock); + + return c; + } +@@ -418,7 +414,7 @@ static void l2cap_chan_timeout(struct wo + if (!conn) + return; + +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling + * this work. No need to call l2cap_chan_hold(chan) here again. + */ +@@ -439,7 +435,7 @@ static void l2cap_chan_timeout(struct wo + l2cap_chan_unlock(chan); + l2cap_chan_put(chan); + +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + } + + struct l2cap_chan *l2cap_chan_create(void) +@@ -642,9 +638,9 @@ void __l2cap_chan_add(struct l2cap_conn + + void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) + { +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + __l2cap_chan_add(conn, chan); +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + } + + void l2cap_chan_del(struct l2cap_chan *chan, int err) +@@ -732,9 +728,9 @@ void l2cap_chan_list(struct l2cap_conn * + if (!conn) + return; + +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + __l2cap_chan_list(conn, func, data); +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + } + + EXPORT_SYMBOL_GPL(l2cap_chan_list); +@@ -746,7 +742,7 @@ static void l2cap_conn_update_id_addr(st + struct hci_conn *hcon = conn->hcon; + struct l2cap_chan *chan; + +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + + list_for_each_entry(chan, &conn->chan_l, list) { + l2cap_chan_lock(chan); +@@ -755,7 +751,7 @@ static void l2cap_conn_update_id_addr(st + l2cap_chan_unlock(chan); + } + +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + } + + static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan) +@@ -1508,8 +1504,6 @@ static void l2cap_conn_start(struct l2ca + + BT_DBG("conn %p", conn); + +- mutex_lock(&conn->chan_lock); +- + list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { + l2cap_chan_lock(chan); + +@@ -1578,8 +1572,6 @@ static void l2cap_conn_start(struct l2ca + + l2cap_chan_unlock(chan); + } +- +- mutex_unlock(&conn->chan_lock); + } + + static void l2cap_le_conn_ready(struct l2cap_conn *conn) +@@ -1625,7 +1617,7 @@ static void l2cap_conn_ready(struct l2ca + if (hcon->type == ACL_LINK) + l2cap_request_info(conn); + +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + + list_for_each_entry(chan, &conn->chan_l, list) { + +@@ -1643,7 +1635,7 @@ static void l2cap_conn_ready(struct l2ca + l2cap_chan_unlock(chan); + } + +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + + if (hcon->type == LE_LINK) + l2cap_le_conn_ready(conn); +@@ -1658,14 +1650,10 @@ static void l2cap_conn_unreliable(struct + + BT_DBG("conn %p", conn); + +- mutex_lock(&conn->chan_lock); +- + list_for_each_entry(chan, &conn->chan_l, list) { + if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) + l2cap_chan_set_err(chan, err); + } +- +- mutex_unlock(&conn->chan_lock); + } + + static void l2cap_info_timeout(struct work_struct *work) +@@ -1676,7 +1664,9 @@ static void l2cap_info_timeout(struct wo + conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; + conn->info_ident = 0; + ++ mutex_lock(&conn->lock); + l2cap_conn_start(conn); ++ mutex_unlock(&conn->lock); + } + + /* +@@ -1768,6 +1758,8 @@ static void l2cap_conn_del(struct hci_co + + BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); + ++ mutex_lock(&conn->lock); ++ + kfree_skb(conn->rx_skb); + + skb_queue_purge(&conn->pending_rx); +@@ -1786,8 +1778,6 @@ static void l2cap_conn_del(struct hci_co + /* Force the connection to be immediately dropped */ + hcon->disc_timeout = 0; + +- mutex_lock(&conn->chan_lock); +- + /* Kill channels */ + list_for_each_entry_safe(chan, l, &conn->chan_l, list) { + l2cap_chan_hold(chan); +@@ -1801,12 +1791,14 @@ static void l2cap_conn_del(struct hci_co + l2cap_chan_put(chan); + } + +- mutex_unlock(&conn->chan_lock); +- + if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) + cancel_delayed_work_sync(&conn->info_timer); + ++ hci_chan_del(conn->hchan); ++ conn->hchan = NULL; ++ + hcon->l2cap_data = NULL; ++ mutex_unlock(&conn->lock); + l2cap_conn_put(conn); + } + +@@ -1814,7 +1806,6 @@ static void l2cap_conn_free(struct kref + { + struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref); + +- hci_chan_del(conn->hchan); + hci_conn_put(conn->hcon); + kfree(conn); + } +@@ -2925,8 +2916,6 @@ static void l2cap_raw_recv(struct l2cap_ + + BT_DBG("conn %p", conn); + +- mutex_lock(&conn->chan_lock); +- + list_for_each_entry(chan, &conn->chan_l, list) { + if (chan->chan_type != L2CAP_CHAN_RAW) + continue; +@@ -2941,8 +2930,6 @@ static void l2cap_raw_recv(struct l2cap_ + if (chan->ops->recv(chan, nskb)) + kfree_skb(nskb); + } +- +- mutex_unlock(&conn->chan_lock); + } + + /* ---- L2CAP signalling commands ---- */ +@@ -3965,7 +3952,6 @@ static void l2cap_connect(struct l2cap_c + goto response; + } + +- mutex_lock(&conn->chan_lock); + l2cap_chan_lock(pchan); + + /* Check if the ACL is secure enough (if not SDP) */ +@@ -4072,7 +4058,6 @@ response: + } + + l2cap_chan_unlock(pchan); +- mutex_unlock(&conn->chan_lock); + l2cap_chan_put(pchan); + } + +@@ -4111,27 +4096,19 @@ static int l2cap_connect_create_rsp(stru + BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", + dcid, scid, result, status); + +- mutex_lock(&conn->chan_lock); +- + if (scid) { + chan = __l2cap_get_chan_by_scid(conn, scid); +- if (!chan) { +- err = -EBADSLT; +- goto unlock; +- } ++ if (!chan) ++ return -EBADSLT; + } else { + chan = __l2cap_get_chan_by_ident(conn, cmd->ident); +- if (!chan) { +- err = -EBADSLT; +- goto unlock; +- } ++ if (!chan) ++ return -EBADSLT; + } + + chan = l2cap_chan_hold_unless_zero(chan); +- if (!chan) { +- err = -EBADSLT; +- goto unlock; +- } ++ if (!chan) ++ return -EBADSLT; + + err = 0; + +@@ -4169,9 +4146,6 @@ static int l2cap_connect_create_rsp(stru + l2cap_chan_unlock(chan); + l2cap_chan_put(chan); + +-unlock: +- mutex_unlock(&conn->chan_lock); +- + return err; + } + +@@ -4459,11 +4433,7 @@ static inline int l2cap_disconnect_req(s + + chan->ops->set_shutdown(chan); + +- l2cap_chan_unlock(chan); +- mutex_lock(&conn->chan_lock); +- l2cap_chan_lock(chan); + l2cap_chan_del(chan, ECONNRESET); +- mutex_unlock(&conn->chan_lock); + + chan->ops->close(chan); + +@@ -4500,11 +4470,7 @@ static inline int l2cap_disconnect_rsp(s + return 0; + } + +- l2cap_chan_unlock(chan); +- mutex_lock(&conn->chan_lock); +- l2cap_chan_lock(chan); + l2cap_chan_del(chan, 0); +- mutex_unlock(&conn->chan_lock); + + chan->ops->close(chan); + +@@ -4702,13 +4668,9 @@ static int l2cap_le_connect_rsp(struct l + BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x", + dcid, mtu, mps, credits, result); + +- mutex_lock(&conn->chan_lock); +- + chan = __l2cap_get_chan_by_ident(conn, cmd->ident); +- if (!chan) { +- err = -EBADSLT; +- goto unlock; +- } ++ if (!chan) ++ return -EBADSLT; + + err = 0; + +@@ -4756,9 +4718,6 @@ static int l2cap_le_connect_rsp(struct l + + l2cap_chan_unlock(chan); + +-unlock: +- mutex_unlock(&conn->chan_lock); +- + return err; + } + +@@ -4870,7 +4829,6 @@ static int l2cap_le_connect_req(struct l + goto response; + } + +- mutex_lock(&conn->chan_lock); + l2cap_chan_lock(pchan); + + if (!smp_sufficient_security(conn->hcon, pchan->sec_level, +@@ -4936,7 +4894,6 @@ static int l2cap_le_connect_req(struct l + + response_unlock: + l2cap_chan_unlock(pchan); +- mutex_unlock(&conn->chan_lock); + l2cap_chan_put(pchan); + + if (result == L2CAP_CR_PEND) +@@ -5070,7 +5027,6 @@ static inline int l2cap_ecred_conn_req(s + goto response; + } + +- mutex_lock(&conn->chan_lock); + l2cap_chan_lock(pchan); + + if (!smp_sufficient_security(conn->hcon, pchan->sec_level, +@@ -5145,7 +5101,6 @@ static inline int l2cap_ecred_conn_req(s + + unlock: + l2cap_chan_unlock(pchan); +- mutex_unlock(&conn->chan_lock); + l2cap_chan_put(pchan); + + response: +@@ -5182,8 +5137,6 @@ static inline int l2cap_ecred_conn_rsp(s + BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits, + result); + +- mutex_lock(&conn->chan_lock); +- + cmd_len -= sizeof(*rsp); + + list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { +@@ -5269,8 +5222,6 @@ static inline int l2cap_ecred_conn_rsp(s + l2cap_chan_unlock(chan); + } + +- mutex_unlock(&conn->chan_lock); +- + return err; + } + +@@ -5383,8 +5334,6 @@ static inline int l2cap_le_command_rej(s + if (cmd_len < sizeof(*rej)) + return -EPROTO; + +- mutex_lock(&conn->chan_lock); +- + chan = __l2cap_get_chan_by_ident(conn, cmd->ident); + if (!chan) + goto done; +@@ -5399,7 +5348,6 @@ static inline int l2cap_le_command_rej(s + l2cap_chan_put(chan); + + done: +- mutex_unlock(&conn->chan_lock); + return 0; + } + +@@ -6854,8 +6802,12 @@ static void process_pending_rx(struct wo + + BT_DBG(""); + ++ mutex_lock(&conn->lock); ++ + while ((skb = skb_dequeue(&conn->pending_rx))) + l2cap_recv_frame(conn, skb); ++ ++ mutex_unlock(&conn->lock); + } + + static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) +@@ -6894,7 +6846,7 @@ static struct l2cap_conn *l2cap_conn_add + conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR; + + mutex_init(&conn->ident_lock); +- mutex_init(&conn->chan_lock); ++ mutex_init(&conn->lock); + + INIT_LIST_HEAD(&conn->chan_l); + INIT_LIST_HEAD(&conn->users); +@@ -7085,7 +7037,7 @@ int l2cap_chan_connect(struct l2cap_chan + } + } + +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + l2cap_chan_lock(chan); + + if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { +@@ -7126,7 +7078,7 @@ int l2cap_chan_connect(struct l2cap_chan + + chan_unlock: + l2cap_chan_unlock(chan); +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + done: + hci_dev_unlock(hdev); + hci_dev_put(hdev); +@@ -7339,7 +7291,7 @@ static void l2cap_security_cfm(struct hc + + BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); + +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + + list_for_each_entry(chan, &conn->chan_l, list) { + l2cap_chan_lock(chan); +@@ -7413,7 +7365,7 @@ static void l2cap_security_cfm(struct hc + l2cap_chan_unlock(chan); + } + +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + } + + /* Append fragment into frame respecting the maximum len of rx_skb */ +@@ -7480,8 +7432,11 @@ static void l2cap_recv_reset(struct l2ca + conn->rx_len = 0; + } + +-static struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c) ++struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c) + { ++ if (!c) ++ return NULL; ++ + BT_DBG("conn %p orig refcnt %u", c, kref_read(&c->ref)); + + if (!kref_get_unless_zero(&c->ref)) +@@ -7507,11 +7462,15 @@ void l2cap_recv_acldata(struct hci_conn + + hci_dev_unlock(hcon->hdev); + +- if (!conn) +- goto drop; ++ if (!conn) { ++ kfree_skb(skb); ++ return; ++ } + + BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags); + ++ mutex_lock(&conn->lock); ++ + switch (flags) { + case ACL_START: + case ACL_START_NO_FLUSH: +@@ -7536,7 +7495,7 @@ void l2cap_recv_acldata(struct hci_conn + if (len == skb->len) { + /* Complete frame received */ + l2cap_recv_frame(conn, skb); +- return; ++ goto unlock; + } + + BT_DBG("Start: total len %d, frag len %u", len, skb->len); +@@ -7598,10 +7557,11 @@ void l2cap_recv_acldata(struct hci_conn + break; + } + +- l2cap_conn_put(conn); +- + drop: + kfree_skb(skb); ++unlock: ++ mutex_unlock(&conn->lock); ++ l2cap_conn_put(conn); + } + + static struct hci_cb l2cap_cb = { +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -1326,9 +1326,10 @@ static int l2cap_sock_shutdown(struct so + /* prevent sk structure from being freed whilst unlocked */ + sock_hold(sk); + +- chan = l2cap_pi(sk)->chan; + /* prevent chan structure from being freed whilst unlocked */ +- l2cap_chan_hold(chan); ++ chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan); ++ if (!chan) ++ goto shutdown_already; + + BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); + +@@ -1358,22 +1359,20 @@ static int l2cap_sock_shutdown(struct so + release_sock(sk); + + l2cap_chan_lock(chan); +- conn = chan->conn; +- if (conn) +- /* prevent conn structure from being freed */ +- l2cap_conn_get(conn); ++ /* prevent conn structure from being freed */ ++ conn = l2cap_conn_hold_unless_zero(chan->conn); + l2cap_chan_unlock(chan); + + if (conn) + /* mutex lock must be taken before l2cap_chan_lock() */ +- mutex_lock(&conn->chan_lock); ++ mutex_lock(&conn->lock); + + l2cap_chan_lock(chan); + l2cap_chan_close(chan, 0); + l2cap_chan_unlock(chan); + + if (conn) { +- mutex_unlock(&conn->chan_lock); ++ mutex_unlock(&conn->lock); + l2cap_conn_put(conn); + } + diff --git a/queue-6.13/drm-xe-guc-fix-size_t-print-format.patch b/queue-6.13/drm-xe-guc-fix-size_t-print-format.patch new file mode 100644 index 0000000000..6060a38929 --- /dev/null +++ b/queue-6.13/drm-xe-guc-fix-size_t-print-format.patch @@ -0,0 +1,57 @@ +From 213e24250feed3bcf58d7594298df2d7e78a88ab Mon Sep 17 00:00:00 2001 +From: Lucas De Marchi +Date: Tue, 28 Jan 2025 07:42:42 -0800 +Subject: drm/xe/guc: Fix size_t print format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lucas De Marchi + +commit 213e24250feed3bcf58d7594298df2d7e78a88ab upstream. + +Use %zx format to print size_t to remove the following warning when +building for i386: + +>> drivers/gpu/drm/xe/xe_guc_ct.c:1727:43: warning: format specifies type 'unsigned long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat] + 1727 | drm_printf(p, "[CTB].length: 0x%lx\n", snapshot->ctb_size); + | ~~~ ^~~~~~~~~~~~~~~~~~ + | %zx + +Cc: José Roberto de Souza +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202501281627.H6nj184e-lkp@intel.com/ +Fixes: 643f209ba3fd ("drm/xe: Make GUC binaries dump consistent with other binaries in devcoredump") +Reviewed-by: Rodrigo Vivi +Link: https://patchwork.freedesktop.org/patch/msgid/20250128154242.3371687-1-lucas.demarchi@intel.com +Signed-off-by: Lucas De Marchi +(cherry picked from commit 7748289df510638ba61fed86b59ce7d2fb4a194c) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/xe/xe_guc_ct.c | 2 +- + drivers/gpu/drm/xe/xe_guc_log.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/xe/xe_guc_ct.c ++++ b/drivers/gpu/drm/xe/xe_guc_ct.c +@@ -1700,7 +1700,7 @@ void xe_guc_ct_snapshot_print(struct xe_ + snapshot->g2h_outstanding); + + if (snapshot->ctb) { +- drm_printf(p, "[CTB].length: 0x%lx\n", snapshot->ctb_size); ++ drm_printf(p, "[CTB].length: 0x%zx\n", snapshot->ctb_size); + xe_print_blob_ascii85(p, "[CTB].data", '\n', + snapshot->ctb, 0, snapshot->ctb_size); + } +--- a/drivers/gpu/drm/xe/xe_guc_log.c ++++ b/drivers/gpu/drm/xe/xe_guc_log.c +@@ -208,7 +208,7 @@ void xe_guc_log_snapshot_print(struct xe + drm_printf(p, "GuC timestamp: 0x%08llX [%llu]\n", snapshot->stamp, snapshot->stamp); + drm_printf(p, "Log level: %u\n", snapshot->level); + +- drm_printf(p, "[LOG].length: 0x%lx\n", snapshot->size); ++ drm_printf(p, "[LOG].length: 0x%zx\n", snapshot->size); + remain = snapshot->size; + for (i = 0; i < snapshot->num_chunks; i++) { + size_t size = min(GUC_LOG_CHUNK_SIZE, remain); diff --git a/queue-6.13/hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch b/queue-6.13/hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch new file mode 100644 index 0000000000..20cceaea41 --- /dev/null +++ b/queue-6.13/hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch @@ -0,0 +1,72 @@ +From 221cea1003d8a412e5ec64a58df7ab19b654f490 Mon Sep 17 00:00:00 2001 +From: Alex Henrie +Date: Sun, 23 Feb 2025 22:36:30 -0700 +Subject: HID: apple: disable Fn key handling on the Omoton KB066 + +From: Alex Henrie + +commit 221cea1003d8a412e5ec64a58df7ab19b654f490 upstream. + +Remove the fixup to make the Omoton KB066's F6 key F6 when not holding +Fn. That was really just a hack to allow typing F6 in fnmode>0, and it +didn't fix any of the other F keys that were likewise untypable in +fnmode>0. Instead, because the Omoton's Fn key is entirely internal to +the keyboard, completely disable Fn key translation when an Omoton is +detected, which will prevent the hid-apple driver from interfering with +the keyboard's built-in Fn key handling. All of the F keys, including +F6, are then typable when Fn is held. + +The Omoton KB066 and the Apple A1255 both have HID product code +05ac:022c. The self-reported name of every original A1255 when they left +the factory was "Apple Wireless Keyboard". By default, Mac OS changes +the name to "'s keyboard" when pairing with the keyboard, but +Mac OS allows the user to set the internal name of Apple keyboards to +anything they like. The Omoton KB066's name, on the other hand, is not +configurable: It is always "Bluetooth Keyboard". Because that name is so +generic that a user might conceivably use the same name for a real Apple +keyboard, detect Omoton keyboards based on both having that exact name +and having HID product code 022c. + +Fixes: 819083cb6eed ("HID: apple: fix up the F6 key on the Omoton KB066 keyboard") +Signed-off-by: Alex Henrie +Reviewed-by: Aditya Garg +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-apple.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -378,6 +378,12 @@ static bool apple_is_non_apple_keyboard( + return false; + } + ++static bool apple_is_omoton_kb066(struct hid_device *hdev) ++{ ++ return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI && ++ strcmp(hdev->name, "Bluetooth Keyboard") == 0; ++} ++ + static inline void apple_setup_key_translation(struct input_dev *input, + const struct apple_key_translation *table) + { +@@ -546,9 +552,6 @@ static int hidinput_apple_event(struct h + } + } + +- if (usage->hid == 0xc0301) /* Omoton KB066 quirk */ +- code = KEY_F6; +- + if (usage->code != code) { + input_event_with_scancode(input, usage->type, code, usage->hid, value); + +@@ -728,7 +731,7 @@ static int apple_input_configured(struct + { + struct apple_sc *asc = hid_get_drvdata(hdev); + +- if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) { ++ if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) { + hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n"); + asc->quirks &= ~APPLE_HAS_FN; + } diff --git a/queue-6.13/nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch b/queue-6.13/nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch new file mode 100644 index 0000000000..503b7b9aba --- /dev/null +++ b/queue-6.13/nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch @@ -0,0 +1,138 @@ +From f13409bb3f9140dad7256febcb478f0c9600312c Mon Sep 17 00:00:00 2001 +From: Daniel Wagner +Date: Fri, 14 Feb 2025 09:02:04 +0100 +Subject: nvme-fc: rely on state transitions to handle connectivity loss + +From: Daniel Wagner + +commit f13409bb3f9140dad7256febcb478f0c9600312c upstream. + +It's not possible to call nvme_state_ctrl_state with holding a spin +lock, because nvme_state_ctrl_state calls cancel_delayed_work_sync +when fastfail is enabled. + +Instead syncing the ASSOC_FLAG and state transitions using a lock, it's +possible to only rely on the state machine transitions. That means +nvme_fc_ctrl_connectivity_loss should unconditionally call +nvme_reset_ctrl which avoids the read race on the ctrl state variable. +Actually, it's not necessary to test in which state the ctrl is, the +reset work will only scheduled when the state machine is in LIVE state. + +In nvme_fc_create_association, the LIVE state can only be entered if it +was previously CONNECTING. If this is not possible then the reset +handler got triggered. Thus just error out here. + +Fixes: ee59e3820ca9 ("nvme-fc: do not ignore connectivity loss during connecting") +Closes: https://lore.kernel.org/all/denqwui6sl5erqmz2gvrwueyxakl5txzbbiu3fgebryzrfxunm@iwxuthct377m/ +Reported-by: Shinichiro Kawasaki +Tested-by: Shin'ichiro Kawasaki +Reviewed-by: Sagi Grimberg +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fc.c | 67 ++++--------------------------------------------- + 1 file changed, 6 insertions(+), 61 deletions(-) + +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -782,61 +782,12 @@ restart: + static void + nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl) + { +- enum nvme_ctrl_state state; +- unsigned long flags; +- + dev_info(ctrl->ctrl.device, + "NVME-FC{%d}: controller connectivity lost. Awaiting " + "Reconnect", ctrl->cnum); + +- spin_lock_irqsave(&ctrl->lock, flags); + set_bit(ASSOC_FAILED, &ctrl->flags); +- state = nvme_ctrl_state(&ctrl->ctrl); +- spin_unlock_irqrestore(&ctrl->lock, flags); +- +- switch (state) { +- case NVME_CTRL_NEW: +- case NVME_CTRL_LIVE: +- /* +- * Schedule a controller reset. The reset will terminate the +- * association and schedule the reconnect timer. Reconnects +- * will be attempted until either the ctlr_loss_tmo +- * (max_retries * connect_delay) expires or the remoteport's +- * dev_loss_tmo expires. +- */ +- if (nvme_reset_ctrl(&ctrl->ctrl)) { +- dev_warn(ctrl->ctrl.device, +- "NVME-FC{%d}: Couldn't schedule reset.\n", +- ctrl->cnum); +- nvme_delete_ctrl(&ctrl->ctrl); +- } +- break; +- +- case NVME_CTRL_CONNECTING: +- /* +- * The association has already been terminated and the +- * controller is attempting reconnects. No need to do anything +- * futher. Reconnects will be attempted until either the +- * ctlr_loss_tmo (max_retries * connect_delay) expires or the +- * remoteport's dev_loss_tmo expires. +- */ +- break; +- +- case NVME_CTRL_RESETTING: +- /* +- * Controller is already in the process of terminating the +- * association. No need to do anything further. The reconnect +- * step will kick in naturally after the association is +- * terminated. +- */ +- break; +- +- case NVME_CTRL_DELETING: +- case NVME_CTRL_DELETING_NOIO: +- default: +- /* no action to take - let it delete */ +- break; +- } ++ nvme_reset_ctrl(&ctrl->ctrl); + } + + /** +@@ -3072,7 +3023,6 @@ nvme_fc_create_association(struct nvme_f + struct nvmefc_ls_rcv_op *disls = NULL; + unsigned long flags; + int ret; +- bool changed; + + ++ctrl->ctrl.nr_reconnects; + +@@ -3178,23 +3128,18 @@ nvme_fc_create_association(struct nvme_f + else + ret = nvme_fc_recreate_io_queues(ctrl); + } ++ if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags)) ++ ret = -EIO; + if (ret) + goto out_term_aen_ops; + +- spin_lock_irqsave(&ctrl->lock, flags); +- if (!test_bit(ASSOC_FAILED, &ctrl->flags)) +- changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); +- else ++ if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE)) { + ret = -EIO; +- spin_unlock_irqrestore(&ctrl->lock, flags); +- +- if (ret) + goto out_term_aen_ops; ++ } + + ctrl->ctrl.nr_reconnects = 0; +- +- if (changed) +- nvme_start_ctrl(&ctrl->ctrl); ++ nvme_start_ctrl(&ctrl->ctrl); + + return 0; /* Success */ + diff --git a/queue-6.13/sched_ext-selftests-dsp_local_on-fix-selftest-on-up-systems.patch b/queue-6.13/sched_ext-selftests-dsp_local_on-fix-selftest-on-up-systems.patch new file mode 100644 index 0000000000..9dbee5288f --- /dev/null +++ b/queue-6.13/sched_ext-selftests-dsp_local_on-fix-selftest-on-up-systems.patch @@ -0,0 +1,31 @@ +From 3c7d51b0d29954c40ea3a097e0ec7884b4344331 Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Sat, 25 Jan 2025 10:36:07 +0100 +Subject: sched_ext: selftests/dsp_local_on: Fix selftest on UP systems + +From: Andrea Righi + +commit 3c7d51b0d29954c40ea3a097e0ec7884b4344331 upstream. + +In UP systems p->migration_disabled is not available. Fix this by using +the portable helper is_migration_disabled(p). + +Fixes: e9fe182772dc ("sched_ext: selftests/dsp_local_on: Fix sporadic failures") +Signed-off-by: Andrea Righi +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/sched_ext/dsp_local_on.bpf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/testing/selftests/sched_ext/dsp_local_on.bpf.c ++++ b/tools/testing/selftests/sched_ext/dsp_local_on.bpf.c +@@ -43,7 +43,7 @@ void BPF_STRUCT_OPS(dsp_local_on_dispatc + if (!p) + return; + +- if (p->nr_cpus_allowed == nr_cpus && !p->migration_disabled) ++ if (p->nr_cpus_allowed == nr_cpus && !is_migration_disabled(p)) + target = bpf_get_prandom_u32() % nr_cpus; + else + target = scx_bpf_task_cpu(p); diff --git a/queue-6.13/series b/queue-6.13/series index 664644a6df..7306d5c8ca 100644 --- a/queue-6.13/series +++ b/queue-6.13/series @@ -242,3 +242,9 @@ mm-shmem-fix-potential-data-corruption-during-shmem-.patch mm-hugetlb-wait-for-hugetlb-folios-to-be-freed.patch smb3-add-support-for-iakerb.patch smb-client-fix-match_session-bug-preventing-session-.patch +sched_ext-selftests-dsp_local_on-fix-selftest-on-up-systems.patch +tools-sched_ext-add-helper-to-check-task-migration-state.patch +drm-xe-guc-fix-size_t-print-format.patch +bluetooth-l2cap-fix-corrupted-list-in-hci_chan_del.patch +nvme-fc-rely-on-state-transitions-to-handle-connectivity-loss.patch +hid-apple-disable-fn-key-handling-on-the-omoton-kb066.patch diff --git a/queue-6.13/tools-sched_ext-add-helper-to-check-task-migration-state.patch b/queue-6.13/tools-sched_ext-add-helper-to-check-task-migration-state.patch new file mode 100644 index 0000000000..99f8f33246 --- /dev/null +++ b/queue-6.13/tools-sched_ext-add-helper-to-check-task-migration-state.patch @@ -0,0 +1,40 @@ +From 5f52bbf2f6e0997394cf9c449d44e1c80ff4282c Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Sat, 25 Jan 2025 18:14:12 +0100 +Subject: tools/sched_ext: Add helper to check task migration state + +From: Andrea Righi + +commit 5f52bbf2f6e0997394cf9c449d44e1c80ff4282c upstream. + +Introduce a new helper for BPF schedulers to determine whether a task +can migrate or not (supporting both SMP and UP systems). + +Fixes: e9fe182772dc ("sched_ext: selftests/dsp_local_on: Fix sporadic failures") +Signed-off-by: Andrea Righi +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + tools/sched_ext/include/scx/common.bpf.h | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/tools/sched_ext/include/scx/common.bpf.h ++++ b/tools/sched_ext/include/scx/common.bpf.h +@@ -333,6 +333,17 @@ static __always_inline const struct cpum + return (const struct cpumask *)mask; + } + ++/* ++ * Return true if task @p cannot migrate to a different CPU, false ++ * otherwise. ++ */ ++static inline bool is_migration_disabled(const struct task_struct *p) ++{ ++ if (bpf_core_field_exists(p->migration_disabled)) ++ return p->migration_disabled; ++ return false; ++} ++ + /* rcu */ + void bpf_rcu_read_lock(void) __ksym; + void bpf_rcu_read_unlock(void) __ksym; -- 2.47.3