Recreate RHEL 5.14.0-687.10.1 from CS9/upstream backports
Drop the 687.5.3/687.5.4 security-ahead patches superseded by the RHEL 687.6.1..687.10.1 backports (1100-1104), and add those backports (1100-1196) sourced from centos-stream-9 and upstream stable. Keep the AlmaLinux-ahead smb cifs.spnego fix (retained as 1197). Bump to 5.14.0-687.10.1.
This commit is contained in:
parent
53ec6c7fe3
commit
5c58271075
@ -0,0 +1,167 @@
|
||||
From 07bcb984353e8e436251bdc10804e952fec12943 Mon Sep 17 00:00:00 2001
|
||||
From: Kamal Heib <kheib@redhat.com>
|
||||
Date: Mon, 13 Apr 2026 13:56:58 -0400
|
||||
Subject: [PATCH] rtnetlink: Allocate vfinfo size for VF GUIDs when supported
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-167866
|
||||
|
||||
CVE: CVE-2025-22075
|
||||
|
||||
commit 23f00807619d15063d676218f36c5dfeda1eb420
|
||||
Author: Mark Zhang <markzhang@nvidia.com>
|
||||
Date: Tue Mar 25 11:02:26 2025 +0200
|
||||
|
||||
rtnetlink: Allocate vfinfo size for VF GUIDs when supported
|
||||
|
||||
Commit 30aad41721e0 ("net/core: Add support for getting VF GUIDs")
|
||||
added support for getting VF port and node GUIDs in netlink ifinfo
|
||||
messages, but their size was not taken into consideration in the
|
||||
function that allocates the netlink message, causing the following
|
||||
warning when a netlink message is filled with many VF port and node
|
||||
GUIDs:
|
||||
# echo 64 > /sys/bus/pci/devices/0000\:08\:00.0/sriov_numvfs
|
||||
# ip link show dev ib0
|
||||
RTNETLINK answers: Message too long
|
||||
Cannot send link get request: Message too long
|
||||
|
||||
Kernel warning:
|
||||
|
||||
------------[ cut here ]------------
|
||||
WARNING: CPU: 2 PID: 1930 at net/core/rtnetlink.c:4151 rtnl_getlink+0x586/0x5a0
|
||||
Modules linked in: xt_conntrack xt_MASQUERADE nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter overlay mlx5_ib macsec mlx5_core tls rpcrdma rdma_ucm ib_uverbs ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm iw_cm ib_ipoib fuse ib_cm ib_core
|
||||
CPU: 2 UID: 0 PID: 1930 Comm: ip Not tainted 6.14.0-rc2+ #1
|
||||
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
|
||||
RIP: 0010:rtnl_getlink+0x586/0x5a0
|
||||
Code: cb 82 e8 3d af 0a 00 4d 85 ff 0f 84 08 ff ff ff 4c 89 ff 41 be ea ff ff ff e8 66 63 5b ff 49 c7 07 80 4f cb 82 e9 36 fc ff ff <0f> 0b e9 16 fe ff ff e8 de a0 56 00 66 66 2e 0f 1f 84 00 00 00 00
|
||||
RSP: 0018:ffff888113557348 EFLAGS: 00010246
|
||||
RAX: 00000000ffffffa6 RBX: ffff88817e87aa34 RCX: dffffc0000000000
|
||||
RDX: 0000000000000003 RSI: 0000000000000000 RDI: ffff88817e87afb8
|
||||
RBP: 0000000000000009 R08: ffffffff821f44aa R09: 0000000000000000
|
||||
R10: ffff8881260f79a8 R11: ffff88817e87af00 R12: ffff88817e87aa00
|
||||
R13: ffffffff8563d300 R14: 00000000ffffffa6 R15: 00000000ffffffff
|
||||
FS: 00007f63a5dbf280(0000) GS:ffff88881ee00000(0000) knlGS:0000000000000000
|
||||
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
CR2: 00007f63a5ba4493 CR3: 00000001700fe002 CR4: 0000000000772eb0
|
||||
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||
PKRU: 55555554
|
||||
Call Trace:
|
||||
<TASK>
|
||||
? __warn+0xa5/0x230
|
||||
? rtnl_getlink+0x586/0x5a0
|
||||
? report_bug+0x22d/0x240
|
||||
? handle_bug+0x53/0xa0
|
||||
? exc_invalid_op+0x14/0x50
|
||||
? asm_exc_invalid_op+0x16/0x20
|
||||
? skb_trim+0x6a/0x80
|
||||
? rtnl_getlink+0x586/0x5a0
|
||||
? __pfx_rtnl_getlink+0x10/0x10
|
||||
? rtnetlink_rcv_msg+0x1e5/0x860
|
||||
? __pfx___mutex_lock+0x10/0x10
|
||||
? rcu_is_watching+0x34/0x60
|
||||
? __pfx_lock_acquire+0x10/0x10
|
||||
? stack_trace_save+0x90/0xd0
|
||||
? filter_irq_stacks+0x1d/0x70
|
||||
? kasan_save_stack+0x30/0x40
|
||||
? kasan_save_stack+0x20/0x40
|
||||
? kasan_save_track+0x10/0x30
|
||||
rtnetlink_rcv_msg+0x21c/0x860
|
||||
? entry_SYSCALL_64_after_hwframe+0x76/0x7e
|
||||
? __pfx_rtnetlink_rcv_msg+0x10/0x10
|
||||
? arch_stack_walk+0x9e/0xf0
|
||||
? rcu_is_watching+0x34/0x60
|
||||
? lock_acquire+0xd5/0x410
|
||||
? rcu_is_watching+0x34/0x60
|
||||
netlink_rcv_skb+0xe0/0x210
|
||||
? __pfx_rtnetlink_rcv_msg+0x10/0x10
|
||||
? __pfx_netlink_rcv_skb+0x10/0x10
|
||||
? rcu_is_watching+0x34/0x60
|
||||
? __pfx___netlink_lookup+0x10/0x10
|
||||
? lock_release+0x62/0x200
|
||||
? netlink_deliver_tap+0xfd/0x290
|
||||
? rcu_is_watching+0x34/0x60
|
||||
? lock_release+0x62/0x200
|
||||
? netlink_deliver_tap+0x95/0x290
|
||||
netlink_unicast+0x31f/0x480
|
||||
? __pfx_netlink_unicast+0x10/0x10
|
||||
? rcu_is_watching+0x34/0x60
|
||||
? lock_acquire+0xd5/0x410
|
||||
netlink_sendmsg+0x369/0x660
|
||||
? lock_release+0x62/0x200
|
||||
? __pfx_netlink_sendmsg+0x10/0x10
|
||||
? import_ubuf+0xb9/0xf0
|
||||
? __import_iovec+0x254/0x2b0
|
||||
? lock_release+0x62/0x200
|
||||
? __pfx_netlink_sendmsg+0x10/0x10
|
||||
____sys_sendmsg+0x559/0x5a0
|
||||
? __pfx_____sys_sendmsg+0x10/0x10
|
||||
? __pfx_copy_msghdr_from_user+0x10/0x10
|
||||
? rcu_is_watching+0x34/0x60
|
||||
? do_read_fault+0x213/0x4a0
|
||||
? rcu_is_watching+0x34/0x60
|
||||
___sys_sendmsg+0xe4/0x150
|
||||
? __pfx____sys_sendmsg+0x10/0x10
|
||||
? do_fault+0x2cc/0x6f0
|
||||
? handle_pte_fault+0x2e3/0x3d0
|
||||
? __pfx_handle_pte_fault+0x10/0x10
|
||||
? preempt_count_sub+0x14/0xc0
|
||||
? __down_read_trylock+0x150/0x270
|
||||
? __handle_mm_fault+0x404/0x8e0
|
||||
? __pfx___handle_mm_fault+0x10/0x10
|
||||
? lock_release+0x62/0x200
|
||||
? __rcu_read_unlock+0x65/0x90
|
||||
? rcu_is_watching+0x34/0x60
|
||||
__sys_sendmsg+0xd5/0x150
|
||||
? __pfx___sys_sendmsg+0x10/0x10
|
||||
? __up_read+0x192/0x480
|
||||
? lock_release+0x62/0x200
|
||||
? __rcu_read_unlock+0x65/0x90
|
||||
? rcu_is_watching+0x34/0x60
|
||||
do_syscall_64+0x6d/0x140
|
||||
entry_SYSCALL_64_after_hwframe+0x76/0x7e
|
||||
RIP: 0033:0x7f63a5b13367
|
||||
Code: 0e 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10
|
||||
RSP: 002b:00007fff8c726bc8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
|
||||
RAX: ffffffffffffffda RBX: 0000000067b687c2 RCX: 00007f63a5b13367
|
||||
RDX: 0000000000000000 RSI: 00007fff8c726c30 RDI: 0000000000000004
|
||||
RBP: 00007fff8c726cb8 R08: 0000000000000000 R09: 0000000000000034
|
||||
R10: 00007fff8c726c7c R11: 0000000000000246 R12: 0000000000000001
|
||||
R13: 0000000000000000 R14: 00007fff8c726cd0 R15: 00007fff8c726cd0
|
||||
</TASK>
|
||||
irq event stamp: 0
|
||||
hardirqs last enabled at (0): [<0000000000000000>] 0x0
|
||||
hardirqs last disabled at (0): [<ffffffff813f9e58>] copy_process+0xd08/0x2830
|
||||
softirqs last enabled at (0): [<ffffffff813f9e58>] copy_process+0xd08/0x2830
|
||||
softirqs last disabled at (0): [<0000000000000000>] 0x0
|
||||
---[ end trace 0000000000000000 ]---
|
||||
|
||||
Thus, when calculating ifinfo message size, take VF GUIDs sizes into
|
||||
account when supported.
|
||||
|
||||
Fixes: 30aad41721e0 ("net/core: Add support for getting VF GUIDs")
|
||||
Signed-off-by: Mark Zhang <markzhang@nvidia.com>
|
||||
Reviewed-by: Maher Sanalla <msanalla@nvidia.com>
|
||||
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
|
||||
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
|
||||
Link: https://patch.msgid.link/20250325090226.749730-1-mbloch@nvidia.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
Signed-off-by: Kamal Heib <kheib@redhat.com>
|
||||
|
||||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
|
||||
index e58604891437..cf61b887c5fc 100644
|
||||
--- a/net/core/rtnetlink.c
|
||||
+++ b/net/core/rtnetlink.c
|
||||
@@ -1005,6 +1005,9 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
|
||||
/* IFLA_VF_STATS_TX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)));
|
||||
}
|
||||
+ if (dev->netdev_ops->ndo_get_vf_guid)
|
||||
+ size += num_vfs * 2 *
|
||||
+ nla_total_size(sizeof(struct ifla_vf_guid));
|
||||
return size;
|
||||
} else
|
||||
return 0;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
From: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
Subject: [PATCH AlmaLinux 9] xfrm: esp: avoid in-place decrypt on shared skb frags
|
||||
|
||||
Backport of upstream commit f4c50a4034e6 ("xfrm: esp: avoid in-place
|
||||
decrypt on shared skb frags") for AlmaLinux 9 (5.14 kernel).
|
||||
|
||||
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no rejects)
|
||||
against kernel-5.14.0-611.54.1.el9_7.
|
||||
|
||||
ESP-in-UDP packets built from caller-owned pages (e.g. pipe pages
|
||||
attached via udp_sendpage(2) -> ip_append_page() -> skb_append_pagefrags())
|
||||
look like ordinary uncloned nonlinear skbs. ESP input then takes the
|
||||
no-COW fast path and decrypts in place over data that is not owned
|
||||
privately by the skb.
|
||||
|
||||
Tree adaptation:
|
||||
* Upstream patches __ip_append_data() / __ip6_append_data(), the
|
||||
MSG_SPLICE_PAGES branch added by 7da0dde68486 / 6d8192bd69bb.
|
||||
That feature has not been wired into UDP send paths on this tree
|
||||
(no caller of skb_splice_from_iter in net/ipv{4,6}/).
|
||||
* The age-equivalent producer is ip_append_page() (udp_sendpage).
|
||||
Mark frags there with SKBFL_SHARED_FRAG so skb_has_shared_frag()
|
||||
fires for these skbs.
|
||||
* UDPv6 has no .sendpage op in this tree, so the esp6 hunk is
|
||||
defense-in-depth in case a later backport adds one.
|
||||
* The esp4/esp6 receiver-side hunks are taken verbatim from
|
||||
upstream.
|
||||
|
||||
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
|
||||
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
|
||||
(cherry picked from commit f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4)
|
||||
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
---
|
||||
net/ipv4/esp4.c | 3 ++-
|
||||
net/ipv4/ip_output.c | 2 ++
|
||||
net/ipv6/esp6.c | 3 ++-
|
||||
3 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/net/ipv4/esp4.c
|
||||
+++ b/net/ipv4/esp4.c
|
||||
@@ -920,7 +920,8 @@
|
||||
nfrags = 1;
|
||||
|
||||
goto skip_cow;
|
||||
- } else if (!skb_has_frag_list(skb)) {
|
||||
+ } else if (!skb_has_frag_list(skb) &&
|
||||
+ !skb_has_shared_frag(skb)) {
|
||||
nfrags = skb_shinfo(skb)->nr_frags;
|
||||
nfrags++;
|
||||
|
||||
--- a/net/ipv4/ip_output.c
|
||||
+++ b/net/ipv4/ip_output.c
|
||||
@@ -1467,6 +1467,8 @@
|
||||
err = -EMSGSIZE;
|
||||
goto error;
|
||||
}
|
||||
+ if (!(flags & MSG_NO_SHARED_FRAGS))
|
||||
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_NONE) {
|
||||
__wsum csum;
|
||||
--- a/net/ipv6/esp6.c
|
||||
+++ b/net/ipv6/esp6.c
|
||||
@@ -960,7 +960,8 @@
|
||||
nfrags = 1;
|
||||
|
||||
goto skip_cow;
|
||||
- } else if (!skb_has_frag_list(skb)) {
|
||||
+ } else if (!skb_has_frag_list(skb) &&
|
||||
+ !skb_has_shared_frag(skb)) {
|
||||
nfrags = skb_shinfo(skb)->nr_frags;
|
||||
nfrags++;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
@ -0,0 +1,97 @@
|
||||
From be8f678b4eaf729472075519c05dc8a70ae4b072 Mon Sep 17 00:00:00 2001
|
||||
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
Date: Fri, 10 Apr 2026 08:59:49 +0000
|
||||
Subject: [PATCH] net/sched: Make cake_enqueue return NET_XMIT_CN when past
|
||||
buffer_limit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-166730
|
||||
CVE: CVE-2025-39766
|
||||
|
||||
commit 15de71d06a400f7fdc15bf377a2552b0ec437cf5
|
||||
Author: William Liu <will@willsroot.io>
|
||||
Date: Tue Aug 19 03:36:28 2025 +0000
|
||||
|
||||
net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit
|
||||
|
||||
The following setup can trigger a WARNING in htb_activate due to
|
||||
the condition: !cl->leaf.q->q.qlen
|
||||
|
||||
tc qdisc del dev lo root
|
||||
tc qdisc add dev lo root handle 1: htb default 1
|
||||
tc class add dev lo parent 1: classid 1:1 \
|
||||
htb rate 64bit
|
||||
tc qdisc add dev lo parent 1:1 handle f: \
|
||||
cake memlimit 1b
|
||||
ping -I lo -f -c1 -s64 -W0.001 127.0.0.1
|
||||
|
||||
This is because the low memlimit leads to a low buffer_limit, which
|
||||
causes packet dropping. However, cake_enqueue still returns
|
||||
NET_XMIT_SUCCESS, causing htb_enqueue to call htb_activate with an
|
||||
empty child qdisc. We should return NET_XMIT_CN when packets are
|
||||
dropped from the same tin and flow.
|
||||
|
||||
I do not believe return value of NET_XMIT_CN is necessary for packet
|
||||
drops in the case of ack filtering, as that is meant to optimize
|
||||
performance, not to signal congestion.
|
||||
|
||||
Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc")
|
||||
Signed-off-by: William Liu <will@willsroot.io>
|
||||
Reviewed-by: Savino Dicanosa <savy@syst3mfailure.io>
|
||||
Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
|
||||
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
|
||||
Link: https://patch.msgid.link/20250819033601.579821-1-will@willsroot.io
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
|
||||
diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
|
||||
index 48dd8c88903f..aa9f31e4415a 100644
|
||||
--- a/net/sched/sch_cake.c
|
||||
+++ b/net/sched/sch_cake.c
|
||||
@@ -1747,7 +1747,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
ktime_t now = ktime_get();
|
||||
struct cake_tin_data *b;
|
||||
struct cake_flow *flow;
|
||||
- u32 idx;
|
||||
+ u32 idx, tin;
|
||||
|
||||
/* choose flow to insert into */
|
||||
idx = cake_classify(sch, &b, skb, q->flow_mode, &ret);
|
||||
@@ -1757,6 +1757,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
__qdisc_drop(skb, to_free);
|
||||
return ret;
|
||||
}
|
||||
+ tin = (u32)(b - q->tins);
|
||||
idx--;
|
||||
flow = &b->flows[idx];
|
||||
|
||||
@@ -1924,13 +1925,22 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
q->buffer_max_used = q->buffer_used;
|
||||
|
||||
if (q->buffer_used > q->buffer_limit) {
|
||||
+ bool same_flow = false;
|
||||
u32 dropped = 0;
|
||||
+ u32 drop_id;
|
||||
|
||||
while (q->buffer_used > q->buffer_limit) {
|
||||
dropped++;
|
||||
- cake_drop(sch, to_free);
|
||||
+ drop_id = cake_drop(sch, to_free);
|
||||
+
|
||||
+ if ((drop_id >> 16) == tin &&
|
||||
+ (drop_id & 0xFFFF) == idx)
|
||||
+ same_flow = true;
|
||||
}
|
||||
b->drop_overlimit += dropped;
|
||||
+
|
||||
+ if (same_flow)
|
||||
+ return NET_XMIT_CN;
|
||||
}
|
||||
return NET_XMIT_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
From: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
Subject: [PATCH AlmaLinux 9] rxrpc: linearize incoming DATA packet when it has paged frags
|
||||
|
||||
AlmaLinux-specific backport of the intent of the upstream rxrpc fix
|
||||
posted at https://lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/
|
||||
(sibling to upstream commit f4c50a4034e6 in the ESP/xfrm subsystem).
|
||||
|
||||
The upstream patch can not be cherry-picked against this 5.14 tree:
|
||||
its target lines were introduced by upstream commit d0d5c0cd1e71
|
||||
("rxrpc: Use skb_unshare() rather than skb_cow_data()") which is not
|
||||
present here. The age-equivalent code path on AlmaLinux 9 is the
|
||||
centralized skb_unshare() in net/rxrpc/io_thread.c that is run for
|
||||
every DATA packet with a non-zero securityIndex before in-place
|
||||
decryption.
|
||||
|
||||
skb_unshare() only handles cloned skbs. An skb that is non-cloned but
|
||||
carries paged fragments (skb->data_len != 0) — e.g. pages attached via
|
||||
udp_sendpage() / splice() / MSG_SPLICE_PAGES on a UDP socket carrying
|
||||
rxrpc traffic — slips through and is decrypted in place over data the
|
||||
skb does not own privately. With kernel-modules-partner installed
|
||||
(rxrpc.ko enabled), this is exploitable.
|
||||
|
||||
Replace the unconditional skb_unshare() with skb_copy() whenever the
|
||||
skb is cloned OR carries paged fragments. skb_copy() always returns a
|
||||
freshly allocated linear skb, so subsequent in-place decryption only
|
||||
touches kernel-owned memory. The original skb is consumed explicitly
|
||||
(skb_unshare did this internally via consume_skb()).
|
||||
|
||||
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no
|
||||
rejects) against kernel-5.14.0-611.54.1.el9_7.
|
||||
|
||||
Fixes: cac2661c53f3 ("rxrpc: Use skb_cow_data() in rxrpc_recvmsg_data()")
|
||||
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
---
|
||||
net/rxrpc/io_thread.c | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/net/rxrpc/io_thread.c
|
||||
+++ b/net/rxrpc/io_thread.c
|
||||
@@ -225,16 +225,18 @@
|
||||
* decryption.
|
||||
*/
|
||||
if (sp->hdr.securityIndex != 0) {
|
||||
- skb = skb_unshare(skb, GFP_ATOMIC);
|
||||
- if (!skb) {
|
||||
- rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare_nomem);
|
||||
- *_skb = NULL;
|
||||
- return just_discard;
|
||||
- }
|
||||
+ if (skb_cloned(skb) || skb->data_len) {
|
||||
+ struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
|
||||
+
|
||||
+ if (!nskb) {
|
||||
+ rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare_nomem);
|
||||
+ return just_discard;
|
||||
+ }
|
||||
|
||||
- if (skb != *_skb) {
|
||||
rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare);
|
||||
- *_skb = skb;
|
||||
+ consume_skb(*_skb);
|
||||
+ *_skb = nskb;
|
||||
+ skb = nskb;
|
||||
rxrpc_new_skb(skb, rxrpc_skb_new_unshared);
|
||||
sp = rxrpc_skb(skb);
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
@ -0,0 +1,162 @@
|
||||
From d7f88307eaa11490b3ad24647bdf96922504fd5e Mon Sep 17 00:00:00 2001
|
||||
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
Date: Fri, 10 Apr 2026 08:59:50 +0000
|
||||
Subject: [PATCH] net/sched: sch_cake: Fix incorrect qlen reduction in
|
||||
cake_drop
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-166730
|
||||
CVE: CVE-2025-39766
|
||||
|
||||
commit 9fefc78f7f02d71810776fdeb119a05a946a27cc
|
||||
Author: Xiang Mei <xmei5@asu.edu>
|
||||
Date: Thu Nov 27 17:14:14 2025 -0700
|
||||
|
||||
net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop
|
||||
|
||||
In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen
|
||||
and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes
|
||||
that the parent qdisc will enqueue the current packet. However, this
|
||||
assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent
|
||||
qdisc stops enqueuing current packet, leaving the tree qlen/backlog
|
||||
accounting inconsistent. This mismatch can lead to a NULL dereference
|
||||
(e.g., when the parent Qdisc is qfq_qdisc).
|
||||
|
||||
This patch computes the qlen/backlog delta in a more robust way by
|
||||
observing the difference before and after the series of cake_drop()
|
||||
calls, and then compensates the qdisc tree accounting if cake_enqueue()
|
||||
returns NET_XMIT_CN.
|
||||
|
||||
To ensure correct compensation when ACK thinning is enabled, a new
|
||||
variable is introduced to keep qlen unchanged.
|
||||
|
||||
Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit")
|
||||
Signed-off-by: Xiang Mei <xmei5@asu.edu>
|
||||
Reviewed-by: Toke Høiland-Jørgensen <toke@toke.dk>
|
||||
Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
|
||||
diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
|
||||
index aa9f31e4415a..ef51a9e0f621 100644
|
||||
--- a/net/sched/sch_cake.c
|
||||
+++ b/net/sched/sch_cake.c
|
||||
@@ -1594,7 +1594,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
|
||||
|
||||
qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_OVERLIMIT);
|
||||
sch->q.qlen--;
|
||||
- qdisc_tree_reduce_backlog(sch, 1, len);
|
||||
|
||||
cake_heapify(q, 0);
|
||||
|
||||
@@ -1740,14 +1739,14 @@ static void cake_reconfigure(struct Qdisc *sch);
|
||||
static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
struct sk_buff **to_free)
|
||||
{
|
||||
+ u32 idx, tin, prev_qlen, prev_backlog, drop_id;
|
||||
struct cake_sched_data *q = qdisc_priv(sch);
|
||||
- int len = qdisc_pkt_len(skb);
|
||||
- int ret;
|
||||
+ int len = qdisc_pkt_len(skb), ret;
|
||||
struct sk_buff *ack = NULL;
|
||||
ktime_t now = ktime_get();
|
||||
struct cake_tin_data *b;
|
||||
struct cake_flow *flow;
|
||||
- u32 idx, tin;
|
||||
+ bool same_flow = false;
|
||||
|
||||
/* choose flow to insert into */
|
||||
idx = cake_classify(sch, &b, skb, q->flow_mode, &ret);
|
||||
@@ -1820,6 +1819,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
consume_skb(skb);
|
||||
} else {
|
||||
/* not splitting */
|
||||
+ int ack_pkt_len = 0;
|
||||
+
|
||||
cobalt_set_enqueue_time(skb, now);
|
||||
get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb);
|
||||
flow_queue_add(flow, skb);
|
||||
@@ -1830,13 +1831,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
if (ack) {
|
||||
b->ack_drops++;
|
||||
sch->qstats.drops++;
|
||||
- b->bytes += qdisc_pkt_len(ack);
|
||||
- len -= qdisc_pkt_len(ack);
|
||||
+ ack_pkt_len = qdisc_pkt_len(ack);
|
||||
+ b->bytes += ack_pkt_len;
|
||||
q->buffer_used += skb->truesize - ack->truesize;
|
||||
if (q->rate_flags & CAKE_FLAG_INGRESS)
|
||||
cake_advance_shaper(q, b, ack, now, true);
|
||||
|
||||
- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack));
|
||||
+ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len);
|
||||
consume_skb(ack);
|
||||
} else {
|
||||
sch->q.qlen++;
|
||||
@@ -1845,11 +1846,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
|
||||
/* stats */
|
||||
b->packets++;
|
||||
- b->bytes += len;
|
||||
- b->backlogs[idx] += len;
|
||||
- b->tin_backlog += len;
|
||||
- sch->qstats.backlog += len;
|
||||
- q->avg_window_bytes += len;
|
||||
+ b->bytes += len - ack_pkt_len;
|
||||
+ b->backlogs[idx] += len - ack_pkt_len;
|
||||
+ b->tin_backlog += len - ack_pkt_len;
|
||||
+ sch->qstats.backlog += len - ack_pkt_len;
|
||||
+ q->avg_window_bytes += len - ack_pkt_len;
|
||||
}
|
||||
|
||||
if (q->overflow_timeout)
|
||||
@@ -1924,24 +1925,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
if (q->buffer_used > q->buffer_max_used)
|
||||
q->buffer_max_used = q->buffer_used;
|
||||
|
||||
- if (q->buffer_used > q->buffer_limit) {
|
||||
- bool same_flow = false;
|
||||
- u32 dropped = 0;
|
||||
- u32 drop_id;
|
||||
+ if (q->buffer_used <= q->buffer_limit)
|
||||
+ return NET_XMIT_SUCCESS;
|
||||
|
||||
- while (q->buffer_used > q->buffer_limit) {
|
||||
- dropped++;
|
||||
- drop_id = cake_drop(sch, to_free);
|
||||
+ prev_qlen = sch->q.qlen;
|
||||
+ prev_backlog = sch->qstats.backlog;
|
||||
|
||||
- if ((drop_id >> 16) == tin &&
|
||||
- (drop_id & 0xFFFF) == idx)
|
||||
- same_flow = true;
|
||||
- }
|
||||
- b->drop_overlimit += dropped;
|
||||
+ while (q->buffer_used > q->buffer_limit) {
|
||||
+ drop_id = cake_drop(sch, to_free);
|
||||
+ if ((drop_id >> 16) == tin &&
|
||||
+ (drop_id & 0xFFFF) == idx)
|
||||
+ same_flow = true;
|
||||
+ }
|
||||
+
|
||||
+ prev_qlen -= sch->q.qlen;
|
||||
+ prev_backlog -= sch->qstats.backlog;
|
||||
+ b->drop_overlimit += prev_qlen;
|
||||
|
||||
- if (same_flow)
|
||||
- return NET_XMIT_CN;
|
||||
+ if (same_flow) {
|
||||
+ qdisc_tree_reduce_backlog(sch, prev_qlen - 1,
|
||||
+ prev_backlog - len);
|
||||
+ return NET_XMIT_CN;
|
||||
}
|
||||
+ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog);
|
||||
return NET_XMIT_SUCCESS;
|
||||
}
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -1,145 +0,0 @@
|
||||
From: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
Subject: [PATCH AlmaLinux 9] net: skbuff: propagate shared-frag marker through frag-transfer helpers
|
||||
|
||||
Backport of upstream v5 patch posted at
|
||||
https://lore.kernel.org/all/ageeJfJHwgzmKXbh@v4bel/
|
||||
(sibling to upstream commit f4c50a4034e6 "xfrm: esp: avoid in-place
|
||||
decrypt on shared skb frags").
|
||||
|
||||
Three frag-transfer helpers in net/core/skbuff.c
|
||||
(__pskb_copy_fclone(), skb_try_coalesce(), skb_shift()), the GRO
|
||||
accumulator path in net/core/gro.c (skb_gro_receive()) and the UDP
|
||||
GRO list helper in net/ipv4/udp_offload.c (skb_gro_receive_list(),
|
||||
kept as a static helper on AlmaLinux 9) fail to propagate the
|
||||
SKBFL_SHARED_FRAG bit in skb_shinfo()->flags when moving frag
|
||||
descriptors from source to destination. In addition, skb_segment()
|
||||
folds only head_skb's flag into nskb on the per-iteration flag
|
||||
merge, and the inner switch that rebinds frag_skb to list_skb on
|
||||
head_skb-frags exhaustion does not fold the new frag_skb's flag
|
||||
into nskb. As a result, the destination skb keeps a reference to
|
||||
the same externally-owned or page-cache-backed pages while reporting
|
||||
skb_has_shared_frag() as false.
|
||||
|
||||
The mismatch is harmful in any in-place writer that uses
|
||||
skb_has_shared_frag() to decide whether shared pages must be detoured
|
||||
through skb_cow_data(). ESP input is one such writer (esp4.c,
|
||||
esp6.c). Combined with an nft 'dup to <local>' rule, an
|
||||
nf_dup_ipv4() / xt_TEE caller, or ESP-over-UDP with UDP GRO, this
|
||||
lets an unprivileged user write into the page cache of a root-owned
|
||||
read-only file via authencesn-ESN stray writes (CVE-2026-46300,
|
||||
"Fragnesia").
|
||||
|
||||
Set SKBFL_SHARED_FRAG on the destination whenever frag descriptors
|
||||
were actually moved from the source. skb_copy() and skb_copy_expand()
|
||||
share skb_copy_header() too but linearize all paged data into freshly
|
||||
allocated head storage and emerge with nr_frags == 0, so
|
||||
skb_has_shared_frag() returns false on its own; they need no change.
|
||||
tcp_clone_payload() does not exist in 5.14; no equivalent hunk
|
||||
applies.
|
||||
|
||||
The same omission exists in skb_gro_receive() and
|
||||
skb_gro_receive_list(). The former moves the incoming skb's frag
|
||||
descriptors into the accumulator's last sub-skb via two paths plus a
|
||||
"merge:" fallback that chains the whole skb onto frag_list; the
|
||||
latter chains the incoming skb whole onto p's frag_list. Downstream
|
||||
skb_segment() reads only skb_shinfo(p)->flags, and skb_segment_list()
|
||||
reuses each sub-skb's shinfo as the nskb -- both p and lp must carry
|
||||
the marker.
|
||||
|
||||
Tree adaptation:
|
||||
* Upstream v5 places skb_gro_receive_list() in net/core/gro.c.
|
||||
AlmaLinux 9 still keeps it as a static helper in
|
||||
net/ipv4/udp_offload.c (it has not been promoted to a global
|
||||
GRO helper in this tree). Apply the propagation hunk there
|
||||
instead.
|
||||
* Upstream tcp_clone_payload() was added in v6.5 (commit
|
||||
808599b88c93); 5.14 has no such helper, so the corresponding v5
|
||||
hunk is omitted.
|
||||
|
||||
Fixes: cef401de7be8 ("net: fix possible wrong checksum generation")
|
||||
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
|
||||
Reported-by: Sultan Alsawaf <sultan@kerneltoast.com>
|
||||
Reported-by: William Bowling <vakzz@zellic.io>
|
||||
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
|
||||
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
---
|
||||
net/core/gro.c | 2 ++
|
||||
net/core/skbuff.c | 12 ++++++++++++
|
||||
net/ipv4/udp_offload.c | 2 ++
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
--- a/net/core/skbuff.c 2026-05-28 12:54:14.127155793 +0200
|
||||
+++ b/net/core/skbuff.c 2026-05-28 12:57:03.811526691 +0200
|
||||
@@ -2027,6 +2027,7 @@
|
||||
skb_frag_ref(skb, i);
|
||||
}
|
||||
skb_shinfo(n)->nr_frags = i;
|
||||
+ skb_shinfo(n)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
|
||||
}
|
||||
|
||||
if (skb_has_frag_list(skb)) {
|
||||
@@ -4029,6 +4030,8 @@
|
||||
tgt->ip_summed = CHECKSUM_PARTIAL;
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
|
||||
+ skb_shinfo(tgt)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
|
||||
+
|
||||
/* Yak, is it really working this way? Some helper please? */
|
||||
skb->len -= shiftlen;
|
||||
skb->data_len -= shiftlen;
|
||||
@@ -4604,7 +4607,8 @@
|
||||
skb_copy_from_linear_data_offset(head_skb, offset,
|
||||
skb_put(nskb, hsize), hsize);
|
||||
|
||||
- skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags &
|
||||
+ skb_shinfo(nskb)->flags |= (skb_shinfo(head_skb)->flags |
|
||||
+ skb_shinfo(frag_skb)->flags) &
|
||||
SKBFL_SHARED_FRAG;
|
||||
|
||||
if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC))
|
||||
@@ -4621,6 +4625,10 @@
|
||||
nfrags = skb_shinfo(list_skb)->nr_frags;
|
||||
frag = skb_shinfo(list_skb)->frags;
|
||||
frag_skb = list_skb;
|
||||
+
|
||||
+ skb_shinfo(nskb)->flags |= skb_shinfo(frag_skb)->flags &
|
||||
+ SKBFL_SHARED_FRAG;
|
||||
+
|
||||
if (!skb_headlen(list_skb)) {
|
||||
BUG_ON(!nfrags);
|
||||
} else {
|
||||
@@ -5741,6 +5749,8 @@
|
||||
from_shinfo->frags,
|
||||
from_shinfo->nr_frags * sizeof(skb_frag_t));
|
||||
to_shinfo->nr_frags += from_shinfo->nr_frags;
|
||||
+ if (from_shinfo->nr_frags)
|
||||
+ to_shinfo->flags |= from_shinfo->flags & SKBFL_SHARED_FRAG;
|
||||
|
||||
if (!skb_cloned(from))
|
||||
from_shinfo->nr_frags = 0;
|
||||
--- a/net/core/gro.c 2026-05-28 12:54:14.126244251 +0200
|
||||
+++ b/net/core/gro.c 2026-05-28 12:57:12.210673266 +0200
|
||||
@@ -222,10 +222,12 @@
|
||||
p->data_len += len;
|
||||
p->truesize += delta_truesize;
|
||||
p->len += len;
|
||||
+ skb_shinfo(p)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
|
||||
if (lp != p) {
|
||||
lp->data_len += len;
|
||||
lp->truesize += delta_truesize;
|
||||
lp->len += len;
|
||||
+ skb_shinfo(lp)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
|
||||
}
|
||||
NAPI_GRO_CB(skb)->same_flow = 1;
|
||||
return 0;
|
||||
--- a/net/ipv4/udp_offload.c 2026-05-28 12:54:14.556608350 +0200
|
||||
+++ b/net/ipv4/udp_offload.c 2026-05-28 12:57:19.503137455 +0200
|
||||
@@ -487,6 +487,8 @@
|
||||
p->truesize += skb->truesize;
|
||||
p->len += skb->len;
|
||||
|
||||
+ skb_shinfo(p)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
|
||||
+
|
||||
NAPI_GRO_CB(skb)->same_flow = 1;
|
||||
|
||||
return 0;
|
||||
@ -0,0 +1,135 @@
|
||||
From d770e24a36c555404676344d2b3a55f0aeecbde0 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Oros <poros@redhat.com>
|
||||
Date: Thu, 5 Mar 2026 14:22:14 +0100
|
||||
Subject: [PATCH] ice: fix page leak for zero-size Rx descriptors
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-152865
|
||||
Upstream Status: RHEL-only
|
||||
|
||||
Intel E800 hardware can generate zero-size descriptors within
|
||||
multi-buffer (jumbo) frames. These descriptors carry no packet data
|
||||
but still occupy a slot in the Rx ring and have a page assigned to
|
||||
them.
|
||||
|
||||
ice_add_xdp_frag() correctly skips zero-size descriptors (returns 0
|
||||
when size == 0), so the page is never added to the xdp_buff/SKB.
|
||||
However, ice_get_rx_buf() unconditionally decrements pagecnt_bias for
|
||||
every descriptor, including zero-size ones. This creates a permanent
|
||||
pagecnt_bias deficit for the affected page: the driver has "promised"
|
||||
(via pagecnt_bias--) that someone will eventually call put_page() to
|
||||
balance it, but since the page is not part of any SKB, nobody ever
|
||||
does.
|
||||
|
||||
The deficit accumulates and manifests as follows:
|
||||
|
||||
1. Zero-size descriptor: pagecnt_bias-- in ice_get_rx_buf(), but
|
||||
the page is not added to any SKB by ice_add_xdp_frag().
|
||||
2. The page is recycled back to the ring via ice_reuse_rx_page()
|
||||
with pagecnt_bias one lower than it should be.
|
||||
3. On the next normal use of this page, pagecnt_bias-- again.
|
||||
Now page_count - pagecnt_bias = 2 > 1, so ice_can_reuse_rx_page()
|
||||
returns false.
|
||||
4. The page goes to __page_frag_cache_drain(page, pagecnt_bias),
|
||||
but pagecnt_bias is too low by 1, leaving page_count = 2.
|
||||
5. The SKB eventually frees its reference (put_page), bringing
|
||||
page_count to 1 - a phantom reference with no owner.
|
||||
6. The page is permanently leaked. ice_alloc_rx_bufs() must
|
||||
allocate a fresh page to replace it.
|
||||
|
||||
The previous attempt to fix the associated panic (commit ef68094cb09e
|
||||
"ice: Fix kernel panic due to page refcount underflow") added
|
||||
pagecnt_bias-- for zero-size descriptors in ice_get_rx_buf(). This
|
||||
fixed the panic in the CONSUMED (XDP_DROP/error) path but introduced
|
||||
the page leak in the PASS path described above.
|
||||
|
||||
The root cause is that ice_put_rx_mbuf() used a positional counter
|
||||
('i') to decide which buffers need pagecnt_bias restoration. This
|
||||
counter counted all ring positions including zero-size descriptors,
|
||||
but xdp_frags only counted real fragments, causing misalignment:
|
||||
zero-size descriptors "stole" pagecnt_bias++ slots from real
|
||||
fragments that needed them.
|
||||
|
||||
Fix this by adding an 'has_data' flag to ice_rx_buf that records whether
|
||||
ice_get_rx_buf() was called with actual data (size > 0). Replace
|
||||
the broken positional counter in ice_put_rx_mbuf() with a direct
|
||||
check on this flag:
|
||||
|
||||
- has_data && !CONSUMED: call ice_rx_buf_adjust_pg_offset() — the page
|
||||
is in an SKB or XDP TX buffer that will eventually call put_page()
|
||||
to balance the pagecnt_bias decrement.
|
||||
|
||||
- !has_data || CONSUMED: call pagecnt_bias++ — either the page carries
|
||||
no data (zero-size descriptor, nobody will put_page()) or the
|
||||
frame was dropped (no external reference holds any page).
|
||||
|
||||
The 'has_data' field fits within existing struct padding so ice_rx_buf
|
||||
size does not change.
|
||||
|
||||
Signed-off-by: Petr Oros <poros@redhat.com>
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
index 499269f03c9d..2712ad743d38 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
|
||||
@@ -1081,6 +1081,7 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
|
||||
|
||||
if (!size) {
|
||||
rx_buf->pagecnt_bias--;
|
||||
+ rx_buf->has_data = false;
|
||||
return rx_buf;
|
||||
}
|
||||
/* we are reusing so sync this buffer for CPU use */
|
||||
@@ -1090,6 +1091,7 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
|
||||
|
||||
/* We have pulled a buffer for use, so decrement pagecnt_bias */
|
||||
rx_buf->pagecnt_bias--;
|
||||
+ rx_buf->has_data = true;
|
||||
|
||||
return rx_buf;
|
||||
}
|
||||
@@ -1302,25 +1304,15 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
|
||||
u32 idx = rx_ring->first_desc;
|
||||
u32 cnt = rx_ring->count;
|
||||
struct ice_rx_buf *buf;
|
||||
- u32 xdp_frags = 0;
|
||||
- int i = 0;
|
||||
-
|
||||
- if (unlikely(xdp_buff_has_frags(xdp)))
|
||||
- xdp_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
|
||||
|
||||
while (idx != ntc) {
|
||||
buf = &rx_ring->rx_buf[idx];
|
||||
if (++idx == cnt)
|
||||
idx = 0;
|
||||
|
||||
- /* An XDP program could release fragments from the end of the
|
||||
- * buffer. For these, we need to keep the pagecnt_bias as-is.
|
||||
- * To do this, only adjust pagecnt_bias for fragments up to
|
||||
- * the total remaining after the XDP program has run.
|
||||
- */
|
||||
- if (verdict != ICE_XDP_CONSUMED)
|
||||
+ if (verdict != ICE_XDP_CONSUMED && buf->has_data)
|
||||
ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
|
||||
- else if (i++ <= xdp_frags)
|
||||
+ else
|
||||
buf->pagecnt_bias++;
|
||||
|
||||
ice_put_rx_buf(rx_ring, buf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
index 841a07bfba54..70f40a5ec33f 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
|
||||
@@ -203,6 +203,7 @@ struct ice_rx_buf {
|
||||
unsigned int page_offset;
|
||||
unsigned int pgcnt;
|
||||
unsigned int pagecnt_bias;
|
||||
+ bool has_data;
|
||||
};
|
||||
|
||||
struct ice_q_stats {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
From: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
Subject: [PATCH AlmaLinux 9] ptrace: require CAP_SYS_PTRACE when task has no mm
|
||||
|
||||
kABI-safe AlmaLinux backport of upstream commit 31e62c2ebbfd
|
||||
("ptrace: slightly saner 'get_dumpable()' logic") posted at
|
||||
https://github.com/torvalds/linux/commit/31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a
|
||||
|
||||
The upstream fix adds a 'user_dumpable:1' bit to task_struct and
|
||||
caches the last dumpability in exit_mm() so __ptrace_may_access()
|
||||
can require CAP_SYS_PTRACE when the target has no mm (e.g. kernel
|
||||
threads or already-exited user tasks). That layout change to
|
||||
task_struct breaks kABI on RHEL/AlmaLinux 9 (the symtype
|
||||
signature of struct task_struct is referenced by stablelist exports
|
||||
such as set_cpus_allowed_ptr() and wake_up_process()), so we cannot
|
||||
import the field/exit_mm hunks as-is.
|
||||
|
||||
Take the minimal kABI-safe slice instead: when task->mm == NULL,
|
||||
require CAP_SYS_PTRACE in init_user_ns unconditionally. This closes
|
||||
the Qualys Security Advisory hole -- mm-less targets no longer pass
|
||||
the dumpability check by default -- without touching task_struct or
|
||||
exit.c. The only behavioural delta versus upstream is that a user
|
||||
task that has already cleared its mm in exit_mm() (a dying/zombie
|
||||
task) now also requires CAP_SYS_PTRACE to attach, instead of being
|
||||
remembered as previously dumpable. Such targets are rarely ptraced
|
||||
in practice.
|
||||
|
||||
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no rejects)
|
||||
against kernel-5.14.0-611.54.1.el9_7.
|
||||
|
||||
Reported-by: Qualys Security Advisory <qsa@qualys.com>
|
||||
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
---
|
||||
kernel/ptrace.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/kernel/ptrace.c
|
||||
+++ b/kernel/ptrace.c
|
||||
@@ -349,8 +349,11 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
|
||||
smp_rmb();
|
||||
mm = task->mm;
|
||||
- if (mm &&
|
||||
- ((get_dumpable(mm) != SUID_DUMP_USER) &&
|
||||
- !ptrace_has_cap(mm->user_ns, mode)))
|
||||
- return -EPERM;
|
||||
+ if (mm) {
|
||||
+ if ((get_dumpable(mm) != SUID_DUMP_USER) &&
|
||||
+ !ptrace_has_cap(mm->user_ns, mode))
|
||||
+ return -EPERM;
|
||||
+ } else if (!ptrace_has_cap(&init_user_ns, mode)) {
|
||||
+ return -EPERM;
|
||||
+ }
|
||||
|
||||
return security_ptrace_access_check(task, mode);
|
||||
--
|
||||
2.43.0
|
||||
@ -1,962 +0,0 @@
|
||||
From: AlmaLinux Backport <packager@almalinux.org>
|
||||
Subject: [PATCH] CVE-2026-31431 ("Copy Fail"): crypto AEAD/algif fixes from linux-5.15.y
|
||||
|
||||
Combined backport addressing CVE-2026-31431 ("Copy Fail"), reported by
|
||||
Taeyang Lee <0wn@theori.io>. EL9 kernel is based on 5.14.0; the closest
|
||||
stable branch is linux-5.15.y. Pulls one prerequisite (committed
|
||||
2026-02-06 to 5.15.y) plus nine 2026-04-30 stable fixes:
|
||||
|
||||
fee86edf5803 crypto: authencesn - reject too-short AAD (assoclen<8) to match ESP/ESN spec
|
||||
36435a56cd6b crypto: scatterwalk - Backport memcpy_sglist()
|
||||
17774d99bb43 crypto: algif_aead - use memcpy_sglist() instead of null skcipher
|
||||
19d43105a97b crypto: algif_aead - Revert to operating out-of-place
|
||||
a920cabdb0b7 crypto: algif_aead - snapshot IV for async AEAD requests
|
||||
e416c41a96c8 crypto: authenc - use memcpy_sglist() instead of null skcipher
|
||||
d589abd8b019 crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption
|
||||
723bb1b4a6dd crypto: authencesn - Fix src offset when decrypting in-place
|
||||
2b781d1d4f93 crypto: af_alg - Fix page reassignment overflow in af_alg_pull_tsgl
|
||||
fd427dd84f22 crypto: algif_aead - Fix minimum RX size check for decryption
|
||||
|
||||
fee86edf5803 is the prerequisite for d589abd8b019 to apply.
|
||||
|
||||
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
---
|
||||
--- a/crypto/af_alg.c
|
||||
+++ b/crypto/af_alg.c
|
||||
@@ -525,15 +525,13 @@
|
||||
/**
|
||||
* af_alg_count_tsgl - Count number of TX SG entries
|
||||
*
|
||||
- * The counting starts from the beginning of the SGL to @bytes. If
|
||||
- * an @offset is provided, the counting of the SG entries starts at the @offset.
|
||||
+ * The counting starts from the beginning of the SGL to @bytes.
|
||||
*
|
||||
* @sk: socket of connection to user space
|
||||
* @bytes: Count the number of SG entries holding given number of bytes.
|
||||
- * @offset: Start the counting of SG entries from the given offset.
|
||||
* Return: Number of TX SG entries found given the constraints
|
||||
*/
|
||||
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
|
||||
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes)
|
||||
{
|
||||
const struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_ctx *ctx = ask->private;
|
||||
@@ -548,25 +546,11 @@
|
||||
const struct scatterlist *sg = sgl->sg;
|
||||
|
||||
for (i = 0; i < sgl->cur; i++) {
|
||||
- size_t bytes_count;
|
||||
-
|
||||
- /* Skip offset */
|
||||
- if (offset >= sg[i].length) {
|
||||
- offset -= sg[i].length;
|
||||
- bytes -= sg[i].length;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- bytes_count = sg[i].length - offset;
|
||||
-
|
||||
- offset = 0;
|
||||
sgl_count++;
|
||||
-
|
||||
- /* If we have seen requested number of bytes, stop */
|
||||
- if (bytes_count >= bytes)
|
||||
+ if (sg[i].length >= bytes)
|
||||
return sgl_count;
|
||||
|
||||
- bytes -= bytes_count;
|
||||
+ bytes -= sg[i].length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,19 +562,14 @@
|
||||
* af_alg_pull_tsgl - Release the specified buffers from TX SGL
|
||||
*
|
||||
* If @dst is non-null, reassign the pages to @dst. The caller must release
|
||||
- * the pages. If @dst_offset is given only reassign the pages to @dst starting
|
||||
- * at the @dst_offset (byte). The caller must ensure that @dst is large
|
||||
- * enough (e.g. by using af_alg_count_tsgl with the same offset).
|
||||
+ * the pages.
|
||||
*
|
||||
* @sk: socket of connection to user space
|
||||
* @used: Number of bytes to pull from TX SGL
|
||||
* @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
|
||||
* caller must release the buffers in dst.
|
||||
- * @dst_offset: Reassign the TX SGL from given offset. All buffers before
|
||||
- * reaching the offset is released.
|
||||
*/
|
||||
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
|
||||
- size_t dst_offset)
|
||||
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
|
||||
{
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct af_alg_ctx *ctx = ask->private;
|
||||
@@ -614,19 +593,11 @@
|
||||
* Assumption: caller created af_alg_count_tsgl(len)
|
||||
* SG entries in dst.
|
||||
*/
|
||||
- if (dst) {
|
||||
- if (dst_offset >= plen) {
|
||||
- /* discard page before offset */
|
||||
- dst_offset -= plen;
|
||||
- } else {
|
||||
- /* reassign page to dst after offset */
|
||||
- get_page(page);
|
||||
- sg_set_page(dst + j, page,
|
||||
- plen - dst_offset,
|
||||
- sg[i].offset + dst_offset);
|
||||
- dst_offset = 0;
|
||||
- j++;
|
||||
- }
|
||||
+ if (dst && plen) {
|
||||
+ /* reassign page to dst */
|
||||
+ get_page(page);
|
||||
+ sg_set_page(dst + j, page, plen, sg[i].offset);
|
||||
+ j++;
|
||||
}
|
||||
|
||||
sg[i].length -= plen;
|
||||
--- a/crypto/algif_aead.c
|
||||
+++ b/crypto/algif_aead.c
|
||||
@@ -26,8 +26,6 @@
|
||||
#include <crypto/internal/aead.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/if_alg.h>
|
||||
-#include <crypto/skcipher.h>
|
||||
-#include <crypto/null.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -36,19 +34,13 @@
|
||||
#include <linux/net.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
-struct aead_tfm {
|
||||
- struct crypto_aead *aead;
|
||||
- struct crypto_sync_skcipher *null_tfm;
|
||||
-};
|
||||
-
|
||||
static inline bool aead_sufficient_data(struct sock *sk)
|
||||
{
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct af_alg_ctx *ctx = ask->private;
|
||||
- struct aead_tfm *aeadc = pask->private;
|
||||
- struct crypto_aead *tfm = aeadc->aead;
|
||||
+ struct crypto_aead *tfm = pask->private;
|
||||
unsigned int as = crypto_aead_authsize(tfm);
|
||||
|
||||
/*
|
||||
@@ -64,27 +56,12 @@
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
- struct aead_tfm *aeadc = pask->private;
|
||||
- struct crypto_aead *tfm = aeadc->aead;
|
||||
+ struct crypto_aead *tfm = pask->private;
|
||||
unsigned int ivsize = crypto_aead_ivsize(tfm);
|
||||
|
||||
return af_alg_sendmsg(sock, msg, size, ivsize);
|
||||
}
|
||||
|
||||
-static int crypto_aead_copy_sgl(struct crypto_sync_skcipher *null_tfm,
|
||||
- struct scatterlist *src,
|
||||
- struct scatterlist *dst, unsigned int len)
|
||||
-{
|
||||
- SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, null_tfm);
|
||||
-
|
||||
- skcipher_request_set_sync_tfm(skreq, null_tfm);
|
||||
- skcipher_request_set_callback(skreq, CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||
- NULL, NULL);
|
||||
- skcipher_request_set_crypt(skreq, src, dst, len, NULL);
|
||||
-
|
||||
- return crypto_skcipher_encrypt(skreq);
|
||||
-}
|
||||
-
|
||||
static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
@@ -93,13 +70,12 @@
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct af_alg_ctx *ctx = ask->private;
|
||||
- struct aead_tfm *aeadc = pask->private;
|
||||
- struct crypto_aead *tfm = aeadc->aead;
|
||||
- struct crypto_sync_skcipher *null_tfm = aeadc->null_tfm;
|
||||
- unsigned int i, as = crypto_aead_authsize(tfm);
|
||||
+ struct crypto_aead *tfm = pask->private;
|
||||
+ unsigned int as = crypto_aead_authsize(tfm);
|
||||
+ unsigned int ivsize = crypto_aead_ivsize(tfm);
|
||||
struct af_alg_async_req *areq;
|
||||
- struct af_alg_tsgl *tsgl, *tmp;
|
||||
struct scatterlist *rsgl_src, *tsgl_src = NULL;
|
||||
+ void *iv;
|
||||
int err = 0;
|
||||
size_t used = 0; /* [in] TX bufs to be en/decrypted */
|
||||
size_t outlen = 0; /* [out] RX bufs produced by kernel */
|
||||
@@ -151,10 +127,14 @@
|
||||
|
||||
/* Allocate cipher request for current operation. */
|
||||
areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
|
||||
- crypto_aead_reqsize(tfm));
|
||||
+ crypto_aead_reqsize(tfm) + ivsize);
|
||||
if (IS_ERR(areq))
|
||||
return PTR_ERR(areq);
|
||||
|
||||
+ iv = (u8 *)aead_request_ctx(&areq->cra_u.aead_req) +
|
||||
+ crypto_aead_reqsize(tfm);
|
||||
+ memcpy(iv, ctx->iv, ivsize);
|
||||
+
|
||||
/* convert iovecs of output buffers into RX SGL */
|
||||
err = af_alg_get_rsgl(sk, msg, flags, areq, outlen, &usedpages);
|
||||
if (err)
|
||||
@@ -170,7 +150,7 @@
|
||||
if (usedpages < outlen) {
|
||||
size_t less = outlen - usedpages;
|
||||
|
||||
- if (used < less) {
|
||||
+ if (used < less + (ctx->enc ? 0 : as)) {
|
||||
err = -EINVAL;
|
||||
goto free;
|
||||
}
|
||||
@@ -178,23 +158,24 @@
|
||||
outlen -= less;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Create a per request TX SGL for this request which tracks the
|
||||
+ * SG entries from the global TX SGL.
|
||||
+ */
|
||||
processed = used + ctx->aead_assoclen;
|
||||
- list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) {
|
||||
- for (i = 0; i < tsgl->cur; i++) {
|
||||
- struct scatterlist *process_sg = tsgl->sg + i;
|
||||
-
|
||||
- if (!(process_sg->length) || !sg_page(process_sg))
|
||||
- continue;
|
||||
- tsgl_src = process_sg;
|
||||
- break;
|
||||
- }
|
||||
- if (tsgl_src)
|
||||
- break;
|
||||
- }
|
||||
- if (processed && !tsgl_src) {
|
||||
- err = -EFAULT;
|
||||
+ areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
|
||||
+ if (!areq->tsgl_entries)
|
||||
+ areq->tsgl_entries = 1;
|
||||
+ areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
|
||||
+ areq->tsgl_entries),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!areq->tsgl) {
|
||||
+ err = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
+ sg_init_table(areq->tsgl, areq->tsgl_entries);
|
||||
+ af_alg_pull_tsgl(sk, processed, areq->tsgl);
|
||||
+ tsgl_src = areq->tsgl;
|
||||
|
||||
/*
|
||||
* Copy of AAD from source to destination
|
||||
@@ -203,82 +184,16 @@
|
||||
* when user space uses an in-place cipher operation, the kernel
|
||||
* will copy the data as it does not see whether such in-place operation
|
||||
* is initiated.
|
||||
- *
|
||||
- * To ensure efficiency, the following implementation ensure that the
|
||||
- * ciphers are invoked to perform a crypto operation in-place. This
|
||||
- * is achieved by memory management specified as follows.
|
||||
*/
|
||||
|
||||
/* Use the RX SGL as source (and destination) for crypto op. */
|
||||
rsgl_src = areq->first_rsgl.sgl.sg;
|
||||
|
||||
- if (ctx->enc) {
|
||||
- /*
|
||||
- * Encryption operation - The in-place cipher operation is
|
||||
- * achieved by the following operation:
|
||||
- *
|
||||
- * TX SGL: AAD || PT
|
||||
- * | |
|
||||
- * | copy |
|
||||
- * v v
|
||||
- * RX SGL: AAD || PT || Tag
|
||||
- */
|
||||
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
|
||||
- areq->first_rsgl.sgl.sg, processed);
|
||||
- if (err)
|
||||
- goto free;
|
||||
- af_alg_pull_tsgl(sk, processed, NULL, 0);
|
||||
- } else {
|
||||
- /*
|
||||
- * Decryption operation - To achieve an in-place cipher
|
||||
- * operation, the following SGL structure is used:
|
||||
- *
|
||||
- * TX SGL: AAD || CT || Tag
|
||||
- * | | ^
|
||||
- * | copy | | Create SGL link.
|
||||
- * v v |
|
||||
- * RX SGL: AAD || CT ----+
|
||||
- */
|
||||
-
|
||||
- /* Copy AAD || CT to RX SGL buffer for in-place operation. */
|
||||
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
|
||||
- areq->first_rsgl.sgl.sg, outlen);
|
||||
- if (err)
|
||||
- goto free;
|
||||
-
|
||||
- /* Create TX SGL for tag and chain it to RX SGL. */
|
||||
- areq->tsgl_entries = af_alg_count_tsgl(sk, processed,
|
||||
- processed - as);
|
||||
- if (!areq->tsgl_entries)
|
||||
- areq->tsgl_entries = 1;
|
||||
- areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
|
||||
- areq->tsgl_entries),
|
||||
- GFP_KERNEL);
|
||||
- if (!areq->tsgl) {
|
||||
- err = -ENOMEM;
|
||||
- goto free;
|
||||
- }
|
||||
- sg_init_table(areq->tsgl, areq->tsgl_entries);
|
||||
-
|
||||
- /* Release TX SGL, except for tag data and reassign tag data. */
|
||||
- af_alg_pull_tsgl(sk, processed, areq->tsgl, processed - as);
|
||||
-
|
||||
- /* chain the areq TX SGL holding the tag with RX SGL */
|
||||
- if (usedpages) {
|
||||
- /* RX SGL present */
|
||||
- struct af_alg_sgl *sgl_prev = &areq->last_rsgl->sgl;
|
||||
-
|
||||
- sg_unmark_end(sgl_prev->sg + sgl_prev->npages - 1);
|
||||
- sg_chain(sgl_prev->sg, sgl_prev->npages + 1,
|
||||
- areq->tsgl);
|
||||
- } else
|
||||
- /* no RX SGL present (e.g. authentication only) */
|
||||
- rsgl_src = areq->tsgl;
|
||||
- }
|
||||
+ memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
|
||||
|
||||
/* Initialize the crypto operation */
|
||||
- aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
|
||||
- areq->first_rsgl.sgl.sg, used, ctx->iv);
|
||||
+ aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
|
||||
+ areq->first_rsgl.sgl.sg, used, iv);
|
||||
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
|
||||
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
|
||||
|
||||
@@ -378,7 +293,7 @@
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
- struct aead_tfm *tfm;
|
||||
+ struct crypto_aead *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
@@ -392,7 +307,7 @@
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
- if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY)
|
||||
+ if (crypto_aead_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
|
||||
goto unlock;
|
||||
|
||||
atomic_dec(&pask->nokey_refcnt);
|
||||
@@ -466,54 +381,22 @@
|
||||
|
||||
static void *aead_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
- struct aead_tfm *tfm;
|
||||
- struct crypto_aead *aead;
|
||||
- struct crypto_sync_skcipher *null_tfm;
|
||||
-
|
||||
- tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
- if (!tfm)
|
||||
- return ERR_PTR(-ENOMEM);
|
||||
-
|
||||
- aead = crypto_alloc_aead(name, type, mask);
|
||||
- if (IS_ERR(aead)) {
|
||||
- kfree(tfm);
|
||||
- return ERR_CAST(aead);
|
||||
- }
|
||||
-
|
||||
- null_tfm = crypto_get_default_null_skcipher();
|
||||
- if (IS_ERR(null_tfm)) {
|
||||
- crypto_free_aead(aead);
|
||||
- kfree(tfm);
|
||||
- return ERR_CAST(null_tfm);
|
||||
- }
|
||||
-
|
||||
- tfm->aead = aead;
|
||||
- tfm->null_tfm = null_tfm;
|
||||
-
|
||||
- return tfm;
|
||||
+ return crypto_alloc_aead(name, type, mask);
|
||||
}
|
||||
|
||||
static void aead_release(void *private)
|
||||
{
|
||||
- struct aead_tfm *tfm = private;
|
||||
-
|
||||
- crypto_free_aead(tfm->aead);
|
||||
- crypto_put_default_null_skcipher();
|
||||
- kfree(tfm);
|
||||
+ crypto_free_aead(private);
|
||||
}
|
||||
|
||||
static int aead_setauthsize(void *private, unsigned int authsize)
|
||||
{
|
||||
- struct aead_tfm *tfm = private;
|
||||
-
|
||||
- return crypto_aead_setauthsize(tfm->aead, authsize);
|
||||
+ return crypto_aead_setauthsize(private, authsize);
|
||||
}
|
||||
|
||||
static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
- struct aead_tfm *tfm = private;
|
||||
-
|
||||
- return crypto_aead_setkey(tfm->aead, key, keylen);
|
||||
+ return crypto_aead_setkey(private, key, keylen);
|
||||
}
|
||||
|
||||
static void aead_sock_destruct(struct sock *sk)
|
||||
@@ -522,11 +405,10 @@
|
||||
struct af_alg_ctx *ctx = ask->private;
|
||||
struct sock *psk = ask->parent;
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
- struct aead_tfm *aeadc = pask->private;
|
||||
- struct crypto_aead *tfm = aeadc->aead;
|
||||
+ struct crypto_aead *tfm = pask->private;
|
||||
unsigned int ivlen = crypto_aead_ivsize(tfm);
|
||||
|
||||
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
|
||||
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
|
||||
sock_kzfree_s(sk, ctx->iv, ivlen);
|
||||
sock_kfree_s(sk, ctx, ctx->len);
|
||||
af_alg_release_parent(sk);
|
||||
@@ -536,10 +418,9 @@
|
||||
{
|
||||
struct af_alg_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
- struct aead_tfm *tfm = private;
|
||||
- struct crypto_aead *aead = tfm->aead;
|
||||
+ struct crypto_aead *tfm = private;
|
||||
unsigned int len = sizeof(*ctx);
|
||||
- unsigned int ivlen = crypto_aead_ivsize(aead);
|
||||
+ unsigned int ivlen = crypto_aead_ivsize(tfm);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
@@ -566,9 +447,9 @@
|
||||
|
||||
static int aead_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
- struct aead_tfm *tfm = private;
|
||||
+ struct crypto_aead *tfm = private;
|
||||
|
||||
- if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY)
|
||||
+ if (crypto_aead_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
|
||||
return -ENOKEY;
|
||||
|
||||
return aead_accept_parent_nokey(private, sk);
|
||||
--- a/crypto/algif_skcipher.c
|
||||
+++ b/crypto/algif_skcipher.c
|
||||
@@ -89,7 +89,7 @@
|
||||
* Create a per request TX SGL for this request which tracks the
|
||||
* SG entries from the global TX SGL.
|
||||
*/
|
||||
- areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
|
||||
+ areq->tsgl_entries = af_alg_count_tsgl(sk, len);
|
||||
if (!areq->tsgl_entries)
|
||||
areq->tsgl_entries = 1;
|
||||
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
|
||||
@@ -100,7 +100,7 @@
|
||||
goto free;
|
||||
}
|
||||
sg_init_table(areq->tsgl, areq->tsgl_entries);
|
||||
- af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
|
||||
+ af_alg_pull_tsgl(sk, len, areq->tsgl);
|
||||
|
||||
/* Initialize the crypto operation */
|
||||
skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
|
||||
@@ -313,7 +313,7 @@
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct crypto_skcipher *tfm = pask->private;
|
||||
|
||||
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
|
||||
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
|
||||
sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
|
||||
sock_kfree_s(sk, ctx, ctx->len);
|
||||
af_alg_release_parent(sk);
|
||||
--- a/crypto/authenc.c
|
||||
+++ b/crypto/authenc.c
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/authenc.h>
|
||||
-#include <crypto/null.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
@@ -28,7 +27,6 @@
|
||||
struct crypto_authenc_ctx {
|
||||
struct crypto_ahash *auth;
|
||||
struct crypto_skcipher *enc;
|
||||
- struct crypto_sync_skcipher *null;
|
||||
};
|
||||
|
||||
struct authenc_request_ctx {
|
||||
@@ -174,21 +172,6 @@
|
||||
authenc_request_complete(areq, err);
|
||||
}
|
||||
|
||||
-static int crypto_authenc_copy_assoc(struct aead_request *req)
|
||||
-{
|
||||
- struct crypto_aead *authenc = crypto_aead_reqtfm(req);
|
||||
- struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
|
||||
- SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
|
||||
-
|
||||
- skcipher_request_set_sync_tfm(skreq, ctx->null);
|
||||
- skcipher_request_set_callback(skreq, aead_request_flags(req),
|
||||
- NULL, NULL);
|
||||
- skcipher_request_set_crypt(skreq, req->src, req->dst, req->assoclen,
|
||||
- NULL);
|
||||
-
|
||||
- return crypto_skcipher_encrypt(skreq);
|
||||
-}
|
||||
-
|
||||
static int crypto_authenc_encrypt(struct aead_request *req)
|
||||
{
|
||||
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
|
||||
@@ -207,10 +190,7 @@
|
||||
dst = src;
|
||||
|
||||
if (req->src != req->dst) {
|
||||
- err = crypto_authenc_copy_assoc(req);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
+ memcpy_sglist(req->dst, req->src, req->assoclen);
|
||||
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
|
||||
}
|
||||
|
||||
@@ -311,7 +291,6 @@
|
||||
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
struct crypto_ahash *auth;
|
||||
struct crypto_skcipher *enc;
|
||||
- struct crypto_sync_skcipher *null;
|
||||
int err;
|
||||
|
||||
auth = crypto_spawn_ahash(&ictx->auth);
|
||||
@@ -323,14 +302,8 @@
|
||||
if (IS_ERR(enc))
|
||||
goto err_free_ahash;
|
||||
|
||||
- null = crypto_get_default_null_skcipher();
|
||||
- err = PTR_ERR(null);
|
||||
- if (IS_ERR(null))
|
||||
- goto err_free_skcipher;
|
||||
-
|
||||
ctx->auth = auth;
|
||||
ctx->enc = enc;
|
||||
- ctx->null = null;
|
||||
|
||||
crypto_aead_set_reqsize(
|
||||
tfm,
|
||||
@@ -344,8 +317,6 @@
|
||||
|
||||
return 0;
|
||||
|
||||
-err_free_skcipher:
|
||||
- crypto_free_skcipher(enc);
|
||||
err_free_ahash:
|
||||
crypto_free_ahash(auth);
|
||||
return err;
|
||||
@@ -357,7 +328,6 @@
|
||||
|
||||
crypto_free_ahash(ctx->auth);
|
||||
crypto_free_skcipher(ctx->enc);
|
||||
- crypto_put_default_null_skcipher();
|
||||
}
|
||||
|
||||
static void crypto_authenc_free(struct aead_instance *inst)
|
||||
--- a/crypto/authencesn.c
|
||||
+++ b/crypto/authencesn.c
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/authenc.h>
|
||||
-#include <crypto/null.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
@@ -31,7 +30,6 @@
|
||||
unsigned int reqoff;
|
||||
struct crypto_ahash *auth;
|
||||
struct crypto_skcipher *enc;
|
||||
- struct crypto_sync_skcipher *null;
|
||||
};
|
||||
|
||||
struct authenc_esn_request_ctx {
|
||||
@@ -164,20 +162,6 @@
|
||||
authenc_esn_request_complete(areq, err);
|
||||
}
|
||||
|
||||
-static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
|
||||
-{
|
||||
- struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
|
||||
- struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
|
||||
- SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
|
||||
-
|
||||
- skcipher_request_set_sync_tfm(skreq, ctx->null);
|
||||
- skcipher_request_set_callback(skreq, aead_request_flags(req),
|
||||
- NULL, NULL);
|
||||
- skcipher_request_set_crypt(skreq, req->src, req->dst, len, NULL);
|
||||
-
|
||||
- return crypto_skcipher_encrypt(skreq);
|
||||
-}
|
||||
-
|
||||
static int crypto_authenc_esn_encrypt(struct aead_request *req)
|
||||
{
|
||||
struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
|
||||
@@ -191,15 +175,15 @@
|
||||
struct scatterlist *src, *dst;
|
||||
int err;
|
||||
|
||||
+ if (assoclen < 8)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
sg_init_table(areq_ctx->src, 2);
|
||||
src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen);
|
||||
dst = src;
|
||||
|
||||
if (req->src != req->dst) {
|
||||
- err = crypto_authenc_esn_copy(req, assoclen);
|
||||
- if (err)
|
||||
- return err;
|
||||
-
|
||||
+ memcpy_sglist(req->dst, req->src, assoclen);
|
||||
sg_init_table(areq_ctx->dst, 2);
|
||||
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, assoclen);
|
||||
}
|
||||
@@ -230,6 +214,7 @@
|
||||
crypto_ahash_alignmask(auth) + 1);
|
||||
unsigned int cryptlen = req->cryptlen - authsize;
|
||||
unsigned int assoclen = req->assoclen;
|
||||
+ struct scatterlist *src = req->src;
|
||||
struct scatterlist *dst = req->dst;
|
||||
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
|
||||
u32 tmp[2];
|
||||
@@ -237,23 +222,29 @@
|
||||
if (!authsize)
|
||||
goto decrypt;
|
||||
|
||||
- /* Move high-order bits of sequence number back. */
|
||||
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
|
||||
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
|
||||
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
|
||||
+ if (src == dst) {
|
||||
+ /* Move high-order bits of sequence number back. */
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
|
||||
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
|
||||
+ } else
|
||||
+ memcpy_sglist(dst, src, assoclen);
|
||||
|
||||
if (crypto_memneq(ihash, ohash, authsize))
|
||||
return -EBADMSG;
|
||||
|
||||
decrypt:
|
||||
|
||||
- sg_init_table(areq_ctx->dst, 2);
|
||||
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
|
||||
+ if (req->src == req->dst)
|
||||
+ src = dst;
|
||||
+ else
|
||||
+ src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
|
||||
|
||||
skcipher_request_set_tfm(skreq, ctx->enc);
|
||||
skcipher_request_set_callback(skreq, flags,
|
||||
req->base.complete, req->base.data);
|
||||
- skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
|
||||
+ skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
|
||||
|
||||
return crypto_skcipher_decrypt(skreq);
|
||||
}
|
||||
@@ -280,31 +271,36 @@
|
||||
unsigned int assoclen = req->assoclen;
|
||||
unsigned int cryptlen = req->cryptlen;
|
||||
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
|
||||
+ struct scatterlist *src = req->src;
|
||||
struct scatterlist *dst = req->dst;
|
||||
u32 tmp[2];
|
||||
int err;
|
||||
|
||||
- cryptlen -= authsize;
|
||||
+ if (assoclen < 8)
|
||||
+ return -EINVAL;
|
||||
|
||||
- if (req->src != dst) {
|
||||
- err = crypto_authenc_esn_copy(req, assoclen + cryptlen);
|
||||
- if (err)
|
||||
- return err;
|
||||
- }
|
||||
+ if (!authsize)
|
||||
+ goto tail;
|
||||
|
||||
+ cryptlen -= authsize;
|
||||
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
- if (!authsize)
|
||||
- goto tail;
|
||||
-
|
||||
/* Move high-order bits of sequence number to the end. */
|
||||
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
|
||||
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
|
||||
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
|
||||
-
|
||||
- sg_init_table(areq_ctx->dst, 2);
|
||||
- dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
|
||||
+ scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
|
||||
+ if (src == dst) {
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
|
||||
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
|
||||
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
|
||||
+ } else {
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
|
||||
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
|
||||
+
|
||||
+ src = scatterwalk_ffwd(areq_ctx->src, src, 8);
|
||||
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
|
||||
+ memcpy_sglist(dst, src, assoclen + cryptlen - 8);
|
||||
+ dst = req->dst;
|
||||
+ }
|
||||
|
||||
ahash_request_set_tfm(ahreq, auth);
|
||||
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);
|
||||
@@ -326,7 +322,6 @@
|
||||
struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
struct crypto_ahash *auth;
|
||||
struct crypto_skcipher *enc;
|
||||
- struct crypto_sync_skcipher *null;
|
||||
int err;
|
||||
|
||||
auth = crypto_spawn_ahash(&ictx->auth);
|
||||
@@ -338,14 +333,8 @@
|
||||
if (IS_ERR(enc))
|
||||
goto err_free_ahash;
|
||||
|
||||
- null = crypto_get_default_null_skcipher();
|
||||
- err = PTR_ERR(null);
|
||||
- if (IS_ERR(null))
|
||||
- goto err_free_skcipher;
|
||||
-
|
||||
ctx->auth = auth;
|
||||
ctx->enc = enc;
|
||||
- ctx->null = null;
|
||||
|
||||
ctx->reqoff = ALIGN(2 * crypto_ahash_digestsize(auth),
|
||||
crypto_ahash_alignmask(auth) + 1);
|
||||
@@ -362,8 +351,6 @@
|
||||
|
||||
return 0;
|
||||
|
||||
-err_free_skcipher:
|
||||
- crypto_free_skcipher(enc);
|
||||
err_free_ahash:
|
||||
crypto_free_ahash(auth);
|
||||
return err;
|
||||
@@ -375,7 +362,6 @@
|
||||
|
||||
crypto_free_ahash(ctx->auth);
|
||||
crypto_free_skcipher(ctx->enc);
|
||||
- crypto_put_default_null_skcipher();
|
||||
}
|
||||
|
||||
static void crypto_authenc_esn_free(struct aead_instance *inst)
|
||||
--- a/crypto/scatterwalk.c
|
||||
+++ b/crypto/scatterwalk.c
|
||||
@@ -69,6 +69,100 @@
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);
|
||||
|
||||
+/**
|
||||
+ * memcpy_sglist() - Copy data from one scatterlist to another
|
||||
+ * @dst: The destination scatterlist. Can be NULL if @nbytes == 0.
|
||||
+ * @src: The source scatterlist. Can be NULL if @nbytes == 0.
|
||||
+ * @nbytes: Number of bytes to copy
|
||||
+ *
|
||||
+ * The scatterlists can describe exactly the same memory, in which case this
|
||||
+ * function is a no-op. No other overlaps are supported.
|
||||
+ *
|
||||
+ * Context: Any context
|
||||
+ */
|
||||
+void memcpy_sglist(struct scatterlist *dst, struct scatterlist *src,
|
||||
+ unsigned int nbytes)
|
||||
+{
|
||||
+ unsigned int src_offset, dst_offset;
|
||||
+
|
||||
+ if (unlikely(nbytes == 0)) /* in case src and/or dst is NULL */
|
||||
+ return;
|
||||
+
|
||||
+ src_offset = src->offset;
|
||||
+ dst_offset = dst->offset;
|
||||
+ for (;;) {
|
||||
+ /* Compute the length to copy this step. */
|
||||
+ unsigned int len = min3(src->offset + src->length - src_offset,
|
||||
+ dst->offset + dst->length - dst_offset,
|
||||
+ nbytes);
|
||||
+ struct page *src_page = sg_page(src);
|
||||
+ struct page *dst_page = sg_page(dst);
|
||||
+ const void *src_virt;
|
||||
+ void *dst_virt;
|
||||
+
|
||||
+ if (IS_ENABLED(CONFIG_HIGHMEM)) {
|
||||
+ /* HIGHMEM: we may have to actually map the pages. */
|
||||
+ const unsigned int src_oip = offset_in_page(src_offset);
|
||||
+ const unsigned int dst_oip = offset_in_page(dst_offset);
|
||||
+ const unsigned int limit = PAGE_SIZE;
|
||||
+
|
||||
+ /* Further limit len to not cross a page boundary. */
|
||||
+ len = min3(len, limit - src_oip, limit - dst_oip);
|
||||
+
|
||||
+ /* Compute the source and destination pages. */
|
||||
+ src_page += src_offset / PAGE_SIZE;
|
||||
+ dst_page += dst_offset / PAGE_SIZE;
|
||||
+
|
||||
+ if (src_page != dst_page) {
|
||||
+ /* Copy between different pages. */
|
||||
+ memcpy_page(dst_page, dst_oip,
|
||||
+ src_page, src_oip, len);
|
||||
+ flush_dcache_page(dst_page);
|
||||
+ } else if (src_oip != dst_oip) {
|
||||
+ /* Copy between different parts of same page. */
|
||||
+ dst_virt = kmap_local_page(dst_page);
|
||||
+ memcpy(dst_virt + dst_oip, dst_virt + src_oip,
|
||||
+ len);
|
||||
+ kunmap_local(dst_virt);
|
||||
+ flush_dcache_page(dst_page);
|
||||
+ } /* Else, it's the same memory. No action needed. */
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * !HIGHMEM: no mapping needed. Just work in the linear
|
||||
+ * buffer of each sg entry. Note that we can cross page
|
||||
+ * boundaries, as they are not significant in this case.
|
||||
+ */
|
||||
+ src_virt = page_address(src_page) + src_offset;
|
||||
+ dst_virt = page_address(dst_page) + dst_offset;
|
||||
+ if (src_virt != dst_virt) {
|
||||
+ memcpy(dst_virt, src_virt, len);
|
||||
+ if (ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE)
|
||||
+ __scatterwalk_flush_dcache_pages(
|
||||
+ dst_page, dst_offset, len);
|
||||
+ } /* Else, it's the same memory. No action needed. */
|
||||
+ }
|
||||
+ nbytes -= len;
|
||||
+ if (nbytes == 0) /* No more to copy? */
|
||||
+ break;
|
||||
+
|
||||
+ /*
|
||||
+ * There's more to copy. Advance the offsets by the length
|
||||
+ * copied this step, and advance the sg entries as needed.
|
||||
+ */
|
||||
+ src_offset += len;
|
||||
+ if (src_offset >= src->offset + src->length) {
|
||||
+ src = sg_next(src);
|
||||
+ src_offset = src->offset;
|
||||
+ }
|
||||
+ dst_offset += len;
|
||||
+ if (dst_offset >= dst->offset + dst->length) {
|
||||
+ dst = sg_next(dst);
|
||||
+ dst_offset = dst->offset;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(memcpy_sglist);
|
||||
+
|
||||
struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],
|
||||
struct scatterlist *src,
|
||||
unsigned int len)
|
||||
--- a/crypto/Kconfig
|
||||
+++ b/crypto/Kconfig
|
||||
@@ -221,7 +221,6 @@
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
select CRYPTO_HASH
|
||||
- select CRYPTO_NULL
|
||||
help
|
||||
Authenc: Combined mode wrapper for IPsec.
|
||||
This is required for IPSec.
|
||||
@@ -2120,7 +2119,6 @@
|
||||
depends on NET
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_SKCIPHER
|
||||
- select CRYPTO_NULL
|
||||
select CRYPTO_USER_API
|
||||
help
|
||||
This option enables the user-spaces interface for AEAD
|
||||
--- a/include/crypto/if_alg.h
|
||||
+++ b/include/crypto/if_alg.h
|
||||
@@ -226,9 +226,8 @@
|
||||
return PAGE_SIZE <= af_alg_rcvbuf(sk);
|
||||
}
|
||||
|
||||
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
|
||||
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
|
||||
- size_t dst_offset);
|
||||
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes);
|
||||
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst);
|
||||
void af_alg_wmem_wakeup(struct sock *sk);
|
||||
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
|
||||
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
|
||||
--- a/include/crypto/scatterwalk.h
|
||||
+++ b/include/crypto/scatterwalk.h
|
||||
@@ -89,6 +89,35 @@
|
||||
scatterwalk_start(walk, sg_next(walk->sg));
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Flush the dcache of any pages that overlap the region
|
||||
+ * [offset, offset + nbytes) relative to base_page.
|
||||
+ *
|
||||
+ * This should be called only when ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, to ensure
|
||||
+ * that all relevant code (including the call to sg_page() in the caller, if
|
||||
+ * applicable) gets fully optimized out when !ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE.
|
||||
+ */
|
||||
+static inline void __scatterwalk_flush_dcache_pages(struct page *base_page,
|
||||
+ unsigned int offset,
|
||||
+ unsigned int nbytes)
|
||||
+{
|
||||
+ unsigned int num_pages;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ base_page += offset / PAGE_SIZE;
|
||||
+ offset %= PAGE_SIZE;
|
||||
+
|
||||
+ /*
|
||||
+ * This is an overflow-safe version of
|
||||
+ * num_pages = DIV_ROUND_UP(offset + nbytes, PAGE_SIZE).
|
||||
+ */
|
||||
+ num_pages = nbytes / PAGE_SIZE;
|
||||
+ num_pages += DIV_ROUND_UP(offset + (nbytes % PAGE_SIZE), PAGE_SIZE);
|
||||
+
|
||||
+ for (i = 0; i < num_pages; i++)
|
||||
+ flush_dcache_page(base_page + i);
|
||||
+}
|
||||
+
|
||||
static inline void scatterwalk_done(struct scatter_walk *walk, int out,
|
||||
int more)
|
||||
{
|
||||
@@ -101,6 +130,9 @@
|
||||
size_t nbytes, int out);
|
||||
void *scatterwalk_map(struct scatter_walk *walk);
|
||||
|
||||
+void memcpy_sglist(struct scatterlist *dst, struct scatterlist *src,
|
||||
+ unsigned int nbytes);
|
||||
+
|
||||
void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
|
||||
unsigned int start, unsigned int nbytes, int out);
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From 21f7e8315ba37d429d01c98365e7e33d7611eb1e Mon Sep 17 00:00:00 2001
|
||||
From: Medha Mummigatti <mmummiga@redhat.com>
|
||||
Date: Thu, 12 Mar 2026 13:47:24 +0530
|
||||
Subject: [PATCH] net: hv_netvsc: reject RSS hash key programming without RX
|
||||
indirection table
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-150569
|
||||
|
||||
commit d23564955811da493f34412d7de60fa268c8cb50
|
||||
Author Aditya Garg <gargaditya@linux.microsoft.com>
|
||||
|
||||
net: hv_netvsc: reject RSS hash key programming without RX indirection table
|
||||
|
||||
RSS configuration requires a valid RX indirection table. When the device
|
||||
reports a single receive queue, rndis_filter_device_add() does not
|
||||
allocate an indirection table, accepting RSS hash key updates in this
|
||||
state leads to a hang.
|
||||
|
||||
Fix this by gating netvsc_set_rxfh() on ndc->rx_table_sz and return
|
||||
-EOPNOTSUPP when the table is absent. This aligns set_rxfh with the device
|
||||
capabilities and prevents incorrect behavior.
|
||||
|
||||
Fixes: 962f3fee83a4 ("netvsc: add ethtool ops to get/set RSS key")
|
||||
Signed-off-by: Aditya Garg <gargaditya@linux.microsoft.com>
|
||||
Reviewed-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
|
||||
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
|
||||
Link: https://patch.msgid.link/1768212093-1594-1-git-send-email-gargaditya@linux.microsoft.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
(cherry picked from commit d23564955811da493f34412d7de60fa268c8cb50)
|
||||
|
||||
Signed-off-by: Medha Mummigatti <mmummiga@redhat.com>
|
||||
|
||||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
|
||||
index 229e29498ecf..6cfef8b22cae 100644
|
||||
--- a/drivers/net/hyperv/netvsc_drv.c
|
||||
+++ b/drivers/net/hyperv/netvsc_drv.c
|
||||
@@ -1756,6 +1756,9 @@ static int netvsc_set_rxfh(struct net_device *dev,
|
||||
rxfh->hfunc != ETH_RSS_HASH_TOP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
+ if (!ndc->rx_table_sz)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
rndis_dev = ndev->extension;
|
||||
if (rxfh->indir) {
|
||||
for (i = 0; i < ndc->rx_table_sz; i++)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
From 4f4e442a275bfa406ab9766548cb30001deb4515 Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 16:35:13 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Support extended stats for Thor2 VF
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 260ce16e579d375ba8f1ac945308343522f98d50
|
||||
Author: Ajit Khaparde <ajit.khaparde@broadcom.com>
|
||||
Date: Fri May 23 13:29:52 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Support extended stats for Thor2 VF
|
||||
|
||||
The driver currently checks if the user is querying VF RoCE statistics.
|
||||
It will not send the query_roce_stats_ext HWRM command if it is for a
|
||||
VF. But Thor2 VF can support extended statistics.
|
||||
Allow query of extended stats for Thor2 VFs.
|
||||
|
||||
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
|
||||
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250523075952.1267827-1-kalesh-anakkur.purayil@broadcom.com
|
||||
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
|
||||
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
||||
index 457eecb99f96..be34c605d516 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
||||
@@ -1113,7 +1113,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
|
||||
qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION;
|
||||
if (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE)
|
||||
qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_VARIABLE_SIZED_WQE_ENABLED;
|
||||
- if (_is_ext_stats_supported(res->dattr->dev_cap_flags) && !res->is_vf)
|
||||
+ if (bnxt_ext_stats_supported(res->cctx, res->dattr->dev_cap_flags, res->is_vf))
|
||||
qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_EXT_STATS_ENABLED;
|
||||
|
||||
req.qp_flags = cpu_to_le32(qp_flags);
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
|
||||
index f231e886ad9d..9efd32a3dc55 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
|
||||
@@ -846,7 +846,12 @@ int bnxt_qplib_qext_stat(struct bnxt_qplib_rcfw *rcfw, u32 fid,
|
||||
|
||||
req.resp_size = sbuf.size / BNXT_QPLIB_CMDQE_UNITS;
|
||||
req.resp_addr = cpu_to_le64(sbuf.dma_addr);
|
||||
- req.function_id = cpu_to_le32(fid);
|
||||
+ if (bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx) && rcfw->res->is_vf)
|
||||
+ req.function_id =
|
||||
+ cpu_to_le32(CMDQ_QUERY_ROCE_STATS_EXT_VF_VALID |
|
||||
+ (fid << CMDQ_QUERY_ROCE_STATS_EXT_VF_NUM_SFT));
|
||||
+ else
|
||||
+ req.function_id = cpu_to_le32(fid);
|
||||
req.flags = cpu_to_le16(CMDQ_QUERY_ROCE_STATS_EXT_FLAGS_FUNCTION_ID);
|
||||
|
||||
bnxt_qplib_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From fd15899f1b6ab1026242424f9b3f9ba817c9656f Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 16:35:35 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Fix size of uverbs_copy_to() in
|
||||
BNXT_RE_METHOD_GET_TOGGLE_MEM
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 09d231ab569ca97478445ccc1ad44ab026de39b1
|
||||
Author: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Date: Fri Jul 4 10:08:55 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Fix size of uverbs_copy_to() in BNXT_RE_METHOD_GET_TOGGLE_MEM
|
||||
|
||||
Since both "length" and "offset" are of type u32, there is
|
||||
no functional issue here.
|
||||
|
||||
Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
|
||||
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
|
||||
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250704043857.19158-2-kalesh-anakkur.purayil@broadcom.com
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
|
||||
index 063801384b2b..3a627acb82ce 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
|
||||
@@ -4738,7 +4738,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
|
||||
return err;
|
||||
|
||||
err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
|
||||
- &offset, sizeof(length));
|
||||
+ &offset, sizeof(offset));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
128
SOURCES/1107-rdma-bnxt-re-support-2g-message-size.patch
Normal file
128
SOURCES/1107-rdma-bnxt-re-support-2g-message-size.patch
Normal file
@ -0,0 +1,128 @@
|
||||
From bae4a2298624cecd837e2deff15b915e6804f940 Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 16:35:48 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Support 2G message size
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 0aed817380d620987b2d5c573fdd2f01c30976a4
|
||||
Author: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Date: Fri Jul 4 10:08:56 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Support 2G message size
|
||||
|
||||
bnxt_qplib_put_sges is calculating the length in
|
||||
a signed int. So handling the 2G message size
|
||||
is not working since it is considered as negative.
|
||||
|
||||
Use a unsigned number to calculate the total message
|
||||
length. As per the spec, IB message size shall be
|
||||
between zero and 2^31 bytes (inclusive). So adding
|
||||
a check for 2G message size.
|
||||
|
||||
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250704043857.19158-3-kalesh-anakkur.purayil@broadcom.com
|
||||
Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
|
||||
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
||||
index be34c605d516..dfe3177123e5 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
|
||||
@@ -1750,9 +1750,9 @@ static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp,
|
||||
}
|
||||
}
|
||||
|
||||
-static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
|
||||
- struct bnxt_qplib_swqe *wqe,
|
||||
- u16 *idx)
|
||||
+static unsigned int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
|
||||
+ struct bnxt_qplib_swqe *wqe,
|
||||
+ u32 *idx)
|
||||
{
|
||||
struct bnxt_qplib_hwq *hwq;
|
||||
int len, t_len, offt;
|
||||
@@ -1769,7 +1769,7 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
|
||||
il_src = (void *)wqe->sg_list[indx].addr;
|
||||
t_len += len;
|
||||
if (t_len > qp->max_inline_data)
|
||||
- return -ENOMEM;
|
||||
+ return BNXT_RE_INVAL_MSG_SIZE;
|
||||
while (len) {
|
||||
if (pull_dst) {
|
||||
pull_dst = false;
|
||||
@@ -1795,9 +1795,9 @@ static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
|
||||
return t_len;
|
||||
}
|
||||
|
||||
-static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
|
||||
- struct bnxt_qplib_sge *ssge,
|
||||
- u16 nsge, u16 *idx)
|
||||
+static unsigned int bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
|
||||
+ struct bnxt_qplib_sge *ssge,
|
||||
+ u32 nsge, u32 *idx)
|
||||
{
|
||||
struct sq_sge *dsge;
|
||||
int indx, len = 0;
|
||||
@@ -1878,14 +1878,12 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
|
||||
struct bnxt_qplib_hwq *hwq;
|
||||
struct bnxt_qplib_swq *swq;
|
||||
bool sch_handler = false;
|
||||
+ u32 wqe_idx, slots, idx;
|
||||
u16 wqe_sz, qdf = 0;
|
||||
bool msn_update;
|
||||
void *base_hdr;
|
||||
void *ext_hdr;
|
||||
__le32 temp32;
|
||||
- u32 wqe_idx;
|
||||
- u32 slots;
|
||||
- u16 idx;
|
||||
|
||||
hwq = &sq->hwq;
|
||||
if (qp->state != CMDQ_MODIFY_QP_NEW_STATE_RTS &&
|
||||
@@ -1937,8 +1935,10 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
|
||||
else
|
||||
data_len = bnxt_qplib_put_sges(hwq, wqe->sg_list, wqe->num_sge,
|
||||
&idx);
|
||||
- if (data_len < 0)
|
||||
- goto queue_err;
|
||||
+ if (data_len > BNXT_RE_MAX_MSG_SIZE) {
|
||||
+ rc = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
/* Make sure we update MSN table only for wired wqes */
|
||||
msn_update = true;
|
||||
/* Specifics */
|
||||
@@ -2139,8 +2139,8 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
|
||||
struct bnxt_qplib_hwq *hwq;
|
||||
struct bnxt_qplib_swq *swq;
|
||||
bool sch_handler = false;
|
||||
- u16 wqe_sz, idx;
|
||||
- u32 wqe_idx;
|
||||
+ u32 wqe_idx, idx;
|
||||
+ u16 wqe_sz;
|
||||
int rc = 0;
|
||||
|
||||
hwq = &rq->hwq;
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
|
||||
index 0d9487c889ff..ab125f1d949e 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
|
||||
@@ -346,6 +346,9 @@ struct bnxt_qplib_qp {
|
||||
u8 tos_dscp;
|
||||
};
|
||||
|
||||
+#define BNXT_RE_MAX_MSG_SIZE 0x80000000
|
||||
+#define BNXT_RE_INVAL_MSG_SIZE 0xFFFFFFFF
|
||||
+
|
||||
#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)
|
||||
|
||||
#define CQE_CNT_PER_PG (PAGE_SIZE / BNXT_QPLIB_MAX_CQE_ENTRY_SIZE)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From ab6f51d337f71bac3f2fa37ef2508295fcf5323f Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 16:36:00 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Use macro instead of hard coded value
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 7788278ff267f831bab39a377beaa7e08d79c2a9
|
||||
Author: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Date: Fri Jul 4 10:08:57 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Use macro instead of hard coded value
|
||||
|
||||
1. Defined a macro for the hard coded value.
|
||||
2. "access" field in the request structure is of type "u8".
|
||||
Updated the mask accordingly.
|
||||
|
||||
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250704043857.19158-4-kalesh-anakkur.purayil@broadcom.com
|
||||
Reviewed-by: Hongguang Gao <hongguang.gao@broadcom.com>
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
|
||||
index 9efd32a3dc55..68981399598d 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
|
||||
@@ -674,7 +674,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
|
||||
req.log2_pbl_pg_size = cpu_to_le16(((ilog2(PAGE_SIZE) <<
|
||||
CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_SFT) &
|
||||
CMDQ_REGISTER_MR_LOG2_PBL_PG_SIZE_MASK));
|
||||
- req.access = (mr->access_flags & 0xFFFF);
|
||||
+ req.access = (mr->access_flags & BNXT_QPLIB_MR_ACCESS_MASK);
|
||||
req.va = cpu_to_le64(mr->va);
|
||||
req.key = cpu_to_le32(mr->lkey);
|
||||
if (_is_alloc_mr_unified(res->dattr->dev_cap_flags))
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
|
||||
index e626b05038a1..09faf4a1e849 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
|
||||
@@ -111,6 +111,7 @@ struct bnxt_qplib_mrw {
|
||||
struct bnxt_qplib_pd *pd;
|
||||
int type;
|
||||
u32 access_flags;
|
||||
+#define BNXT_QPLIB_MR_ACCESS_MASK 0xFF
|
||||
#define BNXT_QPLIB_FR_PMR 0x80000000
|
||||
u32 lkey;
|
||||
u32 rkey;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,311 @@
|
||||
From 8f82b5a5bc35f1760cc957cd20aa8d1b804f0076 Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:28:40 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Congestion control settings using debugfs hook
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 656dff55da19eb889f2b1df5a5f2aa1d28f024fd
|
||||
Author: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Date: Sun Jan 19 07:45:35 2025 -0800
|
||||
|
||||
RDMA/bnxt_re: Congestion control settings using debugfs hook
|
||||
|
||||
Implements routines to set and get different settings of
|
||||
the congestion control. This will enable the users to modify
|
||||
the settings according to their network.
|
||||
|
||||
Currently supporting only GEN 0 version of the parameters.
|
||||
Reading these files queries the firmware and report the values
|
||||
currently programmed. Writing to the files sends commands that
|
||||
update the congestion control settings
|
||||
|
||||
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Link: https://patch.msgid.link/1737301535-6599-1-git-send-email-selvin.xavier@broadcom.com
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
|
||||
index b758705e2062..6df5a2738c95 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
|
||||
@@ -225,6 +225,8 @@ struct bnxt_re_dev {
|
||||
unsigned long event_bitmap;
|
||||
struct bnxt_qplib_cc_param cc_param;
|
||||
struct workqueue_struct *dcb_wq;
|
||||
+ struct dentry *cc_config;
|
||||
+ struct bnxt_re_dbg_cc_config_params *cc_config_params;
|
||||
};
|
||||
|
||||
#define to_bnxt_re_dev(ptr, member) \
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
index 7c47039044ef..f4dd2fb51867 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
@@ -22,6 +22,23 @@
|
||||
|
||||
static struct dentry *bnxt_re_debugfs_root;
|
||||
|
||||
+static const char * const bnxt_re_cc_gen0_name[] = {
|
||||
+ "enable_cc",
|
||||
+ "run_avg_weight_g",
|
||||
+ "num_phase_per_state",
|
||||
+ "init_cr",
|
||||
+ "init_tr",
|
||||
+ "tos_ecn",
|
||||
+ "tos_dscp",
|
||||
+ "alt_vlan_pcp",
|
||||
+ "alt_vlan_dscp",
|
||||
+ "rtt",
|
||||
+ "cc_mode",
|
||||
+ "tcp_cp",
|
||||
+ "tx_queue",
|
||||
+ "inactivity_cp",
|
||||
+};
|
||||
+
|
||||
static inline const char *bnxt_re_qp_state_str(u8 state)
|
||||
{
|
||||
switch (state) {
|
||||
@@ -110,19 +127,212 @@ void bnxt_re_debug_rem_qpinfo(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp)
|
||||
debugfs_remove(qp->dentry);
|
||||
}
|
||||
|
||||
+static int map_cc_config_offset_gen0_ext0(u32 offset, struct bnxt_qplib_cc_param *ccparam, u32 *val)
|
||||
+{
|
||||
+ u64 map_offset;
|
||||
+
|
||||
+ map_offset = BIT(offset);
|
||||
+
|
||||
+ switch (map_offset) {
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC:
|
||||
+ *val = ccparam->enable;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G:
|
||||
+ *val = ccparam->g;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE:
|
||||
+ *val = ccparam->nph_per_state;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR:
|
||||
+ *val = ccparam->init_cr;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR:
|
||||
+ *val = ccparam->init_tr;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN:
|
||||
+ *val = ccparam->tos_ecn;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP:
|
||||
+ *val = ccparam->tos_dscp;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP:
|
||||
+ *val = ccparam->alt_vlan_pcp;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP:
|
||||
+ *val = ccparam->alt_tos_dscp;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT:
|
||||
+ *val = ccparam->rtt;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE:
|
||||
+ *val = ccparam->cc_mode;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
|
||||
+ *val = ccparam->tcp_cp;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer,
|
||||
+ size_t usr_buf_len, loff_t *ppos)
|
||||
+{
|
||||
+ struct bnxt_re_cc_param *dbg_cc_param = filp->private_data;
|
||||
+ struct bnxt_re_dev *rdev = dbg_cc_param->rdev;
|
||||
+ struct bnxt_qplib_cc_param ccparam = {};
|
||||
+ u32 offset = dbg_cc_param->offset;
|
||||
+ char buf[16];
|
||||
+ u32 val;
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = bnxt_qplib_query_cc_param(&rdev->qplib_res, &ccparam);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = map_cc_config_offset_gen0_ext0(offset, &ccparam, &val);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = snprintf(buf, sizeof(buf), "%d\n", val);
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
+
|
||||
+ return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc);
|
||||
+}
|
||||
+
|
||||
+static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
|
||||
+{
|
||||
+ u32 modify_mask;
|
||||
+
|
||||
+ modify_mask = BIT(offset);
|
||||
+
|
||||
+ switch (modify_mask) {
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ENABLE_CC:
|
||||
+ ccparam->enable = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_G:
|
||||
+ ccparam->g = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_NUMPHASEPERSTATE:
|
||||
+ ccparam->nph_per_state = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_CR:
|
||||
+ ccparam->init_cr = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INIT_TR:
|
||||
+ ccparam->init_tr = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_ECN:
|
||||
+ ccparam->tos_ecn = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TOS_DSCP:
|
||||
+ ccparam->tos_dscp = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_VLAN_PCP:
|
||||
+ ccparam->alt_vlan_pcp = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_ALT_TOS_DSCP:
|
||||
+ ccparam->alt_tos_dscp = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_RTT:
|
||||
+ ccparam->rtt = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_CC_MODE:
|
||||
+ ccparam->cc_mode = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
|
||||
+ ccparam->tcp_cp = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE:
|
||||
+ ccparam->time_pph = val;
|
||||
+ break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_PKTS_PER_PHASE:
|
||||
+ ccparam->pkts_pph = val;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ccparam->mask = modify_mask;
|
||||
+}
|
||||
+
|
||||
+static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val)
|
||||
+{
|
||||
+ struct bnxt_qplib_cc_param ccparam = { };
|
||||
+
|
||||
+ /* Supporting only Gen 0 now */
|
||||
+ if (gen_ext != CC_CONFIG_GEN0_EXT0)
|
||||
+ bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
|
||||
+ else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t bnxt_re_cc_config_set(struct file *filp, const char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct bnxt_re_cc_param *dbg_cc_param = filp->private_data;
|
||||
+ struct bnxt_re_dev *rdev = dbg_cc_param->rdev;
|
||||
+ u32 offset = dbg_cc_param->offset;
|
||||
+ u8 cc_gen = dbg_cc_param->cc_gen;
|
||||
+ char buf[16];
|
||||
+ u32 val;
|
||||
+ int rc;
|
||||
+
|
||||
+ if (copy_from_user(buf, buffer, count))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[count] = '\0';
|
||||
+ if (kstrtou32(buf, 0, &val))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ rc = bnxt_re_configure_cc(rdev, cc_gen, offset, val);
|
||||
+ return rc ? rc : count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations bnxt_re_cc_config_ops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = simple_open,
|
||||
+ .read = bnxt_re_cc_config_get,
|
||||
+ .write = bnxt_re_cc_config_set,
|
||||
+};
|
||||
+
|
||||
void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct pci_dev *pdev = rdev->en_dev->pdev;
|
||||
+ struct bnxt_re_dbg_cc_config_params *cc_params;
|
||||
+ int i;
|
||||
|
||||
rdev->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), bnxt_re_debugfs_root);
|
||||
|
||||
rdev->qp_debugfs = debugfs_create_dir("QPs", rdev->dbg_root);
|
||||
+ rdev->cc_config = debugfs_create_dir("cc_config", rdev->dbg_root);
|
||||
+
|
||||
+ rdev->cc_config_params = kzalloc(sizeof(*cc_params), GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < BNXT_RE_CC_PARAM_GEN0; i++) {
|
||||
+ struct bnxt_re_cc_param *tmp_params = &rdev->cc_config_params->gen0_parms[i];
|
||||
+
|
||||
+ tmp_params->rdev = rdev;
|
||||
+ tmp_params->offset = i;
|
||||
+ tmp_params->cc_gen = CC_CONFIG_GEN0_EXT0;
|
||||
+ tmp_params->dentry = debugfs_create_file(bnxt_re_cc_gen0_name[i], 0400,
|
||||
+ rdev->cc_config, tmp_params,
|
||||
+ &bnxt_re_cc_config_ops);
|
||||
+ }
|
||||
}
|
||||
|
||||
void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
debugfs_remove_recursive(rdev->qp_debugfs);
|
||||
-
|
||||
+ debugfs_remove_recursive(rdev->cc_config);
|
||||
+ kfree(rdev->cc_config_params);
|
||||
debugfs_remove_recursive(rdev->dbg_root);
|
||||
rdev->dbg_root = NULL;
|
||||
}
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.h b/drivers/infiniband/hw/bnxt_re/debugfs.h
|
||||
index cd3be0a9ec7e..8f101df4e838 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.h
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.h
|
||||
@@ -18,4 +18,19 @@ void bnxt_re_debugfs_rem_pdev(struct bnxt_re_dev *rdev);
|
||||
void bnxt_re_register_debugfs(void);
|
||||
void bnxt_re_unregister_debugfs(void);
|
||||
|
||||
+#define CC_CONFIG_GEN_EXT(x, y) (((x) << 16) | (y))
|
||||
+#define CC_CONFIG_GEN0_EXT0 CC_CONFIG_GEN_EXT(0, 0)
|
||||
+
|
||||
+#define BNXT_RE_CC_PARAM_GEN0 14
|
||||
+
|
||||
+struct bnxt_re_cc_param {
|
||||
+ struct bnxt_re_dev *rdev;
|
||||
+ struct dentry *dentry;
|
||||
+ u32 offset;
|
||||
+ u8 cc_gen;
|
||||
+};
|
||||
+
|
||||
+struct bnxt_re_dbg_cc_config_params {
|
||||
+ struct bnxt_re_cc_param gen0_parms[BNXT_RE_CC_PARAM_GEN0];
|
||||
+};
|
||||
#endif
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 62a794efee2f8717d599696c8e1933b675c727e9 Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:30:09 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Fix buffer overflow in debugfs code
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit dbc641ecf1cbd41a649e7ac6ea7175562ef599b2
|
||||
Author: Dan Carpenter <dan.carpenter@linaro.org>
|
||||
Date: Fri Feb 7 12:16:19 2025 +0300
|
||||
|
||||
RDMA/bnxt_re: Fix buffer overflow in debugfs code
|
||||
|
||||
Add some bounds checking to prevent memory corruption in
|
||||
bnxt_re_cc_config_set(). This is debugfs code so the bug can only be
|
||||
triggered by root.
|
||||
|
||||
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
|
||||
Link: https://patch.msgid.link/a6b081ab-55fe-4d0c-8f69-c5e5a59e9141@stanley.mountain
|
||||
Acked-by: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
index f4dd2fb51867..d7354e7753fe 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
@@ -285,6 +285,9 @@ static ssize_t bnxt_re_cc_config_set(struct file *filp, const char __user *buffe
|
||||
u32 val;
|
||||
int rc;
|
||||
|
||||
+ if (count >= sizeof(buf))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if (copy_from_user(buf, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 01d9de21a2cdbcaf02378da7cb143a2c5b84547a Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:31:21 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Fix the condition check while programming
|
||||
congestion control
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit f26e648a978ae7958e0958095768363c851a736d
|
||||
Author: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Date: Sat Feb 8 05:48:26 2025 -0800
|
||||
|
||||
RDMA/bnxt_re: Fix the condition check while programming congestion control
|
||||
|
||||
Program the Congestion control values when the CC gen matches.
|
||||
Fix the condition check for the same.
|
||||
|
||||
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
|
||||
Reported-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Reported-by: Chengchang Tang <tangchengchang@huawei.com>
|
||||
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
|
||||
Link: https://patch.msgid.link/1739022506-8937-1-git-send-email-selvin.xavier@broadcom.com
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
index d7354e7753fe..af91d16c3c77 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
@@ -265,7 +265,7 @@ static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offse
|
||||
struct bnxt_qplib_cc_param ccparam = { };
|
||||
|
||||
/* Supporting only Gen 0 now */
|
||||
- if (gen_ext != CC_CONFIG_GEN0_EXT0)
|
||||
+ if (gen_ext == CC_CONFIG_GEN0_EXT0)
|
||||
bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
|
||||
else
|
||||
return -EINVAL;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 1938524b38203de2db0bbd8ffffbc96bf23a5e9b Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:32:40 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Fix incorrect display of inactivity_cp in
|
||||
debugfs output
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 58d7a965bb2b014d467445d38cdb07099b1f0f77
|
||||
Author: Gautam R A <gautam-r.a@broadcom.com>
|
||||
Date: Tue May 20 09:29:07 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Fix incorrect display of inactivity_cp in debugfs output
|
||||
|
||||
The inactivity_cp parameter in debugfs was not being read or
|
||||
written correctly, resulting in "Invalid argument" errors.
|
||||
|
||||
Fixed this by ensuring proper mapping of inactivity_cp in
|
||||
both the map_cc_config_offset_gen0_ext0 and
|
||||
bnxt_re_fill_gen0_ext0() functions.
|
||||
|
||||
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
|
||||
Signed-off-by: Gautam R A <gautam-r.a@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250520035910.1061918-2-kalesh-anakkur.purayil@broadcom.com
|
||||
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
index af91d16c3c77..a3aad6c3dbec 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
@@ -170,6 +170,9 @@ static int map_cc_config_offset_gen0_ext0(u32 offset, struct bnxt_qplib_cc_param
|
||||
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TCP_CP:
|
||||
*val = ccparam->tcp_cp;
|
||||
break;
|
||||
+ case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
|
||||
+ *val = ccparam->inact_th;
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -247,7 +250,9 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
|
||||
ccparam->tcp_cp = val;
|
||||
break;
|
||||
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
|
||||
+ break;
|
||||
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
|
||||
+ ccparam->inact_th = val;
|
||||
break;
|
||||
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TIME_PER_PHASE:
|
||||
ccparam->time_pph = val;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
From bc635dde20a74550cf70a2e7f5b25ce3f07db3ed Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:32:52 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Fix missing error handling for tx_queue
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit e3d57a00d4d1f36689e9eab80b60d5024361efec
|
||||
Author: Gautam R A <gautam-r.a@broadcom.com>
|
||||
Date: Tue May 20 09:29:08 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Fix missing error handling for tx_queue
|
||||
|
||||
bnxt_re_fill_gen0_ext0() did not return an error when
|
||||
attempting to modify CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE,
|
||||
leading to silent failures.
|
||||
|
||||
Fixed this by returning -EOPNOTSUPP for tx_queue modifications and
|
||||
ensuring proper error propagation in bnxt_re_configure_cc().
|
||||
|
||||
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
|
||||
Signed-off-by: Gautam R A <gautam-r.a@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250520035910.1061918-3-kalesh-anakkur.purayil@broadcom.com
|
||||
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
index a3aad6c3dbec..9f6392155d91 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
@@ -206,7 +206,7 @@ static ssize_t bnxt_re_cc_config_get(struct file *filp, char __user *buffer,
|
||||
return simple_read_from_buffer(buffer, usr_buf_len, ppos, (u8 *)(buf), rc);
|
||||
}
|
||||
|
||||
-static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
|
||||
+static int bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offset, u32 val)
|
||||
{
|
||||
u32 modify_mask;
|
||||
|
||||
@@ -250,7 +250,7 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
|
||||
ccparam->tcp_cp = val;
|
||||
break;
|
||||
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_TX_QUEUE:
|
||||
- break;
|
||||
+ return -EOPNOTSUPP;
|
||||
case CMDQ_MODIFY_ROCE_CC_MODIFY_MASK_INACTIVITY_CP:
|
||||
ccparam->inact_th = val;
|
||||
break;
|
||||
@@ -263,18 +263,21 @@ static void bnxt_re_fill_gen0_ext0(struct bnxt_qplib_cc_param *ccparam, u32 offs
|
||||
}
|
||||
|
||||
ccparam->mask = modify_mask;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offset, u32 val)
|
||||
{
|
||||
struct bnxt_qplib_cc_param ccparam = { };
|
||||
+ int rc;
|
||||
|
||||
- /* Supporting only Gen 0 now */
|
||||
- if (gen_ext == CC_CONFIG_GEN0_EXT0)
|
||||
- bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
|
||||
- else
|
||||
+ if (gen_ext != CC_CONFIG_GEN0_EXT0)
|
||||
return -EINVAL;
|
||||
|
||||
+ rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
bnxt_qplib_modify_cc(&rdev->qplib_res, &ccparam);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From a646adda44acd8b4eca1b95ed00609a27bbd390c Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:32:59 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: Fix return code of bnxt_re_configure_cc
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit 990b5c07f677a0b633b41130a70771337c18343e
|
||||
Author: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Date: Tue May 20 09:29:09 2025 +0530
|
||||
|
||||
RDMA/bnxt_re: Fix return code of bnxt_re_configure_cc
|
||||
|
||||
Driver currently supports modifying GEN0_EXT0 CC parameters
|
||||
through debugfs hook.
|
||||
|
||||
Fixed to return -EOPNOTSUPP instead of -EINVAL in bnxt_re_configure_cc()
|
||||
when the user tries to modify any other CC parameters.
|
||||
|
||||
Fixes: 656dff55da19 ("RDMA/bnxt_re: Congestion control settings using debugfs hook")
|
||||
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
|
||||
Link: https://patch.msgid.link/20250520035910.1061918-4-kalesh-anakkur.purayil@broadcom.com
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
index 9f6392155d91..e632f1661b92 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/debugfs.c
|
||||
@@ -272,7 +272,7 @@ static int bnxt_re_configure_cc(struct bnxt_re_dev *rdev, u32 gen_ext, u32 offse
|
||||
int rc;
|
||||
|
||||
if (gen_ext != CC_CONFIG_GEN0_EXT0)
|
||||
- return -EINVAL;
|
||||
+ return -EOPNOTSUPP;
|
||||
|
||||
rc = bnxt_re_fill_gen0_ext0(&ccparam, offset, val);
|
||||
if (rc)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,94 @@
|
||||
From 489b805b61b98f02178efdbe33f9d3f11f039fd0 Mon Sep 17 00:00:00 2001
|
||||
From: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
Date: Tue, 19 Aug 2025 14:33:06 -0700
|
||||
Subject: [PATCH] RDMA/bnxt_re: convert timeouts to secs_to_jiffies()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108696
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-96539
|
||||
|
||||
commit f873136416293b786e7611d36226c9f5a8f6d20b
|
||||
Author: Easwar Hariharan <eahariha@linux.microsoft.com>
|
||||
Date: Tue Feb 25 20:17:30 2025 +0000
|
||||
|
||||
RDMA/bnxt_re: convert timeouts to secs_to_jiffies()
|
||||
|
||||
Commit b35108a51cf7 ("jiffies: Define secs_to_jiffies()") introduced
|
||||
secs_to_jiffies(). As the value here is a multiple of 1000, use
|
||||
secs_to_jiffies() instead of msecs_to_jiffies() to avoid the
|
||||
multiplication
|
||||
|
||||
This is converted using scripts/coccinelle/misc/secs_to_jiffies.cocci with
|
||||
the following Coccinelle rules:
|
||||
|
||||
@depends on patch@
|
||||
expression E;
|
||||
@@
|
||||
|
||||
-msecs_to_jiffies
|
||||
+secs_to_jiffies
|
||||
(E
|
||||
- * \( 1000 \| MSEC_PER_SEC \)
|
||||
)
|
||||
|
||||
Link: https://lkml.kernel.org/r/20250225-converge-secs-to-jiffies-part-two-v3-16-a43967e36c88@linux.microsoft.com
|
||||
Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
|
||||
Cc: Carlos Maiolino <cem@kernel.org>
|
||||
Cc: Carlos Maiolino <cmaiolino@redhat.com>
|
||||
Cc: Chris Mason <clm@fb.com>
|
||||
Cc: Christoph Hellwig <hch@lst.de>
|
||||
Cc: Damien Le Maol <dlemoal@kernel.org>
|
||||
Cc: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Cc: David Sterba <dsterba@suse.com>
|
||||
Cc: Dick Kennedy <dick.kennedy@broadcom.com>
|
||||
Cc: Dongsheng Yang <dongsheng.yang@easystack.cn>
|
||||
Cc: Fabio Estevam <festevam@gmail.com>
|
||||
Cc: Frank Li <frank.li@nxp.com>
|
||||
Cc: Hans de Goede <hdegoede@redhat.com>
|
||||
Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
Cc: Ilpo Jarvinen <ilpo.jarvinen@linux.intel.com>
|
||||
Cc: Ilya Dryomov <idryomov@gmail.com>
|
||||
Cc: James Bottomley <james.bottomley@HansenPartnership.com>
|
||||
Cc: James Smart <james.smart@broadcom.com>
|
||||
Cc: Jaroslav Kysela <perex@perex.cz>
|
||||
Cc: Jason Gunthorpe <jgg@ziepe.ca>
|
||||
Cc: Jens Axboe <axboe@kernel.dk>
|
||||
Cc: Josef Bacik <josef@toxicpanda.com>
|
||||
Cc: Julia Lawall <julia.lawall@inria.fr>
|
||||
Cc: Kalesh Anakkur Purayil <kalesh-anakkur.purayil@broadcom.com>
|
||||
Cc: Keith Busch <kbusch@kernel.org>
|
||||
Cc: Leon Romanovsky <leon@kernel.org>
|
||||
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
Cc: Mark Brown <broonie@kernel.org>
|
||||
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
|
||||
Cc: Nicolas Palix <nicolas.palix@imag.fr>
|
||||
Cc: Niklas Cassel <cassel@kernel.org>
|
||||
Cc: Oded Gabbay <ogabbay@kernel.org>
|
||||
Cc: Sagi Grimberg <sagi@grimberg.me>
|
||||
Cc: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Cc: Sebastian Reichel <sre@kernel.org>
|
||||
Cc: Selvin Thyparampil Xavier <selvin.xavier@broadcom.com>
|
||||
Cc: Shawn Guo <shawnguo@kernel.org>
|
||||
Cc: Shyam-sundar S-k <Shyam-sundar.S-k@amd.com>
|
||||
Cc: Takashi Iwai <tiwai@suse.com>
|
||||
Cc: Takashi Iwai <tiwai@suse.de>
|
||||
Cc: Xiubo Li <xiubli@redhat.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
|
||||
Signed-off-by: Sreekanth Reddy <sreeredd@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
|
||||
index d23074383428..804bc773b4ef 100644
|
||||
--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
|
||||
+++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
|
||||
@@ -160,7 +160,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
|
||||
wait_event_timeout(cmdq->waitq,
|
||||
!crsqe->is_in_used ||
|
||||
test_bit(ERR_DEVICE_DETACHED, &cmdq->flags),
|
||||
- msecs_to_jiffies(rcfw->max_timeout * 1000));
|
||||
+ secs_to_jiffies(rcfw->max_timeout));
|
||||
|
||||
if (!crsqe->is_in_used)
|
||||
return 0;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From cbcb3cfcdc436d6f91a3d95ecfa9c831abe14aed Mon Sep 17 00:00:00 2001
|
||||
From: Mohammad Heib <mheib@redhat.com>
|
||||
Date: Tue, 17 Mar 2026 19:08:06 +0200
|
||||
Subject: [PATCH] ionic: fix persistent MAC address override on PF
|
||||
|
||||
The use of IONIC_CMD_LIF_SETATTR in the MAC address update path causes
|
||||
the ionic firmware to update the LIF's identity in its persistent state.
|
||||
Since the firmware state is maintained across host warm boots and driver
|
||||
reloads, any MAC change on the Physical Function (PF) becomes "sticky.
|
||||
|
||||
This is problematic because it causes ethtool -P to report the
|
||||
user-configured MAC as the permanent factory address, which breaks
|
||||
system management tools that rely on a stable hardware identity.
|
||||
|
||||
While Virtual Functions (VFs) need this hardware-level programming to
|
||||
properly handle MAC assignments in guest environments, the PF should
|
||||
maintain standard transient behavior. This patch gates the
|
||||
ionic_program_mac call using is_virtfn so that PF MAC changes remain
|
||||
local to the netdev filters and do not overwrite the firmware's
|
||||
permanent identity block.
|
||||
|
||||
Fixes: 19058be7c48c ("ionic: VF initial random MAC address if no assigned mac")
|
||||
Signed-off-by: Mohammad Heib <mheib@redhat.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
|
||||
Link: https://patch.msgid.link/20260317170806.35390-1-mheib@redhat.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
|
||||
index 8d040e611d5a..637e635bbf03 100644
|
||||
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
|
||||
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
|
||||
@@ -1719,13 +1719,18 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
|
||||
if (ether_addr_equal(netdev->dev_addr, mac))
|
||||
return 0;
|
||||
|
||||
- err = ionic_program_mac(lif, mac);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+ /* Only program macs for virtual functions to avoid losing the permanent
|
||||
+ * Mac across warm reset/reboot.
|
||||
+ */
|
||||
+ if (lif->ionic->pdev->is_virtfn) {
|
||||
+ err = ionic_program_mac(lif, mac);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
|
||||
- if (err > 0)
|
||||
- netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
|
||||
- __func__);
|
||||
+ if (err > 0)
|
||||
+ netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
|
||||
+ __func__);
|
||||
+ }
|
||||
|
||||
err = eth_prepare_mac_addr_change(netdev, addr);
|
||||
if (err)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
From def2d2719295c70f747e7bd1cb56fc51992c6977 Mon Sep 17 00:00:00 2001
|
||||
From: Paulo Alcantara <paalcant@redhat.com>
|
||||
Date: Mon, 23 Mar 2026 19:10:59 -0300
|
||||
Subject: [PATCH] smb: client: fix krb5 mount with username option
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-156455
|
||||
|
||||
commit 12b4c5d98cd7ca46d5035a57bcd995df614c14e1
|
||||
Author: Paulo Alcantara <pc@manguebit.org>
|
||||
Date: Fri Mar 13 00:03:38 2026 -0300
|
||||
|
||||
smb: client: fix krb5 mount with username option
|
||||
|
||||
Customer reported that some of their krb5 mounts were failing against
|
||||
a single server as the client was trying to mount the shares with
|
||||
wrong credentials. It turned out the client was reusing SMB session
|
||||
from first mount to try mounting the other shares, even though a
|
||||
different username= option had been specified to the other mounts.
|
||||
|
||||
By using username mount option along with sec=krb5 to search for
|
||||
principals from keytab is supported by cifs.upcall(8) since
|
||||
cifs-utils-4.8. So fix this by matching username mount option in
|
||||
match_session() even with Kerberos.
|
||||
|
||||
For example, the second mount below should fail with -ENOKEY as there
|
||||
is no 'foobar' principal in keytab (/etc/krb5.keytab). The client
|
||||
ends up reusing SMB session from first mount to perform the second
|
||||
one, which is wrong.
|
||||
|
||||
```
|
||||
$ ktutil
|
||||
ktutil: add_entry -password -p testuser -k 1 -e aes256-cts
|
||||
Password for testuser@ZELDA.TEST:
|
||||
ktutil: write_kt /etc/krb5.keytab
|
||||
ktutil: quit
|
||||
$ klist -ke
|
||||
Keytab name: FILE:/etc/krb5.keytab
|
||||
KVNO Principal
|
||||
---- ----------------------------------------------------------------
|
||||
1 testuser@ZELDA.TEST (aes256-cts-hmac-sha1-96)
|
||||
$ mount.cifs //w22-root2/scratch /mnt/1 -o sec=krb5,username=testuser
|
||||
$ mount.cifs //w22-root2/scratch /mnt/2 -o sec=krb5,username=foobar
|
||||
$ mount -t cifs | grep -Po 'username=\K\w+'
|
||||
testuser
|
||||
testuser
|
||||
```
|
||||
|
||||
Reported-by: Oscar Santos <ossantos@redhat.com>
|
||||
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
|
||||
Cc: David Howells <dhowells@redhat.com>
|
||||
Cc: linux-cifs@vger.kernel.org
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Steve French <stfrench@microsoft.com>
|
||||
|
||||
Signed-off-by: Paulo Alcantara <paalcant@redhat.com>
|
||||
|
||||
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
|
||||
index 3e06f59ba8ad..0c2dea25572d 100644
|
||||
--- a/fs/smb/client/connect.c
|
||||
+++ b/fs/smb/client/connect.c
|
||||
@@ -1954,6 +1954,10 @@ static int match_session(struct cifs_ses *ses,
|
||||
case Kerberos:
|
||||
if (!uid_eq(ctx->cred_uid, ses->cred_uid))
|
||||
return 0;
|
||||
+ if (strncmp(ses->user_name ?: "",
|
||||
+ ctx->username ?: "",
|
||||
+ CIFS_MAX_USERNAME_LEN))
|
||||
+ return 0;
|
||||
break;
|
||||
case NTLMv2:
|
||||
case RawNTLMSSP:
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From b05914e695853c3784f3fd1b588cabc025cf4337 Mon Sep 17 00:00:00 2001
|
||||
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
Date: Thu, 26 Mar 2026 20:21:27 +0000
|
||||
Subject: [PATCH] scsi: qla2xxx: Fix improper freeing of purex item
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-161149
|
||||
CVE: CVE-2025-68741
|
||||
|
||||
commit 78b1a242fe612a755f2158fd206ee6bb577d18ca
|
||||
Author: Zilin Guan <zilin@seu.edu.cn>
|
||||
Date: Thu Nov 13 15:12:46 2025 +0000
|
||||
|
||||
scsi: qla2xxx: Fix improper freeing of purex item
|
||||
|
||||
In qla2xxx_process_purls_iocb(), an item is allocated via
|
||||
qla27xx_copy_multiple_pkt(), which internally calls
|
||||
qla24xx_alloc_purex_item().
|
||||
|
||||
The qla24xx_alloc_purex_item() function may return a pre-allocated item
|
||||
from a per-adapter pool for small allocations, instead of dynamically
|
||||
allocating memory with kzalloc().
|
||||
|
||||
An error handling path in qla2xxx_process_purls_iocb() incorrectly uses
|
||||
kfree() to release the item. If the item was from the pre-allocated
|
||||
pool, calling kfree() on it is a bug that can lead to memory corruption.
|
||||
|
||||
Fix this by using the correct deallocation function,
|
||||
qla24xx_free_purex_item(), which properly handles both dynamically
|
||||
allocated and pre-allocated items.
|
||||
|
||||
Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe")
|
||||
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
|
||||
Reviewed-by: Himanshu Madhani <hmadhani2024@gmail.com>
|
||||
Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn
|
||||
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
||||
|
||||
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
|
||||
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
|
||||
index 8ee2e337c9e1..6ecf3da765aa 100644
|
||||
--- a/drivers/scsi/qla2xxx/qla_nvme.c
|
||||
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
|
||||
@@ -1292,7 +1292,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp)
|
||||
a.reason = FCNVME_RJT_RC_LOGIC;
|
||||
a.explanation = FCNVME_RJT_EXP_NONE;
|
||||
xmt_reject = true;
|
||||
- kfree(item);
|
||||
+ qla24xx_free_purex_item(item);
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
From 5133b61aaf437e5f25b1b396b14242a6bb0508e2 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@kernel.org>
|
||||
Date: Tue, 24 Feb 2026 11:33:35 -0500
|
||||
Subject: [PATCH] nfsd: fix heap overflow in NFSv4.0 LOCK replay cache
|
||||
|
||||
The NFSv4.0 replay cache uses a fixed 112-byte inline buffer
|
||||
(rp_ibuf[NFSD4_REPLAY_ISIZE]) to store encoded operation responses.
|
||||
This size was calculated based on OPEN responses and does not account
|
||||
for LOCK denied responses, which include the conflicting lock owner as
|
||||
a variable-length field up to 1024 bytes (NFS4_OPAQUE_LIMIT).
|
||||
|
||||
When a LOCK operation is denied due to a conflict with an existing lock
|
||||
that has a large owner, nfsd4_encode_operation() copies the full encoded
|
||||
response into the undersized replay buffer via read_bytes_from_xdr_buf()
|
||||
with no bounds check. This results in a slab-out-of-bounds write of up
|
||||
to 944 bytes past the end of the buffer, corrupting adjacent heap memory.
|
||||
|
||||
This can be triggered remotely by an unauthenticated attacker with two
|
||||
cooperating NFSv4.0 clients: one sets a lock with a large owner string,
|
||||
then the other requests a conflicting lock to provoke the denial.
|
||||
|
||||
We could fix this by increasing NFSD4_REPLAY_ISIZE to allow for a full
|
||||
opaque, but that would increase the size of every stateowner, when most
|
||||
lockowners are not that large.
|
||||
|
||||
Instead, fix this by checking the encoded response length against
|
||||
NFSD4_REPLAY_ISIZE before copying into the replay buffer. If the
|
||||
response is too large, set rp_buflen to 0 to skip caching the replay
|
||||
payload. The status is still cached, and the client already received the
|
||||
correct response on the original request.
|
||||
|
||||
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
|
||||
Cc: stable@kernel.org
|
||||
Reported-by: Nicholas Carlini <npc@anthropic.com>
|
||||
Tested-by: Nicholas Carlini <npc@anthropic.com>
|
||||
Signed-off-by: Jeff Layton <jlayton@kernel.org>
|
||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
||||
|
||||
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
|
||||
index 5172dbd0cb05..fa16b34fae50 100644
|
||||
--- a/fs/nfsd/nfs4xdr.c
|
||||
+++ b/fs/nfsd/nfs4xdr.c
|
||||
@@ -6281,9 +6281,14 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
|
||||
int len = xdr->buf->len - (op_status_offset + XDR_UNIT);
|
||||
|
||||
so->so_replay.rp_status = op->status;
|
||||
- so->so_replay.rp_buflen = len;
|
||||
- read_bytes_from_xdr_buf(xdr->buf, op_status_offset + XDR_UNIT,
|
||||
+ if (len <= NFSD4_REPLAY_ISIZE) {
|
||||
+ so->so_replay.rp_buflen = len;
|
||||
+ read_bytes_from_xdr_buf(xdr->buf,
|
||||
+ op_status_offset + XDR_UNIT,
|
||||
so->so_replay.rp_buf, len);
|
||||
+ } else {
|
||||
+ so->so_replay.rp_buflen = 0;
|
||||
+ }
|
||||
}
|
||||
status:
|
||||
op->status = nfsd4_map_status(op->status,
|
||||
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
|
||||
index 6fcbf1e427d4..c0ca115c3b74 100644
|
||||
--- a/fs/nfsd/state.h
|
||||
+++ b/fs/nfsd/state.h
|
||||
@@ -541,11 +541,18 @@ struct nfs4_client_reclaim {
|
||||
struct xdr_netobj cr_princhash;
|
||||
};
|
||||
|
||||
-/* A reasonable value for REPLAY_ISIZE was estimated as follows:
|
||||
- * The OPEN response, typically the largest, requires
|
||||
- * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) +
|
||||
- * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
|
||||
- * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
|
||||
+/*
|
||||
+ * REPLAY_ISIZE is sized for an OPEN response with delegation:
|
||||
+ * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +
|
||||
+ * 8(verifier) + 4(deleg. type) + 8(deleg. stateid) +
|
||||
+ * 4(deleg. recall flag) + 20(deleg. space limit) +
|
||||
+ * ~32(deleg. ace) = 112 bytes
|
||||
+ *
|
||||
+ * Some responses can exceed this. A LOCK denial includes the conflicting
|
||||
+ * lock owner, which can be up to 1024 bytes (NFS4_OPAQUE_LIMIT). Responses
|
||||
+ * larger than REPLAY_ISIZE are not cached in rp_ibuf; only rp_status is
|
||||
+ * saved. Enlarging this constant increases the size of every
|
||||
+ * nfs4_stateowner.
|
||||
*/
|
||||
|
||||
#define NFSD4_REPLAY_ISIZE 112
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
39
SOURCES/1120-net-add-skb-header-pointer-careful-helper.patch
Normal file
39
SOURCES/1120-net-add-skb-header-pointer-careful-helper.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 13e00fdc9236bd4d0bff4109d2983171fbcb74c4 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Wed, 28 Jan 2026 14:15:38 +0000
|
||||
Subject: [PATCH] net: add skb_header_pointer_careful() helper
|
||||
|
||||
This variant of skb_header_pointer() should be used in contexts
|
||||
where @offset argument is user-controlled and could be negative.
|
||||
|
||||
Negative offsets are supported, as long as the zone starts
|
||||
between skb->head and skb->data.
|
||||
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Link: https://patch.msgid.link/20260128141539.3404400-2-edumazet@google.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
|
||||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
|
||||
index 3f4decc..574edae 100644
|
||||
--- a/include/linux/skbuff.h
|
||||
+++ b/include/linux/skbuff.h
|
||||
@@ -4043,6 +4043,18 @@ skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer)
|
||||
skb_headlen(skb), buffer);
|
||||
}
|
||||
|
||||
+/* Variant of skb_header_pointer() where @offset is user-controlled
|
||||
+ * and potentially negative.
|
||||
+ */
|
||||
+static inline void * __must_check
|
||||
+skb_header_pointer_careful(const struct sk_buff *skb, int offset,
|
||||
+ int len, void *buffer)
|
||||
+{
|
||||
+ if (unlikely(offset < 0 && -offset > skb_headroom(skb)))
|
||||
+ return NULL;
|
||||
+ return skb_header_pointer(skb, offset, len, buffer);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* skb_needs_linearize - check if we need to linearize a given skb
|
||||
* depending on the given device features.
|
||||
@ -0,0 +1,62 @@
|
||||
From cabd1a976375780dabab888784e356f574bbaed8 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Wed, 28 Jan 2026 14:15:39 +0000
|
||||
Subject: [PATCH] net/sched: cls_u32: use skb_header_pointer_careful()
|
||||
|
||||
skb_header_pointer() does not fully validate negative @offset values.
|
||||
|
||||
Use skb_header_pointer_careful() instead.
|
||||
|
||||
GangMin Kim provided a report and a repro fooling u32_classify():
|
||||
|
||||
BUG: KASAN: slab-out-of-bounds in u32_classify+0x1180/0x11b0
|
||||
net/sched/cls_u32.c:221
|
||||
|
||||
Fixes: fbc2e7d9cf49 ("cls_u32: use skb_header_pointer() to dereference data safely")
|
||||
Reported-by: GangMin Kim <km.kim1503@gmail.com>
|
||||
Closes: https://lore.kernel.org/netdev/CANn89iJkyUZ=mAzLzC4GdcAgLuPnUoivdLaOs6B9rq5_erj76w@mail.gmail.com/T/
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Link: https://patch.msgid.link/20260128141539.3404400-3-edumazet@google.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
|
||||
index 2a1c00048fd6..58e849c0acf4 100644
|
||||
--- a/net/sched/cls_u32.c
|
||||
+++ b/net/sched/cls_u32.c
|
||||
@@ -161,10 +161,8 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
|
||||
int toff = off + key->off + (off2 & key->offmask);
|
||||
__be32 *data, hdata;
|
||||
|
||||
- if (skb_headroom(skb) + toff > INT_MAX)
|
||||
- goto out;
|
||||
-
|
||||
- data = skb_header_pointer(skb, toff, 4, &hdata);
|
||||
+ data = skb_header_pointer_careful(skb, toff, 4,
|
||||
+ &hdata);
|
||||
if (!data)
|
||||
goto out;
|
||||
if ((*data ^ key->val) & key->mask) {
|
||||
@@ -214,8 +212,9 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
|
||||
if (ht->divisor) {
|
||||
__be32 *data, hdata;
|
||||
|
||||
- data = skb_header_pointer(skb, off + n->sel.hoff, 4,
|
||||
- &hdata);
|
||||
+ data = skb_header_pointer_careful(skb,
|
||||
+ off + n->sel.hoff,
|
||||
+ 4, &hdata);
|
||||
if (!data)
|
||||
goto out;
|
||||
sel = ht->divisor & u32_hash_fold(*data, &n->sel,
|
||||
@@ -229,7 +228,7 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb,
|
||||
if (n->sel.flags & TC_U32_VAROFFSET) {
|
||||
__be16 *data, hdata;
|
||||
|
||||
- data = skb_header_pointer(skb,
|
||||
+ data = skb_header_pointer_careful(skb,
|
||||
off + n->sel.offoff,
|
||||
2, &hdata);
|
||||
if (!data)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
From 11cb63b0d1a0685e0831ae3c77223e002ef18189 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Nogueira <victor@mojatatu.com>
|
||||
Date: Wed, 25 Feb 2026 10:43:48 -0300
|
||||
Subject: [PATCH] net/sched: Only allow act_ct to bind to clsact/ingress qdiscs
|
||||
and shared blocks
|
||||
|
||||
As Paolo said earlier [1]:
|
||||
|
||||
"Since the blamed commit below, classify can return TC_ACT_CONSUMED while
|
||||
the current skb being held by the defragmentation engine. As reported by
|
||||
GangMin Kim, if such packet is that may cause a UaF when the defrag engine
|
||||
later on tries to tuch again such packet."
|
||||
|
||||
act_ct was never meant to be used in the egress path, however some users
|
||||
are attaching it to egress today [2]. Attempting to reach a middle
|
||||
ground, we noticed that, while most qdiscs are not handling
|
||||
TC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we
|
||||
address the issue by only allowing act_ct to bind to clsact/ingress
|
||||
qdiscs and shared blocks. That way it's still possible to attach act_ct to
|
||||
egress (albeit only with clsact).
|
||||
|
||||
[1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/
|
||||
[2] https://lore.kernel.org/netdev/cc6bfb4a-4a2b-42d8-b9ce-7ef6644fb22b@ovn.org/
|
||||
|
||||
Reported-by: GangMin Kim <km.kim1503@gmail.com>
|
||||
Fixes: 3f14b377d01d ("net/sched: act_ct: fix skb leak and crash on ooo frags")
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
|
||||
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
|
||||
Link: https://patch.msgid.link/20260225134349.1287037-1-victor@mojatatu.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
diff --git a/include/net/act_api.h b/include/net/act_api.h
|
||||
index e1e8f0f7dacb..d11b79107930 100644
|
||||
--- a/include/net/act_api.h
|
||||
+++ b/include/net/act_api.h
|
||||
@@ -70,6 +70,7 @@ struct tc_action {
|
||||
#define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2))
|
||||
#define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3))
|
||||
#define TCA_ACT_FLAGS_AT_INGRESS (1U << (TCA_ACT_FLAGS_USER_BITS + 4))
|
||||
+#define TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT (1U << (TCA_ACT_FLAGS_USER_BITS + 5))
|
||||
|
||||
/* Update lastuse only if needed, to avoid dirtying a cache line.
|
||||
* We use a temp variable to avoid fetching jiffies twice.
|
||||
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
|
||||
index bd51522c7953..7d5e50c921a0 100644
|
||||
--- a/net/sched/act_ct.c
|
||||
+++ b/net/sched/act_ct.c
|
||||
@@ -1360,6 +1360,12 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (bind && !(flags & TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT)) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack,
|
||||
+ "Attaching ct to a non ingress/clsact qdisc is unsupported");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
err = nla_parse_nested(tb, TCA_CT_MAX, nla, ct_policy, extack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
|
||||
index 343309e9009b..4829c27446e3 100644
|
||||
--- a/net/sched/cls_api.c
|
||||
+++ b/net/sched/cls_api.c
|
||||
@@ -2228,6 +2228,11 @@ static bool is_qdisc_ingress(__u32 classid)
|
||||
return (TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS));
|
||||
}
|
||||
|
||||
+static bool is_ingress_or_clsact(struct tcf_block *block, struct Qdisc *q)
|
||||
+{
|
||||
+ return tcf_block_shared(block) || (q && !!(q->flags & TCQ_F_INGRESS));
|
||||
+}
|
||||
+
|
||||
static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@@ -2420,6 +2425,8 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
|
||||
flags |= TCA_ACT_FLAGS_NO_RTNL;
|
||||
if (is_qdisc_ingress(parent))
|
||||
flags |= TCA_ACT_FLAGS_AT_INGRESS;
|
||||
+ if (is_ingress_or_clsact(block, q))
|
||||
+ flags |= TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT;
|
||||
err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
|
||||
flags, extack);
|
||||
if (err == 0) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
From 65b8cbd50f25d2dab7050a51dd9cbd4122c29113 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Stancek <jstancek@redhat.com>
|
||||
Date: Mon, 9 Mar 2026 08:52:45 +0100
|
||||
Subject: [PATCH] x86/boot: Handle relative CONFIG_EFI_SBAT_FILE file paths
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-150459
|
||||
Upstream Status: linux.git
|
||||
|
||||
Conflicts: minor context difference, rhel9 strips quotes from config value
|
||||
|
||||
commit 3d1973a0c76a78a4728cff13648a188ed486cf44
|
||||
Author: Jan Stancek <jstancek@redhat.com>
|
||||
Date: Wed Feb 25 20:30:23 2026 +0100
|
||||
|
||||
x86/boot: Handle relative CONFIG_EFI_SBAT_FILE file paths
|
||||
|
||||
CONFIG_EFI_SBAT_FILE can be a relative path. When compiling using a different
|
||||
output directory (O=) the build currently fails because it can't find the
|
||||
filename set in CONFIG_EFI_SBAT_FILE:
|
||||
|
||||
arch/x86/boot/compressed/sbat.S: Assembler messages:
|
||||
arch/x86/boot/compressed/sbat.S:6: Error: file not found: kernel.sbat
|
||||
|
||||
Add $(srctree) as include dir for sbat.o.
|
||||
|
||||
[ bp: Massage commit message. ]
|
||||
|
||||
Fixes: 61b57d35396a ("x86/efi: Implement support for embedding SBAT data for x86")
|
||||
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
||||
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
|
||||
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
Cc: <stable@kernel.org>
|
||||
Link: https://patch.msgid.link/f4eda155b0cef91d4d316b4e92f5771cb0aa7187.1772047658.git.jstancek@redhat.com
|
||||
|
||||
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
||||
|
||||
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
|
||||
index b294f0a7ac32..77e3bd5d39af 100644
|
||||
--- a/arch/x86/boot/compressed/Makefile
|
||||
+++ b/arch/x86/boot/compressed/Makefile
|
||||
@@ -122,6 +122,7 @@ vmlinux-objs-$(CONFIG_EFI_SBAT) += $(obj)/sbat.o
|
||||
ifdef CONFIG_EFI_SBAT
|
||||
# Strip quotes
|
||||
$(obj)/sbat.o: $(strip $(subst ",,$(CONFIG_EFI_SBAT_FILE)))
|
||||
+AFLAGS_sbat.o += -I $(srctree)
|
||||
endif
|
||||
|
||||
$(obj)/vmlinux: $(vmlinux-objs-y) FORCE
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
From c88e70dc8bfca9a2be74a100387b1b66de973128 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:28 +0300
|
||||
Subject: [PATCH] drm/i915/dsc: Add helper to enable the DSC configuration for
|
||||
a CRTC
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add a helper to enable the DSC compression configuration for a CRTC.
|
||||
Follow-up changes will introduce tracking for the same DSC state on the
|
||||
whole link, which will need to be set whenever DSC is enabled for the
|
||||
CRTC. Also, according to the above, when querying the DSC state on the
|
||||
link, both the CRTC's and the link's DSC state must be considered.
|
||||
|
||||
Setting the DSC configuration for a CRTC and querying the DSC
|
||||
configuration for the link (added by follow-up changes) is better done
|
||||
via helper functions based on the above, prepare for that here.
|
||||
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-2-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
|
||||
index 37faa8f19f6e..297368ff42a5 100644
|
||||
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
|
||||
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
|
||||
@@ -1655,7 +1655,7 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- crtc_state->dsc.compression_enable = true;
|
||||
+ intel_dsc_enable_on_crtc(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
index 7059d55687cf..fc1949e0c4de 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
@@ -2475,7 +2475,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
return ret;
|
||||
}
|
||||
|
||||
- pipe_config->dsc.compression_enable = true;
|
||||
+ intel_dsc_enable_on_crtc(pipe_config);
|
||||
+
|
||||
drm_dbg_kms(display->drm, "DP DSC computed with Input Bpp = %d "
|
||||
"Compressed Bpp = " FXP_Q4_FMT " Slice Count = %d\n",
|
||||
pipe_config->pipe_bpp,
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
|
||||
index bca747e24a7f..803f3b395c79 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
|
||||
@@ -372,6 +372,11 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state)
|
||||
+{
|
||||
+ crtc_state->dsc.compression_enable = true;
|
||||
+}
|
||||
+
|
||||
enum intel_display_power_domain
|
||||
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
|
||||
{
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
|
||||
index 2139391ff881..8c7c7fb652c3 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
|
||||
@@ -20,6 +20,7 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
|
||||
void intel_dsc_enable(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
|
||||
int intel_dsc_compute_params(struct intel_crtc_state *pipe_config);
|
||||
+void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
|
||||
enum intel_display_power_domain
|
||||
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
From 69df31263bcabc527a5b526fb8972cb080a179b3 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:29 +0300
|
||||
Subject: [PATCH] drm/i915/dp: Ensure the FEC state stays disabled for UHBR
|
||||
links
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Atm, in the DP SST case the FEC state is computed before
|
||||
intel_crtc_state::port_clock is initialized, hence intel_dp_is_uhbr()
|
||||
will always return false and the FEC state will be always computed
|
||||
assuming a non-UHBR link.
|
||||
|
||||
This happens to work, since the FEC state is recomputed later in
|
||||
intel_dp_mtp_tu_compute_config(), where port_clock will be set already,
|
||||
so intel_crtc_state::fec_enable will be reset as expected for UHBR. This
|
||||
also depends on link rates being tried in an increasing order (i.e. from
|
||||
non-UHBR -> UHBR link rates) in dsc_compute_link_config(), thus
|
||||
intel_crtc_state::fec_enable being set for the non-UHBR rates and
|
||||
getting reset for the first UHBR rate as expected.
|
||||
|
||||
A follow-up change will reuse intel_dp_fec_compute_config() for the DP
|
||||
MST state computation, prepare for that here, making sure that the
|
||||
function determines the correct intel_crtc_state::fec_enable=false state
|
||||
for UHBR link rates based on the above.
|
||||
|
||||
The DP SST and MST state computation should be further unified to avoid
|
||||
computing/setting the intel_crtc_state::fec_enable state multiple times,
|
||||
but that's left for a follow-up change. For now add only code comments
|
||||
about this.
|
||||
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-3-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
index fc1949e0c4de..7c568c23134f 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
@@ -2368,6 +2368,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
||||
static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
+ if (intel_dp_is_uhbr(crtc_state))
|
||||
+ return;
|
||||
+
|
||||
if (crtc_state->fec_enable)
|
||||
return;
|
||||
|
||||
@@ -2379,9 +2382,6 @@ static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
return;
|
||||
|
||||
- if (intel_dp_is_uhbr(crtc_state))
|
||||
- return;
|
||||
-
|
||||
crtc_state->fec_enable = true;
|
||||
}
|
||||
|
||||
@@ -2400,6 +2400,10 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
bool is_mst = intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST);
|
||||
int ret;
|
||||
|
||||
+ /*
|
||||
+ * FIXME: set the FEC enabled state once pipe_config->port_clock is
|
||||
+ * already known, so the UHBR/non-UHBR mode can be determined.
|
||||
+ */
|
||||
intel_dp_fec_compute_config(intel_dp, pipe_config);
|
||||
|
||||
if (!intel_dp_dsc_supports_format(connector, pipe_config->output_format))
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
index f2266b265304..27e952a67c34 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
@@ -293,6 +293,11 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
||||
mst_stream_update_slots(crtc_state, mst_state);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * NOTE: The following must reset crtc_state->fec_enable for UHBR/DSC
|
||||
+ * after it was set by intel_dp_dsc_compute_config() ->
|
||||
+ * intel_dp_fec_compute_config().
|
||||
+ */
|
||||
if (dsc) {
|
||||
if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
|
||||
return -EINVAL;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
From cb6c8f1f6f46ac2cbfb42ce8eb8b18257aeaa91a Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:30 +0300
|
||||
Subject: [PATCH] drm/i915/dp: Export helper to determine if FEC on non-UHBR
|
||||
links is required
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Export the helper function to determine if FEC is required on a non-UHBR
|
||||
(8b10b) SST or MST link. A follow up change will take this into use for
|
||||
MST as well.
|
||||
|
||||
While at it determine the output type from the CRTC state, which allows
|
||||
dropping the intel_dp argument. Also make the function return the
|
||||
required FEC state, instead of setting this in the CRTC state, which
|
||||
allows only querying this requirement, without changing the state.
|
||||
|
||||
Also rename the function to intel_dp_needs_8b10b_fec(), to clarify that
|
||||
the function determines if FEC is required on an 8b10b link (on 128b132b
|
||||
links FEC is always enabled by the HW implicitly, so the function will
|
||||
return false for that case).
|
||||
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-4-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
index 7c568c23134f..844118735998 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
@@ -2365,24 +2365,29 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
|
||||
- struct intel_crtc_state *crtc_state)
|
||||
+/*
|
||||
+ * Return whether FEC must be enabled for 8b10b SST or MST links. On 128b132b
|
||||
+ * links FEC is always enabled implicitly by the HW, so this function returns
|
||||
+ * false for that case.
|
||||
+ */
|
||||
+bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
|
||||
+ bool dsc_enabled_on_crtc)
|
||||
{
|
||||
if (intel_dp_is_uhbr(crtc_state))
|
||||
- return;
|
||||
+ return false;
|
||||
|
||||
if (crtc_state->fec_enable)
|
||||
- return;
|
||||
+ return true;
|
||||
|
||||
/*
|
||||
* Though eDP v1.5 supports FEC with DSC, unlike DP, it is optional.
|
||||
* Since, FEC is a bandwidth overhead, continue to not enable it for
|
||||
* eDP. Until, there is a good reason to do so.
|
||||
*/
|
||||
- if (intel_dp_is_edp(intel_dp))
|
||||
- return;
|
||||
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
|
||||
+ return false;
|
||||
|
||||
- crtc_state->fec_enable = true;
|
||||
+ return dsc_enabled_on_crtc;
|
||||
}
|
||||
|
||||
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
@@ -2404,7 +2409,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
* FIXME: set the FEC enabled state once pipe_config->port_clock is
|
||||
* already known, so the UHBR/non-UHBR mode can be determined.
|
||||
*/
|
||||
- intel_dp_fec_compute_config(intel_dp, pipe_config);
|
||||
+ pipe_config->fec_enable = intel_dp_needs_8b10b_fec(pipe_config, true);
|
||||
|
||||
if (!intel_dp_dsc_supports_format(connector, pipe_config->output_format))
|
||||
return -EINVAL;
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
|
||||
index 281ced3a3b39..0537be20fe7b 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp.h
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
|
||||
@@ -73,6 +73,8 @@ void intel_dp_encoder_flush_work(struct drm_encoder *encoder);
|
||||
int intel_dp_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state);
|
||||
+bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
|
||||
+ bool dsc_enabled_on_crtc);
|
||||
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state,
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
index 27e952a67c34..d0590b5ffffd 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
@@ -296,7 +296,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
||||
/*
|
||||
* NOTE: The following must reset crtc_state->fec_enable for UHBR/DSC
|
||||
* after it was set by intel_dp_dsc_compute_config() ->
|
||||
- * intel_dp_fec_compute_config().
|
||||
+ * intel_dp_needs_8b10b_fec().
|
||||
*/
|
||||
if (dsc) {
|
||||
if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From b762ae48293e2cc2145cdc91eb596d057f1aff11 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:31 +0300
|
||||
Subject: [PATCH] drm/i915/dp_mst: Reuse the DP-SST helper function to compute
|
||||
FEC config
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reuse the DP-SST helper to compute the state for the FEC enabled state
|
||||
for DP-MST as well.
|
||||
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-5-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
index d0590b5ffffd..0cbb4c3a8e22 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
@@ -298,12 +298,10 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
||||
* after it was set by intel_dp_dsc_compute_config() ->
|
||||
* intel_dp_needs_8b10b_fec().
|
||||
*/
|
||||
- if (dsc) {
|
||||
- if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state);
|
||||
- }
|
||||
+ crtc_state->fec_enable = intel_dp_needs_8b10b_fec(crtc_state, dsc);
|
||||
+ if (crtc_state->fec_enable &&
|
||||
+ !intel_dp_supports_fec(intel_dp, connector, crtc_state))
|
||||
+ return -EINVAL;
|
||||
|
||||
max_dpt_bpp_x16 = fxp_q4_from_int(intel_dp_mst_max_dpt_bpp(crtc_state, dsc));
|
||||
if (max_dpt_bpp_x16 && max_bpp_x16 > max_dpt_bpp_x16) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
From 7c027070e98d7b515e4d3a94b54d288c61cb5918 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:32 +0300
|
||||
Subject: [PATCH] drm/i915/dp_mst: Track DSC enabled status on the MST link
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Track whether DSC is enabled on any CRTC on a link. On DP-SST (and DSI)
|
||||
this will always match the CRTC's DSC state, those links having only a
|
||||
single stream (aka CRTC). For instance, on DP-MST if DSC is enabled for
|
||||
CRTC#0, but disabled for CRTC#1, the DSC/FEC state for these CRTCs will
|
||||
be as follows:
|
||||
|
||||
CRTC#0:
|
||||
- compression_enable = true
|
||||
- compression_enabled_on_link = true
|
||||
- fec_enable = true for 8b10b, false for 128b132b
|
||||
|
||||
CRTC#1:
|
||||
- compression_enable = false
|
||||
- compression_enabled_on_link = true
|
||||
- fec_enable = true for 8b10b, false for 128b132b
|
||||
|
||||
This patch only sets compression_enabled_on_link for CRTC#0 above and
|
||||
enables FEC on CRTC#0 if DSC was enabled on any other CRTC on the 8b10b
|
||||
MST link. A follow-up change will make sure that the state of all the
|
||||
CRTCs (CRTC#1 above) on an MST link is recomputed if DSC gets enabled on
|
||||
any CRTC, setting compression_enabled_on_link and fec_enable for these.
|
||||
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-6-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
|
||||
index 203dd38a9ec4..20747fa4d3da 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
|
||||
@@ -1279,6 +1279,8 @@ struct intel_crtc_state {
|
||||
|
||||
/* Display Stream compression state */
|
||||
struct {
|
||||
+ /* Only used for state computation, not read out from the HW. */
|
||||
+ bool compression_enabled_on_link;
|
||||
bool compression_enable;
|
||||
int num_streams;
|
||||
/* Compressed Bpp in U6.4 format (first 4 bits for fractional part) */
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
index 844118735998..95884af242b3 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
@@ -2387,7 +2387,7 @@ bool intel_dp_needs_8b10b_fec(const struct intel_crtc_state *crtc_state,
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
|
||||
return false;
|
||||
|
||||
- return dsc_enabled_on_crtc;
|
||||
+ return dsc_enabled_on_crtc || intel_dsc_enabled_on_link(crtc_state);
|
||||
}
|
||||
|
||||
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
|
||||
index 803f3b395c79..dbf2cf1b896d 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
|
||||
@@ -374,9 +374,20 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
|
||||
|
||||
void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
+ crtc_state->dsc.compression_enabled_on_link = true;
|
||||
crtc_state->dsc.compression_enable = true;
|
||||
}
|
||||
|
||||
+bool intel_dsc_enabled_on_link(const struct intel_crtc_state *crtc_state)
|
||||
+{
|
||||
+ struct intel_display *display = to_intel_display(crtc_state);
|
||||
+
|
||||
+ drm_WARN_ON(display->drm, crtc_state->dsc.compression_enable &&
|
||||
+ !crtc_state->dsc.compression_enabled_on_link);
|
||||
+
|
||||
+ return crtc_state->dsc.compression_enabled_on_link;
|
||||
+}
|
||||
+
|
||||
enum intel_display_power_domain
|
||||
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
|
||||
{
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
|
||||
index 8c7c7fb652c3..99f64ac54b27 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
|
||||
@@ -21,6 +21,7 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
|
||||
int intel_dsc_compute_params(struct intel_crtc_state *pipe_config);
|
||||
void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state);
|
||||
+bool intel_dsc_enabled_on_link(const struct intel_crtc_state *crtc_state);
|
||||
void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
|
||||
enum intel_display_power_domain
|
||||
intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,171 @@
|
||||
From 470b84af457e34cbfa4d2c17dab78746736ab898 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:33 +0300
|
||||
Subject: [PATCH] drm/i915/dp_mst: Recompute all MST link CRTCs if DSC gets
|
||||
enabled on the link
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The state of all the CRTCs on an MST link must be recomputed, if DSC
|
||||
gets enabled on any of the CRTCs on the link. For instance an MST
|
||||
docking station's Panel Replay capability may depend on whether DSC is
|
||||
enabled on any of the dock's streams (aka CRTCs). To assist the Panel
|
||||
Replay state computation for a CRTC based on the above, track in the
|
||||
CRTC state if DSC is enabled on any CRTC on an MST link.
|
||||
|
||||
The intel_link_bw_limits::force_fec_pipes mask is used for a reason
|
||||
similar to the above: enable FEC on all CRTCs of a non-UHBR (8b10b) MST
|
||||
link if DSC is enabled on any of the link's CRTCs. The FEC enabled state
|
||||
for a CRTC doesn't indicate if DSC is enabled on a UHBR MST link (FEC is
|
||||
always enabled by the HW for UHBR, hence it's not tracked by the
|
||||
intel_crtc_state::fec_enable flag for such links, where this flag is
|
||||
always false).
|
||||
|
||||
Based on the above, to be able to determine the DSC state on both
|
||||
non-UHBR and UHBR MST links, track the more generic DSC-enabled-on-link
|
||||
state (instead of the FEC-enabled-on-link state) for each CRTC in
|
||||
intel_link_bw_limits.
|
||||
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-7-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
|
||||
index bbb6ff929d64..a8b4619de347 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_display.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_display.c
|
||||
@@ -4603,7 +4603,7 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- crtc_state->fec_enable = limits->force_fec_pipes & BIT(crtc->pipe);
|
||||
+ crtc_state->dsc.compression_enabled_on_link = limits->link_dsc_pipes & BIT(crtc->pipe);
|
||||
crtc_state->max_link_bpp_x16 = limits->max_bpp_x16[crtc->pipe];
|
||||
|
||||
if (crtc_state->pipe_bpp > fxp_q4_to_int(crtc_state->max_link_bpp_x16)) {
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
index 0cbb4c3a8e22..a845b2612a3f 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
|
||||
@@ -814,14 +814,14 @@ static u8 get_pipes_downstream_of_mst_port(struct intel_atomic_state *state,
|
||||
return mask;
|
||||
}
|
||||
|
||||
-static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
|
||||
+static int intel_dp_mst_check_dsc_change(struct intel_atomic_state *state,
|
||||
struct drm_dp_mst_topology_mgr *mst_mgr,
|
||||
struct intel_link_bw_limits *limits)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct intel_crtc *crtc;
|
||||
u8 mst_pipe_mask;
|
||||
- u8 fec_pipe_mask = 0;
|
||||
+ u8 dsc_pipe_mask = 0;
|
||||
int ret;
|
||||
|
||||
mst_pipe_mask = get_pipes_downstream_of_mst_port(state, mst_mgr, NULL);
|
||||
@@ -834,16 +834,16 @@ static int intel_dp_mst_check_fec_change(struct intel_atomic_state *state,
|
||||
if (drm_WARN_ON(display->drm, !crtc_state))
|
||||
return -EINVAL;
|
||||
|
||||
- if (crtc_state->fec_enable)
|
||||
- fec_pipe_mask |= BIT(crtc->pipe);
|
||||
+ if (intel_dsc_enabled_on_link(crtc_state))
|
||||
+ dsc_pipe_mask |= BIT(crtc->pipe);
|
||||
}
|
||||
|
||||
- if (!fec_pipe_mask || mst_pipe_mask == fec_pipe_mask)
|
||||
+ if (!dsc_pipe_mask || mst_pipe_mask == dsc_pipe_mask)
|
||||
return 0;
|
||||
|
||||
- limits->force_fec_pipes |= mst_pipe_mask;
|
||||
+ limits->link_dsc_pipes |= mst_pipe_mask;
|
||||
|
||||
- ret = intel_modeset_pipes_in_mask_early(state, "MST FEC",
|
||||
+ ret = intel_modeset_pipes_in_mask_early(state, "MST DSC",
|
||||
mst_pipe_mask);
|
||||
|
||||
return ret ? : -EAGAIN;
|
||||
@@ -897,7 +897,7 @@ int intel_dp_mst_atomic_check_link(struct intel_atomic_state *state,
|
||||
int i;
|
||||
|
||||
for_each_new_mst_mgr_in_state(&state->base, mgr, mst_state, i) {
|
||||
- ret = intel_dp_mst_check_fec_change(state, mgr, limits);
|
||||
+ ret = intel_dp_mst_check_dsc_change(state, mgr, limits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c
|
||||
index f52dee0ea412..d2862de894fa 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_link_bw.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "intel_dp_tunnel.h"
|
||||
#include "intel_fdi.h"
|
||||
#include "intel_link_bw.h"
|
||||
+#include "intel_vdsc.h"
|
||||
|
||||
static int get_forced_link_bpp_x16(struct intel_atomic_state *state,
|
||||
const struct intel_crtc *crtc)
|
||||
@@ -55,7 +56,7 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
enum pipe pipe;
|
||||
|
||||
- limits->force_fec_pipes = 0;
|
||||
+ limits->link_dsc_pipes = 0;
|
||||
limits->bpp_limit_reached_pipes = 0;
|
||||
for_each_pipe(display, pipe) {
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
|
||||
@@ -65,8 +66,8 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state,
|
||||
|
||||
if (state->base.duplicated && crtc_state) {
|
||||
limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
|
||||
- if (crtc_state->fec_enable)
|
||||
- limits->force_fec_pipes |= BIT(pipe);
|
||||
+ if (intel_dsc_enabled_on_link(crtc_state))
|
||||
+ limits->link_dsc_pipes |= BIT(pipe);
|
||||
} else {
|
||||
limits->max_bpp_x16[pipe] = INT_MAX;
|
||||
}
|
||||
@@ -265,10 +266,10 @@ assert_link_limit_change_valid(struct intel_display *display,
|
||||
bool bpps_changed = false;
|
||||
enum pipe pipe;
|
||||
|
||||
- /* FEC can't be forced off after it was forced on. */
|
||||
+ /* DSC can't be disabled after it was enabled. */
|
||||
if (drm_WARN_ON(display->drm,
|
||||
- (old_limits->force_fec_pipes & new_limits->force_fec_pipes) !=
|
||||
- old_limits->force_fec_pipes))
|
||||
+ (old_limits->link_dsc_pipes & new_limits->link_dsc_pipes) !=
|
||||
+ old_limits->link_dsc_pipes))
|
||||
return false;
|
||||
|
||||
for_each_pipe(display, pipe) {
|
||||
@@ -286,8 +287,8 @@ assert_link_limit_change_valid(struct intel_display *display,
|
||||
/* At least one limit must change. */
|
||||
if (drm_WARN_ON(display->drm,
|
||||
!bpps_changed &&
|
||||
- new_limits->force_fec_pipes ==
|
||||
- old_limits->force_fec_pipes))
|
||||
+ new_limits->link_dsc_pipes ==
|
||||
+ old_limits->link_dsc_pipes))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.h b/drivers/gpu/drm/i915/display/intel_link_bw.h
|
||||
index 95ab7c50c61d..cb18e171037c 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_link_bw.h
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_link_bw.h
|
||||
@@ -15,7 +15,7 @@ struct intel_connector;
|
||||
struct intel_crtc_state;
|
||||
|
||||
struct intel_link_bw_limits {
|
||||
- u8 force_fec_pipes;
|
||||
+ u8 link_dsc_pipes;
|
||||
u8 bpp_limit_reached_pipes;
|
||||
/* in 1/16 bpp units */
|
||||
int max_bpp_x16[I915_MAX_PIPES];
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,248 @@
|
||||
From c390bf07961b3a39f3417d75850a4e721b87e595 Mon Sep 17 00:00:00 2001
|
||||
From: Imre Deak <imre.deak@intel.com>
|
||||
Date: Wed, 15 Oct 2025 19:19:34 +0300
|
||||
Subject: [PATCH] drm/i915/dp: Fix panel replay when DSC is enabled
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Prevent enabling panel replay if the sink doesn't support this due to
|
||||
DSC being enabled.
|
||||
|
||||
Panel replay has two modes, updating full frames or only selected
|
||||
regions of the frame. If the sink doesn't support Panel Replay in full
|
||||
frame update mode with DSC prevent Panel Replay completely if DSC is
|
||||
enabled. If the sink doesn't support Panel Replay only in the selective
|
||||
update mode while DSC is enabled, it will still support Panel Replay in
|
||||
the full frame update mode, so only prevent selective updates in this
|
||||
case.
|
||||
|
||||
v2:
|
||||
- Use Panel Replay instead of PR in debug prints. (Jouni)
|
||||
- Rebase on change tracking the link DSC state in the crtc state.
|
||||
|
||||
Cc: Jouni Högander <jouni.hogander@intel.com>
|
||||
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14869
|
||||
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
|
||||
Signed-off-by: Imre Deak <imre.deak@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251015161934.262108-8-imre.deak@intel.com
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
|
||||
index 20747fa4d3da..1e0cd81c9474 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
|
||||
@@ -955,6 +955,12 @@ struct intel_csc_matrix {
|
||||
u16 postoff[3];
|
||||
};
|
||||
|
||||
+enum intel_panel_replay_dsc_support {
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED,
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY,
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE,
|
||||
+};
|
||||
+
|
||||
struct intel_crtc_state {
|
||||
/*
|
||||
* uapi (drm) state. This is the software state shown to userspace.
|
||||
@@ -1133,6 +1139,8 @@ struct intel_crtc_state {
|
||||
bool has_panel_replay;
|
||||
bool wm_level_disabled;
|
||||
bool pkg_c_latency_used;
|
||||
+ /* Only used for state verification. */
|
||||
+ enum intel_panel_replay_dsc_support panel_replay_dsc_support;
|
||||
u32 dc3co_exitline;
|
||||
u16 su_y_granularity;
|
||||
u8 active_non_psr_pipes;
|
||||
@@ -1706,6 +1714,7 @@ struct intel_psr {
|
||||
bool source_panel_replay_support;
|
||||
bool sink_panel_replay_support;
|
||||
bool sink_panel_replay_su_support;
|
||||
+ enum intel_panel_replay_dsc_support sink_panel_replay_dsc_support;
|
||||
bool panel_replay_enabled;
|
||||
u32 dc3co_exitline;
|
||||
u32 dc3co_exit_delay;
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
index 95884af242b3..215ad690ab07 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
|
||||
@@ -6053,6 +6053,8 @@ intel_dp_detect(struct drm_connector *_connector,
|
||||
memset(connector->dp.dsc_dpcd, 0, sizeof(connector->dp.dsc_dpcd));
|
||||
intel_dp->psr.sink_panel_replay_support = false;
|
||||
intel_dp->psr.sink_panel_replay_su_support = false;
|
||||
+ intel_dp->psr.sink_panel_replay_dsc_support =
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED;
|
||||
|
||||
intel_dp_mst_disconnect(intel_dp);
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
|
||||
index 703e5f6af04c..3e99a65ec988 100644
|
||||
--- a/drivers/gpu/drm/i915/display/intel_psr.c
|
||||
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
+#include "i915_utils.h"
|
||||
#include "intel_alpm.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_crtc.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
#include "intel_snps_phy.h"
|
||||
#include "intel_step.h"
|
||||
#include "intel_vblank.h"
|
||||
+#include "intel_vdsc.h"
|
||||
#include "intel_vrr.h"
|
||||
#include "skl_universal_plane.h"
|
||||
|
||||
@@ -580,6 +582,44 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
|
||||
intel_dp->psr.su_y_granularity = y;
|
||||
}
|
||||
|
||||
+static enum intel_panel_replay_dsc_support
|
||||
+compute_pr_dsc_support(struct intel_dp *intel_dp)
|
||||
+{
|
||||
+ u8 pr_dsc_mode;
|
||||
+ u8 val;
|
||||
+
|
||||
+ val = intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)];
|
||||
+ pr_dsc_mode = REG_FIELD_GET8(DP_PANEL_REPLAY_DSC_DECODE_CAPABILITY_IN_PR_MASK, val);
|
||||
+
|
||||
+ switch (pr_dsc_mode) {
|
||||
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_FULL_FRAME_ONLY:
|
||||
+ return INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY;
|
||||
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_SUPPORTED:
|
||||
+ return INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE;
|
||||
+ default:
|
||||
+ MISSING_CASE(pr_dsc_mode);
|
||||
+ fallthrough;
|
||||
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_NOT_SUPPORTED:
|
||||
+ case DP_DSC_DECODE_CAPABILITY_IN_PR_RESERVED:
|
||||
+ return INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const char *panel_replay_dsc_support_str(enum intel_panel_replay_dsc_support dsc_support)
|
||||
+{
|
||||
+ switch (dsc_support) {
|
||||
+ case INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED:
|
||||
+ return "not supported";
|
||||
+ case INTEL_DP_PANEL_REPLAY_DSC_FULL_FRAME_ONLY:
|
||||
+ return "full frame only";
|
||||
+ case INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE:
|
||||
+ return "selective update";
|
||||
+ default:
|
||||
+ MISSING_CASE(dsc_support);
|
||||
+ return "n/a";
|
||||
+ };
|
||||
+}
|
||||
+
|
||||
static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
@@ -615,10 +655,13 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
|
||||
DP_PANEL_REPLAY_SU_SUPPORT)
|
||||
intel_dp->psr.sink_panel_replay_su_support = true;
|
||||
|
||||
+ intel_dp->psr.sink_panel_replay_dsc_support = compute_pr_dsc_support(intel_dp);
|
||||
+
|
||||
drm_dbg_kms(display->drm,
|
||||
- "Panel replay %sis supported by panel\n",
|
||||
+ "Panel replay %sis supported by panel (in DSC mode: %s)\n",
|
||||
intel_dp->psr.sink_panel_replay_su_support ?
|
||||
- "selective_update " : "");
|
||||
+ "selective_update " : "",
|
||||
+ panel_replay_dsc_support_str(intel_dp->psr.sink_panel_replay_dsc_support));
|
||||
}
|
||||
|
||||
static void _psr_init_dpcd(struct intel_dp *intel_dp)
|
||||
@@ -1606,9 +1649,21 @@ static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
- if (crtc_state->has_panel_replay && (DISPLAY_VER(display) < 14 ||
|
||||
- !intel_dp->psr.sink_panel_replay_su_support))
|
||||
- goto unsupported;
|
||||
+ if (crtc_state->has_panel_replay) {
|
||||
+ if (DISPLAY_VER(display) < 14)
|
||||
+ goto unsupported;
|
||||
+
|
||||
+ if (!intel_dp->psr.sink_panel_replay_su_support)
|
||||
+ goto unsupported;
|
||||
+
|
||||
+ if (intel_dsc_enabled_on_link(crtc_state) &&
|
||||
+ intel_dp->psr.sink_panel_replay_dsc_support !=
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE) {
|
||||
+ drm_dbg_kms(display->drm,
|
||||
+ "Selective update with Panel Replay not enabled because it's not supported with DSC\n");
|
||||
+ goto unsupported;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (crtc_state->crc_enabled) {
|
||||
drm_dbg_kms(display->drm,
|
||||
@@ -1685,6 +1740,14 @@ _panel_replay_compute_config(struct intel_dp *intel_dp,
|
||||
return false;
|
||||
}
|
||||
|
||||
+ if (intel_dsc_enabled_on_link(crtc_state) &&
|
||||
+ intel_dp->psr.sink_panel_replay_dsc_support ==
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED) {
|
||||
+ drm_dbg_kms(display->drm,
|
||||
+ "Panel Replay not enabled because it's not supported with DSC\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!intel_dp_is_edp(intel_dp))
|
||||
return true;
|
||||
|
||||
@@ -1790,6 +1853,8 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* Only used for state verification. */
|
||||
+ crtc_state->panel_replay_dsc_support = intel_dp->psr.sink_panel_replay_dsc_support;
|
||||
crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp,
|
||||
crtc_state,
|
||||
conn_state);
|
||||
@@ -2991,6 +3056,20 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state,
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+verify_panel_replay_dsc_state(const struct intel_crtc_state *crtc_state)
|
||||
+{
|
||||
+ struct intel_display *display = to_intel_display(crtc_state);
|
||||
+
|
||||
+ if (!crtc_state->has_panel_replay)
|
||||
+ return;
|
||||
+
|
||||
+ drm_WARN_ON(display->drm,
|
||||
+ intel_dsc_enabled_on_link(crtc_state) &&
|
||||
+ crtc_state->panel_replay_dsc_support ==
|
||||
+ INTEL_DP_PANEL_REPLAY_DSC_NOT_SUPPORTED);
|
||||
+}
|
||||
+
|
||||
void intel_psr_post_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
@@ -3002,6 +3081,8 @@ void intel_psr_post_plane_update(struct intel_atomic_state *state,
|
||||
if (!crtc_state->has_psr)
|
||||
return;
|
||||
|
||||
+ verify_panel_replay_dsc_state(crtc_state);
|
||||
+
|
||||
for_each_intel_encoder_mask_with_psr(state->base.dev, encoder,
|
||||
crtc_state->uapi.encoder_mask) {
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
@@ -4031,6 +4112,8 @@ static void intel_psr_sink_capability(struct intel_dp *intel_dp,
|
||||
seq_printf(m, ", Panel Replay = %s", str_yes_no(psr->sink_panel_replay_support));
|
||||
seq_printf(m, ", Panel Replay Selective Update = %s",
|
||||
str_yes_no(psr->sink_panel_replay_su_support));
|
||||
+ seq_printf(m, ", Panel Replay DSC support = %s",
|
||||
+ panel_replay_dsc_support_str(psr->sink_panel_replay_dsc_support));
|
||||
if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] &
|
||||
DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)
|
||||
seq_printf(m, " (Early Transport)");
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Update lpfc version to 14.4.0.12"
|
||||
# Revert of f586e5f3f3751e4115a539e81d8dce066fb27f2d
|
||||
scsi: lpfc: Update lpfc version to 14.4.0.12
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
|
||||
index f3dada5bf7c1..31c3c5abdca6 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_version.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_version.h
|
||||
@@ -20,7 +20,7 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
-#define LPFC_DRIVER_VERSION "14.4.0.12"
|
||||
+#define LPFC_DRIVER_VERSION "14.4.0.11"
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
/* Used for SLI 2/3 */
|
||||
@ -0,0 +1,332 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Add capability to register Platform Name ID to fabric"
|
||||
# Revert of 329b0632fcf901b929ca7658a8a3a4af2682011e
|
||||
scsi: lpfc: Add capability to register Platform Name ID to fabric
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
|
||||
index ef83b8e0e9f8..42bf2fda825f 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc.h
|
||||
@@ -634,7 +634,6 @@ struct lpfc_vport {
|
||||
#define FC_CT_RSPN_ID 0x8 /* RSPN_ID accepted by switch */
|
||||
#define FC_CT_RFT_ID 0x10 /* RFT_ID accepted by switch */
|
||||
#define FC_CT_RPRT_DEFER 0x20 /* Defer issuing FDMI RPRT */
|
||||
-#define FC_CT_RSPNI_PNI 0x40 /* RSPNI_PNI accepted by switch */
|
||||
|
||||
struct list_head fc_nodes;
|
||||
spinlock_t fc_nodes_list_lock; /* spinlock for fc_nodes list */
|
||||
@@ -1079,8 +1078,6 @@ struct lpfc_hba {
|
||||
|
||||
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
|
||||
|
||||
- unsigned long pni; /* 64-bit Platform Name Identifier */
|
||||
-
|
||||
uint8_t wwnn[8];
|
||||
uint8_t wwpn[8];
|
||||
uint32_t RandomData[7];
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
index 1c7fa13c8728..94f612d1fef0 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_ct.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
@@ -1742,28 +1742,6 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
return;
|
||||
}
|
||||
|
||||
-static void
|
||||
-lpfc_cmpl_ct_cmd_rspni_pni(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
- struct lpfc_iocbq *rspiocb)
|
||||
-{
|
||||
- struct lpfc_vport *vport;
|
||||
- struct lpfc_dmabuf *outp;
|
||||
- struct lpfc_sli_ct_request *ctrsp;
|
||||
- u32 ulp_status;
|
||||
-
|
||||
- vport = cmdiocb->vport;
|
||||
- ulp_status = get_job_ulpstatus(phba, rspiocb);
|
||||
-
|
||||
- if (ulp_status == IOSTAT_SUCCESS) {
|
||||
- outp = cmdiocb->rsp_dmabuf;
|
||||
- ctrsp = (struct lpfc_sli_ct_request *)outp->virt;
|
||||
- if (be16_to_cpu(ctrsp->CommandResponse.bits.CmdRsp) ==
|
||||
- SLI_CT_RESPONSE_FS_ACC)
|
||||
- vport->ct_flags |= FC_CT_RSPNI_PNI;
|
||||
- }
|
||||
- lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
|
||||
-}
|
||||
-
|
||||
static void
|
||||
lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_iocbq *rspiocb)
|
||||
@@ -1978,8 +1956,6 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
||||
bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_RSNN_NN)
|
||||
bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
|
||||
- else if (cmdcode == SLI_CTNS_RSPNI_PNI)
|
||||
- bpl->tus.f.bdeSize = RSPNI_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_DA_ID)
|
||||
bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
|
||||
else if (cmdcode == SLI_CTNS_RFF_ID)
|
||||
@@ -2101,18 +2077,6 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
|
||||
CtReq->un.rsnn.symbname, size);
|
||||
cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
|
||||
break;
|
||||
- case SLI_CTNS_RSPNI_PNI:
|
||||
- vport->ct_flags &= ~FC_CT_RSPNI_PNI;
|
||||
- CtReq->CommandResponse.bits.CmdRsp =
|
||||
- cpu_to_be16(SLI_CTNS_RSPNI_PNI);
|
||||
- CtReq->un.rspni.pni = cpu_to_be64(phba->pni);
|
||||
- scnprintf(CtReq->un.rspni.symbname,
|
||||
- sizeof(CtReq->un.rspni.symbname), "OS Host Name::%s",
|
||||
- phba->os_host_name);
|
||||
- CtReq->un.rspni.len = strnlen(CtReq->un.rspni.symbname,
|
||||
- sizeof(CtReq->un.rspni.symbname));
|
||||
- cmpl = lpfc_cmpl_ct_cmd_rspni_pni;
|
||||
- break;
|
||||
case SLI_CTNS_DA_ID:
|
||||
/* Implement DA_ID Nameserver request */
|
||||
CtReq->CommandResponse.bits.CmdRsp =
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index fbf2fd97f093..c07d6805dbdb 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -650,6 +650,8 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS2;
|
||||
if (sp->cls3.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS3;
|
||||
+ if (sp->cls4.classValid)
|
||||
+ ndlp->nlp_class_sup |= FC_COS_CLASS4;
|
||||
ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
|
||||
sp->cmn.bbRcvSizeLsb;
|
||||
|
||||
@@ -1354,14 +1356,6 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
/* Can't do SLI4 class2 without support sequence coalescing */
|
||||
sp->cls2.classValid = 0;
|
||||
sp->cls2.seqDelivery = 0;
|
||||
-
|
||||
- /* Fill out Auxiliary Parameter Data */
|
||||
- if (phba->pni) {
|
||||
- sp->aux.flags =
|
||||
- AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
|
||||
- sp->aux.pni = cpu_to_be64(phba->pni);
|
||||
- sp->aux.npiv_cnt = cpu_to_be16(phba->max_vpi - 1);
|
||||
- }
|
||||
} else {
|
||||
/* Historical, setting sequential-delivery bit for SLI3 */
|
||||
sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
|
||||
@@ -5662,6 +5656,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
|
||||
sp->cls1.classValid = 0;
|
||||
sp->cls2.classValid = 0;
|
||||
sp->cls3.classValid = 0;
|
||||
+ sp->cls4.classValid = 0;
|
||||
|
||||
/* Copy our worldwide names */
|
||||
memcpy(&sp->portName, &vport->fc_sparam.portName,
|
||||
@@ -11520,13 +11515,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
sp->cls2.seqDelivery = 1;
|
||||
sp->cls3.seqDelivery = 1;
|
||||
|
||||
- /* Fill out Auxiliary Parameter Data */
|
||||
- if (phba->pni) {
|
||||
- sp->aux.flags =
|
||||
- AUX_PARM_DATA_VALID | AUX_PARM_PNI_VALID;
|
||||
- sp->aux.pni = cpu_to_be64(phba->pni);
|
||||
- }
|
||||
-
|
||||
pcmd += sizeof(uint32_t); /* CSP Word 2 */
|
||||
pcmd += sizeof(uint32_t); /* CSP Word 3 */
|
||||
pcmd += sizeof(uint32_t); /* CSP Word 4 */
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
index 5d2210790c0a..5a8ccdc956df 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
@@ -4373,8 +4373,6 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
|
||||
- if (phba->pni)
|
||||
- lpfc_ns_cmd(vport, SLI_CTNS_RSPNI_PNI, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);
|
||||
|
||||
if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
|
||||
index b2e353590ebb..3bc0efa7453e 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hw.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hw.h
|
||||
@@ -168,11 +168,6 @@ struct lpfc_sli_ct_request {
|
||||
uint8_t len;
|
||||
uint8_t symbname[255];
|
||||
} rspn;
|
||||
- struct rspni { /* For RSPNI_PNI requests */
|
||||
- __be64 pni;
|
||||
- u8 len;
|
||||
- u8 symbname[255];
|
||||
- } rspni;
|
||||
struct gff {
|
||||
uint32_t PortId;
|
||||
} gff;
|
||||
@@ -218,8 +213,6 @@ struct lpfc_sli_ct_request {
|
||||
sizeof(struct da_id))
|
||||
#define RSPN_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
|
||||
sizeof(struct rspn))
|
||||
-#define RSPNI_REQUEST_SZ (offsetof(struct lpfc_sli_ct_request, un) + \
|
||||
- sizeof(struct rspni))
|
||||
|
||||
/*
|
||||
* FsType Definitions
|
||||
@@ -316,7 +309,6 @@ struct lpfc_sli_ct_request {
|
||||
#define SLI_CTNS_RIP_NN 0x0235
|
||||
#define SLI_CTNS_RIPA_NN 0x0236
|
||||
#define SLI_CTNS_RSNN_NN 0x0239
|
||||
-#define SLI_CTNS_RSPNI_PNI 0x0240
|
||||
#define SLI_CTNS_DA_ID 0x0300
|
||||
|
||||
/*
|
||||
@@ -520,21 +512,6 @@ struct class_parms {
|
||||
uint8_t word3Reserved2; /* Fc Word 3, bit 0: 7 */
|
||||
};
|
||||
|
||||
-enum aux_parm_flags {
|
||||
- AUX_PARM_PNI_VALID = 0x20, /* FC Word 0, bit 29 */
|
||||
- AUX_PARM_DATA_VALID = 0x40, /* FC Word 0, bit 30 */
|
||||
-};
|
||||
-
|
||||
-struct aux_parm {
|
||||
- u8 flags; /* FC Word 0, bit 31:24 */
|
||||
- u8 ext_feat[3]; /* FC Word 0, bit 23:0 */
|
||||
-
|
||||
- __be64 pni; /* FC Word 1 and 2, platform name identifier */
|
||||
-
|
||||
- __be16 rsvd; /* FC Word 3, bit 31:16 */
|
||||
- __be16 npiv_cnt; /* FC Word 3, bit 15:0 */
|
||||
-} __packed;
|
||||
-
|
||||
struct serv_parm { /* Structure is in Big Endian format */
|
||||
struct csp cmn;
|
||||
struct lpfc_name portName;
|
||||
@@ -542,7 +519,7 @@ struct serv_parm { /* Structure is in Big Endian format */
|
||||
struct class_parms cls1;
|
||||
struct class_parms cls2;
|
||||
struct class_parms cls3;
|
||||
- struct aux_parm aux;
|
||||
+ struct class_parms cls4;
|
||||
union {
|
||||
uint8_t vendorVersion[16];
|
||||
struct {
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
index 9e785bbf6785..e16370da3e45 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
@@ -432,6 +432,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS2;
|
||||
if (sp->cls3.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS3;
|
||||
+ if (sp->cls4.classValid)
|
||||
+ ndlp->nlp_class_sup |= FC_COS_CLASS4;
|
||||
ndlp->nlp_maxframe =
|
||||
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
|
||||
/* if already logged in, do implicit logout */
|
||||
@@ -1415,6 +1417,8 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS2;
|
||||
if (sp->cls3.classValid)
|
||||
ndlp->nlp_class_sup |= FC_COS_CLASS3;
|
||||
+ if (sp->cls4.classValid)
|
||||
+ ndlp->nlp_class_sup |= FC_COS_CLASS4;
|
||||
ndlp->nlp_maxframe =
|
||||
((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index 2e3f77538266..66730c3e4cb9 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -27,8 +27,6 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lockdep.h>
|
||||
-#include <linux/dmi.h>
|
||||
-#include <linux/of.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
@@ -8451,70 +8449,6 @@ lpfc_set_host_tm(struct lpfc_hba *phba)
|
||||
return rc;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * lpfc_get_platform_uuid - Attempts to extract a platform uuid
|
||||
- * @phba: pointer to lpfc hba data structure.
|
||||
- *
|
||||
- * This routine attempts to first read SMBIOS DMI data for the System
|
||||
- * Information structure offset 08h called System UUID. Else, no platform
|
||||
- * UUID will be advertised.
|
||||
- **/
|
||||
-static void
|
||||
-lpfc_get_platform_uuid(struct lpfc_hba *phba)
|
||||
-{
|
||||
- int rc;
|
||||
- const char *uuid;
|
||||
- char pni[17] = {0}; /* 16 characters + '\0' */
|
||||
- bool is_ff = true, is_00 = true;
|
||||
- u8 i;
|
||||
-
|
||||
- /* First attempt SMBIOS DMI */
|
||||
- uuid = dmi_get_system_info(DMI_PRODUCT_UUID);
|
||||
- if (uuid) {
|
||||
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
- "2088 SMBIOS UUID %s\n",
|
||||
- uuid);
|
||||
- } else {
|
||||
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
- "2099 Could not extract UUID\n");
|
||||
- }
|
||||
-
|
||||
- if (uuid && uuid_is_valid(uuid)) {
|
||||
- /* Generate PNI from UUID format.
|
||||
- *
|
||||
- * 1.) Extract lower 64 bits from UUID format.
|
||||
- * 2.) Set 3h for NAA Locally Assigned Name Identifier format.
|
||||
- *
|
||||
- * e.g. xxxxxxxx-xxxx-xxxx-yyyy-yyyyyyyyyyyy
|
||||
- *
|
||||
- * extract the yyyy-yyyyyyyyyyyy portion
|
||||
- * final PNI 3yyyyyyyyyyyyyyy
|
||||
- */
|
||||
- scnprintf(pni, sizeof(pni), "3%c%c%c%s",
|
||||
- uuid[20], uuid[21], uuid[22], &uuid[24]);
|
||||
-
|
||||
- /* Sanitize the converted PNI */
|
||||
- for (i = 1; i < 16 && (is_ff || is_00); i++) {
|
||||
- if (pni[i] != '0')
|
||||
- is_00 = false;
|
||||
- if (pni[i] != 'f' && pni[i] != 'F')
|
||||
- is_ff = false;
|
||||
- }
|
||||
-
|
||||
- /* Convert from char* to unsigned long */
|
||||
- rc = kstrtoul(pni, 16, &phba->pni);
|
||||
- if (!rc && !is_ff && !is_00) {
|
||||
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
- "2100 PNI 0x%016lx\n", phba->pni);
|
||||
- } else {
|
||||
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
- "2101 PNI %s generation status %d\n",
|
||||
- pni, rc);
|
||||
- phba->pni = 0;
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* lpfc_sli4_hba_setup - SLI4 device initialization PCI function
|
||||
* @phba: Pointer to HBA context object.
|
||||
@@ -8598,10 +8532,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||
clear_bit(HBA_FCOE_MODE, &phba->hba_flag);
|
||||
}
|
||||
|
||||
- /* Obtain platform UUID, only for SLI4 FC adapters */
|
||||
- if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag))
|
||||
- lpfc_get_platform_uuid(phba);
|
||||
-
|
||||
if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
|
||||
LPFC_DCBX_CEE_MODE)
|
||||
set_bit(HBA_FIP_SUPPORT, &phba->hba_flag);
|
||||
@ -0,0 +1,30 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Allow support for BB credit recovery in point-to-point topology"
|
||||
# Revert of a07aace5da5f860c8db0ec271438e9b46e3db858
|
||||
scsi: lpfc: Allow support for BB credit recovery in point-to-point topology
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index c07d6805dbdb..0ebd6a0b0b76 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -2279,8 +2279,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
|
||||
|
||||
sp->cmn.valid_vendor_ver_level = 0;
|
||||
memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion));
|
||||
- if (!test_bit(FC_PT2PT, &vport->fc_flag))
|
||||
- sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
+ sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
|
||||
/* Check if the destination port supports VMID */
|
||||
ndlp->vmid_support = 0;
|
||||
@@ -5670,8 +5669,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
|
||||
sp->cmn.valid_vendor_ver_level = 0;
|
||||
memset(sp->un.vendorVersion, 0,
|
||||
sizeof(sp->un.vendorVersion));
|
||||
- if (!test_bit(FC_PT2PT, &vport->fc_flag))
|
||||
- sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
+ sp->cmn.bbRcvSizeMsb &= 0xF;
|
||||
|
||||
/* If our firmware supports this feature, convey that
|
||||
* info to the target using the vendor specific field.
|
||||
@ -0,0 +1,234 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Modify kref handling for Fabric Controller ndlps"
|
||||
# Revert of f827c0e0303fbe9099192ebe9363b1170bc9d736
|
||||
scsi: lpfc: Modify kref handling for Fabric Controller ndlps
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 0f9ddb7d2e7b..74b1a4116aee 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -3390,21 +3390,11 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_cmpl_els_edc(phba, cmdiocb, rspiocb);
|
||||
return;
|
||||
}
|
||||
-
|
||||
if (ulp_status) {
|
||||
/* ELS discovery cmd completes with error */
|
||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS | LOG_CGN_MGMT,
|
||||
"4203 ELS cmd x%x error: x%x x%X\n", cmd,
|
||||
ulp_status, ulp_word4);
|
||||
-
|
||||
- /* In the case where the ELS cmd completes with an error and
|
||||
- * the node does not have RPI registered, the node is
|
||||
- * outstanding and should put its initial reference.
|
||||
- */
|
||||
- if ((cmd == ELS_CMD_SCR || cmd == ELS_CMD_RDF) &&
|
||||
- !(ndlp->fc4_xpt_flags & SCSI_XPT_REGD) &&
|
||||
- !test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
- lpfc_nlp_put(ndlp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3473,7 +3463,6 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
|
||||
uint8_t *pcmd;
|
||||
uint16_t cmdsize;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
- bool node_created = false;
|
||||
|
||||
cmdsize = (sizeof(uint32_t) + sizeof(SCR));
|
||||
|
||||
@@ -3483,21 +3472,21 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
|
||||
if (!ndlp)
|
||||
return 1;
|
||||
lpfc_enqueue_node(vport, ndlp);
|
||||
- node_created = true;
|
||||
}
|
||||
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_SCR);
|
||||
if (!elsiocb)
|
||||
- goto out_node_created;
|
||||
+ return 1;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
rc = lpfc_reg_fab_ctrl_node(vport, ndlp);
|
||||
if (rc) {
|
||||
+ lpfc_els_free_iocb(phba, elsiocb);
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
|
||||
"0937 %s: Failed to reg fc node, rc %d\n",
|
||||
__func__, rc);
|
||||
- goto out_free_iocb;
|
||||
+ return 1;
|
||||
}
|
||||
}
|
||||
pcmd = (uint8_t *)elsiocb->cmd_dmabuf->virt;
|
||||
@@ -3516,27 +3505,23 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
|
||||
phba->fc_stat.elsXmitSCR++;
|
||||
elsiocb->cmd_cmpl = lpfc_cmpl_els_disc_cmd;
|
||||
elsiocb->ndlp = lpfc_nlp_get(ndlp);
|
||||
- if (!elsiocb->ndlp)
|
||||
- goto out_free_iocb;
|
||||
+ if (!elsiocb->ndlp) {
|
||||
+ lpfc_els_free_iocb(phba, elsiocb);
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
"Issue SCR: did:x%x refcnt %d",
|
||||
ndlp->nlp_DID, kref_read(&ndlp->kref), 0);
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
- if (rc == IOCB_ERROR)
|
||||
- goto out_iocb_error;
|
||||
+ if (rc == IOCB_ERROR) {
|
||||
+ lpfc_els_free_iocb(phba, elsiocb);
|
||||
+ lpfc_nlp_put(ndlp);
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
-
|
||||
-out_iocb_error:
|
||||
- lpfc_nlp_put(ndlp);
|
||||
-out_free_iocb:
|
||||
- lpfc_els_free_iocb(phba, elsiocb);
|
||||
-out_node_created:
|
||||
- if (node_created)
|
||||
- lpfc_nlp_put(ndlp);
|
||||
- return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3749,12 +3734,7 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||
*
|
||||
* Return code
|
||||
* 0 - Successfully issued rdf command
|
||||
- * < 0 - Failed to issue rdf command
|
||||
- * -EACCES - RDF not required for NPIV_PORT
|
||||
- * -ENODEV - No fabric controller device available
|
||||
- * -ENOMEM - No available memory
|
||||
- * -EIO - The mailbox failed to complete successfully.
|
||||
- *
|
||||
+ * 1 - Failed to issue rdf command
|
||||
**/
|
||||
int
|
||||
lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
@@ -3765,30 +3745,25 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
struct lpfc_nodelist *ndlp;
|
||||
uint16_t cmdsize;
|
||||
int rc;
|
||||
- bool node_created = false;
|
||||
- int err;
|
||||
|
||||
cmdsize = sizeof(*prdf);
|
||||
|
||||
- /* RDF ELS is not required on an NPIV VN_Port. */
|
||||
- if (vport->port_type == LPFC_NPIV_PORT)
|
||||
- return -EACCES;
|
||||
-
|
||||
ndlp = lpfc_findnode_did(vport, Fabric_Cntl_DID);
|
||||
if (!ndlp) {
|
||||
ndlp = lpfc_nlp_init(vport, Fabric_Cntl_DID);
|
||||
if (!ndlp)
|
||||
return -ENODEV;
|
||||
lpfc_enqueue_node(vport, ndlp);
|
||||
- node_created = true;
|
||||
}
|
||||
|
||||
+ /* RDF ELS is not required on an NPIV VN_Port. */
|
||||
+ if (vport->port_type == LPFC_NPIV_PORT)
|
||||
+ return -EACCES;
|
||||
+
|
||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||
ndlp->nlp_DID, ELS_CMD_RDF);
|
||||
- if (!elsiocb) {
|
||||
- err = -ENOMEM;
|
||||
- goto out_node_created;
|
||||
- }
|
||||
+ if (!elsiocb)
|
||||
+ return -ENOMEM;
|
||||
|
||||
/* Configure the payload for the supported FPIN events. */
|
||||
prdf = (struct lpfc_els_rdf_req *)elsiocb->cmd_dmabuf->virt;
|
||||
@@ -3814,8 +3789,8 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
elsiocb->cmd_cmpl = lpfc_cmpl_els_disc_cmd;
|
||||
elsiocb->ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!elsiocb->ndlp) {
|
||||
- err = -EIO;
|
||||
- goto out_free_iocb;
|
||||
+ lpfc_els_free_iocb(phba, elsiocb);
|
||||
+ return -EIO;
|
||||
}
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
@@ -3824,19 +3799,11 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
- err = -EIO;
|
||||
- goto out_iocb_error;
|
||||
+ lpfc_els_free_iocb(phba, elsiocb);
|
||||
+ lpfc_nlp_put(ndlp);
|
||||
+ return -EIO;
|
||||
}
|
||||
return 0;
|
||||
-
|
||||
-out_iocb_error:
|
||||
- lpfc_nlp_put(ndlp);
|
||||
-out_free_iocb:
|
||||
- lpfc_els_free_iocb(phba, elsiocb);
|
||||
-out_node_created:
|
||||
- if (node_created)
|
||||
- lpfc_nlp_put(ndlp);
|
||||
- return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3857,23 +3824,19 @@ static int
|
||||
lpfc_els_rcv_rdf(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
- int rc;
|
||||
-
|
||||
- rc = lpfc_els_rsp_acc(vport, ELS_CMD_RDF, cmdiocb, ndlp, NULL);
|
||||
/* Send LS_ACC */
|
||||
- if (rc) {
|
||||
+ if (lpfc_els_rsp_acc(vport, ELS_CMD_RDF, cmdiocb, ndlp, NULL)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
- "1623 Failed to RDF_ACC from x%x for x%x Data: %d\n",
|
||||
- ndlp->nlp_DID, vport->fc_myDID, rc);
|
||||
+ "1623 Failed to RDF_ACC from x%x for x%x\n",
|
||||
+ ndlp->nlp_DID, vport->fc_myDID);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
- rc = lpfc_issue_els_rdf(vport, 0);
|
||||
/* Issue new RDF for reregistering */
|
||||
- if (rc) {
|
||||
+ if (lpfc_issue_els_rdf(vport, 0)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
|
||||
- "2623 Failed to re register RDF for x%x Data: %d\n",
|
||||
- vport->fc_myDID, rc);
|
||||
+ "2623 Failed to re register RDF for x%x\n",
|
||||
+ vport->fc_myDID);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
||||
index f3bd42652549..e32a2dfa516a 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_init.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
||||
@@ -3057,6 +3057,12 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
||||
lpfc_vmid_vport_cleanup(vport);
|
||||
|
||||
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
|
||||
+ if (ndlp->nlp_DID == Fabric_Cntl_DID &&
|
||||
+ ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
|
||||
+ lpfc_nlp_put(ndlp);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
/* Fabric Ports not in UNMAPPED state are cleaned up in the
|
||||
* DEVICE_RM event.
|
||||
*/
|
||||
@ -0,0 +1,169 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Fix leaked ndlp krefs when in point-to-point topology"
|
||||
# Revert of 355b54c3c42b0525403b8b17058d27d418a24106
|
||||
scsi: lpfc: Fix leaked ndlp krefs when in point-to-point topology
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
|
||||
index 42bf2fda825f..4d095a3bcb0e 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc.h
|
||||
@@ -312,6 +312,7 @@ struct lpfc_defer_flogi_acc {
|
||||
u16 rx_id;
|
||||
u16 ox_id;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
+
|
||||
};
|
||||
|
||||
#define LPFC_VMID_TIMER 300 /* timer interval in seconds */
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
|
||||
index 51cb8571c049..3d47dc7458d1 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_disc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_disc.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2013 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
@@ -208,7 +208,6 @@ enum lpfc_nlp_flag {
|
||||
NPR list */
|
||||
NLP_RM_DFLT_RPI = 26, /* need to remove leftover dflt RPI */
|
||||
NLP_NODEV_REMOVE = 27, /* Defer removal till discovery ends */
|
||||
- NLP_FLOGI_DFR_ACC = 28, /* FLOGI LS_ACC was Deferred */
|
||||
NLP_SC_REQ = 29, /* Target requires authentication */
|
||||
NLP_FIRSTBURST = 30, /* Target supports FirstBurst */
|
||||
NLP_RPI_REGISTERED = 31 /* nlp_rpi is valid */
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 74b1a4116aee..5beef9df9884 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -1413,12 +1413,11 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
phba->defer_flogi_acc.ox_id;
|
||||
}
|
||||
|
||||
- /* The LS_ACC completion needs to drop the initial reference.
|
||||
- * This is a special case for Pt2Pt because both FLOGIs need
|
||||
- * to complete and lpfc defers the LS_ACC when the remote
|
||||
- * FLOGI arrives before the driver's FLOGI.
|
||||
- */
|
||||
- set_bit(NLP_FLOGI_DFR_ACC, &ndlp->nlp_flag);
|
||||
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
+ "3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
|
||||
+ " ox_id: x%x, hba_flag x%lx\n",
|
||||
+ phba->defer_flogi_acc.rx_id,
|
||||
+ phba->defer_flogi_acc.ox_id, phba->hba_flag);
|
||||
|
||||
/* Send deferred FLOGI ACC */
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, &defer_flogi_acc,
|
||||
@@ -1434,14 +1433,6 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
phba->defer_flogi_acc.ndlp = NULL;
|
||||
}
|
||||
|
||||
- lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
- "3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
|
||||
- " ox_id: x%x, ndlp x%px hba_flag x%lx\n",
|
||||
- phba->defer_flogi_acc.rx_id,
|
||||
- phba->defer_flogi_acc.ox_id,
|
||||
- phba->defer_flogi_acc.ndlp,
|
||||
- phba->hba_flag);
|
||||
-
|
||||
vport->fc_myDID = did;
|
||||
}
|
||||
|
||||
@@ -5310,12 +5301,11 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
IOCB_t *irsp;
|
||||
LPFC_MBOXQ_t *mbox = NULL;
|
||||
u32 ulp_status, ulp_word4, tmo, did, iotag;
|
||||
- u32 cmd;
|
||||
|
||||
if (!vport) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_ELS,
|
||||
"3177 null vport in ELS rsp\n");
|
||||
- goto release;
|
||||
+ goto out;
|
||||
}
|
||||
if (cmdiocb->context_un.mbox)
|
||||
mbox = cmdiocb->context_un.mbox;
|
||||
@@ -5425,7 +5415,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
* these conditions because it doesn't need the login.
|
||||
*/
|
||||
if (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||
- vport->port_type == LPFC_NPIV_PORT &&
|
||||
+ vport && vport->port_type == LPFC_NPIV_PORT &&
|
||||
!(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) {
|
||||
if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE &&
|
||||
ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE &&
|
||||
@@ -5441,27 +5431,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
}
|
||||
}
|
||||
|
||||
- /* The driver's unsolicited deferred FLOGI ACC in Pt2Pt needs to
|
||||
- * release the initial reference because the put after the free_iocb
|
||||
- * call removes only the reference from the defer logic. This FLOGI
|
||||
- * is never registered with the SCSI transport.
|
||||
- */
|
||||
- if (test_bit(FC_PT2PT, &vport->fc_flag) &&
|
||||
- test_and_clear_bit(NLP_FLOGI_DFR_ACC, &ndlp->nlp_flag)) {
|
||||
- lpfc_printf_vlog(vport, KERN_INFO,
|
||||
- LOG_ELS | LOG_NODE | LOG_DISCOVERY,
|
||||
- "3357 Pt2Pt Defer FLOGI ACC ndlp x%px, "
|
||||
- "nflags x%lx, fc_flag x%lx\n",
|
||||
- ndlp, ndlp->nlp_flag,
|
||||
- vport->fc_flag);
|
||||
- cmd = *((u32 *)cmdiocb->cmd_dmabuf->virt);
|
||||
- if (cmd == ELS_CMD_ACC) {
|
||||
- if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
- lpfc_nlp_put(ndlp);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-release:
|
||||
/* Release the originating I/O reference. */
|
||||
lpfc_els_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
@@ -8430,6 +8399,13 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
&wqe->xmit_els_rsp.wqe_com);
|
||||
|
||||
vport->fc_myDID = did;
|
||||
+
|
||||
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
+ "3344 Deferring FLOGI ACC: rx_id: x%x,"
|
||||
+ " ox_id: x%x, hba_flag x%lx\n",
|
||||
+ phba->defer_flogi_acc.rx_id,
|
||||
+ phba->defer_flogi_acc.ox_id, phba->hba_flag);
|
||||
+
|
||||
phba->defer_flogi_acc.flag = true;
|
||||
|
||||
/* This nlp_get is paired with nlp_puts that reset the
|
||||
@@ -8438,14 +8414,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
* processed or cancelled.
|
||||
*/
|
||||
phba->defer_flogi_acc.ndlp = lpfc_nlp_get(ndlp);
|
||||
-
|
||||
- lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
- "3344 Deferring FLOGI ACC: rx_id: x%x,"
|
||||
- " ox_id: x%x, ndlp x%px, hba_flag x%lx\n",
|
||||
- phba->defer_flogi_acc.rx_id,
|
||||
- phba->defer_flogi_acc.ox_id,
|
||||
- phba->defer_flogi_acc.ndlp,
|
||||
- phba->hba_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10391,8 +10359,11 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
* Do not process any unsolicited ELS commands
|
||||
* if the ndlp is in DEV_LOSS
|
||||
*/
|
||||
- if (test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag))
|
||||
+ if (test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag)) {
|
||||
+ if (newnode)
|
||||
+ lpfc_nlp_put(ndlp);
|
||||
goto dropit;
|
||||
+ }
|
||||
|
||||
elsiocb->ndlp = lpfc_nlp_get(ndlp);
|
||||
if (!elsiocb->ndlp)
|
||||
@ -0,0 +1,54 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Ensure unregistration of rpis for received PLOGIs"
|
||||
# Revert of 35234917d9a2719b77db215e5b8dce2e2687bce9
|
||||
scsi: lpfc: Ensure unregistration of rpis for received PLOGIs
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 5beef9df9884..377add7048d7 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -3263,7 +3263,7 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = lpfc_reg_rpi(phba, vport->vpi, fc_ndlp->nlp_DID,
|
||||
- (u8 *)&ns_ndlp->fc_sparam, mbox, fc_ndlp->nlp_rpi);
|
||||
+ (u8 *)&vport->fc_sparam, mbox, fc_ndlp->nlp_rpi);
|
||||
if (rc) {
|
||||
rc = -EACCES;
|
||||
goto out;
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
index e16370da3e45..99aefc54ac35 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
@@ -452,7 +452,18 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
*/
|
||||
if (!(ndlp->nlp_type & NLP_FABRIC) &&
|
||||
!(phba->nvmet_support)) {
|
||||
- break;
|
||||
+ /* Clear ndlp info, since follow up PRLI may have
|
||||
+ * updated ndlp information
|
||||
+ */
|
||||
+ ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||
+ ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||
+ ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
+ ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
|
||||
+ clear_bit(NLP_FIRSTBURST, &ndlp->nlp_flag);
|
||||
+
|
||||
+ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
|
||||
+ ndlp, NULL);
|
||||
+ return 1;
|
||||
}
|
||||
if (nlp_portwwn != 0 &&
|
||||
nlp_portwwn != wwn_to_u64(sp->portName.u.wwn))
|
||||
@@ -474,9 +485,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
break;
|
||||
}
|
||||
- /* Clear ndlp info, since follow up processes may have
|
||||
- * updated ndlp information
|
||||
- */
|
||||
+
|
||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
@ -0,0 +1,25 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Remove redundant NULL ptr assignment in lpfc_els_free_iocb()"
|
||||
# Revert of 9ed3e03334ac8ffb8a7371dc760940ef8de5d0ea
|
||||
scsi: lpfc: Remove redundant NULL ptr assignment in lpfc_els_free_iocb()
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 377add7048d7..9bc2f4975566 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -5158,12 +5158,14 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
|
||||
} else {
|
||||
buf_ptr1 = elsiocb->cmd_dmabuf;
|
||||
lpfc_els_free_data(phba, buf_ptr1);
|
||||
+ elsiocb->cmd_dmabuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (elsiocb->bpl_dmabuf) {
|
||||
buf_ptr = elsiocb->bpl_dmabuf;
|
||||
lpfc_els_free_bpl(phba, buf_ptr);
|
||||
+ elsiocb->bpl_dmabuf = NULL;
|
||||
}
|
||||
lpfc_sli_release_iocbq(phba, elsiocb);
|
||||
return 0;
|
||||
@ -0,0 +1,107 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Revise discovery related function headers and comments"
|
||||
# Revert of 75d230ed196c1375f5a200039c8ee4495240c57c
|
||||
scsi: lpfc: Revise discovery related function headers and comments
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 9bc2f4975566..7f6ddf50c315 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -3024,7 +3024,6 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
ndlp->nlp_DID, ulp_status,
|
||||
ulp_word4);
|
||||
|
||||
- /* Call NLP_EVT_DEVICE_RM if link is down or LOGO is aborted */
|
||||
if (lpfc_error_lost_link(vport, ulp_status, ulp_word4))
|
||||
skip_recovery = 1;
|
||||
}
|
||||
@@ -3307,8 +3306,7 @@ lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
|
||||
*
|
||||
* This routine is a generic completion callback function for Discovery ELS cmd.
|
||||
* Currently used by the ELS command issuing routines for the ELS State Change
|
||||
- * Request (SCR), lpfc_issue_els_scr(), Exchange Diagnostic Capabilities (EDC),
|
||||
- * lpfc_issue_els_edc() and the ELS RDF, lpfc_issue_els_rdf().
|
||||
+ * Request (SCR), lpfc_issue_els_scr() and the ELS RDF, lpfc_issue_els_rdf().
|
||||
* These commands will be retried once only for ELS timeout errors.
|
||||
**/
|
||||
static void
|
||||
@@ -3707,7 +3705,10 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||
lpfc_nlp_put(ndlp);
|
||||
return 1;
|
||||
}
|
||||
-
|
||||
+ /* This will cause the callback-function lpfc_cmpl_els_cmd to
|
||||
+ * trigger the release of the node.
|
||||
+ */
|
||||
+ /* Don't release reference count as RDF is likely outstanding */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4298,7 +4299,7 @@ lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry)
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
/* The additional lpfc_nlp_put will cause the following
|
||||
- * lpfc_els_free_iocb routine to trigger the release of
|
||||
+ * lpfc_els_free_iocb routine to trigger the rlease of
|
||||
* the node.
|
||||
*/
|
||||
lpfc_els_free_iocb(phba, elsiocb);
|
||||
@@ -5125,7 +5126,7 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
|
||||
{
|
||||
struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
|
||||
|
||||
- /* The I/O iocb is complete. Clear the node and first dmabuf */
|
||||
+ /* The I/O iocb is complete. Clear the node and first dmbuf */
|
||||
elsiocb->ndlp = NULL;
|
||||
|
||||
/* cmd_dmabuf = cmd, cmd_dmabuf->next = rsp, bpl_dmabuf = bpl */
|
||||
@@ -8733,7 +8734,7 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
* @cmdiocb: pointer to lpfc command iocb data structure.
|
||||
* @ndlp: pointer to a node-list data structure.
|
||||
*
|
||||
- * This routine processes Read Timeout Value (RTV) IOCB received as an
|
||||
+ * This routine processes Read Timout Value (RTV) IOCB received as an
|
||||
* ELS unsolicited event. It first checks the remote port state. If the
|
||||
* remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
|
||||
* state, it invokes the lpfc_els_rsl_reject() routine to send the reject
|
||||
@@ -10847,7 +10848,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
|
||||
/*
|
||||
* The different unsolicited event handlers would tell us
|
||||
- * if they are done with "mp" by setting cmd_dmabuf/bpl_dmabuf to NULL.
|
||||
+ * if they are done with "mp" by setting cmd_dmabuf to NULL.
|
||||
*/
|
||||
if (elsiocb->cmd_dmabuf) {
|
||||
lpfc_in_buf_free(phba, elsiocb->cmd_dmabuf);
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index 66730c3e4cb9..e658f2a914d9 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -19867,15 +19867,13 @@ lpfc_sli4_remove_rpis(struct lpfc_hba *phba)
|
||||
}
|
||||
|
||||
/**
|
||||
- * lpfc_sli4_resume_rpi - Resume traffic relative to an RPI
|
||||
+ * lpfc_sli4_resume_rpi - Remove the rpi bitmask region
|
||||
* @ndlp: pointer to lpfc nodelist data structure.
|
||||
* @cmpl: completion call-back.
|
||||
* @iocbq: data to load as mbox ctx_u information
|
||||
*
|
||||
- * Return codes
|
||||
- * 0 - successful
|
||||
- * -ENOMEM - No available memory
|
||||
- * -EIO - The mailbox failed to complete successfully.
|
||||
+ * This routine is invoked to remove the memory region that
|
||||
+ * provided rpi via a bitmask.
|
||||
**/
|
||||
int
|
||||
lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp,
|
||||
@@ -19905,6 +19903,7 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
+ /* Post all rpi memory regions to the port. */
|
||||
lpfc_resume_rpi(mboxq, ndlp);
|
||||
if (cmpl) {
|
||||
mboxq->mbox_cmpl = cmpl;
|
||||
@ -0,0 +1,47 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Update various NPIV diagnostic log messaging"
|
||||
# Revert of 958b3db3862eeef3b1e92c877d70f57ce019740a
|
||||
scsi: lpfc: Update various NPIV diagnostic log messaging
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 7f6ddf50c315..0630d109e767 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -2367,7 +2367,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
mode = KERN_INFO;
|
||||
|
||||
/* Warn PRLI status */
|
||||
- lpfc_vlog_msg(vport, mode, LOG_ELS,
|
||||
+ lpfc_printf_vlog(vport, mode, LOG_ELS,
|
||||
"2754 PRLI DID:%06X Status:x%x/x%x, "
|
||||
"data: x%x x%x x%lx\n",
|
||||
ndlp->nlp_DID, ulp_status,
|
||||
@@ -3597,8 +3597,8 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry)
|
||||
}
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
- "Issue RSCN: did:x%x refcnt %d",
|
||||
- ndlp->nlp_DID, kref_read(&ndlp->kref), 0);
|
||||
+ "Issue RSCN: did:x%x",
|
||||
+ ndlp->nlp_DID, 0, 0);
|
||||
|
||||
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
|
||||
if (rc == IOCB_ERROR) {
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
||||
index e32a2dfa516a..2f3629ef64e6 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_init.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
||||
@@ -9077,9 +9077,9 @@ lpfc_setup_fdmi_mask(struct lpfc_vport *vport)
|
||||
vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
|
||||
}
|
||||
|
||||
- lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
- "6077 Setup FDMI mask: hba x%x port x%x\n",
|
||||
- vport->fdmi_hba_mask, vport->fdmi_port_mask);
|
||||
+ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
|
||||
+ "6077 Setup FDMI mask: hba x%x port x%x\n",
|
||||
+ vport->fdmi_hba_mask, vport->fdmi_port_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -0,0 +1,58 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Copyright updates for 14.4.0.11 patches"
|
||||
# Revert of 6da7906c531c73840fecb724d4da97334ab46ca6
|
||||
scsi: lpfc: Copyright updates for 14.4.0.11 patches
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
|
||||
index 4d095a3bcb0e..5e08f7a39702 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
index a1464f8ac331..566dd84e0677 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2007-2011 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
|
||||
index 3bc0efa7453e..b287d39ad033 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hw.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hw.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
index 99aefc54ac35..1e331b76dff4 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
@ -0,0 +1,19 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Update lpfc version to 14.4.0.11"
|
||||
# Revert of 1a4e6ee8d31372eff037fed3dfc762ecbe964e98
|
||||
scsi: lpfc: Update lpfc version to 14.4.0.11
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
|
||||
index 31c3c5abdca6..9ee3a3a4ec4d 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_version.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_version.h
|
||||
@@ -20,7 +20,7 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
-#define LPFC_DRIVER_VERSION "14.4.0.11"
|
||||
+#define LPFC_DRIVER_VERSION "14.4.0.10"
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
/* Used for SLI 2/3 */
|
||||
@ -0,0 +1,92 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Convert debugfs directory counts from atomic to unsigned int"
|
||||
# Revert of a20734de11ba1c0ef97622bf51ee502b626dca0a
|
||||
scsi: lpfc: Convert debugfs directory counts from atomic to unsigned int
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
|
||||
index 5e08f7a39702..291f0cc38f14 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc.h
|
||||
@@ -1333,7 +1333,7 @@ struct lpfc_hba {
|
||||
unsigned long last_ramp_down_time;
|
||||
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
|
||||
struct dentry *hba_debugfs_root;
|
||||
- unsigned int debugfs_vport_count;
|
||||
+ atomic_t debugfs_vport_count;
|
||||
|
||||
struct lpfc_debugfs_nvmeio_trc *nvmeio_trc;
|
||||
atomic_t nvmeio_trc_cnt;
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index a4378c66427c..bfc0b9c40c5b 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -5752,7 +5752,7 @@ static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
|
||||
};
|
||||
|
||||
static struct dentry *lpfc_debugfs_root = NULL;
|
||||
-static unsigned int lpfc_debugfs_hba_count;
|
||||
+static atomic_t lpfc_debugfs_hba_count;
|
||||
|
||||
/*
|
||||
* File operations for the iDiag debugfs
|
||||
@@ -6074,7 +6074,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
/* Setup lpfc root directory */
|
||||
if (!lpfc_debugfs_root) {
|
||||
lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
|
||||
- lpfc_debugfs_hba_count = 0;
|
||||
+ atomic_set(&lpfc_debugfs_hba_count, 0);
|
||||
if (IS_ERR(lpfc_debugfs_root)) {
|
||||
lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT,
|
||||
"0527 Cannot create debugfs lpfc\n");
|
||||
@@ -6090,13 +6090,13 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
pport_setup = true;
|
||||
phba->hba_debugfs_root =
|
||||
debugfs_create_dir(name, lpfc_debugfs_root);
|
||||
- phba->debugfs_vport_count = 0;
|
||||
+ atomic_set(&phba->debugfs_vport_count, 0);
|
||||
if (IS_ERR(phba->hba_debugfs_root)) {
|
||||
lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT,
|
||||
"0528 Cannot create debugfs %s\n", name);
|
||||
return;
|
||||
}
|
||||
- lpfc_debugfs_hba_count++;
|
||||
+ atomic_inc(&lpfc_debugfs_hba_count);
|
||||
|
||||
/* Multi-XRI pools */
|
||||
debugfs_create_file("multixripools", 0644,
|
||||
@@ -6268,7 +6268,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
"0529 Cannot create debugfs %s\n", name);
|
||||
return;
|
||||
}
|
||||
- phba->debugfs_vport_count++;
|
||||
+ atomic_inc(&phba->debugfs_vport_count);
|
||||
}
|
||||
|
||||
if (lpfc_debugfs_max_disc_trc) {
|
||||
@@ -6402,10 +6402,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
|
||||
if (vport->vport_debugfs_root) {
|
||||
debugfs_remove(vport->vport_debugfs_root); /* vportX */
|
||||
vport->vport_debugfs_root = NULL;
|
||||
- phba->debugfs_vport_count--;
|
||||
+ atomic_dec(&phba->debugfs_vport_count);
|
||||
}
|
||||
|
||||
- if (!phba->debugfs_vport_count) {
|
||||
+ if (atomic_read(&phba->debugfs_vport_count) == 0) {
|
||||
kfree(phba->slow_ring_trc);
|
||||
phba->slow_ring_trc = NULL;
|
||||
|
||||
@@ -6415,10 +6415,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
|
||||
if (phba->hba_debugfs_root) {
|
||||
debugfs_remove(phba->hba_debugfs_root); /* fnX */
|
||||
phba->hba_debugfs_root = NULL;
|
||||
- lpfc_debugfs_hba_count--;
|
||||
+ atomic_dec(&lpfc_debugfs_hba_count);
|
||||
}
|
||||
|
||||
- if (!lpfc_debugfs_hba_count) {
|
||||
+ if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
|
||||
debugfs_remove(lpfc_debugfs_root); /* lpfc */
|
||||
lpfc_debugfs_root = NULL;
|
||||
}
|
||||
@ -0,0 +1,683 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Clean up extraneous phba dentries"
|
||||
# Revert of 080408a120c922181dec5d5a59ee6e94b010bbc5
|
||||
scsi: lpfc: Clean up extraneous phba dentries
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
|
||||
index 291f0cc38f14..0a43be24cee8 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc.h
|
||||
@@ -742,6 +742,12 @@ struct lpfc_vport {
|
||||
struct lpfc_vmid_priority_info vmid_priority;
|
||||
|
||||
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
|
||||
+ struct dentry *debug_disc_trc;
|
||||
+ struct dentry *debug_nodelist;
|
||||
+ struct dentry *debug_nvmestat;
|
||||
+ struct dentry *debug_scsistat;
|
||||
+ struct dentry *debug_ioktime;
|
||||
+ struct dentry *debug_hdwqstat;
|
||||
struct dentry *vport_debugfs_root;
|
||||
struct lpfc_debugfs_trc *disc_trc;
|
||||
atomic_t disc_trc_cnt;
|
||||
@@ -1334,8 +1340,29 @@ struct lpfc_hba {
|
||||
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
|
||||
struct dentry *hba_debugfs_root;
|
||||
atomic_t debugfs_vport_count;
|
||||
-
|
||||
+ struct dentry *debug_multixri_pools;
|
||||
+ struct dentry *debug_hbqinfo;
|
||||
+ struct dentry *debug_dumpHostSlim;
|
||||
+ struct dentry *debug_dumpHBASlim;
|
||||
+ struct dentry *debug_InjErrLBA; /* LBA to inject errors at */
|
||||
+ struct dentry *debug_InjErrNPortID; /* NPortID to inject errors at */
|
||||
+ struct dentry *debug_InjErrWWPN; /* WWPN to inject errors at */
|
||||
+ struct dentry *debug_writeGuard; /* inject write guard_tag errors */
|
||||
+ struct dentry *debug_writeApp; /* inject write app_tag errors */
|
||||
+ struct dentry *debug_writeRef; /* inject write ref_tag errors */
|
||||
+ struct dentry *debug_readGuard; /* inject read guard_tag errors */
|
||||
+ struct dentry *debug_readApp; /* inject read app_tag errors */
|
||||
+ struct dentry *debug_readRef; /* inject read ref_tag errors */
|
||||
+
|
||||
+ struct dentry *debug_nvmeio_trc;
|
||||
struct lpfc_debugfs_nvmeio_trc *nvmeio_trc;
|
||||
+ struct dentry *debug_hdwqinfo;
|
||||
+#ifdef LPFC_HDWQ_LOCK_STAT
|
||||
+ struct dentry *debug_lockstat;
|
||||
+#endif
|
||||
+ struct dentry *debug_cgn_buffer;
|
||||
+ struct dentry *debug_rx_monitor;
|
||||
+ struct dentry *debug_ras_log;
|
||||
atomic_t nvmeio_trc_cnt;
|
||||
uint32_t nvmeio_trc_size;
|
||||
uint32_t nvmeio_trc_output_idx;
|
||||
@@ -1352,10 +1379,19 @@ struct lpfc_hba {
|
||||
sector_t lpfc_injerr_lba;
|
||||
#define LPFC_INJERR_LBA_OFF (sector_t)(-1)
|
||||
|
||||
+ struct dentry *debug_slow_ring_trc;
|
||||
struct lpfc_debugfs_trc *slow_ring_trc;
|
||||
atomic_t slow_ring_trc_cnt;
|
||||
/* iDiag debugfs sub-directory */
|
||||
struct dentry *idiag_root;
|
||||
+ struct dentry *idiag_pci_cfg;
|
||||
+ struct dentry *idiag_bar_acc;
|
||||
+ struct dentry *idiag_que_info;
|
||||
+ struct dentry *idiag_que_acc;
|
||||
+ struct dentry *idiag_drb_acc;
|
||||
+ struct dentry *idiag_ctl_acc;
|
||||
+ struct dentry *idiag_mbx_acc;
|
||||
+ struct dentry *idiag_ext_acc;
|
||||
uint8_t lpfc_idiag_last_eq;
|
||||
#endif
|
||||
uint16_t nvmeio_trc_on;
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index bfc0b9c40c5b..892e2177663a 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -6075,11 +6075,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
if (!lpfc_debugfs_root) {
|
||||
lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
|
||||
atomic_set(&lpfc_debugfs_hba_count, 0);
|
||||
- if (IS_ERR(lpfc_debugfs_root)) {
|
||||
- lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT,
|
||||
- "0527 Cannot create debugfs lpfc\n");
|
||||
- return;
|
||||
- }
|
||||
}
|
||||
if (!lpfc_debugfs_start_time)
|
||||
lpfc_debugfs_start_time = jiffies;
|
||||
@@ -6090,96 +6085,150 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
pport_setup = true;
|
||||
phba->hba_debugfs_root =
|
||||
debugfs_create_dir(name, lpfc_debugfs_root);
|
||||
- atomic_set(&phba->debugfs_vport_count, 0);
|
||||
- if (IS_ERR(phba->hba_debugfs_root)) {
|
||||
- lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT,
|
||||
- "0528 Cannot create debugfs %s\n", name);
|
||||
- return;
|
||||
- }
|
||||
atomic_inc(&lpfc_debugfs_hba_count);
|
||||
+ atomic_set(&phba->debugfs_vport_count, 0);
|
||||
|
||||
/* Multi-XRI pools */
|
||||
- debugfs_create_file("multixripools", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- &lpfc_debugfs_op_multixripools);
|
||||
+ snprintf(name, sizeof(name), "multixripools");
|
||||
+ phba->debug_multixri_pools =
|
||||
+ debugfs_create_file(name, S_IFREG | 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba,
|
||||
+ &lpfc_debugfs_op_multixripools);
|
||||
+ if (IS_ERR(phba->debug_multixri_pools)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "0527 Cannot create debugfs multixripools\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
|
||||
/* Congestion Info Buffer */
|
||||
- debugfs_create_file("cgn_buffer", 0644, phba->hba_debugfs_root,
|
||||
- phba, &lpfc_cgn_buffer_op);
|
||||
+ scnprintf(name, sizeof(name), "cgn_buffer");
|
||||
+ phba->debug_cgn_buffer =
|
||||
+ debugfs_create_file(name, S_IFREG | 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_cgn_buffer_op);
|
||||
+ if (IS_ERR(phba->debug_cgn_buffer)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "6527 Cannot create debugfs "
|
||||
+ "cgn_buffer\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
|
||||
/* RX Monitor */
|
||||
- debugfs_create_file("rx_monitor", 0644, phba->hba_debugfs_root,
|
||||
- phba, &lpfc_rx_monitor_op);
|
||||
+ scnprintf(name, sizeof(name), "rx_monitor");
|
||||
+ phba->debug_rx_monitor =
|
||||
+ debugfs_create_file(name, S_IFREG | 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_rx_monitor_op);
|
||||
+ if (IS_ERR(phba->debug_rx_monitor)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "6528 Cannot create debugfs "
|
||||
+ "rx_monitor\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
|
||||
/* RAS log */
|
||||
- debugfs_create_file("ras_log", 0644, phba->hba_debugfs_root,
|
||||
- phba, &lpfc_debugfs_ras_log);
|
||||
+ snprintf(name, sizeof(name), "ras_log");
|
||||
+ phba->debug_ras_log =
|
||||
+ debugfs_create_file(name, 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_ras_log);
|
||||
+ if (IS_ERR(phba->debug_ras_log)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "6148 Cannot create debugfs"
|
||||
+ " ras_log\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
|
||||
/* Setup hbqinfo */
|
||||
- debugfs_create_file("hbqinfo", 0644, phba->hba_debugfs_root,
|
||||
- phba, &lpfc_debugfs_op_hbqinfo);
|
||||
+ snprintf(name, sizeof(name), "hbqinfo");
|
||||
+ phba->debug_hbqinfo =
|
||||
+ debugfs_create_file(name, S_IFREG | 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_op_hbqinfo);
|
||||
|
||||
#ifdef LPFC_HDWQ_LOCK_STAT
|
||||
/* Setup lockstat */
|
||||
- debugfs_create_file("lockstat", 0644, phba->hba_debugfs_root,
|
||||
- phba, &lpfc_debugfs_op_lockstat);
|
||||
+ snprintf(name, sizeof(name), "lockstat");
|
||||
+ phba->debug_lockstat =
|
||||
+ debugfs_create_file(name, S_IFREG | 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_op_lockstat);
|
||||
+ if (IS_ERR(phba->debug_lockstat)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "4610 Can't create debugfs lockstat\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
#endif
|
||||
+
|
||||
+ /* Setup dumpHBASlim */
|
||||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
- /* Setup dumpHBASlim */
|
||||
- debugfs_create_file("dumpHBASlim", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- &lpfc_debugfs_op_dumpHBASlim);
|
||||
- }
|
||||
+ snprintf(name, sizeof(name), "dumpHBASlim");
|
||||
+ phba->debug_dumpHBASlim =
|
||||
+ debugfs_create_file(name,
|
||||
+ S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_op_dumpHBASlim);
|
||||
+ } else
|
||||
+ phba->debug_dumpHBASlim = NULL;
|
||||
|
||||
+ /* Setup dumpHostSlim */
|
||||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
- /* Setup dumpHostSlim */
|
||||
- debugfs_create_file("dumpHostSlim", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- &lpfc_debugfs_op_dumpHostSlim);
|
||||
- }
|
||||
+ snprintf(name, sizeof(name), "dumpHostSlim");
|
||||
+ phba->debug_dumpHostSlim =
|
||||
+ debugfs_create_file(name,
|
||||
+ S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_op_dumpHostSlim);
|
||||
+ } else
|
||||
+ phba->debug_dumpHostSlim = NULL;
|
||||
|
||||
/* Setup DIF Error Injections */
|
||||
- debugfs_create_file_aux_num("InjErrLBA", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- InjErrLBA,
|
||||
- &lpfc_debugfs_op_dif_err);
|
||||
+ phba->debug_InjErrLBA =
|
||||
+ debugfs_create_file_aux_num("InjErrLBA", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, InjErrLBA, &lpfc_debugfs_op_dif_err);
|
||||
phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
|
||||
|
||||
- debugfs_create_file_aux_num("InjErrNPortID", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- InjErrNPortID,
|
||||
- &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("InjErrWWPN", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- InjErrWWPN,
|
||||
- &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("writeGuardInjErr", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- writeGuard,
|
||||
- &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("writeAppInjErr", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- writeApp, &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("writeRefInjErr", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- writeRef, &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("readGuardInjErr", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- readGuard,
|
||||
- &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("readAppInjErr", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- readApp, &lpfc_debugfs_op_dif_err);
|
||||
-
|
||||
- debugfs_create_file_aux_num("readRefInjErr", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- readRef, &lpfc_debugfs_op_dif_err);
|
||||
+ phba->debug_InjErrNPortID =
|
||||
+ debugfs_create_file_aux_num("InjErrNPortID", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, InjErrNPortID, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_InjErrWWPN =
|
||||
+ debugfs_create_file_aux_num("InjErrWWPN", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, InjErrWWPN, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_writeGuard =
|
||||
+ debugfs_create_file_aux_num("writeGuardInjErr", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, writeGuard, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_writeApp =
|
||||
+ debugfs_create_file_aux_num("writeAppInjErr", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, writeApp, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_writeRef =
|
||||
+ debugfs_create_file_aux_num("writeRefInjErr", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, writeRef, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_readGuard =
|
||||
+ debugfs_create_file_aux_num("readGuardInjErr", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, readGuard, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_readApp =
|
||||
+ debugfs_create_file_aux_num("readAppInjErr", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, readApp, &lpfc_debugfs_op_dif_err);
|
||||
+
|
||||
+ phba->debug_readRef =
|
||||
+ debugfs_create_file_aux_num("readRefInjErr", 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, readRef, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
/* Setup slow ring trace */
|
||||
if (lpfc_debugfs_max_slow_ring_trc) {
|
||||
@@ -6199,9 +6248,11 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
}
|
||||
}
|
||||
|
||||
- debugfs_create_file("slow_ring_trace", 0644,
|
||||
- phba->hba_debugfs_root, phba,
|
||||
- &lpfc_debugfs_op_slow_ring_trc);
|
||||
+ snprintf(name, sizeof(name), "slow_ring_trace");
|
||||
+ phba->debug_slow_ring_trc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_op_slow_ring_trc);
|
||||
if (!phba->slow_ring_trc) {
|
||||
phba->slow_ring_trc = kcalloc(
|
||||
lpfc_debugfs_max_slow_ring_trc,
|
||||
@@ -6211,13 +6262,16 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
"0416 Cannot create debugfs "
|
||||
"slow_ring buffer\n");
|
||||
- goto out;
|
||||
+ goto debug_failed;
|
||||
}
|
||||
atomic_set(&phba->slow_ring_trc_cnt, 0);
|
||||
}
|
||||
|
||||
- debugfs_create_file("nvmeio_trc", 0644, phba->hba_debugfs_root,
|
||||
- phba, &lpfc_debugfs_op_nvmeio_trc);
|
||||
+ snprintf(name, sizeof(name), "nvmeio_trc");
|
||||
+ phba->debug_nvmeio_trc =
|
||||
+ debugfs_create_file(name, 0644,
|
||||
+ phba->hba_debugfs_root,
|
||||
+ phba, &lpfc_debugfs_op_nvmeio_trc);
|
||||
|
||||
atomic_set(&phba->nvmeio_trc_cnt, 0);
|
||||
if (lpfc_debugfs_max_nvmeio_trc) {
|
||||
@@ -6263,11 +6317,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
if (!vport->vport_debugfs_root) {
|
||||
vport->vport_debugfs_root =
|
||||
debugfs_create_dir(name, phba->hba_debugfs_root);
|
||||
- if (IS_ERR(vport->vport_debugfs_root)) {
|
||||
- lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT,
|
||||
- "0529 Cannot create debugfs %s\n", name);
|
||||
- return;
|
||||
- }
|
||||
atomic_inc(&phba->debugfs_vport_count);
|
||||
}
|
||||
|
||||
@@ -6295,27 +6344,54 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
"0418 Cannot create debugfs disc trace "
|
||||
"buffer\n");
|
||||
- goto out;
|
||||
+ goto debug_failed;
|
||||
}
|
||||
atomic_set(&vport->disc_trc_cnt, 0);
|
||||
|
||||
- debugfs_create_file("discovery_trace", 0644, vport->vport_debugfs_root,
|
||||
- vport, &lpfc_debugfs_op_disc_trc);
|
||||
-
|
||||
- debugfs_create_file("nodelist", 0644, vport->vport_debugfs_root, vport,
|
||||
- &lpfc_debugfs_op_nodelist);
|
||||
-
|
||||
- debugfs_create_file("nvmestat", 0644, vport->vport_debugfs_root, vport,
|
||||
- &lpfc_debugfs_op_nvmestat);
|
||||
-
|
||||
- debugfs_create_file("scsistat", 0644, vport->vport_debugfs_root, vport,
|
||||
- &lpfc_debugfs_op_scsistat);
|
||||
+ snprintf(name, sizeof(name), "discovery_trace");
|
||||
+ vport->debug_disc_trc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ vport->vport_debugfs_root,
|
||||
+ vport, &lpfc_debugfs_op_disc_trc);
|
||||
+ snprintf(name, sizeof(name), "nodelist");
|
||||
+ vport->debug_nodelist =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ vport->vport_debugfs_root,
|
||||
+ vport, &lpfc_debugfs_op_nodelist);
|
||||
+
|
||||
+ snprintf(name, sizeof(name), "nvmestat");
|
||||
+ vport->debug_nvmestat =
|
||||
+ debugfs_create_file(name, 0644,
|
||||
+ vport->vport_debugfs_root,
|
||||
+ vport, &lpfc_debugfs_op_nvmestat);
|
||||
+
|
||||
+ snprintf(name, sizeof(name), "scsistat");
|
||||
+ vport->debug_scsistat =
|
||||
+ debugfs_create_file(name, 0644,
|
||||
+ vport->vport_debugfs_root,
|
||||
+ vport, &lpfc_debugfs_op_scsistat);
|
||||
+ if (IS_ERR(vport->debug_scsistat)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "4611 Cannot create debugfs scsistat\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
|
||||
- debugfs_create_file("ioktime", 0644, vport->vport_debugfs_root, vport,
|
||||
- &lpfc_debugfs_op_ioktime);
|
||||
+ snprintf(name, sizeof(name), "ioktime");
|
||||
+ vport->debug_ioktime =
|
||||
+ debugfs_create_file(name, 0644,
|
||||
+ vport->vport_debugfs_root,
|
||||
+ vport, &lpfc_debugfs_op_ioktime);
|
||||
+ if (IS_ERR(vport->debug_ioktime)) {
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
+ "0815 Cannot create debugfs ioktime\n");
|
||||
+ goto debug_failed;
|
||||
+ }
|
||||
|
||||
- debugfs_create_file("hdwqstat", 0644, vport->vport_debugfs_root, vport,
|
||||
- &lpfc_debugfs_op_hdwqstat);
|
||||
+ snprintf(name, sizeof(name), "hdwqstat");
|
||||
+ vport->debug_hdwqstat =
|
||||
+ debugfs_create_file(name, 0644,
|
||||
+ vport->vport_debugfs_root,
|
||||
+ vport, &lpfc_debugfs_op_hdwqstat);
|
||||
|
||||
/*
|
||||
* The following section is for additional directories/files for the
|
||||
@@ -6323,58 +6399,93 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
*/
|
||||
|
||||
if (!pport_setup)
|
||||
- return;
|
||||
+ goto debug_failed;
|
||||
|
||||
/*
|
||||
* iDiag debugfs root entry points for SLI4 device only
|
||||
*/
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
- return;
|
||||
+ goto debug_failed;
|
||||
|
||||
+ snprintf(name, sizeof(name), "iDiag");
|
||||
if (!phba->idiag_root) {
|
||||
phba->idiag_root =
|
||||
- debugfs_create_dir("iDiag", phba->hba_debugfs_root);
|
||||
+ debugfs_create_dir(name, phba->hba_debugfs_root);
|
||||
/* Initialize iDiag data structure */
|
||||
memset(&idiag, 0, sizeof(idiag));
|
||||
}
|
||||
|
||||
/* iDiag read PCI config space */
|
||||
- debugfs_create_file("pciCfg", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_pciCfg);
|
||||
- idiag.offset.last_rd = 0;
|
||||
+ snprintf(name, sizeof(name), "pciCfg");
|
||||
+ if (!phba->idiag_pci_cfg) {
|
||||
+ phba->idiag_pci_cfg =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
|
||||
+ idiag.offset.last_rd = 0;
|
||||
+ }
|
||||
|
||||
/* iDiag PCI BAR access */
|
||||
- debugfs_create_file("barAcc", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_barAcc);
|
||||
- idiag.offset.last_rd = 0;
|
||||
+ snprintf(name, sizeof(name), "barAcc");
|
||||
+ if (!phba->idiag_bar_acc) {
|
||||
+ phba->idiag_bar_acc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
|
||||
+ idiag.offset.last_rd = 0;
|
||||
+ }
|
||||
|
||||
/* iDiag get PCI function queue information */
|
||||
- debugfs_create_file("queInfo", 0444, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_queInfo);
|
||||
+ snprintf(name, sizeof(name), "queInfo");
|
||||
+ if (!phba->idiag_que_info) {
|
||||
+ phba->idiag_que_info =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
|
||||
+ }
|
||||
|
||||
/* iDiag access PCI function queue */
|
||||
- debugfs_create_file("queAcc", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_queAcc);
|
||||
+ snprintf(name, sizeof(name), "queAcc");
|
||||
+ if (!phba->idiag_que_acc) {
|
||||
+ phba->idiag_que_acc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
|
||||
+ }
|
||||
|
||||
/* iDiag access PCI function doorbell registers */
|
||||
- debugfs_create_file("drbAcc", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_drbAcc);
|
||||
+ snprintf(name, sizeof(name), "drbAcc");
|
||||
+ if (!phba->idiag_drb_acc) {
|
||||
+ phba->idiag_drb_acc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
|
||||
+ }
|
||||
|
||||
/* iDiag access PCI function control registers */
|
||||
- debugfs_create_file("ctlAcc", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_ctlAcc);
|
||||
+ snprintf(name, sizeof(name), "ctlAcc");
|
||||
+ if (!phba->idiag_ctl_acc) {
|
||||
+ phba->idiag_ctl_acc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
|
||||
+ }
|
||||
|
||||
/* iDiag access mbox commands */
|
||||
- debugfs_create_file("mbxAcc", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_mbxAcc);
|
||||
+ snprintf(name, sizeof(name), "mbxAcc");
|
||||
+ if (!phba->idiag_mbx_acc) {
|
||||
+ phba->idiag_mbx_acc =
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
|
||||
+ }
|
||||
|
||||
/* iDiag extents access commands */
|
||||
if (phba->sli4_hba.extents_in_use) {
|
||||
- debugfs_create_file("extAcc", 0644, phba->idiag_root, phba,
|
||||
- &lpfc_idiag_op_extAcc);
|
||||
+ snprintf(name, sizeof(name), "extAcc");
|
||||
+ if (!phba->idiag_ext_acc) {
|
||||
+ phba->idiag_ext_acc =
|
||||
+ debugfs_create_file(name,
|
||||
+ S_IFREG|S_IRUGO|S_IWUSR,
|
||||
+ phba->idiag_root, phba,
|
||||
+ &lpfc_idiag_op_extAcc);
|
||||
+ }
|
||||
}
|
||||
-out:
|
||||
- /* alloc'ed items are kfree'd in lpfc_debugfs_terminate */
|
||||
+
|
||||
+debug_failed:
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
@@ -6399,6 +6510,24 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
|
||||
kfree(vport->disc_trc);
|
||||
vport->disc_trc = NULL;
|
||||
|
||||
+ debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
|
||||
+ vport->debug_disc_trc = NULL;
|
||||
+
|
||||
+ debugfs_remove(vport->debug_nodelist); /* nodelist */
|
||||
+ vport->debug_nodelist = NULL;
|
||||
+
|
||||
+ debugfs_remove(vport->debug_nvmestat); /* nvmestat */
|
||||
+ vport->debug_nvmestat = NULL;
|
||||
+
|
||||
+ debugfs_remove(vport->debug_scsistat); /* scsistat */
|
||||
+ vport->debug_scsistat = NULL;
|
||||
+
|
||||
+ debugfs_remove(vport->debug_ioktime); /* ioktime */
|
||||
+ vport->debug_ioktime = NULL;
|
||||
+
|
||||
+ debugfs_remove(vport->debug_hdwqstat); /* hdwqstat */
|
||||
+ vport->debug_hdwqstat = NULL;
|
||||
+
|
||||
if (vport->vport_debugfs_root) {
|
||||
debugfs_remove(vport->vport_debugfs_root); /* vportX */
|
||||
vport->vport_debugfs_root = NULL;
|
||||
@@ -6406,12 +6535,113 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
|
||||
}
|
||||
|
||||
if (atomic_read(&phba->debugfs_vport_count) == 0) {
|
||||
+
|
||||
+ debugfs_remove(phba->debug_multixri_pools); /* multixripools*/
|
||||
+ phba->debug_multixri_pools = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
|
||||
+ phba->debug_hbqinfo = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_cgn_buffer);
|
||||
+ phba->debug_cgn_buffer = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_rx_monitor);
|
||||
+ phba->debug_rx_monitor = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_ras_log);
|
||||
+ phba->debug_ras_log = NULL;
|
||||
+
|
||||
+#ifdef LPFC_HDWQ_LOCK_STAT
|
||||
+ debugfs_remove(phba->debug_lockstat); /* lockstat */
|
||||
+ phba->debug_lockstat = NULL;
|
||||
+#endif
|
||||
+ debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
|
||||
+ phba->debug_dumpHBASlim = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
|
||||
+ phba->debug_dumpHostSlim = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
|
||||
+ phba->debug_InjErrLBA = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_InjErrNPortID);
|
||||
+ phba->debug_InjErrNPortID = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */
|
||||
+ phba->debug_InjErrWWPN = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_writeGuard); /* writeGuard */
|
||||
+ phba->debug_writeGuard = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_writeApp); /* writeApp */
|
||||
+ phba->debug_writeApp = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_writeRef); /* writeRef */
|
||||
+ phba->debug_writeRef = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_readGuard); /* readGuard */
|
||||
+ phba->debug_readGuard = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_readApp); /* readApp */
|
||||
+ phba->debug_readApp = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_readRef); /* readRef */
|
||||
+ phba->debug_readRef = NULL;
|
||||
+
|
||||
kfree(phba->slow_ring_trc);
|
||||
phba->slow_ring_trc = NULL;
|
||||
|
||||
+ /* slow_ring_trace */
|
||||
+ debugfs_remove(phba->debug_slow_ring_trc);
|
||||
+ phba->debug_slow_ring_trc = NULL;
|
||||
+
|
||||
+ debugfs_remove(phba->debug_nvmeio_trc);
|
||||
+ phba->debug_nvmeio_trc = NULL;
|
||||
+
|
||||
kfree(phba->nvmeio_trc);
|
||||
phba->nvmeio_trc = NULL;
|
||||
|
||||
+ /*
|
||||
+ * iDiag release
|
||||
+ */
|
||||
+ if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
+ /* iDiag extAcc */
|
||||
+ debugfs_remove(phba->idiag_ext_acc);
|
||||
+ phba->idiag_ext_acc = NULL;
|
||||
+
|
||||
+ /* iDiag mbxAcc */
|
||||
+ debugfs_remove(phba->idiag_mbx_acc);
|
||||
+ phba->idiag_mbx_acc = NULL;
|
||||
+
|
||||
+ /* iDiag ctlAcc */
|
||||
+ debugfs_remove(phba->idiag_ctl_acc);
|
||||
+ phba->idiag_ctl_acc = NULL;
|
||||
+
|
||||
+ /* iDiag drbAcc */
|
||||
+ debugfs_remove(phba->idiag_drb_acc);
|
||||
+ phba->idiag_drb_acc = NULL;
|
||||
+
|
||||
+ /* iDiag queAcc */
|
||||
+ debugfs_remove(phba->idiag_que_acc);
|
||||
+ phba->idiag_que_acc = NULL;
|
||||
+
|
||||
+ /* iDiag queInfo */
|
||||
+ debugfs_remove(phba->idiag_que_info);
|
||||
+ phba->idiag_que_info = NULL;
|
||||
+
|
||||
+ /* iDiag barAcc */
|
||||
+ debugfs_remove(phba->idiag_bar_acc);
|
||||
+ phba->idiag_bar_acc = NULL;
|
||||
+
|
||||
+ /* iDiag pciCfg */
|
||||
+ debugfs_remove(phba->idiag_pci_cfg);
|
||||
+ phba->idiag_pci_cfg = NULL;
|
||||
+
|
||||
+ /* Finally remove the iDiag debugfs root */
|
||||
+ debugfs_remove(phba->idiag_root);
|
||||
+ phba->idiag_root = NULL;
|
||||
+ }
|
||||
+
|
||||
if (phba->hba_debugfs_root) {
|
||||
debugfs_remove(phba->hba_debugfs_root); /* fnX */
|
||||
phba->hba_debugfs_root = NULL;
|
||||
@ -0,0 +1,198 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Use switch case statements in DIF debugfs handlers"
|
||||
# Revert of ab563ef364bb83aeddbbfaa4f23f317cb3145f2e
|
||||
scsi: lpfc: Use switch case statements in DIF debugfs handlers
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index 892e2177663a..cd5180151321 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -2373,117 +2373,93 @@ lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
|
||||
|
||||
static ssize_t
|
||||
lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
|
||||
- size_t nbytes, loff_t *ppos)
|
||||
+ size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
struct lpfc_hba *phba = file->private_data;
|
||||
int kind = debugfs_get_aux_num(file);
|
||||
- char cbuf[32] = {0};
|
||||
+ char cbuf[32];
|
||||
+ uint64_t tmp = 0;
|
||||
int cnt = 0;
|
||||
|
||||
- switch (kind) {
|
||||
- case writeGuard:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n",
|
||||
- phba->lpfc_injerr_wgrd_cnt);
|
||||
- break;
|
||||
- case writeApp:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n",
|
||||
- phba->lpfc_injerr_wapp_cnt);
|
||||
- break;
|
||||
- case writeRef:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n",
|
||||
- phba->lpfc_injerr_wref_cnt);
|
||||
- break;
|
||||
- case readGuard:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n",
|
||||
- phba->lpfc_injerr_rgrd_cnt);
|
||||
- break;
|
||||
- case readApp:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n",
|
||||
- phba->lpfc_injerr_rapp_cnt);
|
||||
- break;
|
||||
- case readRef:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n",
|
||||
- phba->lpfc_injerr_rref_cnt);
|
||||
- break;
|
||||
- case InjErrNPortID:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "0x%06x\n",
|
||||
+ if (kind == writeGuard)
|
||||
+ cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
|
||||
+ else if (kind == writeApp)
|
||||
+ cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
|
||||
+ else if (kind == writeRef)
|
||||
+ cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
|
||||
+ else if (kind == readGuard)
|
||||
+ cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
|
||||
+ else if (kind == readApp)
|
||||
+ cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
|
||||
+ else if (kind == readRef)
|
||||
+ cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
|
||||
+ else if (kind == InjErrNPortID)
|
||||
+ cnt = scnprintf(cbuf, 32, "0x%06x\n",
|
||||
phba->lpfc_injerr_nportid);
|
||||
- break;
|
||||
- case InjErrWWPN:
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "0x%016llx\n",
|
||||
- be64_to_cpu(phba->lpfc_injerr_wwpn.u.wwn_be));
|
||||
- break;
|
||||
- case InjErrLBA:
|
||||
- if (phba->lpfc_injerr_lba == LPFC_INJERR_LBA_OFF)
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "off\n");
|
||||
+ else if (kind == InjErrWWPN) {
|
||||
+ memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
|
||||
+ tmp = cpu_to_be64(tmp);
|
||||
+ cnt = scnprintf(cbuf, 32, "0x%016llx\n", tmp);
|
||||
+ } else if (kind == InjErrLBA) {
|
||||
+ if (phba->lpfc_injerr_lba == (sector_t)(-1))
|
||||
+ cnt = scnprintf(cbuf, 32, "off\n");
|
||||
else
|
||||
- cnt = scnprintf(cbuf, sizeof(cbuf), "0x%llx\n",
|
||||
- (uint64_t)phba->lpfc_injerr_lba);
|
||||
- break;
|
||||
- default:
|
||||
- lpfc_log_msg(phba, KERN_WARNING, LOG_INIT,
|
||||
- "0547 Unknown debugfs error injection entry\n");
|
||||
- break;
|
||||
- }
|
||||
+ cnt = scnprintf(cbuf, 32, "0x%llx\n",
|
||||
+ (uint64_t) phba->lpfc_injerr_lba);
|
||||
+ } else
|
||||
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
+ "0547 Unknown debugfs error injection entry\n");
|
||||
|
||||
return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
|
||||
- size_t nbytes, loff_t *ppos)
|
||||
+ size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
struct lpfc_hba *phba = file->private_data;
|
||||
int kind = debugfs_get_aux_num(file);
|
||||
- char dstbuf[33] = {0};
|
||||
- unsigned long long tmp;
|
||||
- unsigned long size;
|
||||
+ char dstbuf[33];
|
||||
+ uint64_t tmp = 0;
|
||||
+ int size;
|
||||
|
||||
- size = (nbytes < (sizeof(dstbuf) - 1)) ? nbytes : (sizeof(dstbuf) - 1);
|
||||
+ memset(dstbuf, 0, 33);
|
||||
+ size = (nbytes < 32) ? nbytes : 32;
|
||||
if (copy_from_user(dstbuf, buf, size))
|
||||
return -EFAULT;
|
||||
|
||||
- if (kstrtoull(dstbuf, 0, &tmp)) {
|
||||
- if (kind != InjErrLBA || !strstr(dstbuf, "off"))
|
||||
- return -EINVAL;
|
||||
+ if (kind == InjErrLBA) {
|
||||
+ if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') &&
|
||||
+ (dstbuf[2] == 'f'))
|
||||
+ tmp = (uint64_t)(-1);
|
||||
}
|
||||
|
||||
- switch (kind) {
|
||||
- case writeGuard:
|
||||
+ if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (kind == writeGuard)
|
||||
phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
|
||||
- break;
|
||||
- case writeApp:
|
||||
+ else if (kind == writeApp)
|
||||
phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
|
||||
- break;
|
||||
- case writeRef:
|
||||
+ else if (kind == writeRef)
|
||||
phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
|
||||
- break;
|
||||
- case readGuard:
|
||||
+ else if (kind == readGuard)
|
||||
phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
|
||||
- break;
|
||||
- case readApp:
|
||||
+ else if (kind == readApp)
|
||||
phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
|
||||
- break;
|
||||
- case readRef:
|
||||
+ else if (kind == readRef)
|
||||
phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
|
||||
- break;
|
||||
- case InjErrLBA:
|
||||
- if (strstr(dstbuf, "off"))
|
||||
- phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
|
||||
- else
|
||||
- phba->lpfc_injerr_lba = (sector_t)tmp;
|
||||
- break;
|
||||
- case InjErrNPortID:
|
||||
+ else if (kind == InjErrLBA)
|
||||
+ phba->lpfc_injerr_lba = (sector_t)tmp;
|
||||
+ else if (kind == InjErrNPortID)
|
||||
phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
|
||||
- break;
|
||||
- case InjErrWWPN:
|
||||
- phba->lpfc_injerr_wwpn.u.wwn_be = cpu_to_be64(tmp);
|
||||
- break;
|
||||
- default:
|
||||
- lpfc_log_msg(phba, KERN_WARNING, LOG_INIT,
|
||||
- "0548 Unknown debugfs error injection entry\n");
|
||||
- break;
|
||||
- }
|
||||
+ else if (kind == InjErrWWPN) {
|
||||
+ tmp = cpu_to_be64(tmp);
|
||||
+ memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
|
||||
+ } else
|
||||
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
+ "0548 Unknown debugfs error injection entry\n");
|
||||
+
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
|
||||
index b287d39ad033..32298285ea5e 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hw.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hw.h
|
||||
@@ -366,7 +366,6 @@ struct lpfc_name {
|
||||
} s;
|
||||
uint8_t wwn[8];
|
||||
uint64_t name __packed __aligned(4);
|
||||
- __be64 wwn_be __packed __aligned(4);
|
||||
} u;
|
||||
};
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Fix memory leak when nvmeio_trc debugfs entry is used"
|
||||
# Revert of 7188eff1a4a6e2f9144684df495ee5bcce503c8d
|
||||
scsi: lpfc: Fix memory leak when nvmeio_trc debugfs entry is used
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index cd5180151321..82ab7660572f 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -6280,6 +6280,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
}
|
||||
phba->nvmeio_trc_on = 1;
|
||||
phba->nvmeio_trc_output_idx = 0;
|
||||
+ phba->nvmeio_trc = NULL;
|
||||
} else {
|
||||
nvmeio_off:
|
||||
phba->nvmeio_trc_size = 0;
|
||||
@ -0,0 +1,20 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Define size of debugfs entry for xri rebalancing"
|
||||
# Revert of 5eec6dfb351f6412694cfb294f1a0d153a9b8142
|
||||
scsi: lpfc: Define size of debugfs entry for xri rebalancing
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
index 566dd84e0677..f319f3af0400 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
@@ -44,9 +44,6 @@
|
||||
/* hbqinfo output buffer size */
|
||||
#define LPFC_HBQINFO_SIZE 8192
|
||||
|
||||
-/* hdwqinfo output buffer size */
|
||||
-#define LPFC_HDWQINFO_SIZE 8192
|
||||
-
|
||||
/* nvmestat output buffer size */
|
||||
#define LPFC_NVMESTAT_SIZE 8192
|
||||
#define LPFC_IOKTIME_SIZE 8192
|
||||
@ -0,0 +1,78 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Ensure PLOGI_ACC is sent prior to PRLI in Point to Point topology"
|
||||
# Revert of 123878d674dbeccfa9efa5b489d2a538dd740f7c
|
||||
scsi: lpfc: Ensure PLOGI_ACC is sent prior to PRLI in Point to Point topology
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 0630d109e767..3cc9d9829551 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -5338,12 +5338,12 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
ulp_status, ulp_word4, did);
|
||||
/* ELS response tag <ulpIoTag> completes */
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
- "0110 ELS response tag x%x completes fc_flag x%lx"
|
||||
+ "0110 ELS response tag x%x completes "
|
||||
"Data: x%x x%x x%x x%x x%lx x%x x%x x%x %p %p\n",
|
||||
- iotag, vport->fc_flag, ulp_status, ulp_word4, tmo,
|
||||
+ iotag, ulp_status, ulp_word4, tmo,
|
||||
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
|
||||
ndlp->nlp_rpi, kref_read(&ndlp->kref), mbox, ndlp);
|
||||
- if (mbox && !test_bit(FC_PT2PT, &vport->fc_flag)) {
|
||||
+ if (mbox) {
|
||||
if (ulp_status == 0 &&
|
||||
test_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag)) {
|
||||
if (!lpfc_unreg_rpi(vport, ndlp) &&
|
||||
@@ -5402,10 +5402,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
}
|
||||
out_free_mbox:
|
||||
lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
|
||||
- } else if (mbox && test_bit(FC_PT2PT, &vport->fc_flag) &&
|
||||
- test_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag)) {
|
||||
- lpfc_mbx_cmpl_reg_login(phba, mbox);
|
||||
- clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
|
||||
}
|
||||
out:
|
||||
if (ndlp && shost) {
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
index 1e331b76dff4..5aa21c683ac6 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
||||
@@ -326,14 +326,8 @@ lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
|
||||
/* Now that REG_RPI completed successfully,
|
||||
* we can now proceed with sending the PLOGI ACC.
|
||||
*/
|
||||
- if (test_bit(FC_PT2PT, &ndlp->vport->fc_flag)) {
|
||||
- rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
|
||||
- save_iocb, ndlp, login_mbox);
|
||||
- } else {
|
||||
- rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
|
||||
- save_iocb, ndlp, NULL);
|
||||
- }
|
||||
-
|
||||
+ rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
|
||||
+ save_iocb, ndlp, NULL);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"4576 PLOGI ACC fails pt2pt discovery: "
|
||||
@@ -341,16 +335,9 @@ lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
|
||||
}
|
||||
}
|
||||
|
||||
- /* If this is a fabric topology, complete the reg_rpi and prli now.
|
||||
- * For Pt2Pt, the reg_rpi and PRLI are deferred until after the LS_ACC
|
||||
- * completes. This ensures, in Pt2Pt, that the PLOGI LS_ACC is sent
|
||||
- * before the PRLI.
|
||||
- */
|
||||
- if (!test_bit(FC_PT2PT, &ndlp->vport->fc_flag)) {
|
||||
- /* Now process the REG_RPI cmpl */
|
||||
- lpfc_mbx_cmpl_reg_login(phba, login_mbox);
|
||||
- clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
|
||||
- }
|
||||
+ /* Now process the REG_RPI cmpl */
|
||||
+ lpfc_mbx_cmpl_reg_login(phba, login_mbox);
|
||||
+ clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
|
||||
kfree(save_iocb);
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Check return status of lpfc_reset_flush_io_context during TGT_RESET"
|
||||
# Revert of 42cd66663ae18668544eaee105d82bea2a5921f4
|
||||
scsi: lpfc: Check return status of lpfc_reset_flush_io_context during TGT_RESET
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
index 1638fc3fc916..0f145022aaaa 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
@@ -5943,7 +5943,7 @@ lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct fc_rport *rport)
|
||||
/**
|
||||
* lpfc_reset_flush_io_context -
|
||||
* @vport: The virtual port (scsi_host) for the flush context
|
||||
- * @tgt_id: If aborting by Target context - specifies the target id
|
||||
+ * @tgt_id: If aborting by Target contect - specifies the target id
|
||||
* @lun_id: If aborting by Lun context - specifies the lun id
|
||||
* @context: specifies the context level to flush at.
|
||||
*
|
||||
@@ -6117,14 +6117,8 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
|
||||
pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
spin_unlock_irqrestore(&pnode->lock, flags);
|
||||
}
|
||||
- status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
|
||||
- LPFC_CTX_TGT);
|
||||
- if (status != SUCCESS) {
|
||||
- lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
|
||||
- "0726 Target Reset flush status x%x\n",
|
||||
- status);
|
||||
- return status;
|
||||
- }
|
||||
+ lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
|
||||
+ LPFC_CTX_TGT);
|
||||
return FAST_IO_FAIL;
|
||||
}
|
||||
|
||||
@@ -6217,7 +6211,7 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd)
|
||||
int rc, ret = SUCCESS;
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
|
||||
- "3172 SCSI layer issued Host Reset\n");
|
||||
+ "3172 SCSI layer issued Host Reset Data:\n");
|
||||
|
||||
lpfc_offline_prep(phba, LPFC_MBX_WAIT);
|
||||
lpfc_offline(phba);
|
||||
@ -0,0 +1,22 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Decrement ndlp kref after FDISC retries exhausted"
|
||||
# Revert of 34a2ffe35bb05d7eeb7353737c22efaead84158c
|
||||
scsi: lpfc: Decrement ndlp kref after FDISC retries exhausted
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 3cc9d9829551..729bee3c657e 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -11264,11 +11264,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
|
||||
"0126 FDISC cmpl status: x%x/x%x)\n",
|
||||
ulp_status, ulp_word4);
|
||||
-
|
||||
- /* drop initial reference */
|
||||
- if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag))
|
||||
- lpfc_nlp_put(ndlp);
|
||||
-
|
||||
goto fdisc_failed;
|
||||
}
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Remove ndlp kref decrement clause for F_Port_Ctrl in lpfc_cleanup"
|
||||
# Revert of 0cfe4ba53cd1fe0efede8ebdc450d75daf07a3f2
|
||||
scsi: lpfc: Remove ndlp kref decrement clause for F_Port_Ctrl in lpfc_cleanup
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 729bee3c657e..853cf7649451 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -12012,11 +12012,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
|
||||
sglq_entry->state = SGL_FREED;
|
||||
spin_unlock_irqrestore(&phba->sli4_hba.sgl_list_lock,
|
||||
iflag);
|
||||
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_SLI |
|
||||
- LOG_DISCOVERY | LOG_NODE,
|
||||
- "0732 ELS XRI ABORT on Node: ndlp=x%px "
|
||||
- "xri=x%x\n",
|
||||
- ndlp, xri);
|
||||
+
|
||||
if (ndlp) {
|
||||
lpfc_set_rrq_active(phba, ndlp,
|
||||
sglq_entry->sli4_lxritag,
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
||||
index 2f3629ef64e6..c681bd0ecbbc 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_init.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
||||
@@ -3057,6 +3057,13 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
||||
lpfc_vmid_vport_cleanup(vport);
|
||||
|
||||
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
|
||||
+ if (vport->port_type != LPFC_PHYSICAL_PORT &&
|
||||
+ ndlp->nlp_DID == Fabric_DID) {
|
||||
+ /* Just free up ndlp with Fabric_DID for vports */
|
||||
+ lpfc_nlp_put(ndlp);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (ndlp->nlp_DID == Fabric_Cntl_DID &&
|
||||
ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
|
||||
lpfc_nlp_put(ndlp);
|
||||
@ -0,0 +1,27 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Clean up allocated queues when queue setup mbox commands fail"
|
||||
# Revert of dd7b6c550a31baa747b697cf9746e05c6d36464e
|
||||
scsi: lpfc: Clean up allocated queues when queue setup mbox commands fail
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index e658f2a914d9..c6bfd8e97f59 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -8823,7 +8823,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||
if (unlikely(rc)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0381 Error %d during queue setup.\n", rc);
|
||||
- goto out_destroy_queue;
|
||||
+ goto out_stop_timers;
|
||||
}
|
||||
/* Initialize the driver internal SLI layer lists. */
|
||||
lpfc_sli4_setup(phba);
|
||||
@@ -9106,6 +9106,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||
lpfc_free_iocb_list(phba);
|
||||
out_destroy_queue:
|
||||
lpfc_sli4_queue_destroy(phba);
|
||||
+out_stop_timers:
|
||||
lpfc_stop_hba_timers(phba);
|
||||
out_free_mbox:
|
||||
mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
@ -0,0 +1,34 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Abort outstanding ELS WQEs regardless of if rmmod is in progress"
|
||||
# Revert of 70672fd3d84f298f276d2e2604b1d385e8b553fc
|
||||
scsi: lpfc: Abort outstanding ELS WQEs regardless of if rmmod is in progress
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index c6bfd8e97f59..393937c727f6 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -12446,11 +12446,19 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
}
|
||||
|
||||
/*
|
||||
- * Always abort the outstanding WQE and set the IA bit correctly
|
||||
- * for the context. This is necessary for correctly removing
|
||||
- * outstanding ndlp reference counts when the CQE completes with
|
||||
- * the XB bit set.
|
||||
+ * If we're unloading, don't abort iocb on the ELS ring, but change
|
||||
+ * the callback so that nothing happens when it finishes.
|
||||
*/
|
||||
+ if (test_bit(FC_UNLOADING, &vport->load_flag) &&
|
||||
+ pring->ringno == LPFC_ELS_RING) {
|
||||
+ if (cmdiocb->cmd_flag & LPFC_IO_FABRIC)
|
||||
+ cmdiocb->fabric_cmd_cmpl = lpfc_ignore_els_cmpl;
|
||||
+ else
|
||||
+ cmdiocb->cmd_cmpl = lpfc_ignore_els_cmpl;
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ /* issue ABTS for this IOCB based on iotag */
|
||||
abtsiocbp = __lpfc_sli_get_iocbq(phba);
|
||||
if (abtsiocbp == NULL)
|
||||
return IOCB_NORESOURCE;
|
||||
@ -0,0 +1,61 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Remove unused member variables in struct lpfc_hba and lpfc_vport"
|
||||
# Revert of 12503dd7ac27930b8889b15014474829c56c11f2
|
||||
scsi: lpfc: Remove unused member variables in struct lpfc_hba and lpfc_vport
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
|
||||
index 0a43be24cee8..bf8ec461c0ee 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc.h
|
||||
@@ -662,12 +662,15 @@ struct lpfc_vport {
|
||||
uint32_t num_disc_nodes; /* in addition to hba_state */
|
||||
uint32_t gidft_inp; /* cnt of outstanding GID_FTs */
|
||||
|
||||
+ uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */
|
||||
uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */
|
||||
uint32_t fc_rscn_flush; /* flag use of fc_rscn_id_list */
|
||||
struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
|
||||
struct lpfc_name fc_nodename; /* fc nodename */
|
||||
struct lpfc_name fc_portname; /* fc portname */
|
||||
|
||||
+ struct lpfc_work_evt disc_timeout_evt;
|
||||
+
|
||||
struct timer_list fc_disctmo; /* Discovery rescue timer */
|
||||
uint8_t fc_ns_retry; /* retries for fabric nameserver */
|
||||
uint32_t fc_prli_sent; /* cntr for outstanding PRLIs */
|
||||
@@ -765,6 +768,7 @@ struct lpfc_vport {
|
||||
/* There is a single nvme instance per vport. */
|
||||
struct nvme_fc_local_port *localport;
|
||||
uint8_t nvmei_support; /* driver supports NVME Initiator */
|
||||
+ uint32_t last_fcp_wqidx;
|
||||
uint32_t rcv_flogi_cnt; /* How many unsol FLOGIs ACK'd. */
|
||||
};
|
||||
|
||||
@@ -1057,6 +1061,8 @@ struct lpfc_hba {
|
||||
|
||||
struct lpfc_dmabuf hbqslimp;
|
||||
|
||||
+ uint16_t pci_cfg_value;
|
||||
+
|
||||
uint8_t fc_linkspeed; /* Link speed after last READ_LA */
|
||||
|
||||
uint32_t fc_eventTag; /* event tag for link attention */
|
||||
@@ -1083,6 +1089,7 @@ struct lpfc_hba {
|
||||
|
||||
struct lpfc_stats fc_stat;
|
||||
|
||||
+ struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */
|
||||
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
|
||||
|
||||
uint8_t wwnn[8];
|
||||
@@ -1223,6 +1230,9 @@ struct lpfc_hba {
|
||||
uint32_t hbq_count; /* Count of configured HBQs */
|
||||
struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */
|
||||
|
||||
+ atomic_t fcp_qidx; /* next FCP WQ (RR Policy) */
|
||||
+ atomic_t nvme_qidx; /* next NVME WQ (RR Policy) */
|
||||
+
|
||||
phys_addr_t pci_bar0_map; /* Physical address for PCI BAR0 */
|
||||
phys_addr_t pci_bar1_map; /* Physical address for PCI BAR1 */
|
||||
phys_addr_t pci_bar2_map; /* Physical address for PCI BAR2 */
|
||||
@ -0,0 +1,19 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Use int type to store negative error codes"
|
||||
# Revert of dfe48c6bb068813490395974ec06f38342da2d6f
|
||||
scsi: lpfc: Use int type to store negative error codes
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index 393937c727f6..7d459a88ec5a 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -21382,7 +21382,7 @@ lpfc_sli4_issue_wqe(struct lpfc_hba *phba, struct lpfc_sli4_hdw_queue *qp,
|
||||
struct lpfc_sglq *sglq;
|
||||
struct lpfc_sli_ring *pring;
|
||||
unsigned long iflags;
|
||||
- int ret = 0;
|
||||
+ uint32_t ret = 0;
|
||||
|
||||
/* NVME_LS and NVME_LS ABTS requests. */
|
||||
if (pwqe->cmd_flag & LPFC_IO_NVME_LS) {
|
||||
41
SOURCES/1155-revert-scsi-lpfc-use-min-to-improve-code.patch
Normal file
41
SOURCES/1155-revert-scsi-lpfc-use-min-to-improve-code.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: use min() to improve code"
|
||||
# Revert of 548552ed278e8ebd0e27ae1461b7fe891f268825
|
||||
scsi: lpfc: use min() to improve code
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
||||
index c681bd0ecbbc..b78edd11d9d4 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_init.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
||||
@@ -8298,7 +8298,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
||||
phba->cfg_total_seg_cnt, phba->cfg_scsi_seg_cnt,
|
||||
phba->cfg_nvme_seg_cnt);
|
||||
|
||||
- i = min(phba->cfg_sg_dma_buf_size, SLI4_PAGE_SIZE);
|
||||
+ if (phba->cfg_sg_dma_buf_size < SLI4_PAGE_SIZE)
|
||||
+ i = phba->cfg_sg_dma_buf_size;
|
||||
+ else
|
||||
+ i = SLI4_PAGE_SIZE;
|
||||
|
||||
phba->lpfc_sg_dma_buf_pool =
|
||||
dma_pool_create("lpfc_sg_dma_buf_pool",
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
|
||||
index 47818cf5b2f3..d539ee15a806 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_nvme.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
|
||||
@@ -1234,8 +1234,12 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
|
||||
if ((phba->cfg_nvme_enable_fb) &&
|
||||
test_bit(NLP_FIRSTBURST, &pnode->nlp_flag)) {
|
||||
req_len = lpfc_ncmd->nvmeCmd->payload_length;
|
||||
- wqe->fcp_iwrite.initial_xfer_len = min(req_len,
|
||||
- pnode->nvme_fb_size);
|
||||
+ if (req_len < pnode->nvme_fb_size)
|
||||
+ wqe->fcp_iwrite.initial_xfer_len =
|
||||
+ req_len;
|
||||
+ else
|
||||
+ wqe->fcp_iwrite.initial_xfer_len =
|
||||
+ pnode->nvme_fb_size;
|
||||
} else {
|
||||
wqe->fcp_iwrite.initial_xfer_len = 0;
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Fix wrong function reference in a comment"
|
||||
# Revert of 2936f5bdfbcc6669ca78472d83afe96613281b41
|
||||
scsi: lpfc: Fix wrong function reference in a comment
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
|
||||
index 8653839ee728..3d70cc517573 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_vport.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_vport.c
|
||||
@@ -666,7 +666,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
||||
* Take early refcount for outstanding I/O requests we schedule during
|
||||
* delete processing for unreg_vpi. Always keep this before
|
||||
* scsi_remove_host() as we can no longer obtain a reference through
|
||||
- * scsi_host_get() after scsi_remove_host as shost is set to SHOST_DEL.
|
||||
+ * scsi_host_get() after scsi_host_remove as shost is set to SHOST_DEL.
|
||||
*/
|
||||
if (!scsi_host_get(shost))
|
||||
return VPORT_INVAL;
|
||||
@ -0,0 +1,206 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "lpfc: don't use file->f_path.dentry for comparisons"
|
||||
# Revert of 6190ea44e36d9cc8416eef6efdd1561ee22696c2
|
||||
lpfc: don't use file->f_path.dentry for comparisons
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index 82ab7660572f..52ad5449fa26 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -2375,32 +2375,32 @@ static ssize_t
|
||||
lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
+ struct dentry *dent = file->f_path.dentry;
|
||||
struct lpfc_hba *phba = file->private_data;
|
||||
- int kind = debugfs_get_aux_num(file);
|
||||
char cbuf[32];
|
||||
uint64_t tmp = 0;
|
||||
int cnt = 0;
|
||||
|
||||
- if (kind == writeGuard)
|
||||
+ if (dent == phba->debug_writeGuard)
|
||||
cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
|
||||
- else if (kind == writeApp)
|
||||
+ else if (dent == phba->debug_writeApp)
|
||||
cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
|
||||
- else if (kind == writeRef)
|
||||
+ else if (dent == phba->debug_writeRef)
|
||||
cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
|
||||
- else if (kind == readGuard)
|
||||
+ else if (dent == phba->debug_readGuard)
|
||||
cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
|
||||
- else if (kind == readApp)
|
||||
+ else if (dent == phba->debug_readApp)
|
||||
cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
|
||||
- else if (kind == readRef)
|
||||
+ else if (dent == phba->debug_readRef)
|
||||
cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
|
||||
- else if (kind == InjErrNPortID)
|
||||
+ else if (dent == phba->debug_InjErrNPortID)
|
||||
cnt = scnprintf(cbuf, 32, "0x%06x\n",
|
||||
phba->lpfc_injerr_nportid);
|
||||
- else if (kind == InjErrWWPN) {
|
||||
+ else if (dent == phba->debug_InjErrWWPN) {
|
||||
memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
|
||||
tmp = cpu_to_be64(tmp);
|
||||
cnt = scnprintf(cbuf, 32, "0x%016llx\n", tmp);
|
||||
- } else if (kind == InjErrLBA) {
|
||||
+ } else if (dent == phba->debug_InjErrLBA) {
|
||||
if (phba->lpfc_injerr_lba == (sector_t)(-1))
|
||||
cnt = scnprintf(cbuf, 32, "off\n");
|
||||
else
|
||||
@@ -2417,8 +2417,8 @@ static ssize_t
|
||||
lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
+ struct dentry *dent = file->f_path.dentry;
|
||||
struct lpfc_hba *phba = file->private_data;
|
||||
- int kind = debugfs_get_aux_num(file);
|
||||
char dstbuf[33];
|
||||
uint64_t tmp = 0;
|
||||
int size;
|
||||
@@ -2428,7 +2428,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
|
||||
if (copy_from_user(dstbuf, buf, size))
|
||||
return -EFAULT;
|
||||
|
||||
- if (kind == InjErrLBA) {
|
||||
+ if (dent == phba->debug_InjErrLBA) {
|
||||
if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') &&
|
||||
(dstbuf[2] == 'f'))
|
||||
tmp = (uint64_t)(-1);
|
||||
@@ -2437,23 +2437,23 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
|
||||
if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
|
||||
return -EINVAL;
|
||||
|
||||
- if (kind == writeGuard)
|
||||
+ if (dent == phba->debug_writeGuard)
|
||||
phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
|
||||
- else if (kind == writeApp)
|
||||
+ else if (dent == phba->debug_writeApp)
|
||||
phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
|
||||
- else if (kind == writeRef)
|
||||
+ else if (dent == phba->debug_writeRef)
|
||||
phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
|
||||
- else if (kind == readGuard)
|
||||
+ else if (dent == phba->debug_readGuard)
|
||||
phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
|
||||
- else if (kind == readApp)
|
||||
+ else if (dent == phba->debug_readApp)
|
||||
phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
|
||||
- else if (kind == readRef)
|
||||
+ else if (dent == phba->debug_readRef)
|
||||
phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
|
||||
- else if (kind == InjErrLBA)
|
||||
+ else if (dent == phba->debug_InjErrLBA)
|
||||
phba->lpfc_injerr_lba = (sector_t)tmp;
|
||||
- else if (kind == InjErrNPortID)
|
||||
+ else if (dent == phba->debug_InjErrNPortID)
|
||||
phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
|
||||
- else if (kind == InjErrWWPN) {
|
||||
+ else if (dent == phba->debug_InjErrWWPN) {
|
||||
tmp = cpu_to_be64(tmp);
|
||||
memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
|
||||
} else
|
||||
@@ -6160,51 +6160,60 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
phba->debug_dumpHostSlim = NULL;
|
||||
|
||||
/* Setup DIF Error Injections */
|
||||
+ snprintf(name, sizeof(name), "InjErrLBA");
|
||||
phba->debug_InjErrLBA =
|
||||
- debugfs_create_file_aux_num("InjErrLBA", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, InjErrLBA, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
|
||||
|
||||
+ snprintf(name, sizeof(name), "InjErrNPortID");
|
||||
phba->debug_InjErrNPortID =
|
||||
- debugfs_create_file_aux_num("InjErrNPortID", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, InjErrNPortID, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "InjErrWWPN");
|
||||
phba->debug_InjErrWWPN =
|
||||
- debugfs_create_file_aux_num("InjErrWWPN", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, InjErrWWPN, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "writeGuardInjErr");
|
||||
phba->debug_writeGuard =
|
||||
- debugfs_create_file_aux_num("writeGuardInjErr", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, writeGuard, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "writeAppInjErr");
|
||||
phba->debug_writeApp =
|
||||
- debugfs_create_file_aux_num("writeAppInjErr", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, writeApp, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "writeRefInjErr");
|
||||
phba->debug_writeRef =
|
||||
- debugfs_create_file_aux_num("writeRefInjErr", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, writeRef, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "readGuardInjErr");
|
||||
phba->debug_readGuard =
|
||||
- debugfs_create_file_aux_num("readGuardInjErr", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, readGuard, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "readAppInjErr");
|
||||
phba->debug_readApp =
|
||||
- debugfs_create_file_aux_num("readAppInjErr", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, readApp, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
+ snprintf(name, sizeof(name), "readRefInjErr");
|
||||
phba->debug_readRef =
|
||||
- debugfs_create_file_aux_num("readRefInjErr", 0644,
|
||||
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
|
||||
phba->hba_debugfs_root,
|
||||
- phba, readRef, &lpfc_debugfs_op_dif_err);
|
||||
+ phba, &lpfc_debugfs_op_dif_err);
|
||||
|
||||
/* Setup slow ring trace */
|
||||
if (lpfc_debugfs_max_slow_ring_trc) {
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
index f319f3af0400..8d2e8d05bbc0 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
|
||||
@@ -322,17 +322,6 @@ enum {
|
||||
* discovery */
|
||||
#endif /* H_LPFC_DEBUG_FS */
|
||||
|
||||
-enum {
|
||||
- writeGuard = 1,
|
||||
- writeApp,
|
||||
- writeRef,
|
||||
- readGuard,
|
||||
- readApp,
|
||||
- readRef,
|
||||
- InjErrLBA,
|
||||
- InjErrNPortID,
|
||||
- InjErrWWPN,
|
||||
-};
|
||||
|
||||
/*
|
||||
* Driver debug utility routines outside of debugfs. The debug utility
|
||||
@ -0,0 +1,19 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Update lpfc version to 14.4.0.10"
|
||||
# Revert of 962ac7d119e10f5ce809aea5c67e2e20415fe24e
|
||||
scsi: lpfc: Update lpfc version to 14.4.0.10
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
|
||||
index 9ee3a3a4ec4d..749688aa8a82 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_version.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_version.h
|
||||
@@ -20,7 +20,7 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
-#define LPFC_DRIVER_VERSION "14.4.0.10"
|
||||
+#define LPFC_DRIVER_VERSION "14.4.0.9"
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
/* Used for SLI 2/3 */
|
||||
@ -0,0 +1,71 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Copyright updates for 14.4.0.10 patches"
|
||||
# Revert of 6826b3ee8d47e7dea2f29e327e33a1a40433eaaf
|
||||
scsi: lpfc: Copyright updates for 14.4.0.10 patches
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
index 94f612d1fef0..aa6c2b0f9907 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_ct.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index 52ad5449fa26..1b6cdadc7426 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2007-2015 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
|
||||
index bc709786e6af..dd9f170fbdc8 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hw4.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2009-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
index 0f145022aaaa..0786952cd7d5 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
|
||||
index fd6dab157887..e42b44fcc7f6 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli4.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
|
||||
+ * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
|
||||
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
|
||||
* Copyright (C) 2009-2016 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
@ -0,0 +1,141 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Modify end-of-life adapters' model descriptions"
|
||||
# Revert of 19ab9fa7f11f1675a15dda0cd6606d71f7599cfd
|
||||
scsi: lpfc: Modify end-of-life adapters' model descriptions
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
||||
index b78edd11d9d4..8007c961bbd7 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_init.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
||||
@@ -2627,33 +2627,27 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
||||
"Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_BMID:
|
||||
- m = (typeof(m)){"LP1150", "PCI-X2",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LP1150", "PCI-X2", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_BSMB:
|
||||
m = (typeof(m)){"LP111", "PCI-X2",
|
||||
"Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_ZEPHYR:
|
||||
- m = (typeof(m)){"LPe11000", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_ZEPHYR_SCSP:
|
||||
- m = (typeof(m)){"LPe11000", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_ZEPHYR_DCSP:
|
||||
- m = (typeof(m)){"LP2105", "PCIe",
|
||||
- "Obsolete, Unsupported FCoE Adapter"};
|
||||
+ m = (typeof(m)){"LP2105", "PCIe", "FCoE Adapter"};
|
||||
GE = 1;
|
||||
break;
|
||||
case PCI_DEVICE_ID_ZMID:
|
||||
- m = (typeof(m)){"LPe1150", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe1150", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_ZSMB:
|
||||
- m = (typeof(m)){"LPe111", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe111", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_LP101:
|
||||
m = (typeof(m)){"LP101", "PCI-X",
|
||||
@@ -2672,28 +2666,22 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
||||
"Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_SAT:
|
||||
- m = (typeof(m)){"LPe12000", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe12000", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_SAT_MID:
|
||||
- m = (typeof(m)){"LPe1250", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe1250", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_SAT_SMB:
|
||||
- m = (typeof(m)){"LPe121", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe121", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_SAT_DCSP:
|
||||
- m = (typeof(m)){"LPe12002-SP", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe12002-SP", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_SAT_SCSP:
|
||||
- m = (typeof(m)){"LPe12000-SP", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe12000-SP", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_SAT_S:
|
||||
- m = (typeof(m)){"LPe12000-S", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe12000-S", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_PROTEUS_VF:
|
||||
m = (typeof(m)){"LPev12000", "PCIe IOV",
|
||||
@@ -2709,25 +2697,22 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
||||
break;
|
||||
case PCI_DEVICE_ID_TIGERSHARK:
|
||||
oneConnect = 1;
|
||||
- m = (typeof(m)){"OCe10100", "PCIe",
|
||||
- "Obsolete, Unsupported FCoE Adapter"};
|
||||
+ m = (typeof(m)){"OCe10100", "PCIe", "FCoE"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_TOMCAT:
|
||||
oneConnect = 1;
|
||||
- m = (typeof(m)){"OCe11100", "PCIe",
|
||||
- "Obsolete, Unsupported FCoE Adapter"};
|
||||
+ m = (typeof(m)){"OCe11100", "PCIe", "FCoE"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_FALCON:
|
||||
m = (typeof(m)){"LPSe12002-ML1-E", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ "EmulexSecure Fibre"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_BALIUS:
|
||||
m = (typeof(m)){"LPVe12002", "PCIe Shared I/O",
|
||||
"Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_LANCER_FC:
|
||||
- m = (typeof(m)){"LPe16000", "PCIe",
|
||||
- "Obsolete, Unsupported Fibre Channel Adapter"};
|
||||
+ m = (typeof(m)){"LPe16000", "PCIe", "Fibre Channel Adapter"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_LANCER_FC_VF:
|
||||
m = (typeof(m)){"LPe16000", "PCIe",
|
||||
@@ -2735,13 +2720,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
||||
break;
|
||||
case PCI_DEVICE_ID_LANCER_FCOE:
|
||||
oneConnect = 1;
|
||||
- m = (typeof(m)){"OCe15100", "PCIe",
|
||||
- "Obsolete, Unsupported FCoE Adapter"};
|
||||
+ m = (typeof(m)){"OCe15100", "PCIe", "FCoE"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_LANCER_FCOE_VF:
|
||||
oneConnect = 1;
|
||||
m = (typeof(m)){"OCe15100", "PCIe",
|
||||
- "Obsolete, Unsupported FCoE Adapter"};
|
||||
+ "Obsolete, Unsupported FCoE"};
|
||||
break;
|
||||
case PCI_DEVICE_ID_LANCER_G6_FC:
|
||||
m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"};
|
||||
@@ -2755,8 +2739,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
|
||||
case PCI_DEVICE_ID_SKYHAWK:
|
||||
case PCI_DEVICE_ID_SKYHAWK_VF:
|
||||
oneConnect = 1;
|
||||
- m = (typeof(m)){"OCe14000", "PCIe",
|
||||
- "Obsolete, Unsupported FCoE Adapter"};
|
||||
+ m = (typeof(m)){"OCe14000", "PCIe", "FCoE"};
|
||||
break;
|
||||
default:
|
||||
m = (typeof(m)){"Unknown", "", ""};
|
||||
@ -0,0 +1,105 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Revise CQ_CREATE_SET mailbox bitfield definitions"
|
||||
# Revert of 47f0e888d0df9c51919a5258f9019c6a619bb8ad
|
||||
scsi: lpfc: Revise CQ_CREATE_SET mailbox bitfield definitions
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
|
||||
index dd9f170fbdc8..2dedb273b091 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hw4.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
|
||||
@@ -1328,9 +1328,6 @@ struct cq_context {
|
||||
#define LPFC_CQ_CNT_512 0x1
|
||||
#define LPFC_CQ_CNT_1024 0x2
|
||||
#define LPFC_CQ_CNT_WORD7 0x3
|
||||
-#define lpfc_cq_context_cqe_sz_SHIFT 25
|
||||
-#define lpfc_cq_context_cqe_sz_MASK 0x00000003
|
||||
-#define lpfc_cq_context_cqe_sz_WORD word0
|
||||
#define lpfc_cq_context_autovalid_SHIFT 15
|
||||
#define lpfc_cq_context_autovalid_MASK 0x00000001
|
||||
#define lpfc_cq_context_autovalid_WORD word0
|
||||
@@ -1386,9 +1383,9 @@ struct lpfc_mbx_cq_create_set {
|
||||
#define lpfc_mbx_cq_create_set_valid_SHIFT 29
|
||||
#define lpfc_mbx_cq_create_set_valid_MASK 0x00000001
|
||||
#define lpfc_mbx_cq_create_set_valid_WORD word1
|
||||
-#define lpfc_mbx_cq_create_set_cqecnt_SHIFT 27
|
||||
-#define lpfc_mbx_cq_create_set_cqecnt_MASK 0x00000003
|
||||
-#define lpfc_mbx_cq_create_set_cqecnt_WORD word1
|
||||
+#define lpfc_mbx_cq_create_set_cqe_cnt_SHIFT 27
|
||||
+#define lpfc_mbx_cq_create_set_cqe_cnt_MASK 0x00000003
|
||||
+#define lpfc_mbx_cq_create_set_cqe_cnt_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_cqe_size_SHIFT 25
|
||||
#define lpfc_mbx_cq_create_set_cqe_size_MASK 0x00000003
|
||||
#define lpfc_mbx_cq_create_set_cqe_size_WORD word1
|
||||
@@ -1401,16 +1398,13 @@ struct lpfc_mbx_cq_create_set {
|
||||
#define lpfc_mbx_cq_create_set_clswm_SHIFT 12
|
||||
#define lpfc_mbx_cq_create_set_clswm_MASK 0x00000003
|
||||
#define lpfc_mbx_cq_create_set_clswm_WORD word1
|
||||
-#define lpfc_mbx_cq_create_set_cqe_cnt_hi_SHIFT 0
|
||||
-#define lpfc_mbx_cq_create_set_cqe_cnt_hi_MASK 0x0000001F
|
||||
-#define lpfc_mbx_cq_create_set_cqe_cnt_hi_WORD word1
|
||||
uint32_t word2;
|
||||
#define lpfc_mbx_cq_create_set_arm_SHIFT 31
|
||||
#define lpfc_mbx_cq_create_set_arm_MASK 0x00000001
|
||||
#define lpfc_mbx_cq_create_set_arm_WORD word2
|
||||
-#define lpfc_mbx_cq_create_set_cqe_cnt_lo_SHIFT 16
|
||||
-#define lpfc_mbx_cq_create_set_cqe_cnt_lo_MASK 0x00007FFF
|
||||
-#define lpfc_mbx_cq_create_set_cqe_cnt_lo_WORD word2
|
||||
+#define lpfc_mbx_cq_create_set_cq_cnt_SHIFT 16
|
||||
+#define lpfc_mbx_cq_create_set_cq_cnt_MASK 0x00007FFF
|
||||
+#define lpfc_mbx_cq_create_set_cq_cnt_WORD word2
|
||||
#define lpfc_mbx_cq_create_set_num_cq_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_num_cq_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_num_cq_WORD word2
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index 7d459a88ec5a..73f8a0e3a4c0 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -16486,10 +16486,10 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
|
||||
case 4096:
|
||||
if (phba->sli4_hba.pc_sli4_params.cqv ==
|
||||
LPFC_Q_CREATE_VERSION_2) {
|
||||
- bf_set(lpfc_mbx_cq_create_set_cqe_cnt_lo,
|
||||
+ bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request,
|
||||
- cq->entry_count);
|
||||
- bf_set(lpfc_mbx_cq_create_set_cqecnt,
|
||||
+ cq->entry_count);
|
||||
+ bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request,
|
||||
LPFC_CQ_CNT_WORD7);
|
||||
break;
|
||||
@@ -16505,15 +16505,15 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
|
||||
}
|
||||
fallthrough; /* otherwise default to smallest */
|
||||
case 256:
|
||||
- bf_set(lpfc_mbx_cq_create_set_cqecnt,
|
||||
+ bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request, LPFC_CQ_CNT_256);
|
||||
break;
|
||||
case 512:
|
||||
- bf_set(lpfc_mbx_cq_create_set_cqecnt,
|
||||
+ bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request, LPFC_CQ_CNT_512);
|
||||
break;
|
||||
case 1024:
|
||||
- bf_set(lpfc_mbx_cq_create_set_cqecnt,
|
||||
+ bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request, LPFC_CQ_CNT_1024);
|
||||
break;
|
||||
}
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
|
||||
index e42b44fcc7f6..9be3da91c923 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli4.h
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
|
||||
@@ -575,10 +575,8 @@ struct lpfc_pc_sli4_params {
|
||||
|
||||
#define LPFC_CQ_4K_PAGE_SZ 0x1
|
||||
#define LPFC_CQ_16K_PAGE_SZ 0x4
|
||||
-#define LPFC_CQ_32K_PAGE_SZ 0x8
|
||||
#define LPFC_WQ_4K_PAGE_SZ 0x1
|
||||
#define LPFC_WQ_16K_PAGE_SZ 0x4
|
||||
-#define LPFC_WQ_32K_PAGE_SZ 0x8
|
||||
|
||||
struct lpfc_iov {
|
||||
uint32_t pf_number;
|
||||
@ -0,0 +1,40 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Move clearing of HBA_SETUP flag to before lpfc_sli4_queue_unset"
|
||||
# Revert of 0506fd6f9cce6d603c88619704e0281fbea553cc
|
||||
scsi: lpfc: Move clearing of HBA_SETUP flag to before lpfc_sli4_queue_unset
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
index 0786952cd7d5..9fa5de43f500 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
@@ -536,8 +536,7 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba,
|
||||
psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
|
||||
psb->flags &= ~LPFC_SBUF_XBUSY;
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
||||
- if (test_bit(HBA_SETUP, &phba->hba_flag) &&
|
||||
- !list_empty(&pring->txq))
|
||||
+ if (!list_empty(&pring->txq))
|
||||
lpfc_worker_wake_up(phba);
|
||||
return;
|
||||
}
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
index 73f8a0e3a4c0..bcc7ce426fbe 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
||||
@@ -5170,6 +5170,7 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
|
||||
phba->link_events = 0;
|
||||
phba->pport->fc_myDID = 0;
|
||||
phba->pport->fc_prevDID = 0;
|
||||
+ clear_bit(HBA_SETUP, &phba->hba_flag);
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
psli->sli_flag &= ~(LPFC_PROCESS_LA);
|
||||
@@ -5286,7 +5287,6 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
|
||||
"0296 Restart HBA Data: x%x x%x\n",
|
||||
phba->pport->port_state, psli->sli_flag);
|
||||
|
||||
- clear_bit(HBA_SETUP, &phba->hba_flag);
|
||||
lpfc_sli4_queue_unset(phba);
|
||||
|
||||
rc = lpfc_sli4_brdreset(phba);
|
||||
@ -0,0 +1,20 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Ensure HBA_SETUP flag is used only for SLI4 in dev_loss_tmo_callbk"
|
||||
# Revert of 86faf91ba7bc2858562ae56d12d90779b9e5ca53
|
||||
scsi: lpfc: Ensure HBA_SETUP flag is used only for SLI4 in dev_loss_tmo_callbk
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
index d4760fa67076..bcd943722f06 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
@@ -183,8 +183,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
|
||||
/* Don't schedule a worker thread event if the vport is going down. */
|
||||
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
|
||||
- (phba->sli_rev == LPFC_SLI_REV4 &&
|
||||
- !test_bit(HBA_SETUP, &phba->hba_flag))) {
|
||||
+ !test_bit(HBA_SETUP, &phba->hba_flag)) {
|
||||
|
||||
spin_lock_irqsave(&ndlp->lock, iflags);
|
||||
ndlp->rport = NULL;
|
||||
@ -0,0 +1,48 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Relocate clearing initial phba flags from link up to link down hdlr"
|
||||
# Revert of 0bba7f35a566c624c3a3c74285b61b59f2cf68bb
|
||||
scsi: lpfc: Relocate clearing initial phba flags from link up to link down hdlr
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index 853cf7649451..cdac8600ae9c 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -8376,9 +8376,9 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||
clear_bit(FC_PUBLIC_LOOP, &vport->fc_flag);
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
"3311 Rcv Flogi PS x%x new PS x%x "
|
||||
- "fc_flag x%lx new fc_flag x%lx, hba_flag x%lx\n",
|
||||
+ "fc_flag x%lx new fc_flag x%lx\n",
|
||||
port_state, vport->port_state,
|
||||
- fc_flag, vport->fc_flag, phba->hba_flag);
|
||||
+ fc_flag, vport->fc_flag);
|
||||
|
||||
/*
|
||||
* We temporarily set fc_myDID to make it look like we are
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
index bcd943722f06..c5502272f00e 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
@@ -1266,10 +1266,6 @@ lpfc_linkdown(struct lpfc_hba *phba)
|
||||
}
|
||||
phba->defer_flogi_acc.flag = false;
|
||||
|
||||
- /* reinitialize initial HBA flag */
|
||||
- clear_bit(HBA_FLOGI_ISSUED, &phba->hba_flag);
|
||||
- clear_bit(HBA_RHBA_CMPL, &phba->hba_flag);
|
||||
-
|
||||
/* Clear external loopback plug detected flag */
|
||||
phba->link_flag &= ~LS_EXTERNAL_LOOPBACK;
|
||||
|
||||
@@ -1440,6 +1436,10 @@ lpfc_linkup(struct lpfc_hba *phba)
|
||||
phba->pport->rcv_flogi_cnt = 0;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
+ /* reinitialize initial HBA flag */
|
||||
+ clear_bit(HBA_FLOGI_ISSUED, &phba->hba_flag);
|
||||
+ clear_bit(HBA_RHBA_CMPL, &phba->hba_flag);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Simplify error handling for failed lpfc_get_sli4_parameters cmd"
|
||||
# Revert of 58213a54e9c389dbde59a6b2714a77c7aed21eff
|
||||
scsi: lpfc: Simplify error handling for failed lpfc_get_sli4_parameters cmd
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
|
||||
index 8007c961bbd7..488a4bd363e3 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_init.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
||||
@@ -7916,6 +7916,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
||||
int longs;
|
||||
int extra;
|
||||
uint64_t wwn;
|
||||
+ u32 if_type;
|
||||
+ u32 if_fam;
|
||||
|
||||
phba->sli4_hba.num_present_cpu = lpfc_present_cpu;
|
||||
phba->sli4_hba.num_possible_cpu = cpumask_last(cpu_possible_mask) + 1;
|
||||
@@ -8176,11 +8178,28 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
||||
*/
|
||||
rc = lpfc_get_sli4_parameters(phba, mboxq);
|
||||
if (rc) {
|
||||
- lpfc_log_msg(phba, KERN_WARNING, LOG_INIT,
|
||||
- "2999 Could not get SLI4 parameters\n");
|
||||
- rc = -EIO;
|
||||
- mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
- goto out_free_bsmbx;
|
||||
+ if_type = bf_get(lpfc_sli_intf_if_type,
|
||||
+ &phba->sli4_hba.sli_intf);
|
||||
+ if_fam = bf_get(lpfc_sli_intf_sli_family,
|
||||
+ &phba->sli4_hba.sli_intf);
|
||||
+ if (phba->sli4_hba.extents_in_use &&
|
||||
+ phba->sli4_hba.rpi_hdrs_in_use) {
|
||||
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
+ "2999 Unsupported SLI4 Parameters "
|
||||
+ "Extents and RPI headers enabled.\n");
|
||||
+ if (if_type == LPFC_SLI_INTF_IF_TYPE_0 &&
|
||||
+ if_fam == LPFC_SLI_INTF_FAMILY_BE2) {
|
||||
+ mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
+ rc = -EIO;
|
||||
+ goto out_free_bsmbx;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!(if_type == LPFC_SLI_INTF_IF_TYPE_0 &&
|
||||
+ if_fam == LPFC_SLI_INTF_FAMILY_BE2)) {
|
||||
+ mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
+ rc = -EIO;
|
||||
+ goto out_free_bsmbx;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@ -0,0 +1,42 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Early return out of FDMI cmpl for locally rejected statuses"
|
||||
# Revert of 9c000843bf3d8afda0e42d382062558a239dc7f9
|
||||
scsi: lpfc: Early return out of FDMI cmpl for locally rejected statuses
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
index aa6c2b0f9907..2e1d762b75a9 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_ct.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
@@ -2229,6 +2229,21 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
/* Look for a retryable error */
|
||||
if (ulp_status == IOSTAT_LOCAL_REJECT) {
|
||||
switch ((ulp_word4 & IOERR_PARAM_MASK)) {
|
||||
+ case IOERR_SLI_ABORTED:
|
||||
+ case IOERR_SLI_DOWN:
|
||||
+ /* Driver aborted this IO. No retry as error
|
||||
+ * is likely Offline->Online or some adapter
|
||||
+ * error. Recovery will try again, but if port
|
||||
+ * is not active there's no point to continue
|
||||
+ * issuing follow up FDMI commands.
|
||||
+ */
|
||||
+ if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) {
|
||||
+ free_ndlp = cmdiocb->ndlp;
|
||||
+ lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
+ lpfc_nlp_put(free_ndlp);
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
case IOERR_ABORT_IN_PROGRESS:
|
||||
case IOERR_SEQUENCE_TIMEOUT:
|
||||
case IOERR_ILLEGAL_FRAME:
|
||||
@@ -2254,9 +2269,6 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_ct_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(free_ndlp);
|
||||
|
||||
- if (ulp_status != IOSTAT_SUCCESS)
|
||||
- return;
|
||||
-
|
||||
ndlp = lpfc_findnode_did(vport, FDMI_DID);
|
||||
if (!ndlp)
|
||||
return;
|
||||
@ -0,0 +1,24 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Skip RSCN processing when FC_UNLOADING flag is set"
|
||||
# Revert of c21abd3cdb713b806a0a8ecbc1c161f1fa9be73b
|
||||
scsi: lpfc: Skip RSCN processing when FC_UNLOADING flag is set
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
|
||||
index cdac8600ae9c..0205c54bce63 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_els.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
||||
@@ -7860,13 +7860,6 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
|
||||
|
||||
/* Move all affected nodes by pending RSCNs to NPR state. */
|
||||
list_for_each_entry_safe(ndlp, n, &vport->fc_nodes, nlp_listp) {
|
||||
- if (test_bit(FC_UNLOADING, &vport->load_flag)) {
|
||||
- lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||
- "1000 %s Unloading set\n",
|
||||
- __func__);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
if ((ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
|
||||
!lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
|
||||
continue;
|
||||
@ -0,0 +1,21 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Check for hdwq null ptr when cleaning up lpfc_vport structure"
|
||||
# Revert of 22e5c00fb500e6d78967da8a034de9e950a4db49
|
||||
scsi: lpfc: Check for hdwq null ptr when cleaning up lpfc_vport structure
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
index 9fa5de43f500..6309eb286a33 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
|
||||
@@ -390,10 +390,6 @@ lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport)
|
||||
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
|
||||
return;
|
||||
|
||||
- /* may be called before queues established if hba_setup fails */
|
||||
- if (!phba->sli4_hba.hdwq)
|
||||
- return;
|
||||
-
|
||||
spin_lock_irqsave(&phba->hbalock, iflag);
|
||||
for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
|
||||
qp = &phba->sli4_hba.hdwq[idx];
|
||||
@ -0,0 +1,56 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Update debugfs trace ring initialization messages"
|
||||
# Revert of 580bc25e722ca698094ef3e4aa1ac7152ed0e071
|
||||
scsi: lpfc: Update debugfs trace ring initialization messages
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
index 1b6cdadc7426..e5a31bc0f6c9 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
||||
@@ -6227,9 +6227,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
i++;
|
||||
}
|
||||
lpfc_debugfs_max_slow_ring_trc = (1 << i);
|
||||
- pr_info("lpfc_debugfs_max_slow_ring_trc "
|
||||
- "changed to %d\n",
|
||||
- lpfc_debugfs_max_slow_ring_trc);
|
||||
+ pr_err("lpfc_debugfs_max_disc_trc changed to "
|
||||
+ "%d\n", lpfc_debugfs_max_disc_trc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6261,7 +6260,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
atomic_set(&phba->nvmeio_trc_cnt, 0);
|
||||
if (lpfc_debugfs_max_nvmeio_trc) {
|
||||
num = lpfc_debugfs_max_nvmeio_trc - 1;
|
||||
- if (num & lpfc_debugfs_max_nvmeio_trc) {
|
||||
+ if (num & lpfc_debugfs_max_disc_trc) {
|
||||
/* Change to be a power of 2 */
|
||||
num = lpfc_debugfs_max_nvmeio_trc;
|
||||
i = 0;
|
||||
@@ -6270,9 +6269,10 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
i++;
|
||||
}
|
||||
lpfc_debugfs_max_nvmeio_trc = (1 << i);
|
||||
- pr_info("lpfc_debugfs_max_nvmeio_trc changed "
|
||||
- "to %d\n",
|
||||
- lpfc_debugfs_max_nvmeio_trc);
|
||||
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
+ "0575 lpfc_debugfs_max_nvmeio_trc "
|
||||
+ "changed to %d\n",
|
||||
+ lpfc_debugfs_max_nvmeio_trc);
|
||||
}
|
||||
phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc;
|
||||
|
||||
@@ -6317,8 +6317,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
|
||||
i++;
|
||||
}
|
||||
lpfc_debugfs_max_disc_trc = (1 << i);
|
||||
- pr_info("lpfc_debugfs_max_disc_trc changed to %d\n",
|
||||
- lpfc_debugfs_max_disc_trc);
|
||||
+ pr_err("lpfc_debugfs_max_disc_trc changed to %d\n",
|
||||
+ lpfc_debugfs_max_disc_trc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From: AlmaLinux backport
|
||||
Subject: [PATCH] Revert "scsi: lpfc: Revise logging format for failed CT MIB requests"
|
||||
# Revert of dfd30218a269fc6f6df48cb0781977d53223f955
|
||||
scsi: lpfc: Revise logging format for failed CT MIB requests
|
||||
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
index 2e1d762b75a9..0c9260dc2706 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_ct.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_ct.c
|
||||
@@ -264,9 +264,9 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,
|
||||
ct_free_mp:
|
||||
kfree(mp);
|
||||
ct_exit:
|
||||
- lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
|
||||
- "6440 Unsol CT: Rsp err %d Data: x%lx\n",
|
||||
- rc, vport->fc_flag);
|
||||
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
|
||||
+ "6440 Unsol CT: Rsp err %d Data: x%lx\n",
|
||||
+ rc, vport->fc_flag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +313,7 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)
|
||||
|
||||
mi_cmd = be16_to_cpu(ct_req->CommandResponse.bits.CmdRsp);
|
||||
lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
|
||||
- "6442 MI Cmd: x%x Not Supported\n", mi_cmd);
|
||||
+ "6442 MI Cmd : x%x Not Supported\n", mi_cmd);
|
||||
lpfc_ct_reject_event(ndlp, ct_req,
|
||||
bf_get(wqe_ctxt_tag,
|
||||
&ctiocbq->wqe.xmit_els_rsp.wqe_com),
|
||||
@ -0,0 +1,33 @@
|
||||
From: AlmaLinux (RHEL-only, no upstream/CS9 source) <noreply@almalinux.org>
|
||||
Subject: [PATCH] scsi: lpfc: avoid crashing in lpfc_nlp_get() if lpfc_nodelist was freed
|
||||
JIRA: RHEL-167742
|
||||
NOTE: RHEL-specific fix; no CS9 or upstream commit exists. Reconstructed change.
|
||||
|
||||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
index 14ebc9c..a7064fd 100644
|
||||
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
||||
@@ -6597,11 +6597,6 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp)
|
||||
unsigned long flags;
|
||||
|
||||
if (ndlp) {
|
||||
- lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
|
||||
- "node get: did:x%x flg:x%lx refcnt:x%x",
|
||||
- ndlp->nlp_DID, ndlp->nlp_flag,
|
||||
- kref_read(&ndlp->kref));
|
||||
-
|
||||
/* The check of ndlp usage to prevent incrementing the
|
||||
* ndlp reference count that is in the process of being
|
||||
* released.
|
||||
@@ -6609,9 +6604,8 @@ lpfc_nlp_get(struct lpfc_nodelist *ndlp)
|
||||
spin_lock_irqsave(&ndlp->lock, flags);
|
||||
if (!kref_get_unless_zero(&ndlp->kref)) {
|
||||
spin_unlock_irqrestore(&ndlp->lock, flags);
|
||||
- lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
|
||||
- "0276 %s: ndlp:x%px refcnt:%d\n",
|
||||
- __func__, (void *)ndlp, kref_read(&ndlp->kref));
|
||||
+ pr_info("0276 %s: NDLP has zero reference count. "
|
||||
+ "Exiting\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&ndlp->lock, flags);
|
||||
@ -0,0 +1,218 @@
|
||||
From 8c738512714e8c0aa18f8a10c072d5b01c83db39 Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Dryomov <idryomov@gmail.com>
|
||||
Date: Tue, 2 Dec 2025 10:32:31 +0100
|
||||
Subject: [PATCH] libceph: make decode_pool() more resilient against corrupted
|
||||
osdmaps
|
||||
|
||||
If the osdmap is (maliciously) corrupted such that the encoded length
|
||||
of ceph_pg_pool envelope is less than what is expected for a particular
|
||||
encoding version, out-of-bounds reads may ensue because the only bounds
|
||||
check that is there is based on that length value.
|
||||
|
||||
This patch adds explicit bounds checks for each field that is decoded
|
||||
or skipped.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: ziming zhang <ezrakiez@gmail.com>
|
||||
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
Reviewed-by: Xiubo Li <xiubli@redhat.com>
|
||||
Tested-by: ziming zhang <ezrakiez@gmail.com>
|
||||
|
||||
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
|
||||
index 329eeea2f922..34b3ab59602f 100644
|
||||
--- a/net/ceph/osdmap.c
|
||||
+++ b/net/ceph/osdmap.c
|
||||
@@ -806,51 +806,49 @@ static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
|
||||
ceph_decode_need(p, end, len, bad);
|
||||
pool_end = *p + len;
|
||||
|
||||
+ ceph_decode_need(p, end, 4 + 4 + 4, bad);
|
||||
pi->type = ceph_decode_8(p);
|
||||
pi->size = ceph_decode_8(p);
|
||||
pi->crush_ruleset = ceph_decode_8(p);
|
||||
pi->object_hash = ceph_decode_8(p);
|
||||
-
|
||||
pi->pg_num = ceph_decode_32(p);
|
||||
pi->pgp_num = ceph_decode_32(p);
|
||||
|
||||
- *p += 4 + 4; /* skip lpg* */
|
||||
- *p += 4; /* skip last_change */
|
||||
- *p += 8 + 4; /* skip snap_seq, snap_epoch */
|
||||
+ /* lpg*, last_change, snap_seq, snap_epoch */
|
||||
+ ceph_decode_skip_n(p, end, 8 + 4 + 8 + 4, bad);
|
||||
|
||||
/* skip snaps */
|
||||
- num = ceph_decode_32(p);
|
||||
+ ceph_decode_32_safe(p, end, num, bad);
|
||||
while (num--) {
|
||||
- *p += 8; /* snapid key */
|
||||
- *p += 1 + 1; /* versions */
|
||||
- len = ceph_decode_32(p);
|
||||
- *p += len;
|
||||
+ /* snapid key, pool snap (with versions) */
|
||||
+ ceph_decode_skip_n(p, end, 8 + 2, bad);
|
||||
+ ceph_decode_skip_string(p, end, bad);
|
||||
}
|
||||
|
||||
- /* skip removed_snaps */
|
||||
- num = ceph_decode_32(p);
|
||||
- *p += num * (8 + 8);
|
||||
+ /* removed_snaps */
|
||||
+ ceph_decode_skip_map(p, end, 64, 64, bad);
|
||||
|
||||
+ ceph_decode_need(p, end, 8 + 8 + 4, bad);
|
||||
*p += 8; /* skip auid */
|
||||
pi->flags = ceph_decode_64(p);
|
||||
*p += 4; /* skip crash_replay_interval */
|
||||
|
||||
if (ev >= 7)
|
||||
- pi->min_size = ceph_decode_8(p);
|
||||
+ ceph_decode_8_safe(p, end, pi->min_size, bad);
|
||||
else
|
||||
pi->min_size = pi->size - pi->size / 2;
|
||||
|
||||
if (ev >= 8)
|
||||
- *p += 8 + 8; /* skip quota_max_* */
|
||||
+ /* quota_max_* */
|
||||
+ ceph_decode_skip_n(p, end, 8 + 8, bad);
|
||||
|
||||
if (ev >= 9) {
|
||||
- /* skip tiers */
|
||||
- num = ceph_decode_32(p);
|
||||
- *p += num * 8;
|
||||
+ /* tiers */
|
||||
+ ceph_decode_skip_set(p, end, 64, bad);
|
||||
|
||||
+ ceph_decode_need(p, end, 8 + 1 + 8 + 8, bad);
|
||||
*p += 8; /* skip tier_of */
|
||||
*p += 1; /* skip cache_mode */
|
||||
-
|
||||
pi->read_tier = ceph_decode_64(p);
|
||||
pi->write_tier = ceph_decode_64(p);
|
||||
} else {
|
||||
@@ -858,86 +856,76 @@ static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
|
||||
pi->write_tier = -1;
|
||||
}
|
||||
|
||||
- if (ev >= 10) {
|
||||
- /* skip properties */
|
||||
- num = ceph_decode_32(p);
|
||||
- while (num--) {
|
||||
- len = ceph_decode_32(p);
|
||||
- *p += len; /* key */
|
||||
- len = ceph_decode_32(p);
|
||||
- *p += len; /* val */
|
||||
- }
|
||||
- }
|
||||
+ if (ev >= 10)
|
||||
+ /* properties */
|
||||
+ ceph_decode_skip_map(p, end, string, string, bad);
|
||||
|
||||
if (ev >= 11) {
|
||||
- /* skip hit_set_params */
|
||||
- *p += 1 + 1; /* versions */
|
||||
- len = ceph_decode_32(p);
|
||||
- *p += len;
|
||||
+ /* hit_set_params (with versions) */
|
||||
+ ceph_decode_skip_n(p, end, 2, bad);
|
||||
+ ceph_decode_skip_string(p, end, bad);
|
||||
|
||||
- *p += 4; /* skip hit_set_period */
|
||||
- *p += 4; /* skip hit_set_count */
|
||||
+ /* hit_set_period, hit_set_count */
|
||||
+ ceph_decode_skip_n(p, end, 4 + 4, bad);
|
||||
}
|
||||
|
||||
if (ev >= 12)
|
||||
- *p += 4; /* skip stripe_width */
|
||||
+ /* stripe_width */
|
||||
+ ceph_decode_skip_32(p, end, bad);
|
||||
|
||||
- if (ev >= 13) {
|
||||
- *p += 8; /* skip target_max_bytes */
|
||||
- *p += 8; /* skip target_max_objects */
|
||||
- *p += 4; /* skip cache_target_dirty_ratio_micro */
|
||||
- *p += 4; /* skip cache_target_full_ratio_micro */
|
||||
- *p += 4; /* skip cache_min_flush_age */
|
||||
- *p += 4; /* skip cache_min_evict_age */
|
||||
- }
|
||||
+ if (ev >= 13)
|
||||
+ /* target_max_*, cache_target_*, cache_min_* */
|
||||
+ ceph_decode_skip_n(p, end, 16 + 8 + 8, bad);
|
||||
|
||||
- if (ev >= 14) {
|
||||
- /* skip erasure_code_profile */
|
||||
- len = ceph_decode_32(p);
|
||||
- *p += len;
|
||||
- }
|
||||
+ if (ev >= 14)
|
||||
+ /* erasure_code_profile */
|
||||
+ ceph_decode_skip_string(p, end, bad);
|
||||
|
||||
/*
|
||||
* last_force_op_resend_preluminous, will be overridden if the
|
||||
* map was encoded with RESEND_ON_SPLIT
|
||||
*/
|
||||
if (ev >= 15)
|
||||
- pi->last_force_request_resend = ceph_decode_32(p);
|
||||
+ ceph_decode_32_safe(p, end, pi->last_force_request_resend, bad);
|
||||
else
|
||||
pi->last_force_request_resend = 0;
|
||||
|
||||
if (ev >= 16)
|
||||
- *p += 4; /* skip min_read_recency_for_promote */
|
||||
+ /* min_read_recency_for_promote */
|
||||
+ ceph_decode_skip_32(p, end, bad);
|
||||
|
||||
if (ev >= 17)
|
||||
- *p += 8; /* skip expected_num_objects */
|
||||
+ /* expected_num_objects */
|
||||
+ ceph_decode_skip_64(p, end, bad);
|
||||
|
||||
if (ev >= 19)
|
||||
- *p += 4; /* skip cache_target_dirty_high_ratio_micro */
|
||||
+ /* cache_target_dirty_high_ratio_micro */
|
||||
+ ceph_decode_skip_32(p, end, bad);
|
||||
|
||||
if (ev >= 20)
|
||||
- *p += 4; /* skip min_write_recency_for_promote */
|
||||
+ /* min_write_recency_for_promote */
|
||||
+ ceph_decode_skip_32(p, end, bad);
|
||||
|
||||
if (ev >= 21)
|
||||
- *p += 1; /* skip use_gmt_hitset */
|
||||
+ /* use_gmt_hitset */
|
||||
+ ceph_decode_skip_8(p, end, bad);
|
||||
|
||||
if (ev >= 22)
|
||||
- *p += 1; /* skip fast_read */
|
||||
+ /* fast_read */
|
||||
+ ceph_decode_skip_8(p, end, bad);
|
||||
|
||||
- if (ev >= 23) {
|
||||
- *p += 4; /* skip hit_set_grade_decay_rate */
|
||||
- *p += 4; /* skip hit_set_search_last_n */
|
||||
- }
|
||||
+ if (ev >= 23)
|
||||
+ /* hit_set_grade_decay_rate, hit_set_search_last_n */
|
||||
+ ceph_decode_skip_n(p, end, 4 + 4, bad);
|
||||
|
||||
if (ev >= 24) {
|
||||
- /* skip opts */
|
||||
- *p += 1 + 1; /* versions */
|
||||
- len = ceph_decode_32(p);
|
||||
- *p += len;
|
||||
+ /* opts (with versions) */
|
||||
+ ceph_decode_skip_n(p, end, 2, bad);
|
||||
+ ceph_decode_skip_string(p, end, bad);
|
||||
}
|
||||
|
||||
if (ev >= 25)
|
||||
- pi->last_force_request_resend = ceph_decode_32(p);
|
||||
+ ceph_decode_32_safe(p, end, pi->last_force_request_resend, bad);
|
||||
|
||||
/* ignore the rest */
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 818156caffbf55cb4d368f9c3cac64e458fb49c9 Mon Sep 17 00:00:00 2001
|
||||
From: ziming zhang <ezrakiez@gmail.com>
|
||||
Date: Thu, 11 Dec 2025 16:52:58 +0800
|
||||
Subject: [PATCH] libceph: prevent potential out-of-bounds reads in
|
||||
handle_auth_done()
|
||||
|
||||
Perform an explicit bounds check on payload_len to avoid a possible
|
||||
out-of-bounds access in the callout.
|
||||
|
||||
[ idryomov: changelog ]
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: ziming zhang <ezrakiez@gmail.com>
|
||||
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
|
||||
diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c
|
||||
index 833e57849c1d..c9d50c0dcd33 100644
|
||||
--- a/net/ceph/messenger_v2.c
|
||||
+++ b/net/ceph/messenger_v2.c
|
||||
@@ -2376,7 +2376,9 @@ static int process_auth_done(struct ceph_connection *con, void *p, void *end)
|
||||
|
||||
ceph_decode_64_safe(&p, end, global_id, bad);
|
||||
ceph_decode_32_safe(&p, end, con->v2.con_mode, bad);
|
||||
+
|
||||
ceph_decode_32_safe(&p, end, payload_len, bad);
|
||||
+ ceph_decode_need(&p, end, payload_len, bad);
|
||||
|
||||
dout("%s con %p global_id %llu con_mode %d payload_len %d\n",
|
||||
__func__, con, global_id, con->v2.con_mode, payload_len);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From e00c3f71b5cf75681dbd74ee3f982a99cb690c2b Mon Sep 17 00:00:00 2001
|
||||
From: Ilya Dryomov <idryomov@gmail.com>
|
||||
Date: Mon, 15 Dec 2025 11:53:31 +0100
|
||||
Subject: [PATCH] libceph: replace overzealous BUG_ON in
|
||||
osdmap_apply_incremental()
|
||||
|
||||
If the osdmap is (maliciously) corrupted such that the incremental
|
||||
osdmap epoch is different from what is expected, there is no need to
|
||||
BUG. Instead, just declare the incremental osdmap to be invalid.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: ziming zhang <ezrakiez@gmail.com>
|
||||
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
|
||||
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
|
||||
index 34b3ab59602f..3377a22e3f6c 100644
|
||||
--- a/net/ceph/osdmap.c
|
||||
+++ b/net/ceph/osdmap.c
|
||||
@@ -1979,11 +1979,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, bool msgr2,
|
||||
sizeof(u64) + sizeof(u32), e_inval);
|
||||
ceph_decode_copy(p, &fsid, sizeof(fsid));
|
||||
epoch = ceph_decode_32(p);
|
||||
- BUG_ON(epoch != map->epoch+1);
|
||||
ceph_decode_copy(p, &modified, sizeof(modified));
|
||||
new_pool_max = ceph_decode_64(p);
|
||||
new_flags = ceph_decode_32(p);
|
||||
|
||||
+ if (epoch != map->epoch + 1)
|
||||
+ goto e_inval;
|
||||
+
|
||||
/* full map? */
|
||||
ceph_decode_32_safe(p, end, len, e_inval);
|
||||
if (len > 0) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From 11194b416ef95012c2cfe5f546d71af07b639e93 Mon Sep 17 00:00:00 2001
|
||||
From: Sam Edwards <cfsworks@gmail.com>
|
||||
Date: Tue, 30 Dec 2025 20:05:06 -0800
|
||||
Subject: [PATCH] libceph: reset sparse-read state in osd_fault()
|
||||
|
||||
When a fault occurs, the connection is abandoned, reestablished, and any
|
||||
pending operations are retried. The OSD client tracks the progress of a
|
||||
sparse-read reply using a separate state machine, largely independent of
|
||||
the messenger's state.
|
||||
|
||||
If a connection is lost mid-payload or the sparse-read state machine
|
||||
returns an error, the sparse-read state is not reset. The OSD client
|
||||
will then interpret the beginning of a new reply as the continuation of
|
||||
the old one. If this makes the sparse-read machinery enter a failure
|
||||
state, it may never recover, producing loops like:
|
||||
|
||||
libceph: [0] got 0 extents
|
||||
libceph: data len 142248331 != extent len 0
|
||||
libceph: osd0 (1)...:6801 socket error on read
|
||||
libceph: data len 142248331 != extent len 0
|
||||
libceph: osd0 (1)...:6801 socket error on read
|
||||
|
||||
Therefore, reset the sparse-read state in osd_fault(), ensuring retries
|
||||
start from a clean state.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: f628d7999727 ("libceph: add sparse read support to OSD client")
|
||||
Signed-off-by: Sam Edwards <CFSworks@gmail.com>
|
||||
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|
||||
|
||||
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
|
||||
index 3667319b949d..1a7be2f615dc 100644
|
||||
--- a/net/ceph/osd_client.c
|
||||
+++ b/net/ceph/osd_client.c
|
||||
@@ -4281,6 +4281,9 @@ static void osd_fault(struct ceph_connection *con)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
+ osd->o_sparse_op_idx = -1;
|
||||
+ ceph_init_sparse_read(&osd->o_sparse_read);
|
||||
+
|
||||
if (!reopen_osd(osd))
|
||||
kick_osd_requests(osd);
|
||||
maybe_request_map(osdc);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From 123d241dcfc31871e2610504c50583dce8ac832f Mon Sep 17 00:00:00 2001
|
||||
From: Jan Stancek <jstancek@redhat.com>
|
||||
Date: Tue, 23 Sep 2025 17:32:16 +0200
|
||||
Subject: [PATCH] powerpc/tools: drop `-o pipefail` in gcc check scripts
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-165107
|
||||
Upstream Status: linux.git
|
||||
|
||||
Conflicts:
|
||||
- RHEL commit 12e313df71b6 ("powerpc/tools: drop `-o pipefail` in gcc check scripts")
|
||||
applied one of the hunks of upstream commit, because at the time RHEL9
|
||||
was missing gcc-check-fpatchable-function-entry.sh.
|
||||
This has changed when RHEL commit
|
||||
c3aeb790328d ("powerpc/ftrace: Add support for -fpatchable-function-entry")
|
||||
introduced it.
|
||||
This applies missing hunk from f1164534ad62f0cc247d99650b07bd59ad2a49fd to
|
||||
arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh
|
||||
|
||||
commit f1164534ad62f0cc247d99650b07bd59ad2a49fd
|
||||
Author: Jan Stancek <jstancek@redhat.com>
|
||||
Date: Tue Sep 23 17:32:16 2025 +0200
|
||||
|
||||
powerpc/tools: drop `-o pipefail` in gcc check scripts
|
||||
|
||||
Fixes: 0f71dcfb4aef ("powerpc/ftrace: Add support for -fpatchable-function-entry")
|
||||
Fixes: b71c9ffb1405 ("powerpc: Add arch/powerpc/tools directory")
|
||||
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
|
||||
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
|
||||
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
||||
Fixes: 8c50b72a3b4f ("powerpc/ftrace: Add Kconfig & Make glue for mprofile-kernel")
|
||||
Fixes: abba759796f9 ("powerpc/kbuild: move -mprofile-kernel check to Kconfig")
|
||||
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
|
||||
Reviewed-by: Naveen N Rao (AMD) <naveen@kernel.org>
|
||||
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
|
||||
Link: https://patch.msgid.link/cc6cdd116c3ad9d990df21f13c6d8e8a83815bbd.1758641374.git.jstancek@redhat.com
|
||||
|
||||
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
||||
|
||||
diff --git a/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh b/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh
|
||||
index 06706903503b..baed467a016b 100755
|
||||
--- a/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh
|
||||
+++ b/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh
|
||||
@@ -2,7 +2,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
set -e
|
||||
-set -o pipefail
|
||||
|
||||
# To debug, uncomment the following line
|
||||
# set -x
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
From aad885e774966e97b675dfe928da164214a71605 Mon Sep 17 00:00:00 2001
|
||||
From: Sean Christopherson <seanjc@google.com>
|
||||
Date: Thu, 5 Mar 2026 17:28:04 -0800
|
||||
Subject: [PATCH] KVM: x86/mmu: Drop/zap existing present SPTE even when
|
||||
creating an MMIO SPTE
|
||||
|
||||
When installing an emulated MMIO SPTE, do so *after* dropping/zapping the
|
||||
existing SPTE (if it's shadow-present). While commit a54aa15c6bda3 was
|
||||
right about it being impossible to convert a shadow-present SPTE to an
|
||||
MMIO SPTE due to a _guest_ write, it failed to account for writes to guest
|
||||
memory that are outside the scope of KVM.
|
||||
|
||||
E.g. if host userspace modifies a shadowed gPTE to switch from a memslot
|
||||
to emulted MMIO and then the guest hits a relevant page fault, KVM will
|
||||
install the MMIO SPTE without first zapping the shadow-present SPTE.
|
||||
|
||||
------------[ cut here ]------------
|
||||
is_shadow_present_pte(*sptep)
|
||||
WARNING: arch/x86/kvm/mmu/mmu.c:484 at mark_mmio_spte+0xb2/0xc0 [kvm], CPU#0: vmx_ept_stale_r/4292
|
||||
Modules linked in: kvm_intel kvm irqbypass
|
||||
CPU: 0 UID: 1000 PID: 4292 Comm: vmx_ept_stale_r Not tainted 7.0.0-rc2-eafebd2d2ab0-sink-vm #319 PREEMPT
|
||||
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
|
||||
RIP: 0010:mark_mmio_spte+0xb2/0xc0 [kvm]
|
||||
Call Trace:
|
||||
<TASK>
|
||||
mmu_set_spte+0x237/0x440 [kvm]
|
||||
ept_page_fault+0x535/0x7f0 [kvm]
|
||||
kvm_mmu_do_page_fault+0xee/0x1f0 [kvm]
|
||||
kvm_mmu_page_fault+0x8d/0x620 [kvm]
|
||||
vmx_handle_exit+0x18c/0x5a0 [kvm_intel]
|
||||
kvm_arch_vcpu_ioctl_run+0xc55/0x1c20 [kvm]
|
||||
kvm_vcpu_ioctl+0x2d5/0x980 [kvm]
|
||||
__x64_sys_ioctl+0x8a/0xd0
|
||||
do_syscall_64+0xb5/0x730
|
||||
entry_SYSCALL_64_after_hwframe+0x4b/0x53
|
||||
RIP: 0033:0x47fa3f
|
||||
</TASK>
|
||||
---[ end trace 0000000000000000 ]---
|
||||
|
||||
Reported-by: Alexander Bulekov <bkov@amazon.com>
|
||||
Debugged-by: Alexander Bulekov <bkov@amazon.com>
|
||||
Suggested-by: Fred Griffoul <fgriffo@amazon.co.uk>
|
||||
Fixes: a54aa15c6bda3 ("KVM: x86/mmu: Handle MMIO SPTEs directly in mmu_set_spte()")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Sean Christopherson <seanjc@google.com>
|
||||
|
||||
|
||||
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
|
||||
index c542b26..8895c98 100644
|
||||
--- a/arch/x86/kvm/mmu/mmu.c
|
||||
+++ b/arch/x86/kvm/mmu/mmu.c
|
||||
@@ -2892,12 +2892,6 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
|
||||
bool prefetch = !fault || fault->prefetch;
|
||||
bool write_fault = fault && fault->write;
|
||||
|
||||
- if (unlikely(is_noslot_pfn(pfn))) {
|
||||
- vcpu->stat.pf_mmio_spte_created++;
|
||||
- mark_mmio_spte(vcpu, sptep, gfn, pte_access);
|
||||
- return RET_PF_EMULATE;
|
||||
- }
|
||||
-
|
||||
if (is_shadow_present_pte(*sptep)) {
|
||||
if (prefetch)
|
||||
return RET_PF_SPURIOUS;
|
||||
@@ -2920,6 +2914,14 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
|
||||
was_rmapped = 1;
|
||||
}
|
||||
|
||||
+ if (unlikely(is_noslot_pfn(pfn))) {
|
||||
+ vcpu->stat.pf_mmio_spte_created++;
|
||||
+ mark_mmio_spte(vcpu, sptep, gfn, pte_access);
|
||||
+ if (flush)
|
||||
+ kvm_flush_remote_tlbs_gfn(vcpu->kvm, gfn, level);
|
||||
+ return RET_PF_EMULATE;
|
||||
+ }
|
||||
+
|
||||
wrprot = make_spte(vcpu, sp, slot, pte_access, gfn, pfn, *sptep, prefetch,
|
||||
true, host_writable, &spte);
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From 00de3c031466400b8db061ae3149de8c64999974 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 12:54:18 +0800
|
||||
Subject: [PATCH] crypto: af-alg - fix NULL pointer dereference in scatterwalk
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
|
||||
Upstream Status: 62397b493e14107ae82d8b80938f293d95425bcb
|
||||
|
||||
commit 62397b493e14107ae82d8b80938f293d95425bcb
|
||||
Author: Norbert Szetei <norbert@doyensec.com>
|
||||
Date: Wed Mar 25 18:26:13 2026 +0100
|
||||
|
||||
crypto: af-alg - fix NULL pointer dereference in scatterwalk
|
||||
|
||||
The AF_ALG interface fails to unmark the end of a Scatter/Gather List (SGL)
|
||||
when chaining a new af_alg_tsgl structure. If a sendmsg() fills an SGL
|
||||
exactly to MAX_SGL_ENTS, the last entry is marked as the end. A subsequent
|
||||
sendmsg() allocates a new SGL and chains it, but fails to clear the end
|
||||
marker on the previous SGL's last data entry.
|
||||
|
||||
This causes the crypto scatterwalk to hit a premature end, returning NULL
|
||||
on sg_next() and leading to a kernel panic during dereference.
|
||||
|
||||
Fix this by explicitly unmarking the end of the previous SGL when
|
||||
performing sg_chain() in af_alg_alloc_tsgl().
|
||||
|
||||
Fixes: 8ff590903d5f ("crypto: algif_skcipher - User-space interface for skcipher operations")
|
||||
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
|
||||
index 67e66729281b..25d9d907dd9f 100644
|
||||
--- a/crypto/af_alg.c
|
||||
+++ b/crypto/af_alg.c
|
||||
@@ -513,8 +513,10 @@ static int af_alg_alloc_tsgl(struct sock *sk)
|
||||
sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
|
||||
sgl->cur = 0;
|
||||
|
||||
- if (sg)
|
||||
+ if (sg) {
|
||||
+ sg_unmark_end(sg + MAX_SGL_ENTS - 1);
|
||||
sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
|
||||
+ }
|
||||
|
||||
list_add_tail(&sgl->list, &ctx->tsgl_list);
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,325 @@
|
||||
From ada3d4ca449018dd63cee4a4b806d7cb78e76e4c Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 20:52:06 +0800
|
||||
Subject: [PATCH] crypto: algif_aead - Revert to operating out-of-place
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
CVE: CVE-2026-31431
|
||||
|
||||
Upstream Status: a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
|
||||
|
||||
commit a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
|
||||
Author: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Thu Mar 26 15:30:20 2026 +0900
|
||||
|
||||
crypto: algif_aead - Revert to operating out-of-place
|
||||
|
||||
This mostly reverts commit 72548b093ee3 except for the copying of
|
||||
the associated data.
|
||||
|
||||
There is no benefit in operating in-place in algif_aead since the
|
||||
source and destination come from different mappings. Get rid of
|
||||
all the complexity added for in-place operation and just copy the
|
||||
AD directly.
|
||||
|
||||
Fixes: 72548b093ee3 ("crypto: algif_aead - copy AAD from src to dst")
|
||||
Reported-by: Taeyang Lee <0wn@theori.io>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
|
||||
index 25d9d907dd9f..45a058ca890a 100644
|
||||
--- a/crypto/af_alg.c
|
||||
+++ b/crypto/af_alg.c
|
||||
@@ -527,15 +527,13 @@ static int af_alg_alloc_tsgl(struct sock *sk)
|
||||
/**
|
||||
* af_alg_count_tsgl - Count number of TX SG entries
|
||||
*
|
||||
- * The counting starts from the beginning of the SGL to @bytes. If
|
||||
- * an @offset is provided, the counting of the SG entries starts at the @offset.
|
||||
+ * The counting starts from the beginning of the SGL to @bytes.
|
||||
*
|
||||
* @sk: socket of connection to user space
|
||||
* @bytes: Count the number of SG entries holding given number of bytes.
|
||||
- * @offset: Start the counting of SG entries from the given offset.
|
||||
* Return: Number of TX SG entries found given the constraints
|
||||
*/
|
||||
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
|
||||
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes)
|
||||
{
|
||||
const struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_ctx *ctx = ask->private;
|
||||
@@ -550,25 +548,11 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
|
||||
const struct scatterlist *sg = sgl->sg;
|
||||
|
||||
for (i = 0; i < sgl->cur; i++) {
|
||||
- size_t bytes_count;
|
||||
-
|
||||
- /* Skip offset */
|
||||
- if (offset >= sg[i].length) {
|
||||
- offset -= sg[i].length;
|
||||
- bytes -= sg[i].length;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- bytes_count = sg[i].length - offset;
|
||||
-
|
||||
- offset = 0;
|
||||
sgl_count++;
|
||||
-
|
||||
- /* If we have seen requested number of bytes, stop */
|
||||
- if (bytes_count >= bytes)
|
||||
+ if (sg[i].length >= bytes)
|
||||
return sgl_count;
|
||||
|
||||
- bytes -= bytes_count;
|
||||
+ bytes -= sg[i].length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,19 +564,14 @@ EXPORT_SYMBOL_GPL(af_alg_count_tsgl);
|
||||
* af_alg_pull_tsgl - Release the specified buffers from TX SGL
|
||||
*
|
||||
* If @dst is non-null, reassign the pages to @dst. The caller must release
|
||||
- * the pages. If @dst_offset is given only reassign the pages to @dst starting
|
||||
- * at the @dst_offset (byte). The caller must ensure that @dst is large
|
||||
- * enough (e.g. by using af_alg_count_tsgl with the same offset).
|
||||
+ * the pages.
|
||||
*
|
||||
* @sk: socket of connection to user space
|
||||
* @used: Number of bytes to pull from TX SGL
|
||||
* @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
|
||||
* caller must release the buffers in dst.
|
||||
- * @dst_offset: Reassign the TX SGL from given offset. All buffers before
|
||||
- * reaching the offset is released.
|
||||
*/
|
||||
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
|
||||
- size_t dst_offset)
|
||||
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
|
||||
{
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct af_alg_ctx *ctx = ask->private;
|
||||
@@ -617,18 +596,10 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
|
||||
* SG entries in dst.
|
||||
*/
|
||||
if (dst) {
|
||||
- if (dst_offset >= plen) {
|
||||
- /* discard page before offset */
|
||||
- dst_offset -= plen;
|
||||
- } else {
|
||||
- /* reassign page to dst after offset */
|
||||
- get_page(page);
|
||||
- sg_set_page(dst + j, page,
|
||||
- plen - dst_offset,
|
||||
- sg[i].offset + dst_offset);
|
||||
- dst_offset = 0;
|
||||
- j++;
|
||||
- }
|
||||
+ /* reassign page to dst after offset */
|
||||
+ get_page(page);
|
||||
+ sg_set_page(dst + j, page, plen, sg[i].offset);
|
||||
+ j++;
|
||||
}
|
||||
|
||||
sg[i].length -= plen;
|
||||
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
|
||||
index 42493b4d8ce4..4a6a0bb1ae3c 100644
|
||||
--- a/crypto/algif_aead.c
|
||||
+++ b/crypto/algif_aead.c
|
||||
@@ -96,9 +96,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
struct aead_tfm *aeadc = pask->private;
|
||||
struct crypto_aead *tfm = aeadc->aead;
|
||||
struct crypto_sync_skcipher *null_tfm = aeadc->null_tfm;
|
||||
- unsigned int i, as = crypto_aead_authsize(tfm);
|
||||
+ unsigned int as = crypto_aead_authsize(tfm);
|
||||
struct af_alg_async_req *areq;
|
||||
- struct af_alg_tsgl *tsgl, *tmp;
|
||||
struct scatterlist *rsgl_src, *tsgl_src = NULL;
|
||||
int err = 0;
|
||||
size_t used = 0; /* [in] TX bufs to be en/decrypted */
|
||||
@@ -178,23 +177,24 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
outlen -= less;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Create a per request TX SGL for this request which tracks the
|
||||
+ * SG entries from the global TX SGL.
|
||||
+ */
|
||||
processed = used + ctx->aead_assoclen;
|
||||
- list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) {
|
||||
- for (i = 0; i < tsgl->cur; i++) {
|
||||
- struct scatterlist *process_sg = tsgl->sg + i;
|
||||
-
|
||||
- if (!(process_sg->length) || !sg_page(process_sg))
|
||||
- continue;
|
||||
- tsgl_src = process_sg;
|
||||
- break;
|
||||
- }
|
||||
- if (tsgl_src)
|
||||
- break;
|
||||
- }
|
||||
- if (processed && !tsgl_src) {
|
||||
- err = -EFAULT;
|
||||
+ areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
|
||||
+ if (!areq->tsgl_entries)
|
||||
+ areq->tsgl_entries = 1;
|
||||
+ areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
|
||||
+ areq->tsgl_entries),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!areq->tsgl) {
|
||||
+ err = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
+ sg_init_table(areq->tsgl, areq->tsgl_entries);
|
||||
+ af_alg_pull_tsgl(sk, processed, areq->tsgl);
|
||||
+ tsgl_src = areq->tsgl;
|
||||
|
||||
/*
|
||||
* Copy of AAD from source to destination
|
||||
@@ -203,81 +203,18 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
* when user space uses an in-place cipher operation, the kernel
|
||||
* will copy the data as it does not see whether such in-place operation
|
||||
* is initiated.
|
||||
- *
|
||||
- * To ensure efficiency, the following implementation ensure that the
|
||||
- * ciphers are invoked to perform a crypto operation in-place. This
|
||||
- * is achieved by memory management specified as follows.
|
||||
*/
|
||||
|
||||
/* Use the RX SGL as source (and destination) for crypto op. */
|
||||
rsgl_src = areq->first_rsgl.sgl.sg;
|
||||
|
||||
- if (ctx->enc) {
|
||||
- /*
|
||||
- * Encryption operation - The in-place cipher operation is
|
||||
- * achieved by the following operation:
|
||||
- *
|
||||
- * TX SGL: AAD || PT
|
||||
- * | |
|
||||
- * | copy |
|
||||
- * v v
|
||||
- * RX SGL: AAD || PT || Tag
|
||||
- */
|
||||
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
|
||||
- areq->first_rsgl.sgl.sg, processed);
|
||||
- if (err)
|
||||
- goto free;
|
||||
- af_alg_pull_tsgl(sk, processed, NULL, 0);
|
||||
- } else {
|
||||
- /*
|
||||
- * Decryption operation - To achieve an in-place cipher
|
||||
- * operation, the following SGL structure is used:
|
||||
- *
|
||||
- * TX SGL: AAD || CT || Tag
|
||||
- * | | ^
|
||||
- * | copy | | Create SGL link.
|
||||
- * v v |
|
||||
- * RX SGL: AAD || CT ----+
|
||||
- */
|
||||
-
|
||||
- /* Copy AAD || CT to RX SGL buffer for in-place operation. */
|
||||
- err = crypto_aead_copy_sgl(null_tfm, tsgl_src,
|
||||
- areq->first_rsgl.sgl.sg, outlen);
|
||||
- if (err)
|
||||
- goto free;
|
||||
-
|
||||
- /* Create TX SGL for tag and chain it to RX SGL. */
|
||||
- areq->tsgl_entries = af_alg_count_tsgl(sk, processed,
|
||||
- processed - as);
|
||||
- if (!areq->tsgl_entries)
|
||||
- areq->tsgl_entries = 1;
|
||||
- areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
|
||||
- areq->tsgl_entries),
|
||||
- GFP_KERNEL);
|
||||
- if (!areq->tsgl) {
|
||||
- err = -ENOMEM;
|
||||
- goto free;
|
||||
- }
|
||||
- sg_init_table(areq->tsgl, areq->tsgl_entries);
|
||||
-
|
||||
- /* Release TX SGL, except for tag data and reassign tag data. */
|
||||
- af_alg_pull_tsgl(sk, processed, areq->tsgl, processed - as);
|
||||
-
|
||||
- /* chain the areq TX SGL holding the tag with RX SGL */
|
||||
- if (usedpages) {
|
||||
- /* RX SGL present */
|
||||
- struct af_alg_sgl *sgl_prev = &areq->last_rsgl->sgl;
|
||||
-
|
||||
- sg_unmark_end(sgl_prev->sg + sgl_prev->npages - 1);
|
||||
- sg_chain(sgl_prev->sg, sgl_prev->npages + 1,
|
||||
- areq->tsgl);
|
||||
- } else
|
||||
- /* no RX SGL present (e.g. authentication only) */
|
||||
- rsgl_src = areq->tsgl;
|
||||
- }
|
||||
+ err = crypto_aead_copy_sgl(null_tfm, tsgl_src, rsgl_src,
|
||||
+ ctx->aead_assoclen);
|
||||
+ if (err)
|
||||
+ goto free;
|
||||
|
||||
/* Initialize the crypto operation */
|
||||
- aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
|
||||
+ aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
|
||||
areq->first_rsgl.sgl.sg, used, ctx->iv);
|
||||
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
|
||||
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
|
||||
@@ -526,7 +463,7 @@ static void aead_sock_destruct(struct sock *sk)
|
||||
struct crypto_aead *tfm = aeadc->aead;
|
||||
unsigned int ivlen = crypto_aead_ivsize(tfm);
|
||||
|
||||
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
|
||||
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
|
||||
sock_kzfree_s(sk, ctx->iv, ivlen);
|
||||
sock_kfree_s(sk, ctx, ctx->len);
|
||||
af_alg_release_parent(sk);
|
||||
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
|
||||
index ee8890ee8f33..8b314260929f 100644
|
||||
--- a/crypto/algif_skcipher.c
|
||||
+++ b/crypto/algif_skcipher.c
|
||||
@@ -89,7 +89,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
* Create a per request TX SGL for this request which tracks the
|
||||
* SG entries from the global TX SGL.
|
||||
*/
|
||||
- areq->tsgl_entries = af_alg_count_tsgl(sk, len, 0);
|
||||
+ areq->tsgl_entries = af_alg_count_tsgl(sk, len);
|
||||
if (!areq->tsgl_entries)
|
||||
areq->tsgl_entries = 1;
|
||||
areq->tsgl = sock_kmalloc(sk, array_size(sizeof(*areq->tsgl),
|
||||
@@ -100,7 +100,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
goto free;
|
||||
}
|
||||
sg_init_table(areq->tsgl, areq->tsgl_entries);
|
||||
- af_alg_pull_tsgl(sk, len, areq->tsgl, 0);
|
||||
+ af_alg_pull_tsgl(sk, len, areq->tsgl);
|
||||
|
||||
/* Initialize the crypto operation */
|
||||
skcipher_request_set_tfm(&areq->cra_u.skcipher_req, tfm);
|
||||
@@ -313,7 +313,7 @@ static void skcipher_sock_destruct(struct sock *sk)
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct crypto_skcipher *tfm = pask->private;
|
||||
|
||||
- af_alg_pull_tsgl(sk, ctx->used, NULL, 0);
|
||||
+ af_alg_pull_tsgl(sk, ctx->used, NULL);
|
||||
sock_kzfree_s(sk, ctx->iv, crypto_skcipher_ivsize(tfm));
|
||||
sock_kfree_s(sk, ctx, ctx->len);
|
||||
af_alg_release_parent(sk);
|
||||
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
|
||||
index 249e6bbf5cb2..f18a4ca6f07c 100644
|
||||
--- a/include/crypto/if_alg.h
|
||||
+++ b/include/crypto/if_alg.h
|
||||
@@ -226,9 +226,8 @@ static inline bool af_alg_readable(struct sock *sk)
|
||||
return PAGE_SIZE <= af_alg_rcvbuf(sk);
|
||||
}
|
||||
|
||||
-unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset);
|
||||
-void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
|
||||
- size_t dst_offset);
|
||||
+unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes);
|
||||
+void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst);
|
||||
void af_alg_wmem_wakeup(struct sock *sk);
|
||||
int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min);
|
||||
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
From 40240fa36eae2ed097d9191cfa568fcc702472b6 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Fri, 1 May 2026 21:54:01 +0800
|
||||
Subject: [PATCH] crypto: af_alg - limit RX SG extraction by receive buffer
|
||||
budget
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
CVE: CVE-2026-31677
|
||||
|
||||
Upstream Status: 8eceab19eba9dcbfd2a0daec72e1bf48aa100170
|
||||
|
||||
commit 8eceab19eba9dcbfd2a0daec72e1bf48aa100170
|
||||
Author: Douya Le <ldy3087146292@gmail.com>
|
||||
Date: Thu Apr 2 23:34:55 2026 +0800
|
||||
|
||||
crypto: af_alg - limit RX SG extraction by receive buffer budget
|
||||
|
||||
Make af_alg_get_rsgl() limit each RX scatterlist extraction to the
|
||||
remaining receive buffer budget.
|
||||
|
||||
af_alg_get_rsgl() currently uses af_alg_readable() only as a gate
|
||||
before extracting data into the RX scatterlist. Limit each extraction
|
||||
to the remaining af_alg_rcvbuf(sk) budget so that receive-side
|
||||
accounting matches the amount of data attached to the request.
|
||||
|
||||
If skcipher cannot obtain enough RX space for at least one chunk while
|
||||
more data remains to be processed, reject the recvmsg call instead of
|
||||
rounding the request length down to zero.
|
||||
|
||||
Fixes: e870456d8e7c8d57c059ea479b5aadbb55ff4c3a ("crypto: algif_skcipher - overhaul memory management")
|
||||
Reported-by: Yifan Wu <yifanwucs@gmail.com>
|
||||
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
|
||||
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
|
||||
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
|
||||
Suggested-by: Xin Liu <bird@lzu.edu.cn>
|
||||
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
|
||||
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
|
||||
index 45a058ca890a..450869efc079 100644
|
||||
--- a/crypto/af_alg.c
|
||||
+++ b/crypto/af_alg.c
|
||||
@@ -1135,6 +1135,8 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
|
||||
|
||||
seglen = min_t(size_t, (maxsize - len),
|
||||
msg_data_left(msg));
|
||||
+ /* Never pin more pages than the remaining RX accounting budget. */
|
||||
+ seglen = min_t(size_t, seglen, af_alg_rcvbuf(sk));
|
||||
|
||||
if (list_empty(&areq->rsgl_list)) {
|
||||
rsgl = &areq->first_rsgl;
|
||||
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
|
||||
index 8b314260929f..edbdc19cdb31 100644
|
||||
--- a/crypto/algif_skcipher.c
|
||||
+++ b/crypto/algif_skcipher.c
|
||||
@@ -82,8 +82,14 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
* If more buffers are to be expected to be processed, process only
|
||||
* full block size buffers.
|
||||
*/
|
||||
- if (ctx->more || len < ctx->used)
|
||||
+ if (ctx->more || len < ctx->used) {
|
||||
+ if (len < bs) {
|
||||
+ err = -EINVAL;
|
||||
+ goto free;
|
||||
+ }
|
||||
+
|
||||
len -= len % bs;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Create a per request TX SGL for this request which tracks the
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From 9e1c6ad59b9a5d325cda7cf7860d1442a1121c34 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 20:10:09 +0800
|
||||
Subject: [PATCH] crypto: af_alg - Fix page reassignment overflow in
|
||||
af_alg_pull_tsgl
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
|
||||
Upstream Status: 31d00156e50ecad37f2cb6cbf04aaa9a260505ef
|
||||
|
||||
commit 31d00156e50ecad37f2cb6cbf04aaa9a260505ef
|
||||
Author: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Sat Apr 4 08:29:58 2026 +0800
|
||||
|
||||
crypto: af_alg - Fix page reassignment overflow in af_alg_pull_tsgl
|
||||
|
||||
When page reassignment was added to af_alg_pull_tsgl the original
|
||||
loop wasn't updated so it may try to reassign one more page than
|
||||
necessary.
|
||||
|
||||
Add the check to the reassignment so that this does not happen.
|
||||
|
||||
Also update the comment which still refers to the obsolete offset
|
||||
argument.
|
||||
|
||||
Reported-by: syzbot+d23888375c2737c17ba5@syzkaller.appspotmail.com
|
||||
Fixes: e870456d8e7c ("crypto: algif_skcipher - overhaul memory management")
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
|
||||
index 450869efc079..567e9f234ba3 100644
|
||||
--- a/crypto/af_alg.c
|
||||
+++ b/crypto/af_alg.c
|
||||
@@ -595,8 +595,8 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst)
|
||||
* Assumption: caller created af_alg_count_tsgl(len)
|
||||
* SG entries in dst.
|
||||
*/
|
||||
- if (dst) {
|
||||
- /* reassign page to dst after offset */
|
||||
+ if (dst && plen) {
|
||||
+ /* reassign page to dst */
|
||||
get_page(page);
|
||||
sg_set_page(dst + j, page, plen, sg[i].offset);
|
||||
j++;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
From 3d6c89a117ab9fce6fa8240ad5b45bcd48f6d751 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Fri, 1 May 2026 21:54:32 +0800
|
||||
Subject: [PATCH] crypto: authencesn - reject too-short AAD (assoclen<8) to
|
||||
match ESP/ESN spec
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
CVE: CVE-2026-23060
|
||||
|
||||
Upstream Status: 2397e9264676be7794f8f7f1e9763d90bd3c7335
|
||||
|
||||
commit 2397e9264676be7794f8f7f1e9763d90bd3c7335
|
||||
Author: Taeyang Lee <0wn@theori.io>
|
||||
Date: Fri Jan 16 16:03:58 2026 +0900
|
||||
|
||||
crypto: authencesn - reject too-short AAD (assoclen<8) to match ESP/ESN spec
|
||||
|
||||
authencesn assumes an ESP/ESN-formatted AAD. When assoclen is shorter than
|
||||
the minimum expected length, crypto_authenc_esn_decrypt() can advance past
|
||||
the end of the destination scatterlist and trigger a NULL pointer dereference
|
||||
in scatterwalk_map_and_copy(), leading to a kernel panic (DoS).
|
||||
|
||||
Add a minimum AAD length check to fail fast on invalid inputs.
|
||||
|
||||
Fixes: 104880a6b470 ("crypto: authencesn - Convert to new AEAD interface")
|
||||
Reported-By: Taeyang Lee <0wn@theori.io>
|
||||
Signed-off-by: Taeyang Lee <0wn@theori.io>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
|
||||
index b60e61b1904c..6487b35851d5 100644
|
||||
--- a/crypto/authencesn.c
|
||||
+++ b/crypto/authencesn.c
|
||||
@@ -191,6 +191,9 @@ static int crypto_authenc_esn_encrypt(struct aead_request *req)
|
||||
struct scatterlist *src, *dst;
|
||||
int err;
|
||||
|
||||
+ if (assoclen < 8)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
sg_init_table(areq_ctx->src, 2);
|
||||
src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen);
|
||||
dst = src;
|
||||
@@ -284,6 +287,9 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
|
||||
u32 tmp[2];
|
||||
int err;
|
||||
|
||||
+ if (assoclen < 8)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
cryptlen -= authsize;
|
||||
|
||||
if (req->src != dst) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,172 @@
|
||||
From 4a2446436fe796a1b8cef89e30f54c2c295943fe Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 20:16:25 +0800
|
||||
Subject: [PATCH] crypto: authencesn - Do not place hiseq at end of dst for
|
||||
out-of-place decryption
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
CVE: CVE-2026-31431
|
||||
|
||||
Upstream Status: e02494114ebf7c8b42777c6cd6982f113bfdbec7
|
||||
|
||||
commit e02494114ebf7c8b42777c6cd6982f113bfdbec7
|
||||
Author: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Fri Mar 27 15:04:17 2026 +0900
|
||||
|
||||
crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption
|
||||
|
||||
When decrypting data that is not in-place (src != dst), there is
|
||||
no need to save the high-order sequence bits in dst as it could
|
||||
simply be re-copied from the source.
|
||||
|
||||
However, the data to be hashed need to be rearranged accordingly.
|
||||
|
||||
Reported-by: Taeyang Lee <0wn@theori.io>
|
||||
Fixes: 104880a6b470 ("crypto: authencesn - Convert to new AEAD interface")
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Thanks,
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
|
||||
index 6487b35851d5..8664dad45792 100644
|
||||
--- a/crypto/authencesn.c
|
||||
+++ b/crypto/authencesn.c
|
||||
@@ -164,7 +164,10 @@ static void crypto_authenc_esn_encrypt_done(struct crypto_async_request *req,
|
||||
authenc_esn_request_complete(areq, err);
|
||||
}
|
||||
|
||||
-static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
|
||||
+static int crypto_authenc_esn_copy_sg(struct aead_request *req,
|
||||
+ struct scatterlist *src,
|
||||
+ struct scatterlist *dst,
|
||||
+ unsigned int len)
|
||||
{
|
||||
struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
|
||||
struct crypto_authenc_esn_ctx *ctx = crypto_aead_ctx(authenc_esn);
|
||||
@@ -173,11 +176,16 @@ static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
|
||||
skcipher_request_set_sync_tfm(skreq, ctx->null);
|
||||
skcipher_request_set_callback(skreq, aead_request_flags(req),
|
||||
NULL, NULL);
|
||||
- skcipher_request_set_crypt(skreq, req->src, req->dst, len, NULL);
|
||||
+ skcipher_request_set_crypt(skreq, src, dst, len, NULL);
|
||||
|
||||
return crypto_skcipher_encrypt(skreq);
|
||||
}
|
||||
|
||||
+static int crypto_authenc_esn_copy(struct aead_request *req, unsigned int len)
|
||||
+{
|
||||
+ return crypto_authenc_esn_copy_sg(req, req->src, req->dst, len);
|
||||
+}
|
||||
+
|
||||
static int crypto_authenc_esn_encrypt(struct aead_request *req)
|
||||
{
|
||||
struct crypto_aead *authenc_esn = crypto_aead_reqtfm(req);
|
||||
@@ -233,30 +241,39 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
|
||||
crypto_ahash_alignmask(auth) + 1);
|
||||
unsigned int cryptlen = req->cryptlen - authsize;
|
||||
unsigned int assoclen = req->assoclen;
|
||||
+ struct scatterlist *src = req->src;
|
||||
struct scatterlist *dst = req->dst;
|
||||
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
|
||||
u32 tmp[2];
|
||||
+ int err;
|
||||
|
||||
if (!authsize)
|
||||
goto decrypt;
|
||||
|
||||
- /* Move high-order bits of sequence number back. */
|
||||
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
|
||||
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
|
||||
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
|
||||
+ if (src == dst) {
|
||||
+ /* Move high-order bits of sequence number back. */
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
|
||||
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 0, 8, 1);
|
||||
+ } else {
|
||||
+ err = crypto_authenc_esn_copy(req, assoclen);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
if (crypto_memneq(ihash, ohash, authsize))
|
||||
return -EBADMSG;
|
||||
|
||||
decrypt:
|
||||
|
||||
- sg_init_table(areq_ctx->dst, 2);
|
||||
+ if (src != dst)
|
||||
+ src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
|
||||
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
|
||||
|
||||
skcipher_request_set_tfm(skreq, ctx->enc);
|
||||
skcipher_request_set_callback(skreq, flags,
|
||||
req->base.complete, req->base.data);
|
||||
- skcipher_request_set_crypt(skreq, dst, dst, cryptlen, req->iv);
|
||||
+ skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
|
||||
|
||||
return crypto_skcipher_decrypt(skreq);
|
||||
}
|
||||
@@ -283,6 +300,7 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
|
||||
unsigned int assoclen = req->assoclen;
|
||||
unsigned int cryptlen = req->cryptlen;
|
||||
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
|
||||
+ struct scatterlist *src = req->src;
|
||||
struct scatterlist *dst = req->dst;
|
||||
u32 tmp[2];
|
||||
int err;
|
||||
@@ -290,27 +308,31 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
|
||||
if (assoclen < 8)
|
||||
return -EINVAL;
|
||||
|
||||
- cryptlen -= authsize;
|
||||
-
|
||||
- if (req->src != dst) {
|
||||
- err = crypto_authenc_esn_copy(req, assoclen + cryptlen);
|
||||
- if (err)
|
||||
- return err;
|
||||
- }
|
||||
+ if (!authsize)
|
||||
+ goto tail;
|
||||
|
||||
+ cryptlen -= authsize;
|
||||
scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
- if (!authsize)
|
||||
- goto tail;
|
||||
-
|
||||
/* Move high-order bits of sequence number to the end. */
|
||||
- scatterwalk_map_and_copy(tmp, dst, 0, 8, 0);
|
||||
- scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
|
||||
- scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
|
||||
-
|
||||
- sg_init_table(areq_ctx->dst, 2);
|
||||
- dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
|
||||
+ scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
|
||||
+ if (src == dst) {
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 4, 4, 1);
|
||||
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
|
||||
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
|
||||
+ } else {
|
||||
+ scatterwalk_map_and_copy(tmp, dst, 0, 4, 1);
|
||||
+ scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1);
|
||||
+
|
||||
+ src = scatterwalk_ffwd(areq_ctx->src, src, 8);
|
||||
+ dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4);
|
||||
+ err = crypto_authenc_esn_copy_sg(req, src, dst,
|
||||
+ assoclen + cryptlen - 8);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ dst = req->dst;
|
||||
+ }
|
||||
|
||||
ahash_request_set_tfm(ahreq, auth);
|
||||
ahash_request_set_crypt(ahreq, dst, ohash, assoclen + cryptlen);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From 37dc4d521edd3990b54849381ea8a82ee5f8bdc5 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 19:56:24 +0800
|
||||
Subject: [PATCH] crypto: authencesn - Fix src offset when decrypting in-place
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
|
||||
Upstream Status: 1f48ad3b19a9dfc947868edda0bb8e48e5b5a8fa
|
||||
|
||||
commit 1f48ad3b19a9dfc947868edda0bb8e48e5b5a8fa
|
||||
Author: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Wed Apr 15 07:39:06 2026 +0800
|
||||
|
||||
crypto: authencesn - Fix src offset when decrypting in-place
|
||||
|
||||
The src SG list offset wasn't set properly when decrypting in-place,
|
||||
fix it.
|
||||
|
||||
Reported-by: Wolfgang Walter <linux@stwm.de>
|
||||
Fixes: e02494114ebf ("crypto: authencesn - Do not place hiseq at end of dst for out-of-place decryption")
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
|
||||
index 8664dad45792..9a586b0b7716 100644
|
||||
--- a/crypto/authencesn.c
|
||||
+++ b/crypto/authencesn.c
|
||||
@@ -266,9 +266,11 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
|
||||
|
||||
decrypt:
|
||||
|
||||
- if (src != dst)
|
||||
- src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
|
||||
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
|
||||
+ if (req->src == req->dst)
|
||||
+ src = dst;
|
||||
+ else
|
||||
+ src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
|
||||
|
||||
skcipher_request_set_tfm(skreq, ctx->enc);
|
||||
skcipher_request_set_callback(skreq, flags,
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 18fe1da8a470fbfaf19071dac3e9f43a61bd2ec9 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 20:02:19 +0800
|
||||
Subject: [PATCH] crypto: authencesn - reject short ahash digests during
|
||||
instance creation
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
|
||||
Upstream Status: cryptodev
|
||||
|
||||
commit 5db6ef9847717329f12c5ea8aba7e9f588a980c0
|
||||
Author: Yucheng Lu <kanolyc@gmail.com>
|
||||
Date: Wed Apr 22 21:45:04 2026 +0800
|
||||
|
||||
crypto: authencesn - reject short ahash digests during instance creation
|
||||
|
||||
authencesn requires either a zero authsize or an authsize of at least
|
||||
4 bytes because the ESN encrypt/decrypt paths always move 4 bytes of
|
||||
high-order sequence number data at the end of the authenticated data.
|
||||
|
||||
While crypto_authenc_esn_setauthsize() already rejects explicit
|
||||
non-zero authsizes in the range 1..3, crypto_authenc_esn_create()
|
||||
still copied auth->digestsize into inst->alg.maxauthsize without
|
||||
validating it. The AEAD core then initialized the tfm's default
|
||||
authsize from that value.
|
||||
|
||||
As a result, selecting an ahash with digest size 1..3, such as
|
||||
cbcmac(cipher_null), exposed authencesn instances whose default
|
||||
authsize was invalid even though setauthsize() would have rejected the
|
||||
same value. AF_ALG could then trigger the ESN tail handling with a
|
||||
too-short tag and hit an out-of-bounds access.
|
||||
|
||||
Reject authencesn instances whose ahash digest size is in the invalid
|
||||
non-zero range 1..3 so that no tfm can inherit an unsupported default
|
||||
authsize.
|
||||
|
||||
Fixes: f15f05b0a5de ("crypto: ccm - switch to separate cbcmac driver")
|
||||
Cc: stable@kernel.org
|
||||
Reported-by: Yifan Wu <yifanwucs@gmail.com>
|
||||
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
|
||||
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
|
||||
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
|
||||
Suggested-by: Xin Liu <bird@lzu.edu.cn>
|
||||
Tested-by: Yuhang Zheng <z1652074432@gmail.com>
|
||||
Reviewed-by: Eric Biggers <ebiggers@kernel.org>
|
||||
Signed-off-by: Yucheng Lu <kanolyc@gmail.com>
|
||||
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
|
||||
index 9a586b0b7716..b0f40fe03b56 100644
|
||||
--- a/crypto/authencesn.c
|
||||
+++ b/crypto/authencesn.c
|
||||
@@ -444,6 +444,11 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
|
||||
auth = crypto_spawn_ahash_alg(&ctx->auth);
|
||||
auth_base = &auth->base;
|
||||
|
||||
+ if (auth->digestsize > 0 && auth->digestsize < 4) {
|
||||
+ err = -EINVAL;
|
||||
+ goto err_free_inst;
|
||||
+ }
|
||||
+
|
||||
err = crypto_grab_skcipher(&ctx->enc, aead_crypto_instance(inst),
|
||||
crypto_attr_alg_name(tb[2]), 0, mask);
|
||||
if (err)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From 834916d950469022e266fb8667df2c17af47df94 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Fri, 1 May 2026 21:56:44 +0800
|
||||
Subject: [PATCH] crypto: algif_aead - Fix minimum RX size check for decryption
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
|
||||
Upstream Status: 3d14bd48e3a77091cbce637a12c2ae31b4a1687c
|
||||
|
||||
commit 3d14bd48e3a77091cbce637a12c2ae31b4a1687c
|
||||
Author: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Date: Sun Apr 12 13:32:21 2026 +0800
|
||||
|
||||
crypto: algif_aead - Fix minimum RX size check for decryption
|
||||
|
||||
The check for the minimum receive buffer size did not take the
|
||||
tag size into account during decryption. Fix this by adding the
|
||||
required extra length.
|
||||
|
||||
Reported-by: syzbot+aa11561819dc42ebbc7c@syzkaller.appspotmail.com
|
||||
Reported-by: Daniel Pouzzner <douzzer@mega.nu>
|
||||
Fixes: d887c52d6ae4 ("crypto: algif_aead - overhaul memory management")
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
|
||||
index 4a6a0bb1ae3c..029f1bd72fd7 100644
|
||||
--- a/crypto/algif_aead.c
|
||||
+++ b/crypto/algif_aead.c
|
||||
@@ -169,7 +169,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
if (usedpages < outlen) {
|
||||
size_t less = outlen - usedpages;
|
||||
|
||||
- if (used < less) {
|
||||
+ if (used < less + (ctx->enc ? 0 : as)) {
|
||||
err = -EINVAL;
|
||||
goto free;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
From 39335f1f582fbe7006ab1d9c83f0957324ad0367 Mon Sep 17 00:00:00 2001
|
||||
From: Herbert Xu <herbert.xu@redhat.com>
|
||||
Date: Thu, 30 Apr 2026 20:03:29 +0800
|
||||
Subject: [PATCH] crypto: algif_aead - snapshot IV for async AEAD requests
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172207
|
||||
|
||||
Upstream Status: 5aa58c3a572b3e3b6c786953339f7978b845cc52
|
||||
|
||||
commit 5aa58c3a572b3e3b6c786953339f7978b845cc52
|
||||
Author: Douya Le <ldy3087146292@gmail.com>
|
||||
Date: Sun Apr 19 16:52:59 2026 +0800
|
||||
|
||||
crypto: algif_aead - snapshot IV for async AEAD requests
|
||||
|
||||
AF_ALG AEAD AIO requests currently use the socket-wide IV buffer during
|
||||
request processing. For async requests, later socket activity can
|
||||
update that shared state before the original request has fully
|
||||
completed, which can lead to inconsistent IV handling.
|
||||
|
||||
Snapshot the IV into per-request storage when preparing the AEAD
|
||||
request, so in-flight operations no longer depend on mutable socket
|
||||
state.
|
||||
|
||||
Fixes: d887c52d6ae4 ("crypto: algif_aead - overhaul memory management")
|
||||
Cc: stable@kernel.org
|
||||
Reported-by: Yuan Tan <yuantan098@gmail.com>
|
||||
Reported-by: Yifan Wu <yifanwucs@gmail.com>
|
||||
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
|
||||
Reported-by: Xin Liu <bird@lzu.edu.cn>
|
||||
Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
|
||||
Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
|
||||
Tested-by: Yucheng Lu <kanolyc@gmail.com>
|
||||
Signed-off-by: Douya Le <ldy3087146292@gmail.com>
|
||||
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
|
||||
Signed-off-by: Herbert Xu <herbert.xu@redhat.com>
|
||||
|
||||
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
|
||||
index 029f1bd72fd7..9b589ab1af20 100644
|
||||
--- a/crypto/algif_aead.c
|
||||
+++ b/crypto/algif_aead.c
|
||||
@@ -97,8 +97,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
struct crypto_aead *tfm = aeadc->aead;
|
||||
struct crypto_sync_skcipher *null_tfm = aeadc->null_tfm;
|
||||
unsigned int as = crypto_aead_authsize(tfm);
|
||||
+ unsigned int ivsize = crypto_aead_ivsize(tfm);
|
||||
struct af_alg_async_req *areq;
|
||||
struct scatterlist *rsgl_src, *tsgl_src = NULL;
|
||||
+ void *iv;
|
||||
int err = 0;
|
||||
size_t used = 0; /* [in] TX bufs to be en/decrypted */
|
||||
size_t outlen = 0; /* [out] RX bufs produced by kernel */
|
||||
@@ -150,10 +152,14 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
|
||||
/* Allocate cipher request for current operation. */
|
||||
areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
|
||||
- crypto_aead_reqsize(tfm));
|
||||
+ crypto_aead_reqsize(tfm) + ivsize);
|
||||
if (IS_ERR(areq))
|
||||
return PTR_ERR(areq);
|
||||
|
||||
+ iv = (u8 *)aead_request_ctx(&areq->cra_u.aead_req) +
|
||||
+ crypto_aead_reqsize(tfm);
|
||||
+ memcpy(iv, ctx->iv, ivsize);
|
||||
+
|
||||
/* convert iovecs of output buffers into RX SGL */
|
||||
err = af_alg_get_rsgl(sk, msg, flags, areq, outlen, &usedpages);
|
||||
if (err)
|
||||
@@ -215,7 +221,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
|
||||
/* Initialize the crypto operation */
|
||||
aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
|
||||
- areq->first_rsgl.sgl.sg, used, ctx->iv);
|
||||
+ areq->first_rsgl.sgl.sg, used, iv);
|
||||
aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
|
||||
aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
From 52a21cfbdbc63d33544aafaa89e3ac9571268065 Mon Sep 17 00:00:00 2001
|
||||
From: Sabrina Dubroca <sdubroca@redhat.com>
|
||||
Date: Fri, 8 May 2026 00:56:43 +0200
|
||||
Subject: [PATCH] xfrm: esp: avoid in-place decrypt on shared skb frags
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-174565
|
||||
CVE: CVE-2026-43284
|
||||
Conflicts: rhel9 doesn't use MSG_SPLICE_PAGES in
|
||||
sendmsg/ip_append_data
|
||||
patch udp_sendpage/ip_append_page instead
|
||||
nothing to do for ipv6, no .sendpage for UDP there
|
||||
|
||||
commit f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4
|
||||
Author: Kuan-Ting Chen <h3xrabbit@gmail.com>
|
||||
Date: Mon May 4 23:27:12 2026 +0800
|
||||
|
||||
xfrm: esp: avoid in-place decrypt on shared skb frags
|
||||
|
||||
MSG_SPLICE_PAGES can attach pages from a pipe directly to an skb. TCP
|
||||
marks such skbs with SKBFL_SHARED_FRAG after skb_splice_from_iter(),
|
||||
so later paths that may modify packet data can first make a private
|
||||
copy. The IPv4/IPv6 datagram append paths did not set this flag when
|
||||
splicing pages into UDP skbs.
|
||||
|
||||
That leaves an ESP-in-UDP packet made from shared pipe pages looking
|
||||
like an ordinary uncloned nonlinear skb. ESP input then takes the no-COW
|
||||
fast path for uncloned skbs without a frag_list and decrypts in place
|
||||
over data that is not owned privately by the skb.
|
||||
|
||||
Mark IPv4/IPv6 datagram splice frags with SKBFL_SHARED_FRAG, matching
|
||||
TCP. Also make ESP input fall back to skb_cow_data() when the flag is
|
||||
present, so ESP does not decrypt externally backed frags in place.
|
||||
Private nonlinear skb frags still use the existing fast path.
|
||||
|
||||
This intentionally does not change ESP output. In esp_output_head(),
|
||||
the path that appends the ESP trailer to existing skb tailroom without
|
||||
calling skb_cow_data() is not reachable for nonlinear skbs:
|
||||
skb_tailroom() returns zero when skb->data_len is nonzero, while ESP
|
||||
tailen is positive. Thus ESP output will either use the separate
|
||||
destination-frag path or fall back to skb_cow_data().
|
||||
|
||||
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
|
||||
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
|
||||
Fixes: 7da0dde68486 ("ip, udp: Support MSG_SPLICE_PAGES")
|
||||
Fixes: 6d8192bd69bb ("ip6, udp6: Support MSG_SPLICE_PAGES")
|
||||
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
|
||||
Reported-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
|
||||
Tested-by: Hyunwoo Kim <imv4bel@gmail.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
|
||||
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
|
||||
|
||||
Signed-off-by: Sabrina Dubroca <sdubroca@redhat.com>
|
||||
|
||||
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
|
||||
index 4d07a51fa9a0..8ff8489bbf37 100644
|
||||
--- a/net/ipv4/esp4.c
|
||||
+++ b/net/ipv4/esp4.c
|
||||
@@ -881,7 +881,8 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
nfrags = 1;
|
||||
|
||||
goto skip_cow;
|
||||
- } else if (!skb_has_frag_list(skb)) {
|
||||
+ } else if (!skb_has_frag_list(skb) &&
|
||||
+ !skb_has_shared_frag(skb)) {
|
||||
nfrags = skb_shinfo(skb)->nr_frags;
|
||||
nfrags++;
|
||||
|
||||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
|
||||
index ec48d434acca..9c000e0ceb39 100644
|
||||
--- a/net/ipv4/ip_output.c
|
||||
+++ b/net/ipv4/ip_output.c
|
||||
@@ -1480,6 +1480,9 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
|
||||
goto error;
|
||||
}
|
||||
|
||||
+ if (!(flags & MSG_NO_SHARED_FRAGS))
|
||||
+ skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
|
||||
+
|
||||
if (skb->ip_summed == CHECKSUM_NONE) {
|
||||
__wsum csum;
|
||||
csum = csum_page(page, offset, len);
|
||||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
|
||||
index 07565986cf82..7e17e9e1a33b 100644
|
||||
--- a/net/ipv6/esp6.c
|
||||
+++ b/net/ipv6/esp6.c
|
||||
@@ -921,7 +921,8 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
nfrags = 1;
|
||||
|
||||
goto skip_cow;
|
||||
- } else if (!skb_has_frag_list(skb)) {
|
||||
+ } else if (!skb_has_frag_list(skb) &&
|
||||
+ !skb_has_shared_frag(skb)) {
|
||||
nfrags = skb_shinfo(skb)->nr_frags;
|
||||
nfrags++;
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From a535a9217ca3f2fccedaafb2fddb4c48f27d36dc Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Page <sam@bynar.io>
|
||||
Date: Wed, 8 Apr 2026 15:30:13 +0100
|
||||
Subject: [PATCH] can: raw: fix ro->uniq use-after-free in raw_rcv()
|
||||
|
||||
raw_release() unregisters raw CAN receive filters via can_rx_unregister(),
|
||||
but receiver deletion is deferred with call_rcu(). This leaves a window
|
||||
where raw_rcv() may still be running in an RCU read-side critical section
|
||||
after raw_release() frees ro->uniq, leading to a use-after-free of the
|
||||
percpu uniq storage.
|
||||
|
||||
Move free_percpu(ro->uniq) out of raw_release() and into a raw-specific
|
||||
socket destructor. can_rx_unregister() takes an extra reference to the
|
||||
socket and only drops it from the RCU callback, so freeing uniq from
|
||||
sk_destruct ensures the percpu area is not released until the relevant
|
||||
callbacks have drained.
|
||||
|
||||
Fixes: 514ac99c64b2 ("can: fix multiple delivery of a single CAN frame for overlapping CAN filters")
|
||||
Cc: stable@vger.kernel.org # v4.1+
|
||||
Assisted-by: Bynario AI
|
||||
Signed-off-by: Samuel Page <sam@bynar.io>
|
||||
Link: https://patch.msgid.link/26ec626d-cae7-4418-9782-7198864d070c@bynar.io
|
||||
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
|
||||
[mkl: applied manually]
|
||||
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
diff --git a/net/can/raw.c b/net/can/raw.c
|
||||
index eee244ffc31e..58a96e933deb 100644
|
||||
--- a/net/can/raw.c
|
||||
+++ b/net/can/raw.c
|
||||
@@ -361,6 +361,14 @@ static int raw_notifier(struct notifier_block *nb, unsigned long msg,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
+static void raw_sock_destruct(struct sock *sk)
|
||||
+{
|
||||
+ struct raw_sock *ro = raw_sk(sk);
|
||||
+
|
||||
+ free_percpu(ro->uniq);
|
||||
+ can_sock_destruct(sk);
|
||||
+}
|
||||
+
|
||||
static int raw_init(struct sock *sk)
|
||||
{
|
||||
struct raw_sock *ro = raw_sk(sk);
|
||||
@@ -387,6 +395,8 @@ static int raw_init(struct sock *sk)
|
||||
if (unlikely(!ro->uniq))
|
||||
return -ENOMEM;
|
||||
|
||||
+ sk->sk_destruct = raw_sock_destruct;
|
||||
+
|
||||
/* set notifier */
|
||||
spin_lock(&raw_notifier_lock);
|
||||
list_add_tail(&ro->notifier, &raw_notifier_list);
|
||||
@@ -436,7 +446,6 @@ static int raw_release(struct socket *sock)
|
||||
ro->bound = 0;
|
||||
ro->dev = NULL;
|
||||
ro->count = 0;
|
||||
- free_percpu(ro->uniq);
|
||||
|
||||
sock_orphan(sk);
|
||||
sock->sk = NULL;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
From 98551d7729dace772c045e8696df06ba532d4088 Mon Sep 17 00:00:00 2001
|
||||
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 11:39:45 +0000
|
||||
Subject: [PATCH] usbip: validate number_of_packets in usbip_pack_ret_submit()
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-171433
|
||||
CVE: CVE-2026-31607
|
||||
|
||||
commit 2ab833a16a825373aad2ba7d54b572b277e95b71
|
||||
Author: Nathan Rebello <nathan.c.rebello@gmail.com>
|
||||
Date: Thu Apr 2 04:52:59 2026 -0400
|
||||
|
||||
usbip: validate number_of_packets in usbip_pack_ret_submit()
|
||||
|
||||
When a USB/IP client receives a RET_SUBMIT response,
|
||||
usbip_pack_ret_submit() unconditionally overwrites
|
||||
urb->number_of_packets from the network PDU. This value is
|
||||
subsequently used as the loop bound in usbip_recv_iso() and
|
||||
usbip_pad_iso() to iterate over urb->iso_frame_desc[], a flexible
|
||||
array whose size was fixed at URB allocation time based on the
|
||||
*original* number_of_packets from the CMD_SUBMIT.
|
||||
|
||||
A malicious USB/IP server can set number_of_packets in the response
|
||||
to a value larger than what was originally submitted, causing a heap
|
||||
out-of-bounds write when usbip_recv_iso() writes to
|
||||
urb->iso_frame_desc[i] beyond the allocated region.
|
||||
|
||||
KASAN confirmed this with kernel 7.0.0-rc5:
|
||||
|
||||
BUG: KASAN: slab-out-of-bounds in usbip_recv_iso+0x46a/0x640
|
||||
Write of size 4 at addr ffff888106351d40 by task vhci_rx/69
|
||||
|
||||
The buggy address is located 0 bytes to the right of
|
||||
allocated 320-byte region [ffff888106351c00, ffff888106351d40)
|
||||
|
||||
The server side (stub_rx.c) and gadget side (vudc_rx.c) already
|
||||
validate number_of_packets in the CMD_SUBMIT path since commits
|
||||
c6688ef9f297 ("usbip: fix stub_rx: harden CMD_SUBMIT path to handle
|
||||
malicious input") and b78d830f0049 ("usbip: fix vudc_rx: harden
|
||||
CMD_SUBMIT path to handle malicious input"). The server side validates
|
||||
against USBIP_MAX_ISO_PACKETS because no URB exists yet at that point.
|
||||
On the client side we have the original URB, so we can use the tighter
|
||||
bound: the response must not exceed the original number_of_packets.
|
||||
|
||||
This mirrors the existing validation of actual_length against
|
||||
transfer_buffer_length in usbip_recv_xbuff(), which checks the
|
||||
response value against the original allocation size.
|
||||
|
||||
Kelvin Mbogo's series ("usb: usbip: fix integer overflow in
|
||||
usbip_recv_iso()", v2) hardens the receive-side functions themselves;
|
||||
this patch complements that work by catching the bad value at its
|
||||
source -- in usbip_pack_ret_submit() before the overwrite -- and
|
||||
using the tighter per-URB allocation bound rather than the global
|
||||
USBIP_MAX_ISO_PACKETS limit.
|
||||
|
||||
Fix this by checking rpdu->number_of_packets against
|
||||
urb->number_of_packets in usbip_pack_ret_submit() before the
|
||||
overwrite. On violation, clamp to zero so that usbip_recv_iso() and
|
||||
usbip_pad_iso() safely return early.
|
||||
|
||||
Fixes: 1325f85fa49f ("staging: usbip: bugfix add number of packets for isochronous frames")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
|
||||
Signed-off-by: Nathan Rebello <nathan.c.rebello@gmail.com>
|
||||
Link: https://patch.msgid.link/20260402085259.234-1-nathan.c.rebello@gmail.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
|
||||
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
|
||||
index a2b2da1255dd..ba9e7c616e12 100644
|
||||
--- a/drivers/usb/usbip/usbip_common.c
|
||||
+++ b/drivers/usb/usbip/usbip_common.c
|
||||
@@ -470,6 +470,18 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb,
|
||||
urb->status = rpdu->status;
|
||||
urb->actual_length = rpdu->actual_length;
|
||||
urb->start_frame = rpdu->start_frame;
|
||||
+ /*
|
||||
+ * The number_of_packets field determines the length of
|
||||
+ * iso_frame_desc[], which is a flexible array allocated
|
||||
+ * at URB creation time. A response must never claim more
|
||||
+ * packets than originally submitted; doing so would cause
|
||||
+ * an out-of-bounds write in usbip_recv_iso() and
|
||||
+ * usbip_pad_iso(). Clamp to zero on violation so both
|
||||
+ * functions safely return early.
|
||||
+ */
|
||||
+ if (rpdu->number_of_packets < 0 ||
|
||||
+ rpdu->number_of_packets > urb->number_of_packets)
|
||||
+ rpdu->number_of_packets = 0;
|
||||
urb->number_of_packets = rpdu->number_of_packets;
|
||||
urb->error_count = rpdu->error_count;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From 31e26e3f09482329fb7f0fcf3893ed2dbb4e231a Mon Sep 17 00:00:00 2001
|
||||
From: Kamal Heib <kheib@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 13:24:19 -0400
|
||||
Subject: [PATCH] RDMA/umem: Fix double dma_buf_unpin in failure path
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-163491
|
||||
|
||||
commit 104016eb671e19709721c1b0048dd912dc2e96be
|
||||
Author: Jacob Moroni <jmoroni@google.com>
|
||||
Date: Tue Feb 24 23:41:53 2026 +0000
|
||||
|
||||
RDMA/umem: Fix double dma_buf_unpin in failure path
|
||||
|
||||
In ib_umem_dmabuf_get_pinned_with_dma_device(), the call to
|
||||
ib_umem_dmabuf_map_pages() can fail. If this occurs, the dmabuf
|
||||
is immediately unpinned but the umem_dmabuf->pinned flag is still
|
||||
set. Then, when ib_umem_release() is called, it calls
|
||||
ib_umem_dmabuf_revoke() which will call dma_buf_unpin() again.
|
||||
|
||||
Fix this by removing the immediate unpin upon failure and just let
|
||||
the ib_umem_release/revoke path handle it. This also ensures the
|
||||
proper unmap-unpin unwind ordering if the dmabuf_map_pages call
|
||||
happened to fail due to dma_resv_wait_timeout (and therefore has
|
||||
a non-NULL umem_dmabuf->sgt).
|
||||
|
||||
Fixes: 1e4df4a21c5a ("RDMA/umem: Allow pinned dmabuf umem usage")
|
||||
Signed-off-by: Jacob Moroni <jmoroni@google.com>
|
||||
Link: https://patch.msgid.link/20260224234153.1207849-1-jmoroni@google.com
|
||||
Signed-off-by: Leon Romanovsky <leon@kernel.org>
|
||||
|
||||
Signed-off-by: Kamal Heib <kheib@redhat.com>
|
||||
|
||||
diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
|
||||
index 2023a735de20..8d6430278000 100644
|
||||
--- a/drivers/infiniband/core/umem_dmabuf.c
|
||||
+++ b/drivers/infiniband/core/umem_dmabuf.c
|
||||
@@ -220,13 +220,11 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
|
||||
|
||||
err = ib_umem_dmabuf_map_pages(umem_dmabuf);
|
||||
if (err)
|
||||
- goto err_unpin;
|
||||
+ goto err_release;
|
||||
dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
|
||||
|
||||
return umem_dmabuf;
|
||||
|
||||
-err_unpin:
|
||||
- dma_buf_unpin(umem_dmabuf->attach);
|
||||
err_release:
|
||||
dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
|
||||
ib_umem_release(&umem_dmabuf->umem);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 43ed28eec61843c0cc821683028c70c9419a7b40 Mon Sep 17 00:00:00 2001
|
||||
From: Nigel Croxon <ncroxon@redhat.com>
|
||||
Date: Mon, 16 Feb 2026 13:50:16 -0500
|
||||
Subject: [PATCH] md/bitmap: fix GPF in write_page caused by resize race
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-129338
|
||||
|
||||
commit 46ef85f854dfa9d5226b3c1c46493d79556c9589
|
||||
Author: Jack Wang <jinpu.wang@ionos.com>
|
||||
Date: Tue Jan 20 11:24:56 2026 +0100
|
||||
|
||||
md/bitmap: fix GPF in write_page caused by resize race
|
||||
|
||||
A General Protection Fault occurs in write_page() during array resize:
|
||||
RIP: 0010:write_page+0x22b/0x3c0 [md_mod]
|
||||
|
||||
This is a use-after-free race between bitmap_daemon_work() and
|
||||
__bitmap_resize(). The daemon iterates over `bitmap->storage.filemap`
|
||||
without locking, while the resize path frees that storage via
|
||||
md_bitmap_file_unmap(). `quiesce()` does not stop the md thread,
|
||||
allowing concurrent access to freed pages.
|
||||
|
||||
Fix by holding `mddev->bitmap_info.mutex` during the bitmap update.
|
||||
|
||||
Link: https://lore.kernel.org/linux-raid/20260120102456.25169-1-jinpu.wang@ionos.com
|
||||
Closes: https://lore.kernel.org/linux-raid/CAMGffE=Mbfp=7xD_hYxXk1PAaCZNSEAVeQGKGy7YF9f2S4=NEA@mail.gmail.com/T/#u
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: d60b479d177a ("md/bitmap: add bitmap_resize function to allow bitmap resizing.")
|
||||
Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
|
||||
Signed-off-by: Yu Kuai <yukuai@fnnas.com>
|
||||
|
||||
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
|
||||
|
||||
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
|
||||
index 6280bae60526..3b86909a411e 100644
|
||||
--- a/drivers/md/md-bitmap.c
|
||||
+++ b/drivers/md/md-bitmap.c
|
||||
@@ -2453,6 +2453,7 @@ static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks,
|
||||
memcpy(page_address(store.sb_page),
|
||||
page_address(bitmap->storage.sb_page),
|
||||
sizeof(bitmap_super_t));
|
||||
+ mutex_lock(&bitmap->mddev->bitmap_info.mutex);
|
||||
spin_lock_irq(&bitmap->counts.lock);
|
||||
md_bitmap_file_unmap(&bitmap->storage);
|
||||
bitmap->storage = store;
|
||||
@@ -2560,7 +2561,7 @@ static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks,
|
||||
set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
|
||||
}
|
||||
spin_unlock_irq(&bitmap->counts.lock);
|
||||
-
|
||||
+ mutex_unlock(&bitmap->mddev->bitmap_info.mutex);
|
||||
if (!init) {
|
||||
__bitmap_unplug(bitmap);
|
||||
bitmap->mddev->pers->quiesce(bitmap->mddev, 0);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
122
SOURCES/1193-ptrace-slightly-saner-get-dumpable-logic.patch
Normal file
122
SOURCES/1193-ptrace-slightly-saner-get-dumpable-logic.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From bb79c39164a6539d01cfa3151a81da5be998840f Mon Sep 17 00:00:00 2001
|
||||
From: Ricardo Robaina <rrobaina@redhat.com>
|
||||
Date: Fri, 15 May 2026 10:20:50 -0300
|
||||
Subject: [PATCH] ptrace: slightly saner 'get_dumpable()' logic
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-176447
|
||||
CVE: CVE-2026-46333
|
||||
|
||||
Conflicts:
|
||||
- Minor context conflict due to missing upstream commit
|
||||
90383cc07895 ("exec: Distinguish in_execve from in_exec")
|
||||
|
||||
commit 31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a
|
||||
Author: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Wed May 13 11:37:18 2026 -0700
|
||||
|
||||
ptrace: slightly saner 'get_dumpable()' logic
|
||||
|
||||
The 'dumpability' of a task is fundamentally about the memory image of
|
||||
the task - the concept comes from whether it can core dump or not - and
|
||||
makes no sense when you don't have an associated mm.
|
||||
|
||||
And almost all users do in fact use it only for the case where the task
|
||||
has a mm pointer.
|
||||
|
||||
But we have one odd special case: ptrace_may_access() uses 'dumpable' to
|
||||
check various other things entirely independently of the MM (typically
|
||||
explicitly using flags like PTRACE_MODE_READ_FSCREDS). Including for
|
||||
threads that no longer have a VM (and maybe never did, like most kernel
|
||||
threads).
|
||||
|
||||
It's not what this flag was designed for, but it is what it is.
|
||||
|
||||
The ptrace code does check that the uid/gid matches, so you do have to
|
||||
be uid-0 to see kernel thread details, but this means that the
|
||||
traditional "drop capabilities" model doesn't make any difference for
|
||||
this all.
|
||||
|
||||
Make it all make a *bit* more sense by saying that if you don't have a
|
||||
MM pointer, we'll use a cached "last dumpability" flag if the thread
|
||||
ever had a MM (it will be zero for kernel threads since it is never
|
||||
set), and require a proper CAP_SYS_PTRACE capability to override.
|
||||
|
||||
Reported-by: Qualys Security Advisory <qsa@qualys.com>
|
||||
Cc: Oleg Nesterov <oleg@redhat.com>
|
||||
Cc: Kees Cook <kees@kernel.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
|
||||
|
||||
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index 066ab5f..0ecc266 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -936,6 +936,9 @@ struct task_struct {
|
||||
unsigned sched_migrated:1;
|
||||
unsigned sched_task_hot:1;
|
||||
|
||||
+ /* Save user-dumpable when mm goes away */
|
||||
+ RH_KABI_FILL_HOLE(unsigned user_dumpable:1)
|
||||
+
|
||||
/* Force alignment to the next boundary: */
|
||||
unsigned :0;
|
||||
|
||||
diff --git a/kernel/exit.c b/kernel/exit.c
|
||||
index 8782a6b..aa08b46 100644
|
||||
--- a/kernel/exit.c
|
||||
+++ b/kernel/exit.c
|
||||
@@ -534,6 +534,7 @@ static void exit_mm(void)
|
||||
*/
|
||||
smp_mb__after_spinlock();
|
||||
local_irq_disable();
|
||||
+ current->user_dumpable = (get_dumpable(mm) == SUID_DUMP_USER);
|
||||
current->mm = NULL;
|
||||
membarrier_update_current_mm(NULL);
|
||||
enter_lazy_tlb(mm, current);
|
||||
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
||||
index a0fd4bd..495fde1 100644
|
||||
--- a/kernel/ptrace.c
|
||||
+++ b/kernel/ptrace.c
|
||||
@@ -282,11 +282,24 @@ static bool ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
|
||||
return ns_capable(ns, CAP_SYS_PTRACE);
|
||||
}
|
||||
|
||||
+static bool task_still_dumpable(struct task_struct *task, unsigned int mode)
|
||||
+{
|
||||
+ struct mm_struct *mm = task->mm;
|
||||
+ if (mm) {
|
||||
+ if (get_dumpable(mm) == SUID_DUMP_USER)
|
||||
+ return true;
|
||||
+ return ptrace_has_cap(mm->user_ns, mode);
|
||||
+ }
|
||||
+
|
||||
+ if (task->user_dumpable)
|
||||
+ return true;
|
||||
+ return ptrace_has_cap(&init_user_ns, mode);
|
||||
+}
|
||||
+
|
||||
/* Returns 0 on success, -errno on denial. */
|
||||
static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
|
||||
{
|
||||
const struct cred *cred = current_cred(), *tcred;
|
||||
- struct mm_struct *mm;
|
||||
kuid_t caller_uid;
|
||||
kgid_t caller_gid;
|
||||
|
||||
@@ -347,11 +360,8 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
|
||||
* Pairs with a write barrier in commit_creds().
|
||||
*/
|
||||
smp_rmb();
|
||||
- mm = task->mm;
|
||||
- if (mm &&
|
||||
- ((get_dumpable(mm) != SUID_DUMP_USER) &&
|
||||
- !ptrace_has_cap(mm->user_ns, mode)))
|
||||
- return -EPERM;
|
||||
+ if (!task_still_dumpable(task, mode))
|
||||
+ return -EPERM;
|
||||
|
||||
return security_ptrace_access_check(task, mode);
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
From f84eca5817390257cef78013d0112481c503b4a3 Mon Sep 17 00:00:00 2001
|
||||
From: William Bowling <vakzz@zellic.io>
|
||||
Date: Wed, 13 May 2026 04:16:35 +0000
|
||||
Subject: [PATCH] net: skbuff: preserve shared-frag marker during coalescing
|
||||
|
||||
skb_try_coalesce() can attach paged frags from @from to @to. If @from
|
||||
has SKBFL_SHARED_FRAG set, the resulting @to skb can contain the same
|
||||
externally-owned or page-cache-backed frags, but the shared-frag marker
|
||||
is currently lost.
|
||||
|
||||
That breaks the invariant relied on by later in-place writers. In
|
||||
particular, ESP input checks skb_has_shared_frag() before deciding
|
||||
whether an uncloned nonlinear skb can skip skb_cow_data(). If TCP
|
||||
receive coalescing has moved shared frags into an unmarked skb, ESP can
|
||||
see skb_has_shared_frag() as false and decrypt in place over page-cache
|
||||
backed frags.
|
||||
|
||||
Propagate SKBFL_SHARED_FRAG when skb_try_coalesce() transfers paged
|
||||
frags. The tailroom copy path does not need the marker because it copies
|
||||
bytes into @to's linear data rather than transferring frag descriptors.
|
||||
|
||||
Fixes: cef401de7be8 ("net: fix possible wrong checksum generation")
|
||||
Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
|
||||
Signed-off-by: William Bowling <vakzz@zellic.io>
|
||||
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||
Tested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
|
||||
Link: https://patch.msgid.link/20260513041635.1289541-1-vakzz@zellic.io
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
index 7dad68e3b518..9c4e8d331d6d 100644
|
||||
--- a/net/core/skbuff.c
|
||||
+++ b/net/core/skbuff.c
|
||||
@@ -6200,6 +6200,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
|
||||
from_shinfo->frags,
|
||||
from_shinfo->nr_frags * sizeof(skb_frag_t));
|
||||
to_shinfo->nr_frags += from_shinfo->nr_frags;
|
||||
+ if (from_shinfo->nr_frags)
|
||||
+ to_shinfo->flags |= from_shinfo->flags & SKBFL_SHARED_FRAG;
|
||||
|
||||
if (!skb_cloned(from))
|
||||
from_shinfo->nr_frags = 0;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user