From 12ed4a792d57d81de67a83566caf186cb3d34eaa Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:32 -0500 Subject: [PATCH 01/13] smc: Use __sk_dst_get() and dst_dev_rcu() in smc_clc_prfx_match(). jira KERNEL-703 cve CVE-2025-40168 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Kuniyuki Iwashima commit 235f81045c008169cc4e1955b4a64e118eebe61b smc_clc_prfx_match() is called from smc_listen_work() and not under RCU nor RTNL. Using sk_dst_get(sk)->dev could trigger UAF. Let's use __sk_dst_get() and dst_dev_rcu(). Note that the returned value of smc_clc_prfx_match() is not used in the caller. Fixes: a046d57da19f ("smc: CLC handshake (incl. preparation steps)") Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20250916214758.650211-4-kuniyu@google.com Signed-off-by: Jakub Kicinski (cherry picked from commit 235f81045c008169cc4e1955b4a64e118eebe61b) Signed-off-by: Jonathan Maple --- net/smc/smc_clc.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 7afc53f1ec74e..f2065ed66d0c0 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c @@ -656,26 +656,26 @@ static int smc_clc_prfx_match6_rcu(struct net_device *dev, int smc_clc_prfx_match(struct socket *clcsock, struct smc_clc_msg_proposal_prefix *prop) { - struct dst_entry *dst = sk_dst_get(clcsock->sk); + struct net_device *dev; + struct dst_entry *dst; int rc; - if (!dst) { - rc = -ENOTCONN; - goto out; - } - if (!dst->dev) { + rcu_read_lock(); + + dst = __sk_dst_get(clcsock->sk); + dev = dst ? dst_dev_rcu(dst) : NULL; + if (!dev) { rc = -ENODEV; - goto out_rel; + goto out; } - rcu_read_lock(); + if (!prop->ipv6_prefixes_cnt) - rc = smc_clc_prfx_match4_rcu(dst->dev, prop); + rc = smc_clc_prfx_match4_rcu(dev, prop); else - rc = smc_clc_prfx_match6_rcu(dst->dev, prop); - rcu_read_unlock(); -out_rel: - dst_release(dst); + rc = smc_clc_prfx_match6_rcu(dev, prop); out: + rcu_read_unlock(); + return rc; } From 7830ed9cfd6c6640bd6a6461a574dc16461a5d96 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:33 -0500 Subject: [PATCH 02/13] tick/sched: Limit non-timekeeper CPUs calling jiffies update jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Steve Wahl commit 4138787408aa47e9e107f28876cb59b42d78bb99 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/41387874.failed On large NUMA systems, while running a test program that saturates the inter-processor and inter-NUMA links, acquiring the jiffies_lock can be very expensive. If the cpu designated to do jiffies updates (tick_do_timer_cpu) gets delayed and other cpus decide to do the jiffies update themselves, a large number of them decide to do so at the same time. The inexpensive check against tick_next_period is far quicker than actually acquiring the lock, so most of these get in line to obtain the lock. If obtaining the lock is slow enough, this spirals into the vast majority of CPUs continuously being stuck waiting for this lock, just to obtain it and find out that time has already been updated by another cpu. For example, on one random entry to kdb by manually-injected NMI, 2912 of 3840 CPUs were observed to be stuck there. To avoid this, allow only one non-timekeeper CPU to call tick_do_update_jiffies64() at any given time, resetting ts->stalled jiffies only if the jiffies update function is actually called. With this change, manually interrupting the test at most two CPUs are observed to invoke tick_do_update_jiffies64() - the timekeeper and one other. Signed-off-by: Steve Wahl Signed-off-by: Thomas Gleixner Acked-by: Shrikanth Hegde Link: https://patch.msgid.link/20251027183456.343407-1-steve.wahl@hpe.com (cherry picked from commit 4138787408aa47e9e107f28876cb59b42d78bb99) Signed-off-by: Jonathan Maple # Conflicts: # kernel/time/tick-sched.c --- .../41387874.failed | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/41387874.failed diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/41387874.failed b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/41387874.failed new file mode 100644 index 0000000000000..a955bd4266202 --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/41387874.failed @@ -0,0 +1,99 @@ +tick/sched: Limit non-timekeeper CPUs calling jiffies update + +jira KERNEL-703 +Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 +commit-author Steve Wahl +commit 4138787408aa47e9e107f28876cb59b42d78bb99 +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/41387874.failed + +On large NUMA systems, while running a test program that saturates the +inter-processor and inter-NUMA links, acquiring the jiffies_lock can be +very expensive. + +If the cpu designated to do jiffies updates (tick_do_timer_cpu) gets +delayed and other cpus decide to do the jiffies update themselves, a large +number of them decide to do so at the same time. + +The inexpensive check against tick_next_period is far quicker than actually +acquiring the lock, so most of these get in line to obtain the lock. If +obtaining the lock is slow enough, this spirals into the vast majority of +CPUs continuously being stuck waiting for this lock, just to obtain it and +find out that time has already been updated by another cpu. For example, on +one random entry to kdb by manually-injected NMI, 2912 of 3840 CPUs were +observed to be stuck there. + +To avoid this, allow only one non-timekeeper CPU to call +tick_do_update_jiffies64() at any given time, resetting ts->stalled jiffies +only if the jiffies update function is actually called. + +With this change, manually interrupting the test at most two CPUs are +observed to invoke tick_do_update_jiffies64() - the timekeeper and one +other. + + Signed-off-by: Steve Wahl + Signed-off-by: Thomas Gleixner + Acked-by: Shrikanth Hegde +Link: https://patch.msgid.link/20251027183456.343407-1-steve.wahl@hpe.com +(cherry picked from commit 4138787408aa47e9e107f28876cb59b42d78bb99) + Signed-off-by: Jonathan Maple + +# Conflicts: +# kernel/time/tick-sched.c +diff --cc kernel/time/tick-sched.c +index 5205373652e9,3ff3eb1f90d0..000000000000 +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@@ -181,6 -181,47 +181,50 @@@ static ktime_t tick_init_jiffy_update(v + return period; + } + +++<<<<<<< HEAD +++======= ++ static inline int tick_sched_flag_test(struct tick_sched *ts, ++ unsigned long flag) ++ { ++ return !!(ts->flags & flag); ++ } ++ ++ static inline void tick_sched_flag_set(struct tick_sched *ts, ++ unsigned long flag) ++ { ++ lockdep_assert_irqs_disabled(); ++ ts->flags |= flag; ++ } ++ ++ static inline void tick_sched_flag_clear(struct tick_sched *ts, ++ unsigned long flag) ++ { ++ lockdep_assert_irqs_disabled(); ++ ts->flags &= ~flag; ++ } ++ ++ /* ++ * Allow only one non-timekeeper CPU at a time update jiffies from ++ * the timer tick. ++ * ++ * Returns true if update was run. ++ */ ++ static bool tick_limited_update_jiffies64(struct tick_sched *ts, ktime_t now) ++ { ++ static atomic_t in_progress; ++ int inp; ++ ++ inp = atomic_read(&in_progress); ++ if (inp || !atomic_try_cmpxchg(&in_progress, &inp, 1)) ++ return false; ++ ++ if (ts->last_tick_jiffies == jiffies) ++ tick_do_update_jiffies64(now); ++ atomic_set(&in_progress, 0); ++ return true; ++ } ++ +++>>>>>>> 4138787408aa (tick/sched: Limit non-timekeeper CPUs calling jiffies update) + #define MAX_STALLED_JIFFIES 5 + + static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now) +* Unmerged path kernel/time/tick-sched.c From 28a2fb6029d546434862fdffb2c9dafb5dfa7935 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:33 -0500 Subject: [PATCH 03/13] ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr() jira KERNEL-703 cve CVE-2025-71085 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Will Rosenberg commit 58fc7342b529803d3c221101102fe913df7adb83 There exists a kernel oops caused by a BUG_ON(nhead < 0) at net/core/skbuff.c:2232 in pskb_expand_head(). This bug is triggered as part of the calipso_skbuff_setattr() routine when skb_cow() is passed headroom > INT_MAX (i.e. (int)(skb_headroom(skb) + len_delta) < 0). The root cause of the bug is due to an implicit integer cast in __skb_cow(). The check (headroom > skb_headroom(skb)) is meant to ensure that delta = headroom - skb_headroom(skb) is never negative, otherwise we will trigger a BUG_ON in pskb_expand_head(). However, if headroom > INT_MAX and delta <= -NET_SKB_PAD, the check passes, delta becomes negative, and pskb_expand_head() is passed a negative value for nhead. Fix the trigger condition in calipso_skbuff_setattr(). Avoid passing "negative" headroom sizes to skb_cow() within calipso_skbuff_setattr() by only using skb_cow() to grow headroom. PoC: Using `netlabelctl` tool: netlabelctl map del default netlabelctl calipso add pass doi:7 netlabelctl map add default address:0::1/128 protocol:calipso,7 Then run the following PoC: int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); // setup msghdr int cmsg_size = 2; int cmsg_len = 0x60; struct msghdr msg; struct sockaddr_in6 dest_addr; struct cmsghdr * cmsg = (struct cmsghdr *) calloc(1, sizeof(struct cmsghdr) + cmsg_len); msg.msg_name = &dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = NULL; msg.msg_iovlen = 0; msg.msg_control = cmsg; msg.msg_controllen = cmsg_len; msg.msg_flags = 0; // setup sockaddr dest_addr.sin6_family = AF_INET6; dest_addr.sin6_port = htons(31337); dest_addr.sin6_flowinfo = htonl(31337); dest_addr.sin6_addr = in6addr_loopback; dest_addr.sin6_scope_id = 31337; // setup cmsghdr cmsg->cmsg_len = cmsg_len; cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_HOPOPTS; char * hop_hdr = (char *)cmsg + sizeof(struct cmsghdr); hop_hdr[1] = 0x9; //set hop size - (0x9 + 1) * 8 = 80 sendmsg(fd, &msg, 0); Fixes: 2917f57b6bc1 ("calipso: Allow the lsm to label the skbuff directly.") Suggested-by: Paul Moore Signed-off-by: Will Rosenberg Acked-by: Paul Moore Link: https://patch.msgid.link/20251219173637.797418-1-whrosenb@asu.edu Signed-off-by: Paolo Abeni (cherry picked from commit 58fc7342b529803d3c221101102fe913df7adb83) Signed-off-by: Jonathan Maple --- net/ipv6/calipso.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index 1578ed9e97d89..201f455653639 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -1322,7 +1322,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb, /* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */ pad = ((new_end & 4) + (end & 7)) & 7; len_delta = new_end - (int)end + pad; - ret_val = skb_cow(skb, skb_headroom(skb) + len_delta); + ret_val = skb_cow(skb, + skb_headroom(skb) + (len_delta > 0 ? len_delta : 0)); if (ret_val < 0) return ret_val; From b2f113c6900e762641dd5a50c918271aa24d4a6a Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:34 -0500 Subject: [PATCH 04/13] s390/mm: Fix __ptep_rdp() inline assembly jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Heiko Carstens commit 31475b88110c4725b4f9a79c3a0d9bbf97e69e1c Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/31475b88.failed When a zero ASCE is passed to the __ptep_rdp() inline assembly, the generated instruction should have the R3 field of the instruction set to zero. However the inline assembly is written incorrectly: for such cases a zero is loaded into a register allocated by the compiler and this register is then used by the instruction. This means that selected TLB entries may not be flushed since the specified ASCE does not match the one which was used when the selected TLB entries were created. Fix this by removing the asce and opt parameters of __ptep_rdp(), since all callers always pass zero, and use a hard-coded register zero for the R3 field. Fixes: 0807b856521f ("s390/mm: add support for RDP (Reset DAT-Protection)") Cc: stable@vger.kernel.org Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens (cherry picked from commit 31475b88110c4725b4f9a79c3a0d9bbf97e69e1c) Signed-off-by: Jonathan Maple # Conflicts: # arch/s390/include/asm/pgtable.h --- .../31475b88.failed | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/31475b88.failed diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/31475b88.failed b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/31475b88.failed new file mode 100644 index 0000000000000..ce16eec93a6c8 --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/31475b88.failed @@ -0,0 +1,68 @@ +s390/mm: Fix __ptep_rdp() inline assembly + +jira KERNEL-703 +Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 +commit-author Heiko Carstens +commit 31475b88110c4725b4f9a79c3a0d9bbf97e69e1c +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/31475b88.failed + +When a zero ASCE is passed to the __ptep_rdp() inline assembly, the +generated instruction should have the R3 field of the instruction set to +zero. However the inline assembly is written incorrectly: for such cases a +zero is loaded into a register allocated by the compiler and this register +is then used by the instruction. + +This means that selected TLB entries may not be flushed since the specified +ASCE does not match the one which was used when the selected TLB entries +were created. + +Fix this by removing the asce and opt parameters of __ptep_rdp(), since +all callers always pass zero, and use a hard-coded register zero for +the R3 field. + +Fixes: 0807b856521f ("s390/mm: add support for RDP (Reset DAT-Protection)") + Cc: stable@vger.kernel.org + Reviewed-by: Gerald Schaefer + Signed-off-by: Heiko Carstens +(cherry picked from commit 31475b88110c4725b4f9a79c3a0d9bbf97e69e1c) + Signed-off-by: Jonathan Maple + +# Conflicts: +# arch/s390/include/asm/pgtable.h +diff --cc arch/s390/include/asm/pgtable.h +index 0a696d0fbf73,6663f1619abb..000000000000 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@@ -1296,8 -1345,8 +1294,13 @@@ static inline void flush_tlb_fix_spurio + * PTE does not have _PAGE_PROTECT set, to avoid unnecessary overhead. + * A local RDP can be used to do the flush. + */ +++<<<<<<< HEAD + + if (MACHINE_HAS_RDP && !(pte_val(*ptep) & _PAGE_PROTECT)) + + __ptep_rdp(address, ptep, 0, 0, 1); +++======= ++ if (cpu_has_rdp() && !(pte_val(*ptep) & _PAGE_PROTECT)) ++ __ptep_rdp(address, ptep, 1); +++>>>>>>> 31475b88110c (s390/mm: Fix __ptep_rdp() inline assembly) + } + #define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault + +* Unmerged path arch/s390/include/asm/pgtable.h +diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c +index c670195c0107..61c6ae698199 100644 +--- a/arch/s390/mm/pgtable.c ++++ b/arch/s390/mm/pgtable.c +@@ -303,9 +303,9 @@ void ptep_reset_dat_prot(struct mm_struct *mm, unsigned long addr, pte_t *ptep, + preempt_disable(); + atomic_inc(&mm->context.flush_count); + if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) +- __ptep_rdp(addr, ptep, 0, 0, 1); ++ __ptep_rdp(addr, ptep, 1); + else +- __ptep_rdp(addr, ptep, 0, 0, 0); ++ __ptep_rdp(addr, ptep, 0); + /* + * PTE is not invalidated by RDP, only _PAGE_PROTECT is cleared. That + * means it is still valid and active, and must not be changed according From 513a39aae176d6a655b83205cfbfcbecd83c8e4a Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:34 -0500 Subject: [PATCH 05/13] fou: remove sparse errors jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Eric Dumazet commit 8d65cd8d25fa23951171094553901d69a88ccdff We need to add __rcu qualifier to avoid these errors: net/ipv4/fou.c:250:18: warning: incorrect type in assignment (different address spaces) net/ipv4/fou.c:250:18: expected struct net_offload const **offloads net/ipv4/fou.c:250:18: got struct net_offload const [noderef] __rcu ** net/ipv4/fou.c:251:15: error: incompatible types in comparison expression (different address spaces): net/ipv4/fou.c:251:15: struct net_offload const [noderef] __rcu * net/ipv4/fou.c:251:15: struct net_offload const * net/ipv4/fou.c:272:18: warning: incorrect type in assignment (different address spaces) net/ipv4/fou.c:272:18: expected struct net_offload const **offloads net/ipv4/fou.c:272:18: got struct net_offload const [noderef] __rcu ** net/ipv4/fou.c:273:15: error: incompatible types in comparison expression (different address spaces): net/ipv4/fou.c:273:15: struct net_offload const [noderef] __rcu * net/ipv4/fou.c:273:15: struct net_offload const * net/ipv4/fou.c:442:18: warning: incorrect type in assignment (different address spaces) net/ipv4/fou.c:442:18: expected struct net_offload const **offloads net/ipv4/fou.c:442:18: got struct net_offload const [noderef] __rcu ** net/ipv4/fou.c:443:15: error: incompatible types in comparison expression (different address spaces): net/ipv4/fou.c:443:15: struct net_offload const [noderef] __rcu * net/ipv4/fou.c:443:15: struct net_offload const * net/ipv4/fou.c:489:18: warning: incorrect type in assignment (different address spaces) net/ipv4/fou.c:489:18: expected struct net_offload const **offloads net/ipv4/fou.c:489:18: got struct net_offload const [noderef] __rcu ** net/ipv4/fou.c:490:15: error: incompatible types in comparison expression (different address spaces): net/ipv4/fou.c:490:15: struct net_offload const [noderef] __rcu * net/ipv4/fou.c:490:15: struct net_offload const * net/ipv4/udp_offload.c:170:26: warning: incorrect type in assignment (different address spaces) net/ipv4/udp_offload.c:170:26: expected struct net_offload const **offloads net/ipv4/udp_offload.c:170:26: got struct net_offload const [noderef] __rcu ** net/ipv4/udp_offload.c:171:23: error: incompatible types in comparison expression (different address spaces): net/ipv4/udp_offload.c:171:23: struct net_offload const [noderef] __rcu * net/ipv4/udp_offload.c:171:23: struct net_offload const * Fixes: efc98d08e1ec ("fou: eliminate IPv4,v6 specific GRO functions") Fixes: 8bce6d7d0d1e ("udp: Generalize skb_udp_segment") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller (cherry picked from commit 8d65cd8d25fa23951171094553901d69a88ccdff) Signed-off-by: Jonathan Maple --- net/ipv4/fou_core.c | 10 +++++----- net/ipv4/udp_offload.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index 9e94970e07418..5c543015dca93 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -233,8 +233,8 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, struct list_head *head, struct sk_buff *skb) { + const struct net_offload __rcu **offloads; u8 proto = fou_from_sock(sk)->protocol; - const struct net_offload **offloads; const struct net_offload *ops; struct sk_buff *pp = NULL; @@ -266,10 +266,10 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, static int fou_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) { - const struct net_offload *ops; + const struct net_offload __rcu **offloads; u8 proto = fou_from_sock(sk)->protocol; + const struct net_offload *ops; int err = -ENOSYS; - const struct net_offload **offloads; rcu_read_lock(); offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; @@ -314,7 +314,7 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, struct list_head *head, struct sk_buff *skb) { - const struct net_offload **offloads; + const struct net_offload __rcu **offloads; const struct net_offload *ops; struct sk_buff *pp = NULL; struct sk_buff *p; @@ -457,8 +457,8 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) { - const struct net_offload **offloads; struct guehdr *guehdr = (struct guehdr *)(skb->data + nhoff); + const struct net_offload __rcu **offloads; const struct net_offload *ops; unsigned int guehlen = 0; u8 proto; diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index da7a3f7d5ea60..911e475e8e4d0 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -154,8 +154,8 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, netdev_features_t features, bool is_ipv6) { + const struct net_offload __rcu **offloads; __be16 protocol = skb->protocol; - const struct net_offload **offloads; const struct net_offload *ops; struct sk_buff *segs = ERR_PTR(-EINVAL); struct sk_buff *(*gso_inner_segment)(struct sk_buff *skb, From 6880369b0148568a6b37105f4169b16772982ab3 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:35 -0500 Subject: [PATCH 06/13] fou: Remove XRFM from NET_FOU Kconfig jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Coco Li commit 753b953774b5840825c9b7bc6413036292138467 XRFM is no longer needed for configuring FOU tunnels (CONFIG_NET_FOU_IP_TUNNELS), remove from Kconfig. Also remove the xrfm.h dependency in fou.c. It was added in '23461551c006 ("fou: Support for foo-over-udp RX path")' for depencies of udp_del_offload and udp_offloads, which were removed in 'd92283e338f6 ("fou: change to use UDP socket GRO")'. Built and installed kernel and setup GUE/FOU tunnels. Signed-off-by: Coco Li Link: https://lore.kernel.org/r/20220411213717.3688789-1-lixiaoyan@google.com Signed-off-by: Jakub Kicinski (cherry picked from commit 753b953774b5840825c9b7bc6413036292138467) Signed-off-by: Jonathan Maple --- net/ipv4/Kconfig | 1 - net/ipv4/fou_core.c | 1 - 2 files changed, 2 deletions(-) diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 87983e70f03f3..e983bb0c50127 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -321,7 +321,6 @@ config NET_UDP_TUNNEL config NET_FOU tristate "IP: Foo (IP protocols) over UDP" - select XFRM select NET_UDP_TUNNEL help Foo over UDP allows any IP protocol to be directly encapsulated diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index 5c543015dca93..b7b887f83b659 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include From 3168bddba827cb87092e95dcc3973eb3249c9ac9 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:36 -0500 Subject: [PATCH 07/13] fou: remove warn in gue_gro_receive on unsupported protocol jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Willem de Bruijn commit dd89a81d850fa9a65f67b4527c0e420d15bf836c Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/dd89a81d.failed Drop the WARN_ON_ONCE inn gue_gro_receive if the encapsulated type is not known or does not have a GRO handler. Such a packet is easily constructed. Syzbot generates them and sets off this warning. Remove the warning as it is expected and not actionable. The warning was previously reduced from WARN_ON to WARN_ON_ONCE in commit 270136613bf7 ("fou: Do WARN_ON_ONCE in gue_gro_receive for bad proto callbacks"). Signed-off-by: Willem de Bruijn Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20240614122552.1649044-1-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski (cherry picked from commit dd89a81d850fa9a65f67b4527c0e420d15bf836c) Signed-off-by: Jonathan Maple # Conflicts: # net/ipv4/fou_core.c --- .../dd89a81d.failed | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/dd89a81d.failed diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/dd89a81d.failed b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/dd89a81d.failed new file mode 100644 index 0000000000000..25a8fd0cc719c --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/dd89a81d.failed @@ -0,0 +1,53 @@ +fou: remove warn in gue_gro_receive on unsupported protocol + +jira KERNEL-703 +Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 +commit-author Willem de Bruijn +commit dd89a81d850fa9a65f67b4527c0e420d15bf836c +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/dd89a81d.failed + +Drop the WARN_ON_ONCE inn gue_gro_receive if the encapsulated type is +not known or does not have a GRO handler. + +Such a packet is easily constructed. Syzbot generates them and sets +off this warning. + +Remove the warning as it is expected and not actionable. + +The warning was previously reduced from WARN_ON to WARN_ON_ONCE in +commit 270136613bf7 ("fou: Do WARN_ON_ONCE in gue_gro_receive for bad +proto callbacks"). + + Signed-off-by: Willem de Bruijn + Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20240614122552.1649044-1-willemdebruijn.kernel@gmail.com + Signed-off-by: Jakub Kicinski +(cherry picked from commit dd89a81d850fa9a65f67b4527c0e420d15bf836c) + Signed-off-by: Jonathan Maple + +# Conflicts: +# net/ipv4/fou_core.c +diff --cc net/ipv4/fou_core.c +index b7b887f83b65,0abbc413e0fe..000000000000 +--- a/net/ipv4/fou_core.c ++++ b/net/ipv4/fou_core.c +@@@ -437,11 -431,10 +437,16 @@@ next_proto + /* Flag this frame as already having an outer encap header */ + NAPI_GRO_CB(skb)->is_fou = 1; + + + rcu_read_lock(); + offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; + ops = rcu_dereference(offloads[proto]); +++<<<<<<< HEAD + + if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) + + goto out_unlock; +++======= ++ if (!ops || !ops->callbacks.gro_receive) ++ goto out; +++>>>>>>> dd89a81d850f (fou: remove warn in gue_gro_receive on unsupported protocol) + + pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); + flush = 0; +* Unmerged path net/ipv4/fou_core.c From d28b3400871a77c523e168415add41e370fd8462 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:36 -0500 Subject: [PATCH 08/13] fou: Fix null-ptr-deref in GRO. jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Kuniyuki Iwashima commit 7e4196935069947d8b70b09c1660b67b067e75cb Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/7e419693.failed We observed a null-ptr-deref in fou_gro_receive() while shutting down a host. [0] The NULL pointer is sk->sk_user_data, and the offset 8 is of protocol in struct fou. When fou_release() is called due to netns dismantle or explicit tunnel teardown, udp_tunnel_sock_release() sets NULL to sk->sk_user_data. Then, the tunnel socket is destroyed after a single RCU grace period. So, in-flight udp4_gro_receive() could find the socket and execute the FOU GRO handler, where sk->sk_user_data could be NULL. Let's use rcu_dereference_sk_user_data() in fou_from_sock() and add NULL checks in FOU GRO handlers. [0]: BUG: kernel NULL pointer dereference, address: 0000000000000008 PF: supervisor read access in kernel mode PF: error_code(0x0000) - not-present page PGD 80000001032f4067 P4D 80000001032f4067 PUD 103240067 PMD 0 SMP PTI CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.216-204.855.amzn2.x86_64 #1 Hardware name: Amazon EC2 c5.large/, BIOS 1.0 10/16/2017 RIP: 0010:fou_gro_receive (net/ipv4/fou.c:233) [fou] Code: 41 5f c3 cc cc cc cc e8 e7 2e 69 f4 0f 1f 80 00 00 00 00 0f 1f 44 00 00 49 89 f8 41 54 48 89 f7 48 89 d6 49 8b 80 88 02 00 00 <0f> b6 48 08 0f b7 42 4a 66 25 fd fd 80 cc 02 66 89 42 4a 0f b6 42 RSP: 0018:ffffa330c0003d08 EFLAGS: 00010297 RAX: 0000000000000000 RBX: ffff93d9e3a6b900 RCX: 0000000000000010 RDX: ffff93d9e3a6b900 RSI: ffff93d9e3a6b900 RDI: ffff93dac2e24d08 RBP: ffff93d9e3a6b900 R08: ffff93dacbce6400 R09: 0000000000000002 R10: 0000000000000000 R11: ffffffffb5f369b0 R12: ffff93dacbce6400 R13: ffff93dac2e24d08 R14: 0000000000000000 R15: ffffffffb4edd1c0 FS: 0000000000000000(0000) GS:ffff93daee800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 0000000102140001 CR4: 00000000007706f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: ? show_trace_log_lvl (arch/x86/kernel/dumpstack.c:259) ? __die_body.cold (arch/x86/kernel/dumpstack.c:478 arch/x86/kernel/dumpstack.c:420) ? no_context (arch/x86/mm/fault.c:752) ? exc_page_fault (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 arch/x86/mm/fault.c:1435 arch/x86/mm/fault.c:1483) ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:571) ? fou_gro_receive (net/ipv4/fou.c:233) [fou] udp_gro_receive (include/linux/netdevice.h:2552 net/ipv4/udp_offload.c:559) udp4_gro_receive (net/ipv4/udp_offload.c:604) inet_gro_receive (net/ipv4/af_inet.c:1549 (discriminator 7)) dev_gro_receive (net/core/dev.c:6035 (discriminator 4)) napi_gro_receive (net/core/dev.c:6170) ena_clean_rx_irq (drivers/amazon/net/ena/ena_netdev.c:1558) [ena] ena_io_poll (drivers/amazon/net/ena/ena_netdev.c:1742) [ena] napi_poll (net/core/dev.c:6847) net_rx_action (net/core/dev.c:6917) __do_softirq (arch/x86/include/asm/jump_label.h:25 include/linux/jump_label.h:200 include/trace/events/irq.h:142 kernel/softirq.c:299) asm_call_irq_on_stack (arch/x86/entry/entry_64.S:809) do_softirq_own_stack (arch/x86/include/asm/irq_stack.h:27 arch/x86/include/asm/irq_stack.h:77 arch/x86/kernel/irq_64.c:77) irq_exit_rcu (kernel/softirq.c:393 kernel/softirq.c:423 kernel/softirq.c:435) common_interrupt (arch/x86/kernel/irq.c:239) asm_common_interrupt (arch/x86/include/asm/idtentry.h:626) RIP: 0010:acpi_idle_do_entry (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 drivers/acpi/processor_idle.c:114 drivers/acpi/processor_idle.c:575) Code: 8b 15 d1 3c c4 02 ed c3 cc cc cc cc 65 48 8b 04 25 40 ef 01 00 48 8b 00 a8 08 75 eb 0f 1f 44 00 00 0f 00 2d d5 09 55 00 fb f4 c3 cc cc cc cc e9 be fc ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 RSP: 0018:ffffffffb5603e58 EFLAGS: 00000246 RAX: 0000000000004000 RBX: ffff93dac0929c00 RCX: ffff93daee833900 RDX: ffff93daee800000 RSI: ffff93daee87dc00 RDI: ffff93daee87dc64 RBP: 0000000000000001 R08: ffffffffb5e7b6c0 R09: 0000000000000044 R10: ffff93daee831b04 R11: 00000000000001cd R12: 0000000000000001 R13: ffffffffb5e7b740 R14: 0000000000000001 R15: 0000000000000000 ? sched_clock_cpu (kernel/sched/clock.c:371) acpi_idle_enter (drivers/acpi/processor_idle.c:712 (discriminator 3)) cpuidle_enter_state (drivers/cpuidle/cpuidle.c:237) cpuidle_enter (drivers/cpuidle/cpuidle.c:353) cpuidle_idle_call (kernel/sched/idle.c:158 kernel/sched/idle.c:239) do_idle (kernel/sched/idle.c:302) cpu_startup_entry (kernel/sched/idle.c:395 (discriminator 1)) start_kernel (init/main.c:1048) secondary_startup_64_no_verify (arch/x86/kernel/head_64.S:310) Modules linked in: udp_diag tcp_diag inet_diag nft_nat ipip tunnel4 dummy fou ip_tunnel nft_masq nft_chain_nat nf_nat wireguard nft_ct curve25519_x86_64 libcurve25519_generic nf_conntrack libchacha20poly1305 nf_defrag_ipv6 nf_defrag_ipv4 nft_objref chacha_x86_64 nft_counter nf_tables nfnetlink poly1305_x86_64 ip6_udp_tunnel udp_tunnel libchacha crc32_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper mousedev psmouse button ena ptp pps_core crc32c_intel CR2: 0000000000000008 Fixes: d92283e338f6 ("fou: change to use UDP socket GRO") Reported-by: Alphonse Kurian Signed-off-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20240902173927.62706-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski (cherry picked from commit 7e4196935069947d8b70b09c1660b67b067e75cb) Signed-off-by: Jonathan Maple # Conflicts: # net/ipv4/fou_core.c --- .../7e419693.failed | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/7e419693.failed diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/7e419693.failed b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/7e419693.failed new file mode 100644 index 0000000000000..25542097589f0 --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/7e419693.failed @@ -0,0 +1,140 @@ +fou: Fix null-ptr-deref in GRO. + +jira KERNEL-703 +Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 +commit-author Kuniyuki Iwashima +commit 7e4196935069947d8b70b09c1660b67b067e75cb +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/7e419693.failed + +We observed a null-ptr-deref in fou_gro_receive() while shutting down +a host. [0] + +The NULL pointer is sk->sk_user_data, and the offset 8 is of protocol +in struct fou. + +When fou_release() is called due to netns dismantle or explicit tunnel +teardown, udp_tunnel_sock_release() sets NULL to sk->sk_user_data. +Then, the tunnel socket is destroyed after a single RCU grace period. + +So, in-flight udp4_gro_receive() could find the socket and execute the +FOU GRO handler, where sk->sk_user_data could be NULL. + +Let's use rcu_dereference_sk_user_data() in fou_from_sock() and add NULL +checks in FOU GRO handlers. + +[0]: +BUG: kernel NULL pointer dereference, address: 0000000000000008 + PF: supervisor read access in kernel mode + PF: error_code(0x0000) - not-present page +PGD 80000001032f4067 P4D 80000001032f4067 PUD 103240067 PMD 0 +SMP PTI +CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.216-204.855.amzn2.x86_64 #1 +Hardware name: Amazon EC2 c5.large/, BIOS 1.0 10/16/2017 +RIP: 0010:fou_gro_receive (net/ipv4/fou.c:233) [fou] +Code: 41 5f c3 cc cc cc cc e8 e7 2e 69 f4 0f 1f 80 00 00 00 00 0f 1f 44 00 00 49 89 f8 41 54 48 89 f7 48 89 d6 49 8b 80 88 02 00 00 <0f> b6 48 08 0f b7 42 4a 66 25 fd fd 80 cc 02 66 89 42 4a 0f b6 42 +RSP: 0018:ffffa330c0003d08 EFLAGS: 00010297 +RAX: 0000000000000000 RBX: ffff93d9e3a6b900 RCX: 0000000000000010 +RDX: ffff93d9e3a6b900 RSI: ffff93d9e3a6b900 RDI: ffff93dac2e24d08 +RBP: ffff93d9e3a6b900 R08: ffff93dacbce6400 R09: 0000000000000002 +R10: 0000000000000000 R11: ffffffffb5f369b0 R12: ffff93dacbce6400 +R13: ffff93dac2e24d08 R14: 0000000000000000 R15: ffffffffb4edd1c0 +FS: 0000000000000000(0000) GS:ffff93daee800000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000008 CR3: 0000000102140001 CR4: 00000000007706f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +PKRU: 55555554 +Call Trace: + + ? show_trace_log_lvl (arch/x86/kernel/dumpstack.c:259) + ? __die_body.cold (arch/x86/kernel/dumpstack.c:478 arch/x86/kernel/dumpstack.c:420) + ? no_context (arch/x86/mm/fault.c:752) + ? exc_page_fault (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 arch/x86/mm/fault.c:1435 arch/x86/mm/fault.c:1483) + ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:571) + ? fou_gro_receive (net/ipv4/fou.c:233) [fou] + udp_gro_receive (include/linux/netdevice.h:2552 net/ipv4/udp_offload.c:559) + udp4_gro_receive (net/ipv4/udp_offload.c:604) + inet_gro_receive (net/ipv4/af_inet.c:1549 (discriminator 7)) + dev_gro_receive (net/core/dev.c:6035 (discriminator 4)) + napi_gro_receive (net/core/dev.c:6170) + ena_clean_rx_irq (drivers/amazon/net/ena/ena_netdev.c:1558) [ena] + ena_io_poll (drivers/amazon/net/ena/ena_netdev.c:1742) [ena] + napi_poll (net/core/dev.c:6847) + net_rx_action (net/core/dev.c:6917) + __do_softirq (arch/x86/include/asm/jump_label.h:25 include/linux/jump_label.h:200 include/trace/events/irq.h:142 kernel/softirq.c:299) + asm_call_irq_on_stack (arch/x86/entry/entry_64.S:809) + + do_softirq_own_stack (arch/x86/include/asm/irq_stack.h:27 arch/x86/include/asm/irq_stack.h:77 arch/x86/kernel/irq_64.c:77) + irq_exit_rcu (kernel/softirq.c:393 kernel/softirq.c:423 kernel/softirq.c:435) + common_interrupt (arch/x86/kernel/irq.c:239) + asm_common_interrupt (arch/x86/include/asm/idtentry.h:626) +RIP: 0010:acpi_idle_do_entry (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 drivers/acpi/processor_idle.c:114 drivers/acpi/processor_idle.c:575) +Code: 8b 15 d1 3c c4 02 ed c3 cc cc cc cc 65 48 8b 04 25 40 ef 01 00 48 8b 00 a8 08 75 eb 0f 1f 44 00 00 0f 00 2d d5 09 55 00 fb f4 c3 cc cc cc cc e9 be fc ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 +RSP: 0018:ffffffffb5603e58 EFLAGS: 00000246 +RAX: 0000000000004000 RBX: ffff93dac0929c00 RCX: ffff93daee833900 +RDX: ffff93daee800000 RSI: ffff93daee87dc00 RDI: ffff93daee87dc64 +RBP: 0000000000000001 R08: ffffffffb5e7b6c0 R09: 0000000000000044 +R10: ffff93daee831b04 R11: 00000000000001cd R12: 0000000000000001 +R13: ffffffffb5e7b740 R14: 0000000000000001 R15: 0000000000000000 + ? sched_clock_cpu (kernel/sched/clock.c:371) + acpi_idle_enter (drivers/acpi/processor_idle.c:712 (discriminator 3)) + cpuidle_enter_state (drivers/cpuidle/cpuidle.c:237) + cpuidle_enter (drivers/cpuidle/cpuidle.c:353) + cpuidle_idle_call (kernel/sched/idle.c:158 kernel/sched/idle.c:239) + do_idle (kernel/sched/idle.c:302) + cpu_startup_entry (kernel/sched/idle.c:395 (discriminator 1)) + start_kernel (init/main.c:1048) + secondary_startup_64_no_verify (arch/x86/kernel/head_64.S:310) +Modules linked in: udp_diag tcp_diag inet_diag nft_nat ipip tunnel4 dummy fou ip_tunnel nft_masq nft_chain_nat nf_nat wireguard nft_ct curve25519_x86_64 libcurve25519_generic nf_conntrack libchacha20poly1305 nf_defrag_ipv6 nf_defrag_ipv4 nft_objref chacha_x86_64 nft_counter nf_tables nfnetlink poly1305_x86_64 ip6_udp_tunnel udp_tunnel libchacha crc32_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper mousedev psmouse button ena ptp pps_core crc32c_intel +CR2: 0000000000000008 + +Fixes: d92283e338f6 ("fou: change to use UDP socket GRO") + Reported-by: Alphonse Kurian + Signed-off-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20240902173927.62706-1-kuniyu@amazon.com + Signed-off-by: Jakub Kicinski +(cherry picked from commit 7e4196935069947d8b70b09c1660b67b067e75cb) + Signed-off-by: Jonathan Maple + +# Conflicts: +# net/ipv4/fou_core.c +diff --cc net/ipv4/fou_core.c +index b7b887f83b65,78b869b31492..000000000000 +--- a/net/ipv4/fou_core.c ++++ b/net/ipv4/fou_core.c +@@@ -266,15 -269,24 +272,30 @@@ static int fou_gro_complete(struct soc + int nhoff) + { + const struct net_offload __rcu **offloads; +- u8 proto = fou_from_sock(sk)->protocol; ++ struct fou *fou = fou_from_sock(sk); + const struct net_offload *ops; +- int err = -ENOSYS; ++ u8 proto; ++ int err; ++ ++ if (!fou) { ++ err = -ENOENT; ++ goto out; ++ } ++ ++ proto = fou->protocol; + + + rcu_read_lock(); + offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; + ops = rcu_dereference(offloads[proto]); +++<<<<<<< HEAD + + if (WARN_ON(!ops || !ops->callbacks.gro_complete)) + + goto out_unlock; +++======= ++ if (WARN_ON(!ops || !ops->callbacks.gro_complete)) { ++ err = -ENOSYS; ++ goto out; ++ } +++>>>>>>> 7e4196935069 (fou: Fix null-ptr-deref in GRO.) + + err = ops->callbacks.gro_complete(skb, nhoff); + +* Unmerged path net/ipv4/fou_core.c From d91e5687a5310f15e2b371a718db704425c5e5c2 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:37 -0500 Subject: [PATCH 09/13] fou: fix initialization of grc jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Muhammad Usama Anjum commit 4c8002277167125078e6b9b90137bdf443ebaa08 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/4c800227.failed The grc must be initialize first. There can be a condition where if fou is NULL, goto out will be executed and grc would be used uninitialized. Fixes: 7e4196935069 ("fou: Fix null-ptr-deref in GRO.") Signed-off-by: Muhammad Usama Anjum Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20240906102839.202798-1-usama.anjum@collabora.com Signed-off-by: Jakub Kicinski (cherry picked from commit 4c8002277167125078e6b9b90137bdf443ebaa08) Signed-off-by: Jonathan Maple # Conflicts: # net/ipv4/fou_core.c --- .../4c800227.failed | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/4c800227.failed diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/4c800227.failed b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/4c800227.failed new file mode 100644 index 0000000000000..39ac3e0c1e235 --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/4c800227.failed @@ -0,0 +1,42 @@ +fou: fix initialization of grc + +jira KERNEL-703 +Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 +commit-author Muhammad Usama Anjum +commit 4c8002277167125078e6b9b90137bdf443ebaa08 +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/4c800227.failed + +The grc must be initialize first. There can be a condition where if +fou is NULL, goto out will be executed and grc would be used +uninitialized. + +Fixes: 7e4196935069 ("fou: Fix null-ptr-deref in GRO.") + Signed-off-by: Muhammad Usama Anjum + Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20240906102839.202798-1-usama.anjum@collabora.com + Signed-off-by: Jakub Kicinski +(cherry picked from commit 4c8002277167125078e6b9b90137bdf443ebaa08) + Signed-off-by: Jonathan Maple + +# Conflicts: +# net/ipv4/fou_core.c +diff --cc net/ipv4/fou_core.c +index b7b887f83b65,3e30745e2c09..000000000000 +--- a/net/ipv4/fou_core.c ++++ b/net/ipv4/fou_core.c +@@@ -328,6 -338,9 +328,12 @@@ static struct sk_buff *gue_gro_receive( + + skb_gro_remcsum_init(&grc); + +++<<<<<<< HEAD +++======= ++ if (!fou) ++ goto out; ++ +++>>>>>>> 4c8002277167 (fou: fix initialization of grc) + off = skb_gro_offset(skb); + len = off + sizeof(*guehdr); + +* Unmerged path net/ipv4/fou_core.c From 6cc7bfd2bdb3a7552ddecb0acc3005996dc89bae Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:37 -0500 Subject: [PATCH 10/13] netlink: specs: fou: replace underscores with dashes in names jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Jakub Kicinski commit 791a9ed0a40dfa70fe793dcecf950273255cbb84 We're trying to add a strict regexp for the name format in the spec. Underscores will not be allowed, dashes should be used instead. This makes no difference to C (codegen, if used, replaces special chars in names) but it gives more uniform naming in Python. Fixes: 4eb77b4ecd3c ("netlink: add a proto specification for FOU") Reviewed-by: Donald Hunter Link: https://patch.msgid.link/20250624211002.3475021-3-kuba@kernel.org Signed-off-by: Jakub Kicinski (cherry picked from commit 791a9ed0a40dfa70fe793dcecf950273255cbb84) Signed-off-by: Jonathan Maple --- Documentation/netlink/specs/fou.yaml | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Documentation/netlink/specs/fou.yaml b/Documentation/netlink/specs/fou.yaml index 0af5ab842c04d..b02ab19817d3c 100644 --- a/Documentation/netlink/specs/fou.yaml +++ b/Documentation/netlink/specs/fou.yaml @@ -15,7 +15,7 @@ kernel-policy: global definitions: - type: enum - name: encap_type + name: encap-type name-prefix: fou-encap- enum-name: entries: [ unspec, direct, gue ] @@ -43,26 +43,26 @@ attribute-sets: name: type type: u8 - - name: remcsum_nopartial + name: remcsum-nopartial type: flag - - name: local_v4 + name: local-v4 type: u32 - - name: local_v6 + name: local-v6 type: binary checks: min-len: 16 - - name: peer_v4 + name: peer-v4 type: u32 - - name: peer_v6 + name: peer-v6 type: binary checks: min-len: 16 - - name: peer_port + name: peer-port type: u16 byte-order: big-endian - @@ -90,12 +90,12 @@ operations: - port - ipproto - type - - remcsum_nopartial - - local_v4 - - peer_v4 - - local_v6 - - peer_v6 - - peer_port + - remcsum-nopartial + - local-v4 + - peer-v4 + - local-v6 + - peer-v6 + - peer-port - ifindex - @@ -112,11 +112,11 @@ operations: - af - ifindex - port - - peer_port - - local_v4 - - peer_v4 - - local_v6 - - peer_v6 + - peer-port + - local-v4 + - peer-v4 + - local-v6 + - peer-v6 - name: get From 15ffc8b5f77a641fb1afb06d8d964afde7a75ecf Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:37 -0500 Subject: [PATCH 11/13] autofs: dont trigger mount if it cant succeed jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Ian Kent commit 922a6f34c1756d2b0c35d9b2d915b8af19e85965 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/922a6f34.failed If a mount namespace contains autofs mounts, and they are propagation private, and there is no namespace specific automount daemon to handle possible automounting then attempted path resolution will loop until MAXSYMLINKS is reached before failing causing quite a bit of noise in the log. Add a check for this in autofs ->d_automount() so that the VFS can immediately return an error in this case. Since the mount is propagation private an EPERM return seems most appropriate. Suggested by: Christian Brauner Signed-off-by: Ian Kent Link: https://patch.msgid.link/20251118024631.10854-2-raven@themaw.net Signed-off-by: Christian Brauner (cherry picked from commit 922a6f34c1756d2b0c35d9b2d915b8af19e85965) Signed-off-by: Jonathan Maple # Conflicts: # fs/autofs/autofs_i.h # fs/autofs/inode.c # fs/namespace.c --- .../922a6f34.failed | 1117 +++++++++++++++++ 1 file changed, 1117 insertions(+) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/922a6f34.failed diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/922a6f34.failed b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/922a6f34.failed new file mode 100644 index 0000000000000..c40e5acd9449f --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/922a6f34.failed @@ -0,0 +1,1117 @@ +autofs: dont trigger mount if it cant succeed + +jira KERNEL-703 +Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 +commit-author Ian Kent +commit 922a6f34c1756d2b0c35d9b2d915b8af19e85965 +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/922a6f34.failed + +If a mount namespace contains autofs mounts, and they are propagation +private, and there is no namespace specific automount daemon to handle +possible automounting then attempted path resolution will loop until +MAXSYMLINKS is reached before failing causing quite a bit of noise in +the log. + +Add a check for this in autofs ->d_automount() so that the VFS can +immediately return an error in this case. Since the mount is propagation +private an EPERM return seems most appropriate. + +Suggested by: Christian Brauner + + Signed-off-by: Ian Kent +Link: https://patch.msgid.link/20251118024631.10854-2-raven@themaw.net + Signed-off-by: Christian Brauner +(cherry picked from commit 922a6f34c1756d2b0c35d9b2d915b8af19e85965) + Signed-off-by: Jonathan Maple + +# Conflicts: +# fs/autofs/autofs_i.h +# fs/autofs/inode.c +# fs/namespace.c +diff --cc fs/autofs/autofs_i.h +index 8026f44a107e,4fd555528c5d..000000000000 +--- a/fs/autofs/autofs_i.h ++++ b/fs/autofs/autofs_i.h +@@@ -25,6 -26,11 +26,14 @@@ + #include + #include + #include +++<<<<<<< HEAD +++======= ++ #include ++ #include ++ #include "../mount.h" ++ #include ++ +++>>>>>>> 922a6f34c175 (autofs: dont trigger mount if it cant succeed) + + /* This is the range of ioctl() numbers we claim as ours */ + #define AUTOFS_IOC_FIRST AUTOFS_IOC_READY +diff --cc fs/autofs/inode.c +index 49b34730e7b9,732aee76a24c..000000000000 +--- a/fs/autofs/inode.c ++++ b/fs/autofs/inode.c +@@@ -233,22 -244,16 +233,27 @@@ int autofs_fill_super(struct super_bloc + + sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + if (!sbi) + - return NULL; + + return -ENOMEM; + + pr_debug("starting up, sbi = %p\n", sbi); + + + s->s_fs_info = sbi; + sbi->magic = AUTOFS_SBI_MAGIC; + - sbi->flags = AUTOFS_SBI_CATATONIC; + - sbi->min_proto = AUTOFS_MIN_PROTO_VERSION; + - sbi->max_proto = AUTOFS_MAX_PROTO_VERSION; + sbi->pipefd = -1; +++<<<<<<< HEAD + + sbi->pipe = NULL; + + sbi->exp_timeout = 0; + + sbi->oz_pgrp = NULL; + + sbi->sb = s; + + sbi->version = 0; + + sbi->sub_version = 0; + + sbi->flags = AUTOFS_SBI_CATATONIC; +++======= ++ sbi->mnt_ns_id = to_ns_common(current->nsproxy->mnt_ns)->ns_id; ++ +++>>>>>>> 922a6f34c175 (autofs: dont trigger mount if it cant succeed) + set_autofs_type_indirect(&sbi->type); + + sbi->min_proto = 0; + + sbi->max_proto = 0; + mutex_init(&sbi->wq_mutex); + mutex_init(&sbi->pipe_mutex); + spin_lock_init(&sbi->fs_lock); +diff --cc fs/namespace.c +index faa8e1bff7c9,27bb12693cba..000000000000 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@@ -4278,6 -5031,976 +4278,979 @@@ SYSCALL_DEFINE5(mount_setattr, int, dfd + return err; + } + +++<<<<<<< HEAD +++======= ++ SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename, ++ unsigned, flags, struct mount_attr __user *, uattr, ++ size_t, usize) ++ { ++ struct file __free(fput) *file = NULL; ++ int fd; ++ ++ if (!uattr && usize) ++ return -EINVAL; ++ ++ file = vfs_open_tree(dfd, filename, flags); ++ if (IS_ERR(file)) ++ return PTR_ERR(file); ++ ++ if (uattr) { ++ int ret; ++ struct mount_kattr kattr = {}; ++ ++ if (flags & OPEN_TREE_CLONE) ++ kattr.kflags = MOUNT_KATTR_IDMAP_REPLACE; ++ if (flags & AT_RECURSIVE) ++ kattr.kflags |= MOUNT_KATTR_RECURSE; ++ ++ ret = wants_mount_setattr(uattr, usize, &kattr); ++ if (ret > 0) { ++ ret = do_mount_setattr(&file->f_path, &kattr); ++ finish_mount_kattr(&kattr); ++ } ++ if (ret) ++ return ret; ++ } ++ ++ fd = get_unused_fd_flags(flags & O_CLOEXEC); ++ if (fd < 0) ++ return fd; ++ ++ fd_install(fd, no_free_ptr(file)); ++ return fd; ++ } ++ ++ int show_path(struct seq_file *m, struct dentry *root) ++ { ++ if (root->d_sb->s_op->show_path) ++ return root->d_sb->s_op->show_path(m, root); ++ ++ seq_dentry(m, root, " \t\n\\"); ++ return 0; ++ } ++ ++ static struct vfsmount *lookup_mnt_in_ns(u64 id, struct mnt_namespace *ns) ++ { ++ struct mount *mnt = mnt_find_id_at(ns, id); ++ ++ if (!mnt || mnt->mnt_id_unique != id) ++ return NULL; ++ ++ return &mnt->mnt; ++ } ++ ++ struct kstatmount { ++ struct statmount __user *buf; ++ size_t bufsize; ++ struct vfsmount *mnt; ++ struct mnt_idmap *idmap; ++ u64 mask; ++ struct path root; ++ struct seq_file seq; ++ ++ /* Must be last --ends in a flexible-array member. */ ++ struct statmount sm; ++ }; ++ ++ static u64 mnt_to_attr_flags(struct vfsmount *mnt) ++ { ++ unsigned int mnt_flags = READ_ONCE(mnt->mnt_flags); ++ u64 attr_flags = 0; ++ ++ if (mnt_flags & MNT_READONLY) ++ attr_flags |= MOUNT_ATTR_RDONLY; ++ if (mnt_flags & MNT_NOSUID) ++ attr_flags |= MOUNT_ATTR_NOSUID; ++ if (mnt_flags & MNT_NODEV) ++ attr_flags |= MOUNT_ATTR_NODEV; ++ if (mnt_flags & MNT_NOEXEC) ++ attr_flags |= MOUNT_ATTR_NOEXEC; ++ if (mnt_flags & MNT_NODIRATIME) ++ attr_flags |= MOUNT_ATTR_NODIRATIME; ++ if (mnt_flags & MNT_NOSYMFOLLOW) ++ attr_flags |= MOUNT_ATTR_NOSYMFOLLOW; ++ ++ if (mnt_flags & MNT_NOATIME) ++ attr_flags |= MOUNT_ATTR_NOATIME; ++ else if (mnt_flags & MNT_RELATIME) ++ attr_flags |= MOUNT_ATTR_RELATIME; ++ else ++ attr_flags |= MOUNT_ATTR_STRICTATIME; ++ ++ if (is_idmapped_mnt(mnt)) ++ attr_flags |= MOUNT_ATTR_IDMAP; ++ ++ return attr_flags; ++ } ++ ++ static u64 mnt_to_propagation_flags(struct mount *m) ++ { ++ u64 propagation = 0; ++ ++ if (IS_MNT_SHARED(m)) ++ propagation |= MS_SHARED; ++ if (IS_MNT_SLAVE(m)) ++ propagation |= MS_SLAVE; ++ if (IS_MNT_UNBINDABLE(m)) ++ propagation |= MS_UNBINDABLE; ++ if (!propagation) ++ propagation |= MS_PRIVATE; ++ ++ return propagation; ++ } ++ ++ u64 vfsmount_to_propagation_flags(struct vfsmount *mnt) ++ { ++ return mnt_to_propagation_flags(real_mount(mnt)); ++ } ++ EXPORT_SYMBOL_GPL(vfsmount_to_propagation_flags); ++ ++ static void statmount_sb_basic(struct kstatmount *s) ++ { ++ struct super_block *sb = s->mnt->mnt_sb; ++ ++ s->sm.mask |= STATMOUNT_SB_BASIC; ++ s->sm.sb_dev_major = MAJOR(sb->s_dev); ++ s->sm.sb_dev_minor = MINOR(sb->s_dev); ++ s->sm.sb_magic = sb->s_magic; ++ s->sm.sb_flags = sb->s_flags & (SB_RDONLY|SB_SYNCHRONOUS|SB_DIRSYNC|SB_LAZYTIME); ++ } ++ ++ static void statmount_mnt_basic(struct kstatmount *s) ++ { ++ struct mount *m = real_mount(s->mnt); ++ ++ s->sm.mask |= STATMOUNT_MNT_BASIC; ++ s->sm.mnt_id = m->mnt_id_unique; ++ s->sm.mnt_parent_id = m->mnt_parent->mnt_id_unique; ++ s->sm.mnt_id_old = m->mnt_id; ++ s->sm.mnt_parent_id_old = m->mnt_parent->mnt_id; ++ s->sm.mnt_attr = mnt_to_attr_flags(&m->mnt); ++ s->sm.mnt_propagation = mnt_to_propagation_flags(m); ++ s->sm.mnt_peer_group = m->mnt_group_id; ++ s->sm.mnt_master = IS_MNT_SLAVE(m) ? m->mnt_master->mnt_group_id : 0; ++ } ++ ++ static void statmount_propagate_from(struct kstatmount *s) ++ { ++ struct mount *m = real_mount(s->mnt); ++ ++ s->sm.mask |= STATMOUNT_PROPAGATE_FROM; ++ if (IS_MNT_SLAVE(m)) ++ s->sm.propagate_from = get_dominating_id(m, ¤t->fs->root); ++ } ++ ++ static int statmount_mnt_root(struct kstatmount *s, struct seq_file *seq) ++ { ++ int ret; ++ size_t start = seq->count; ++ ++ ret = show_path(seq, s->mnt->mnt_root); ++ if (ret) ++ return ret; ++ ++ if (unlikely(seq_has_overflowed(seq))) ++ return -EAGAIN; ++ ++ /* ++ * Unescape the result. It would be better if supplied string was not ++ * escaped in the first place, but that's a pretty invasive change. ++ */ ++ seq->buf[seq->count] = '\0'; ++ seq->count = start; ++ seq_commit(seq, string_unescape_inplace(seq->buf + start, UNESCAPE_OCTAL)); ++ return 0; ++ } ++ ++ static int statmount_mnt_point(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct vfsmount *mnt = s->mnt; ++ struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; ++ int err; ++ ++ err = seq_path_root(seq, &mnt_path, &s->root, ""); ++ return err == SEQ_SKIP ? 0 : err; ++ } ++ ++ static int statmount_fs_type(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct super_block *sb = s->mnt->mnt_sb; ++ ++ seq_puts(seq, sb->s_type->name); ++ return 0; ++ } ++ ++ static void statmount_fs_subtype(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct super_block *sb = s->mnt->mnt_sb; ++ ++ if (sb->s_subtype) ++ seq_puts(seq, sb->s_subtype); ++ } ++ ++ static int statmount_sb_source(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct super_block *sb = s->mnt->mnt_sb; ++ struct mount *r = real_mount(s->mnt); ++ ++ if (sb->s_op->show_devname) { ++ size_t start = seq->count; ++ int ret; ++ ++ ret = sb->s_op->show_devname(seq, s->mnt->mnt_root); ++ if (ret) ++ return ret; ++ ++ if (unlikely(seq_has_overflowed(seq))) ++ return -EAGAIN; ++ ++ /* Unescape the result */ ++ seq->buf[seq->count] = '\0'; ++ seq->count = start; ++ seq_commit(seq, string_unescape_inplace(seq->buf + start, UNESCAPE_OCTAL)); ++ } else { ++ seq_puts(seq, r->mnt_devname); ++ } ++ return 0; ++ } ++ ++ static void statmount_mnt_ns_id(struct kstatmount *s, struct mnt_namespace *ns) ++ { ++ s->sm.mask |= STATMOUNT_MNT_NS_ID; ++ s->sm.mnt_ns_id = ns->ns.ns_id; ++ } ++ ++ static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct vfsmount *mnt = s->mnt; ++ struct super_block *sb = mnt->mnt_sb; ++ size_t start = seq->count; ++ int err; ++ ++ err = security_sb_show_options(seq, sb); ++ if (err) ++ return err; ++ ++ if (sb->s_op->show_options) { ++ err = sb->s_op->show_options(seq, mnt->mnt_root); ++ if (err) ++ return err; ++ } ++ ++ if (unlikely(seq_has_overflowed(seq))) ++ return -EAGAIN; ++ ++ if (seq->count == start) ++ return 0; ++ ++ /* skip leading comma */ ++ memmove(seq->buf + start, seq->buf + start + 1, ++ seq->count - start - 1); ++ seq->count--; ++ ++ return 0; ++ } ++ ++ static inline int statmount_opt_process(struct seq_file *seq, size_t start) ++ { ++ char *buf_end, *opt_end, *src, *dst; ++ int count = 0; ++ ++ if (unlikely(seq_has_overflowed(seq))) ++ return -EAGAIN; ++ ++ buf_end = seq->buf + seq->count; ++ dst = seq->buf + start; ++ src = dst + 1; /* skip initial comma */ ++ ++ if (src >= buf_end) { ++ seq->count = start; ++ return 0; ++ } ++ ++ *buf_end = '\0'; ++ for (; src < buf_end; src = opt_end + 1) { ++ opt_end = strchrnul(src, ','); ++ *opt_end = '\0'; ++ dst += string_unescape(src, dst, 0, UNESCAPE_OCTAL) + 1; ++ if (WARN_ON_ONCE(++count == INT_MAX)) ++ return -EOVERFLOW; ++ } ++ seq->count = dst - 1 - seq->buf; ++ return count; ++ } ++ ++ static int statmount_opt_array(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct vfsmount *mnt = s->mnt; ++ struct super_block *sb = mnt->mnt_sb; ++ size_t start = seq->count; ++ int err; ++ ++ if (!sb->s_op->show_options) ++ return 0; ++ ++ err = sb->s_op->show_options(seq, mnt->mnt_root); ++ if (err) ++ return err; ++ ++ err = statmount_opt_process(seq, start); ++ if (err < 0) ++ return err; ++ ++ s->sm.opt_num = err; ++ return 0; ++ } ++ ++ static int statmount_opt_sec_array(struct kstatmount *s, struct seq_file *seq) ++ { ++ struct vfsmount *mnt = s->mnt; ++ struct super_block *sb = mnt->mnt_sb; ++ size_t start = seq->count; ++ int err; ++ ++ err = security_sb_show_options(seq, sb); ++ if (err) ++ return err; ++ ++ err = statmount_opt_process(seq, start); ++ if (err < 0) ++ return err; ++ ++ s->sm.opt_sec_num = err; ++ return 0; ++ } ++ ++ static inline int statmount_mnt_uidmap(struct kstatmount *s, struct seq_file *seq) ++ { ++ int ret; ++ ++ ret = statmount_mnt_idmap(s->idmap, seq, true); ++ if (ret < 0) ++ return ret; ++ ++ s->sm.mnt_uidmap_num = ret; ++ /* ++ * Always raise STATMOUNT_MNT_UIDMAP even if there are no valid ++ * mappings. This allows userspace to distinguish between a ++ * non-idmapped mount and an idmapped mount where none of the ++ * individual mappings are valid in the caller's idmapping. ++ */ ++ if (is_valid_mnt_idmap(s->idmap)) ++ s->sm.mask |= STATMOUNT_MNT_UIDMAP; ++ return 0; ++ } ++ ++ static inline int statmount_mnt_gidmap(struct kstatmount *s, struct seq_file *seq) ++ { ++ int ret; ++ ++ ret = statmount_mnt_idmap(s->idmap, seq, false); ++ if (ret < 0) ++ return ret; ++ ++ s->sm.mnt_gidmap_num = ret; ++ /* ++ * Always raise STATMOUNT_MNT_GIDMAP even if there are no valid ++ * mappings. This allows userspace to distinguish between a ++ * non-idmapped mount and an idmapped mount where none of the ++ * individual mappings are valid in the caller's idmapping. ++ */ ++ if (is_valid_mnt_idmap(s->idmap)) ++ s->sm.mask |= STATMOUNT_MNT_GIDMAP; ++ return 0; ++ } ++ ++ static int statmount_string(struct kstatmount *s, u64 flag) ++ { ++ int ret = 0; ++ size_t kbufsize; ++ struct seq_file *seq = &s->seq; ++ struct statmount *sm = &s->sm; ++ u32 start, *offp; ++ ++ /* Reserve an empty string at the beginning for any unset offsets */ ++ if (!seq->count) ++ seq_putc(seq, 0); ++ ++ start = seq->count; ++ ++ switch (flag) { ++ case STATMOUNT_FS_TYPE: ++ offp = &sm->fs_type; ++ ret = statmount_fs_type(s, seq); ++ break; ++ case STATMOUNT_MNT_ROOT: ++ offp = &sm->mnt_root; ++ ret = statmount_mnt_root(s, seq); ++ break; ++ case STATMOUNT_MNT_POINT: ++ offp = &sm->mnt_point; ++ ret = statmount_mnt_point(s, seq); ++ break; ++ case STATMOUNT_MNT_OPTS: ++ offp = &sm->mnt_opts; ++ ret = statmount_mnt_opts(s, seq); ++ break; ++ case STATMOUNT_OPT_ARRAY: ++ offp = &sm->opt_array; ++ ret = statmount_opt_array(s, seq); ++ break; ++ case STATMOUNT_OPT_SEC_ARRAY: ++ offp = &sm->opt_sec_array; ++ ret = statmount_opt_sec_array(s, seq); ++ break; ++ case STATMOUNT_FS_SUBTYPE: ++ offp = &sm->fs_subtype; ++ statmount_fs_subtype(s, seq); ++ break; ++ case STATMOUNT_SB_SOURCE: ++ offp = &sm->sb_source; ++ ret = statmount_sb_source(s, seq); ++ break; ++ case STATMOUNT_MNT_UIDMAP: ++ sm->mnt_uidmap = start; ++ ret = statmount_mnt_uidmap(s, seq); ++ break; ++ case STATMOUNT_MNT_GIDMAP: ++ sm->mnt_gidmap = start; ++ ret = statmount_mnt_gidmap(s, seq); ++ break; ++ default: ++ WARN_ON_ONCE(true); ++ return -EINVAL; ++ } ++ ++ /* ++ * If nothing was emitted, return to avoid setting the flag ++ * and terminating the buffer. ++ */ ++ if (seq->count == start) ++ return ret; ++ if (unlikely(check_add_overflow(sizeof(*sm), seq->count, &kbufsize))) ++ return -EOVERFLOW; ++ if (kbufsize >= s->bufsize) ++ return -EOVERFLOW; ++ ++ /* signal a retry */ ++ if (unlikely(seq_has_overflowed(seq))) ++ return -EAGAIN; ++ ++ if (ret) ++ return ret; ++ ++ seq->buf[seq->count++] = '\0'; ++ sm->mask |= flag; ++ *offp = start; ++ return 0; ++ } ++ ++ static int copy_statmount_to_user(struct kstatmount *s) ++ { ++ struct statmount *sm = &s->sm; ++ struct seq_file *seq = &s->seq; ++ char __user *str = ((char __user *)s->buf) + sizeof(*sm); ++ size_t copysize = min_t(size_t, s->bufsize, sizeof(*sm)); ++ ++ if (seq->count && copy_to_user(str, seq->buf, seq->count)) ++ return -EFAULT; ++ ++ /* Return the number of bytes copied to the buffer */ ++ sm->size = copysize + seq->count; ++ if (copy_to_user(s->buf, sm, copysize)) ++ return -EFAULT; ++ ++ return 0; ++ } ++ ++ static struct mount *listmnt_next(struct mount *curr, bool reverse) ++ { ++ struct rb_node *node; ++ ++ if (reverse) ++ node = rb_prev(&curr->mnt_node); ++ else ++ node = rb_next(&curr->mnt_node); ++ ++ return node_to_mount(node); ++ } ++ ++ static int grab_requested_root(struct mnt_namespace *ns, struct path *root) ++ { ++ struct mount *first, *child; ++ ++ rwsem_assert_held(&namespace_sem); ++ ++ /* We're looking at our own ns, just use get_fs_root. */ ++ if (ns == current->nsproxy->mnt_ns) { ++ get_fs_root(current->fs, root); ++ return 0; ++ } ++ ++ /* ++ * We have to find the first mount in our ns and use that, however it ++ * may not exist, so handle that properly. ++ */ ++ if (mnt_ns_empty(ns)) ++ return -ENOENT; ++ ++ first = child = ns->root; ++ for (;;) { ++ child = listmnt_next(child, false); ++ if (!child) ++ return -ENOENT; ++ if (child->mnt_parent == first) ++ break; ++ } ++ ++ root->mnt = mntget(&child->mnt); ++ root->dentry = dget(root->mnt->mnt_root); ++ return 0; ++ } ++ ++ /* This must be updated whenever a new flag is added */ ++ #define STATMOUNT_SUPPORTED (STATMOUNT_SB_BASIC | \ ++ STATMOUNT_MNT_BASIC | \ ++ STATMOUNT_PROPAGATE_FROM | \ ++ STATMOUNT_MNT_ROOT | \ ++ STATMOUNT_MNT_POINT | \ ++ STATMOUNT_FS_TYPE | \ ++ STATMOUNT_MNT_NS_ID | \ ++ STATMOUNT_MNT_OPTS | \ ++ STATMOUNT_FS_SUBTYPE | \ ++ STATMOUNT_SB_SOURCE | \ ++ STATMOUNT_OPT_ARRAY | \ ++ STATMOUNT_OPT_SEC_ARRAY | \ ++ STATMOUNT_SUPPORTED_MASK | \ ++ STATMOUNT_MNT_UIDMAP | \ ++ STATMOUNT_MNT_GIDMAP) ++ ++ /* locks: namespace_shared */ ++ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id, ++ struct mnt_namespace *ns) ++ { ++ struct mount *m; ++ int err; ++ ++ /* Has the namespace already been emptied? */ ++ if (mnt_ns_id && mnt_ns_empty(ns)) ++ return -ENOENT; ++ ++ s->mnt = lookup_mnt_in_ns(mnt_id, ns); ++ if (!s->mnt) ++ return -ENOENT; ++ ++ err = grab_requested_root(ns, &s->root); ++ if (err) ++ return err; ++ ++ /* ++ * Don't trigger audit denials. We just want to determine what ++ * mounts to show users. ++ */ ++ m = real_mount(s->mnt); ++ if (!is_path_reachable(m, m->mnt.mnt_root, &s->root) && ++ !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) ++ return -EPERM; ++ ++ err = security_sb_statfs(s->mnt->mnt_root); ++ if (err) ++ return err; ++ ++ /* ++ * Note that mount properties in mnt->mnt_flags, mnt->mnt_idmap ++ * can change concurrently as we only hold the read-side of the ++ * namespace semaphore and mount properties may change with only ++ * the mount lock held. ++ * ++ * We could sample the mount lock sequence counter to detect ++ * those changes and retry. But it's not worth it. Worst that ++ * happens is that the mnt->mnt_idmap pointer is already changed ++ * while mnt->mnt_flags isn't or vica versa. So what. ++ * ++ * Both mnt->mnt_flags and mnt->mnt_idmap are set and retrieved ++ * via READ_ONCE()/WRITE_ONCE() and guard against theoretical ++ * torn read/write. That's all we care about right now. ++ */ ++ s->idmap = mnt_idmap(s->mnt); ++ if (s->mask & STATMOUNT_MNT_BASIC) ++ statmount_mnt_basic(s); ++ ++ if (s->mask & STATMOUNT_SB_BASIC) ++ statmount_sb_basic(s); ++ ++ if (s->mask & STATMOUNT_PROPAGATE_FROM) ++ statmount_propagate_from(s); ++ ++ if (s->mask & STATMOUNT_FS_TYPE) ++ err = statmount_string(s, STATMOUNT_FS_TYPE); ++ ++ if (!err && s->mask & STATMOUNT_MNT_ROOT) ++ err = statmount_string(s, STATMOUNT_MNT_ROOT); ++ ++ if (!err && s->mask & STATMOUNT_MNT_POINT) ++ err = statmount_string(s, STATMOUNT_MNT_POINT); ++ ++ if (!err && s->mask & STATMOUNT_MNT_OPTS) ++ err = statmount_string(s, STATMOUNT_MNT_OPTS); ++ ++ if (!err && s->mask & STATMOUNT_OPT_ARRAY) ++ err = statmount_string(s, STATMOUNT_OPT_ARRAY); ++ ++ if (!err && s->mask & STATMOUNT_OPT_SEC_ARRAY) ++ err = statmount_string(s, STATMOUNT_OPT_SEC_ARRAY); ++ ++ if (!err && s->mask & STATMOUNT_FS_SUBTYPE) ++ err = statmount_string(s, STATMOUNT_FS_SUBTYPE); ++ ++ if (!err && s->mask & STATMOUNT_SB_SOURCE) ++ err = statmount_string(s, STATMOUNT_SB_SOURCE); ++ ++ if (!err && s->mask & STATMOUNT_MNT_UIDMAP) ++ err = statmount_string(s, STATMOUNT_MNT_UIDMAP); ++ ++ if (!err && s->mask & STATMOUNT_MNT_GIDMAP) ++ err = statmount_string(s, STATMOUNT_MNT_GIDMAP); ++ ++ if (!err && s->mask & STATMOUNT_MNT_NS_ID) ++ statmount_mnt_ns_id(s, ns); ++ ++ if (!err && s->mask & STATMOUNT_SUPPORTED_MASK) { ++ s->sm.mask |= STATMOUNT_SUPPORTED_MASK; ++ s->sm.supported_mask = STATMOUNT_SUPPORTED; ++ } ++ ++ if (err) ++ return err; ++ ++ /* Are there bits in the return mask not present in STATMOUNT_SUPPORTED? */ ++ WARN_ON_ONCE(~STATMOUNT_SUPPORTED & s->sm.mask); ++ ++ return 0; ++ } ++ ++ static inline bool retry_statmount(const long ret, size_t *seq_size) ++ { ++ if (likely(ret != -EAGAIN)) ++ return false; ++ if (unlikely(check_mul_overflow(*seq_size, 2, seq_size))) ++ return false; ++ if (unlikely(*seq_size > MAX_RW_COUNT)) ++ return false; ++ return true; ++ } ++ ++ #define STATMOUNT_STRING_REQ (STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT | \ ++ STATMOUNT_FS_TYPE | STATMOUNT_MNT_OPTS | \ ++ STATMOUNT_FS_SUBTYPE | STATMOUNT_SB_SOURCE | \ ++ STATMOUNT_OPT_ARRAY | STATMOUNT_OPT_SEC_ARRAY | \ ++ STATMOUNT_MNT_UIDMAP | STATMOUNT_MNT_GIDMAP) ++ ++ static int prepare_kstatmount(struct kstatmount *ks, struct mnt_id_req *kreq, ++ struct statmount __user *buf, size_t bufsize, ++ size_t seq_size) ++ { ++ if (!access_ok(buf, bufsize)) ++ return -EFAULT; ++ ++ memset(ks, 0, sizeof(*ks)); ++ ks->mask = kreq->param; ++ ks->buf = buf; ++ ks->bufsize = bufsize; ++ ++ if (ks->mask & STATMOUNT_STRING_REQ) { ++ if (bufsize == sizeof(ks->sm)) ++ return -EOVERFLOW; ++ ++ ks->seq.buf = kvmalloc(seq_size, GFP_KERNEL_ACCOUNT); ++ if (!ks->seq.buf) ++ return -ENOMEM; ++ ++ ks->seq.size = seq_size; ++ } ++ ++ return 0; ++ } ++ ++ static int copy_mnt_id_req(const struct mnt_id_req __user *req, ++ struct mnt_id_req *kreq) ++ { ++ int ret; ++ size_t usize; ++ ++ BUILD_BUG_ON(sizeof(struct mnt_id_req) != MNT_ID_REQ_SIZE_VER1); ++ ++ ret = get_user(usize, &req->size); ++ if (ret) ++ return -EFAULT; ++ if (unlikely(usize > PAGE_SIZE)) ++ return -E2BIG; ++ if (unlikely(usize < MNT_ID_REQ_SIZE_VER0)) ++ return -EINVAL; ++ memset(kreq, 0, sizeof(*kreq)); ++ ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize); ++ if (ret) ++ return ret; ++ if (kreq->spare != 0) ++ return -EINVAL; ++ /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ ++ if (kreq->mnt_id <= MNT_UNIQUE_ID_OFFSET) ++ return -EINVAL; ++ return 0; ++ } ++ ++ /* ++ * If the user requested a specific mount namespace id, look that up and return ++ * that, or if not simply grab a passive reference on our mount namespace and ++ * return that. ++ */ ++ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq) ++ { ++ struct mnt_namespace *mnt_ns; ++ ++ if (kreq->mnt_ns_id && kreq->spare) ++ return ERR_PTR(-EINVAL); ++ ++ if (kreq->mnt_ns_id) ++ return lookup_mnt_ns(kreq->mnt_ns_id); ++ ++ if (kreq->spare) { ++ struct ns_common *ns; ++ ++ CLASS(fd, f)(kreq->spare); ++ if (fd_empty(f)) ++ return ERR_PTR(-EBADF); ++ ++ if (!proc_ns_file(fd_file(f))) ++ return ERR_PTR(-EINVAL); ++ ++ ns = get_proc_ns(file_inode(fd_file(f))); ++ if (ns->ns_type != CLONE_NEWNS) ++ return ERR_PTR(-EINVAL); ++ ++ mnt_ns = to_mnt_ns(ns); ++ } else { ++ mnt_ns = current->nsproxy->mnt_ns; ++ } ++ ++ refcount_inc(&mnt_ns->passive); ++ return mnt_ns; ++ } ++ ++ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, ++ struct statmount __user *, buf, size_t, bufsize, ++ unsigned int, flags) ++ { ++ struct mnt_namespace *ns __free(mnt_ns_release) = NULL; ++ struct kstatmount *ks __free(kfree) = NULL; ++ struct mnt_id_req kreq; ++ /* We currently support retrieval of 3 strings. */ ++ size_t seq_size = 3 * PATH_MAX; ++ int ret; ++ ++ if (flags) ++ return -EINVAL; ++ ++ ret = copy_mnt_id_req(req, &kreq); ++ if (ret) ++ return ret; ++ ++ ns = grab_requested_mnt_ns(&kreq); ++ if (!ns) ++ return -ENOENT; ++ ++ if (kreq.mnt_ns_id && (ns != current->nsproxy->mnt_ns) && ++ !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) ++ return -ENOENT; ++ ++ ks = kmalloc(sizeof(*ks), GFP_KERNEL_ACCOUNT); ++ if (!ks) ++ return -ENOMEM; ++ ++ retry: ++ ret = prepare_kstatmount(ks, &kreq, buf, bufsize, seq_size); ++ if (ret) ++ return ret; ++ ++ scoped_guard(namespace_shared) ++ ret = do_statmount(ks, kreq.mnt_id, kreq.mnt_ns_id, ns); ++ ++ if (!ret) ++ ret = copy_statmount_to_user(ks); ++ kvfree(ks->seq.buf); ++ path_put(&ks->root); ++ if (retry_statmount(ret, &seq_size)) ++ goto retry; ++ return ret; ++ } ++ ++ struct klistmount { ++ u64 last_mnt_id; ++ u64 mnt_parent_id; ++ u64 *kmnt_ids; ++ u32 nr_mnt_ids; ++ struct mnt_namespace *ns; ++ struct path root; ++ }; ++ ++ /* locks: namespace_shared */ ++ static ssize_t do_listmount(struct klistmount *kls, bool reverse) ++ { ++ struct mnt_namespace *ns = kls->ns; ++ u64 mnt_parent_id = kls->mnt_parent_id; ++ u64 last_mnt_id = kls->last_mnt_id; ++ u64 *mnt_ids = kls->kmnt_ids; ++ size_t nr_mnt_ids = kls->nr_mnt_ids; ++ struct path orig; ++ struct mount *r, *first; ++ ssize_t ret; ++ ++ rwsem_assert_held(&namespace_sem); ++ ++ ret = grab_requested_root(ns, &kls->root); ++ if (ret) ++ return ret; ++ ++ if (mnt_parent_id == LSMT_ROOT) { ++ orig = kls->root; ++ } else { ++ orig.mnt = lookup_mnt_in_ns(mnt_parent_id, ns); ++ if (!orig.mnt) ++ return -ENOENT; ++ orig.dentry = orig.mnt->mnt_root; ++ } ++ ++ /* ++ * Don't trigger audit denials. We just want to determine what ++ * mounts to show users. ++ */ ++ if (!is_path_reachable(real_mount(orig.mnt), orig.dentry, &kls->root) && ++ !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) ++ return -EPERM; ++ ++ ret = security_sb_statfs(orig.dentry); ++ if (ret) ++ return ret; ++ ++ if (!last_mnt_id) { ++ if (reverse) ++ first = node_to_mount(ns->mnt_last_node); ++ else ++ first = node_to_mount(ns->mnt_first_node); ++ } else { ++ if (reverse) ++ first = mnt_find_id_at_reverse(ns, last_mnt_id - 1); ++ else ++ first = mnt_find_id_at(ns, last_mnt_id + 1); ++ } ++ ++ for (ret = 0, r = first; r && nr_mnt_ids; r = listmnt_next(r, reverse)) { ++ if (r->mnt_id_unique == mnt_parent_id) ++ continue; ++ if (!is_path_reachable(r, r->mnt.mnt_root, &orig)) ++ continue; ++ *mnt_ids = r->mnt_id_unique; ++ mnt_ids++; ++ nr_mnt_ids--; ++ ret++; ++ } ++ return ret; ++ } ++ ++ static void __free_klistmount_free(const struct klistmount *kls) ++ { ++ path_put(&kls->root); ++ kvfree(kls->kmnt_ids); ++ mnt_ns_release(kls->ns); ++ } ++ ++ static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *kreq, ++ size_t nr_mnt_ids) ++ { ++ ++ u64 last_mnt_id = kreq->param; ++ ++ /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ ++ if (last_mnt_id != 0 && last_mnt_id <= MNT_UNIQUE_ID_OFFSET) ++ return -EINVAL; ++ ++ kls->last_mnt_id = last_mnt_id; ++ ++ kls->nr_mnt_ids = nr_mnt_ids; ++ kls->kmnt_ids = kvmalloc_array(nr_mnt_ids, sizeof(*kls->kmnt_ids), ++ GFP_KERNEL_ACCOUNT); ++ if (!kls->kmnt_ids) ++ return -ENOMEM; ++ ++ kls->ns = grab_requested_mnt_ns(kreq); ++ if (!kls->ns) ++ return -ENOENT; ++ ++ kls->mnt_parent_id = kreq->mnt_id; ++ return 0; ++ } ++ ++ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, ++ u64 __user *, mnt_ids, size_t, nr_mnt_ids, unsigned int, flags) ++ { ++ struct klistmount kls __free(klistmount_free) = {}; ++ const size_t maxcount = 1000000; ++ struct mnt_id_req kreq; ++ ssize_t ret; ++ ++ if (flags & ~LISTMOUNT_REVERSE) ++ return -EINVAL; ++ ++ /* ++ * If the mount namespace really has more than 1 million mounts the ++ * caller must iterate over the mount namespace (and reconsider their ++ * system design...). ++ */ ++ if (unlikely(nr_mnt_ids > maxcount)) ++ return -EOVERFLOW; ++ ++ if (!access_ok(mnt_ids, nr_mnt_ids * sizeof(*mnt_ids))) ++ return -EFAULT; ++ ++ ret = copy_mnt_id_req(req, &kreq); ++ if (ret) ++ return ret; ++ ++ ret = prepare_klistmount(&kls, &kreq, nr_mnt_ids); ++ if (ret) ++ return ret; ++ ++ if (kreq.mnt_ns_id && (kls.ns != current->nsproxy->mnt_ns) && ++ !ns_capable_noaudit(kls.ns->user_ns, CAP_SYS_ADMIN)) ++ return -ENOENT; ++ ++ /* ++ * We only need to guard against mount topology changes as ++ * listmount() doesn't care about any mount properties. ++ */ ++ scoped_guard(namespace_shared) ++ ret = do_listmount(&kls, (flags & LISTMOUNT_REVERSE)); ++ if (ret <= 0) ++ return ret; ++ ++ if (copy_to_user(mnt_ids, kls.kmnt_ids, ret * sizeof(*mnt_ids))) ++ return -EFAULT; ++ ++ return ret; ++ } ++ ++ struct mnt_namespace init_mnt_ns = { ++ .ns.inum = ns_init_inum(&init_mnt_ns), ++ .ns.ops = &mntns_operations, ++ .user_ns = &init_user_ns, ++ .ns.__ns_ref = REFCOUNT_INIT(1), ++ .ns.ns_type = ns_common_type(&init_mnt_ns), ++ .passive = REFCOUNT_INIT(1), ++ .mounts = RB_ROOT, ++ .poll = __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll), ++ }; ++ +++>>>>>>> 922a6f34c175 (autofs: dont trigger mount if it cant succeed) + static void __init init_mount_tree(void) + { + struct vfsmount *mnt; +* Unmerged path fs/autofs/autofs_i.h +diff --git a/fs/autofs/dev-ioctl.c b/fs/autofs/dev-ioctl.c +index 6d57efbb8110..67c76e6590f9 100644 +--- a/fs/autofs/dev-ioctl.c ++++ b/fs/autofs/dev-ioctl.c +@@ -381,6 +381,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, + swap(sbi->oz_pgrp, new_pid); + sbi->pipefd = pipefd; + sbi->pipe = pipe; ++ sbi->mnt_ns_id = to_ns_common(current->nsproxy->mnt_ns)->ns_id; + sbi->flags &= ~AUTOFS_SBI_CATATONIC; + } + out: +* Unmerged path fs/autofs/inode.c +diff --git a/fs/autofs/root.c b/fs/autofs/root.c +index 6baf90b08e0e..05b908c965a9 100644 +--- a/fs/autofs/root.c ++++ b/fs/autofs/root.c +@@ -341,6 +341,14 @@ static struct vfsmount *autofs_d_automount(struct path *path) + if (autofs_oz_mode(sbi)) + return NULL; + ++ /* Refuse to trigger mount if current namespace is not the owner ++ * and the mount is propagation private. ++ */ ++ if (sbi->mnt_ns_id != to_ns_common(current->nsproxy->mnt_ns)->ns_id) { ++ if (vfsmount_to_propagation_flags(path->mnt) & MS_PRIVATE) ++ return ERR_PTR(-EPERM); ++ } ++ + /* + * If an expire request is pending everyone must wait. + * If the expire fails we're still mounted so continue +* Unmerged path fs/namespace.c +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 53cf26162c5d..d02f204c7eb9 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2808,6 +2808,7 @@ extern struct file * open_exec(const char *); + /* fs/dcache.c -- generic fs support functions */ + extern bool is_subdir(struct dentry *, struct dentry *); + extern bool path_is_under(const struct path *, const struct path *); ++u64 vfsmount_to_propagation_flags(struct vfsmount *mnt); + + extern char *file_path(struct file *, char *, int); + From 4d681495ec95fd2cc307d0ecab7de0e56d5d70c8 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:38 -0500 Subject: [PATCH 12/13] net/smc: Remove validation of reserved bits in CLC Decline message jira KERNEL-703 Rebuild_History Non-Buildable kernel-5.14.0-611.36.1.el9_7 commit-author Mahanta Jambigi commit cc282f73bc0cbdf3ee7af2f2d3a2ef4e6b19242d Currently SMC code is validating the reserved bits while parsing the incoming CLC decline message & when this validation fails, its treated as a protocol error. As a result, the SMC connection is terminated instead of falling back to TCP. As per RFC7609[1] specs we shouldn't be validating the reserved bits that is part of CLC message. This patch fixes this issue. CLC Decline message format can viewed here[2]. [1] https://datatracker.ietf.org/doc/html/rfc7609#page-92 [2] https://datatracker.ietf.org/doc/html/rfc7609#page-105 Fixes: 8ade200c269f ("net/smc: add v2 format of CLC decline message") Signed-off-by: Mahanta Jambigi Reviewed-by: Sidraya Jayagond Reviewed-by: Alexandra Winter Reviewed-by: Dust Li Link: https://patch.msgid.link/20250902082041.98996-1-mjambigi@linux.ibm.com Signed-off-by: Jakub Kicinski (cherry picked from commit cc282f73bc0cbdf3ee7af2f2d3a2ef4e6b19242d) Signed-off-by: Jonathan Maple --- net/smc/smc_clc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index f2065ed66d0c0..f86161201e065 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c @@ -426,8 +426,6 @@ smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc) { struct smc_clc_msg_hdr *hdr = &dclc->hdr; - if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D) - return false; if (hdr->version == SMC_V1) { if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline)) return false; From 52342fd2bff05234cd1abbd3509551b77c8fe8cc Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 3 Mar 2026 00:01:52 -0500 Subject: [PATCH 13/13] Rebuild rocky9_7 with kernel-5.14.0-611.36.1.el9_7 Rebuild_History BUILDABLE Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% Number of commits in upstream range v5.14~1..kernel-mainline: 351590 Number of commits in rpm: 28 Number of commits matched with upstream: 12 (42.86%) Number of commits in upstream but not in rpm: 351578 Number of commits NOT found in upstream: 16 (57.14%) Rebuilding Kernel on Branch rocky9_7_rebuild_kernel-5.14.0-611.36.1.el9_7 for kernel-5.14.0-611.36.1.el9_7 Clean Cherry Picks: 6 (50.00%) Empty Cherry Picks: 6 (50.00%) _______________________________ Full Details Located here: ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/rebuild.details.txt Includes: * git commit header above * Empty Commits with upstream SHA * RPM ChangeLog Entries that could not be matched Individual Empty Commit failures contained in the same containing directory. The git message for empty commits will have the path for the failed commit. File names are the first 8 characters of the upstream SHA --- ...5.1.el9_7 => COPYING-5.14.0-611.36.1.el9_7 | 0 Documentation/netlink/specs/dpll.yaml | 12 ++ Documentation/netlink/specs/fou.yaml | 2 + Makefile.rhelver | 2 +- arch/s390/include/asm/pgtable.h | 12 +- arch/s390/mm/pgtable.c | 4 +- .../rebuild.details.txt | 38 +++++ .../kernel-5.14.0-aarch64-64k-debug.config | 6 +- configs/kernel-5.14.0-aarch64-64k.config | 6 +- configs/kernel-5.14.0-aarch64-debug.config | 6 +- .../kernel-5.14.0-aarch64-rt-64k-debug.config | 6 +- configs/kernel-5.14.0-aarch64-rt-64k.config | 6 +- configs/kernel-5.14.0-aarch64-rt-debug.config | 6 +- configs/kernel-5.14.0-aarch64-rt.config | 6 +- configs/kernel-5.14.0-aarch64.config | 6 +- configs/kernel-5.14.0-ppc64le-debug.config | 6 +- configs/kernel-5.14.0-ppc64le.config | 6 +- configs/kernel-5.14.0-s390x-debug.config | 6 +- configs/kernel-5.14.0-s390x.config | 6 +- configs/kernel-5.14.0-x86_64-debug.config | 6 +- configs/kernel-5.14.0-x86_64-rt-debug.config | 6 +- configs/kernel-5.14.0-x86_64-rt.config | 6 +- configs/kernel-5.14.0-x86_64.config | 6 +- configs/kernel-aarch64-64k-debug-rhel.config | 4 +- configs/kernel-aarch64-64k-rhel.config | 4 +- configs/kernel-aarch64-debug-rhel.config | 4 +- configs/kernel-aarch64-rhel.config | 4 +- .../kernel-aarch64-rt-64k-debug-rhel.config | 4 +- configs/kernel-aarch64-rt-64k-rhel.config | 4 +- configs/kernel-aarch64-rt-debug-rhel.config | 4 +- configs/kernel-aarch64-rt-rhel.config | 4 +- configs/kernel-ppc64le-debug-rhel.config | 4 +- configs/kernel-ppc64le-rhel.config | 4 +- configs/kernel-s390x-debug-rhel.config | 4 +- configs/kernel-s390x-rhel.config | 4 +- configs/kernel-s390x-zfcpdump-rhel.config | 4 +- configs/kernel-x86_64-debug-rhel.config | 4 +- configs/kernel-x86_64-rhel.config | 4 +- configs/kernel-x86_64-rt-debug-rhel.config | 4 +- configs/kernel-x86_64-rt-rhel.config | 4 +- configs/mod-extra.list | 2 + drivers/dpll/dpll_netlink.c | 81 ++++++++-- drivers/dpll/dpll_nl.c | 1 + drivers/dpll/zl3073x/core.c | 7 +- drivers/dpll/zl3073x/dpll.c | 112 +++++++++++++ .../net/ethernet/intel/i40e/i40e_devlink.c | 6 +- drivers/net/ethernet/intel/ice/ice_main.c | 27 ++-- drivers/net/ethernet/intel/ice/ice_ptp.c | 148 ++++++++++-------- drivers/net/ethernet/intel/ice/ice_ptp.h | 13 +- .../net/ethernet/mellanox/mlx5/core/dpll.c | 2 +- drivers/scsi/qla2xxx/qla_bsg.c | 28 ++-- fs/autofs/autofs_i.h | 5 + fs/autofs/dev-ioctl.c | 1 + fs/autofs/inode.c | 1 + fs/autofs/root.c | 8 + fs/namespace.c | 21 +++ include/linux/dpll.h | 7 +- include/linux/fs.h | 1 + include/uapi/linux/dpll.h | 1 + kernel/time/tick-sched.c | 30 +++- mm/migrate.c | 12 +- net/ipv4/fou_core.c | 32 +++- net/ipv4/fou_nl.c | 2 +- redhat/configs/common/generic/CONFIG_NET_FOU | 1 + .../common/generic/CONFIG_NET_FOU_IP_TUNNELS | 1 + redhat/configs/rhel/generic/CONFIG_NET_FOU | 1 - .../rhel/generic/CONFIG_NET_FOU_IP_TUNNELS | 1 - redhat/kernel.changelog-9.7 | 28 ++++ redhat/rhel_files/mod-extra.list.rhel | 2 + tools/net/ynl/ynl-regen.sh | 2 +- 70 files changed, 618 insertions(+), 200 deletions(-) rename COPYING-5.14.0-611.35.1.el9_7 => COPYING-5.14.0-611.36.1.el9_7 (100%) create mode 100644 ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/rebuild.details.txt create mode 100644 redhat/configs/common/generic/CONFIG_NET_FOU create mode 100644 redhat/configs/common/generic/CONFIG_NET_FOU_IP_TUNNELS delete mode 100644 redhat/configs/rhel/generic/CONFIG_NET_FOU delete mode 100644 redhat/configs/rhel/generic/CONFIG_NET_FOU_IP_TUNNELS diff --git a/COPYING-5.14.0-611.35.1.el9_7 b/COPYING-5.14.0-611.36.1.el9_7 similarity index 100% rename from COPYING-5.14.0-611.35.1.el9_7 rename to COPYING-5.14.0-611.36.1.el9_7 diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml index 50188eb74e04f..ed5866238682e 100644 --- a/Documentation/netlink/specs/dpll.yaml +++ b/Documentation/netlink/specs/dpll.yaml @@ -446,6 +446,16 @@ attribute-sets: doc: | Granularity of phase adjustment, in picoseconds. The value of phase adjustment must be a multiple of this granularity. + - + name: fractional-frequency-offset-ppt + type: sint + doc: | + The FFO (Fractional Frequency Offset) of the pin with respect to + the nominal frequency. + Value = (frequency_measured - frequency_nominal) / frequency_nominal + Value is in PPT (parts per trillion, 10^-12). + Note: This attribute provides higher resolution than the standard + fractional-frequency-offset (which is in PPM). - name: pin-parent-device @@ -550,6 +560,7 @@ operations: request: attributes: - id + - mode - phase-offset-monitor - phase-offset-avg-factor - @@ -627,6 +638,7 @@ operations: - phase-adjust-max - phase-adjust - fractional-frequency-offset + - fractional-frequency-offset-ppt - esync-frequency - esync-frequency-supported - esync-pulse diff --git a/Documentation/netlink/specs/fou.yaml b/Documentation/netlink/specs/fou.yaml index b02ab19817d3c..79f8dc5055642 100644 --- a/Documentation/netlink/specs/fou.yaml +++ b/Documentation/netlink/specs/fou.yaml @@ -39,6 +39,8 @@ attribute-sets: - name: ipproto type: u8 + checks: + min: 1 - name: type type: u8 diff --git a/Makefile.rhelver b/Makefile.rhelver index 6ea0bba4c136d..b118f9faf53a1 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 7 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 611.35.1 +RHEL_RELEASE = 611.36.1 # # ZSTREAM diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0a696d0fbf737..e5d44e575a7ed 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1103,17 +1103,15 @@ static inline pte_t pte_mkhuge(pte_t pte) #define IPTE_NODAT 0x400 #define IPTE_GUEST_ASCE 0x800 -static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, - unsigned long opt, unsigned long asce, - int local) +static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, int local) { unsigned long pto; pto = __pa(ptep) & ~(PTRS_PER_PTE * sizeof(pte_t) - 1); - asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%[asce],%[m4]" + asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%%r0,%[m4]" : "+m" (*ptep) - : [r1] "a" (pto), [r2] "a" ((addr & PAGE_MASK) | opt), - [asce] "a" (asce), [m4] "i" (local)); + : [r1] "a" (pto), [r2] "a" (addr & PAGE_MASK), + [m4] "i" (local)); } static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep, @@ -1297,7 +1295,7 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma, * A local RDP can be used to do the flush. */ if (MACHINE_HAS_RDP && !(pte_val(*ptep) & _PAGE_PROTECT)) - __ptep_rdp(address, ptep, 0, 0, 1); + __ptep_rdp(address, ptep, 1); } #define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index c670195c01077..61c6ae698199b 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -303,9 +303,9 @@ void ptep_reset_dat_prot(struct mm_struct *mm, unsigned long addr, pte_t *ptep, preempt_disable(); atomic_inc(&mm->context.flush_count); if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __ptep_rdp(addr, ptep, 0, 0, 1); + __ptep_rdp(addr, ptep, 1); else - __ptep_rdp(addr, ptep, 0, 0, 0); + __ptep_rdp(addr, ptep, 0); /* * PTE is not invalidated by RDP, only _PAGE_PROTECT is cleared. That * means it is still valid and active, and must not be changed according diff --git a/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/rebuild.details.txt b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/rebuild.details.txt new file mode 100644 index 0000000000000..e24e9e736c7ba --- /dev/null +++ b/ciq/ciq_backports/kernel-5.14.0-611.36.1.el9_7/rebuild.details.txt @@ -0,0 +1,38 @@ +Rebuild_History BUILDABLE +Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% +Number of commits in upstream range v5.14~1..kernel-mainline: 351590 +Number of commits in rpm: 28 +Number of commits matched with upstream: 12 (42.86%) +Number of commits in upstream but not in rpm: 351578 +Number of commits NOT found in upstream: 16 (57.14%) + +Rebuilding Kernel on Branch rocky9_7_rebuild_kernel-5.14.0-611.36.1.el9_7 for kernel-5.14.0-611.36.1.el9_7 +Clean Cherry Picks: 6 (50.00%) +Empty Cherry Picks: 6 (50.00%) +_______________________________ + +__EMPTY COMMITS__________________________ +4138787408aa47e9e107f28876cb59b42d78bb99 tick/sched: Limit non-timekeeper CPUs calling jiffies update +31475b88110c4725b4f9a79c3a0d9bbf97e69e1c s390/mm: Fix __ptep_rdp() inline assembly +dd89a81d850fa9a65f67b4527c0e420d15bf836c fou: remove warn in gue_gro_receive on unsupported protocol +7e4196935069947d8b70b09c1660b67b067e75cb fou: Fix null-ptr-deref in GRO. +4c8002277167125078e6b9b90137bdf443ebaa08 fou: fix initialization of grc +922a6f34c1756d2b0c35d9b2d915b8af19e85965 autofs: dont trigger mount if it cant succeed + +__CHANGES NOT IN UPSTREAM________________ +Replace sbat with Rocky Linux sbat +Change bug tracker URL +Ensure appended release in sbat is removed' +migrate: correct lock ordering for hugetlb file folios +ice: PTP: fix missing timestamps on E825 hardware +fou: Don't allow 0 for FOU_ATTR_IPPROTO. +tools: ynl: Specify --no-line-number in ynl-regen.sh. +gue: Fix skb memleak with inner IP protocol 0. +redhat: enable FOU modules in kernel-modules-extra +dpll: expose fractional frequency offset in ppt +dpll: zl3073x: Implement device mode setting support +dpll: add dpll_device op to set working mode +dpll: add dpll_device op to get supported modes +i40e: add rh_phys_port_name mod option to behave like upstream +ice: add rh_phys_port_name mod option to behave like upstream +scsi: qla2xxx: Fix bsg_done() causing double free diff --git a/configs/kernel-5.14.0-aarch64-64k-debug.config b/configs/kernel-5.14.0-aarch64-64k-debug.config index 04233b7333bd2..5369541016e1f 100644 --- a/configs/kernel-5.14.0-aarch64-64k-debug.config +++ b/configs/kernel-5.14.0-aarch64-64k-debug.config @@ -1200,8 +1200,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1254,6 +1254,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64-64k.config b/configs/kernel-5.14.0-aarch64-64k.config index 0058678b6ea43..a9b7c905758b8 100644 --- a/configs/kernel-5.14.0-aarch64-64k.config +++ b/configs/kernel-5.14.0-aarch64-64k.config @@ -1196,8 +1196,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1250,6 +1250,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64-debug.config b/configs/kernel-5.14.0-aarch64-debug.config index c737657c77114..e5f52f699a616 100644 --- a/configs/kernel-5.14.0-aarch64-debug.config +++ b/configs/kernel-5.14.0-aarch64-debug.config @@ -1203,8 +1203,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1257,6 +1257,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64-rt-64k-debug.config b/configs/kernel-5.14.0-aarch64-rt-64k-debug.config index 79725480470d1..31611cd217db9 100644 --- a/configs/kernel-5.14.0-aarch64-rt-64k-debug.config +++ b/configs/kernel-5.14.0-aarch64-rt-64k-debug.config @@ -1197,8 +1197,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1251,6 +1251,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64-rt-64k.config b/configs/kernel-5.14.0-aarch64-rt-64k.config index 7c723e71f914a..bb13fa62ef1a4 100644 --- a/configs/kernel-5.14.0-aarch64-rt-64k.config +++ b/configs/kernel-5.14.0-aarch64-rt-64k.config @@ -1194,8 +1194,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1248,6 +1248,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64-rt-debug.config b/configs/kernel-5.14.0-aarch64-rt-debug.config index 695cfeed66113..40eaa51751799 100644 --- a/configs/kernel-5.14.0-aarch64-rt-debug.config +++ b/configs/kernel-5.14.0-aarch64-rt-debug.config @@ -1198,8 +1198,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1252,6 +1252,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64-rt.config b/configs/kernel-5.14.0-aarch64-rt.config index e09ce0fdc7564..cd833762598d6 100644 --- a/configs/kernel-5.14.0-aarch64-rt.config +++ b/configs/kernel-5.14.0-aarch64-rt.config @@ -1195,8 +1195,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1249,6 +1249,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-aarch64.config b/configs/kernel-5.14.0-aarch64.config index ffa8960cd4807..572b21cc9493b 100644 --- a/configs/kernel-5.14.0-aarch64.config +++ b/configs/kernel-5.14.0-aarch64.config @@ -1199,8 +1199,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1253,6 +1253,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-ppc64le-debug.config b/configs/kernel-5.14.0-ppc64le-debug.config index f0ae4d0e99095..d198f247bdebf 100644 --- a/configs/kernel-5.14.0-ppc64le-debug.config +++ b/configs/kernel-5.14.0-ppc64le-debug.config @@ -966,8 +966,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1020,6 +1020,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-ppc64le.config b/configs/kernel-5.14.0-ppc64le.config index 531b9025abbbe..25c9d6cca4efb 100644 --- a/configs/kernel-5.14.0-ppc64le.config +++ b/configs/kernel-5.14.0-ppc64le.config @@ -969,8 +969,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1023,6 +1023,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-s390x-debug.config b/configs/kernel-5.14.0-s390x-debug.config index 8da129157e89a..b0b6bdf9b9b1b 100644 --- a/configs/kernel-5.14.0-s390x-debug.config +++ b/configs/kernel-5.14.0-s390x-debug.config @@ -832,8 +832,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -886,6 +886,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-s390x.config b/configs/kernel-5.14.0-s390x.config index 44541bd3e0f48..092da14fef0e1 100644 --- a/configs/kernel-5.14.0-s390x.config +++ b/configs/kernel-5.14.0-s390x.config @@ -855,8 +855,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -909,6 +909,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-x86_64-debug.config b/configs/kernel-5.14.0-x86_64-debug.config index e74a390505da8..c554d7f09753a 100644 --- a/configs/kernel-5.14.0-x86_64-debug.config +++ b/configs/kernel-5.14.0-x86_64-debug.config @@ -1282,8 +1282,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1336,6 +1336,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-x86_64-rt-debug.config b/configs/kernel-5.14.0-x86_64-rt-debug.config index 537a6df1ace9d..f9ad603f4dab8 100644 --- a/configs/kernel-5.14.0-x86_64-rt-debug.config +++ b/configs/kernel-5.14.0-x86_64-rt-debug.config @@ -1282,8 +1282,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1336,6 +1336,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-x86_64-rt.config b/configs/kernel-5.14.0-x86_64-rt.config index 5a8eaaa847058..6f00bdbf8322a 100644 --- a/configs/kernel-5.14.0-x86_64-rt.config +++ b/configs/kernel-5.14.0-x86_64-rt.config @@ -1279,8 +1279,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1333,6 +1333,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-5.14.0-x86_64.config b/configs/kernel-5.14.0-x86_64.config index 24116f549bc30..bd11b1b23a6a7 100644 --- a/configs/kernel-5.14.0-x86_64.config +++ b/configs/kernel-5.14.0-x86_64.config @@ -1278,8 +1278,8 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m @@ -1332,6 +1332,8 @@ CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_IPV6_SUBTREES is not set CONFIG_IPV6_MROUTE=y diff --git a/configs/kernel-aarch64-64k-debug-rhel.config b/configs/kernel-aarch64-64k-debug-rhel.config index 2a996aed8966a..7d4db19474dda 100644 --- a/configs/kernel-aarch64-64k-debug-rhel.config +++ b/configs/kernel-aarch64-64k-debug-rhel.config @@ -3934,8 +3934,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-64k-rhel.config b/configs/kernel-aarch64-64k-rhel.config index 2bf130311bbfc..1283e67ee3f7b 100644 --- a/configs/kernel-aarch64-64k-rhel.config +++ b/configs/kernel-aarch64-64k-rhel.config @@ -3913,8 +3913,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-debug-rhel.config b/configs/kernel-aarch64-debug-rhel.config index da59c4daefce4..e9f0d381f9a7a 100644 --- a/configs/kernel-aarch64-debug-rhel.config +++ b/configs/kernel-aarch64-debug-rhel.config @@ -3932,8 +3932,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-rhel.config b/configs/kernel-aarch64-rhel.config index 299d893226bee..b26a83fe659b7 100644 --- a/configs/kernel-aarch64-rhel.config +++ b/configs/kernel-aarch64-rhel.config @@ -3911,8 +3911,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-rt-64k-debug-rhel.config b/configs/kernel-aarch64-rt-64k-debug-rhel.config index 4cc140e73e725..f1d5eda47da98 100644 --- a/configs/kernel-aarch64-rt-64k-debug-rhel.config +++ b/configs/kernel-aarch64-rt-64k-debug-rhel.config @@ -4007,8 +4007,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-rt-64k-rhel.config b/configs/kernel-aarch64-rt-64k-rhel.config index 75303a482086b..129cd2164f578 100644 --- a/configs/kernel-aarch64-rt-64k-rhel.config +++ b/configs/kernel-aarch64-rt-64k-rhel.config @@ -3986,8 +3986,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-rt-debug-rhel.config b/configs/kernel-aarch64-rt-debug-rhel.config index 9d3d42e4d6912..f4070ab441df7 100644 --- a/configs/kernel-aarch64-rt-debug-rhel.config +++ b/configs/kernel-aarch64-rt-debug-rhel.config @@ -4005,8 +4005,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-aarch64-rt-rhel.config b/configs/kernel-aarch64-rt-rhel.config index 273e126722712..2793f45b558a4 100644 --- a/configs/kernel-aarch64-rt-rhel.config +++ b/configs/kernel-aarch64-rt-rhel.config @@ -3984,8 +3984,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-ppc64le-debug-rhel.config b/configs/kernel-ppc64le-debug-rhel.config index 1e8d5fb1efe27..a02846413886d 100644 --- a/configs/kernel-ppc64le-debug-rhel.config +++ b/configs/kernel-ppc64le-debug-rhel.config @@ -3559,8 +3559,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-ppc64le-rhel.config b/configs/kernel-ppc64le-rhel.config index ffb3ad34923f1..60e25de180301 100644 --- a/configs/kernel-ppc64le-rhel.config +++ b/configs/kernel-ppc64le-rhel.config @@ -3539,8 +3539,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-s390x-debug-rhel.config b/configs/kernel-s390x-debug-rhel.config index f4afec11a246f..f8c7a4247122f 100644 --- a/configs/kernel-s390x-debug-rhel.config +++ b/configs/kernel-s390x-debug-rhel.config @@ -3550,8 +3550,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-s390x-rhel.config b/configs/kernel-s390x-rhel.config index f74c811e652ae..b2e9d27c8b481 100644 --- a/configs/kernel-s390x-rhel.config +++ b/configs/kernel-s390x-rhel.config @@ -3530,8 +3530,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-s390x-zfcpdump-rhel.config b/configs/kernel-s390x-zfcpdump-rhel.config index 41f013b88959e..7e1f33a503dfb 100644 --- a/configs/kernel-s390x-zfcpdump-rhel.config +++ b/configs/kernel-s390x-zfcpdump-rhel.config @@ -3542,8 +3542,8 @@ CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y # CONFIG_NETFS_SUPPORT is not set CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-x86_64-debug-rhel.config b/configs/kernel-x86_64-debug-rhel.config index 77b391b9d43f3..bcff13948f384 100644 --- a/configs/kernel-x86_64-debug-rhel.config +++ b/configs/kernel-x86_64-debug-rhel.config @@ -3790,8 +3790,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-x86_64-rhel.config b/configs/kernel-x86_64-rhel.config index d15a210df8fbe..81d63c0cc4f1c 100644 --- a/configs/kernel-x86_64-rhel.config +++ b/configs/kernel-x86_64-rhel.config @@ -3770,8 +3770,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-x86_64-rt-debug-rhel.config b/configs/kernel-x86_64-rt-debug-rhel.config index b522df4754adc..f895e1c9b78c7 100644 --- a/configs/kernel-x86_64-rt-debug-rhel.config +++ b/configs/kernel-x86_64-rt-debug-rhel.config @@ -3861,8 +3861,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/kernel-x86_64-rt-rhel.config b/configs/kernel-x86_64-rt-rhel.config index 407374b0fd2b1..41141176f9aa1 100644 --- a/configs/kernel-x86_64-rt-rhel.config +++ b/configs/kernel-x86_64-rt-rhel.config @@ -3841,8 +3841,8 @@ CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER=y -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_FOU is not set +CONFIG_NET_FOU_IP_TUNNELS=y +CONFIG_NET_FOU=m CONFIG_NETFS_STATS=y CONFIG_NETFS_SUPPORT=m CONFIG_NET_HANDSHAKE_KUNIT_TEST=m diff --git a/configs/mod-extra.list b/configs/mod-extra.list index f9ec7eb96e42a..c63247ed3a599 100644 --- a/configs/mod-extra.list +++ b/configs/mod-extra.list @@ -47,6 +47,8 @@ ems_pci.ko ems_usb.ko esd_usb2.ko esi-sir.ko +fou.ko +fou6.ko gamecon.ko gf2k.ko gigaset.ko diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 64944f601ee5a..904199ddd1781 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -128,18 +128,29 @@ dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll, struct netlink_ext_ack *extack) { const struct dpll_device_ops *ops = dpll_device_ops(dpll); + DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 }; enum dpll_mode mode; int ret; - /* No mode change is supported now, so the only supported mode is the - * one obtained by mode_get(). - */ + if (ops->supported_modes_get) { + ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes, + extack); + if (ret) + return ret; + } else { + /* If the supported modes are not reported by the driver, the + * only supported mode is the one obtained by mode_get(). + */ + ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack); + if (ret) + return ret; - ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack); - if (ret) - return ret; - if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode)) - return -EMSGSIZE; + __set_bit(mode, modes); + } + + for_each_set_bit(mode, modes, DPLL_MODE_MAX + 1) + if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode)) + return -EMSGSIZE; return 0; } @@ -378,7 +389,15 @@ static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin, return 0; return ret; } - return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, ffo); + /* Put the FFO value in PPM to preserve compatibility with older + * programs. + */ + ret = nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, + div_s64(ffo, 1000000)); + if (ret) + return -EMSGSIZE; + return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT, + ffo); } static int @@ -842,6 +861,45 @@ int dpll_pin_change_ntf(struct dpll_pin *pin) } EXPORT_SYMBOL_GPL(dpll_pin_change_ntf); +static int +dpll_mode_set(struct dpll_device *dpll, struct nlattr *a, + struct netlink_ext_ack *extack) +{ + const struct dpll_device_ops *ops = dpll_device_ops(dpll); + DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 }; + enum dpll_mode mode = nla_get_u32(a), old_mode; + int ret; + + if (!(ops->mode_set && ops->supported_modes_get)) { + NL_SET_ERR_MSG_ATTR(extack, a, + "dpll device does not support mode switch"); + return -EOPNOTSUPP; + } + + ret = ops->mode_get(dpll, dpll_priv(dpll), &old_mode, extack); + if (ret) { + NL_SET_ERR_MSG(extack, "unable to get current mode"); + return ret; + } + + if (mode == old_mode) + return 0; + + ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes, extack); + if (ret) { + NL_SET_ERR_MSG(extack, "unable to get supported modes"); + return ret; + } + + if (!test_bit(mode, modes)) { + NL_SET_ERR_MSG(extack, + "dpll device does not support requested mode"); + return -EINVAL; + } + + return ops->mode_set(dpll, dpll_priv(dpll), mode, extack); +} + static int dpll_phase_offset_monitor_set(struct dpll_device *dpll, struct nlattr *a, struct netlink_ext_ack *extack) @@ -1797,6 +1855,11 @@ dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info) nla_for_each_attr(a, genlmsg_data(info->genlhdr), genlmsg_len(info->genlhdr), rem) { switch (nla_type(a)) { + case DPLL_A_MODE: + ret = dpll_mode_set(dpll, a, info->extack); + if (ret) + return ret; + break; case DPLL_A_PHASE_OFFSET_MONITOR: ret = dpll_phase_offset_monitor_set(dpll, a, info->extack); diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index 3c6d570babf89..3fb64aab18fa3 100644 --- a/drivers/dpll/dpll_nl.c +++ b/drivers/dpll/dpll_nl.c @@ -44,6 +44,7 @@ static const struct nla_policy dpll_device_get_nl_policy[DPLL_A_ID + 1] = { /* DPLL_CMD_DEVICE_SET - do */ static const struct nla_policy dpll_device_set_nl_policy[DPLL_A_PHASE_OFFSET_AVG_FACTOR + 1] = { [DPLL_A_ID] = { .type = NLA_U32, }, + [DPLL_A_MODE] = NLA_POLICY_RANGE(NLA_U32, 1, 2), [DPLL_A_PHASE_OFFSET_MONITOR] = NLA_POLICY_MAX(NLA_U32, 1), [DPLL_A_PHASE_OFFSET_AVG_FACTOR] = { .type = NLA_U32, }, }; diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index 986fb2eada843..60bf70f3c2826 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -710,8 +710,11 @@ zl3073x_ref_ffo_update(struct zl3073x_dev *zldev) if (rc) return rc; - /* Convert to ppm -> ffo = (10^6 * value) / 2^32 */ - zldev->ref[i].ffo = mul_s64_u64_shr(value, 1000000, 32); + /* Convert to ppt + * ffo = (10^12 * value) / 2^32 + * ffo = ( 5^12 * value) / 2^20 + */ + zldev->ref[i].ffo = mul_s64_u64_shr(value, 244140625, 20); } return 0; diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index 9879d85d29af0..7d8ed948b9706 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -100,6 +100,20 @@ zl3073x_dpll_pin_direction_get(const struct dpll_pin *dpll_pin, void *pin_priv, return 0; } +static struct zl3073x_dpll_pin * +zl3073x_dpll_pin_get_by_ref(struct zl3073x_dpll *zldpll, u8 ref_id) +{ + struct zl3073x_dpll_pin *pin; + + list_for_each_entry(pin, &zldpll->pins, list) { + if (zl3073x_dpll_is_input_pin(pin) && + zl3073x_input_pin_ref_get(pin->id) == ref_id) + return pin; + } + + return NULL; +} + static int zl3073x_dpll_input_pin_esync_get(const struct dpll_pin *dpll_pin, void *pin_priv, @@ -1137,6 +1151,26 @@ zl3073x_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, return 0; } +static int +zl3073x_dpll_supported_modes_get(const struct dpll_device *dpll, + void *dpll_priv, unsigned long *modes, + struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll *zldpll = dpll_priv; + + /* We support switching between automatic and manual mode, except in + * a case where the DPLL channel is configured to run in NCO mode. + * In this case, report only the manual mode to which the NCO is mapped + * as the only supported one. + */ + if (zldpll->refsel_mode != ZL_DPLL_MODE_REFSEL_MODE_NCO) + __set_bit(DPLL_MODE_AUTOMATIC, modes); + + __set_bit(DPLL_MODE_MANUAL, modes); + + return 0; +} + static int zl3073x_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv, enum dpll_mode *mode, struct netlink_ext_ack *extack) @@ -1217,6 +1251,82 @@ zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll, return 0; } +static int +zl3073x_dpll_mode_set(const struct dpll_device *dpll, void *dpll_priv, + enum dpll_mode mode, struct netlink_ext_ack *extack) +{ + struct zl3073x_dpll *zldpll = dpll_priv; + u8 hw_mode, mode_refsel, ref; + int rc; + + rc = zl3073x_dpll_selected_ref_get(zldpll, &ref); + if (rc) { + NL_SET_ERR_MSG_MOD(extack, "failed to get selected reference"); + return rc; + } + + if (mode == DPLL_MODE_MANUAL) { + /* We are switching from automatic to manual mode: + * - if we have a valid reference selected during auto mode then + * we will switch to forced reference lock mode and use this + * reference for selection + * - if NO valid reference is selected, we will switch to forced + * holdover mode or freerun mode, depending on the current + * lock status + */ + if (ZL3073X_DPLL_REF_IS_VALID(ref)) + hw_mode = ZL_DPLL_MODE_REFSEL_MODE_REFLOCK; + else if (zldpll->lock_status == DPLL_LOCK_STATUS_UNLOCKED) + hw_mode = ZL_DPLL_MODE_REFSEL_MODE_FREERUN; + else + hw_mode = ZL_DPLL_MODE_REFSEL_MODE_HOLDOVER; + } else { + /* We are switching from manual to automatic mode: + * - if there is a valid reference selected then ensure that + * it is selectable after switch to automatic mode + * - switch to automatic mode + */ + struct zl3073x_dpll_pin *pin; + + pin = zl3073x_dpll_pin_get_by_ref(zldpll, ref); + if (pin && !pin->selectable) { + /* Restore pin priority in HW */ + rc = zl3073x_dpll_ref_prio_set(pin, pin->prio); + if (rc) { + NL_SET_ERR_MSG_MOD(extack, + "failed to restore pin priority"); + return rc; + } + + pin->selectable = true; + } + + hw_mode = ZL_DPLL_MODE_REFSEL_MODE_AUTO; + } + + /* Build mode_refsel value */ + mode_refsel = FIELD_PREP(ZL_DPLL_MODE_REFSEL_MODE, hw_mode); + + if (ZL3073X_DPLL_REF_IS_VALID(ref)) + mode_refsel |= FIELD_PREP(ZL_DPLL_MODE_REFSEL_REF, ref); + + /* Update dpll_mode_refsel register */ + rc = zl3073x_write_u8(zldpll->dev, ZL_REG_DPLL_MODE_REFSEL(zldpll->id), + mode_refsel); + if (rc) { + NL_SET_ERR_MSG_MOD(extack, + "failed to set reference selection mode"); + return rc; + } + + zldpll->refsel_mode = hw_mode; + + if (ZL3073X_DPLL_REF_IS_VALID(ref)) + zldpll->forced_ref = ref; + + return 0; +} + static int zl3073x_dpll_phase_offset_monitor_get(const struct dpll_device *dpll, void *dpll_priv, @@ -1276,10 +1386,12 @@ static const struct dpll_pin_ops zl3073x_dpll_output_pin_ops = { static const struct dpll_device_ops zl3073x_dpll_device_ops = { .lock_status_get = zl3073x_dpll_lock_status_get, .mode_get = zl3073x_dpll_mode_get, + .mode_set = zl3073x_dpll_mode_set, .phase_offset_avg_factor_get = zl3073x_dpll_phase_offset_avg_factor_get, .phase_offset_avg_factor_set = zl3073x_dpll_phase_offset_avg_factor_set, .phase_offset_monitor_get = zl3073x_dpll_phase_offset_monitor_get, .phase_offset_monitor_set = zl3073x_dpll_phase_offset_monitor_set, + .supported_modes_get = zl3073x_dpll_supported_modes_get, }; /** diff --git a/drivers/net/ethernet/intel/i40e/i40e_devlink.c b/drivers/net/ethernet/intel/i40e/i40e_devlink.c index 342b35e124cb0..ca82ad166390f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_devlink.c +++ b/drivers/net/ethernet/intel/i40e/i40e_devlink.c @@ -5,6 +5,10 @@ #include "i40e.h" #include "i40e_devlink.h" +/* RHEL-specific opt-in to expose "phys_port_name" in sysfs to match upstream behavior. */ +static int rh_phys_port_name; +module_param(rh_phys_port_name, int, 0644); + static void i40e_info_get_dsn(struct i40e_pf *pf, char *buf, size_t len) { u8 dsn[8]; @@ -229,7 +233,7 @@ int i40e_devlink_create_port(struct i40e_pf *pf) **/ struct devlink_port *i40e_get_devlink_port(struct net_device *netdev) { - return NULL; + return rh_phys_port_name ? netdev->devlink_port : NULL; } /** diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index f81c5dcbe9d39..27fdbc2bbb821 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -49,6 +49,10 @@ MODULE_PARM_DESC(debug, "netif level (0=none,...,16=all), hw debug_mask (0x8XXXX MODULE_PARM_DESC(debug, "netif level (0=none,...,16=all)"); #endif /* !CONFIG_DYNAMIC_DEBUG */ +/* RHEL-only opt-in to expose "phys_port_name" in sysfs */ +static int rh_phys_port_name; +module_param(rh_phys_port_name, int, 0644); + DEFINE_STATIC_KEY_FALSE(ice_xdp_locking_key); EXPORT_SYMBOL(ice_xdp_locking_key); @@ -321,6 +325,9 @@ static struct devlink_port *ice_get_devlink_port(struct net_device *netdev) { struct ice_pf *pf = ice_netdev_to_pf(netdev); + if (rh_phys_port_name) + return netdev->devlink_port; + if (!ice_is_switchdev_running(pf)) return NULL; @@ -3401,18 +3408,20 @@ static irqreturn_t ice_misc_intr_thread_fn(int __always_unused irq, void *data) if (ice_is_reset_in_progress(pf->state)) goto skip_irq; - if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) { - /* Process outstanding Tx timestamps. If there is more work, - * re-arm the interrupt to trigger again. - */ - if (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING) { - wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M); - ice_flush(hw); - } - } + if (test_and_clear_bit(ICE_MISC_THREAD_TX_TSTAMP, pf->misc_thread)) + ice_ptp_process_ts(pf); skip_irq: ice_irq_dynamic_ena(hw, NULL, NULL); + ice_flush(hw); + + if (ice_ptp_tx_tstamps_pending(pf)) { + /* If any new Tx timestamps happened while in interrupt, + * re-arm the interrupt to trigger it again. + */ + wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M); + ice_flush(hw); + } return IRQ_HANDLED; } diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 0f94dd4dec8e6..9b247304f1416 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -666,6 +666,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx) pf = ptp_port_to_pf(ptp_port); hw = &pf->hw; + if (!tx->init) + return; + /* Read the Tx ready status first */ if (tx->has_ready_bitmap) { err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready); @@ -762,14 +765,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx) } } -/** - * ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device - * @pf: Board private structure - */ -static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf) +static void ice_ptp_tx_tstamp_owner(struct ice_pf *pf) { struct ice_ptp_port *port; - unsigned int i; mutex_lock(&pf->adapter->ports.lock); list_for_each_entry(port, &pf->adapter->ports.ports, list_node) { @@ -781,49 +779,6 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf) ice_ptp_process_tx_tstamp(tx); } mutex_unlock(&pf->adapter->ports.lock); - - for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) { - u64 tstamp_ready; - int err; - - /* Read the Tx ready status first */ - err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready); - if (err) - break; - else if (tstamp_ready) - return ICE_TX_TSTAMP_WORK_PENDING; - } - - return ICE_TX_TSTAMP_WORK_DONE; -} - -/** - * ice_ptp_tx_tstamp - Process Tx timestamps for this function. - * @tx: Tx tracking structure to initialize - * - * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding incomplete - * Tx timestamps, or ICE_TX_TSTAMP_WORK_DONE otherwise. - */ -static enum ice_tx_tstamp_work ice_ptp_tx_tstamp(struct ice_ptp_tx *tx) -{ - bool more_timestamps; - unsigned long flags; - - if (!tx->init) - return ICE_TX_TSTAMP_WORK_DONE; - - /* Process the Tx timestamp tracker */ - ice_ptp_process_tx_tstamp(tx); - - /* Check if there are outstanding Tx timestamps */ - spin_lock_irqsave(&tx->lock, flags); - more_timestamps = tx->init && !bitmap_empty(tx->in_use, tx->len); - spin_unlock_irqrestore(&tx->lock, flags); - - if (more_timestamps) - return ICE_TX_TSTAMP_WORK_PENDING; - - return ICE_TX_TSTAMP_WORK_DONE; } /** @@ -2837,30 +2792,92 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb) return idx + tx->offset; } -/** - * ice_ptp_process_ts - Process the PTP Tx timestamps - * @pf: Board private structure - * - * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding Tx - * timestamps that need processing, and ICE_TX_TSTAMP_WORK_DONE otherwise. - */ -enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf) +void ice_ptp_process_ts(struct ice_pf *pf) { switch (pf->ptp.tx_interrupt_mode) { case ICE_PTP_TX_INTERRUPT_NONE: /* This device has the clock owner handle timestamps for it */ - return ICE_TX_TSTAMP_WORK_DONE; + return; case ICE_PTP_TX_INTERRUPT_SELF: /* This device handles its own timestamps */ - return ice_ptp_tx_tstamp(&pf->ptp.port.tx); + ice_ptp_process_tx_tstamp(&pf->ptp.port.tx); + return; case ICE_PTP_TX_INTERRUPT_ALL: /* This device handles timestamps for all ports */ - return ice_ptp_tx_tstamp_owner(pf); + ice_ptp_tx_tstamp_owner(pf); + return; + default: + WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n", + pf->ptp.tx_interrupt_mode); + return; + } +} + +static bool ice_port_has_timestamps(struct ice_ptp_tx *tx) +{ + bool more_timestamps; + + scoped_guard(spinlock_irqsave, &tx->lock) { + if (!tx->init) + return false; + + more_timestamps = !bitmap_empty(tx->in_use, tx->len); + } + + return more_timestamps; +} + +static bool ice_any_port_has_timestamps(struct ice_pf *pf) +{ + struct ice_ptp_port *port; + + scoped_guard(mutex, &pf->adapter->ports.lock) { + list_for_each_entry(port, &pf->adapter->ports.ports, + list_node) { + struct ice_ptp_tx *tx = &port->tx; + + if (ice_port_has_timestamps(tx)) + return true; + } + } + + return false; +} + +bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf) +{ + struct ice_hw *hw = &pf->hw; + unsigned int i; + + /* Check software indicator */ + switch (pf->ptp.tx_interrupt_mode) { + case ICE_PTP_TX_INTERRUPT_NONE: + return false; + case ICE_PTP_TX_INTERRUPT_SELF: + if (ice_port_has_timestamps(&pf->ptp.port.tx)) + return true; + break; + case ICE_PTP_TX_INTERRUPT_ALL: + if (ice_any_port_has_timestamps(pf)) + return true; + break; default: WARN_ONCE(1, "Unexpected Tx timestamp interrupt mode %u\n", pf->ptp.tx_interrupt_mode); - return ICE_TX_TSTAMP_WORK_DONE; + break; + } + + /* Check hardware indicator */ + for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) { + u64 tstamp_ready = 0; + int err; + + err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready); + if (err || tstamp_ready) + return true; } + + return false; } /** @@ -2912,7 +2929,9 @@ irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf) return IRQ_WAKE_THREAD; case ICE_MAC_E830: /* E830 can read timestamps in the top half using rd32() */ - if (ice_ptp_process_ts(pf) == ICE_TX_TSTAMP_WORK_PENDING) { + ice_ptp_process_ts(pf); + + if (ice_ptp_tx_tstamps_pending(pf)) { /* Process outstanding Tx timestamps. If there * is more work, re-arm the interrupt to trigger again. */ @@ -3365,8 +3384,9 @@ static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf) { switch (pf->hw.mac_type) { case ICE_MAC_GENERIC: - /* E822 based PHY has the clock owner process the interrupt - * for all ports. + case ICE_MAC_GENERIC_3K_E825: + /* E82x hardware has the clock owner process timestamps for + * all ports. */ if (ice_pf_src_tmr_owned(pf)) pf->ptp.tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL; diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h index 3b769a0cad00d..ef281509ae70b 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.h +++ b/drivers/net/ethernet/intel/ice/ice_ptp.h @@ -302,8 +302,9 @@ void ice_ptp_extts_event(struct ice_pf *pf); s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb); void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx); void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx); -enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf); +void ice_ptp_process_ts(struct ice_pf *pf); irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf); +bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf); u64 ice_ptp_read_src_clk_reg(struct ice_pf *pf, struct ptp_system_timestamp *sts); @@ -339,16 +340,18 @@ static inline void ice_ptp_req_tx_single_tstamp(struct ice_ptp_tx *tx, u8 idx) static inline void ice_ptp_complete_tx_single_tstamp(struct ice_ptp_tx *tx) { } -static inline bool ice_ptp_process_ts(struct ice_pf *pf) -{ - return true; -} +static inline void ice_ptp_process_ts(struct ice_pf *pf) { } static inline irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf) { return IRQ_HANDLED; } +static inline bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf) +{ + return false; +} + static inline u64 ice_ptp_read_src_clk_reg(struct ice_pf *pf, struct ptp_system_timestamp *sts) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c index 1e5522a194839..3ea8a1766ae28 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c @@ -136,7 +136,7 @@ mlx5_dpll_pin_ffo_get(struct mlx5_dpll_synce_status *synce_status, { if (!synce_status->oper_freq_measure) return -ENODATA; - *ffo = synce_status->frequency_diff; + *ffo = 1000000LL * synce_status->frequency_diff; return 0; } diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 10431a67d202b..f43969ed87bf9 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -1546,8 +1546,9 @@ qla2x00_update_optrom(struct bsg_job *bsg_job) ha->optrom_buffer = NULL; ha->optrom_state = QLA_SWAITING; mutex_unlock(&ha->optrom_mutex); - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return rval; } @@ -2612,8 +2613,9 @@ qla2x00_manage_host_stats(struct bsg_job *bsg_job) sizeof(struct ql_vnd_mng_host_stats_resp)); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return ret; } @@ -2702,8 +2704,9 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, data, response_len); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); kfree(data); host_stat_out: @@ -2802,8 +2805,9 @@ qla2x00_get_tgt_stats(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, data, response_len); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); tgt_stat_out: kfree(data); @@ -2864,8 +2868,9 @@ qla2x00_manage_host_port(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, &rsp_data, sizeof(struct ql_vnd_mng_host_port_resp)); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return ret; } @@ -3240,7 +3245,8 @@ int qla2x00_mailbox_passthru(struct bsg_job *bsg_job) bsg_job->reply_len = sizeof(*bsg_job->reply); bsg_reply->result = DID_OK << 16; - bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); kfree(req_data); diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h index 8026f44a107e0..e8bd2b6283aa5 100644 --- a/fs/autofs/autofs_i.h +++ b/fs/autofs/autofs_i.h @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -25,6 +27,8 @@ #include #include #include +#include "../mount.h" +#include /* This is the range of ioctl() numbers we claim as ours */ #define AUTOFS_IOC_FIRST AUTOFS_IOC_READY @@ -112,6 +116,7 @@ struct autofs_sb_info { int pipefd; struct file *pipe; struct pid *oz_pgrp; + u64 mnt_ns_id; int version; int sub_version; int min_proto; diff --git a/fs/autofs/dev-ioctl.c b/fs/autofs/dev-ioctl.c index 6d57efbb81102..91a206353e6f2 100644 --- a/fs/autofs/dev-ioctl.c +++ b/fs/autofs/dev-ioctl.c @@ -381,6 +381,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, swap(sbi->oz_pgrp, new_pid); sbi->pipefd = pipefd; sbi->pipe = pipe; + sbi->mnt_ns_id = current->nsproxy->mnt_ns->seq; sbi->flags &= ~AUTOFS_SBI_CATATONIC; } out: diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index 49b34730e7b99..76b974503d2ce 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c @@ -239,6 +239,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) s->s_fs_info = sbi; sbi->magic = AUTOFS_SBI_MAGIC; sbi->pipefd = -1; + sbi->mnt_ns_id = current->nsproxy->mnt_ns->seq; sbi->pipe = NULL; sbi->exp_timeout = 0; sbi->oz_pgrp = NULL; diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 6baf90b08e0ef..ad294a98e6d09 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -341,6 +341,14 @@ static struct vfsmount *autofs_d_automount(struct path *path) if (autofs_oz_mode(sbi)) return NULL; + /* Refuse to trigger mount if current namespace is not the owner + * and the mount is propagation private. + */ + if (sbi->mnt_ns_id != current->nsproxy->mnt_ns->seq) { + if (vfsmount_to_propagation_flags(path->mnt) & MS_PRIVATE) + return ERR_PTR(-EPERM); + } + /* * If an expire request is pending everyone must wait. * If the expire fails we're still mounted so continue diff --git a/fs/namespace.c b/fs/namespace.c index faa8e1bff7c91..1169a95300ddf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4278,6 +4278,27 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, return err; } +static u64 mnt_to_propagation_flags(struct mount *m) +{ + u64 propagation = 0; + + if (IS_MNT_SHARED(m)) + propagation |= MS_SHARED; + if (IS_MNT_SLAVE(m)) + propagation |= MS_SLAVE; + if (IS_MNT_UNBINDABLE(m)) + propagation |= MS_UNBINDABLE; + if (!propagation) + propagation |= MS_PRIVATE; + + return propagation; +} + +u64 vfsmount_to_propagation_flags(struct vfsmount *mnt) +{ + return mnt_to_propagation_flags(real_mount(mnt)); +} + static void __init init_mount_tree(void) { struct vfsmount *mnt; diff --git a/include/linux/dpll.h b/include/linux/dpll.h index 9ad2d62e16ba4..b2c2bf0b2506b 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -47,8 +47,11 @@ struct dpll_device_ops { RH_KABI_USE(2, int (*phase_offset_avg_factor_get)(const struct dpll_device *dpll, void *dpll_priv, u32 *factor, struct netlink_ext_ack *extack)) - RH_KABI_RESERVE(3) - RH_KABI_RESERVE(4) + RH_KABI_USE(3, int (*supported_modes_get)(const struct dpll_device *dpll, + void *dpll_priv, unsigned long *modes, + struct netlink_ext_ack *extack)) + RH_KABI_USE(4, int (*mode_set)(const struct dpll_device *dpll, void *dpll_priv, + enum dpll_mode mode, struct netlink_ext_ack *extack)) RH_KABI_RESERVE(5) RH_KABI_RESERVE(6) RH_KABI_RESERVE(7) diff --git a/include/linux/fs.h b/include/linux/fs.h index 53cf26162c5de..d02f204c7eb91 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2808,6 +2808,7 @@ extern struct file * open_exec(const char *); /* fs/dcache.c -- generic fs support functions */ extern bool is_subdir(struct dentry *, struct dentry *); extern bool path_is_under(const struct path *, const struct path *); +u64 vfsmount_to_propagation_flags(struct vfsmount *mnt); extern char *file_path(struct file *, char *, int); diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h index 69d35570ac4f1..603a88cb665f9 100644 --- a/include/uapi/linux/dpll.h +++ b/include/uapi/linux/dpll.h @@ -252,6 +252,7 @@ enum dpll_a_pin { DPLL_A_PIN_ESYNC_PULSE, DPLL_A_PIN_REFERENCE_SYNC, DPLL_A_PIN_PHASE_ADJUST_GRAN, + DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT, __DPLL_A_PIN_MAX, DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 5205373652e98..94d964a8b952b 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -181,6 +181,27 @@ static ktime_t tick_init_jiffy_update(void) return period; } +/* + * Allow only one non-timekeeper CPU at a time update jiffies from + * the timer tick. + * + * Returns true if update was run. + */ +static bool tick_limited_update_jiffies64(struct tick_sched *ts, ktime_t now) +{ + static atomic_t in_progress; + int inp; + + inp = atomic_read(&in_progress); + if (inp || !atomic_try_cmpxchg(&in_progress, &inp, 1)) + return false; + + if (ts->last_tick_jiffies == jiffies) + tick_do_update_jiffies64(now); + atomic_set(&in_progress, 0); + return true; +} + #define MAX_STALLED_JIFFIES 5 static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now) @@ -218,10 +239,11 @@ static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now) ts->stalled_jiffies = 0; ts->last_tick_jiffies = READ_ONCE(jiffies); } else { - if (++ts->stalled_jiffies == MAX_STALLED_JIFFIES) { - tick_do_update_jiffies64(now); - ts->stalled_jiffies = 0; - ts->last_tick_jiffies = READ_ONCE(jiffies); + if (++ts->stalled_jiffies >= MAX_STALLED_JIFFIES) { + if (tick_limited_update_jiffies64(ts, now)) { + ts->stalled_jiffies = 0; + ts->last_tick_jiffies = READ_ONCE(jiffies); + } } } diff --git a/mm/migrate.c b/mm/migrate.c index 41df98b69c80f..1da730c8222f8 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1383,6 +1383,7 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, int page_was_mapped = 0; struct anon_vma *anon_vma = NULL; struct address_space *mapping = NULL; + enum ttu_flags ttu = 0; if (folio_ref_count(src) == 1) { /* page was freed from under us. So we are done. */ @@ -1424,8 +1425,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, goto put_anon; if (folio_mapped(src)) { - enum ttu_flags ttu = 0; - if (!folio_test_anon(src)) { /* * In shared mappings, try_to_unmap could potentially @@ -1442,9 +1441,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, try_to_migrate(src, ttu); page_was_mapped = 1; - - if (ttu & TTU_RMAP_LOCKED) - i_mmap_unlock_write(mapping); } if (!folio_mapped(src)) @@ -1452,7 +1448,11 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, if (page_was_mapped) remove_migration_ptes(src, - rc == MIGRATEPAGE_SUCCESS ? dst : src, false); + rc == MIGRATEPAGE_SUCCESS ? dst : src, + ttu ? true : false); + + if (ttu & TTU_RMAP_LOCKED) + i_mmap_unlock_write(mapping); unlock_put_anon: folio_unlock(dst); diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index b7b887f83b659..7b5b898cf4c94 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -50,7 +50,7 @@ struct fou_net { static inline struct fou *fou_from_sock(struct sock *sk) { - return sk->sk_user_data; + return rcu_dereference_sk_user_data(sk); } static int fou_recv_pull(struct sk_buff *skb, struct fou *fou, size_t len) @@ -215,6 +215,9 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) return gue_control_message(skb, guehdr); proto_ctype = guehdr->proto_ctype; + if (unlikely(!proto_ctype)) + goto drop; + __skb_pull(skb, sizeof(struct udphdr) + hdrlen); skb_reset_transport_header(skb); @@ -233,9 +236,15 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, struct sk_buff *skb) { const struct net_offload __rcu **offloads; - u8 proto = fou_from_sock(sk)->protocol; + struct fou *fou = fou_from_sock(sk); const struct net_offload *ops; struct sk_buff *pp = NULL; + u8 proto; + + if (!fou) + return NULL; + + proto = fou->protocol; /* We can clear the encap_mark for FOU as we are essentially doing * one of two possible things. We are either adding an L4 tunnel @@ -266,15 +275,23 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) { const struct net_offload __rcu **offloads; - u8 proto = fou_from_sock(sk)->protocol; + struct fou *fou = fou_from_sock(sk); const struct net_offload *ops; - int err = -ENOSYS; + u8 proto; + int err; + + if (!fou) + return -ENOENT; + + proto = fou->protocol; rcu_read_lock(); offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops = rcu_dereference(offloads[proto]); - if (WARN_ON(!ops || !ops->callbacks.gro_complete)) + if (WARN_ON(!ops || !ops->callbacks.gro_complete)) { + err = -ENOSYS; goto out_unlock; + } err = ops->callbacks.gro_complete(skb, nhoff); @@ -328,6 +345,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, skb_gro_remcsum_init(&grc); + if (!fou) + goto out; + off = skb_gro_offset(skb); len = off + sizeof(*guehdr); @@ -440,7 +460,7 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, rcu_read_lock(); offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops = rcu_dereference(offloads[proto]); - if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) + if (!ops || !ops->callbacks.gro_receive) goto out_unlock; pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); diff --git a/net/ipv4/fou_nl.c b/net/ipv4/fou_nl.c index 98b90107b5abc..bbd955f4c9d19 100644 --- a/net/ipv4/fou_nl.c +++ b/net/ipv4/fou_nl.c @@ -14,7 +14,7 @@ const struct nla_policy fou_nl_policy[FOU_ATTR_IFINDEX + 1] = { [FOU_ATTR_PORT] = { .type = NLA_U16, }, [FOU_ATTR_AF] = { .type = NLA_U8, }, - [FOU_ATTR_IPPROTO] = { .type = NLA_U8, }, + [FOU_ATTR_IPPROTO] = NLA_POLICY_MIN(NLA_U8, 1), [FOU_ATTR_TYPE] = { .type = NLA_U8, }, [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, }, [FOU_ATTR_LOCAL_V4] = { .type = NLA_U32, }, diff --git a/redhat/configs/common/generic/CONFIG_NET_FOU b/redhat/configs/common/generic/CONFIG_NET_FOU new file mode 100644 index 0000000000000..f78ee6d878821 --- /dev/null +++ b/redhat/configs/common/generic/CONFIG_NET_FOU @@ -0,0 +1 @@ +CONFIG_NET_FOU=m diff --git a/redhat/configs/common/generic/CONFIG_NET_FOU_IP_TUNNELS b/redhat/configs/common/generic/CONFIG_NET_FOU_IP_TUNNELS new file mode 100644 index 0000000000000..7d89b7659e6d9 --- /dev/null +++ b/redhat/configs/common/generic/CONFIG_NET_FOU_IP_TUNNELS @@ -0,0 +1 @@ +CONFIG_NET_FOU_IP_TUNNELS=y diff --git a/redhat/configs/rhel/generic/CONFIG_NET_FOU b/redhat/configs/rhel/generic/CONFIG_NET_FOU deleted file mode 100644 index 12f5c083633ab..0000000000000 --- a/redhat/configs/rhel/generic/CONFIG_NET_FOU +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_NET_FOU is not set diff --git a/redhat/configs/rhel/generic/CONFIG_NET_FOU_IP_TUNNELS b/redhat/configs/rhel/generic/CONFIG_NET_FOU_IP_TUNNELS deleted file mode 100644 index b2cb0a55c7637..0000000000000 --- a/redhat/configs/rhel/generic/CONFIG_NET_FOU_IP_TUNNELS +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_NET_FOU_IP_TUNNELS is not set diff --git a/redhat/kernel.changelog-9.7 b/redhat/kernel.changelog-9.7 index f431471a80aee..c7aee9685e383 100644 --- a/redhat/kernel.changelog-9.7 +++ b/redhat/kernel.changelog-9.7 @@ -1,3 +1,31 @@ +* Tue Feb 24 2026 CKI KWF Bot [5.14.0-611.36.1.el9_7] +- net/smc: Remove validation of reserved bits in CLC Decline message (Mete Durlu) [RHEL-143718] +- autofs: dont trigger mount if it cant succeed (Ian Kent) [RHEL-149495] +- migrate: correct lock ordering for hugetlb file folios (Luiz Capitulino) [RHEL-147266] {CVE-2026-23097} +- ice: PTP: fix missing timestamps on E825 hardware (CKI Backport Bot) [RHEL-148166] +- fou: Don't allow 0 for FOU_ATTR_IPPROTO. (Xin Long) [RHEL-144987] +- tools: ynl: Specify --no-line-number in ynl-regen.sh. (Xin Long) [RHEL-144987] +- gue: Fix skb memleak with inner IP protocol 0. (Xin Long) [RHEL-144987] +- netlink: specs: fou: replace underscores with dashes in names (Xin Long) [RHEL-144987] +- fou: fix initialization of grc (Xin Long) [RHEL-144987] +- fou: Fix null-ptr-deref in GRO. (Xin Long) [RHEL-144987] +- fou: remove warn in gue_gro_receive on unsupported protocol (Xin Long) [RHEL-144987] +- fou: Remove XRFM from NET_FOU Kconfig (Xin Long) [RHEL-144987] +- fou: remove sparse errors (Xin Long) [RHEL-144987] +- redhat: enable FOU modules in kernel-modules-extra (Xin Long) [RHEL-144987] +- s390/mm: Fix __ptep_rdp() inline assembly (Mete Durlu) [RHEL-143713] +- dpll: expose fractional frequency offset in ppt (Ivan Vecera) [RHEL-146357] +- dpll: zl3073x: Implement device mode setting support (Ivan Vecera) [RHEL-147459] +- dpll: add dpll_device op to set working mode (Ivan Vecera) [RHEL-147459] +- dpll: add dpll_device op to get supported modes (Ivan Vecera) [RHEL-147459] +- i40e: add rh_phys_port_name mod option to behave like upstream (CKI Backport Bot) [RHEL-128237] +- ice: add rh_phys_port_name mod option to behave like upstream (CKI Backport Bot) [RHEL-128237] +- scsi: qla2xxx: Fix bsg_done() causing double free (Ewan D. Milne) [RHEL-146049] +- ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr() (CKI Backport Bot) [RHEL-143545] {CVE-2025-71085} +- tick/sched: Limit non-timekeeper CPUs calling jiffies update (Phil Auld) [RHEL-141462] +- smc: Use __sk_dst_get() and dst_dev_rcu() in smc_clc_prfx_match(). (Mete Durlu) [RHEL-130017] {CVE-2025-40168} +Resolves: RHEL-128237, RHEL-130017, RHEL-141462, RHEL-143545, RHEL-143713, RHEL-143718, RHEL-144987, RHEL-146049, RHEL-146357, RHEL-147266, RHEL-147459, RHEL-148166, RHEL-149495 + * Tue Feb 17 2026 CKI KWF Bot [5.14.0-611.35.1.el9_7] - page_pool: Fix use-after-free in page_pool_recycle_in_ring (Paolo Abeni) [RHEL-137841] {CVE-2025-38129} - exfat: fix double free in delayed_free (CKI Backport Bot) [RHEL-146403] {CVE-2025-38206} diff --git a/redhat/rhel_files/mod-extra.list.rhel b/redhat/rhel_files/mod-extra.list.rhel index f9ec7eb96e42a..c63247ed3a599 100644 --- a/redhat/rhel_files/mod-extra.list.rhel +++ b/redhat/rhel_files/mod-extra.list.rhel @@ -47,6 +47,8 @@ ems_pci.ko ems_usb.ko esd_usb2.ko esi-sir.ko +fou.ko +fou6.ko gamecon.ko gf2k.ko gigaset.ko diff --git a/tools/net/ynl/ynl-regen.sh b/tools/net/ynl/ynl-regen.sh index a37304dcc88e1..7bfe773dce1bf 100755 --- a/tools/net/ynl/ynl-regen.sh +++ b/tools/net/ynl/ynl-regen.sh @@ -21,7 +21,7 @@ files=$(git grep --files-with-matches '^/\* YNL-GEN \(kernel\|uapi\|user\)') for f in $files; do # params: 0 1 2 3 # $YAML YNL-GEN kernel $mode - params=( $(git grep -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') ) + params=( $(git grep --no-line-number -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') ) args=$(sed -n 's@/\* YNL-ARG \(.*\) \*/@\1@p' $f) if [ $f -nt ${params[0]} -a -z "$force" ]; then