]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Mon, 9 Dec 2024 11:18:32 +0000 (06:18 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 9 Dec 2024 11:18:32 +0000 (06:18 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
29 files changed:
queue-5.4/can-j1939-j1939_session_new-fix-skb-reference-counti.patch [new file with mode: 0644]
queue-5.4/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch [new file with mode: 0644]
queue-5.4/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch [new file with mode: 0644]
queue-5.4/crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch [new file with mode: 0644]
queue-5.4/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch [new file with mode: 0644]
queue-5.4/gpio-grgpio-add-null-check-in-grgpio_probe.patch [new file with mode: 0644]
queue-5.4/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch [new file with mode: 0644]
queue-5.4/igb-fix-potential-invalid-memory-access-in-igb_init_.patch [new file with mode: 0644]
queue-5.4/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch [new file with mode: 0644]
queue-5.4/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch [new file with mode: 0644]
queue-5.4/net-ipv6-release-expired-exception-dst-cached-in-soc.patch [new file with mode: 0644]
queue-5.4/net-qed-allow-old-cards-not-supporting-num_images-to.patch [new file with mode: 0644]
queue-5.4/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch [new file with mode: 0644]
queue-5.4/netfilter-ipset-hold-module-reference-while-requesti.patch [new file with mode: 0644]
queue-5.4/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch [new file with mode: 0644]
queue-5.4/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tipc-add-new-aead-key-structure-for-user-api.patch [new file with mode: 0644]
queue-5.4/tipc-add-reference-counter-to-bearer.patch [new file with mode: 0644]
queue-5.4/tipc-enable-creating-a-preliminary-node.patch [new file with mode: 0644]
queue-5.4/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch [new file with mode: 0644]
queue-5.4/watchdog-mediatek-make-sure-system-reset-gets-assert.patch [new file with mode: 0644]
queue-5.4/x86-asm-crypto-annotate-local-functions.patch [new file with mode: 0644]
queue-5.4/x86-asm-reorder-early-variables.patch [new file with mode: 0644]
queue-5.4/xen-fix-the-issue-of-resource-not-being-properly-rel.patch [new file with mode: 0644]
queue-5.4/xen-xenbus-fix-locking.patch [new file with mode: 0644]
queue-5.4/xen-xenbus-reference-count-registered-modules.patch [new file with mode: 0644]
queue-5.4/xenbus-backend-add-memory-pressure-handler-callback.patch [new file with mode: 0644]
queue-5.4/xenbus-backend-protect-xenbus-callback-with-lock.patch [new file with mode: 0644]

diff --git a/queue-5.4/can-j1939-j1939_session_new-fix-skb-reference-counti.patch b/queue-5.4/can-j1939-j1939_session_new-fix-skb-reference-counti.patch
new file mode 100644 (file)
index 0000000..5c4ff0c
--- /dev/null
@@ -0,0 +1,43 @@
+From afaea757f8d6771907cf34a9832f3bea0ac79866 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 12:48:23 +0300
+Subject: can: j1939: j1939_session_new(): fix skb reference counting
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit a8c695005bfe6569acd73d777ca298ddddd66105 ]
+
+Since j1939_session_skb_queue() does an extra skb_get() for each new
+skb, do the same for the initial one in j1939_session_new() to avoid
+refcount underflow.
+
+Reported-by: syzbot+d4e8dc385d9258220c31@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d4e8dc385d9258220c31
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20241105094823.2403806-1-dmantipov@yandex.ru
+[mkl: clean up commit message]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 1d926a0372e61..7cef19287a3ff 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -1489,7 +1489,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv,
+       session->state = J1939_SESSION_NEW;
+       skb_queue_head_init(&session->skb_queue);
+-      skb_queue_tail(&session->skb_queue, skb);
++      skb_queue_tail(&session->skb_queue, skb_get(skb));
+       skcb = j1939_skb_to_cb(skb);
+       memcpy(&session->skcb, skcb, sizeof(session->skcb));
+-- 
+2.43.0
+
diff --git a/queue-5.4/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch b/queue-5.4/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch
new file mode 100644 (file)
index 0000000..d16b7f4
--- /dev/null
@@ -0,0 +1,47 @@
+From 84b79477eef284a527684ef393b64c13aa95b013 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:43 +0100
+Subject: can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf
+ is NULL
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit ee6bf3677ae03569d833795064e17f605c2163c7 ]
+
+Call the function can_change_state() if the allocation of the skb
+fails, as it handles the cf parameter when it is null.
+
+Additionally, this ensures that the statistics related to state error
+counters (i. e. warning, passive, and bus-off) are updated.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-3-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index c519b6f63b33a..d627fb2948be8 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -614,10 +614,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+               tx_state = txerr >= rxerr ? state : 0;
+               rx_state = txerr <= rxerr ? state : 0;
+-              if (likely(skb))
+-                      can_change_state(dev, cf, tx_state, rx_state);
+-              else
+-                      priv->can.state = state;
++              /* The skb allocation might fail, but can_change_state()
++               * handles cf == NULL.
++               */
++              can_change_state(dev, cf, tx_state, rx_state);
+               if (state == CAN_STATE_BUS_OFF)
+                       can_bus_off(dev);
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.4/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch b/queue-5.4/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch
new file mode 100644 (file)
index 0000000..ce44586
--- /dev/null
@@ -0,0 +1,63 @@
+From 93bdb1e6020b1a25a4767d0658900e5f5bdffe2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:51 +0100
+Subject: can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 595a81988a6fe06eb5849e972c8b9cb21c4e0d54 ]
+
+The sun4i_can_err() function only incremented the receive error counter
+and never the transmit error counter, even if the STA_ERR_DIR flag
+reported that an error had occurred during transmission.
+
+Increment the receive/transmit error counter based on the value of the
+STA_ERR_DIR flag.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-11-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index d627fb2948be8..0eddd5779e5a2 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -563,11 +563,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+               /* bus error interrupt */
+               netdev_dbg(dev, "bus error interrupt\n");
+               priv->can.can_stats.bus_error++;
+-              stats->rx_errors++;
++              ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
+               if (likely(skb)) {
+-                      ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
+-
+                       cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+                       switch (ecc & SUN4I_STA_MASK_ERR) {
+@@ -585,9 +583,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+                                              >> 16;
+                               break;
+                       }
+-                      /* error occurred during transmission? */
+-                      if ((ecc & SUN4I_STA_ERR_DIR) == 0)
++              }
++
++              /* error occurred during transmission? */
++              if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
++                      if (likely(skb))
+                               cf->data[2] |= CAN_ERR_PROT_TX;
++                      stats->tx_errors++;
++              } else {
++                      stats->rx_errors++;
+               }
+       }
+       if (isrc & SUN4I_INT_ERR_PASSIVE) {
+-- 
+2.43.0
+
diff --git a/queue-5.4/crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch b/queue-5.4/crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch
new file mode 100644 (file)
index 0000000..e7233c9
--- /dev/null
@@ -0,0 +1,136 @@
+From 4d606812eef72a7fb42016e3a6cf2351811021d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 17:00:42 -0700
+Subject: crypto: x86/aegis128 - access 32-bit arguments as 32-bit
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 3b2f2d22fb424e9bebda4dbf6676cbfc7f9f62cd ]
+
+Fix the AEGIS assembly code to access 'unsigned int' arguments as 32-bit
+values instead of 64-bit, since the upper bits of the corresponding
+64-bit registers are not guaranteed to be zero.
+
+Note: there haven't been any reports of this bug actually causing
+incorrect behavior.  Neither gcc nor clang guarantee zero-extension to
+64 bits, but zero-extension is likely to happen in practice because most
+instructions that operate on 32-bit registers zero-extend to 64 bits.
+
+Fixes: 1d373d4e8e15 ("crypto: x86 - Add optimized AEGIS implementations")
+Cc: stable@vger.kernel.org
+Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/crypto/aegis128-aesni-asm.S | 29 ++++++++++++++--------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/arch/x86/crypto/aegis128-aesni-asm.S b/arch/x86/crypto/aegis128-aesni-asm.S
+index b7026fdef4ff2..6c5048605a664 100644
+--- a/arch/x86/crypto/aegis128-aesni-asm.S
++++ b/arch/x86/crypto/aegis128-aesni-asm.S
+@@ -20,7 +20,7 @@
+ #define T1    %xmm7
+ #define STATEP        %rdi
+-#define LEN   %rsi
++#define LEN   %esi
+ #define SRC   %rdx
+ #define DST   %rcx
+@@ -75,32 +75,32 @@ SYM_FUNC_START_LOCAL(__load_partial)
+       xor %r9d, %r9d
+       pxor MSG, MSG
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x1, %r8
+       jz .Lld_partial_1
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x1E, %r8
+       add SRC, %r8
+       mov (%r8), %r9b
+ .Lld_partial_1:
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x2, %r8
+       jz .Lld_partial_2
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x1C, %r8
+       add SRC, %r8
+       shl $0x10, %r9
+       mov (%r8), %r9w
+ .Lld_partial_2:
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x4, %r8
+       jz .Lld_partial_4
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x18, %r8
+       add SRC, %r8
+       shl $32, %r9
+@@ -110,11 +110,11 @@ SYM_FUNC_START_LOCAL(__load_partial)
+ .Lld_partial_4:
+       movq %r9, MSG
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x8, %r8
+       jz .Lld_partial_8
+-      mov LEN, %r8
++      mov LEN, %r8d
+       and $0x10, %r8
+       add SRC, %r8
+       pslldq $8, MSG
+@@ -138,7 +138,7 @@ SYM_FUNC_END(__load_partial)
+  *   %r10
+  */
+ SYM_FUNC_START_LOCAL(__store_partial)
+-      mov LEN, %r8
++      mov LEN, %r8d
+       mov DST, %r9
+       movq T0, %r10
+@@ -676,7 +676,7 @@ ENTRY(crypto_aegis128_aesni_dec_tail)
+       call __store_partial
+       /* mask with byte count: */
+-      movq LEN, T0
++      movd LEN, T0
+       punpcklbw T0, T0
+       punpcklbw T0, T0
+       punpcklbw T0, T0
+@@ -701,7 +701,8 @@ ENDPROC(crypto_aegis128_aesni_dec_tail)
+ /*
+  * void crypto_aegis128_aesni_final(void *state, void *tag_xor,
+- *                                  u64 assoclen, u64 cryptlen);
++ *                                  unsigned int assoclen,
++ *                                  unsigned int cryptlen);
+  */
+ ENTRY(crypto_aegis128_aesni_final)
+       FRAME_BEGIN
+@@ -714,8 +715,8 @@ ENTRY(crypto_aegis128_aesni_final)
+       movdqu 0x40(STATEP), STATE4
+       /* prepare length block: */
+-      movq %rdx, MSG
+-      movq %rcx, T0
++      movd %edx, MSG
++      movd %ecx, T0
+       pslldq $8, T0
+       pxor T0, MSG
+       psllq $3, MSG /* multiply by 8 (to get bit count) */
+-- 
+2.43.0
+
diff --git a/queue-5.4/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch b/queue-5.4/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch
new file mode 100644 (file)
index 0000000..c8f3e13
--- /dev/null
@@ -0,0 +1,78 @@
+From 28a481b7dab9ac180f98a6dfaf604a82c3736add Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2024 17:39:02 +0300
+Subject: dccp: Fix memory leak in dccp_feat_change_recv
+
+From: Ivan Solodovnikov <solodovnikov.ia@phystech.edu>
+
+[ Upstream commit 22be4727a8f898442066bcac34f8a1ad0bc72e14 ]
+
+If dccp_feat_push_confirm() fails after new value for SP feature was accepted
+without reconciliation ('entry == NULL' branch), memory allocated for that value
+with dccp_feat_clone_sp_val() is never freed.
+
+Here is the kmemleak stack for this:
+
+unreferenced object 0xffff88801d4ab488 (size 8):
+  comm "syz-executor310", pid 1127, jiffies 4295085598 (age 41.666s)
+  hex dump (first 8 bytes):
+    01 b4 4a 1d 80 88 ff ff                          ..J.....
+  backtrace:
+    [<00000000db7cabfe>] kmemdup+0x23/0x50 mm/util.c:128
+    [<0000000019b38405>] kmemdup include/linux/string.h:465 [inline]
+    [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:371 [inline]
+    [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:367 [inline]
+    [<0000000019b38405>] dccp_feat_change_recv net/dccp/feat.c:1145 [inline]
+    [<0000000019b38405>] dccp_feat_parse_options+0x1196/0x2180 net/dccp/feat.c:1416
+    [<00000000b1f6d94a>] dccp_parse_options+0xa2a/0x1260 net/dccp/options.c:125
+    [<0000000030d7b621>] dccp_rcv_state_process+0x197/0x13d0 net/dccp/input.c:650
+    [<000000001f74c72e>] dccp_v4_do_rcv+0xf9/0x1a0 net/dccp/ipv4.c:688
+    [<00000000a6c24128>] sk_backlog_rcv include/net/sock.h:1041 [inline]
+    [<00000000a6c24128>] __release_sock+0x139/0x3b0 net/core/sock.c:2570
+    [<00000000cf1f3a53>] release_sock+0x54/0x1b0 net/core/sock.c:3111
+    [<000000008422fa23>] inet_wait_for_connect net/ipv4/af_inet.c:603 [inline]
+    [<000000008422fa23>] __inet_stream_connect+0x5d0/0xf70 net/ipv4/af_inet.c:696
+    [<0000000015b6f64d>] inet_stream_connect+0x53/0xa0 net/ipv4/af_inet.c:735
+    [<0000000010122488>] __sys_connect_file+0x15c/0x1a0 net/socket.c:1865
+    [<00000000b4b70023>] __sys_connect+0x165/0x1a0 net/socket.c:1882
+    [<00000000f4cb3815>] __do_sys_connect net/socket.c:1892 [inline]
+    [<00000000f4cb3815>] __se_sys_connect net/socket.c:1889 [inline]
+    [<00000000f4cb3815>] __x64_sys_connect+0x6e/0xb0 net/socket.c:1889
+    [<00000000e7b1e839>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
+    [<0000000055e91434>] entry_SYSCALL_64_after_hwframe+0x67/0xd1
+
+Clean up the allocated memory in case of dccp_feat_push_confirm() failure
+and bail out with an error reset code.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: e77b8363b2ea ("dccp: Process incoming Change feature-negotiation options")
+Signed-off-by: Ivan Solodovnikov <solodovnikov.ia@phystech.edu>
+Link: https://patch.msgid.link/20241126143902.190853-1-solodovnikov.ia@phystech.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dccp/feat.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/dccp/feat.c b/net/dccp/feat.c
+index 9c3b5e0562342..7647306802f1e 100644
+--- a/net/dccp/feat.c
++++ b/net/dccp/feat.c
+@@ -1156,8 +1156,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt,
+                       goto not_valid_or_not_known;
+               }
+-              return dccp_feat_push_confirm(fn, feat, local, &fval);
++              if (dccp_feat_push_confirm(fn, feat, local, &fval)) {
++                      kfree(fval.sp.vec);
++                      return DCCP_RESET_CODE_TOO_BUSY;
++              }
++              return 0;
+       } else if (entry->state == FEAT_UNSTABLE) {     /* 6.6.2 */
+               return 0;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.4/gpio-grgpio-add-null-check-in-grgpio_probe.patch b/queue-5.4/gpio-grgpio-add-null-check-in-grgpio_probe.patch
new file mode 100644 (file)
index 0000000..61a4b2b
--- /dev/null
@@ -0,0 +1,41 @@
+From fa237523c59b25984d1cf67fc195dbb22d20ece7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 17:18:22 +0800
+Subject: gpio: grgpio: Add NULL check in grgpio_probe
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 050b23d081da0f29474de043e9538c1f7a351b3b ]
+
+devm_kasprintf() can return a NULL pointer on failure,but this
+returned value in grgpio_probe is not checked.
+Add NULL check in grgpio_probe, to handle kernel NULL
+pointer dereference error.
+
+Cc: stable@vger.kernel.org
+Fixes: 7eb6ce2f2723 ("gpio: Convert to using %pOF instead of full_name")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Link: https://lore.kernel.org/r/20241114091822.78199-1-hanchunchao@inspur.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-grgpio.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index 62ba651fef658..ccf407f415ab3 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -363,6 +363,9 @@ static int grgpio_probe(struct platform_device *ofdev)
+       gc->owner = THIS_MODULE;
+       gc->to_irq = grgpio_to_irq;
+       gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
++      if (!gc->label)
++              return -ENOMEM;
++
+       gc->base = -1;
+       err = of_property_read_u32(np, "nbits", &prop);
+-- 
+2.43.0
+
diff --git a/queue-5.4/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch b/queue-5.4/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch
new file mode 100644 (file)
index 0000000..4e856f3
--- /dev/null
@@ -0,0 +1,115 @@
+From 22dff71e78b0fa4cd97b4bca98cc4b9a6262616b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 15:18:31 +0200
+Subject: gpio: grgpio: use a helper variable to store the address of
+ ofdev->dev
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit d036ae41cebdfae92666024163c109b8fef516fa ]
+
+Instead of dereferencing the platform device pointer repeatedly, just
+store its address in a helper variable.
+
+Link: https://lore.kernel.org/r/20241015131832.44678-3-brgl@bgdev.pl
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-grgpio.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index 3224933f4c8f4..62ba651fef658 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -328,6 +328,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = {
+ static int grgpio_probe(struct platform_device *ofdev)
+ {
+       struct device_node *np = ofdev->dev.of_node;
++      struct device *dev = &ofdev->dev;
+       void  __iomem *regs;
+       struct gpio_chip *gc;
+       struct grgpio_priv *priv;
+@@ -337,7 +338,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+       int size;
+       int i;
+-      priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+@@ -346,29 +347,29 @@ static int grgpio_probe(struct platform_device *ofdev)
+               return PTR_ERR(regs);
+       gc = &priv->gc;
+-      err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA,
++      err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA,
+                        regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL,
+                        BGPIOF_BIG_ENDIAN_BYTE_ORDER);
+       if (err) {
+-              dev_err(&ofdev->dev, "bgpio_init() failed\n");
++              dev_err(dev, "bgpio_init() failed\n");
+               return err;
+       }
+       priv->regs = regs;
+       priv->imask = gc->read_reg(regs + GRGPIO_IMASK);
+-      priv->dev = &ofdev->dev;
++      priv->dev = dev;
+       gc->of_node = np;
+       gc->owner = THIS_MODULE;
+       gc->to_irq = grgpio_to_irq;
+-      gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np);
++      gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
+       gc->base = -1;
+       err = of_property_read_u32(np, "nbits", &prop);
+       if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) {
+               gc->ngpio = GRGPIO_MAX_NGPIO;
+-              dev_dbg(&ofdev->dev,
+-                      "No or invalid nbits property: assume %d\n", gc->ngpio);
++              dev_dbg(dev, "No or invalid nbits property: assume %d\n",
++                      gc->ngpio);
+       } else {
+               gc->ngpio = prop;
+       }
+@@ -380,7 +381,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+       irqmap = (s32 *)of_get_property(np, "irqmap", &size);
+       if (irqmap) {
+               if (size < gc->ngpio) {
+-                      dev_err(&ofdev->dev,
++                      dev_err(dev,
+                               "irqmap shorter than ngpio (%d < %d)\n",
+                               size, gc->ngpio);
+                       return -EINVAL;
+@@ -390,7 +391,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+                                                    &grgpio_irq_domain_ops,
+                                                    priv);
+               if (!priv->domain) {
+-                      dev_err(&ofdev->dev, "Could not add irq domain\n");
++                      dev_err(dev, "Could not add irq domain\n");
+                       return -EINVAL;
+               }
+@@ -420,13 +421,13 @@ static int grgpio_probe(struct platform_device *ofdev)
+       err = gpiochip_add_data(gc, priv);
+       if (err) {
+-              dev_err(&ofdev->dev, "Could not add gpiochip\n");
++              dev_err(dev, "Could not add gpiochip\n");
+               if (priv->domain)
+                       irq_domain_remove(priv->domain);
+               return err;
+       }
+-      dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
++      dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
+                priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off");
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.4/igb-fix-potential-invalid-memory-access-in-igb_init_.patch b/queue-5.4/igb-fix-potential-invalid-memory-access-in-igb_init_.patch
new file mode 100644 (file)
index 0000000..3706a55
--- /dev/null
@@ -0,0 +1,40 @@
+From 869d278598587b9017297048656e1147b29c1303 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 20:10:48 +0800
+Subject: igb: Fix potential invalid memory access in igb_init_module()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 0566f83d206c7a864abcd741fe39d6e0ae5eef29 ]
+
+The pci_register_driver() can fail and when this happened, the dca_notifier
+needs to be unregistered, otherwise the dca_notifier can be called when
+igb fails to install, resulting to invalid memory access.
+
+Fixes: bbd98fe48a43 ("igb: Fix DCA errors and do not use context index for 82576")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index 1e9967657248a..84de6bbace090 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -674,6 +674,10 @@ static int __init igb_init_module(void)
+       dca_register_notify(&dca_notifier);
+ #endif
+       ret = pci_register_driver(&igb_driver);
++#ifdef CONFIG_IGB_DCA
++      if (ret)
++              dca_unregister_notify(&dca_notifier);
++#endif
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch b/queue-5.4/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch
new file mode 100644 (file)
index 0000000..d4af46a
--- /dev/null
@@ -0,0 +1,117 @@
+From 8b2a1d14aff584f8ff23a86d6822241ca1d106e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Nov 2024 03:42:56 -0600
+Subject: ipvs: fix UB due to uninitialized stack access in
+ ip_vs_protocol_init()
+
+From: Jinghao Jia <jinghao7@illinois.edu>
+
+[ Upstream commit 146b6f1112eb30a19776d6c323c994e9d67790db ]
+
+Under certain kernel configurations when building with Clang/LLVM, the
+compiler does not generate a return or jump as the terminator
+instruction for ip_vs_protocol_init(), triggering the following objtool
+warning during build time:
+
+  vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()
+
+At runtime, this either causes an oops when trying to load the ipvs
+module or a boot-time panic if ipvs is built-in. This same issue has
+been reported by the Intel kernel test robot previously.
+
+Digging deeper into both LLVM and the kernel code reveals this to be a
+undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer
+of 64 chars to store the registered protocol names and leaves it
+uninitialized after definition. The function calls strnlen() when
+concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE
+strnlen() performs an extra step to check whether the last byte of the
+input char buffer is a null character (commit 3009f891bb9f ("fortify:
+Allow strlen() and strnlen() to pass compile-time known lengths")).
+This, together with possibly other configurations, cause the following
+IR to be generated:
+
+  define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 {
+    %1 = alloca [64 x i8], align 16
+    ...
+
+  14:                                               ; preds = %11
+    %15 = getelementptr inbounds i8, ptr %1, i64 63
+    %16 = load i8, ptr %15, align 1
+    %17 = tail call i1 @llvm.is.constant.i8(i8 %16)
+    %18 = icmp eq i8 %16, 0
+    %19 = select i1 %17, i1 %18, i1 false
+    br i1 %19, label %20, label %23
+
+  20:                                               ; preds = %14
+    %21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23
+    ...
+
+  23:                                               ; preds = %14, %11, %20
+    %24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24
+    ...
+  }
+
+The above code calculates the address of the last char in the buffer
+(value %15) and then loads from it (value %16). Because the buffer is
+never initialized, the LLVM GVN pass marks value %16 as undefined:
+
+  %13 = getelementptr inbounds i8, ptr %1, i64 63
+  br i1 undef, label %14, label %17
+
+This gives later passes (SCCP, in particular) more DCE opportunities by
+propagating the undef value further, and eventually removes everything
+after the load on the uninitialized stack location:
+
+  define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 {
+    %1 = alloca [64 x i8], align 16
+    ...
+
+  12:                                               ; preds = %11
+    %13 = getelementptr inbounds i8, ptr %1, i64 63
+    unreachable
+  }
+
+In this way, the generated native code will just fall through to the
+next function, as LLVM does not generate any code for the unreachable IR
+instruction and leaves the function without a terminator.
+
+Zero the on-stack buffer to avoid this possible UB.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202402100205.PWXIz1ZK-lkp@intel.com/
+Co-developed-by: Ruowen Qin <ruqin@redhat.com>
+Signed-off-by: Ruowen Qin <ruqin@redhat.com>
+Signed-off-by: Jinghao Jia <jinghao7@illinois.edu>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_proto.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
+index f100da4ba3bc3..a9fd1d3fc2cbf 100644
+--- a/net/netfilter/ipvs/ip_vs_proto.c
++++ b/net/netfilter/ipvs/ip_vs_proto.c
+@@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs)
+ int __init ip_vs_protocol_init(void)
+ {
+-      char protocols[64];
++      char protocols[64] = { 0 };
+ #define REGISTER_PROTOCOL(p)                  \
+       do {                                    \
+               register_ip_vs_protocol(p);     \
+@@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void)
+               strcat(protocols, (p)->name);   \
+       } while (0)
+-      protocols[0] = '\0';
+-      protocols[2] = '\0';
+ #ifdef CONFIG_IP_VS_PROTO_TCP
+       REGISTER_PROTOCOL(&ip_vs_protocol_tcp);
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.4/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch b/queue-5.4/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch
new file mode 100644 (file)
index 0000000..de0a970
--- /dev/null
@@ -0,0 +1,85 @@
+From f3a8d8bc065850255ca3bf7119e745fddbd9885a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 12:14:03 -0700
+Subject: iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
+
+From: Oleksandr Ocheretnyi <oocheret@cisco.com>
+
+[ Upstream commit daa814d784ac034c62ab3fb0ef83daeafef527e2 ]
+
+Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake
+PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's
+value comparison for update_no_reboot_bit() call causing following
+failure:
+
+   ...
+   iTCO_vendor_support: vendor-support=0
+   iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device
+                                    disabled by hardware/BIOS
+   ...
+
+and this can lead to unexpected NMIs later during regular
+crashkernel's workflow because of watchdog probe call failures.
+
+This change masks NMI_NOW bit for TCO1_CNT register values to
+avoid unexpected NMI_NOW bit inversions.
+
+Fixes: da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO")
+Signed-off-by: Oleksandr Ocheretnyi <oocheret@cisco.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Link: https://lore.kernel.org/r/20240913191403.2560805-1-oocheret@cisco.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
+index 134237d8b8fca..c03df400ffb90 100644
+--- a/drivers/watchdog/iTCO_wdt.c
++++ b/drivers/watchdog/iTCO_wdt.c
+@@ -83,6 +83,13 @@
+ #define TCO2_CNT(p)   (TCOBASE(p) + 0x0a) /* TCO2 Control Register    */
+ #define TCOv2_TMR(p)  (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/
++/*
++ * NMI_NOW is bit 8 of TCO1_CNT register
++ * Read/Write
++ * This bit is implemented as RW but has no effect on HW.
++ */
++#define NMI_NOW               BIT(8)
++
+ /* internal variables */
+ struct iTCO_wdt_private {
+       struct watchdog_device wddev;
+@@ -221,13 +228,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set)
+       struct iTCO_wdt_private *p = priv;
+       u16 val, newval;
+-      val = inw(TCO1_CNT(p));
++      /*
++       * writing back 1b1 to NMI_NOW of TCO1_CNT register
++       * causes NMI_NOW bit inversion what consequently does
++       * not allow to perform the register's value comparison
++       * properly.
++       *
++       * NMI_NOW bit masking for TCO1_CNT register values
++       * helps to avoid possible NMI_NOW bit inversions on
++       * following write operation.
++       */
++      val = inw(TCO1_CNT(p)) & ~NMI_NOW;
+       if (set)
+               val |= BIT(0);
+       else
+               val &= ~BIT(0);
+       outw(val, TCO1_CNT(p));
+-      newval = inw(TCO1_CNT(p));
++      newval = inw(TCO1_CNT(p)) & ~NMI_NOW;
+       /* make sure the update is successful */
+       return val != newval ? -EIO : 0;
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-ipv6-release-expired-exception-dst-cached-in-soc.patch b/queue-5.4/net-ipv6-release-expired-exception-dst-cached-in-soc.patch
new file mode 100644 (file)
index 0000000..9cd2786
--- /dev/null
@@ -0,0 +1,85 @@
+From ed9484e1ff6ad7290e7c790f8653203987c9f480 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 09:59:50 +0100
+Subject: net/ipv6: release expired exception dst cached in socket
+
+From: Jiri Wiesner <jwiesner@suse.de>
+
+[ Upstream commit 3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045 ]
+
+Dst objects get leaked in ip6_negative_advice() when this function is
+executed for an expired IPv6 route located in the exception table. There
+are several conditions that must be fulfilled for the leak to occur:
+* an ICMPv6 packet indicating a change of the MTU for the path is received,
+  resulting in an exception dst being created
+* a TCP connection that uses the exception dst for routing packets must
+  start timing out so that TCP begins retransmissions
+* after the exception dst expires, the FIB6 garbage collector must not run
+  before TCP executes ip6_negative_advice() for the expired exception dst
+
+When TCP executes ip6_negative_advice() for an exception dst that has
+expired and if no other socket holds a reference to the exception dst, the
+refcount of the exception dst is 2, which corresponds to the increment
+made by dst_init() and the increment made by the TCP socket for which the
+connection is timing out. The refcount made by the socket is never
+released. The refcount of the dst is decremented in sk_dst_reset() but
+that decrement is counteracted by a dst_hold() intentionally placed just
+before the sk_dst_reset() in ip6_negative_advice(). After
+ip6_negative_advice() has finished, there is no other object tied to the
+dst. The socket lost its reference stored in sk_dst_cache and the dst is
+no longer in the exception table. The exception dst becomes a leaked
+object.
+
+As a result of this dst leak, an unbalanced refcount is reported for the
+loopback device of a net namespace being destroyed under kernels that do
+not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"):
+unregister_netdevice: waiting for lo to become free. Usage count = 2
+
+Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The
+patch that introduced the dst_hold() in ip6_negative_advice() was
+92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22
+merely refactored the code with regards to the dst refcount so the issue
+was present even before 92f1655aa2b22. The bug was introduced in
+54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually
+expired.") where the expired cached route is deleted and the sk_dst_cache
+member of the socket is set to NULL by calling dst_negative_advice() but
+the refcount belonging to the socket is left unbalanced.
+
+The IPv4 version - ipv4_negative_advice() - is not affected by this bug.
+When the TCP connection times out ipv4_negative_advice() merely resets the
+sk_dst_cache of the socket while decrementing the refcount of the
+exception dst.
+
+Fixes: 92f1655aa2b22 ("net: fix __dst_negative_advice() race")
+Fixes: 54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually expired.")
+Link: https://lore.kernel.org/netdev/20241113105611.GA6723@incl/T/#u
+Signed-off-by: Jiri Wiesner <jwiesner@suse.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241128085950.GA4505@incl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 2e91a563139a8..f1c2ac967e36c 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2670,10 +2670,10 @@ static void ip6_negative_advice(struct sock *sk,
+       if (rt->rt6i_flags & RTF_CACHE) {
+               rcu_read_lock();
+               if (rt6_check_expired(rt)) {
+-                      /* counteract the dst_release() in sk_dst_reset() */
+-                      dst_hold(dst);
++                      /* rt/dst can not be destroyed yet,
++                       * because of rcu_read_lock()
++                       */
+                       sk_dst_reset(sk);
+-
+                       rt6_remove_exception_rt(rt);
+               }
+               rcu_read_unlock();
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-qed-allow-old-cards-not-supporting-num_images-to.patch b/queue-5.4/net-qed-allow-old-cards-not-supporting-num_images-to.patch
new file mode 100644 (file)
index 0000000..ee74136
--- /dev/null
@@ -0,0 +1,48 @@
+From c6376df776c740c335583e200d1fa43bac458484 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 09:33:58 +0100
+Subject: net/qed: allow old cards not supporting "num_images" to work
+
+From: Louis Leseur <louis.leseur@gmail.com>
+
+[ Upstream commit 7a0ea70da56ee8c2716d0b79e9959d3c47efab62 ]
+
+Commit 43645ce03e00 ("qed: Populate nvm image attribute shadow.")
+added support for populating flash image attributes, notably
+"num_images". However, some cards were not able to return this
+information. In such cases, the driver would return EINVAL, causing the
+driver to exit.
+
+Add check to return EOPNOTSUPP instead of EINVAL when the card is not
+able to return these information. The caller function already handles
+EOPNOTSUPP without error.
+
+Fixes: 43645ce03e00 ("qed: Populate nvm image attribute shadow.")
+Co-developed-by: Florian Forestier <florian@forestier.re>
+Signed-off-by: Florian Forestier <florian@forestier.re>
+Signed-off-by: Louis Leseur <louis.leseur@gmail.com>
+Link: https://patch.msgid.link/20241128083633.26431-1-louis.leseur@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+index 3769b15b04b3b..168dbf11efed8 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+@@ -3059,7 +3059,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
+       if (rc)
+               return rc;
+-      if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
++      if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED))
++              rc = -EOPNOTSUPP;
++      else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
+               rc = -EINVAL;
+       return rc;
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch b/queue-5.4/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch
new file mode 100644 (file)
index 0000000..775570a
--- /dev/null
@@ -0,0 +1,91 @@
+From d5b1723db6ea5c340a96239b76fe451a9793f53f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 18:46:07 +0100
+Subject: net/sched: tbf: correct backlog statistic for GSO packets
+
+From: Martin Ottens <martin.ottens@fau.de>
+
+[ Upstream commit 1596a135e3180c92e42dd1fbcad321f4fb3e3b17 ]
+
+When the length of a GSO packet in the tbf qdisc is larger than the burst
+size configured the packet will be segmented by the tbf_segment function.
+Whenever this function is used to enqueue SKBs, the backlog statistic of
+the tbf is not increased correctly. This can lead to underflows of the
+'backlog' byte-statistic value when these packets are dequeued from tbf.
+
+Reproduce the bug:
+Ensure that the sender machine has GSO enabled. Configured the tbf on
+the outgoing interface of the machine as follows (burstsize = 1 MTU):
+$ tc qdisc add dev <oif> root handle 1: tbf rate 50Mbit burst 1514 latency 50ms
+
+Send bulk TCP traffic out via this interface, e.g., by running an iPerf3
+client on this machine. Check the qdisc statistics:
+$ tc -s qdisc show dev <oif>
+
+The 'backlog' byte-statistic has incorrect values while traffic is
+transferred, e.g., high values due to u32 underflows. When the transfer
+is stopped, the value is != 0, which should never happen.
+
+This patch fixes this bug by updating the statistics correctly, even if
+single SKBs of a GSO SKB cannot be enqueued.
+
+Fixes: e43ac79a4bc6 ("sch_tbf: segment too big GSO packets")
+Signed-off-by: Martin Ottens <martin.ottens@fau.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241125174608.1484356-1-martin.ottens@fau.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_tbf.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
+index a7f60bb2dd513..259a39ca99bfb 100644
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -146,7 +146,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
+       struct tbf_sched_data *q = qdisc_priv(sch);
+       struct sk_buff *segs, *nskb;
+       netdev_features_t features = netif_skb_features(skb);
+-      unsigned int len = 0, prev_len = qdisc_pkt_len(skb);
++      unsigned int len = 0, prev_len = qdisc_pkt_len(skb), seg_len;
+       int ret, nb;
+       segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+@@ -158,22 +158,28 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
+       while (segs) {
+               nskb = segs->next;
+               skb_mark_not_on_list(segs);
+-              qdisc_skb_cb(segs)->pkt_len = segs->len;
+-              len += segs->len;
++              seg_len = segs->len;
++              qdisc_skb_cb(segs)->pkt_len = seg_len;
+               ret = qdisc_enqueue(segs, q->qdisc, to_free);
+               if (ret != NET_XMIT_SUCCESS) {
+                       if (net_xmit_drop_count(ret))
+                               qdisc_qstats_drop(sch);
+               } else {
+                       nb++;
++                      len += seg_len;
+               }
+               segs = nskb;
+       }
+       sch->q.qlen += nb;
+-      if (nb > 1)
++      sch->qstats.backlog += len;
++      if (nb > 0) {
+               qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len);
+-      consume_skb(skb);
+-      return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP;
++              consume_skb(skb);
++              return NET_XMIT_SUCCESS;
++      }
++
++      kfree_skb(skb);
++      return NET_XMIT_DROP;
+ }
+ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+-- 
+2.43.0
+
diff --git a/queue-5.4/netfilter-ipset-hold-module-reference-while-requesti.patch b/queue-5.4/netfilter-ipset-hold-module-reference-while-requesti.patch
new file mode 100644 (file)
index 0000000..5829267
--- /dev/null
@@ -0,0 +1,49 @@
+From a51c30bf991ead1673fc672b432feb7638a62031 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 16:30:38 +0100
+Subject: netfilter: ipset: Hold module reference while requesting a module
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 456f010bfaefde84d3390c755eedb1b0a5857c3c ]
+
+User space may unload ip_set.ko while it is itself requesting a set type
+backend module, leading to a kernel crash. The race condition may be
+provoked by inserting an mdelay() right after the nfnl_unlock() call.
+
+Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Acked-by: Jozsef Kadlecsik <kadlec@netfilter.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipset/ip_set_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 83fa95ecaad47..1ce19162ebf79 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -103,14 +103,19 @@ find_set_type(const char *name, u8 family, u8 revision)
+ static bool
+ load_settype(const char *name)
+ {
++      if (!try_module_get(THIS_MODULE))
++              return false;
++
+       nfnl_unlock(NFNL_SUBSYS_IPSET);
+       pr_debug("try to load ip_set_%s\n", name);
+       if (request_module("ip_set_%s", name) < 0) {
+               pr_warn("Can't find ip_set type %s\n", name);
+               nfnl_lock(NFNL_SUBSYS_IPSET);
++              module_put(THIS_MODULE);
+               return false;
+       }
+       nfnl_lock(NFNL_SUBSYS_IPSET);
++      module_put(THIS_MODULE);
+       return true;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch b/queue-5.4/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch
new file mode 100644 (file)
index 0000000..d716968
--- /dev/null
@@ -0,0 +1,97 @@
+From 3b8048da92d50cd6f81901f89bf5c58405171e95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 00:04:49 +0100
+Subject: netfilter: nft_set_hash: skip duplicated elements pending gc run
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 7ffc7481153bbabf3332c6a19b289730c7e1edf5 ]
+
+rhashtable does not provide stable walk, duplicated elements are
+possible in case of resizing. I considered that checking for errors when
+calling rhashtable_walk_next() was sufficient to detect the resizing.
+However, rhashtable_walk_next() returns -EAGAIN only at the end of the
+iteration, which is too late, because a gc work containing duplicated
+elements could have been already scheduled for removal to the worker.
+
+Add a u32 gc worker sequence number per set, bump it on every workqueue
+run. Annotate gc worker sequence number on the expired element. Use it
+to skip those already seen in this gc workqueue run.
+
+Note that this new field is never reset in case gc transaction fails, so
+next gc worker run on the expired element overrides it. Wraparound of gc
+worker sequence number should not be an issue with stale gc worker
+sequence number in the element, that would just postpone the element
+removal in one gc run.
+
+Note that it is not possible to use flags to annotate that element is
+pending gc run to detect duplicates, given that gc transaction can be
+invalidated in case of update from the control plane, therefore, not
+allowing to clear such flag.
+
+On x86_64, pahole reports no changes in the size of nft_rhash_elem.
+
+Fixes: f6c383b8c31a ("netfilter: nf_tables: adapt set backend to use GC transaction API")
+Reported-by: Laurent Fasnacht <laurent.fasnacht@proton.ch>
+Tested-by: Laurent Fasnacht <laurent.fasnacht@proton.ch>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_hash.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index ec03d4c77b3df..200f837372adf 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -27,10 +27,12 @@ extern unsigned int nf_tables_net_id;
+ struct nft_rhash {
+       struct rhashtable               ht;
+       struct delayed_work             gc_work;
++      u32                             wq_gc_seq;
+ };
+ struct nft_rhash_elem {
+       struct rhash_head               node;
++      u32                             wq_gc_seq;
+       struct nft_set_ext              ext;
+ };
+@@ -325,6 +327,10 @@ static void nft_rhash_gc(struct work_struct *work)
+       if (!gc)
+               goto done;
++      /* Elements never collected use a zero gc worker sequence number. */
++      if (unlikely(++priv->wq_gc_seq == 0))
++              priv->wq_gc_seq++;
++
+       rhashtable_walk_enter(&priv->ht, &hti);
+       rhashtable_walk_start(&hti);
+@@ -342,6 +348,14 @@ static void nft_rhash_gc(struct work_struct *work)
+                       goto try_later;
+               }
++              /* rhashtable walk is unstable, already seen in this gc run?
++               * Then, skip this element. In case of (unlikely) sequence
++               * wraparound and stale element wq_gc_seq, next gc run will
++               * just find this expired element.
++               */
++              if (he->wq_gc_seq == priv->wq_gc_seq)
++                      continue;
++
+               if (nft_set_elem_is_dead(&he->ext))
+                       goto dead_elem;
+@@ -362,6 +376,8 @@ static void nft_rhash_gc(struct work_struct *work)
+               if (!gc)
+                       goto try_later;
++              /* annotate gc sequence for this attempt. */
++              he->wq_gc_seq = priv->wq_gc_seq;
+               nft_trans_gc_elem_add(gc, he);
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.4/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch b/queue-5.4/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch
new file mode 100644 (file)
index 0000000..88a2237
--- /dev/null
@@ -0,0 +1,109 @@
+From c97bfaf8682b099278ae7a40357b9a35f581aa12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Nov 2024 09:55:42 +0300
+Subject: netfilter: x_tables: fix LED ID check in led_tg_check()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 04317f4eb2aad312ad85c1a17ad81fe75f1f9bc7 ]
+
+Syzbot has reported the following BUG detected by KASAN:
+
+BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70
+Read of size 1 at addr ffff8881022da0c8 by task repro/5879
+...
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x241/0x360
+ ? __pfx_dump_stack_lvl+0x10/0x10
+ ? __pfx__printk+0x10/0x10
+ ? _printk+0xd5/0x120
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x183/0x530
+ print_report+0x169/0x550
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x45f/0x530
+ ? __phys_addr+0xba/0x170
+ ? strlen+0x58/0x70
+ kasan_report+0x143/0x180
+ ? strlen+0x58/0x70
+ strlen+0x58/0x70
+ kstrdup+0x20/0x80
+ led_tg_check+0x18b/0x3c0
+ xt_check_target+0x3bb/0xa40
+ ? __pfx_xt_check_target+0x10/0x10
+ ? stack_depot_save_flags+0x6e4/0x830
+ ? nft_target_init+0x174/0xc30
+ nft_target_init+0x82d/0xc30
+ ? __pfx_nft_target_init+0x10/0x10
+ ? nf_tables_newrule+0x1609/0x2980
+ ? nf_tables_newrule+0x1609/0x2980
+ ? rcu_is_watching+0x15/0xb0
+ ? nf_tables_newrule+0x1609/0x2980
+ ? nf_tables_newrule+0x1609/0x2980
+ ? __kmalloc_noprof+0x21a/0x400
+ nf_tables_newrule+0x1860/0x2980
+ ? __pfx_nf_tables_newrule+0x10/0x10
+ ? __nla_parse+0x40/0x60
+ nfnetlink_rcv+0x14e5/0x2ab0
+ ? __pfx_validate_chain+0x10/0x10
+ ? __pfx_nfnetlink_rcv+0x10/0x10
+ ? __lock_acquire+0x1384/0x2050
+ ? netlink_deliver_tap+0x2e/0x1b0
+ ? __pfx_lock_release+0x10/0x10
+ ? netlink_deliver_tap+0x2e/0x1b0
+ netlink_unicast+0x7f8/0x990
+ ? __pfx_netlink_unicast+0x10/0x10
+ ? __virt_addr_valid+0x183/0x530
+ ? __check_object_size+0x48e/0x900
+ netlink_sendmsg+0x8e4/0xcb0
+ ? __pfx_netlink_sendmsg+0x10/0x10
+ ? aa_sock_msg_perm+0x91/0x160
+ ? __pfx_netlink_sendmsg+0x10/0x10
+ __sock_sendmsg+0x223/0x270
+ ____sys_sendmsg+0x52a/0x7e0
+ ? __pfx_____sys_sendmsg+0x10/0x10
+ __sys_sendmsg+0x292/0x380
+ ? __pfx___sys_sendmsg+0x10/0x10
+ ? lockdep_hardirqs_on_prepare+0x43d/0x780
+ ? __pfx_lockdep_hardirqs_on_prepare+0x10/0x10
+ ? exc_page_fault+0x590/0x8c0
+ ? do_syscall_64+0xb6/0x230
+ do_syscall_64+0xf3/0x230
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+...
+ </TASK>
+
+Since an invalid (without '\0' byte at all) byte sequence may be passed
+from userspace, add an extra check to ensure that such a sequence is
+rejected as possible ID and so never passed to 'kstrdup()' and further.
+
+Reported-by: syzbot+6c8215822f35fdb35667@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6c8215822f35fdb35667
+Fixes: 268cb38e1802 ("netfilter: x_tables: add LED trigger target")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_LED.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c
+index 0371c387b0d1f..13a2b5820b34b 100644
+--- a/net/netfilter/xt_LED.c
++++ b/net/netfilter/xt_LED.c
+@@ -97,7 +97,9 @@ static int led_tg_check(const struct xt_tgchk_param *par)
+       struct xt_led_info_internal *ledinternal;
+       int err;
+-      if (ledinfo->id[0] == '\0')
++      /* Bail out if empty string or not a string at all. */
++      if (ledinfo->id[0] == '\0' ||
++          !memchr(ledinfo->id, '\0', sizeof(ledinfo->id)))
+               return -EINVAL;
+       mutex_lock(&xt_led_mutex);
+-- 
+2.43.0
+
index fecc5c70227bce834560183235de58861397d1a5..c1ef19a6f0797f4ad2eac10e6b29de59dbcca8c4 100644 (file)
@@ -218,3 +218,31 @@ dm-thin-add-missing-destroy_work_on_stack.patch
 nfsd-make-sure-exp-active-before-svc_export_show.patch
 nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch
 drm-etnaviv-flush-shader-l1-cache-after-user-commandstream.patch
+itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch
+watchdog-mediatek-make-sure-system-reset-gets-assert.patch
+can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch
+can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch
+ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch
+netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch
+net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch
+can-j1939-j1939_session_new-fix-skb-reference-counti.patch
+net-ipv6-release-expired-exception-dst-cached-in-soc.patch
+dccp-fix-memory-leak-in-dccp_feat_change_recv.patch
+tipc-add-reference-counter-to-bearer.patch
+tipc-enable-creating-a-preliminary-node.patch
+tipc-add-new-aead-key-structure-for-user-api.patch
+tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch
+net-qed-allow-old-cards-not-supporting-num_images-to.patch
+igb-fix-potential-invalid-memory-access-in-igb_init_.patch
+netfilter-ipset-hold-module-reference-while-requesti.patch
+netfilter-nft_set_hash-skip-duplicated-elements-pend.patch
+xen-xenbus-reference-count-registered-modules.patch
+xenbus-backend-add-memory-pressure-handler-callback.patch
+xenbus-backend-protect-xenbus-callback-with-lock.patch
+xen-xenbus-fix-locking.patch
+xen-fix-the-issue-of-resource-not-being-properly-rel.patch
+x86-asm-reorder-early-variables.patch
+x86-asm-crypto-annotate-local-functions.patch
+crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch
+gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch
+gpio-grgpio-add-null-check-in-grgpio_probe.patch
diff --git a/queue-5.4/tipc-add-new-aead-key-structure-for-user-api.patch b/queue-5.4/tipc-add-new-aead-key-structure-for-user-api.patch
new file mode 100644 (file)
index 0000000..d288c72
--- /dev/null
@@ -0,0 +1,58 @@
+From 092b2eb7e9298c5ed31276a0977ae9c46e01c94b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2019 12:05:10 +0700
+Subject: tipc: add new AEAD key structure for user API
+
+From: Tuong Lien <tuong.t.lien@dektech.com.au>
+
+[ Upstream commit 134bdac397661a5841d9f27f508190c68b26232b ]
+
+The new structure 'tipc_aead_key' is added to the 'tipc.h' for user to
+be able to transfer a key to TIPC in kernel. Netlink will be used for
+this purpose in the later commits.
+
+Acked-by: Ying Xue <ying.xue@windreiver.com>
+Acked-by: Jon Maloy <jon.maloy@ericsson.com>
+Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6a2fa13312e5 ("tipc: Fix use-after-free of kernel socket in cleanup_bearer().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/tipc.h | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
+index 7df026ea6affa..a1b64a9167970 100644
+--- a/include/uapi/linux/tipc.h
++++ b/include/uapi/linux/tipc.h
+@@ -232,6 +232,27 @@ struct tipc_sioc_nodeid_req {
+       char node_id[TIPC_NODEID_LEN];
+ };
++/*
++ * TIPC Crypto, AEAD
++ */
++#define TIPC_AEAD_ALG_NAME            (32)
++
++struct tipc_aead_key {
++      char alg_name[TIPC_AEAD_ALG_NAME];
++      unsigned int keylen;    /* in bytes */
++      char key[];
++};
++
++#define TIPC_AEAD_KEYLEN_MIN          (16 + 4)
++#define TIPC_AEAD_KEYLEN_MAX          (32 + 4)
++#define TIPC_AEAD_KEY_SIZE_MAX                (sizeof(struct tipc_aead_key) + \
++                                                      TIPC_AEAD_KEYLEN_MAX)
++
++static inline int tipc_aead_key_size(struct tipc_aead_key *key)
++{
++      return sizeof(*key) + key->keylen;
++}
++
+ /* The macros and functions below are deprecated:
+  */
+-- 
+2.43.0
+
diff --git a/queue-5.4/tipc-add-reference-counter-to-bearer.patch b/queue-5.4/tipc-add-reference-counter-to-bearer.patch
new file mode 100644 (file)
index 0000000..bf0c0e1
--- /dev/null
@@ -0,0 +1,92 @@
+From d824d7e2a6eacc64760b7c548d4c680e37adb2c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2019 12:05:08 +0700
+Subject: tipc: add reference counter to bearer
+
+From: Tuong Lien <tuong.t.lien@dektech.com.au>
+
+[ Upstream commit 2a7ee696f7b000a970dcce0cb06fdcd0a9e6ee76 ]
+
+As a need to support the crypto asynchronous operations in the later
+commits, apart from the current RCU mechanism for bearer pointer, we
+add a 'refcnt' to the bearer object as well.
+
+So, a bearer can be hold via 'tipc_bearer_hold()' without being freed
+even though the bearer or interface can be disabled in the meanwhile.
+If that happens, the bearer will be released then when the crypto
+operation is completed and 'tipc_bearer_put()' is called.
+
+Acked-by: Ying Xue <ying.xue@windreiver.com>
+Acked-by: Jon Maloy <jon.maloy@ericsson.com>
+Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6a2fa13312e5 ("tipc: Fix use-after-free of kernel socket in cleanup_bearer().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/bearer.c | 14 +++++++++++++-
+ net/tipc/bearer.h |  3 +++
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
+index dc5c6b1e97910..fc0b787fb9286 100644
+--- a/net/tipc/bearer.c
++++ b/net/tipc/bearer.c
+@@ -334,6 +334,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+       b->net_plane = bearer_id + 'A';
+       b->priority = prio;
+       test_and_set_bit_lock(0, &b->up);
++      refcount_set(&b->refcnt, 1);
+       res = tipc_disc_create(net, b, &b->bcast_addr, &skb);
+       if (res) {
+@@ -371,6 +372,17 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b)
+       return 0;
+ }
++bool tipc_bearer_hold(struct tipc_bearer *b)
++{
++      return (b && refcount_inc_not_zero(&b->refcnt));
++}
++
++void tipc_bearer_put(struct tipc_bearer *b)
++{
++      if (b && refcount_dec_and_test(&b->refcnt))
++              kfree_rcu(b, rcu);
++}
++
+ /**
+  * bearer_disable
+  *
+@@ -389,7 +401,7 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b)
+       if (b->disc)
+               tipc_disc_delete(b->disc);
+       RCU_INIT_POINTER(tn->bearer_list[bearer_id], NULL);
+-      kfree_rcu(b, rcu);
++      tipc_bearer_put(b);
+       tipc_mon_delete(net, bearer_id);
+ }
+diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
+index ea0f3c49cbedb..faca696d422ff 100644
+--- a/net/tipc/bearer.h
++++ b/net/tipc/bearer.h
+@@ -165,6 +165,7 @@ struct tipc_bearer {
+       struct tipc_discoverer *disc;
+       char net_plane;
+       unsigned long up;
++      refcount_t refcnt;
+ };
+ struct tipc_bearer_names {
+@@ -210,6 +211,8 @@ int tipc_media_set_window(const char *name, u32 new_value);
+ int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
+ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
+                        struct nlattr *attrs[]);
++bool tipc_bearer_hold(struct tipc_bearer *b);
++void tipc_bearer_put(struct tipc_bearer *b);
+ void tipc_disable_l2_media(struct tipc_bearer *b);
+ int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
+                    struct tipc_bearer *b, struct tipc_media_addr *dest);
+-- 
+2.43.0
+
diff --git a/queue-5.4/tipc-enable-creating-a-preliminary-node.patch b/queue-5.4/tipc-enable-creating-a-preliminary-node.patch
new file mode 100644 (file)
index 0000000..265d8c6
--- /dev/null
@@ -0,0 +1,274 @@
+From a8a6606f4b66250898f08e92063b0f7c90cab33e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2019 12:05:09 +0700
+Subject: tipc: enable creating a "preliminary" node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tuong Lien <tuong.t.lien@dektech.com.au>
+
+[ Upstream commit 4cbf8ac2fe5a0846508fe02b95a5de1a90fa73f4 ]
+
+When user sets RX key for a peer not existing on the own node, a new
+node entry is needed to which the RX key will be attached. However,
+since the peer node address (& capabilities) is unknown at that moment,
+only the node-ID is provided, this commit allows the creation of a node
+with only the data that we call as “preliminary”.
+
+A preliminary node is not the object of the “tipc_node_find()” but the
+“tipc_node_find_by_id()”. Once the first message i.e. LINK_CONFIG comes
+from that peer, and is successfully decrypted by the own node, the
+actual peer node data will be properly updated and the node will
+function as usual.
+
+In addition, the node timer always starts when a node object is created
+so if a preliminary node is not used, it will be cleaned up.
+
+The later encryption functions will also use the node timer and be able
+to create a preliminary node automatically when needed.
+
+Acked-by: Ying Xue <ying.xue@windreiver.com>
+Acked-by: Jon Maloy <jon.maloy@ericsson.com>
+Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 6a2fa13312e5 ("tipc: Fix use-after-free of kernel socket in cleanup_bearer().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/node.c | 99 +++++++++++++++++++++++++++++++++++--------------
+ net/tipc/node.h |  1 +
+ 2 files changed, 73 insertions(+), 27 deletions(-)
+
+diff --git a/net/tipc/node.c b/net/tipc/node.c
+index 535a4a778640a..16de7a1b3b01f 100644
+--- a/net/tipc/node.c
++++ b/net/tipc/node.c
+@@ -89,6 +89,7 @@ struct tipc_bclink_entry {
+  * @links: array containing references to all links to node
+  * @action_flags: bit mask of different types of node actions
+  * @state: connectivity state vs peer node
++ * @preliminary: a preliminary node or not
+  * @sync_point: sequence number where synch/failover is finished
+  * @list: links to adjacent nodes in sorted list of cluster's nodes
+  * @working_links: number of working links to node (both active and standby)
+@@ -112,6 +113,7 @@ struct tipc_node {
+       int action_flags;
+       struct list_head list;
+       int state;
++      bool preliminary;
+       bool failover_sent;
+       u16 sync_point;
+       int link_cnt;
+@@ -120,6 +122,7 @@ struct tipc_node {
+       u32 signature;
+       u32 link_id;
+       u8 peer_id[16];
++      char peer_id_string[NODE_ID_STR_LEN];
+       struct list_head publ_list;
+       struct list_head conn_sks;
+       unsigned long keepalive_intv;
+@@ -245,6 +248,16 @@ u16 tipc_node_get_capabilities(struct net *net, u32 addr)
+       return caps;
+ }
++u32 tipc_node_get_addr(struct tipc_node *node)
++{
++      return (node) ? node->addr : 0;
++}
++
++char *tipc_node_get_id_str(struct tipc_node *node)
++{
++      return node->peer_id_string;
++}
++
+ static void tipc_node_kref_release(struct kref *kref)
+ {
+       struct tipc_node *n = container_of(kref, struct tipc_node, kref);
+@@ -274,7 +287,7 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) {
+-              if (node->addr != addr)
++              if (node->addr != addr || node->preliminary)
+                       continue;
+               if (!kref_get_unless_zero(&node->kref))
+                       node = NULL;
+@@ -400,17 +413,39 @@ static void tipc_node_assign_peer_net(struct tipc_node *n, u32 hash_mixes)
+ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
+                                         u8 *peer_id, u16 capabilities,
+-                                        u32 signature, u32 hash_mixes)
++                                        u32 hash_mixes, bool preliminary)
+ {
+       struct tipc_net *tn = net_generic(net, tipc_net_id);
+       struct tipc_node *n, *temp_node;
+       struct tipc_link *l;
++      unsigned long intv;
+       int bearer_id;
+       int i;
+       spin_lock_bh(&tn->node_list_lock);
+-      n = tipc_node_find(net, addr);
++      n = tipc_node_find(net, addr) ?:
++              tipc_node_find_by_id(net, peer_id);
+       if (n) {
++              if (!n->preliminary)
++                      goto update;
++              if (preliminary)
++                      goto exit;
++              /* A preliminary node becomes "real" now, refresh its data */
++              tipc_node_write_lock(n);
++              n->preliminary = false;
++              n->addr = addr;
++              hlist_del_rcu(&n->hash);
++              hlist_add_head_rcu(&n->hash,
++                                 &tn->node_htable[tipc_hashfn(addr)]);
++              list_del_rcu(&n->list);
++              list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
++                      if (n->addr < temp_node->addr)
++                              break;
++              }
++              list_add_tail_rcu(&n->list, &temp_node->list);
++              tipc_node_write_unlock_fast(n);
++
++update:
+               if (n->peer_hash_mix ^ hash_mixes)
+                       tipc_node_assign_peer_net(n, hash_mixes);
+               if (n->capabilities == capabilities)
+@@ -438,7 +473,9 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
+               pr_warn("Node creation failed, no memory\n");
+               goto exit;
+       }
++      tipc_nodeid2string(n->peer_id_string, peer_id);
+       n->addr = addr;
++      n->preliminary = preliminary;
+       memcpy(&n->peer_id, peer_id, 16);
+       n->net = net;
+       n->peer_net = NULL;
+@@ -463,22 +500,14 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
+       n->signature = INVALID_NODE_SIG;
+       n->active_links[0] = INVALID_BEARER_ID;
+       n->active_links[1] = INVALID_BEARER_ID;
+-      if (!tipc_link_bc_create(net, tipc_own_addr(net),
+-                               addr, U16_MAX,
+-                               tipc_link_window(tipc_bc_sndlink(net)),
+-                               n->capabilities,
+-                               &n->bc_entry.inputq1,
+-                               &n->bc_entry.namedq,
+-                               tipc_bc_sndlink(net),
+-                               &n->bc_entry.link)) {
+-              pr_warn("Broadcast rcv link creation failed, no memory\n");
+-              kfree(n);
+-              n = NULL;
+-              goto exit;
+-      }
++      n->bc_entry.link = NULL;
+       tipc_node_get(n);
+       timer_setup(&n->timer, tipc_node_timeout, 0);
+-      n->keepalive_intv = U32_MAX;
++      /* Start a slow timer anyway, crypto needs it */
++      n->keepalive_intv = 10000;
++      intv = jiffies + msecs_to_jiffies(n->keepalive_intv);
++      if (!mod_timer(&n->timer, intv))
++              tipc_node_get(n);
+       hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]);
+       list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
+               if (n->addr < temp_node->addr)
+@@ -996,6 +1025,8 @@ u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
+ {
+       struct tipc_net *tn = tipc_net(net);
+       struct tipc_node *n;
++      bool preliminary;
++      u32 sugg_addr;
+       /* Suggest new address if some other peer is using this one */
+       n = tipc_node_find(net, addr);
+@@ -1011,9 +1042,11 @@ u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
+       /* Suggest previously used address if peer is known */
+       n = tipc_node_find_by_id(net, id);
+       if (n) {
+-              addr = n->addr;
++              sugg_addr = n->addr;
++              preliminary = n->preliminary;
+               tipc_node_put(n);
+-              return addr;
++              if (!preliminary)
++                      return sugg_addr;
+       }
+       /* Even this node may be in conflict */
+@@ -1030,7 +1063,7 @@ void tipc_node_check_dest(struct net *net, u32 addr,
+                         bool *respond, bool *dupl_addr)
+ {
+       struct tipc_node *n;
+-      struct tipc_link *l;
++      struct tipc_link *l, *snd_l;
+       struct tipc_link_entry *le;
+       bool addr_match = false;
+       bool sign_match = false;
+@@ -1045,12 +1078,27 @@ void tipc_node_check_dest(struct net *net, u32 addr,
+       *dupl_addr = false;
+       *respond = false;
+-      n = tipc_node_create(net, addr, peer_id, capabilities, signature,
+-                           hash_mixes);
++      n = tipc_node_create(net, addr, peer_id, capabilities, hash_mixes,
++                           false);
+       if (!n)
+               return;
+       tipc_node_write_lock(n);
++      if (unlikely(!n->bc_entry.link)) {
++              snd_l = tipc_bc_sndlink(net);
++              if (!tipc_link_bc_create(net, tipc_own_addr(net),
++                                       addr, U16_MAX,
++                                       tipc_link_window(snd_l),
++                                       n->capabilities,
++                                       &n->bc_entry.inputq1,
++                                       &n->bc_entry.namedq, snd_l,
++                                       &n->bc_entry.link)) {
++                      pr_warn("Broadcast rcv link creation failed, no mem\n");
++                      tipc_node_write_unlock_fast(n);
++                      tipc_node_put(n);
++                      return;
++              }
++      }
+       le = &n->links[b->identity];
+@@ -2135,6 +2183,8 @@ int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
+       }
+       list_for_each_entry_rcu(node, &tn->node_list, list) {
++              if (node->preliminary)
++                      continue;
+               if (last_addr) {
+                       if (node->addr == last_addr)
+                               last_addr = 0;
+@@ -2654,11 +2704,6 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
+       return skb->len;
+ }
+-u32 tipc_node_get_addr(struct tipc_node *node)
+-{
+-      return (node) ? node->addr : 0;
+-}
+-
+ /**
+  * tipc_node_dump - dump TIPC node data
+  * @n: tipc node to be dumped
+diff --git a/net/tipc/node.h b/net/tipc/node.h
+index 30563c4f35d5c..1d4345ef49b44 100644
+--- a/net/tipc/node.h
++++ b/net/tipc/node.h
+@@ -72,6 +72,7 @@ enum {
+ void tipc_node_stop(struct net *net);
+ bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);
+ u32 tipc_node_get_addr(struct tipc_node *node);
++char *tipc_node_get_id_str(struct tipc_node *node);
+ u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr);
+ void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128,
+                         struct tipc_bearer *bearer,
+-- 
+2.43.0
+
diff --git a/queue-5.4/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch b/queue-5.4/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch
new file mode 100644 (file)
index 0000000..80217f6
--- /dev/null
@@ -0,0 +1,107 @@
+From 23a6a81bcd8d55695a82a8ae273064c4071d6981 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Nov 2024 14:05:12 +0900
+Subject: tipc: Fix use-after-free of kernel socket in cleanup_bearer().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 6a2fa13312e51a621f652d522d7e2df7066330b6 ]
+
+syzkaller reported a use-after-free of UDP kernel socket
+in cleanup_bearer() without repro. [0][1]
+
+When bearer_disable() calls tipc_udp_disable(), cleanup
+of the UDP kernel socket is deferred by work calling
+cleanup_bearer().
+
+tipc_net_stop() waits for such works to finish by checking
+tipc_net(net)->wq_count.  However, the work decrements the
+count too early before releasing the kernel socket,
+unblocking cleanup_net() and resulting in use-after-free.
+
+Let's move the decrement after releasing the socket in
+cleanup_bearer().
+
+[0]:
+ref_tracker: net notrefcnt@000000009b3d1faf has 1/1 users at
+     sk_alloc+0x438/0x608
+     inet_create+0x4c8/0xcb0
+     __sock_create+0x350/0x6b8
+     sock_create_kern+0x58/0x78
+     udp_sock_create4+0x68/0x398
+     udp_sock_create+0x88/0xc8
+     tipc_udp_enable+0x5e8/0x848
+     __tipc_nl_bearer_enable+0x84c/0xed8
+     tipc_nl_bearer_enable+0x38/0x60
+     genl_family_rcv_msg_doit+0x170/0x248
+     genl_rcv_msg+0x400/0x5b0
+     netlink_rcv_skb+0x1dc/0x398
+     genl_rcv+0x44/0x68
+     netlink_unicast+0x678/0x8b0
+     netlink_sendmsg+0x5e4/0x898
+     ____sys_sendmsg+0x500/0x830
+
+[1]:
+BUG: KMSAN: use-after-free in udp_hashslot include/net/udp.h:85 [inline]
+BUG: KMSAN: use-after-free in udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979
+ udp_hashslot include/net/udp.h:85 [inline]
+ udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979
+ sk_common_release+0xaf/0x3f0 net/core/sock.c:3820
+ inet_release+0x1e0/0x260 net/ipv4/af_inet.c:437
+ inet6_release+0x6f/0xd0 net/ipv6/af_inet6.c:489
+ __sock_release net/socket.c:658 [inline]
+ sock_release+0xa0/0x210 net/socket.c:686
+ cleanup_bearer+0x42d/0x4c0 net/tipc/udp_media.c:819
+ process_one_work kernel/workqueue.c:3229 [inline]
+ process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310
+ worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391
+ kthread+0x531/0x6b0 kernel/kthread.c:389
+ ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
+
+Uninit was created at:
+ slab_free_hook mm/slub.c:2269 [inline]
+ slab_free mm/slub.c:4580 [inline]
+ kmem_cache_free+0x207/0xc40 mm/slub.c:4682
+ net_free net/core/net_namespace.c:454 [inline]
+ cleanup_net+0x16f2/0x19d0 net/core/net_namespace.c:647
+ process_one_work kernel/workqueue.c:3229 [inline]
+ process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310
+ worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391
+ kthread+0x531/0x6b0 kernel/kthread.c:389
+ ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
+
+CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.12.0-rc1-00131-gf66ebf37d69c #7 91723d6f74857f70725e1583cba3cf4adc716cfa
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
+Workqueue: events cleanup_bearer
+
+Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20241127050512.28438-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/udp_media.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
+index 4db2185a32aec..696a21208b24b 100644
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -805,10 +805,10 @@ static void cleanup_bearer(struct work_struct *work)
+               kfree_rcu(rcast, rcu);
+       }
+-      atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
+       dst_cache_destroy(&ub->rcast.dst_cache);
+       udp_tunnel_sock_release(ub->ubsock);
+       synchronize_net();
++      atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
+       kfree(ub);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/watchdog-mediatek-make-sure-system-reset-gets-assert.patch b/queue-5.4/watchdog-mediatek-make-sure-system-reset-gets-assert.patch
new file mode 100644 (file)
index 0000000..f48c040
--- /dev/null
@@ -0,0 +1,48 @@
+From 79b7eeda6d32a1f139db5134640549cd8f51f20d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 10:47:51 +0000
+Subject: watchdog: mediatek: Make sure system reset gets asserted in
+ mtk_wdt_restart()
+
+From: Yassine Oudjana <y.oudjana@protonmail.com>
+
+[ Upstream commit a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 ]
+
+Clear the IRQ enable bit of WDT_MODE before asserting software reset
+in order to make TOPRGU issue a system reset signal instead of an IRQ.
+
+Fixes: a44a45536f7b ("watchdog: Add driver for Mediatek watchdog")
+Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20241106104738.195968-2-y.oudjana@protonmail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/mtk_wdt.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
+index 9c3d0033260d9..a2845c9ad3a7c 100644
+--- a/drivers/watchdog/mtk_wdt.c
++++ b/drivers/watchdog/mtk_wdt.c
+@@ -60,9 +60,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
+ {
+       struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+       void __iomem *wdt_base;
++      u32 reg;
+       wdt_base = mtk_wdt->wdt_base;
++      /* Enable reset in order to issue a system reset instead of an IRQ */
++      reg = readl(wdt_base + WDT_MODE);
++      reg &= ~WDT_MODE_IRQ_EN;
++      writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE);
++
+       while (1) {
+               writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
+               mdelay(5);
+-- 
+2.43.0
+
diff --git a/queue-5.4/x86-asm-crypto-annotate-local-functions.patch b/queue-5.4/x86-asm-crypto-annotate-local-functions.patch
new file mode 100644 (file)
index 0000000..5079d6f
--- /dev/null
@@ -0,0 +1,640 @@
+From 3f15cd401498be0e0a99c0af6f4c9e5622dcc3bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Oct 2019 13:50:46 +0200
+Subject: x86/asm/crypto: Annotate local functions
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+[ Upstream commit 74d8b90a889022e306b543ff2147a6941c99b354 ]
+
+Use the newly added SYM_FUNC_START_LOCAL to annotate beginnings of all
+functions which do not have ".globl" annotation, but their endings are
+annotated by ENDPROC. This is needed to balance ENDPROC for tools that
+generate debuginfo.
+
+These function names are not prepended with ".L" as they might appear in
+call traces and they wouldn't be visible after such change.
+
+To be symmetric, the functions' ENDPROCs are converted to the new
+SYM_FUNC_END.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: linux-arch@vger.kernel.org
+Cc: linux-crypto@vger.kernel.org
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: x86-ml <x86@kernel.org>
+Link: https://lkml.kernel.org/r/20191011115108.12392-7-jslaby@suse.cz
+Stable-dep-of: 3b2f2d22fb42 ("crypto: x86/aegis128 - access 32-bit arguments as 32-bit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/crypto/aegis128-aesni-asm.S         |  8 ++--
+ arch/x86/crypto/aesni-intel_asm.S            | 49 ++++++++------------
+ arch/x86/crypto/camellia-aesni-avx-asm_64.S  | 20 ++++----
+ arch/x86/crypto/camellia-aesni-avx2-asm_64.S | 20 ++++----
+ arch/x86/crypto/cast5-avx-x86_64-asm_64.S    |  8 ++--
+ arch/x86/crypto/cast6-avx-x86_64-asm_64.S    |  8 ++--
+ arch/x86/crypto/chacha-ssse3-x86_64.S        |  4 +-
+ arch/x86/crypto/ghash-clmulni-intel_asm.S    |  4 +-
+ arch/x86/crypto/serpent-avx-x86_64-asm_64.S  |  8 ++--
+ arch/x86/crypto/serpent-avx2-asm_64.S        |  8 ++--
+ arch/x86/crypto/twofish-avx-x86_64-asm_64.S  |  8 ++--
+ 11 files changed, 68 insertions(+), 77 deletions(-)
+
+diff --git a/arch/x86/crypto/aegis128-aesni-asm.S b/arch/x86/crypto/aegis128-aesni-asm.S
+index 4434607e366dc..b7026fdef4ff2 100644
+--- a/arch/x86/crypto/aegis128-aesni-asm.S
++++ b/arch/x86/crypto/aegis128-aesni-asm.S
+@@ -71,7 +71,7 @@
+  *   %r8
+  *   %r9
+  */
+-__load_partial:
++SYM_FUNC_START_LOCAL(__load_partial)
+       xor %r9d, %r9d
+       pxor MSG, MSG
+@@ -123,7 +123,7 @@ __load_partial:
+ .Lld_partial_8:
+       ret
+-ENDPROC(__load_partial)
++SYM_FUNC_END(__load_partial)
+ /*
+  * __store_partial: internal ABI
+@@ -137,7 +137,7 @@ ENDPROC(__load_partial)
+  *   %r9
+  *   %r10
+  */
+-__store_partial:
++SYM_FUNC_START_LOCAL(__store_partial)
+       mov LEN, %r8
+       mov DST, %r9
+@@ -181,7 +181,7 @@ __store_partial:
+ .Lst_partial_1:
+       ret
+-ENDPROC(__store_partial)
++SYM_FUNC_END(__store_partial)
+ /*
+  * void crypto_aegis128_aesni_init(void *state, const void *key, const void *iv);
+diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
+index dd954d8db629b..ef62383c6bd8f 100644
+--- a/arch/x86/crypto/aesni-intel_asm.S
++++ b/arch/x86/crypto/aesni-intel_asm.S
+@@ -1759,7 +1759,7 @@ ENDPROC(aesni_gcm_finalize)
+ .align 4
+ _key_expansion_128:
+-_key_expansion_256a:
++SYM_FUNC_START_LOCAL(_key_expansion_256a)
+       pshufd $0b11111111, %xmm1, %xmm1
+       shufps $0b00010000, %xmm0, %xmm4
+       pxor %xmm4, %xmm0
+@@ -1770,10 +1770,9 @@ _key_expansion_256a:
+       add $0x10, TKEYP
+       ret
+ ENDPROC(_key_expansion_128)
+-ENDPROC(_key_expansion_256a)
++SYM_FUNC_END(_key_expansion_256a)
+-.align 4
+-_key_expansion_192a:
++SYM_FUNC_START_LOCAL(_key_expansion_192a)
+       pshufd $0b01010101, %xmm1, %xmm1
+       shufps $0b00010000, %xmm0, %xmm4
+       pxor %xmm4, %xmm0
+@@ -1795,10 +1794,9 @@ _key_expansion_192a:
+       movaps %xmm1, 0x10(TKEYP)
+       add $0x20, TKEYP
+       ret
+-ENDPROC(_key_expansion_192a)
++SYM_FUNC_END(_key_expansion_192a)
+-.align 4
+-_key_expansion_192b:
++SYM_FUNC_START_LOCAL(_key_expansion_192b)
+       pshufd $0b01010101, %xmm1, %xmm1
+       shufps $0b00010000, %xmm0, %xmm4
+       pxor %xmm4, %xmm0
+@@ -1815,10 +1813,9 @@ _key_expansion_192b:
+       movaps %xmm0, (TKEYP)
+       add $0x10, TKEYP
+       ret
+-ENDPROC(_key_expansion_192b)
++SYM_FUNC_END(_key_expansion_192b)
+-.align 4
+-_key_expansion_256b:
++SYM_FUNC_START_LOCAL(_key_expansion_256b)
+       pshufd $0b10101010, %xmm1, %xmm1
+       shufps $0b00010000, %xmm2, %xmm4
+       pxor %xmm4, %xmm2
+@@ -1828,7 +1825,7 @@ _key_expansion_256b:
+       movaps %xmm2, (TKEYP)
+       add $0x10, TKEYP
+       ret
+-ENDPROC(_key_expansion_256b)
++SYM_FUNC_END(_key_expansion_256b)
+ /*
+  * int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+@@ -1981,8 +1978,7 @@ ENDPROC(aesni_enc)
+  *    KEY
+  *    TKEYP (T1)
+  */
+-.align 4
+-_aesni_enc1:
++SYM_FUNC_START_LOCAL(_aesni_enc1)
+       movaps (KEYP), KEY              # key
+       mov KEYP, TKEYP
+       pxor KEY, STATE         # round 0
+@@ -2025,7 +2021,7 @@ _aesni_enc1:
+       movaps 0x70(TKEYP), KEY
+       AESENCLAST KEY STATE
+       ret
+-ENDPROC(_aesni_enc1)
++SYM_FUNC_END(_aesni_enc1)
+ /*
+  * _aesni_enc4:       internal ABI
+@@ -2045,8 +2041,7 @@ ENDPROC(_aesni_enc1)
+  *    KEY
+  *    TKEYP (T1)
+  */
+-.align 4
+-_aesni_enc4:
++SYM_FUNC_START_LOCAL(_aesni_enc4)
+       movaps (KEYP), KEY              # key
+       mov KEYP, TKEYP
+       pxor KEY, STATE1                # round 0
+@@ -2134,7 +2129,7 @@ _aesni_enc4:
+       AESENCLAST KEY STATE3
+       AESENCLAST KEY STATE4
+       ret
+-ENDPROC(_aesni_enc4)
++SYM_FUNC_END(_aesni_enc4)
+ /*
+  * void aesni_dec (const void *ctx, u8 *dst, const u8 *src)
+@@ -2173,8 +2168,7 @@ ENDPROC(aesni_dec)
+  *    KEY
+  *    TKEYP (T1)
+  */
+-.align 4
+-_aesni_dec1:
++SYM_FUNC_START_LOCAL(_aesni_dec1)
+       movaps (KEYP), KEY              # key
+       mov KEYP, TKEYP
+       pxor KEY, STATE         # round 0
+@@ -2217,7 +2211,7 @@ _aesni_dec1:
+       movaps 0x70(TKEYP), KEY
+       AESDECLAST KEY STATE
+       ret
+-ENDPROC(_aesni_dec1)
++SYM_FUNC_END(_aesni_dec1)
+ /*
+  * _aesni_dec4:       internal ABI
+@@ -2237,8 +2231,7 @@ ENDPROC(_aesni_dec1)
+  *    KEY
+  *    TKEYP (T1)
+  */
+-.align 4
+-_aesni_dec4:
++SYM_FUNC_START_LOCAL(_aesni_dec4)
+       movaps (KEYP), KEY              # key
+       mov KEYP, TKEYP
+       pxor KEY, STATE1                # round 0
+@@ -2326,7 +2319,7 @@ _aesni_dec4:
+       AESDECLAST KEY STATE3
+       AESDECLAST KEY STATE4
+       ret
+-ENDPROC(_aesni_dec4)
++SYM_FUNC_END(_aesni_dec4)
+ /*
+  * void aesni_ecb_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+@@ -2604,8 +2597,7 @@ ENDPROC(aesni_cbc_dec)
+  *    INC:    == 1, in little endian
+  *    BSWAP_MASK == endian swapping mask
+  */
+-.align 4
+-_aesni_inc_init:
++SYM_FUNC_START_LOCAL(_aesni_inc_init)
+       movaps .Lbswap_mask, BSWAP_MASK
+       movaps IV, CTR
+       PSHUFB_XMM BSWAP_MASK CTR
+@@ -2613,7 +2605,7 @@ _aesni_inc_init:
+       MOVQ_R64_XMM TCTR_LOW INC
+       MOVQ_R64_XMM CTR TCTR_LOW
+       ret
+-ENDPROC(_aesni_inc_init)
++SYM_FUNC_END(_aesni_inc_init)
+ /*
+  * _aesni_inc:                internal ABI
+@@ -2630,8 +2622,7 @@ ENDPROC(_aesni_inc_init)
+  *    CTR:    == output IV, in little endian
+  *    TCTR_LOW: == lower qword of CTR
+  */
+-.align 4
+-_aesni_inc:
++SYM_FUNC_START_LOCAL(_aesni_inc)
+       paddq INC, CTR
+       add $1, TCTR_LOW
+       jnc .Linc_low
+@@ -2642,7 +2633,7 @@ _aesni_inc:
+       movaps CTR, IV
+       PSHUFB_XMM BSWAP_MASK IV
+       ret
+-ENDPROC(_aesni_inc)
++SYM_FUNC_END(_aesni_inc)
+ /*
+  * void aesni_ctr_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+index a14af6eb09cb0..f4408ca55fdb3 100644
+--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+@@ -189,20 +189,20 @@
+  * larger and would only be 0.5% faster (on sandy-bridge).
+  */
+ .align 8
+-roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
++SYM_FUNC_START_LOCAL(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+       roundsm16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                 %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15,
+                 %rcx, (%r9));
+       ret;
+-ENDPROC(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
++SYM_FUNC_END(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+ .align 8
+-roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
++SYM_FUNC_START_LOCAL(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+       roundsm16(%xmm4, %xmm5, %xmm6, %xmm7, %xmm0, %xmm1, %xmm2, %xmm3,
+                 %xmm12, %xmm13, %xmm14, %xmm15, %xmm8, %xmm9, %xmm10, %xmm11,
+                 %rax, (%r9));
+       ret;
+-ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
++SYM_FUNC_END(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ /*
+  * IN/OUT:
+@@ -722,7 +722,7 @@ ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ .text
+ .align 8
+-__camellia_enc_blk16:
++SYM_FUNC_START_LOCAL(__camellia_enc_blk16)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 256 bytes
+@@ -806,10 +806,10 @@ __camellia_enc_blk16:
+                    %xmm15, %rax, %rcx, 24);
+       jmp .Lenc_done;
+-ENDPROC(__camellia_enc_blk16)
++SYM_FUNC_END(__camellia_enc_blk16)
+ .align 8
+-__camellia_dec_blk16:
++SYM_FUNC_START_LOCAL(__camellia_dec_blk16)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 256 bytes
+@@ -891,7 +891,7 @@ __camellia_dec_blk16:
+             ((key_table + (24) * 8) + 4)(CTX));
+       jmp .Ldec_max24;
+-ENDPROC(__camellia_dec_blk16)
++SYM_FUNC_END(__camellia_dec_blk16)
+ ENTRY(camellia_ecb_enc_16way)
+       /* input:
+@@ -1120,7 +1120,7 @@ ENDPROC(camellia_ctr_16way)
+       vpxor tmp, iv, iv;
+ .align 8
+-camellia_xts_crypt_16way:
++SYM_FUNC_START_LOCAL(camellia_xts_crypt_16way)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+@@ -1254,7 +1254,7 @@ camellia_xts_crypt_16way:
+       FRAME_END
+       ret;
+-ENDPROC(camellia_xts_crypt_16way)
++SYM_FUNC_END(camellia_xts_crypt_16way)
+ ENTRY(camellia_xts_enc_16way)
+       /* input:
+diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+index 4be4c7c3ba273..72ae3edd09979 100644
+--- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+@@ -223,20 +223,20 @@
+  * larger and would only marginally faster.
+  */
+ .align 8
+-roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
++SYM_FUNC_START_LOCAL(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+       roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                 %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15,
+                 %rcx, (%r9));
+       ret;
+-ENDPROC(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
++SYM_FUNC_END(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+ .align 8
+-roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
++SYM_FUNC_START_LOCAL(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+       roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3,
+                 %ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11,
+                 %rax, (%r9));
+       ret;
+-ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
++SYM_FUNC_END(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ /*
+  * IN/OUT:
+@@ -760,7 +760,7 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ .text
+ .align 8
+-__camellia_enc_blk32:
++SYM_FUNC_START_LOCAL(__camellia_enc_blk32)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 512 bytes
+@@ -844,10 +844,10 @@ __camellia_enc_blk32:
+                    %ymm15, %rax, %rcx, 24);
+       jmp .Lenc_done;
+-ENDPROC(__camellia_enc_blk32)
++SYM_FUNC_END(__camellia_enc_blk32)
+ .align 8
+-__camellia_dec_blk32:
++SYM_FUNC_START_LOCAL(__camellia_dec_blk32)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 512 bytes
+@@ -929,7 +929,7 @@ __camellia_dec_blk32:
+             ((key_table + (24) * 8) + 4)(CTX));
+       jmp .Ldec_max24;
+-ENDPROC(__camellia_dec_blk32)
++SYM_FUNC_END(__camellia_dec_blk32)
+ ENTRY(camellia_ecb_enc_32way)
+       /* input:
+@@ -1222,7 +1222,7 @@ ENDPROC(camellia_ctr_32way)
+       vpxor tmp1, iv, iv;
+ .align 8
+-camellia_xts_crypt_32way:
++SYM_FUNC_START_LOCAL(camellia_xts_crypt_32way)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (32 blocks)
+@@ -1367,7 +1367,7 @@ camellia_xts_crypt_32way:
+       FRAME_END
+       ret;
+-ENDPROC(camellia_xts_crypt_32way)
++SYM_FUNC_END(camellia_xts_crypt_32way)
+ ENTRY(camellia_xts_enc_32way)
+       /* input:
+diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
+index dc55c3332fcc4..ef86c6a966de1 100644
+--- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
+@@ -209,7 +209,7 @@
+ .text
+ .align 16
+-__cast5_enc_blk16:
++SYM_FUNC_START_LOCAL(__cast5_enc_blk16)
+       /* input:
+        *      %rdi: ctx
+        *      RL1: blocks 1 and 2
+@@ -280,10 +280,10 @@ __cast5_enc_blk16:
+       outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
+       ret;
+-ENDPROC(__cast5_enc_blk16)
++SYM_FUNC_END(__cast5_enc_blk16)
+ .align 16
+-__cast5_dec_blk16:
++SYM_FUNC_START_LOCAL(__cast5_dec_blk16)
+       /* input:
+        *      %rdi: ctx
+        *      RL1: encrypted blocks 1 and 2
+@@ -357,7 +357,7 @@ __cast5_dec_blk16:
+ .L__skip_dec:
+       vpsrldq $4, RKR, RKR;
+       jmp .L__dec_tail;
+-ENDPROC(__cast5_dec_blk16)
++SYM_FUNC_END(__cast5_dec_blk16)
+ ENTRY(cast5_ecb_enc_16way)
+       /* input:
+diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
+index 4f0a7cdb94d9d..b080a7454e70e 100644
+--- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
+@@ -247,7 +247,7 @@
+ .text
+ .align 8
+-__cast6_enc_blk8:
++SYM_FUNC_START_LOCAL(__cast6_enc_blk8)
+       /* input:
+        *      %rdi: ctx
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks
+@@ -292,10 +292,10 @@ __cast6_enc_blk8:
+       outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+       ret;
+-ENDPROC(__cast6_enc_blk8)
++SYM_FUNC_END(__cast6_enc_blk8)
+ .align 8
+-__cast6_dec_blk8:
++SYM_FUNC_START_LOCAL(__cast6_dec_blk8)
+       /* input:
+        *      %rdi: ctx
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks
+@@ -339,7 +339,7 @@ __cast6_dec_blk8:
+       outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+       ret;
+-ENDPROC(__cast6_dec_blk8)
++SYM_FUNC_END(__cast6_dec_blk8)
+ ENTRY(cast6_ecb_enc_8way)
+       /* input:
+diff --git a/arch/x86/crypto/chacha-ssse3-x86_64.S b/arch/x86/crypto/chacha-ssse3-x86_64.S
+index 2d86c7d6dc88c..361d2bfc253cb 100644
+--- a/arch/x86/crypto/chacha-ssse3-x86_64.S
++++ b/arch/x86/crypto/chacha-ssse3-x86_64.S
+@@ -33,7 +33,7 @@ CTRINC:      .octa 0x00000003000000020000000100000000
+  *
+  * Clobbers: %r8d, %xmm4-%xmm7
+  */
+-chacha_permute:
++SYM_FUNC_START_LOCAL(chacha_permute)
+       movdqa          ROT8(%rip),%xmm4
+       movdqa          ROT16(%rip),%xmm5
+@@ -109,7 +109,7 @@ chacha_permute:
+       jnz             .Ldoubleround
+       ret
+-ENDPROC(chacha_permute)
++SYM_FUNC_END(chacha_permute)
+ ENTRY(chacha_block_xor_ssse3)
+       # %rdi: Input state matrix, s
+diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+index 5d53effe8abee..e81da25a33caf 100644
+--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S
++++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+@@ -44,7 +44,7 @@
+  *    T2
+  *    T3
+  */
+-__clmul_gf128mul_ble:
++SYM_FUNC_START_LOCAL(__clmul_gf128mul_ble)
+       movaps DATA, T1
+       pshufd $0b01001110, DATA, T2
+       pshufd $0b01001110, SHASH, T3
+@@ -87,7 +87,7 @@ __clmul_gf128mul_ble:
+       pxor T2, T1
+       pxor T1, DATA
+       ret
+-ENDPROC(__clmul_gf128mul_ble)
++SYM_FUNC_END(__clmul_gf128mul_ble)
+ /* void clmul_ghash_mul(char *dst, const u128 *shash) */
+ ENTRY(clmul_ghash_mul)
+diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
+index ddc51dbba3af9..a098aa0157840 100644
+--- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
+@@ -555,7 +555,7 @@
+       transpose_4x4(x0, x1, x2, x3, t0, t1, t2)
+ .align 8
+-__serpent_enc_blk8_avx:
++SYM_FUNC_START_LOCAL(__serpent_enc_blk8_avx)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks
+@@ -606,10 +606,10 @@ __serpent_enc_blk8_avx:
+       write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+       ret;
+-ENDPROC(__serpent_enc_blk8_avx)
++SYM_FUNC_END(__serpent_enc_blk8_avx)
+ .align 8
+-__serpent_dec_blk8_avx:
++SYM_FUNC_START_LOCAL(__serpent_dec_blk8_avx)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks
+@@ -660,7 +660,7 @@ __serpent_dec_blk8_avx:
+       write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+       ret;
+-ENDPROC(__serpent_dec_blk8_avx)
++SYM_FUNC_END(__serpent_dec_blk8_avx)
+ ENTRY(serpent_ecb_enc_8way_avx)
+       /* input:
+diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S b/arch/x86/crypto/serpent-avx2-asm_64.S
+index 37bc1d48106c4..6149ba80b4d16 100644
+--- a/arch/x86/crypto/serpent-avx2-asm_64.S
++++ b/arch/x86/crypto/serpent-avx2-asm_64.S
+@@ -561,7 +561,7 @@
+       transpose_4x4(x0, x1, x2, x3, t0, t1, t2)
+ .align 8
+-__serpent_enc_blk16:
++SYM_FUNC_START_LOCAL(__serpent_enc_blk16)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: plaintext
+@@ -612,10 +612,10 @@ __serpent_enc_blk16:
+       write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+       ret;
+-ENDPROC(__serpent_enc_blk16)
++SYM_FUNC_END(__serpent_enc_blk16)
+ .align 8
+-__serpent_dec_blk16:
++SYM_FUNC_START_LOCAL(__serpent_dec_blk16)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: ciphertext
+@@ -666,7 +666,7 @@ __serpent_dec_blk16:
+       write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+       ret;
+-ENDPROC(__serpent_dec_blk16)
++SYM_FUNC_END(__serpent_dec_blk16)
+ ENTRY(serpent_ecb_enc_16way)
+       /* input:
+diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+index 698b8f2a56e28..588f0a2f63ab2 100644
+--- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+@@ -234,7 +234,7 @@
+       vpxor           x3, wkey, x3;
+ .align 8
+-__twofish_enc_blk8:
++SYM_FUNC_START_LOCAL(__twofish_enc_blk8)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks
+@@ -273,10 +273,10 @@ __twofish_enc_blk8:
+       outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2);
+       ret;
+-ENDPROC(__twofish_enc_blk8)
++SYM_FUNC_END(__twofish_enc_blk8)
+ .align 8
+-__twofish_dec_blk8:
++SYM_FUNC_START_LOCAL(__twofish_dec_blk8)
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2: encrypted blocks
+@@ -313,7 +313,7 @@ __twofish_dec_blk8:
+       outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2);
+       ret;
+-ENDPROC(__twofish_dec_blk8)
++SYM_FUNC_END(__twofish_dec_blk8)
+ ENTRY(twofish_ecb_enc_8way)
+       /* input:
+-- 
+2.43.0
+
diff --git a/queue-5.4/x86-asm-reorder-early-variables.patch b/queue-5.4/x86-asm-reorder-early-variables.patch
new file mode 100644 (file)
index 0000000..d48dd6a
--- /dev/null
@@ -0,0 +1,109 @@
+From 412ac67de3c22418683b90fb02c0926a1789278c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2019 11:52:37 +0200
+Subject: x86/asm: Reorder early variables
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+[ Upstream commit 1a8770b746bd05ef68217989cd723b2c24d2208d ]
+
+Moving early_recursion_flag (4 bytes) after early_level4_pgt (4k) and
+early_dynamic_pgts (256k) saves 4k which are used for alignment of
+early_level4_pgt after early_recursion_flag.
+
+The real improvement is merely on the source code side. Previously it
+was:
+* __INITDATA + .balign
+* early_recursion_flag variable
+* a ton of CPP MACROS
+* __INITDATA (again)
+* early_top_pgt and early_recursion_flag variables
+* .data
+
+Now, it is a bit simpler:
+* a ton of CPP MACROS
+* __INITDATA + .balign
+* early_top_pgt and early_recursion_flag variables
+* early_recursion_flag variable
+* .data
+
+On the binary level the change looks like this:
+Before:
+ (sections)
+  12 .init.data    00042000  0000000000000000  0000000000000000 00008000  2**12
+ (symbols)
+  000000       4 OBJECT  GLOBAL DEFAULT   22 early_recursion_flag
+  001000    4096 OBJECT  GLOBAL DEFAULT   22 early_top_pgt
+  002000 0x40000 OBJECT  GLOBAL DEFAULT   22 early_dynamic_pgts
+
+After:
+ (sections)
+  12 .init.data    00041004  0000000000000000  0000000000000000 00008000  2**12
+ (symbols)
+  000000    4096 OBJECT  GLOBAL DEFAULT   22 early_top_pgt
+  001000 0x40000 OBJECT  GLOBAL DEFAULT   22 early_dynamic_pgts
+  041000       4 OBJECT  GLOBAL DEFAULT   22 early_recursion_flag
+
+So the resulting vmlinux is smaller by 4k with my toolchain as many
+other variables can be placed after early_recursion_flag to fill the
+rest of the page. Note that this is only .init data, so it is freed
+right after being booted anyway. Savings on-disk are none -- compression
+of zeros is easy, so the size of bzImage is the same pre and post the
+change.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: x86-ml <x86@kernel.org>
+Link: https://lkml.kernel.org/r/20191003095238.29831-1-jslaby@suse.cz
+Stable-dep-of: 3b2f2d22fb42 ("crypto: x86/aegis128 - access 32-bit arguments as 32-bit")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/head_64.S | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
+index f3d3e9646a99b..f00d7c0c1c86b 100644
+--- a/arch/x86/kernel/head_64.S
++++ b/arch/x86/kernel/head_64.S
+@@ -335,12 +335,6 @@ early_idt_handler_common:
+       jmp restore_regs_and_return_to_kernel
+ END(early_idt_handler_common)
+-      __INITDATA
+-
+-      .balign 4
+-GLOBAL(early_recursion_flag)
+-      .long 0
+-
+ #define NEXT_PAGE(name) \
+       .balign PAGE_SIZE; \
+ GLOBAL(name)
+@@ -375,6 +369,8 @@ GLOBAL(name)
+       .endr
+       __INITDATA
++      .balign 4
++
+ NEXT_PGD_PAGE(early_top_pgt)
+       .fill   512,8,0
+       .fill   PTI_USER_PGD_FILL,8,0
+@@ -382,6 +378,9 @@ NEXT_PGD_PAGE(early_top_pgt)
+ NEXT_PAGE(early_dynamic_pgts)
+       .fill   512*EARLY_DYNAMIC_PAGE_TABLES,8,0
++GLOBAL(early_recursion_flag)
++      .long 0
++
+       .data
+ #if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH)
+-- 
+2.43.0
+
diff --git a/queue-5.4/xen-fix-the-issue-of-resource-not-being-properly-rel.patch b/queue-5.4/xen-fix-the-issue-of-resource-not-being-properly-rel.patch
new file mode 100644 (file)
index 0000000..97dcab4
--- /dev/null
@@ -0,0 +1,68 @@
+From 82db2647beb7e011a6c9b0e99e0ae665142e1ea6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 21:09:19 +0800
+Subject: xen: Fix the issue of resource not being properly released in
+ xenbus_dev_probe()
+
+From: Qiu-ji Chen <chenqiuji666@gmail.com>
+
+[ Upstream commit afc545da381ba0c651b2658966ac737032676f01 ]
+
+This patch fixes an issue in the function xenbus_dev_probe(). In the
+xenbus_dev_probe() function, within the if (err) branch at line 313, the
+program incorrectly returns err directly without releasing the resources
+allocated by err = drv->probe(dev, id). As the return value is non-zero,
+the upper layers assume the processing logic has failed. However, the probe
+operation was performed earlier without a corresponding remove operation.
+Since the probe actually allocates resources, failing to perform the remove
+operation could lead to problems.
+
+To fix this issue, we followed the resource release logic of the
+xenbus_dev_remove() function by adding a new block fail_remove before the
+fail_put block. After entering the branch if (err) at line 313, the
+function will use a goto statement to jump to the fail_remove block,
+ensuring that the previously acquired resources are correctly released,
+thus preventing the reference count leak.
+
+This bug was identified by an experimental static analysis tool developed
+by our team. The tool specializes in analyzing reference count operations
+and detecting potential issues where resources are not properly managed.
+In this case, the tool flagged the missing release operation as a
+potential problem, which led to the development of this patch.
+
+Fixes: 4bac07c993d0 ("xen: add the Xenbus sysfs and virtual device hotplug driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Qiu-ji Chen <chenqiuji666@gmail.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Message-ID: <20241105130919.4621-1-chenqiuji666@gmail.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xenbus/xenbus_probe.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index b88512d92ef52..fd686b962727a 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -250,10 +250,16 @@ int xenbus_dev_probe(struct device *_dev)
+       if (err) {
+               dev_warn(&dev->dev, "watch_otherend on %s failed.\n",
+                      dev->nodename);
+-              return err;
++              goto fail_remove;
+       }
+       return 0;
++fail_remove:
++      if (drv->remove) {
++              down(&dev->reclaim_sem);
++              drv->remove(dev);
++              up(&dev->reclaim_sem);
++      }
+ fail_put:
+       module_put(drv->driver.owner);
+ fail:
+-- 
+2.43.0
+
diff --git a/queue-5.4/xen-xenbus-fix-locking.patch b/queue-5.4/xen-xenbus-fix-locking.patch
new file mode 100644 (file)
index 0000000..0f77cc7
--- /dev/null
@@ -0,0 +1,114 @@
+From c510ecc5f36c32b69584a25abf78ffeec09ed101 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2020 11:03:23 +0100
+Subject: xen/xenbus: fix locking
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 2f69a110e7bba3ec6bc089a2f736ca0941d887ed ]
+
+Commit 060eabe8fbe726 ("xenbus/backend: Protect xenbus callback with
+lock") introduced a bug by holding a lock while calling a function
+which might schedule.
+
+Fix that by using a semaphore instead.
+
+Fixes: 060eabe8fbe726 ("xenbus/backend: Protect xenbus callback with lock")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20200305100323.16736-1-jgross@suse.com
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xenbus/xenbus_probe.c         | 10 +++++-----
+ drivers/xen/xenbus/xenbus_probe_backend.c |  5 +++--
+ include/xen/xenbus.h                      |  3 ++-
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 1ad5bc9dd6cc4..b88512d92ef52 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -240,9 +240,9 @@ int xenbus_dev_probe(struct device *_dev)
+               goto fail;
+       }
+-      spin_lock(&dev->reclaim_lock);
++      down(&dev->reclaim_sem);
+       err = drv->probe(dev, id);
+-      spin_unlock(&dev->reclaim_lock);
++      up(&dev->reclaim_sem);
+       if (err)
+               goto fail_put;
+@@ -273,9 +273,9 @@ int xenbus_dev_remove(struct device *_dev)
+       free_otherend_watch(dev);
+       if (drv->remove) {
+-              spin_lock(&dev->reclaim_lock);
++              down(&dev->reclaim_sem);
+               drv->remove(dev);
+-              spin_unlock(&dev->reclaim_lock);
++              up(&dev->reclaim_sem);
+       }
+       module_put(drv->driver.owner);
+@@ -489,7 +489,7 @@ int xenbus_probe_node(struct xen_bus_type *bus,
+               goto fail;
+       dev_set_name(&xendev->dev, "%s", devname);
+-      spin_lock_init(&xendev->reclaim_lock);
++      sema_init(&xendev->reclaim_sem, 1);
+       /* Register with generic device framework. */
+       err = device_register(&xendev->dev);
+diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
+index 54aefbbbbff9e..8c76b94f0512d 100644
+--- a/drivers/xen/xenbus/xenbus_probe_backend.c
++++ b/drivers/xen/xenbus/xenbus_probe_backend.c
+@@ -45,6 +45,7 @@
+ #include <linux/mm.h>
+ #include <linux/notifier.h>
+ #include <linux/export.h>
++#include <linux/semaphore.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -265,10 +266,10 @@ static int backend_reclaim_memory(struct device *dev, void *data)
+       drv = to_xenbus_driver(dev->driver);
+       if (drv && drv->reclaim_memory) {
+               xdev = to_xenbus_device(dev);
+-              if (!spin_trylock(&xdev->reclaim_lock))
++              if (down_trylock(&xdev->reclaim_sem))
+                       return 0;
+               drv->reclaim_memory(xdev);
+-              spin_unlock(&xdev->reclaim_lock);
++              up(&xdev->reclaim_sem);
+       }
+       return 0;
+ }
+diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
+index 0d166dfe48334..372c7c69cdf6e 100644
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -42,6 +42,7 @@
+ #include <linux/completion.h>
+ #include <linux/init.h>
+ #include <linux/slab.h>
++#include <linux/semaphore.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/grant_table.h>
+ #include <xen/interface/io/xenbus.h>
+@@ -85,7 +86,7 @@ struct xenbus_device {
+       enum xenbus_state state;
+       struct completion down;
+       struct work_struct work;
+-      spinlock_t reclaim_lock;
++      struct semaphore reclaim_sem;
+ };
+ static inline struct xenbus_device *to_xenbus_device(struct device *dev)
+-- 
+2.43.0
+
diff --git a/queue-5.4/xen-xenbus-reference-count-registered-modules.patch b/queue-5.4/xen-xenbus-reference-count-registered-modules.patch
new file mode 100644 (file)
index 0000000..8420fbb
--- /dev/null
@@ -0,0 +1,69 @@
+From 7bd8b2a692c2f6799ae7a98e0ccbb48eaf433922 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2019 11:41:16 +0000
+Subject: xen/xenbus: reference count registered modules
+
+From: Paul Durrant <pdurrant@amazon.com>
+
+[ Upstream commit 196748a276b4dee01177e6b7abcda27cd759de83 ]
+
+To prevent a PV driver module being removed whilst attached to its other
+end, and hence xenbus calling into potentially invalid text, take a
+reference on the module before calling the probe() method (dropping it if
+unsuccessful) and drop the reference after returning from the remove()
+method.
+
+Suggested-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Paul Durrant <pdurrant@amazon.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xenbus/xenbus_probe.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index b911a91bce6b7..9215099caad61 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -233,9 +233,16 @@ int xenbus_dev_probe(struct device *_dev)
+               return err;
+       }
++      if (!try_module_get(drv->driver.owner)) {
++              dev_warn(&dev->dev, "failed to acquire module reference on '%s'\n",
++                       drv->driver.name);
++              err = -ESRCH;
++              goto fail;
++      }
++
+       err = drv->probe(dev, id);
+       if (err)
+-              goto fail;
++              goto fail_put;
+       err = watch_otherend(dev);
+       if (err) {
+@@ -245,6 +252,8 @@ int xenbus_dev_probe(struct device *_dev)
+       }
+       return 0;
++fail_put:
++      module_put(drv->driver.owner);
+ fail:
+       xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
+       xenbus_switch_state(dev, XenbusStateClosed);
+@@ -264,6 +273,8 @@ int xenbus_dev_remove(struct device *_dev)
+       if (drv->remove)
+               drv->remove(dev);
++      module_put(drv->driver.owner);
++
+       free_otherend_details(dev);
+       xenbus_switch_state(dev, XenbusStateClosed);
+-- 
+2.43.0
+
diff --git a/queue-5.4/xenbus-backend-add-memory-pressure-handler-callback.patch b/queue-5.4/xenbus-backend-add-memory-pressure-handler-callback.patch
new file mode 100644 (file)
index 0000000..587f18f
--- /dev/null
@@ -0,0 +1,107 @@
+From 235178db56f95bc80686936a50f1b0ae99cd9e55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2020 09:18:08 +0100
+Subject: xenbus/backend: Add memory pressure handler callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: SeongJae Park <sjpark@amazon.de>
+
+[ Upstream commit 8a105678fb3ec4763352db84745968bf2cb4aa65 ]
+
+Granting pages consumes backend system memory.  In systems configured
+with insufficient spare memory for those pages, it can cause a memory
+pressure situation.  However, finding the optimal amount of the spare
+memory is challenging for large systems having dynamic resource
+utilization patterns.  Also, such a static configuration might lack
+flexibility.
+
+To mitigate such problems, this commit adds a memory reclaim callback to
+'xenbus_driver'.  If a memory pressure is detected, 'xenbus' requests
+every backend driver to volunarily release its memory.
+
+Note that it would be able to improve the callback facility for more
+sophisticated handlings of general pressures.  For example, it would be
+possible to monitor the memory consumption of each device and issue the
+release requests to only devices which causing the pressure.  Also, the
+callback could be extended to handle not only memory, but general
+resources.  Nevertheless, this version of the implementation defers such
+sophisticated goals as a future work.
+
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xenbus/xenbus_probe_backend.c | 32 +++++++++++++++++++++++
+ include/xen/xenbus.h                      |  1 +
+ 2 files changed, 33 insertions(+)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
+index 4bb603051d5b6..386a1348694a7 100644
+--- a/drivers/xen/xenbus/xenbus_probe_backend.c
++++ b/drivers/xen/xenbus/xenbus_probe_backend.c
+@@ -255,6 +255,35 @@ static int backend_probe_and_watch(struct notifier_block *notifier,
+       return NOTIFY_DONE;
+ }
++static int backend_reclaim_memory(struct device *dev, void *data)
++{
++      const struct xenbus_driver *drv;
++
++      if (!dev->driver)
++              return 0;
++      drv = to_xenbus_driver(dev->driver);
++      if (drv && drv->reclaim_memory)
++              drv->reclaim_memory(to_xenbus_device(dev));
++      return 0;
++}
++
++/*
++ * Returns 0 always because we are using shrinker to only detect memory
++ * pressure.
++ */
++static unsigned long backend_shrink_memory_count(struct shrinker *shrinker,
++                              struct shrink_control *sc)
++{
++      bus_for_each_dev(&xenbus_backend.bus, NULL, NULL,
++                      backend_reclaim_memory);
++      return 0;
++}
++
++static struct shrinker backend_memory_shrinker = {
++      .count_objects = backend_shrink_memory_count,
++      .seeks = DEFAULT_SEEKS,
++};
++
+ static int __init xenbus_probe_backend_init(void)
+ {
+       static struct notifier_block xenstore_notifier = {
+@@ -271,6 +300,9 @@ static int __init xenbus_probe_backend_init(void)
+       register_xenstore_notifier(&xenstore_notifier);
++      if (register_shrinker(&backend_memory_shrinker))
++              pr_warn("shrinker registration failed\n");
++
+       return 0;
+ }
+ subsys_initcall(xenbus_probe_backend_init);
+diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
+index 14d47ed4114fd..cf37b2d93560f 100644
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -113,6 +113,7 @@ struct xenbus_driver {
+       struct device_driver driver;
+       int (*read_otherend_details)(struct xenbus_device *dev);
+       int (*is_ready)(struct xenbus_device *dev);
++      void (*reclaim_memory)(struct xenbus_device *dev);
+ };
+ static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
+-- 
+2.43.0
+
diff --git a/queue-5.4/xenbus-backend-protect-xenbus-callback-with-lock.patch b/queue-5.4/xenbus-backend-protect-xenbus-callback-with-lock.patch
new file mode 100644 (file)
index 0000000..bd7b956
--- /dev/null
@@ -0,0 +1,101 @@
+From 687767a63056cbd1cadbd9daba0952e79bc78612 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jan 2020 09:18:09 +0100
+Subject: xenbus/backend: Protect xenbus callback with lock
+
+From: SeongJae Park <sjpark@amazon.de>
+
+[ Upstream commit 060eabe8fbe726aca341b518366da4d79e338100 ]
+
+A driver's 'reclaim_memory' callback can race with 'probe' or 'remove'
+because it will be called whenever memory pressure is detected.  To
+avoid such race, this commit embeds a spinlock in each 'xenbus_device'
+and make 'xenbus' to hold the lock while the corresponded callbacks are
+running.
+
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xenbus/xenbus_probe.c         |  8 +++++++-
+ drivers/xen/xenbus/xenbus_probe_backend.c | 10 ++++++++--
+ include/xen/xenbus.h                      |  1 +
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 9215099caad61..1ad5bc9dd6cc4 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -240,7 +240,9 @@ int xenbus_dev_probe(struct device *_dev)
+               goto fail;
+       }
++      spin_lock(&dev->reclaim_lock);
+       err = drv->probe(dev, id);
++      spin_unlock(&dev->reclaim_lock);
+       if (err)
+               goto fail_put;
+@@ -270,8 +272,11 @@ int xenbus_dev_remove(struct device *_dev)
+       free_otherend_watch(dev);
+-      if (drv->remove)
++      if (drv->remove) {
++              spin_lock(&dev->reclaim_lock);
+               drv->remove(dev);
++              spin_unlock(&dev->reclaim_lock);
++      }
+       module_put(drv->driver.owner);
+@@ -484,6 +489,7 @@ int xenbus_probe_node(struct xen_bus_type *bus,
+               goto fail;
+       dev_set_name(&xendev->dev, "%s", devname);
++      spin_lock_init(&xendev->reclaim_lock);
+       /* Register with generic device framework. */
+       err = device_register(&xendev->dev);
+diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
+index 386a1348694a7..54aefbbbbff9e 100644
+--- a/drivers/xen/xenbus/xenbus_probe_backend.c
++++ b/drivers/xen/xenbus/xenbus_probe_backend.c
+@@ -258,12 +258,18 @@ static int backend_probe_and_watch(struct notifier_block *notifier,
+ static int backend_reclaim_memory(struct device *dev, void *data)
+ {
+       const struct xenbus_driver *drv;
++      struct xenbus_device *xdev;
+       if (!dev->driver)
+               return 0;
+       drv = to_xenbus_driver(dev->driver);
+-      if (drv && drv->reclaim_memory)
+-              drv->reclaim_memory(to_xenbus_device(dev));
++      if (drv && drv->reclaim_memory) {
++              xdev = to_xenbus_device(dev);
++              if (!spin_trylock(&xdev->reclaim_lock))
++                      return 0;
++              drv->reclaim_memory(xdev);
++              spin_unlock(&xdev->reclaim_lock);
++      }
+       return 0;
+ }
+diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
+index cf37b2d93560f..0d166dfe48334 100644
+--- a/include/xen/xenbus.h
++++ b/include/xen/xenbus.h
+@@ -85,6 +85,7 @@ struct xenbus_device {
+       enum xenbus_state state;
+       struct completion down;
+       struct work_struct work;
++      spinlock_t reclaim_lock;
+ };
+ static inline struct xenbus_device *to_xenbus_device(struct device *dev)
+-- 
+2.43.0
+