From: Sasha Levin Date: Sat, 5 Nov 2022 13:27:09 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v4.9.333~90 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a847a69e47a15d4e0807183e47c1e2bb1c32253e;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/ata-pata_legacy-fix-pdc20230_set_piomode.patch b/queue-5.15/ata-pata_legacy-fix-pdc20230_set_piomode.patch new file mode 100644 index 00000000000..d30a5f174e1 --- /dev/null +++ b/queue-5.15/ata-pata_legacy-fix-pdc20230_set_piomode.patch @@ -0,0 +1,45 @@ +From 0a79ab697134aa5981e6bb51f2d13e7fed7363da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Oct 2022 00:07:06 +0300 +Subject: ata: pata_legacy: fix pdc20230_set_piomode() + +From: Sergey Shtylyov + +[ Upstream commit 171a93182eccd6e6835d2c86b40787f9f832efaa ] + +Clang gives a warning when compiling pata_legacy.c with 'make W=1' about +the 'rt' local variable in pdc20230_set_piomode() being set but unused. +Quite obviously, there is an outb() call missing to write back the updated +variable. Moreover, checking the docs by Petr Soucek revealed that bitwise +AND should have been done with a negated timing mask and the master/slave +timing masks were swapped while updating... + +Fixes: 669a5db411d8 ("[libata] Add a bunch of PATA drivers.") +Reported-by: Damien Le Moal +Signed-off-by: Sergey Shtylyov +Signed-off-by: Damien Le Moal +Signed-off-by: Sasha Levin +--- + drivers/ata/pata_legacy.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c +index 0a8bf09a5c19..03c580625c2c 100644 +--- a/drivers/ata/pata_legacy.c ++++ b/drivers/ata/pata_legacy.c +@@ -315,9 +315,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) + outb(inb(0x1F4) & 0x07, 0x1F4); + + rt = inb(0x1F3); +- rt &= 0x07 << (3 * adev->devno); ++ rt &= ~(0x07 << (3 * !adev->devno)); + if (pio) +- rt |= (1 + 3 * pio) << (3 * adev->devno); ++ rt |= (1 + 3 * pio) << (3 * !adev->devno); ++ outb(rt, 0x1F3); + + udelay(100); + outb(inb(0x1F2) | 0x01, 0x1F2); +-- +2.35.1 + diff --git a/queue-5.15/bluetooth-l2cap-fix-memory-leak-in-vhci_write.patch b/queue-5.15/bluetooth-l2cap-fix-memory-leak-in-vhci_write.patch new file mode 100644 index 00000000000..d5d8b81e408 --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-fix-memory-leak-in-vhci_write.patch @@ -0,0 +1,82 @@ +From 2026c5e272b85a53414e3b2d117ace75b1300ba3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Oct 2022 10:18:51 +0800 +Subject: Bluetooth: L2CAP: Fix memory leak in vhci_write + +From: Hawkins Jiawei + +[ Upstream commit 7c9524d929648935bac2bbb4c20437df8f9c3f42 ] + +Syzkaller reports a memory leak as follows: +==================================== +BUG: memory leak +unreferenced object 0xffff88810d81ac00 (size 240): + [...] + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] __alloc_skb+0x1f9/0x270 net/core/skbuff.c:418 + [] alloc_skb include/linux/skbuff.h:1257 [inline] + [] bt_skb_alloc include/net/bluetooth/bluetooth.h:469 [inline] + [] vhci_get_user drivers/bluetooth/hci_vhci.c:391 [inline] + [] vhci_write+0x5f/0x230 drivers/bluetooth/hci_vhci.c:511 + [] call_write_iter include/linux/fs.h:2192 [inline] + [] new_sync_write fs/read_write.c:491 [inline] + [] vfs_write+0x42d/0x540 fs/read_write.c:578 + [] ksys_write+0x9d/0x160 fs/read_write.c:631 + [] do_syscall_x64 arch/x86/entry/common.c:50 [inline] + [] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 + [] entry_SYSCALL_64_after_hwframe+0x63/0xcd +==================================== + +HCI core will uses hci_rx_work() to process frame, which is queued to +the hdev->rx_q tail in hci_recv_frame() by HCI driver. + +Yet the problem is that, HCI core may not free the skb after handling +ACL data packets. To be more specific, when start fragment does not +contain the L2CAP length, HCI core just copies skb into conn->rx_skb and +finishes frame process in l2cap_recv_acldata(), without freeing the skb, +which triggers the above memory leak. + +This patch solves it by releasing the relative skb, after processing +the above case in l2cap_recv_acldata(). + +Fixes: 4d7ea8ee90e4 ("Bluetooth: L2CAP: Fix handling fragmented length") +Link: https://lore.kernel.org/all/0000000000000d0b1905e6aaef64@google.com/ +Reported-and-tested-by: syzbot+8f819e36e01022991cfa@syzkaller.appspotmail.com +Signed-off-by: Hawkins Jiawei +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index a18a1c608ed1..4802583f1071 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -8461,9 +8461,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + * expected length. + */ + if (skb->len < L2CAP_LEN_SIZE) { +- if (l2cap_recv_frag(conn, skb, conn->mtu) < 0) +- goto drop; +- return; ++ l2cap_recv_frag(conn, skb, conn->mtu); ++ break; + } + + len = get_unaligned_le16(skb->data) + L2CAP_HDR_SIZE; +@@ -8507,7 +8506,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) + + /* Header still could not be read just continue */ + if (conn->rx_skb->len < L2CAP_LEN_SIZE) +- return; ++ break; + } + + if (skb->len > conn->rx_len) { +-- +2.35.1 + diff --git a/queue-5.15/bluetooth-l2cap-fix-use-after-free-caused-by-l2cap_r.patch b/queue-5.15/bluetooth-l2cap-fix-use-after-free-caused-by-l2cap_r.patch new file mode 100644 index 00000000000..b14a8b89767 --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-fix-use-after-free-caused-by-l2cap_r.patch @@ -0,0 +1,175 @@ +From 4d2b76a7674744831e4fb18e2726efcd842a3aa2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Oct 2022 00:27:18 +0300 +Subject: Bluetooth: L2CAP: Fix use-after-free caused by l2cap_reassemble_sdu + +From: Maxim Mikityanskiy + +[ Upstream commit 3aff8aaca4e36dc8b17eaa011684881a80238966 ] + +Fix the race condition between the following two flows that run in +parallel: + +1. l2cap_reassemble_sdu -> chan->ops->recv (l2cap_sock_recv_cb) -> + __sock_queue_rcv_skb. + +2. bt_sock_recvmsg -> skb_recv_datagram, skb_free_datagram. + +An SKB can be queued by the first flow and immediately dequeued and +freed by the second flow, therefore the callers of l2cap_reassemble_sdu +can't use the SKB after that function returns. However, some places +continue accessing struct l2cap_ctrl that resides in the SKB's CB for a +short time after l2cap_reassemble_sdu returns, leading to a +use-after-free condition (the stack trace is below, line numbers for +kernel 5.19.8). + +Fix it by keeping a local copy of struct l2cap_ctrl. + +BUG: KASAN: use-after-free in l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth +Read of size 1 at addr ffff88812025f2f0 by task kworker/u17:3/43169 + +Workqueue: hci0 hci_rx_work [bluetooth] +Call Trace: + + dump_stack_lvl (lib/dump_stack.c:107 (discriminator 4)) + print_report.cold (mm/kasan/report.c:314 mm/kasan/report.c:429) + ? l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth + kasan_report (mm/kasan/report.c:162 mm/kasan/report.c:493) + ? l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth + l2cap_rx_state_recv (net/bluetooth/l2cap_core.c:6906) bluetooth + l2cap_rx (net/bluetooth/l2cap_core.c:7236 net/bluetooth/l2cap_core.c:7271) bluetooth + ret_from_fork (arch/x86/entry/entry_64.S:306) + + +Allocated by task 43169: + kasan_save_stack (mm/kasan/common.c:39) + __kasan_slab_alloc (mm/kasan/common.c:45 mm/kasan/common.c:436 mm/kasan/common.c:469) + kmem_cache_alloc_node (mm/slab.h:750 mm/slub.c:3243 mm/slub.c:3293) + __alloc_skb (net/core/skbuff.c:414) + l2cap_recv_frag (./include/net/bluetooth/bluetooth.h:425 net/bluetooth/l2cap_core.c:8329) bluetooth + l2cap_recv_acldata (net/bluetooth/l2cap_core.c:8442) bluetooth + hci_rx_work (net/bluetooth/hci_core.c:3642 net/bluetooth/hci_core.c:3832) bluetooth + process_one_work (kernel/workqueue.c:2289) + worker_thread (./include/linux/list.h:292 kernel/workqueue.c:2437) + kthread (kernel/kthread.c:376) + ret_from_fork (arch/x86/entry/entry_64.S:306) + +Freed by task 27920: + kasan_save_stack (mm/kasan/common.c:39) + kasan_set_track (mm/kasan/common.c:45) + kasan_set_free_info (mm/kasan/generic.c:372) + ____kasan_slab_free (mm/kasan/common.c:368 mm/kasan/common.c:328) + slab_free_freelist_hook (mm/slub.c:1780) + kmem_cache_free (mm/slub.c:3536 mm/slub.c:3553) + skb_free_datagram (./include/net/sock.h:1578 ./include/net/sock.h:1639 net/core/datagram.c:323) + bt_sock_recvmsg (net/bluetooth/af_bluetooth.c:295) bluetooth + l2cap_sock_recvmsg (net/bluetooth/l2cap_sock.c:1212) bluetooth + sock_read_iter (net/socket.c:1087) + new_sync_read (./include/linux/fs.h:2052 fs/read_write.c:401) + vfs_read (fs/read_write.c:482) + ksys_read (fs/read_write.c:620) + do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) + +Link: https://lore.kernel.org/linux-bluetooth/CAKErNvoqga1WcmoR3-0875esY6TVWFQDandbVZncSiuGPBQXLA@mail.gmail.com/T/#u +Fixes: d2a7ac5d5d3a ("Bluetooth: Add the ERTM receive state machine") +Fixes: 4b51dae96731 ("Bluetooth: Add streaming mode receive and incoming packet classifier") +Signed-off-by: Maxim Mikityanskiy +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 48 ++++++++++++++++++++++++++++++++------ + 1 file changed, 41 insertions(+), 7 deletions(-) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 8f1a95b9d320..d12d66f31b47 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -6885,6 +6885,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, + struct l2cap_ctrl *control, + struct sk_buff *skb, u8 event) + { ++ struct l2cap_ctrl local_control; + int err = 0; + bool skb_in_use = false; + +@@ -6909,15 +6910,32 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, + chan->buffer_seq = chan->expected_tx_seq; + skb_in_use = true; + ++ /* l2cap_reassemble_sdu may free skb, hence invalidate ++ * control, so make a copy in advance to use it after ++ * l2cap_reassemble_sdu returns and to avoid the race ++ * condition, for example: ++ * ++ * The current thread calls: ++ * l2cap_reassemble_sdu ++ * chan->ops->recv == l2cap_sock_recv_cb ++ * __sock_queue_rcv_skb ++ * Another thread calls: ++ * bt_sock_recvmsg ++ * skb_recv_datagram ++ * skb_free_datagram ++ * Then the current thread tries to access control, but ++ * it was freed by skb_free_datagram. ++ */ ++ local_control = *control; + err = l2cap_reassemble_sdu(chan, skb, control); + if (err) + break; + +- if (control->final) { ++ if (local_control.final) { + if (!test_and_clear_bit(CONN_REJ_ACT, + &chan->conn_state)) { +- control->final = 0; +- l2cap_retransmit_all(chan, control); ++ local_control.final = 0; ++ l2cap_retransmit_all(chan, &local_control); + l2cap_ertm_send(chan); + } + } +@@ -7297,11 +7315,27 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + struct sk_buff *skb) + { ++ /* l2cap_reassemble_sdu may free skb, hence invalidate control, so store ++ * the txseq field in advance to use it after l2cap_reassemble_sdu ++ * returns and to avoid the race condition, for example: ++ * ++ * The current thread calls: ++ * l2cap_reassemble_sdu ++ * chan->ops->recv == l2cap_sock_recv_cb ++ * __sock_queue_rcv_skb ++ * Another thread calls: ++ * bt_sock_recvmsg ++ * skb_recv_datagram ++ * skb_free_datagram ++ * Then the current thread tries to access control, but it was freed by ++ * skb_free_datagram. ++ */ ++ u16 txseq = control->txseq; ++ + BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, + chan->rx_state); + +- if (l2cap_classify_txseq(chan, control->txseq) == +- L2CAP_TXSEQ_EXPECTED) { ++ if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) { + l2cap_pass_to_tx(chan, control); + + BT_DBG("buffer_seq %u->%u", chan->buffer_seq, +@@ -7324,8 +7358,8 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, + } + } + +- chan->last_acked_seq = control->txseq; +- chan->expected_tx_seq = __next_seq(chan, control->txseq); ++ chan->last_acked_seq = txseq; ++ chan->expected_tx_seq = __next_seq(chan, txseq); + + return 0; + } +-- +2.35.1 + diff --git a/queue-5.15/bluetooth-l2cap-fix-use-after-free-in-l2cap_conn_del.patch b/queue-5.15/bluetooth-l2cap-fix-use-after-free-in-l2cap_conn_del.patch new file mode 100644 index 00000000000..4994e134d9d --- /dev/null +++ b/queue-5.15/bluetooth-l2cap-fix-use-after-free-in-l2cap_conn_del.patch @@ -0,0 +1,141 @@ +From f3cf2ad9bc6f0ea5f63739ac222113477c837137 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Oct 2022 15:58:13 +0800 +Subject: Bluetooth: L2CAP: fix use-after-free in l2cap_conn_del() + +From: Zhengchao Shao + +[ Upstream commit 0d0e2d032811280b927650ff3c15fe5020e82533 ] + +When l2cap_recv_frame() is invoked to receive data, and the cid is +L2CAP_CID_A2MP, if the channel does not exist, it will create a channel. +However, after a channel is created, the hold operation of the channel +is not performed. In this case, the value of channel reference counting +is 1. As a result, after hci_error_reset() is triggered, l2cap_conn_del() +invokes the close hook function of A2MP to release the channel. Then + l2cap_chan_unlock(chan) will trigger UAF issue. + +The process is as follows: +Receive data: +l2cap_data_channel() + a2mp_channel_create() --->channel ref is 2 + l2cap_chan_put() --->channel ref is 1 + +Triger event: + hci_error_reset() + hci_dev_do_close() + ... + l2cap_disconn_cfm() + l2cap_conn_del() + l2cap_chan_hold() --->channel ref is 2 + l2cap_chan_del() --->channel ref is 1 + a2mp_chan_close_cb() --->channel ref is 0, release channel + l2cap_chan_unlock() --->UAF of channel + +The detailed Call Trace is as follows: +BUG: KASAN: use-after-free in __mutex_unlock_slowpath+0xa6/0x5e0 +Read of size 8 at addr ffff8880160664b8 by task kworker/u11:1/7593 +Workqueue: hci0 hci_error_reset +Call Trace: + + dump_stack_lvl+0xcd/0x134 + print_report.cold+0x2ba/0x719 + kasan_report+0xb1/0x1e0 + kasan_check_range+0x140/0x190 + __mutex_unlock_slowpath+0xa6/0x5e0 + l2cap_conn_del+0x404/0x7b0 + l2cap_disconn_cfm+0x8c/0xc0 + hci_conn_hash_flush+0x11f/0x260 + hci_dev_close_sync+0x5f5/0x11f0 + hci_dev_do_close+0x2d/0x70 + hci_error_reset+0x9e/0x140 + process_one_work+0x98a/0x1620 + worker_thread+0x665/0x1080 + kthread+0x2e4/0x3a0 + ret_from_fork+0x1f/0x30 + + +Allocated by task 7593: + kasan_save_stack+0x1e/0x40 + __kasan_kmalloc+0xa9/0xd0 + l2cap_chan_create+0x40/0x930 + amp_mgr_create+0x96/0x990 + a2mp_channel_create+0x7d/0x150 + l2cap_recv_frame+0x51b8/0x9a70 + l2cap_recv_acldata+0xaa3/0xc00 + hci_rx_work+0x702/0x1220 + process_one_work+0x98a/0x1620 + worker_thread+0x665/0x1080 + kthread+0x2e4/0x3a0 + ret_from_fork+0x1f/0x30 + +Freed by task 7593: + kasan_save_stack+0x1e/0x40 + kasan_set_track+0x21/0x30 + kasan_set_free_info+0x20/0x30 + ____kasan_slab_free+0x167/0x1c0 + slab_free_freelist_hook+0x89/0x1c0 + kfree+0xe2/0x580 + l2cap_chan_put+0x22a/0x2d0 + l2cap_conn_del+0x3fc/0x7b0 + l2cap_disconn_cfm+0x8c/0xc0 + hci_conn_hash_flush+0x11f/0x260 + hci_dev_close_sync+0x5f5/0x11f0 + hci_dev_do_close+0x2d/0x70 + hci_error_reset+0x9e/0x140 + process_one_work+0x98a/0x1620 + worker_thread+0x665/0x1080 + kthread+0x2e4/0x3a0 + ret_from_fork+0x1f/0x30 + +Last potentially related work creation: + kasan_save_stack+0x1e/0x40 + __kasan_record_aux_stack+0xbe/0xd0 + call_rcu+0x99/0x740 + netlink_release+0xe6a/0x1cf0 + __sock_release+0xcd/0x280 + sock_close+0x18/0x20 + __fput+0x27c/0xa90 + task_work_run+0xdd/0x1a0 + exit_to_user_mode_prepare+0x23c/0x250 + syscall_exit_to_user_mode+0x19/0x50 + do_syscall_64+0x42/0x80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Second to last potentially related work creation: + kasan_save_stack+0x1e/0x40 + __kasan_record_aux_stack+0xbe/0xd0 + call_rcu+0x99/0x740 + netlink_release+0xe6a/0x1cf0 + __sock_release+0xcd/0x280 + sock_close+0x18/0x20 + __fput+0x27c/0xa90 + task_work_run+0xdd/0x1a0 + exit_to_user_mode_prepare+0x23c/0x250 + syscall_exit_to_user_mode+0x19/0x50 + do_syscall_64+0x42/0x80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: d0be8347c623 ("Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put") +Signed-off-by: Zhengchao Shao +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index d12d66f31b47..a18a1c608ed1 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -7615,6 +7615,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, + return; + } + ++ l2cap_chan_hold(chan); + l2cap_chan_lock(chan); + } else { + BT_DBG("unknown cid 0x%4.4x", cid); +-- +2.35.1 + diff --git a/queue-5.15/bluetooth-virtio_bt-use-skb_put-to-set-length.patch b/queue-5.15/bluetooth-virtio_bt-use-skb_put-to-set-length.patch new file mode 100644 index 00000000000..8461c4cd6e8 --- /dev/null +++ b/queue-5.15/bluetooth-virtio_bt-use-skb_put-to-set-length.patch @@ -0,0 +1,43 @@ +From b1168f423c3af865a0988f9b099ef706ebb27635 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Oct 2022 09:45:06 +0200 +Subject: Bluetooth: virtio_bt: Use skb_put to set length + +From: Soenke Huster + +[ Upstream commit 160fbcf3bfb93c3c086427f9f4c8bc70f217e9be ] + +By using skb_put we ensure that skb->tail is set +correctly. Currently, skb->tail is always zero, which +leads to errors, such as the following page fault in +rfcomm_recv_frame: + + BUG: unable to handle page fault for address: ffffed1021de29ff + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + RIP: 0010:rfcomm_run+0x831/0x4040 (net/bluetooth/rfcomm/core.c:1751) + +Fixes: afd2daa26c7a ("Bluetooth: Add support for virtio transport driver") +Signed-off-by: Soenke Huster +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/virtio_bt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c +index 076e4942a3f0..612f10456849 100644 +--- a/drivers/bluetooth/virtio_bt.c ++++ b/drivers/bluetooth/virtio_bt.c +@@ -219,7 +219,7 @@ static void virtbt_rx_work(struct work_struct *work) + if (!skb) + return; + +- skb->len = len; ++ skb_put(skb, len); + virtbt_rx_handle(vbt, skb); + + if (virtbt_add_inbuf(vbt) < 0) +-- +2.35.1 + diff --git a/queue-5.15/btrfs-fix-inode-list-leak-during-backref-walking-at-.patch b/queue-5.15/btrfs-fix-inode-list-leak-during-backref-walking-at-.patch new file mode 100644 index 00000000000..c8a7f09bfe7 --- /dev/null +++ b/queue-5.15/btrfs-fix-inode-list-leak-during-backref-walking-at-.patch @@ -0,0 +1,94 @@ +From 16d9c8ab0a39d726e3f749e39e1c9f85d951e9ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 16:15:37 +0000 +Subject: btrfs: fix inode list leak during backref walking at + resolve_indirect_refs() + +From: Filipe Manana + +[ Upstream commit 5614dc3a47e3310fbc77ea3b67eaadd1c6417bf1 ] + +During backref walking, at resolve_indirect_refs(), if we get an error +we jump to the 'out' label and call ulist_free() on the 'parents' ulist, +which frees all the elements in the ulist - however that does not free +any inode lists that may be attached to elements, through the 'aux' field +of a ulist node, so we end up leaking lists if we have any attached to +the unodes. + +Fix this by calling free_leaf_list() instead of ulist_free() when we exit +from resolve_indirect_refs(). The static function free_leaf_list() is +moved up for this to be possible and it's slightly simplified by removing +unnecessary code. + +Fixes: 3301958b7c1d ("Btrfs: add inodes before dropping the extent lock in find_all_leafs") +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/backref.c | 36 +++++++++++++++++------------------- + 1 file changed, 17 insertions(+), 19 deletions(-) + +diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c +index 2e7c3e48bc9c..26e6867ff023 100644 +--- a/fs/btrfs/backref.c ++++ b/fs/btrfs/backref.c +@@ -648,6 +648,18 @@ unode_aux_to_inode_list(struct ulist_node *node) + return (struct extent_inode_elem *)(uintptr_t)node->aux; + } + ++static void free_leaf_list(struct ulist *ulist) ++{ ++ struct ulist_node *node; ++ struct ulist_iterator uiter; ++ ++ ULIST_ITER_INIT(&uiter); ++ while ((node = ulist_next(ulist, &uiter))) ++ free_inode_elem_list(unode_aux_to_inode_list(node)); ++ ++ ulist_free(ulist); ++} ++ + /* + * We maintain three separate rbtrees: one for direct refs, one for + * indirect refs which have a key, and one for indirect refs which do not +@@ -762,7 +774,11 @@ static int resolve_indirect_refs(struct btrfs_fs_info *fs_info, + cond_resched(); + } + out: +- ulist_free(parents); ++ /* ++ * We may have inode lists attached to refs in the parents ulist, so we ++ * must free them before freeing the ulist and its refs. ++ */ ++ free_leaf_list(parents); + return ret; + } + +@@ -1412,24 +1428,6 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, + return ret; + } + +-static void free_leaf_list(struct ulist *blocks) +-{ +- struct ulist_node *node = NULL; +- struct extent_inode_elem *eie; +- struct ulist_iterator uiter; +- +- ULIST_ITER_INIT(&uiter); +- while ((node = ulist_next(blocks, &uiter))) { +- if (!node->aux) +- continue; +- eie = unode_aux_to_inode_list(node); +- free_inode_elem_list(eie); +- node->aux = 0; +- } +- +- ulist_free(blocks); +-} +- + /* + * Finds all leafs with a reference to the specified combination of bytenr and + * offset. key_list_head will point to a list of corresponding keys (caller must +-- +2.35.1 + diff --git a/queue-5.15/btrfs-fix-inode-list-leak-during-backref-walking-at-.patch-13284 b/queue-5.15/btrfs-fix-inode-list-leak-during-backref-walking-at-.patch-13284 new file mode 100644 index 00000000000..b470bdbca80 --- /dev/null +++ b/queue-5.15/btrfs-fix-inode-list-leak-during-backref-walking-at-.patch-13284 @@ -0,0 +1,81 @@ +From 6fd639bc1cedcc070dbdd57805af0d6807c372c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 16:15:38 +0000 +Subject: btrfs: fix inode list leak during backref walking at + find_parent_nodes() + +From: Filipe Manana + +[ Upstream commit 92876eec382a0f19f33d09d2c939e9ca49038ae5 ] + +During backref walking, at find_parent_nodes(), if we are dealing with a +data extent and we get an error while resolving the indirect backrefs, at +resolve_indirect_refs(), or in the while loop that iterates over the refs +in the direct refs rbtree, we end up leaking the inode lists attached to +the direct refs we have in the direct refs rbtree that were not yet added +to the refs ulist passed as argument to find_parent_nodes(). Since they +were not yet added to the refs ulist and prelim_release() does not free +the lists, on error the caller can only free the lists attached to the +refs that were added to the refs ulist, all the remaining refs get their +inode lists never freed, therefore leaking their memory. + +Fix this by having prelim_release() always free any attached inode list +to each ref found in the rbtree, and have find_parent_nodes() set the +ref's inode list to NULL once it transfers ownership of the inode list +to a ref added to the refs ulist passed to find_parent_nodes(). + +Fixes: 86d5f9944252 ("btrfs: convert prelimary reference tracking to use rbtrees") +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/backref.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c +index 26e6867ff023..60bec5a108fa 100644 +--- a/fs/btrfs/backref.c ++++ b/fs/btrfs/backref.c +@@ -289,8 +289,10 @@ static void prelim_release(struct preftree *preftree) + struct prelim_ref *ref, *next_ref; + + rbtree_postorder_for_each_entry_safe(ref, next_ref, +- &preftree->root.rb_root, rbnode) ++ &preftree->root.rb_root, rbnode) { ++ free_inode_elem_list(ref->inode_list); + free_pref(ref); ++ } + + preftree->root = RB_ROOT_CACHED; + preftree->count = 0; +@@ -1387,6 +1389,12 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, + if (ret < 0) + goto out; + ref->inode_list = eie; ++ /* ++ * We transferred the list ownership to the ref, ++ * so set to NULL to avoid a double free in case ++ * an error happens after this. ++ */ ++ eie = NULL; + } + ret = ulist_add_merge_ptr(refs, ref->parent, + ref->inode_list, +@@ -1412,6 +1420,14 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, + eie->next = ref->inode_list; + } + eie = NULL; ++ /* ++ * We have transferred the inode list ownership from ++ * this ref to the ref we added to the 'refs' ulist. ++ * So set this ref's inode list to NULL to avoid ++ * use-after-free when our caller uses it or double ++ * frees in case an error happens before we return. ++ */ ++ ref->inode_list = NULL; + } + cond_resched(); + } +-- +2.35.1 + diff --git a/queue-5.15/btrfs-fix-ulist-leaks-in-error-paths-of-qgroup-self-.patch b/queue-5.15/btrfs-fix-ulist-leaks-in-error-paths-of-qgroup-self-.patch new file mode 100644 index 00000000000..c0c11d06cb6 --- /dev/null +++ b/queue-5.15/btrfs-fix-ulist-leaks-in-error-paths-of-qgroup-self-.patch @@ -0,0 +1,90 @@ +From 4ae3384ea534f181e3228132f3cddbc526970f83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 16:15:39 +0000 +Subject: btrfs: fix ulist leaks in error paths of qgroup self tests + +From: Filipe Manana + +[ Upstream commit d37de92b38932d40e4a251e876cc388f9aee5f42 ] + +In the test_no_shared_qgroup() and test_multiple_refs() qgroup self tests, +if we fail to add the tree ref, remove the extent item or remove the +extent ref, we are returning from the test function without freeing the +"old_roots" ulist that was allocated by the previous calls to +btrfs_find_all_roots(). Fix that by calling ulist_free() before returning. + +Fixes: 442244c96332 ("btrfs: qgroup: Switch self test to extent-oriented qgroup mechanism.") +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tests/qgroup-tests.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c +index 19ba7d5b7d8f..a374b62c9de9 100644 +--- a/fs/btrfs/tests/qgroup-tests.c ++++ b/fs/btrfs/tests/qgroup-tests.c +@@ -232,8 +232,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root, + + ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, + BTRFS_FS_TREE_OBJECTID); +- if (ret) ++ if (ret) { ++ ulist_free(old_roots); + return ret; ++ } + + ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); + if (ret) { +@@ -266,8 +268,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root, + } + + ret = remove_extent_item(root, nodesize, nodesize); +- if (ret) ++ if (ret) { ++ ulist_free(old_roots); + return -EINVAL; ++ } + + ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); + if (ret) { +@@ -329,8 +333,10 @@ static int test_multiple_refs(struct btrfs_root *root, + + ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, + BTRFS_FS_TREE_OBJECTID); +- if (ret) ++ if (ret) { ++ ulist_free(old_roots); + return ret; ++ } + + ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); + if (ret) { +@@ -362,8 +368,10 @@ static int test_multiple_refs(struct btrfs_root *root, + + ret = add_tree_ref(root, nodesize, nodesize, 0, + BTRFS_FIRST_FREE_OBJECTID); +- if (ret) ++ if (ret) { ++ ulist_free(old_roots); + return ret; ++ } + + ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); + if (ret) { +@@ -401,8 +409,10 @@ static int test_multiple_refs(struct btrfs_root *root, + + ret = remove_extent_ref(root, nodesize, nodesize, 0, + BTRFS_FIRST_FREE_OBJECTID); +- if (ret) ++ if (ret) { ++ ulist_free(old_roots); + return ret; ++ } + + ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false); + if (ret) { +-- +2.35.1 + diff --git a/queue-5.15/ib-hfi1-correctly-move-list-in-sc_disable.patch b/queue-5.15/ib-hfi1-correctly-move-list-in-sc_disable.patch new file mode 100644 index 00000000000..d58f0332d35 --- /dev/null +++ b/queue-5.15/ib-hfi1-correctly-move-list-in-sc_disable.patch @@ -0,0 +1,59 @@ +From f3c160fb4a6be82254aa505885af3c452bd95ef7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Oct 2022 10:27:50 -0400 +Subject: IB/hfi1: Correctly move list in sc_disable() + +From: Dean Luick + +[ Upstream commit 1afac08b39d85437187bb2a92d89a741b1078f55 ] + +Commit 13bac861952a ("IB/hfi1: Fix abba locking issue with sc_disable()") +incorrectly tries to move a list from one list head to another. The +result is a kernel crash. + +The crash is triggered when a link goes down and there are waiters for a +send to complete. The following signature is seen: + + BUG: kernel NULL pointer dereference, address: 0000000000000030 + [...] + Call Trace: + sc_disable+0x1ba/0x240 [hfi1] + pio_freeze+0x3d/0x60 [hfi1] + handle_freeze+0x27/0x1b0 [hfi1] + process_one_work+0x1b0/0x380 + ? process_one_work+0x380/0x380 + worker_thread+0x30/0x360 + ? process_one_work+0x380/0x380 + kthread+0xd7/0x100 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x1f/0x30 + +The fix is to use the correct call to move the list. + +Fixes: 13bac861952a ("IB/hfi1: Fix abba locking issue with sc_disable()") +Signed-off-by: Dean Luick +Signed-off-by: Dennis Dalessandro +Link: https://lore.kernel.org/r/166610327042.674422.6146908799669288976.stgit@awfm-02.cornelisnetworks.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/pio.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c +index 3d42bd2b36bd..51ae58c02b15 100644 +--- a/drivers/infiniband/hw/hfi1/pio.c ++++ b/drivers/infiniband/hw/hfi1/pio.c +@@ -913,8 +913,7 @@ void sc_disable(struct send_context *sc) + spin_unlock(&sc->release_lock); + + write_seqlock(&sc->waitlock); +- if (!list_empty(&sc->piowait)) +- list_move(&sc->piowait, &wake_list); ++ list_splice_init(&sc->piowait, &wake_list); + write_sequnlock(&sc->waitlock); + while (!list_empty(&wake_list)) { + struct iowait *wait; +-- +2.35.1 + diff --git a/queue-5.15/ibmvnic-free-rwi-on-reset-success.patch b/queue-5.15/ibmvnic-free-rwi-on-reset-success.patch new file mode 100644 index 00000000000..4bd9b85e8e1 --- /dev/null +++ b/queue-5.15/ibmvnic-free-rwi-on-reset-success.patch @@ -0,0 +1,59 @@ +From 8db7c14f867aa97cdae70a76fda4d708dd8eb54a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 10:06:42 -0500 +Subject: ibmvnic: Free rwi on reset success + +From: Nick Child + +[ Upstream commit d6dd2fe71153f0ff748bf188bd4af076fe09a0a6 ] + +Free the rwi structure in the event that the last rwi in the list +processed successfully. The logic in commit 4f408e1fa6e1 ("ibmvnic: +retry reset if there are no other resets") introduces an issue that +results in a 32 byte memory leak whenever the last rwi in the list +gets processed. + +Fixes: 4f408e1fa6e1 ("ibmvnic: retry reset if there are no other resets") +Signed-off-by: Nick Child +Link: https://lore.kernel.org/r/20221031150642.13356-1-nnac123@linux.ibm.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ibm/ibmvnic.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 4a070724a8fb..8a92c6a6e764 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -2621,19 +2621,19 @@ static void __ibmvnic_reset(struct work_struct *work) + rwi = get_next_rwi(adapter); + + /* +- * If there is another reset queued, free the previous rwi +- * and process the new reset even if previous reset failed +- * (the previous reset could have failed because of a fail +- * over for instance, so process the fail over). +- * + * If there are no resets queued and the previous reset failed, + * the adapter would be in an undefined state. So retry the + * previous reset as a hard reset. ++ * ++ * Else, free the previous rwi and, if there is another reset ++ * queued, process the new reset even if previous reset failed ++ * (the previous reset could have failed because of a fail ++ * over for instance, so process the fail over). + */ +- if (rwi) +- kfree(tmprwi); +- else if (rc) ++ if (!rwi && rc) + rwi = tmprwi; ++ else ++ kfree(tmprwi); + + if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER || + rwi->reset_reason == VNIC_RESET_MOBILITY || rc)) +-- +2.35.1 + diff --git a/queue-5.15/ipv6-fix-warning-in-ip6_route_net_exit_late.patch b/queue-5.15/ipv6-fix-warning-in-ip6_route_net_exit_late.patch new file mode 100644 index 00000000000..59f434668a1 --- /dev/null +++ b/queue-5.15/ipv6-fix-warning-in-ip6_route_net_exit_late.patch @@ -0,0 +1,70 @@ +From 0113d5cc5f24c4dd11ec3006001b98850002dcf4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 10:06:10 +0800 +Subject: ipv6: fix WARNING in ip6_route_net_exit_late() + +From: Zhengchao Shao + +[ Upstream commit 768b3c745fe5789f2430bdab02f35a9ad1148d97 ] + +During the initialization of ip6_route_net_init_late(), if file +ipv6_route or rt6_stats fails to be created, the initialization is +successful by default. Therefore, the ipv6_route or rt6_stats file +doesn't be found during the remove in ip6_route_net_exit_late(). It +will cause WRNING. + +The following is the stack information: +name 'rt6_stats' +WARNING: CPU: 0 PID: 9 at fs/proc/generic.c:712 remove_proc_entry+0x389/0x460 +Modules linked in: +Workqueue: netns cleanup_net +RIP: 0010:remove_proc_entry+0x389/0x460 +PKRU: 55555554 +Call Trace: + +ops_exit_list+0xb0/0x170 +cleanup_net+0x4ea/0xb00 +process_one_work+0x9bf/0x1710 +worker_thread+0x665/0x1080 +kthread+0x2e4/0x3a0 +ret_from_fork+0x1f/0x30 + + +Fixes: cdb1876192db ("[NETNS][IPV6] route6 - create route6 proc files for the namespace") +Signed-off-by: Zhengchao Shao +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20221102020610.351330-1-shaozhengchao@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 27274fc3619a..0655fd8c67e9 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -6570,10 +6570,16 @@ static void __net_exit ip6_route_net_exit(struct net *net) + static int __net_init ip6_route_net_init_late(struct net *net) + { + #ifdef CONFIG_PROC_FS +- proc_create_net("ipv6_route", 0, net->proc_net, &ipv6_route_seq_ops, +- sizeof(struct ipv6_route_iter)); +- proc_create_net_single("rt6_stats", 0444, net->proc_net, +- rt6_stats_seq_show, NULL); ++ if (!proc_create_net("ipv6_route", 0, net->proc_net, ++ &ipv6_route_seq_ops, ++ sizeof(struct ipv6_route_iter))) ++ return -ENOMEM; ++ ++ if (!proc_create_net_single("rt6_stats", 0444, net->proc_net, ++ rt6_stats_seq_show, NULL)) { ++ remove_proc_entry("ipv6_route", net->proc_net); ++ return -ENOMEM; ++ } + #endif + return 0; + } +-- +2.35.1 + diff --git a/queue-5.15/ipvs-fix-warning-in-__ip_vs_cleanup_batch.patch b/queue-5.15/ipvs-fix-warning-in-__ip_vs_cleanup_batch.patch new file mode 100644 index 00000000000..0bcffa80160 --- /dev/null +++ b/queue-5.15/ipvs-fix-warning-in-__ip_vs_cleanup_batch.patch @@ -0,0 +1,90 @@ +From c59feed858066569139a614041be5c221267ff16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 20:07:04 +0800 +Subject: ipvs: fix WARNING in __ip_vs_cleanup_batch() + +From: Zhengchao Shao + +[ Upstream commit 3d00c6a0da8ddcf75213e004765e4a42acc71d5d ] + +During the initialization of ip_vs_conn_net_init(), if file ip_vs_conn +or ip_vs_conn_sync fails to be created, the initialization is successful +by default. Therefore, the ip_vs_conn or ip_vs_conn_sync file doesn't +be found during the remove. + +The following is the stack information: +name 'ip_vs_conn_sync' +WARNING: CPU: 3 PID: 9 at fs/proc/generic.c:712 +remove_proc_entry+0x389/0x460 +Modules linked in: +Workqueue: netns cleanup_net +RIP: 0010:remove_proc_entry+0x389/0x460 +Call Trace: + +__ip_vs_cleanup_batch+0x7d/0x120 +ops_exit_list+0x125/0x170 +cleanup_net+0x4ea/0xb00 +process_one_work+0x9bf/0x1710 +worker_thread+0x665/0x1080 +kthread+0x2e4/0x3a0 +ret_from_fork+0x1f/0x30 + + +Fixes: 61b1ab4583e2 ("IPVS: netns, add basic init per netns.") +Signed-off-by: Zhengchao Shao +Acked-by: Julian Anastasov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_conn.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c +index db13288fddfa..cb6d68220c26 100644 +--- a/net/netfilter/ipvs/ip_vs_conn.c ++++ b/net/netfilter/ipvs/ip_vs_conn.c +@@ -1447,20 +1447,36 @@ int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs) + { + atomic_set(&ipvs->conn_count, 0); + +- proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net, +- &ip_vs_conn_seq_ops, sizeof(struct ip_vs_iter_state)); +- proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net, +- &ip_vs_conn_sync_seq_ops, +- sizeof(struct ip_vs_iter_state)); ++#ifdef CONFIG_PROC_FS ++ if (!proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net, ++ &ip_vs_conn_seq_ops, ++ sizeof(struct ip_vs_iter_state))) ++ goto err_conn; ++ ++ if (!proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net, ++ &ip_vs_conn_sync_seq_ops, ++ sizeof(struct ip_vs_iter_state))) ++ goto err_conn_sync; ++#endif ++ + return 0; ++ ++#ifdef CONFIG_PROC_FS ++err_conn_sync: ++ remove_proc_entry("ip_vs_conn", ipvs->net->proc_net); ++err_conn: ++ return -ENOMEM; ++#endif + } + + void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs) + { + /* flush all the connection entries first */ + ip_vs_conn_flush(ipvs); ++#ifdef CONFIG_PROC_FS + remove_proc_entry("ip_vs_conn", ipvs->net->proc_net); + remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net); ++#endif + } + + int __init ip_vs_conn_init(void) +-- +2.35.1 + diff --git a/queue-5.15/ipvs-fix-warning-in-ip_vs_app_net_cleanup.patch b/queue-5.15/ipvs-fix-warning-in-ip_vs_app_net_cleanup.patch new file mode 100644 index 00000000000..b2bc9f58545 --- /dev/null +++ b/queue-5.15/ipvs-fix-warning-in-ip_vs_app_net_cleanup.patch @@ -0,0 +1,68 @@ +From 9c847e3fad1e54333166d40c056ea3d127223ab0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 20:07:05 +0800 +Subject: ipvs: fix WARNING in ip_vs_app_net_cleanup() + +From: Zhengchao Shao + +[ Upstream commit 5663ed63adb9619c98ab7479aa4606fa9b7a548c ] + +During the initialization of ip_vs_app_net_init(), if file ip_vs_app +fails to be created, the initialization is successful by default. +Therefore, the ip_vs_app file doesn't be found during the remove in +ip_vs_app_net_cleanup(). It will cause WRNING. + +The following is the stack information: +name 'ip_vs_app' +WARNING: CPU: 1 PID: 9 at fs/proc/generic.c:712 remove_proc_entry+0x389/0x460 +Modules linked in: +Workqueue: netns cleanup_net +RIP: 0010:remove_proc_entry+0x389/0x460 +Call Trace: + +ops_exit_list+0x125/0x170 +cleanup_net+0x4ea/0xb00 +process_one_work+0x9bf/0x1710 +worker_thread+0x665/0x1080 +kthread+0x2e4/0x3a0 +ret_from_fork+0x1f/0x30 + + +Fixes: 457c4cbc5a3d ("[NET]: Make /proc/net per network namespace") +Signed-off-by: Zhengchao Shao +Acked-by: Julian Anastasov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_app.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c +index f9b16f2b2219..fdacbc3c15be 100644 +--- a/net/netfilter/ipvs/ip_vs_app.c ++++ b/net/netfilter/ipvs/ip_vs_app.c +@@ -599,13 +599,19 @@ static const struct seq_operations ip_vs_app_seq_ops = { + int __net_init ip_vs_app_net_init(struct netns_ipvs *ipvs) + { + INIT_LIST_HEAD(&ipvs->app_list); +- proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, &ip_vs_app_seq_ops, +- sizeof(struct seq_net_private)); ++#ifdef CONFIG_PROC_FS ++ if (!proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, ++ &ip_vs_app_seq_ops, ++ sizeof(struct seq_net_private))) ++ return -ENOMEM; ++#endif + return 0; + } + + void __net_exit ip_vs_app_net_cleanup(struct netns_ipvs *ipvs) + { + unregister_ip_vs_app(ipvs, NULL /* all */); ++#ifdef CONFIG_PROC_FS + remove_proc_entry("ip_vs_app", ipvs->net->proc_net); ++#endif + } +-- +2.35.1 + diff --git a/queue-5.15/ipvs-use-explicitly-signed-chars.patch b/queue-5.15/ipvs-use-explicitly-signed-chars.patch new file mode 100644 index 00000000000..50bcb0ca06a --- /dev/null +++ b/queue-5.15/ipvs-use-explicitly-signed-chars.patch @@ -0,0 +1,41 @@ +From 4c4e38f6f1ca5f0f15f0a415509de3479648b89f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 14:32:16 +0200 +Subject: ipvs: use explicitly signed chars + +From: Jason A. Donenfeld + +[ Upstream commit 5c26159c97b324dc5174a5713eafb8c855cf8106 ] + +The `char` type with no explicit sign is sometimes signed and sometimes +unsigned. This code will break on platforms such as arm, where char is +unsigned. So mark it here as explicitly signed, so that the +todrop_counter decrement and subsequent comparison is correct. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Jason A. Donenfeld +Acked-by: Julian Anastasov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_conn.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c +index fb67f1ca2495..db13288fddfa 100644 +--- a/net/netfilter/ipvs/ip_vs_conn.c ++++ b/net/netfilter/ipvs/ip_vs_conn.c +@@ -1265,8 +1265,8 @@ static inline int todrop_entry(struct ip_vs_conn *cp) + * The drop rate array needs tuning for real environments. + * Called from timer bh only => no locking + */ +- static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; +- static char todrop_counter[9] = {0}; ++ static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; ++ static signed char todrop_counter[9] = {0}; + int i; + + /* if the conn entry hasn't lasted for 60 seconds, don't drop it. +-- +2.35.1 + diff --git a/queue-5.15/isdn-misdn-netjet-fix-wrong-check-of-device-registra.patch b/queue-5.15/isdn-misdn-netjet-fix-wrong-check-of-device-registra.patch new file mode 100644 index 00000000000..6317a4a508b --- /dev/null +++ b/queue-5.15/isdn-misdn-netjet-fix-wrong-check-of-device-registra.patch @@ -0,0 +1,37 @@ +From d7010f18efa7f8d7bf5ee6ea9897997f2e30ee92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 20:13:41 +0800 +Subject: isdn: mISDN: netjet: fix wrong check of device registration + +From: Yang Yingliang + +[ Upstream commit bf00f5426074249058a106a6edbb89e4b25a4d79 ] + +The class is set in mISDN_register_device(), but if device_add() returns +error, it will lead to delete a device without added, fix this by using +device_is_registered() to check if the device is registered. + +Fixes: a900845e5661 ("mISDN: Add support for Traverse Technologies NETJet PCI cards") +Signed-off-by: Yang Yingliang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/isdn/hardware/mISDN/netjet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c +index a52f275f8263..f8447135a902 100644 +--- a/drivers/isdn/hardware/mISDN/netjet.c ++++ b/drivers/isdn/hardware/mISDN/netjet.c +@@ -956,7 +956,7 @@ nj_release(struct tiger_hw *card) + } + if (card->irq > 0) + free_irq(card->irq, card); +- if (card->isac.dch.dev.dev.class) ++ if (device_is_registered(&card->isac.dch.dev.dev)) + mISDN_unregister_device(&card->isac.dch.dev); + + for (i = 0; i < 2; i++) { +-- +2.35.1 + diff --git a/queue-5.15/misdn-fix-possible-memory-leak-in-misdn_register_dev.patch b/queue-5.15/misdn-fix-possible-memory-leak-in-misdn_register_dev.patch new file mode 100644 index 00000000000..7506c7661e7 --- /dev/null +++ b/queue-5.15/misdn-fix-possible-memory-leak-in-misdn_register_dev.patch @@ -0,0 +1,56 @@ +From 2294eb7fd222da9695b21bc22db17b524952a3c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 20:13:40 +0800 +Subject: mISDN: fix possible memory leak in mISDN_register_device() + +From: Yang Yingliang + +[ Upstream commit e7d1d4d9ac0dfa40be4c2c8abd0731659869b297 ] + +Afer commit 1fa5ae857bb1 ("driver core: get rid of struct device's +bus_id string array"), the name of device is allocated dynamically, +add put_device() to give up the reference, so that the name can be +freed in kobject_cleanup() when the refcount is 0. + +Set device class before put_device() to avoid null release() function +WARN message in device_release(). + +Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array") +Signed-off-by: Yang Yingliang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/isdn/mISDN/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c +index a41b4b264594..7ea0100f218a 100644 +--- a/drivers/isdn/mISDN/core.c ++++ b/drivers/isdn/mISDN/core.c +@@ -233,11 +233,12 @@ mISDN_register_device(struct mISDNdevice *dev, + if (debug & DEBUG_CORE) + printk(KERN_DEBUG "mISDN_register %s %d\n", + dev_name(&dev->dev), dev->id); ++ dev->dev.class = &mISDN_class; ++ + err = create_stack(dev); + if (err) + goto error1; + +- dev->dev.class = &mISDN_class; + dev->dev.platform_data = dev; + dev->dev.parent = parent; + dev_set_drvdata(&dev->dev, dev); +@@ -249,8 +250,8 @@ mISDN_register_device(struct mISDNdevice *dev, + + error3: + delete_stack(dev); +- return err; + error1: ++ put_device(&dev->dev); + return err; + + } +-- +2.35.1 + diff --git a/queue-5.15/net-dsa-fall-back-to-default-tagger-if-we-can-t-load.patch b/queue-5.15/net-dsa-fall-back-to-default-tagger-if-we-can-t-load.patch new file mode 100644 index 00000000000..d2e885cf2a6 --- /dev/null +++ b/queue-5.15/net-dsa-fall-back-to-default-tagger-if-we-can-t-load.patch @@ -0,0 +1,95 @@ +From c1ef6a2b7717251849bdf6d9b9b7a2855b2b0d2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 17:54:39 +0300 +Subject: net: dsa: fall back to default tagger if we can't load the one from + DT + +From: Vladimir Oltean + +[ Upstream commit a2c65a9d0568b6737c02b54f00b80716a53fac61 ] + +DSA tagging protocol drivers can be changed at runtime through sysfs and +at probe time through the device tree (support for the latter was added +later). + +When changing through sysfs, it is assumed that the module for the new +tagging protocol was already loaded into the kernel (in fact this is +only a concern for Ocelot/Felix switches, where we have tag_ocelot.ko +and tag_ocelot_8021q.ko; for every other switch, the default and +alternative protocols are compiled within the same .ko, so there is +nothing for the user to load). + +The kernel cannot currently call request_module(), because it has no way +of constructing the modalias name of the tagging protocol driver +("dsa_tag-%d", where the number is one of DSA_TAG_PROTO_*_VALUE). +The device tree only contains the string name of the tagging protocol +("ocelot-8021q"), and the only mapping between the string and the +DSA_TAG_PROTO_OCELOT_8021Q_VALUE is present in tag_ocelot_8021q.ko. +So this is a chicken-and-egg situation and dsa_core.ko has nothing based +on which it can automatically request the insertion of the module. + +As a consequence, if CONFIG_NET_DSA_TAG_OCELOT_8021Q is built as module, +the switch will forever defer probing. + +The long-term solution is to make DSA call request_module() somehow, +but that probably needs some refactoring. + +What we can do to keep operating with existing device tree blobs is to +cancel the attempt to change the tagging protocol with the one specified +there, and to remain operating with the default one. Depending on the +situation, the default protocol might still allow some functionality +(in the case of ocelot, it does), and it's better to have that than to +fail to probe. + +Fixes: deff710703d8 ("net: dsa: Allow default tag protocol to be overridden from DT") +Link: https://lore.kernel.org/lkml/20221027113248.420216-1-michael@walle.cc/ +Reported-by: Heiko Thiery +Reported-by: Michael Walle +Signed-off-by: Vladimir Oltean +Tested-by: Michael Walle +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20221027145439.3086017-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/dsa/dsa2.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index 64a56db3de58..34763f575c30 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -1253,9 +1253,9 @@ static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp, + static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master, + const char *user_protocol) + { ++ const struct dsa_device_ops *tag_ops = NULL; + struct dsa_switch *ds = dp->ds; + struct dsa_switch_tree *dst = ds->dst; +- const struct dsa_device_ops *tag_ops; + enum dsa_tag_protocol default_proto; + + /* Find out which protocol the switch would prefer. */ +@@ -1278,10 +1278,17 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master, + } + + tag_ops = dsa_find_tagger_by_name(user_protocol); +- } else { +- tag_ops = dsa_tag_driver_get(default_proto); ++ if (IS_ERR(tag_ops)) { ++ dev_warn(ds->dev, ++ "Failed to find a tagging driver for protocol %s, using default\n", ++ user_protocol); ++ tag_ops = NULL; ++ } + } + ++ if (!tag_ops) ++ tag_ops = dsa_tag_driver_get(default_proto); ++ + if (IS_ERR(tag_ops)) { + if (PTR_ERR(tag_ops) == -ENOPROTOOPT) + return -EPROBE_DEFER; +-- +2.35.1 + diff --git a/queue-5.15/net-dsa-fix-possible-memory-leaks-in-dsa_loop_init.patch b/queue-5.15/net-dsa-fix-possible-memory-leaks-in-dsa_loop_init.patch new file mode 100644 index 00000000000..0cb27cf483b --- /dev/null +++ b/queue-5.15/net-dsa-fix-possible-memory-leaks-in-dsa_loop_init.patch @@ -0,0 +1,108 @@ +From 5b954aa8c2583ed5f4deee5f96457653b97e0764 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 10:03:21 +0800 +Subject: net: dsa: Fix possible memory leaks in dsa_loop_init() + +From: Chen Zhongjin + +[ Upstream commit 633efc8b3dc96f56f5a57f2a49764853a2fa3f50 ] + +kmemleak reported memory leaks in dsa_loop_init(): + +kmemleak: 12 new suspected memory leaks + +unreferenced object 0xffff8880138ce000 (size 2048): + comm "modprobe", pid 390, jiffies 4295040478 (age 238.976s) + backtrace: + [<000000006a94f1d5>] kmalloc_trace+0x26/0x60 + [<00000000a9c44622>] phy_device_create+0x5d/0x970 + [<00000000d0ee2afc>] get_phy_device+0xf3/0x2b0 + [<00000000dca0c71f>] __fixed_phy_register.part.0+0x92/0x4e0 + [<000000008a834798>] fixed_phy_register+0x84/0xb0 + [<0000000055223fcb>] dsa_loop_init+0xa9/0x116 [dsa_loop] + ... + +There are two reasons for memleak in dsa_loop_init(). + +First, fixed_phy_register() create and register phy_device: + +fixed_phy_register() + get_phy_device() + phy_device_create() # freed by phy_device_free() + phy_device_register() # freed by phy_device_remove() + +But fixed_phy_unregister() only calls phy_device_remove(). +So the memory allocated in phy_device_create() is leaked. + +Second, when mdio_driver_register() fail in dsa_loop_init(), +it just returns and there is no cleanup for phydevs. + +Fix the problems by catching the error of mdio_driver_register() +in dsa_loop_init(), then calling both fixed_phy_unregister() and +phy_device_free() to release phydevs. +Also add a function for phydevs cleanup to avoid duplacate. + +Fixes: 98cd1552ea27 ("net: dsa: Mock-up driver") +Signed-off-by: Chen Zhongjin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/dsa_loop.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c +index e638e3eea911..e6e1054339b5 100644 +--- a/drivers/net/dsa/dsa_loop.c ++++ b/drivers/net/dsa/dsa_loop.c +@@ -376,6 +376,17 @@ static struct mdio_driver dsa_loop_drv = { + + #define NUM_FIXED_PHYS (DSA_LOOP_NUM_PORTS - 2) + ++static void dsa_loop_phydevs_unregister(void) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < NUM_FIXED_PHYS; i++) ++ if (!IS_ERR(phydevs[i])) { ++ fixed_phy_unregister(phydevs[i]); ++ phy_device_free(phydevs[i]); ++ } ++} ++ + static int __init dsa_loop_init(void) + { + struct fixed_phy_status status = { +@@ -383,23 +394,23 @@ static int __init dsa_loop_init(void) + .speed = SPEED_100, + .duplex = DUPLEX_FULL, + }; +- unsigned int i; ++ unsigned int i, ret; + + for (i = 0; i < NUM_FIXED_PHYS; i++) + phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL); + +- return mdio_driver_register(&dsa_loop_drv); ++ ret = mdio_driver_register(&dsa_loop_drv); ++ if (ret) ++ dsa_loop_phydevs_unregister(); ++ ++ return ret; + } + module_init(dsa_loop_init); + + static void __exit dsa_loop_exit(void) + { +- unsigned int i; +- + mdio_driver_unregister(&dsa_loop_drv); +- for (i = 0; i < NUM_FIXED_PHYS; i++) +- if (!IS_ERR(phydevs[i])) +- fixed_phy_unregister(phydevs[i]); ++ dsa_loop_phydevs_unregister(); + } + module_exit(dsa_loop_exit); + +-- +2.35.1 + diff --git a/queue-5.15/net-fec-fix-improper-use-of-netdev_tx_busy.patch b/queue-5.15/net-fec-fix-improper-use-of-netdev_tx_busy.patch new file mode 100644 index 00000000000..c14c586a734 --- /dev/null +++ b/queue-5.15/net-fec-fix-improper-use-of-netdev_tx_busy.patch @@ -0,0 +1,47 @@ +From 72edd8dc88d69ae7d67e8965ecb921d0f276c642 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 10:09:11 +0800 +Subject: net: fec: fix improper use of NETDEV_TX_BUSY + +From: Zhang Changzhong + +[ Upstream commit 06a4df5863f73af193a4ff7abf7cb04058584f06 ] + +The ndo_start_xmit() method must not free skb when returning +NETDEV_TX_BUSY, since caller is going to requeue freed skb. + +Fix it by returning NETDEV_TX_OK in case of dma_map_single() fails. + +Fixes: 79f339125ea3 ("net: fec: Add software TSO support") +Signed-off-by: Zhang Changzhong +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/fec_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 313ae8112067..a829ba128b9d 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -656,7 +656,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb, + dev_kfree_skb_any(skb); + if (net_ratelimit()) + netdev_err(ndev, "Tx DMA memory map failed\n"); +- return NETDEV_TX_BUSY; ++ return NETDEV_TX_OK; + } + + bdp->cbd_datlen = cpu_to_fec16(size); +@@ -718,7 +718,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq, + dev_kfree_skb_any(skb); + if (net_ratelimit()) + netdev_err(ndev, "Tx DMA memory map failed\n"); +- return NETDEV_TX_BUSY; ++ return NETDEV_TX_OK; + } + } + +-- +2.35.1 + diff --git a/queue-5.15/net-mdio-fix-undefined-behavior-in-bit-shift-for-__m.patch b/queue-5.15/net-mdio-fix-undefined-behavior-in-bit-shift-for-__m.patch new file mode 100644 index 00000000000..ad2b8989e2f --- /dev/null +++ b/queue-5.15/net-mdio-fix-undefined-behavior-in-bit-shift-for-__m.patch @@ -0,0 +1,54 @@ +From 838f06e11a3277b316461f1adc3e2e62a4fc1762 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 21:26:45 +0800 +Subject: net: mdio: fix undefined behavior in bit shift for __mdiobus_register + +From: Gaosheng Cui + +[ Upstream commit 40e4eb324c59e11fcb927aa46742d28aba6ecb8a ] + +Shifting signed 32-bit value by 31 bits is undefined, so changing +significant bit to unsigned. The UBSAN warning calltrace like below: + +UBSAN: shift-out-of-bounds in drivers/net/phy/mdio_bus.c:586:27 +left shift of 1 by 31 places cannot be represented in type 'int' +Call Trace: + + dump_stack_lvl+0x7d/0xa5 + dump_stack+0x15/0x1b + ubsan_epilogue+0xe/0x4e + __ubsan_handle_shift_out_of_bounds+0x1e7/0x20c + __mdiobus_register+0x49d/0x4e0 + fixed_mdio_bus_init+0xd8/0x12d + do_one_initcall+0x76/0x430 + kernel_init_freeable+0x3b3/0x422 + kernel_init+0x24/0x1e0 + ret_from_fork+0x1f/0x30 + + +Fixes: 4fd5f812c23c ("phylib: allow incremental scanning of an mii bus") +Signed-off-by: Gaosheng Cui +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20221031132645.168421-1-cuigaosheng1@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mdio_bus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c +index 2c0216fe58de..dd7739b5f791 100644 +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -577,7 +577,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) + } + + for (i = 0; i < PHY_MAX_ADDR; i++) { +- if ((bus->phy_mask & (1 << i)) == 0) { ++ if ((bus->phy_mask & BIT(i)) == 0) { + struct phy_device *phydev; + + phydev = mdiobus_scan(bus, i); +-- +2.35.1 + diff --git a/queue-5.15/net-neigh-fix-null-ptr-deref-in-neigh_table_clear.patch b/queue-5.15/net-neigh-fix-null-ptr-deref-in-neigh_table_clear.patch new file mode 100644 index 00000000000..bbffb6a6e12 --- /dev/null +++ b/queue-5.15/net-neigh-fix-null-ptr-deref-in-neigh_table_clear.patch @@ -0,0 +1,65 @@ +From 93c8b8295344baf8180075cd6ad4e227e50f3fa0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 20:15:52 +0800 +Subject: net, neigh: Fix null-ptr-deref in neigh_table_clear() + +From: Chen Zhongjin + +[ Upstream commit f8017317cb0b279b8ab98b0f3901a2e0ac880dad ] + +When IPv6 module gets initialized but hits an error in the middle, +kenel panic with: + +KASAN: null-ptr-deref in range [0x0000000000000598-0x000000000000059f] +CPU: 1 PID: 361 Comm: insmod +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) +RIP: 0010:__neigh_ifdown.isra.0+0x24b/0x370 +RSP: 0018:ffff888012677908 EFLAGS: 00000202 +... +Call Trace: + + neigh_table_clear+0x94/0x2d0 + ndisc_cleanup+0x27/0x40 [ipv6] + inet6_init+0x21c/0x2cb [ipv6] + do_one_initcall+0xd3/0x4d0 + do_init_module+0x1ae/0x670 +... +Kernel panic - not syncing: Fatal exception + +When ipv6 initialization fails, it will try to cleanup and calls: + +neigh_table_clear() + neigh_ifdown(tbl, NULL) + pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev == NULL)) + # dev_net(NULL) triggers null-ptr-deref. + +Fix it by passing NULL to pneigh_queue_purge() in neigh_ifdown() if dev +is NULL, to make kernel not panic immediately. + +Fixes: 66ba215cb513 ("neigh: fix possible DoS due to net iface start/stop loop") +Signed-off-by: Chen Zhongjin +Reviewed-by: Eric Dumazet +Reviewed-by: Denis V. Lunev +Link: https://lore.kernel.org/r/20221101121552.21890-1-chenzhongjin@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/neighbour.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index b3556c5c1c08..0e22ecb46977 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -372,7 +372,7 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev, + write_lock_bh(&tbl->lock); + neigh_flush_dev(tbl, dev, skip_perm); + pneigh_ifdown_and_unlock(tbl, dev); +- pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev)); ++ pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL); + if (skb_queue_empty_lockless(&tbl->proxy_queue)) + del_timer_sync(&tbl->proxy_timer); + return 0; +-- +2.35.1 + diff --git a/queue-5.15/net-sched-fix-use-after-free-in-red_enqueue.patch b/queue-5.15/net-sched-fix-use-after-free-in-red_enqueue.patch new file mode 100644 index 00000000000..dae562c7347 --- /dev/null +++ b/queue-5.15/net-sched-fix-use-after-free-in-red_enqueue.patch @@ -0,0 +1,49 @@ +From bfe6baa244475cd6976441b4d740f59f9c6e2c33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 18:05:00 +0300 +Subject: net: sched: Fix use after free in red_enqueue() + +From: Dan Carpenter + +[ Upstream commit 8bdc2acd420c6f3dd1f1c78750ec989f02a1e2b9 ] + +We can't use "skb" again after passing it to qdisc_enqueue(). This is +basically identical to commit 2f09707d0c97 ("sch_sfb: Also store skb +len before calling child enqueue"). + +Fixes: d7f4f332f082 ("sch_red: update backlog as well") +Signed-off-by: Dan Carpenter +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/sch_red.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c +index f1e013e3f04a..935d90874b1b 100644 +--- a/net/sched/sch_red.c ++++ b/net/sched/sch_red.c +@@ -72,6 +72,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch, + { + struct red_sched_data *q = qdisc_priv(sch); + struct Qdisc *child = q->qdisc; ++ unsigned int len; + int ret; + + q->vars.qavg = red_calc_qavg(&q->parms, +@@ -126,9 +127,10 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch, + break; + } + ++ len = qdisc_pkt_len(skb); + ret = qdisc_enqueue(skb, child, to_free); + if (likely(ret == NET_XMIT_SUCCESS)) { +- qdisc_qstats_backlog_inc(sch, skb); ++ sch->qstats.backlog += len; + sch->q.qlen++; + } else if (net_xmit_drop_count(ret)) { + q->stats.pdrop++; +-- +2.35.1 + diff --git a/queue-5.15/net-smc-fix-possible-leaked-pernet-namespace-in-smc_.patch b/queue-5.15/net-smc-fix-possible-leaked-pernet-namespace-in-smc_.patch new file mode 100644 index 00000000000..89bc2506bbe --- /dev/null +++ b/queue-5.15/net-smc-fix-possible-leaked-pernet-namespace-in-smc_.patch @@ -0,0 +1,69 @@ +From f52e47ef464030c85dfcf052fddfd8d354aaf278 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 17:37:22 +0800 +Subject: net/smc: Fix possible leaked pernet namespace in smc_init() + +From: Chen Zhongjin + +[ Upstream commit 62ff373da2534534c55debe6c724c7fe14adb97f ] + +In smc_init(), register_pernet_subsys(&smc_net_stat_ops) is called +without any error handling. +If it fails, registering of &smc_net_ops won't be reverted. +And if smc_nl_init() fails, &smc_net_stat_ops itself won't be reverted. + +This leaves wild ops in subsystem linkedlist and when another module +tries to call register_pernet_operations() it triggers page fault: + +BUG: unable to handle page fault for address: fffffbfff81b964c +RIP: 0010:register_pernet_operations+0x1b9/0x5f0 +Call Trace: + + register_pernet_subsys+0x29/0x40 + ebtables_init+0x58/0x1000 [ebtables] + ... + +Fixes: 194730a9beb5 ("net/smc: Make SMC statistics network namespace aware") +Signed-off-by: Chen Zhongjin +Reviewed-by: Tony Lu +Reviewed-by: Wenjia Zhang +Link: https://lore.kernel.org/r/20221101093722.127223-1-chenzhongjin@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/smc/af_smc.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 26f81e2e1dfb..d5ddf283ed8e 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -2744,14 +2744,14 @@ static int __init smc_init(void) + + rc = register_pernet_subsys(&smc_net_stat_ops); + if (rc) +- return rc; ++ goto out_pernet_subsys; + + smc_ism_init(); + smc_clc_init(); + + rc = smc_nl_init(); + if (rc) +- goto out_pernet_subsys; ++ goto out_pernet_subsys_stat; + + rc = smc_pnet_init(); + if (rc) +@@ -2829,6 +2829,8 @@ static int __init smc_init(void) + smc_pnet_exit(); + out_nl: + smc_nl_exit(); ++out_pernet_subsys_stat: ++ unregister_pernet_subsys(&smc_net_stat_ops); + out_pernet_subsys: + unregister_pernet_subsys(&smc_net_ops); + +-- +2.35.1 + diff --git a/queue-5.15/net-tun-fix-bugs-for-oversize-packet-when-napi-frags.patch b/queue-5.15/net-tun-fix-bugs-for-oversize-packet-when-napi-frags.patch new file mode 100644 index 00000000000..b1536cf698b --- /dev/null +++ b/queue-5.15/net-tun-fix-bugs-for-oversize-packet-when-napi-frags.patch @@ -0,0 +1,96 @@ +From 973ee9fabc65469f967be4d833040cf3a0f85da3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Oct 2022 17:41:01 +0800 +Subject: net: tun: fix bugs for oversize packet when napi frags enabled + +From: Ziyang Xuan + +[ Upstream commit 363a5328f4b0517e59572118ccfb7c626d81dca9 ] + +Recently, we got two syzkaller problems because of oversize packet +when napi frags enabled. + +One of the problems is because the first seg size of the iov_iter +from user space is very big, it is 2147479538 which is bigger than +the threshold value for bail out early in __alloc_pages(). And +skb->pfmemalloc is true, __kmalloc_reserve() would use pfmemalloc +reserves without __GFP_NOWARN flag. Thus we got a warning as following: + +======================================================== +WARNING: CPU: 1 PID: 17965 at mm/page_alloc.c:5295 __alloc_pages+0x1308/0x16c4 mm/page_alloc.c:5295 +... +Call trace: + __alloc_pages+0x1308/0x16c4 mm/page_alloc.c:5295 + __alloc_pages_node include/linux/gfp.h:550 [inline] + alloc_pages_node include/linux/gfp.h:564 [inline] + kmalloc_large_node+0x94/0x350 mm/slub.c:4038 + __kmalloc_node_track_caller+0x620/0x8e4 mm/slub.c:4545 + __kmalloc_reserve.constprop.0+0x1e4/0x2b0 net/core/skbuff.c:151 + pskb_expand_head+0x130/0x8b0 net/core/skbuff.c:1654 + __skb_grow include/linux/skbuff.h:2779 [inline] + tun_napi_alloc_frags+0x144/0x610 drivers/net/tun.c:1477 + tun_get_user+0x31c/0x2010 drivers/net/tun.c:1835 + tun_chr_write_iter+0x98/0x100 drivers/net/tun.c:2036 + +The other problem is because odd IPv6 packets without NEXTHDR_NONE +extension header and have big packet length, it is 2127925 which is +bigger than ETH_MAX_MTU(65535). After ipv6_gso_pull_exthdrs() in +ipv6_gro_receive(), network_header offset and transport_header offset +are all bigger than U16_MAX. That would trigger skb->network_header +and skb->transport_header overflow error, because they are all '__u16' +type. Eventually, it would affect the value for __skb_push(skb, value), +and make it be a big value. After __skb_push() in ipv6_gro_receive(), +skb->data would less than skb->head, an out of bounds memory bug occurred. +That would trigger the problem as following: + +================================================================== +BUG: KASAN: use-after-free in eth_type_trans+0x100/0x260 +... +Call trace: + dump_backtrace+0xd8/0x130 + show_stack+0x1c/0x50 + dump_stack_lvl+0x64/0x7c + print_address_description.constprop.0+0xbc/0x2e8 + print_report+0x100/0x1e4 + kasan_report+0x80/0x120 + __asan_load8+0x78/0xa0 + eth_type_trans+0x100/0x260 + napi_gro_frags+0x164/0x550 + tun_get_user+0xda4/0x1270 + tun_chr_write_iter+0x74/0x130 + do_iter_readv_writev+0x130/0x1ec + do_iter_write+0xbc/0x1e0 + vfs_writev+0x13c/0x26c + +To fix the problems, restrict the packet size less than +(ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN) which has considered reserved +skb space in napi_alloc_skb() because transport_header is an offset from +skb->head. Add len check in tun_napi_alloc_frags() simply. + +Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver") +Signed-off-by: Ziyang Xuan +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20221029094101.1653855-1-william.xuanziyang@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/tun.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index f92d6a12831f..9909f430d723 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1445,7 +1445,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, + int err; + int i; + +- if (it->nr_segs > MAX_SKB_FRAGS + 1) ++ if (it->nr_segs > MAX_SKB_FRAGS + 1 || ++ len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN)) + return ERR_PTR(-EMSGSIZE); + + local_bh_disable(); +-- +2.35.1 + diff --git a/queue-5.15/netfilter-ipset-enforce-documented-limit-to-prevent-.patch b/queue-5.15/netfilter-ipset-enforce-documented-limit-to-prevent-.patch new file mode 100644 index 00000000000..1cc5c34a955 --- /dev/null +++ b/queue-5.15/netfilter-ipset-enforce-documented-limit-to-prevent-.patch @@ -0,0 +1,102 @@ +From 9b361459ff671c9bef0f69688937fabb2032c2e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Nov 2022 10:40:47 +0100 +Subject: netfilter: ipset: enforce documented limit to prevent allocating huge + memory + +From: Jozsef Kadlecsik + +[ Upstream commit 510841da1fcc16f702440ab58ef0b4d82a9056b7 ] + +Daniel Xu reported that the hash:net,iface type of the ipset subsystem does +not limit adding the same network with different interfaces to a set, which +can lead to huge memory usage or allocation failure. + +The quick reproducer is + +$ ipset create ACL.IN.ALL_PERMIT hash:net,iface hashsize 1048576 timeout 0 +$ for i in $(seq 0 100); do /sbin/ipset add ACL.IN.ALL_PERMIT 0.0.0.0/0,kaf_$i timeout 0 -exist; done + +The backtrace when vmalloc fails: + + [Tue Oct 25 00:13:08 2022] ipset: vmalloc error: size 1073741848, exceeds total pages + <...> + [Tue Oct 25 00:13:08 2022] Call Trace: + [Tue Oct 25 00:13:08 2022] + [Tue Oct 25 00:13:08 2022] dump_stack_lvl+0x48/0x60 + [Tue Oct 25 00:13:08 2022] warn_alloc+0x155/0x180 + [Tue Oct 25 00:13:08 2022] __vmalloc_node_range+0x72a/0x760 + [Tue Oct 25 00:13:08 2022] ? hash_netiface4_add+0x7c0/0xb20 + [Tue Oct 25 00:13:08 2022] ? __kmalloc_large_node+0x4a/0x90 + [Tue Oct 25 00:13:08 2022] kvmalloc_node+0xa6/0xd0 + [Tue Oct 25 00:13:08 2022] ? hash_netiface4_resize+0x99/0x710 + <...> + +The fix is to enforce the limit documented in the ipset(8) manpage: + +> The internal restriction of the hash:net,iface set type is that the same +> network prefix cannot be stored with more than 64 different interfaces +> in a single set. + +Fixes: ccf0a4b7fc68 ("netfilter: ipset: Add bucketsize parameter to all hash types") +Reported-by: Daniel Xu +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipset/ip_set_hash_gen.h | 30 ++++++--------------------- + 1 file changed, 6 insertions(+), 24 deletions(-) + +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index 6e391308431d..3adc291d9ce1 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -42,31 +42,8 @@ + #define AHASH_MAX_SIZE (6 * AHASH_INIT_SIZE) + /* Max muber of elements in the array block when tuned */ + #define AHASH_MAX_TUNED 64 +- + #define AHASH_MAX(h) ((h)->bucketsize) + +-/* Max number of elements can be tuned */ +-#ifdef IP_SET_HASH_WITH_MULTI +-static u8 +-tune_bucketsize(u8 curr, u32 multi) +-{ +- u32 n; +- +- if (multi < curr) +- return curr; +- +- n = curr + AHASH_INIT_SIZE; +- /* Currently, at listing one hash bucket must fit into a message. +- * Therefore we have a hard limit here. +- */ +- return n > curr && n <= AHASH_MAX_TUNED ? n : curr; +-} +-#define TUNE_BUCKETSIZE(h, multi) \ +- ((h)->bucketsize = tune_bucketsize((h)->bucketsize, multi)) +-#else +-#define TUNE_BUCKETSIZE(h, multi) +-#endif +- + /* A hash bucket */ + struct hbucket { + struct rcu_head rcu; /* for call_rcu */ +@@ -936,7 +913,12 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + goto set_full; + /* Create a new slot */ + if (n->pos >= n->size) { +- TUNE_BUCKETSIZE(h, multi); ++#ifdef IP_SET_HASH_WITH_MULTI ++ if (h->bucketsize >= AHASH_MAX_TUNED) ++ goto set_full; ++ else if (h->bucketsize < multi) ++ h->bucketsize += AHASH_INIT_SIZE; ++#endif + if (n->size >= AHASH_MAX(h)) { + /* Trigger rehashing */ + mtype_data_next(&h->next, d); +-- +2.35.1 + diff --git a/queue-5.15/netfilter-nf_tables-netlink-notifier-might-race-to-r.patch b/queue-5.15/netfilter-nf_tables-netlink-notifier-might-race-to-r.patch new file mode 100644 index 00000000000..201bc51eba1 --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-netlink-notifier-might-race-to-r.patch @@ -0,0 +1,41 @@ +From 3ebfa42b2d81e40c1d3b9a17d60a4d6162ecf7b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 09:52:36 +0200 +Subject: netfilter: nf_tables: netlink notifier might race to release objects + +From: Pablo Neira Ayuso + +[ Upstream commit d4bc8271db21ea9f1c86a1ca4d64999f184d4aae ] + +commit release path is invoked via call_rcu and it runs lockless to +release the objects after rcu grace period. The netlink notifier handler +might win race to remove objects that the transaction context is still +referencing from the commit release path. + +Call rcu_barrier() to ensure pending rcu callbacks run to completion +if the list of transactions to be destroyed is not empty. + +Fixes: 6001a930ce03 ("netfilter: nftables: introduce table ownership") +Reported-by: syzbot+8f747f62763bc6c32916@syzkaller.appspotmail.com +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index f7a5b8414423..8cd11a7e5a3e 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -9824,6 +9824,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event, + nft_net = nft_pernet(net); + deleted = 0; + mutex_lock(&nft_net->commit_mutex); ++ if (!list_empty(&nf_tables_destroy_list)) ++ rcu_barrier(); + again: + list_for_each_entry(table, &nft_net->tables, list) { + if (nft_table_has_owner(table) && +-- +2.35.1 + diff --git a/queue-5.15/netfilter-nf_tables-release-flow-rule-object-from-co.patch b/queue-5.15/netfilter-nf_tables-release-flow-rule-object-from-co.patch new file mode 100644 index 00000000000..31da8779080 --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-release-flow-rule-object-from-co.patch @@ -0,0 +1,48 @@ +From b2f3f4c0646fde7b7c3a5aafbe77f70c0cd0d068 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 09:54:45 +0200 +Subject: netfilter: nf_tables: release flow rule object from commit path + +From: Pablo Neira Ayuso + +[ Upstream commit 26b5934ff4194e13196bedcba373cd4915071d0e ] + +No need to postpone this to the commit release path, since no packets +are walking over this object, this is accessed from control plane only. +This helped uncovered UAF triggered by races with the netlink notifier. + +Fixes: 9dd732e0bdf5 ("netfilter: nf_tables: memleak flow rule from commit path") +Reported-by: syzbot+8f747f62763bc6c32916@syzkaller.appspotmail.com +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 8cd11a7e5a3e..899f01c6c26c 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -8308,9 +8308,6 @@ static void nft_commit_release(struct nft_trans *trans) + nf_tables_chain_destroy(&trans->ctx); + break; + case NFT_MSG_DELRULE: +- if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) +- nft_flow_rule_destroy(nft_trans_flow_rule(trans)); +- + nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); + break; + case NFT_MSG_DELSET: +@@ -8767,6 +8764,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + nft_rule_expr_deactivate(&trans->ctx, + nft_trans_rule(trans), + NFT_TRANS_COMMIT); ++ ++ if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) ++ nft_flow_rule_destroy(nft_trans_flow_rule(trans)); + break; + case NFT_MSG_NEWSET: + nft_clear(net, nft_trans_set(trans)); +-- +2.35.1 + diff --git a/queue-5.15/nfc-fdp-fix-potential-memory-leak-in-fdp_nci_send.patch b/queue-5.15/nfc-fdp-fix-potential-memory-leak-in-fdp_nci_send.patch new file mode 100644 index 00000000000..eca152943f5 --- /dev/null +++ b/queue-5.15/nfc-fdp-fix-potential-memory-leak-in-fdp_nci_send.patch @@ -0,0 +1,50 @@ +From d250cf58a41eea0e645f937bcd4c7680daab2b2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 22:03:29 +0800 +Subject: nfc: fdp: Fix potential memory leak in fdp_nci_send() + +From: Shang XiaoJing + +[ Upstream commit 8e4aae6b8ca76afb1fb64dcb24be44ba814e7f8a ] + +fdp_nci_send() will call fdp_nci_i2c_write that will not free skb in +the function. As a result, when fdp_nci_i2c_write() finished, the skb +will memleak. fdp_nci_send() should free skb after fdp_nci_i2c_write() +finished. + +Fixes: a06347c04c13 ("NFC: Add Intel Fields Peak NFC solution driver") +Signed-off-by: Shang XiaoJing +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/fdp/fdp.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c +index c6b3334f24c9..f12f903a9dd1 100644 +--- a/drivers/nfc/fdp/fdp.c ++++ b/drivers/nfc/fdp/fdp.c +@@ -249,11 +249,19 @@ static int fdp_nci_close(struct nci_dev *ndev) + static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) + { + struct fdp_nci_info *info = nci_get_drvdata(ndev); ++ int ret; + + if (atomic_dec_and_test(&info->data_pkt_counter)) + info->data_pkt_counter_cb(ndev); + +- return info->phy_ops->write(info->phy, skb); ++ ret = info->phy_ops->write(info->phy, skb); ++ if (ret < 0) { ++ kfree_skb(skb); ++ return ret; ++ } ++ ++ consume_skb(skb); ++ return 0; + } + + static int fdp_nci_request_firmware(struct nci_dev *ndev) +-- +2.35.1 + diff --git a/queue-5.15/nfc-nfcmrvl-fix-potential-memory-leak-in-nfcmrvl_i2c.patch b/queue-5.15/nfc-nfcmrvl-fix-potential-memory-leak-in-nfcmrvl_i2c.patch new file mode 100644 index 00000000000..552f37a036f --- /dev/null +++ b/queue-5.15/nfc-nfcmrvl-fix-potential-memory-leak-in-nfcmrvl_i2c.patch @@ -0,0 +1,47 @@ +From 3a1182b4fa0395b81a66fec40b63e70ccf070ba3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 22:03:32 +0800 +Subject: nfc: nfcmrvl: Fix potential memory leak in nfcmrvl_i2c_nci_send() + +From: Shang XiaoJing + +[ Upstream commit 93d904a734a74c54d945a9884b4962977f1176cd ] + +nfcmrvl_i2c_nci_send() will be called by nfcmrvl_nci_send(), and skb +should be freed in nfcmrvl_i2c_nci_send(). However, nfcmrvl_nci_send() +will only free skb when i2c_master_send() return >=0, which means skb +will memleak when i2c_master_send() failed. Free skb no matter whether +i2c_master_send() succeeds. + +Fixes: b5b3e23e4cac ("NFC: nfcmrvl: add i2c driver") +Signed-off-by: Shang XiaoJing +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/nfcmrvl/i2c.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c +index 01329b91d59d..a902720cd849 100644 +--- a/drivers/nfc/nfcmrvl/i2c.c ++++ b/drivers/nfc/nfcmrvl/i2c.c +@@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv, + ret = -EREMOTEIO; + } else + ret = 0; ++ } ++ ++ if (ret) { + kfree_skb(skb); ++ return ret; + } + +- return ret; ++ consume_skb(skb); ++ return 0; + } + + static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv, +-- +2.35.1 + diff --git a/queue-5.15/nfc-nxp-nci-fix-potential-memory-leak-in-nxp_nci_sen.patch b/queue-5.15/nfc-nxp-nci-fix-potential-memory-leak-in-nxp_nci_sen.patch new file mode 100644 index 00000000000..855675e780a --- /dev/null +++ b/queue-5.15/nfc-nxp-nci-fix-potential-memory-leak-in-nxp_nci_sen.patch @@ -0,0 +1,46 @@ +From 91fe19acf619c523b4af938869042a059fc41305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 22:03:30 +0800 +Subject: nfc: nxp-nci: Fix potential memory leak in nxp_nci_send() + +From: Shang XiaoJing + +[ Upstream commit 7bf1ed6aff0f70434bd0cdd45495e83f1dffb551 ] + +nxp_nci_send() will call nxp_nci_i2c_write(), and only free skb when +nxp_nci_i2c_write() failed. However, even if the nxp_nci_i2c_write() +run succeeds, the skb will not be freed in nxp_nci_i2c_write(). As the +result, the skb will memleak. nxp_nci_send() should also free the skb +when nxp_nci_i2c_write() succeeds. + +Fixes: dece45855a8b ("NFC: nxp-nci: Add support for NXP NCI chips") +Signed-off-by: Shang XiaoJing +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/nxp-nci/core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c +index 518e2afb43a8..13c433eb694d 100644 +--- a/drivers/nfc/nxp-nci/core.c ++++ b/drivers/nfc/nxp-nci/core.c +@@ -77,10 +77,13 @@ static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) + return -EINVAL; + + r = info->phy_ops->write(info->phy_id, skb); +- if (r < 0) ++ if (r < 0) { + kfree_skb(skb); ++ return r; ++ } + +- return r; ++ consume_skb(skb); ++ return 0; + } + + static const struct nci_ops nxp_nci_ops = { +-- +2.35.1 + diff --git a/queue-5.15/nfc-s3fwrn5-fix-potential-memory-leak-in-s3fwrn5_nci.patch b/queue-5.15/nfc-s3fwrn5-fix-potential-memory-leak-in-s3fwrn5_nci.patch new file mode 100644 index 00000000000..583d8fb8873 --- /dev/null +++ b/queue-5.15/nfc-s3fwrn5-fix-potential-memory-leak-in-s3fwrn5_nci.patch @@ -0,0 +1,48 @@ +From 4f3ba9aab6b95e7a05ee7eef0dcce86046f043c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Oct 2022 22:03:31 +0800 +Subject: nfc: s3fwrn5: Fix potential memory leak in s3fwrn5_nci_send() + +From: Shang XiaoJing + +[ Upstream commit 3a146b7e3099dc7cf3114f627d9b79291e2d2203 ] + +s3fwrn5_nci_send() will call s3fwrn5_i2c_write() or s3fwrn82_uart_write(), +and free the skb if write() failed. However, even if the write() run +succeeds, the skb will not be freed in write(). As the result, the skb +will memleak. s3fwrn5_nci_send() should also free the skb when write() +succeeds. + +Fixes: c04c674fadeb ("nfc: s3fwrn5: Add driver for Samsung S3FWRN5 NFC Chip") +Signed-off-by: Shang XiaoJing +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/s3fwrn5/core.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/nfc/s3fwrn5/core.c b/drivers/nfc/s3fwrn5/core.c +index 1c412007fabb..0270e05b68df 100644 +--- a/drivers/nfc/s3fwrn5/core.c ++++ b/drivers/nfc/s3fwrn5/core.c +@@ -110,11 +110,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct sk_buff *skb) + } + + ret = s3fwrn5_write(info, skb); +- if (ret < 0) ++ if (ret < 0) { + kfree_skb(skb); ++ mutex_unlock(&info->mutex); ++ return ret; ++ } + ++ consume_skb(skb); + mutex_unlock(&info->mutex); +- return ret; ++ return 0; + } + + static int s3fwrn5_nci_post_setup(struct nci_dev *ndev) +-- +2.35.1 + diff --git a/queue-5.15/nfs4-fix-kmemleak-when-allocate-slot-failed.patch b/queue-5.15/nfs4-fix-kmemleak-when-allocate-slot-failed.patch new file mode 100644 index 00000000000..4063ab362cf --- /dev/null +++ b/queue-5.15/nfs4-fix-kmemleak-when-allocate-slot-failed.patch @@ -0,0 +1,54 @@ +From aaae64e8577bf7002007a19fdd78cf5f67405a3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 11:20:54 +0800 +Subject: nfs4: Fix kmemleak when allocate slot failed + +From: Zhang Xiaoxu + +[ Upstream commit 7e8436728e22181c3f12a5dbabd35ed3a8b8c593 ] + +If one of the slot allocate failed, should cleanup all the other +allocated slots, otherwise, the allocated slots will leak: + + unreferenced object 0xffff8881115aa100 (size 64): + comm ""mount.nfs"", pid 679, jiffies 4294744957 (age 115.037s) + hex dump (first 32 bytes): + 00 cc 19 73 81 88 ff ff 00 a0 5a 11 81 88 ff ff ...s......Z..... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [<000000007a4c434a>] nfs4_find_or_create_slot+0x8e/0x130 + [<000000005472a39c>] nfs4_realloc_slot_table+0x23f/0x270 + [<00000000cd8ca0eb>] nfs40_init_client+0x4a/0x90 + [<00000000128486db>] nfs4_init_client+0xce/0x270 + [<000000008d2cacad>] nfs4_set_client+0x1a2/0x2b0 + [<000000000e593b52>] nfs4_create_server+0x300/0x5f0 + [<00000000e4425dd2>] nfs4_try_get_tree+0x65/0x110 + [<00000000d3a6176f>] vfs_get_tree+0x41/0xf0 + [<0000000016b5ad4c>] path_mount+0x9b3/0xdd0 + [<00000000494cae71>] __x64_sys_mount+0x190/0x1d0 + [<000000005d56bdec>] do_syscall_64+0x35/0x80 + [<00000000687c9ae4>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +Fixes: abf79bb341bf ("NFS: Add a slot table to struct nfs_client for NFSv4.0 transport blocking") +Signed-off-by: Zhang Xiaoxu +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4client.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c +index ed06b68b2b4e..1bf7a72ebda6 100644 +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -346,6 +346,7 @@ int nfs40_init_client(struct nfs_client *clp) + ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE, + "NFSv4.0 transport Slot table"); + if (ret) { ++ nfs4_shutdown_slot_table(tbl); + kfree(tbl); + return ret; + } +-- +2.35.1 + diff --git a/queue-5.15/nfsv4-fix-a-potential-state-reclaim-deadlock.patch b/queue-5.15/nfsv4-fix-a-potential-state-reclaim-deadlock.patch new file mode 100644 index 00000000000..2cdfc295546 --- /dev/null +++ b/queue-5.15/nfsv4-fix-a-potential-state-reclaim-deadlock.patch @@ -0,0 +1,83 @@ +From 39ad3ac153d72766aa64f573b4b77c9b8eb5b2ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Oct 2022 14:44:31 -0400 +Subject: NFSv4: Fix a potential state reclaim deadlock + +From: Trond Myklebust + +[ Upstream commit 1ba04394e028ea8b45d92685cc0d6ab582cf7647 ] + +If the server reboots while we are engaged in a delegation return, and +there is a pNFS layout with return-on-close set, then the current code +can end up deadlocking in pnfs_roc() when nfs_inode_set_delegation() +tries to return the old delegation. +Now that delegreturn actually uses its own copy of the stateid, it +should be safe to just always update the delegation stateid in place. + +Fixes: 078000d02d57 ("pNFS: We want return-on-close to complete when evicting the inode") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/delegation.c | 36 +++++++++++++++++------------------- + 1 file changed, 17 insertions(+), 19 deletions(-) + +diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c +index 7c9eb679dbdb..6a3ba306c321 100644 +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -228,8 +228,7 @@ static int nfs_delegation_claim_opens(struct inode *inode, + * + */ + void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, +- fmode_t type, +- const nfs4_stateid *stateid, ++ fmode_t type, const nfs4_stateid *stateid, + unsigned long pagemod_limit) + { + struct nfs_delegation *delegation; +@@ -239,25 +238,24 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, + delegation = rcu_dereference(NFS_I(inode)->delegation); + if (delegation != NULL) { + spin_lock(&delegation->lock); +- if (nfs4_is_valid_delegation(delegation, 0)) { +- nfs4_stateid_copy(&delegation->stateid, stateid); +- delegation->type = type; +- delegation->pagemod_limit = pagemod_limit; +- oldcred = delegation->cred; +- delegation->cred = get_cred(cred); +- clear_bit(NFS_DELEGATION_NEED_RECLAIM, +- &delegation->flags); +- spin_unlock(&delegation->lock); +- rcu_read_unlock(); +- put_cred(oldcred); +- trace_nfs4_reclaim_delegation(inode, type); +- return; +- } +- /* We appear to have raced with a delegation return. */ ++ nfs4_stateid_copy(&delegation->stateid, stateid); ++ delegation->type = type; ++ delegation->pagemod_limit = pagemod_limit; ++ oldcred = delegation->cred; ++ delegation->cred = get_cred(cred); ++ clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags); ++ if (test_and_clear_bit(NFS_DELEGATION_REVOKED, ++ &delegation->flags)) ++ atomic_long_inc(&nfs_active_delegations); + spin_unlock(&delegation->lock); ++ rcu_read_unlock(); ++ put_cred(oldcred); ++ trace_nfs4_reclaim_delegation(inode, type); ++ } else { ++ rcu_read_unlock(); ++ nfs_inode_set_delegation(inode, cred, type, stateid, ++ pagemod_limit); + } +- rcu_read_unlock(); +- nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit); + } + + static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync) +-- +2.35.1 + diff --git a/queue-5.15/nfsv4.1-handle-reclaim_complete-trunking-errors.patch b/queue-5.15/nfsv4.1-handle-reclaim_complete-trunking-errors.patch new file mode 100644 index 00000000000..a7430d36a7a --- /dev/null +++ b/queue-5.15/nfsv4.1-handle-reclaim_complete-trunking-errors.patch @@ -0,0 +1,35 @@ +From 87b22c90898783c1750041ea6b34b06a3df34f80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Oct 2022 14:44:32 -0400 +Subject: NFSv4.1: Handle RECLAIM_COMPLETE trunking errors + +From: Trond Myklebust + +[ Upstream commit 5d917cba3201e5c25059df96c29252fd99c4f6a7 ] + +If RECLAIM_COMPLETE sets the NFS4CLNT_BIND_CONN_TO_SESSION flag, then we +need to loop back in order to handle it. + +Fixes: 0048fdd06614 ("NFSv4.1: RECLAIM_COMPLETE must handle NFS4ERR_CONN_NOT_BOUND_TO_SESSION") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4state.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 32ee79a99246..2795aa1c3cf4 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -2651,6 +2651,7 @@ static void nfs4_state_manager(struct nfs_client *clp) + if (status < 0) + goto out_error; + nfs4_state_end_reclaim_reboot(clp); ++ continue; + } + + /* Detect expired delegations... */ +-- +2.35.1 + diff --git a/queue-5.15/nfsv4.1-we-must-always-send-reclaim_complete-after-a.patch b/queue-5.15/nfsv4.1-we-must-always-send-reclaim_complete-after-a.patch new file mode 100644 index 00000000000..06f67798fe8 --- /dev/null +++ b/queue-5.15/nfsv4.1-we-must-always-send-reclaim_complete-after-a.patch @@ -0,0 +1,36 @@ +From ac32138ae9876aa23fd9a0e25afc57689ccf944d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Oct 2022 14:44:33 -0400 +Subject: NFSv4.1: We must always send RECLAIM_COMPLETE after a reboot + +From: Trond Myklebust + +[ Upstream commit e59679f2b7e522ecad99974e5636291ffd47c184 ] + +Currently, we are only guaranteed to send RECLAIM_COMPLETE if we have +open state to recover. Fix the client to always send RECLAIM_COMPLETE +after setting up the lease. + +Fixes: fce5c838e133 ("nfs41: RECLAIM_COMPLETE functionality") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4state.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 2795aa1c3cf4..ecac56be6cb7 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1778,6 +1778,7 @@ static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, + + static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp) + { ++ set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state); + /* Mark all delegations for reclaim */ + nfs_delegation_mark_reclaim(clp); + nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot); +-- +2.35.1 + diff --git a/queue-5.15/nfsv4.2-fixup-clone-dest-file-size-for-zero-length-c.patch b/queue-5.15/nfsv4.2-fixup-clone-dest-file-size-for-zero-length-c.patch new file mode 100644 index 00000000000..1e1e0fc9cc8 --- /dev/null +++ b/queue-5.15/nfsv4.2-fixup-clone-dest-file-size-for-zero-length-c.patch @@ -0,0 +1,41 @@ +From abfc5d3af01cc71fe34709ff2af664a0a1b83773 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Oct 2022 11:58:01 -0400 +Subject: NFSv4.2: Fixup CLONE dest file size for zero-length count + +From: Benjamin Coddington + +[ Upstream commit 038efb6348ce96228f6828354cb809c22a661681 ] + +When holding a delegation, the NFS client optimizes away setting the +attributes of a file from the GETATTR in the compound after CLONE, and for +a zero-length CLONE we will end up setting the inode's size to zero in +nfs42_copy_dest_done(). Handle this case by computing the resulting count +from the server's reported size after CLONE's GETATTR. + +Suggested-by: Trond Myklebust +Signed-off-by: Benjamin Coddington +Fixes: 94d202d5ca39 ("NFSv42: Copy offload should update the file size when appropriate") +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs42proc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index 93f4d8257525..da94bf2afd07 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -1077,6 +1077,9 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, + status = nfs4_call_sync(server->client, server, msg, + &args.seq_args, &res.seq_res, 0); + if (status == 0) { ++ /* a zero-length count means clone to EOF in src */ ++ if (count == 0 && res.dst_fattr->valid & NFS_ATTR_FATTR_SIZE) ++ count = nfs_size_to_loff_t(res.dst_fattr->size) - dst_offset; + nfs42_copy_dest_done(dst_inode, dst_offset, count); + status = nfs_post_op_update_inode(dst_inode, res.dst_fattr); + } +-- +2.35.1 + diff --git a/queue-5.15/rdma-cma-use-output-interface-for-net_dev-check.patch b/queue-5.15/rdma-cma-use-output-interface-for-net_dev-check.patch new file mode 100644 index 00000000000..b7a3dd4e237 --- /dev/null +++ b/queue-5.15/rdma-cma-use-output-interface-for-net_dev-check.patch @@ -0,0 +1,49 @@ +From baf6e0976b7592d1e800f83f39d1026f31f4faec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Oct 2022 16:15:42 +0200 +Subject: RDMA/cma: Use output interface for net_dev check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Håkon Bugge + +[ Upstream commit eb83f502adb036cd56c27e13b9ca3b2aabfa790b ] + +Commit 27cfde795a96 ("RDMA/cma: Fix arguments order in net device +validation") swapped the src and dst addresses in the call to +validate_net_dev(). + +As a consequence, the test in validate_ipv4_net_dev() to see if the +net_dev is the right one, is incorrect for port 1 <-> 2 communication when +the ports are on the same sub-net. This is fixed by denoting the +flowi4_oif as the device instead of the incoming one. + +The bug has not been observed using IPv6 addresses. + +Fixes: 27cfde795a96 ("RDMA/cma: Fix arguments order in net device validation") +Signed-off-by: Håkon Bugge +Link: https://lore.kernel.org/r/20221012141542.16925-1-haakon.bugge@oracle.com +Reviewed-by: Leon Romanovsky +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/cma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index 0da66dd40d6a..fd192104fd8d 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -1433,7 +1433,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev, + return false; + + memset(&fl4, 0, sizeof(fl4)); +- fl4.flowi4_iif = net_dev->ifindex; ++ fl4.flowi4_oif = net_dev->ifindex; + fl4.daddr = daddr; + fl4.saddr = saddr; + +-- +2.35.1 + diff --git a/queue-5.15/rdma-core-fix-null-ptr-deref-in-ib_core_cleanup.patch b/queue-5.15/rdma-core-fix-null-ptr-deref-in-ib_core_cleanup.patch new file mode 100644 index 00000000000..e91be512d63 --- /dev/null +++ b/queue-5.15/rdma-core-fix-null-ptr-deref-in-ib_core_cleanup.patch @@ -0,0 +1,89 @@ +From 5d2ab25def9a30ca40669f8a097a8d58957b0746 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Oct 2022 10:41:46 +0800 +Subject: RDMA/core: Fix null-ptr-deref in ib_core_cleanup() + +From: Chen Zhongjin + +[ Upstream commit 07c0d131cc0fe1f3981a42958fc52d573d303d89 ] + +KASAN reported a null-ptr-deref error: + + KASAN: null-ptr-deref in range [0x0000000000000118-0x000000000000011f] + CPU: 1 PID: 379 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) + RIP: 0010:destroy_workqueue+0x2f/0x740 + RSP: 0018:ffff888016137df8 EFLAGS: 00000202 + ... + Call Trace: + ib_core_cleanup+0xa/0xa1 [ib_core] + __do_sys_delete_module.constprop.0+0x34f/0x5b0 + do_syscall_64+0x3a/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + RIP: 0033:0x7fa1a0d221b7 + ... + +It is because the fail of roce_gid_mgmt_init() is ignored: + + ib_core_init() + roce_gid_mgmt_init() + gid_cache_wq = alloc_ordered_workqueue # fail + ... + ib_core_cleanup() + roce_gid_mgmt_cleanup() + destroy_workqueue(gid_cache_wq) + # destroy an unallocated wq + +Fix this by catching the fail of roce_gid_mgmt_init() in ib_core_init(). + +Fixes: 03db3a2d81e6 ("IB/core: Add RoCE GID table management") +Signed-off-by: Chen Zhongjin +Link: https://lore.kernel.org/r/20221025024146.109137-1-chenzhongjin@huawei.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/device.c | 10 +++++++++- + drivers/infiniband/core/nldev.c | 2 +- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c +index 6ab46648af90..1519379b116e 100644 +--- a/drivers/infiniband/core/device.c ++++ b/drivers/infiniband/core/device.c +@@ -2814,10 +2814,18 @@ static int __init ib_core_init(void) + + nldev_init(); + rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table); +- roce_gid_mgmt_init(); ++ ret = roce_gid_mgmt_init(); ++ if (ret) { ++ pr_warn("Couldn't init RoCE GID management\n"); ++ goto err_parent; ++ } + + return 0; + ++err_parent: ++ rdma_nl_unregister(RDMA_NL_LS); ++ nldev_exit(); ++ unregister_pernet_device(&rdma_dev_net_ops); + err_compat: + unregister_blocking_lsm_notifier(&ibdev_lsm_nb); + err_sa: +diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c +index e9b4b2cccaa0..cd89e59cbe33 100644 +--- a/drivers/infiniband/core/nldev.c ++++ b/drivers/infiniband/core/nldev.c +@@ -2349,7 +2349,7 @@ void __init nldev_init(void) + rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table); + } + +-void __exit nldev_exit(void) ++void nldev_exit(void) + { + rdma_nl_unregister(RDMA_NL_NLDEV); + } +-- +2.35.1 + diff --git a/queue-5.15/rdma-hns-disable-local-invalidate-operation.patch b/queue-5.15/rdma-hns-disable-local-invalidate-operation.patch new file mode 100644 index 00000000000..26a4d7db1a9 --- /dev/null +++ b/queue-5.15/rdma-hns-disable-local-invalidate-operation.patch @@ -0,0 +1,152 @@ +From ec332eb0edc5c4e7baa53775570cc6ce0df5a9ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Oct 2022 16:38:13 +0800 +Subject: RDMA/hns: Disable local invalidate operation + +From: Yangyang Li + +[ Upstream commit 9e272ed69ad6f6952fafd0599d6993575512408e ] + +When function reset and local invalidate are mixed, HNS RoCEE may hang. +Before introducing the cause of the problem, two hardware internal +concepts need to be introduced: + + 1. Execution queue: The queue of hardware execution instructions, + function reset and local invalidate are queued for execution in this + queue. + + 2.Local queue: A queue that stores local operation instructions. The + instructions in the local queue will be sent to the execution queue + for execution. The instructions in the local queue will not be removed + until the execution is completed. + +The reason for the problem is as follows: + + 1. There is a function reset instruction in the execution queue, which + is currently being executed. A necessary condition for the successful + execution of function reset is: the hardware pipeline needs to empty + the instructions that were not completed before; + + 2. A local invalidate instruction at the head of the local queue is + sent to the execution queue. Now there are two instructions in the + execution queue, the first is the function reset instruction, and the + second is the local invalidate instruction, which will be executed in + se quence; + + 3. The user has issued many local invalidate operations, causing the + local queue to be filled up. + + 4. The user still has a new local operation command and is queuing to + enter the local queue. But the local queue is full and cannot receive + new instructions, this instruction is temporarily stored at the + hardware pipeline. + + 5. The function reset has been waiting for the instruction before the + hardware pipeline stage is drained. The hardware pipeline stage also + caches a local invalidate instruction, so the function reset cannot be + completed, and the instructions after it cannot be executed. + +These factors together cause the execution logic deadlock of the hardware, +and the consequence is that RoCEE will not have any response. Considering +that the local operation command may potentially cause RoCEE to hang, this +feature is no longer supported. + +Fixes: e93df0108579 ("RDMA/hns: Support local invalidate for hip08 in kernel space") +Signed-off-by: Yangyang Li +Signed-off-by: Wenpeng Liang +Signed-off-by: Haoyue Xu +Link: https://lore.kernel.org/r/20221024083814.1089722-2-xuhaoyue1@hisilicon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 11 ----------- + drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 -- + 2 files changed, 13 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 3b26c74efee0..1421896abaf0 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -82,7 +82,6 @@ static const u32 hns_roce_op_code[] = { + HR_OPC_MAP(ATOMIC_CMP_AND_SWP, ATOM_CMP_AND_SWAP), + HR_OPC_MAP(ATOMIC_FETCH_AND_ADD, ATOM_FETCH_AND_ADD), + HR_OPC_MAP(SEND_WITH_INV, SEND_WITH_INV), +- HR_OPC_MAP(LOCAL_INV, LOCAL_INV), + HR_OPC_MAP(MASKED_ATOMIC_CMP_AND_SWP, ATOM_MSK_CMP_AND_SWAP), + HR_OPC_MAP(MASKED_ATOMIC_FETCH_AND_ADD, ATOM_MSK_FETCH_AND_ADD), + HR_OPC_MAP(REG_MR, FAST_REG_PMR), +@@ -524,9 +523,6 @@ static int set_rc_opcode(struct hns_roce_dev *hr_dev, + else + ret = -EOPNOTSUPP; + break; +- case IB_WR_LOCAL_INV: +- hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_SO); +- fallthrough; + case IB_WR_SEND_WITH_INV: + rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey); + break; +@@ -3058,7 +3054,6 @@ static int hns_roce_v2_write_mtpt(struct hns_roce_dev *hr_dev, + + hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_VALID); + hr_reg_write(mpt_entry, MPT_PD, mr->pd); +- hr_reg_enable(mpt_entry, MPT_L_INV_EN); + + hr_reg_write_bool(mpt_entry, MPT_BIND_EN, + mr->access & IB_ACCESS_MW_BIND); +@@ -3151,7 +3146,6 @@ static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev, + + hr_reg_enable(mpt_entry, MPT_RA_EN); + hr_reg_enable(mpt_entry, MPT_R_INV_EN); +- hr_reg_enable(mpt_entry, MPT_L_INV_EN); + + hr_reg_enable(mpt_entry, MPT_FRE); + hr_reg_clear(mpt_entry, MPT_MR_MW); +@@ -3183,7 +3177,6 @@ static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw) + hr_reg_write(mpt_entry, MPT_PD, mw->pdn); + + hr_reg_enable(mpt_entry, MPT_R_INV_EN); +- hr_reg_enable(mpt_entry, MPT_L_INV_EN); + hr_reg_enable(mpt_entry, MPT_LW_EN); + + hr_reg_enable(mpt_entry, MPT_MR_MW); +@@ -3540,7 +3533,6 @@ static const u32 wc_send_op_map[] = { + HR_WC_OP_MAP(RDMA_READ, RDMA_READ), + HR_WC_OP_MAP(RDMA_WRITE, RDMA_WRITE), + HR_WC_OP_MAP(RDMA_WRITE_WITH_IMM, RDMA_WRITE), +- HR_WC_OP_MAP(LOCAL_INV, LOCAL_INV), + HR_WC_OP_MAP(ATOM_CMP_AND_SWAP, COMP_SWAP), + HR_WC_OP_MAP(ATOM_FETCH_AND_ADD, FETCH_ADD), + HR_WC_OP_MAP(ATOM_MSK_CMP_AND_SWAP, MASKED_COMP_SWAP), +@@ -3590,9 +3582,6 @@ static void fill_send_wc(struct ib_wc *wc, struct hns_roce_v2_cqe *cqe) + case HNS_ROCE_V2_WQE_OP_RDMA_WRITE_WITH_IMM: + wc->wc_flags |= IB_WC_WITH_IMM; + break; +- case HNS_ROCE_V2_WQE_OP_LOCAL_INV: +- wc->wc_flags |= IB_WC_WITH_INVALIDATE; +- break; + case HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP: + case HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD: + case HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP: +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +index ddb99a7ff135..2f4a0019a716 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +@@ -184,7 +184,6 @@ enum { + HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP = 0x8, + HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD = 0x9, + HNS_ROCE_V2_WQE_OP_FAST_REG_PMR = 0xa, +- HNS_ROCE_V2_WQE_OP_LOCAL_INV = 0xb, + HNS_ROCE_V2_WQE_OP_BIND_MW = 0xc, + HNS_ROCE_V2_WQE_OP_MASK = 0x1f, + }; +@@ -944,7 +943,6 @@ struct hns_roce_v2_rc_send_wqe { + #define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7) + #define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8) + #define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9) +-#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10) + #define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11) + #define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12) + #define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15) +-- +2.35.1 + diff --git a/queue-5.15/rdma-hns-remove-magic-number.patch b/queue-5.15/rdma-hns-remove-magic-number.patch new file mode 100644 index 00000000000..8394766182d --- /dev/null +++ b/queue-5.15/rdma-hns-remove-magic-number.patch @@ -0,0 +1,46 @@ +From 0dd745b7057524badd0ef6431a5f660d73bca829 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Nov 2021 22:02:08 +0800 +Subject: RDMA/hns: Remove magic number + +From: Xinhao Liu + +[ Upstream commit 9c3631d17054a8766dbdc1abf8d29306260e7c7f ] + +Don't use unintelligible constants. + +Link: https://lore.kernel.org/r/20211119140208.40416-10-liangwenpeng@huawei.com +Signed-off-by: Xinhao Liu +Signed-off-by: Wenpeng Liang +Signed-off-by: Jason Gunthorpe +Stable-dep-of: 9e272ed69ad6 ("RDMA/hns: Disable local invalidate operation") +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 1dbad159f379..1782626b54db 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -678,6 +678,7 @@ static void hns_roce_write512(struct hns_roce_dev *hr_dev, u64 *val, + static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, + void *wqe) + { ++#define HNS_ROCE_SL_SHIFT 2 + struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe; + + /* All kinds of DirectWQE have the same header field layout */ +@@ -685,7 +686,8 @@ static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, + roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_DB_SL_L_M, + V2_RC_SEND_WQE_BYTE_4_DB_SL_L_S, qp->sl); + roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_DB_SL_H_M, +- V2_RC_SEND_WQE_BYTE_4_DB_SL_H_S, qp->sl >> 2); ++ V2_RC_SEND_WQE_BYTE_4_DB_SL_H_S, ++ qp->sl >> HNS_ROCE_SL_SHIFT); + roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_M, + V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_S, qp->sq.head); + +-- +2.35.1 + diff --git a/queue-5.15/rdma-hns-use-hr_reg_xxx-instead-of-remaining-roce_se.patch b/queue-5.15/rdma-hns-use-hr_reg_xxx-instead-of-remaining-roce_se.patch new file mode 100644 index 00000000000..d740c98d61c --- /dev/null +++ b/queue-5.15/rdma-hns-use-hr_reg_xxx-instead-of-remaining-roce_se.patch @@ -0,0 +1,736 @@ +From b65b6472e9af1f05498bdcf2b177f78b2c82a322 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 May 2022 16:00:11 +0800 +Subject: RDMA/hns: Use hr_reg_xxx() instead of remaining roce_set_xxx() + +From: Wenpeng Liang + +[ Upstream commit 82600b2d3cd57428bdb03c66ae67708d3c8f7281 ] + +To reduce the code size and make the code clearer, replace all +roce_set_xxx() with hr_reg_xxx() to write the data fields. + +Link: https://lore.kernel.org/r/20220512080012.38728-2-liangwenpeng@huawei.com +Signed-off-by: Wenpeng Liang +Signed-off-by: Jason Gunthorpe +Stable-dep-of: 9e272ed69ad6 ("RDMA/hns: Disable local invalidate operation") +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 261 ++++++++------------- + drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 166 +++++-------- + 2 files changed, 157 insertions(+), 270 deletions(-) + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 1782626b54db..3b26c74efee0 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -149,8 +149,7 @@ static void set_atomic_seg(const struct ib_send_wr *wr, + aseg->cmp_data = 0; + } + +- roce_set_field(rc_sq_wqe->byte_16, V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SGE_NUM, valid_num_sge); + } + + static int fill_ext_sge_inl_data(struct hns_roce_qp *qp, +@@ -271,8 +270,7 @@ static int set_rc_inl(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + dseg += sizeof(struct hns_roce_v2_rc_send_wqe); + + if (msg_len <= HNS_ROCE_V2_MAX_RC_INL_INN_SZ) { +- roce_set_bit(rc_sq_wqe->byte_20, +- V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S, 0); ++ hr_reg_clear(rc_sq_wqe, RC_SEND_WQE_INL_TYPE); + + for (i = 0; i < wr->num_sge; i++) { + memcpy(dseg, ((void *)wr->sg_list[i].addr), +@@ -280,17 +278,13 @@ static int set_rc_inl(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + dseg += wr->sg_list[i].length; + } + } else { +- roce_set_bit(rc_sq_wqe->byte_20, +- V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S, 1); ++ hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_INL_TYPE); + + ret = fill_ext_sge_inl_data(qp, wr, &curr_idx, msg_len); + if (ret) + return ret; + +- roce_set_field(rc_sq_wqe->byte_16, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, +- curr_idx - *sge_idx); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SGE_NUM, curr_idx - *sge_idx); + } + + *sge_idx = curr_idx; +@@ -309,12 +303,10 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + int j = 0; + int i; + +- roce_set_field(rc_sq_wqe->byte_20, +- V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M, +- V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, +- (*sge_ind) & (qp->sge.sge_cnt - 1)); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_MSG_START_SGE_IDX, ++ (*sge_ind) & (qp->sge.sge_cnt - 1)); + +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_INLINE, + !!(wr->send_flags & IB_SEND_INLINE)); + if (wr->send_flags & IB_SEND_INLINE) + return set_rc_inl(qp, wr, rc_sq_wqe, sge_ind); +@@ -339,9 +331,7 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + valid_num_sge - HNS_ROCE_SGE_IN_WQE); + } + +- roce_set_field(rc_sq_wqe->byte_16, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SGE_NUM, valid_num_sge); + + return 0; + } +@@ -412,8 +402,7 @@ static int set_ud_opcode(struct hns_roce_v2_ud_send_wqe *ud_sq_wqe, + + ud_sq_wqe->immtdata = get_immtdata(wr); + +- roce_set_field(ud_sq_wqe->byte_4, V2_UD_SEND_WQE_BYTE_4_OPCODE_M, +- V2_UD_SEND_WQE_BYTE_4_OPCODE_S, to_hr_opcode(ib_op)); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_OPCODE, to_hr_opcode(ib_op)); + + return 0; + } +@@ -424,21 +413,15 @@ static int fill_ud_av(struct hns_roce_v2_ud_send_wqe *ud_sq_wqe, + struct ib_device *ib_dev = ah->ibah.device; + struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev); + +- roce_set_field(ud_sq_wqe->byte_24, V2_UD_SEND_WQE_BYTE_24_UDPSPN_M, +- V2_UD_SEND_WQE_BYTE_24_UDPSPN_S, ah->av.udp_sport); +- +- roce_set_field(ud_sq_wqe->byte_36, V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_M, +- V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_S, ah->av.hop_limit); +- roce_set_field(ud_sq_wqe->byte_36, V2_UD_SEND_WQE_BYTE_36_TCLASS_M, +- V2_UD_SEND_WQE_BYTE_36_TCLASS_S, ah->av.tclass); +- roce_set_field(ud_sq_wqe->byte_40, V2_UD_SEND_WQE_BYTE_40_FLOW_LABEL_M, +- V2_UD_SEND_WQE_BYTE_40_FLOW_LABEL_S, ah->av.flowlabel); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_UDPSPN, ah->av.udp_sport); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_HOPLIMIT, ah->av.hop_limit); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_TCLASS, ah->av.tclass); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_FLOW_LABEL, ah->av.flowlabel); + + if (WARN_ON(ah->av.sl > MAX_SERVICE_LEVEL)) + return -EINVAL; + +- roce_set_field(ud_sq_wqe->byte_40, V2_UD_SEND_WQE_BYTE_40_SL_M, +- V2_UD_SEND_WQE_BYTE_40_SL_S, ah->av.sl); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_SL, ah->av.sl); + + ud_sq_wqe->sgid_index = ah->av.gid_index; + +@@ -448,10 +431,8 @@ static int fill_ud_av(struct hns_roce_v2_ud_send_wqe *ud_sq_wqe, + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) + return 0; + +- roce_set_bit(ud_sq_wqe->byte_40, V2_UD_SEND_WQE_BYTE_40_UD_VLAN_EN_S, +- ah->av.vlan_en); +- roce_set_field(ud_sq_wqe->byte_36, V2_UD_SEND_WQE_BYTE_36_VLAN_M, +- V2_UD_SEND_WQE_BYTE_36_VLAN_S, ah->av.vlan_id); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_VLAN_EN, ah->av.vlan_en); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_VLAN, ah->av.vlan_id); + + return 0; + } +@@ -476,27 +457,19 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp, + + ud_sq_wqe->msg_len = cpu_to_le32(msg_len); + +- roce_set_bit(ud_sq_wqe->byte_4, V2_UD_SEND_WQE_BYTE_4_CQE_S, ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_CQE, + !!(wr->send_flags & IB_SEND_SIGNALED)); +- +- roce_set_bit(ud_sq_wqe->byte_4, V2_UD_SEND_WQE_BYTE_4_SE_S, ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_SE, + !!(wr->send_flags & IB_SEND_SOLICITED)); + +- roce_set_field(ud_sq_wqe->byte_16, V2_UD_SEND_WQE_BYTE_16_PD_M, +- V2_UD_SEND_WQE_BYTE_16_PD_S, to_hr_pd(qp->ibqp.pd)->pdn); +- +- roce_set_field(ud_sq_wqe->byte_16, V2_UD_SEND_WQE_BYTE_16_SGE_NUM_M, +- V2_UD_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge); +- +- roce_set_field(ud_sq_wqe->byte_20, +- V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M, +- V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, +- curr_idx & (qp->sge.sge_cnt - 1)); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_PD, to_hr_pd(qp->ibqp.pd)->pdn); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_SGE_NUM, valid_num_sge); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_MSG_START_SGE_IDX, ++ curr_idx & (qp->sge.sge_cnt - 1)); + + ud_sq_wqe->qkey = cpu_to_le32(ud_wr(wr)->remote_qkey & 0x80000000 ? + qp->qkey : ud_wr(wr)->remote_qkey); +- roce_set_field(ud_sq_wqe->byte_32, V2_UD_SEND_WQE_BYTE_32_DQPN_M, +- V2_UD_SEND_WQE_BYTE_32_DQPN_S, ud_wr(wr)->remote_qpn); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_DQPN, ud_wr(wr)->remote_qpn); + + ret = fill_ud_av(ud_sq_wqe, ah); + if (ret) +@@ -516,8 +489,7 @@ static inline int set_ud_wqe(struct hns_roce_qp *qp, + dma_wmb(); + + *sge_idx = curr_idx; +- roce_set_bit(ud_sq_wqe->byte_4, V2_UD_SEND_WQE_BYTE_4_OWNER_S, +- owner_bit); ++ hr_reg_write(ud_sq_wqe, UD_SEND_WQE_OWNER, owner_bit); + + return 0; + } +@@ -553,7 +525,7 @@ static int set_rc_opcode(struct hns_roce_dev *hr_dev, + ret = -EOPNOTSUPP; + break; + case IB_WR_LOCAL_INV: +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_SO_S, 1); ++ hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_SO); + fallthrough; + case IB_WR_SEND_WITH_INV: + rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey); +@@ -565,11 +537,11 @@ static int set_rc_opcode(struct hns_roce_dev *hr_dev, + if (unlikely(ret)) + return ret; + +- roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OPCODE_M, +- V2_RC_SEND_WQE_BYTE_4_OPCODE_S, to_hr_opcode(ib_op)); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_OPCODE, to_hr_opcode(ib_op)); + + return ret; + } ++ + static inline int set_rc_wqe(struct hns_roce_qp *qp, + const struct ib_send_wr *wr, + void *wqe, unsigned int *sge_idx, +@@ -590,13 +562,13 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, + if (WARN_ON(ret)) + return ret; + +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_FENCE_S, ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_FENCE, + (wr->send_flags & IB_SEND_FENCE) ? 1 : 0); + +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_SE_S, ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SE, + (wr->send_flags & IB_SEND_SOLICITED) ? 1 : 0); + +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_CQE_S, ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_CQE, + (wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0); + + if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP || +@@ -616,8 +588,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, + dma_wmb(); + + *sge_idx = curr_idx; +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OWNER_S, +- owner_bit); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_OWNER, owner_bit); + + return ret; + } +@@ -682,14 +653,11 @@ static void write_dwqe(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, + struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe; + + /* All kinds of DirectWQE have the same header field layout */ +- roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_FLAG_S, 1); +- roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_DB_SL_L_M, +- V2_RC_SEND_WQE_BYTE_4_DB_SL_L_S, qp->sl); +- roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_DB_SL_H_M, +- V2_RC_SEND_WQE_BYTE_4_DB_SL_H_S, +- qp->sl >> HNS_ROCE_SL_SHIFT); +- roce_set_field(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_M, +- V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_S, qp->sq.head); ++ hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_FLAG); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_DB_SL_L, qp->sl); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_DB_SL_H, ++ qp->sl >> HNS_ROCE_SL_SHIFT); ++ hr_reg_write(rc_sq_wqe, RC_SEND_WQE_WQE_INDEX, qp->sq.head); + + hns_roce_write512(hr_dev, wqe, qp->sq.db_reg); + } +@@ -1785,17 +1753,16 @@ static int __hns_roce_set_vf_switch_param(struct hns_roce_dev *hr_dev, + swt = (struct hns_roce_vf_switch *)desc.data; + hns_roce_cmq_setup_basic_desc(&desc, HNS_SWITCH_PARAMETER_CFG, true); + swt->rocee_sel |= cpu_to_le32(HNS_ICL_SWITCH_CMD_ROCEE_SEL); +- roce_set_field(swt->fun_id, VF_SWITCH_DATA_FUN_ID_VF_ID_M, +- VF_SWITCH_DATA_FUN_ID_VF_ID_S, vf_id); ++ hr_reg_write(swt, VF_SWITCH_VF_ID, vf_id); + ret = hns_roce_cmq_send(hr_dev, &desc, 1); + if (ret) + return ret; + + desc.flag = cpu_to_le16(HNS_ROCE_CMD_FLAG_IN); + desc.flag &= cpu_to_le16(~HNS_ROCE_CMD_FLAG_WR); +- roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_LPBK_S, 1); +- roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_LCL_LPBK_S, 0); +- roce_set_bit(swt->cfg, VF_SWITCH_DATA_CFG_ALW_DST_OVRD_S, 1); ++ hr_reg_enable(swt, VF_SWITCH_ALW_LPBK); ++ hr_reg_clear(swt, VF_SWITCH_ALW_LCL_LPBK); ++ hr_reg_enable(swt, VF_SWITCH_ALW_DST_OVRD); + + return hns_roce_cmq_send(hr_dev, &desc, 1); + } +@@ -2944,10 +2911,8 @@ static int config_sgid_table(struct hns_roce_dev *hr_dev, + + hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_CFG_SGID_TB, false); + +- roce_set_field(sgid_tb->table_idx_rsv, CFG_SGID_TB_TABLE_IDX_M, +- CFG_SGID_TB_TABLE_IDX_S, gid_index); +- roce_set_field(sgid_tb->vf_sgid_type_rsv, CFG_SGID_TB_VF_SGID_TYPE_M, +- CFG_SGID_TB_VF_SGID_TYPE_S, sgid_type); ++ hr_reg_write(sgid_tb, CFG_SGID_TB_TABLE_IDX, gid_index); ++ hr_reg_write(sgid_tb, CFG_SGID_TB_VF_SGID_TYPE, sgid_type); + + copy_gid(&sgid_tb->vf_sgid_l, gid); + +@@ -2982,19 +2947,14 @@ static int config_gmv_table(struct hns_roce_dev *hr_dev, + + copy_gid(&tb_a->vf_sgid_l, gid); + +- roce_set_field(tb_a->vf_sgid_type_vlan, CFG_GMV_TB_VF_SGID_TYPE_M, +- CFG_GMV_TB_VF_SGID_TYPE_S, sgid_type); +- roce_set_bit(tb_a->vf_sgid_type_vlan, CFG_GMV_TB_VF_VLAN_EN_S, +- vlan_id < VLAN_CFI_MASK); +- roce_set_field(tb_a->vf_sgid_type_vlan, CFG_GMV_TB_VF_VLAN_ID_M, +- CFG_GMV_TB_VF_VLAN_ID_S, vlan_id); ++ hr_reg_write(tb_a, GMV_TB_A_VF_SGID_TYPE, sgid_type); ++ hr_reg_write(tb_a, GMV_TB_A_VF_VLAN_EN, vlan_id < VLAN_CFI_MASK); ++ hr_reg_write(tb_a, GMV_TB_A_VF_VLAN_ID, vlan_id); + + tb_b->vf_smac_l = cpu_to_le32(*(u32 *)mac); +- roce_set_field(tb_b->vf_smac_h, CFG_GMV_TB_SMAC_H_M, +- CFG_GMV_TB_SMAC_H_S, *(u16 *)&mac[4]); + +- roce_set_field(tb_b->table_idx_rsv, CFG_GMV_TB_SGID_IDX_M, +- CFG_GMV_TB_SGID_IDX_S, gid_index); ++ hr_reg_write(tb_b, GMV_TB_B_SMAC_H, *(u16 *)&mac[4]); ++ hr_reg_write(tb_b, GMV_TB_B_SGID_IDX, gid_index); + + return hns_roce_cmq_send(hr_dev, desc, 2); + } +@@ -3043,10 +3003,8 @@ static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port, + reg_smac_l = *(u32 *)(&addr[0]); + reg_smac_h = *(u16 *)(&addr[4]); + +- roce_set_field(smac_tb->tb_idx_rsv, CFG_SMAC_TB_IDX_M, +- CFG_SMAC_TB_IDX_S, phy_port); +- roce_set_field(smac_tb->vf_smac_h_rsv, CFG_SMAC_TB_VF_SMAC_H_M, +- CFG_SMAC_TB_VF_SMAC_H_S, reg_smac_h); ++ hr_reg_write(smac_tb, CFG_SMAC_TB_IDX, phy_port); ++ hr_reg_write(smac_tb, CFG_SMAC_TB_VF_SMAC_H, reg_smac_h); + smac_tb->vf_smac_l = cpu_to_le32(reg_smac_l); + + return hns_roce_cmq_send(hr_dev, &desc, 1); +@@ -3075,21 +3033,15 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev, + + mpt_entry->pbl_size = cpu_to_le32(mr->npages); + mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> 3); +- roce_set_field(mpt_entry->byte_48_mode_ba, +- V2_MPT_BYTE_48_PBL_BA_H_M, V2_MPT_BYTE_48_PBL_BA_H_S, +- upper_32_bits(pbl_ba >> 3)); ++ hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3)); + + mpt_entry->pa0_l = cpu_to_le32(lower_32_bits(pages[0])); +- roce_set_field(mpt_entry->byte_56_pa0_h, V2_MPT_BYTE_56_PA0_H_M, +- V2_MPT_BYTE_56_PA0_H_S, upper_32_bits(pages[0])); ++ hr_reg_write(mpt_entry, MPT_PA0_H, upper_32_bits(pages[0])); + + mpt_entry->pa1_l = cpu_to_le32(lower_32_bits(pages[1])); +- roce_set_field(mpt_entry->byte_64_buf_pa1, V2_MPT_BYTE_64_PA1_H_M, +- V2_MPT_BYTE_64_PA1_H_S, upper_32_bits(pages[1])); +- roce_set_field(mpt_entry->byte_64_buf_pa1, +- V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M, +- V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S, +- to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift)); ++ hr_reg_write(mpt_entry, MPT_PA1_H, upper_32_bits(pages[1])); ++ hr_reg_write(mpt_entry, MPT_PBL_BUF_PG_SZ, ++ to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift)); + + return 0; + } +@@ -3151,24 +3103,19 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev, + u32 mr_access_flags = mr->access; + int ret = 0; + +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_MPT_ST_M, +- V2_MPT_BYTE_4_MPT_ST_S, V2_MPT_ST_VALID); +- +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M, +- V2_MPT_BYTE_4_PD_S, mr->pd); ++ hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_VALID); ++ hr_reg_write(mpt_entry, MPT_PD, mr->pd); + + if (flags & IB_MR_REREG_ACCESS) { +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, +- V2_MPT_BYTE_8_BIND_EN_S, ++ hr_reg_write(mpt_entry, MPT_BIND_EN, + (mr_access_flags & IB_ACCESS_MW_BIND ? 1 : 0)); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, +- V2_MPT_BYTE_8_ATOMIC_EN_S, ++ hr_reg_write(mpt_entry, MPT_ATOMIC_EN, + mr_access_flags & IB_ACCESS_REMOTE_ATOMIC ? 1 : 0); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_RR_EN_S, ++ hr_reg_write(mpt_entry, MPT_RR_EN, + mr_access_flags & IB_ACCESS_REMOTE_READ ? 1 : 0); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_RW_EN_S, ++ hr_reg_write(mpt_entry, MPT_RW_EN, + mr_access_flags & IB_ACCESS_REMOTE_WRITE ? 1 : 0); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S, ++ hr_reg_write(mpt_entry, MPT_LW_EN, + mr_access_flags & IB_ACCESS_LOCAL_WRITE ? 1 : 0); + } + +@@ -3199,37 +3146,28 @@ static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev, + return -ENOBUFS; + } + +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_MPT_ST_M, +- V2_MPT_BYTE_4_MPT_ST_S, V2_MPT_ST_FREE); +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PBL_HOP_NUM_M, +- V2_MPT_BYTE_4_PBL_HOP_NUM_S, 1); +- roce_set_field(mpt_entry->byte_4_pd_hop_st, +- V2_MPT_BYTE_4_PBL_BA_PG_SZ_M, +- V2_MPT_BYTE_4_PBL_BA_PG_SZ_S, +- to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.ba_pg_shift)); +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M, +- V2_MPT_BYTE_4_PD_S, mr->pd); ++ hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_FREE); ++ hr_reg_write(mpt_entry, MPT_PD, mr->pd); ++ ++ hr_reg_enable(mpt_entry, MPT_RA_EN); ++ hr_reg_enable(mpt_entry, MPT_R_INV_EN); ++ hr_reg_enable(mpt_entry, MPT_L_INV_EN); + +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_RA_EN_S, 1); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1); ++ hr_reg_enable(mpt_entry, MPT_FRE); ++ hr_reg_clear(mpt_entry, MPT_MR_MW); ++ hr_reg_enable(mpt_entry, MPT_BPD); ++ hr_reg_clear(mpt_entry, MPT_PA); + +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_FRE_S, 1); +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0); +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 0); +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_BPD_S, 1); ++ hr_reg_write(mpt_entry, MPT_PBL_HOP_NUM, 1); ++ hr_reg_write(mpt_entry, MPT_PBL_BA_PG_SZ, ++ to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.ba_pg_shift)); ++ hr_reg_write(mpt_entry, MPT_PBL_BUF_PG_SZ, ++ to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift)); + + mpt_entry->pbl_size = cpu_to_le32(mr->npages); + + mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(pbl_ba >> 3)); +- roce_set_field(mpt_entry->byte_48_mode_ba, V2_MPT_BYTE_48_PBL_BA_H_M, +- V2_MPT_BYTE_48_PBL_BA_H_S, +- upper_32_bits(pbl_ba >> 3)); +- +- roce_set_field(mpt_entry->byte_64_buf_pa1, +- V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M, +- V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S, +- to_hr_hw_page_shift(mr->pbl_mtr.hem_cfg.buf_pg_shift)); ++ hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3)); + + return 0; + } +@@ -3241,36 +3179,29 @@ static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw) + mpt_entry = mb_buf; + memset(mpt_entry, 0, sizeof(*mpt_entry)); + +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_MPT_ST_M, +- V2_MPT_BYTE_4_MPT_ST_S, V2_MPT_ST_FREE); +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M, +- V2_MPT_BYTE_4_PD_S, mw->pdn); +- roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PBL_HOP_NUM_M, +- V2_MPT_BYTE_4_PBL_HOP_NUM_S, +- mw->pbl_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 : +- mw->pbl_hop_num); +- roce_set_field(mpt_entry->byte_4_pd_hop_st, +- V2_MPT_BYTE_4_PBL_BA_PG_SZ_M, +- V2_MPT_BYTE_4_PBL_BA_PG_SZ_S, +- mw->pbl_ba_pg_sz + PG_SHIFT_OFFSET); +- +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1); +- roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S, 1); +- +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0); +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 1); +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_BPD_S, 1); +- roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_BQP_S, +- mw->ibmw.type == IB_MW_TYPE_1 ? 0 : 1); ++ hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_FREE); ++ hr_reg_write(mpt_entry, MPT_PD, mw->pdn); + +- roce_set_field(mpt_entry->byte_64_buf_pa1, +- V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M, +- V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S, +- mw->pbl_buf_pg_sz + PG_SHIFT_OFFSET); ++ hr_reg_enable(mpt_entry, MPT_R_INV_EN); ++ hr_reg_enable(mpt_entry, MPT_L_INV_EN); ++ hr_reg_enable(mpt_entry, MPT_LW_EN); ++ ++ hr_reg_enable(mpt_entry, MPT_MR_MW); ++ hr_reg_enable(mpt_entry, MPT_BPD); ++ hr_reg_clear(mpt_entry, MPT_PA); ++ hr_reg_write(mpt_entry, MPT_BQP, ++ mw->ibmw.type == IB_MW_TYPE_1 ? 0 : 1); + + mpt_entry->lkey = cpu_to_le32(mw->rkey); + ++ hr_reg_write(mpt_entry, MPT_PBL_HOP_NUM, ++ mw->pbl_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 : ++ mw->pbl_hop_num); ++ hr_reg_write(mpt_entry, MPT_PBL_BA_PG_SZ, ++ mw->pbl_ba_pg_sz + PG_SHIFT_OFFSET); ++ hr_reg_write(mpt_entry, MPT_PBL_BUF_PG_SZ, ++ mw->pbl_buf_pg_sz + PG_SHIFT_OFFSET); ++ + return 0; + } + +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +index d3d5b5f57052..ddb99a7ff135 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +@@ -790,12 +790,15 @@ struct hns_roce_v2_mpt_entry { + #define MPT_LKEY MPT_FIELD_LOC(223, 192) + #define MPT_VA MPT_FIELD_LOC(287, 224) + #define MPT_PBL_SIZE MPT_FIELD_LOC(319, 288) +-#define MPT_PBL_BA MPT_FIELD_LOC(380, 320) ++#define MPT_PBL_BA_L MPT_FIELD_LOC(351, 320) ++#define MPT_PBL_BA_H MPT_FIELD_LOC(380, 352) + #define MPT_BLK_MODE MPT_FIELD_LOC(381, 381) + #define MPT_RSV0 MPT_FIELD_LOC(383, 382) +-#define MPT_PA0 MPT_FIELD_LOC(441, 384) ++#define MPT_PA0_L MPT_FIELD_LOC(415, 384) ++#define MPT_PA0_H MPT_FIELD_LOC(441, 416) + #define MPT_BOUND_VA MPT_FIELD_LOC(447, 442) +-#define MPT_PA1 MPT_FIELD_LOC(505, 448) ++#define MPT_PA1_L MPT_FIELD_LOC(479, 448) ++#define MPT_PA1_H MPT_FIELD_LOC(505, 480) + #define MPT_PERSIST_EN MPT_FIELD_LOC(506, 506) + #define MPT_RSV2 MPT_FIELD_LOC(507, 507) + #define MPT_PBL_BUF_PG_SZ MPT_FIELD_LOC(511, 508) +@@ -901,48 +904,24 @@ struct hns_roce_v2_ud_send_wqe { + u8 dgid[GID_LEN_V2]; + }; + +-#define V2_UD_SEND_WQE_BYTE_4_OPCODE_S 0 +-#define V2_UD_SEND_WQE_BYTE_4_OPCODE_M GENMASK(4, 0) +- +-#define V2_UD_SEND_WQE_BYTE_4_OWNER_S 7 +- +-#define V2_UD_SEND_WQE_BYTE_4_CQE_S 8 +- +-#define V2_UD_SEND_WQE_BYTE_4_SE_S 11 +- +-#define V2_UD_SEND_WQE_BYTE_16_PD_S 0 +-#define V2_UD_SEND_WQE_BYTE_16_PD_M GENMASK(23, 0) +- +-#define V2_UD_SEND_WQE_BYTE_16_SGE_NUM_S 24 +-#define V2_UD_SEND_WQE_BYTE_16_SGE_NUM_M GENMASK(31, 24) +- +-#define V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S 0 +-#define V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M GENMASK(23, 0) +- +-#define V2_UD_SEND_WQE_BYTE_24_UDPSPN_S 16 +-#define V2_UD_SEND_WQE_BYTE_24_UDPSPN_M GENMASK(31, 16) +- +-#define V2_UD_SEND_WQE_BYTE_32_DQPN_S 0 +-#define V2_UD_SEND_WQE_BYTE_32_DQPN_M GENMASK(23, 0) +- +-#define V2_UD_SEND_WQE_BYTE_36_VLAN_S 0 +-#define V2_UD_SEND_WQE_BYTE_36_VLAN_M GENMASK(15, 0) +- +-#define V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_S 16 +-#define V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_M GENMASK(23, 16) +- +-#define V2_UD_SEND_WQE_BYTE_36_TCLASS_S 24 +-#define V2_UD_SEND_WQE_BYTE_36_TCLASS_M GENMASK(31, 24) +- +-#define V2_UD_SEND_WQE_BYTE_40_FLOW_LABEL_S 0 +-#define V2_UD_SEND_WQE_BYTE_40_FLOW_LABEL_M GENMASK(19, 0) +- +-#define V2_UD_SEND_WQE_BYTE_40_SL_S 20 +-#define V2_UD_SEND_WQE_BYTE_40_SL_M GENMASK(23, 20) +- +-#define V2_UD_SEND_WQE_BYTE_40_UD_VLAN_EN_S 30 +- +-#define V2_UD_SEND_WQE_BYTE_40_LBI_S 31 ++#define UD_SEND_WQE_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_v2_ud_send_wqe, h, l) ++ ++#define UD_SEND_WQE_OPCODE UD_SEND_WQE_FIELD_LOC(4, 0) ++#define UD_SEND_WQE_OWNER UD_SEND_WQE_FIELD_LOC(7, 7) ++#define UD_SEND_WQE_CQE UD_SEND_WQE_FIELD_LOC(8, 8) ++#define UD_SEND_WQE_SE UD_SEND_WQE_FIELD_LOC(11, 11) ++#define UD_SEND_WQE_PD UD_SEND_WQE_FIELD_LOC(119, 96) ++#define UD_SEND_WQE_SGE_NUM UD_SEND_WQE_FIELD_LOC(127, 120) ++#define UD_SEND_WQE_MSG_START_SGE_IDX UD_SEND_WQE_FIELD_LOC(151, 128) ++#define UD_SEND_WQE_UDPSPN UD_SEND_WQE_FIELD_LOC(191, 176) ++#define UD_SEND_WQE_DQPN UD_SEND_WQE_FIELD_LOC(247, 224) ++#define UD_SEND_WQE_VLAN UD_SEND_WQE_FIELD_LOC(271, 256) ++#define UD_SEND_WQE_HOPLIMIT UD_SEND_WQE_FIELD_LOC(279, 272) ++#define UD_SEND_WQE_TCLASS UD_SEND_WQE_FIELD_LOC(287, 280) ++#define UD_SEND_WQE_FLOW_LABEL UD_SEND_WQE_FIELD_LOC(307, 288) ++#define UD_SEND_WQE_SL UD_SEND_WQE_FIELD_LOC(311, 308) ++#define UD_SEND_WQE_VLAN_EN UD_SEND_WQE_FIELD_LOC(318, 318) ++#define UD_SEND_WQE_LBI UD_SEND_WQE_FIELD_LOC(319, 319) + + struct hns_roce_v2_rc_send_wqe { + __le32 byte_4; +@@ -957,42 +936,23 @@ struct hns_roce_v2_rc_send_wqe { + __le64 va; + }; + +-#define V2_RC_SEND_WQE_BYTE_4_OPCODE_S 0 +-#define V2_RC_SEND_WQE_BYTE_4_OPCODE_M GENMASK(4, 0) +- +-#define V2_RC_SEND_WQE_BYTE_4_DB_SL_L_S 5 +-#define V2_RC_SEND_WQE_BYTE_4_DB_SL_L_M GENMASK(6, 5) +- +-#define V2_RC_SEND_WQE_BYTE_4_DB_SL_H_S 13 +-#define V2_RC_SEND_WQE_BYTE_4_DB_SL_H_M GENMASK(14, 13) +- +-#define V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_S 15 +-#define V2_RC_SEND_WQE_BYTE_4_WQE_INDEX_M GENMASK(30, 15) +- +-#define V2_RC_SEND_WQE_BYTE_4_OWNER_S 7 +- +-#define V2_RC_SEND_WQE_BYTE_4_CQE_S 8 +- +-#define V2_RC_SEND_WQE_BYTE_4_FENCE_S 9 +- +-#define V2_RC_SEND_WQE_BYTE_4_SO_S 10 +- +-#define V2_RC_SEND_WQE_BYTE_4_SE_S 11 +- +-#define V2_RC_SEND_WQE_BYTE_4_INLINE_S 12 +- +-#define V2_RC_SEND_WQE_BYTE_4_FLAG_S 31 +- +-#define V2_RC_SEND_WQE_BYTE_16_XRC_SRQN_S 0 +-#define V2_RC_SEND_WQE_BYTE_16_XRC_SRQN_M GENMASK(23, 0) +- +-#define V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S 24 +-#define V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M GENMASK(31, 24) +- +-#define V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S 0 +-#define V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M GENMASK(23, 0) +- +-#define V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S 31 ++#define RC_SEND_WQE_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_v2_rc_send_wqe, h, l) ++ ++#define RC_SEND_WQE_OPCODE RC_SEND_WQE_FIELD_LOC(4, 0) ++#define RC_SEND_WQE_DB_SL_L RC_SEND_WQE_FIELD_LOC(6, 5) ++#define RC_SEND_WQE_DB_SL_H RC_SEND_WQE_FIELD_LOC(14, 13) ++#define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7) ++#define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8) ++#define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9) ++#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10) ++#define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11) ++#define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12) ++#define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15) ++#define RC_SEND_WQE_FLAG RC_SEND_WQE_FIELD_LOC(31, 31) ++#define RC_SEND_WQE_XRC_SRQN RC_SEND_WQE_FIELD_LOC(119, 96) ++#define RC_SEND_WQE_SGE_NUM RC_SEND_WQE_FIELD_LOC(127, 120) ++#define RC_SEND_WQE_MSG_START_SGE_IDX RC_SEND_WQE_FIELD_LOC(151, 128) ++#define RC_SEND_WQE_INL_TYPE RC_SEND_WQE_FIELD_LOC(159, 159) + + struct hns_roce_wqe_frmr_seg { + __le32 pbl_size; +@@ -1114,12 +1074,12 @@ struct hns_roce_vf_switch { + __le32 resv3; + }; + +-#define VF_SWITCH_DATA_FUN_ID_VF_ID_S 3 +-#define VF_SWITCH_DATA_FUN_ID_VF_ID_M GENMASK(10, 3) ++#define VF_SWITCH_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_vf_switch, h, l) + +-#define VF_SWITCH_DATA_CFG_ALW_LPBK_S 1 +-#define VF_SWITCH_DATA_CFG_ALW_LCL_LPBK_S 2 +-#define VF_SWITCH_DATA_CFG_ALW_DST_OVRD_S 3 ++#define VF_SWITCH_VF_ID VF_SWITCH_FIELD_LOC(42, 35) ++#define VF_SWITCH_ALW_LPBK VF_SWITCH_FIELD_LOC(65, 65) ++#define VF_SWITCH_ALW_LCL_LPBK VF_SWITCH_FIELD_LOC(66, 66) ++#define VF_SWITCH_ALW_DST_OVRD VF_SWITCH_FIELD_LOC(67, 67) + + struct hns_roce_post_mbox { + __le32 in_param_l; +@@ -1182,11 +1142,10 @@ struct hns_roce_cfg_sgid_tb { + __le32 vf_sgid_type_rsv; + }; + +-#define CFG_SGID_TB_TABLE_IDX_S 0 +-#define CFG_SGID_TB_TABLE_IDX_M GENMASK(7, 0) ++#define SGID_TB_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_cfg_sgid_tb, h, l) + +-#define CFG_SGID_TB_VF_SGID_TYPE_S 0 +-#define CFG_SGID_TB_VF_SGID_TYPE_M GENMASK(1, 0) ++#define CFG_SGID_TB_TABLE_IDX SGID_TB_FIELD_LOC(7, 0) ++#define CFG_SGID_TB_VF_SGID_TYPE SGID_TB_FIELD_LOC(161, 160) + + struct hns_roce_cfg_smac_tb { + __le32 tb_idx_rsv; +@@ -1194,11 +1153,11 @@ struct hns_roce_cfg_smac_tb { + __le32 vf_smac_h_rsv; + __le32 rsv[3]; + }; +-#define CFG_SMAC_TB_IDX_S 0 +-#define CFG_SMAC_TB_IDX_M GENMASK(7, 0) + +-#define CFG_SMAC_TB_VF_SMAC_H_S 0 +-#define CFG_SMAC_TB_VF_SMAC_H_M GENMASK(15, 0) ++#define SMAC_TB_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_cfg_smac_tb, h, l) ++ ++#define CFG_SMAC_TB_IDX SMAC_TB_FIELD_LOC(7, 0) ++#define CFG_SMAC_TB_VF_SMAC_H SMAC_TB_FIELD_LOC(79, 64) + + struct hns_roce_cfg_gmv_tb_a { + __le32 vf_sgid_l; +@@ -1209,16 +1168,11 @@ struct hns_roce_cfg_gmv_tb_a { + __le32 resv; + }; + +-#define CFG_GMV_TB_SGID_IDX_S 0 +-#define CFG_GMV_TB_SGID_IDX_M GENMASK(7, 0) +- +-#define CFG_GMV_TB_VF_SGID_TYPE_S 0 +-#define CFG_GMV_TB_VF_SGID_TYPE_M GENMASK(1, 0) ++#define GMV_TB_A_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_cfg_gmv_tb_a, h, l) + +-#define CFG_GMV_TB_VF_VLAN_EN_S 2 +- +-#define CFG_GMV_TB_VF_VLAN_ID_S 16 +-#define CFG_GMV_TB_VF_VLAN_ID_M GENMASK(27, 16) ++#define GMV_TB_A_VF_SGID_TYPE GMV_TB_A_FIELD_LOC(129, 128) ++#define GMV_TB_A_VF_VLAN_EN GMV_TB_A_FIELD_LOC(130, 130) ++#define GMV_TB_A_VF_VLAN_ID GMV_TB_A_FIELD_LOC(155, 144) + + struct hns_roce_cfg_gmv_tb_b { + __le32 vf_smac_l; +@@ -1227,8 +1181,10 @@ struct hns_roce_cfg_gmv_tb_b { + __le32 resv[3]; + }; + +-#define CFG_GMV_TB_SMAC_H_S 0 +-#define CFG_GMV_TB_SMAC_H_M GENMASK(15, 0) ++#define GMV_TB_B_FIELD_LOC(h, l) FIELD_LOC(struct hns_roce_cfg_gmv_tb_b, h, l) ++ ++#define GMV_TB_B_SMAC_H GMV_TB_B_FIELD_LOC(47, 32) ++#define GMV_TB_B_SGID_IDX GMV_TB_B_FIELD_LOC(71, 64) + + #define HNS_ROCE_QUERY_PF_CAPS_CMD_NUM 5 + struct hns_roce_query_pf_caps_a { +-- +2.35.1 + diff --git a/queue-5.15/rdma-qedr-clean-up-work-queue-on-failure-in-qedr_all.patch b/queue-5.15/rdma-qedr-clean-up-work-queue-on-failure-in-qedr_all.patch new file mode 100644 index 00000000000..889b1ca7b08 --- /dev/null +++ b/queue-5.15/rdma-qedr-clean-up-work-queue-on-failure-in-qedr_all.patch @@ -0,0 +1,59 @@ +From b45e7b44d77418f3602f1fb8ac120a5480ba2724 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Oct 2022 18:32:32 +0300 +Subject: RDMA/qedr: clean up work queue on failure in qedr_alloc_resources() + +From: Dan Carpenter + +[ Upstream commit 7a47e077e503feb73d56e491ce89aa73b67a3972 ] + +Add a check for if create_singlethread_workqueue() fails and also destroy +the work queue on failure paths. + +Fixes: e411e0587e0d ("RDMA/qedr: Add iWARP connection management functions") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/Y1gBkDucQhhWj5YM@kili +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/qedr/main.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c +index 755930be01b8..6b59f97a182b 100644 +--- a/drivers/infiniband/hw/qedr/main.c ++++ b/drivers/infiniband/hw/qedr/main.c +@@ -345,6 +345,10 @@ static int qedr_alloc_resources(struct qedr_dev *dev) + if (IS_IWARP(dev)) { + xa_init(&dev->qps); + dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq"); ++ if (!dev->iwarp_wq) { ++ rc = -ENOMEM; ++ goto err1; ++ } + } + + /* Allocate Status blocks for CNQ */ +@@ -352,7 +356,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev) + GFP_KERNEL); + if (!dev->sb_array) { + rc = -ENOMEM; +- goto err1; ++ goto err_destroy_wq; + } + + dev->cnq_array = kcalloc(dev->num_cnq, +@@ -403,6 +407,9 @@ static int qedr_alloc_resources(struct qedr_dev *dev) + kfree(dev->cnq_array); + err2: + kfree(dev->sb_array); ++err_destroy_wq: ++ if (IS_IWARP(dev)) ++ destroy_workqueue(dev->iwarp_wq); + err1: + kfree(dev->sgid_tbl); + return rc; +-- +2.35.1 + diff --git a/queue-5.15/rose-fix-null-pointer-dereference-in-rose_send_frame.patch b/queue-5.15/rose-fix-null-pointer-dereference-in-rose_send_frame.patch new file mode 100644 index 00000000000..602ea0112ab --- /dev/null +++ b/queue-5.15/rose-fix-null-pointer-dereference-in-rose_send_frame.patch @@ -0,0 +1,76 @@ +From ae4d5373df27a3a69df2f76c9e4832776360f62b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Oct 2022 00:10:49 +0800 +Subject: rose: Fix NULL pointer dereference in rose_send_frame() + +From: Zhang Qilong + +[ Upstream commit e97c089d7a49f67027395ddf70bf327eeac2611e ] + +The syzkaller reported an issue: + +KASAN: null-ptr-deref in range [0x0000000000000380-0x0000000000000387] +CPU: 0 PID: 4069 Comm: kworker/0:15 Not tainted 6.0.0-syzkaller-02734-g0326074ff465 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/22/2022 +Workqueue: rcu_gp srcu_invoke_callbacks +RIP: 0010:rose_send_frame+0x1dd/0x2f0 net/rose/rose_link.c:101 +Call Trace: + + rose_transmit_clear_request+0x1d5/0x290 net/rose/rose_link.c:255 + rose_rx_call_request+0x4c0/0x1bc0 net/rose/af_rose.c:1009 + rose_loopback_timer+0x19e/0x590 net/rose/rose_loopback.c:111 + call_timer_fn+0x1a0/0x6b0 kernel/time/timer.c:1474 + expire_timers kernel/time/timer.c:1519 [inline] + __run_timers.part.0+0x674/0xa80 kernel/time/timer.c:1790 + __run_timers kernel/time/timer.c:1768 [inline] + run_timer_softirq+0xb3/0x1d0 kernel/time/timer.c:1803 + __do_softirq+0x1d0/0x9c8 kernel/softirq.c:571 + [...] + + +It triggers NULL pointer dereference when 'neigh->dev->dev_addr' is +called in the rose_send_frame(). It's the first occurrence of the +`neigh` is in rose_loopback_timer() as `rose_loopback_neigh', and +the 'dev' in 'rose_loopback_neigh' is initialized sa nullptr. + +It had been fixed by commit 3b3fd068c56e3fbea30090859216a368398e39bf +("rose: Fix Null pointer dereference in rose_send_frame()") ever. +But it's introduced by commit 3c53cd65dece47dd1f9d3a809f32e59d1d87b2b8 +("rose: check NULL rose_loopback_neigh->loopback") again. + +We fix it by add NULL check in rose_transmit_clear_request(). When +the 'dev' in 'neigh' is NULL, we don't reply the request and just +clear it. + +syzkaller don't provide repro, and I provide a syz repro like: +r0 = syz_init_net_socket$bt_sco(0x1f, 0x5, 0x2) +ioctl$sock_inet_SIOCSIFFLAGS(r0, 0x8914, &(0x7f0000000180)={'rose0\x00', 0x201}) +r1 = syz_init_net_socket$rose(0xb, 0x5, 0x0) +bind$rose(r1, &(0x7f00000000c0)=@full={0xb, @dev, @null, 0x0, [@null, @null, @netrom, @netrom, @default, @null]}, 0x40) +connect$rose(r1, &(0x7f0000000240)=@short={0xb, @dev={0xbb, 0xbb, 0xbb, 0x1, 0x0}, @remote={0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x1}, 0x1, @netrom={0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x0, 0x0}}, 0x1c) + +Fixes: 3c53cd65dece ("rose: check NULL rose_loopback_neigh->loopback") +Signed-off-by: Zhang Qilong +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/rose/rose_link.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c +index f6102e6f5161..730d2205f197 100644 +--- a/net/rose/rose_link.c ++++ b/net/rose/rose_link.c +@@ -236,6 +236,9 @@ void rose_transmit_clear_request(struct rose_neigh *neigh, unsigned int lci, uns + unsigned char *dptr; + int len; + ++ if (!neigh->dev) ++ return; ++ + len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3; + + if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL) +-- +2.35.1 + diff --git a/queue-5.15/series b/queue-5.15/series index 7b7c3c169af..4cc33183d09 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -13,3 +13,49 @@ hid-playstation-add-initial-dualsense-edge-controlle.patch kvm-x86-protect-the-unused-bits-in-msr-exiting-flags.patch kvm-x86-copy-filter-arg-outside-kvm_vm_ioctl_set_msr.patch kvm-x86-add-compat-handler-for-kvm_x86_set_msr_filte.patch +rdma-cma-use-output-interface-for-net_dev-check.patch +ib-hfi1-correctly-move-list-in-sc_disable.patch +rdma-hns-remove-magic-number.patch +rdma-hns-use-hr_reg_xxx-instead-of-remaining-roce_se.patch +rdma-hns-disable-local-invalidate-operation.patch +nfsv4-fix-a-potential-state-reclaim-deadlock.patch +nfsv4.1-handle-reclaim_complete-trunking-errors.patch +nfsv4.1-we-must-always-send-reclaim_complete-after-a.patch +sunrpc-fix-null-ptr-deref-when-xps-sysfs-alloc-faile.patch +nfsv4.2-fixup-clone-dest-file-size-for-zero-length-c.patch +nfs4-fix-kmemleak-when-allocate-slot-failed.patch +net-dsa-fix-possible-memory-leaks-in-dsa_loop_init.patch +rdma-core-fix-null-ptr-deref-in-ib_core_cleanup.patch +rdma-qedr-clean-up-work-queue-on-failure-in-qedr_all.patch +net-dsa-fall-back-to-default-tagger-if-we-can-t-load.patch +nfc-fdp-fix-potential-memory-leak-in-fdp_nci_send.patch +nfc-nxp-nci-fix-potential-memory-leak-in-nxp_nci_sen.patch +nfc-s3fwrn5-fix-potential-memory-leak-in-s3fwrn5_nci.patch +nfc-nfcmrvl-fix-potential-memory-leak-in-nfcmrvl_i2c.patch +net-fec-fix-improper-use-of-netdev_tx_busy.patch +ata-pata_legacy-fix-pdc20230_set_piomode.patch +net-sched-fix-use-after-free-in-red_enqueue.patch +net-tun-fix-bugs-for-oversize-packet-when-napi-frags.patch +netfilter-nf_tables-netlink-notifier-might-race-to-r.patch +netfilter-nf_tables-release-flow-rule-object-from-co.patch +ipvs-use-explicitly-signed-chars.patch +ipvs-fix-warning-in-__ip_vs_cleanup_batch.patch +ipvs-fix-warning-in-ip_vs_app_net_cleanup.patch +rose-fix-null-pointer-dereference-in-rose_send_frame.patch +misdn-fix-possible-memory-leak-in-misdn_register_dev.patch +isdn-misdn-netjet-fix-wrong-check-of-device-registra.patch +btrfs-fix-inode-list-leak-during-backref-walking-at-.patch +btrfs-fix-inode-list-leak-during-backref-walking-at-.patch-13284 +btrfs-fix-ulist-leaks-in-error-paths-of-qgroup-self-.patch +netfilter-ipset-enforce-documented-limit-to-prevent-.patch +bluetooth-l2cap-fix-use-after-free-caused-by-l2cap_r.patch +bluetooth-virtio_bt-use-skb_put-to-set-length.patch +bluetooth-l2cap-fix-use-after-free-in-l2cap_conn_del.patch +bluetooth-l2cap-fix-memory-leak-in-vhci_write.patch +net-mdio-fix-undefined-behavior-in-bit-shift-for-__m.patch +ibmvnic-free-rwi-on-reset-success.patch +stmmac-dwmac-loongson-fix-invalid-mdio_node.patch +net-smc-fix-possible-leaked-pernet-namespace-in-smc_.patch +net-neigh-fix-null-ptr-deref-in-neigh_table_clear.patch +ipv6-fix-warning-in-ip6_route_net_exit_late.patch +vsock-fix-possible-infinite-sleep-in-vsock_connectib.patch diff --git a/queue-5.15/stmmac-dwmac-loongson-fix-invalid-mdio_node.patch b/queue-5.15/stmmac-dwmac-loongson-fix-invalid-mdio_node.patch new file mode 100644 index 00000000000..dda34807661 --- /dev/null +++ b/queue-5.15/stmmac-dwmac-loongson-fix-invalid-mdio_node.patch @@ -0,0 +1,57 @@ +From 9a3a3fd21c5de00d4d646c6f38608e68f34732d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 14:02:18 +0800 +Subject: stmmac: dwmac-loongson: fix invalid mdio_node + +From: Liu Peibao + +[ Upstream commit 2ae34111fe4eebb69986f6490015b57c88804373 ] + +In current code "plat->mdio_node" is always NULL, the mdio +support is lost as there is no "mdio_bus_data". The original +driver could work as the "mdio" variable is never set to +false, which is described in commit ("stmmac: +dwmac-loongson: fix uninitialized variable ......"). And +after this commit merged, the "mdio" variable is always +false, causing the mdio supoort logic lost. + +Fixes: 30bba69d7db4 ("stmmac: pci: Add dwmac support for Loongson") +Signed-off-by: Liu Peibao +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20221101060218.16453-1-liupeibao@loongson.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +index ecf759ee1c9f..220bb454626c 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +@@ -51,7 +51,6 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id + struct stmmac_resources res; + struct device_node *np; + int ret, i, phy_mode; +- bool mdio = false; + + np = dev_of_node(&pdev->dev); + +@@ -69,12 +68,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id + if (!plat) + return -ENOMEM; + ++ plat->mdio_node = of_get_child_by_name(np, "mdio"); + if (plat->mdio_node) { +- dev_err(&pdev->dev, "Found MDIO subnode\n"); +- mdio = true; +- } ++ dev_info(&pdev->dev, "Found MDIO subnode\n"); + +- if (mdio) { + plat->mdio_bus_data = devm_kzalloc(&pdev->dev, + sizeof(*plat->mdio_bus_data), + GFP_KERNEL); +-- +2.35.1 + diff --git a/queue-5.15/sunrpc-fix-null-ptr-deref-when-xps-sysfs-alloc-faile.patch b/queue-5.15/sunrpc-fix-null-ptr-deref-when-xps-sysfs-alloc-faile.patch new file mode 100644 index 00000000000..77b527df2f0 --- /dev/null +++ b/queue-5.15/sunrpc-fix-null-ptr-deref-when-xps-sysfs-alloc-faile.patch @@ -0,0 +1,91 @@ +From 0e44c184ae168858847b67d7c149adbc66e2aad4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Oct 2022 11:42:17 +0800 +Subject: SUNRPC: Fix null-ptr-deref when xps sysfs alloc failed + +From: Zhang Xiaoxu + +[ Upstream commit cbdeaee94a415800c65a8c3fa04d9664a8b8fb3a ] + +There is a null-ptr-deref when xps sysfs alloc failed: + BUG: KASAN: null-ptr-deref in sysfs_do_create_link_sd+0x40/0xd0 + Read of size 8 at addr 0000000000000030 by task gssproxy/457 + + CPU: 5 PID: 457 Comm: gssproxy Not tainted 6.0.0-09040-g02357b27ee03 #9 + Call Trace: + + dump_stack_lvl+0x34/0x44 + kasan_report+0xa3/0x120 + sysfs_do_create_link_sd+0x40/0xd0 + rpc_sysfs_client_setup+0x161/0x1b0 + rpc_new_client+0x3fc/0x6e0 + rpc_create_xprt+0x71/0x220 + rpc_create+0x1d4/0x350 + gssp_rpc_create+0xc3/0x160 + set_gssp_clnt+0xbc/0x140 + write_gssp+0x116/0x1a0 + proc_reg_write+0xd6/0x130 + vfs_write+0x177/0x690 + ksys_write+0xb9/0x150 + do_syscall_64+0x35/0x80 + entry_SYSCALL_64_after_hwframe+0x46/0xb0 + +When the xprt_switch sysfs alloc failed, should not add xprt and +switch sysfs to it, otherwise, maybe null-ptr-deref; also initialize +the 'xps_sysfs' to NULL to avoid oops when destroy it. + +Fixes: 2a338a543163 ("sunrpc: add a symlink from rpc-client directory to the xprt_switch") +Fixes: d408ebe04ac5 ("sunrpc: add add sysfs directory per xprt under each xprt_switch") +Fixes: baea99445dd4 ("sunrpc: add xprt_switch direcotry to sunrpc's sysfs") +Signed-off-by: Zhang Xiaoxu +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + net/sunrpc/sysfs.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c +index a7020b1f3ec7..55da1b627a7d 100644 +--- a/net/sunrpc/sysfs.c ++++ b/net/sunrpc/sysfs.c +@@ -525,13 +525,16 @@ void rpc_sysfs_client_setup(struct rpc_clnt *clnt, + struct net *net) + { + struct rpc_sysfs_client *rpc_client; ++ struct rpc_sysfs_xprt_switch *xswitch = ++ (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; ++ ++ if (!xswitch) ++ return; + + rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj, + net, clnt->cl_clid); + if (rpc_client) { + char name[] = "switch"; +- struct rpc_sysfs_xprt_switch *xswitch = +- (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; + int ret; + + clnt->cl_sysfs = rpc_client; +@@ -565,6 +568,8 @@ void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch *xprt_switch, + rpc_xprt_switch->xprt_switch = xprt_switch; + rpc_xprt_switch->xprt = xprt; + kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD); ++ } else { ++ xprt_switch->xps_sysfs = NULL; + } + } + +@@ -576,6 +581,9 @@ void rpc_sysfs_xprt_setup(struct rpc_xprt_switch *xprt_switch, + struct rpc_sysfs_xprt_switch *switch_obj = + (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs; + ++ if (!switch_obj) ++ return; ++ + rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags); + if (rpc_xprt) { + xprt->xprt_sysfs = rpc_xprt; +-- +2.35.1 + diff --git a/queue-5.15/vsock-fix-possible-infinite-sleep-in-vsock_connectib.patch b/queue-5.15/vsock-fix-possible-infinite-sleep-in-vsock_connectib.patch new file mode 100644 index 00000000000..ba0427cc6c6 --- /dev/null +++ b/queue-5.15/vsock-fix-possible-infinite-sleep-in-vsock_connectib.patch @@ -0,0 +1,49 @@ +From 0d69a2d8cd23f6cb6faea2f4c780a41dd73341ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Oct 2022 19:17:06 -0700 +Subject: vsock: fix possible infinite sleep in vsock_connectible_wait_data() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Dexuan Cui + +[ Upstream commit 466a85336fee6e3b35eb97b8405a28302fd25809 ] + +Currently vsock_connectible_has_data() may miss a wakeup operation +between vsock_connectible_has_data() == 0 and the prepare_to_wait(). + +Fix the race by adding the process to the wait queue before checking +vsock_connectible_has_data(). + +Fixes: b3f7fd54881b ("af_vsock: separate wait data loop") +Signed-off-by: Dexuan Cui +Reviewed-by: Stefano Garzarella +Reported-by: Frédéric Dalleau +Tested-by: Frédéric Dalleau +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/vmw_vsock/af_vsock.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 5d46036f3ad7..dc36a46ce0e7 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -1897,8 +1897,11 @@ static int vsock_connectible_wait_data(struct sock *sk, + err = 0; + transport = vsk->transport; + +- while ((data = vsock_connectible_has_data(vsk)) == 0) { ++ while (1) { + prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE); ++ data = vsock_connectible_has_data(vsk); ++ if (data != 0) ++ break; + + if (sk->sk_err != 0 || + (sk->sk_shutdown & RCV_SHUTDOWN) || +-- +2.35.1 +