--- /dev/null
+From d85cf67a339685beae1d0aee27b7f61da95455be Mon Sep 17 00:00:00 2001
+From: Doug Berger <opendmb@gmail.com>
+Date: Thu, 25 Apr 2024 15:27:19 -0700
+Subject: net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access
+
+From: Doug Berger <opendmb@gmail.com>
+
+commit d85cf67a339685beae1d0aee27b7f61da95455be upstream.
+
+The EXT_RGMII_OOB_CTRL register can be written from different
+contexts. It is predominantly written from the adjust_link
+handler which is synchronized by the phydev->lock, but can
+also be written from a different context when configuring the
+mii in bcmgenet_mii_config().
+
+The chances of contention are quite low, but it is conceivable
+that adjust_link could occur during resume when WoL is enabled
+so use the phydev->lock synchronizer in bcmgenet_mii_config()
+to be sure.
+
+Fixes: afe3f907d20f ("net: bcmgenet: power on MII block for all MII modes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+@@ -264,6 +264,7 @@ int bcmgenet_mii_config(struct net_devic
+ * block for the interface to work
+ */
+ if (priv->ext_phy) {
++ mutex_lock(&phydev->lock);
+ reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
+ reg &= ~ID_MODE_DIS;
+ reg |= id_mode_dis;
+@@ -272,6 +273,7 @@ int bcmgenet_mii_config(struct net_devic
+ else
+ reg |= RGMII_MODE_EN;
+ bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
++ mutex_unlock(&phydev->lock);
+ }
+
+ if (init)
--- /dev/null
+From 0d5e2a82232605b337972fb2c7d0cbc46898aca1 Mon Sep 17 00:00:00 2001
+From: Doug Berger <opendmb@gmail.com>
+Date: Thu, 25 Apr 2024 15:27:21 -0700
+Subject: net: bcmgenet: synchronize UMAC_CMD access
+
+From: Doug Berger <opendmb@gmail.com>
+
+commit 0d5e2a82232605b337972fb2c7d0cbc46898aca1 upstream.
+
+The UMAC_CMD register is written from different execution
+contexts and has insufficient synchronization protections to
+prevent possible corruption. Of particular concern are the
+acceses from the phy_device delayed work context used by the
+adjust_link call and the BH context that may be used by the
+ndo_set_rx_mode call.
+
+A spinlock is added to the driver to protect contended register
+accesses (i.e. reg_lock) and it is used to synchronize accesses
+to UMAC_CMD.
+
+Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
+Cc: stable@vger.kernel.org
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c | 12 +++++++++++-
+ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 ++
+ drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++++
+ drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++
+ 4 files changed, 21 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -2424,14 +2424,18 @@ static void umac_enable_set(struct bcmge
+ {
+ u32 reg;
+
++ spin_lock_bh(&priv->reg_lock);
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+- if (reg & CMD_SW_RESET)
++ if (reg & CMD_SW_RESET) {
++ spin_unlock_bh(&priv->reg_lock);
+ return;
++ }
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock_bh(&priv->reg_lock);
+
+ /* UniMAC stops on a packet boundary, wait for a full-size packet
+ * to be processed
+@@ -2447,8 +2451,10 @@ static void reset_umac(struct bcmgenet_p
+ udelay(10);
+
+ /* issue soft reset and disable MAC while updating its registers */
++ spin_lock_bh(&priv->reg_lock);
+ bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
+ udelay(2);
++ spin_unlock_bh(&priv->reg_lock);
+ }
+
+ static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
+@@ -3576,16 +3582,19 @@ static void bcmgenet_set_rx_mode(struct
+ * 3. The number of filters needed exceeds the number filters
+ * supported by the hardware.
+ */
++ spin_lock(&priv->reg_lock);
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
+ (nfilter > MAX_MDF_FILTER)) {
+ reg |= CMD_PROMISC;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock(&priv->reg_lock);
+ bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
+ return;
+ } else {
+ reg &= ~CMD_PROMISC;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock(&priv->reg_lock);
+ }
+
+ /* update MDF filter */
+@@ -3979,6 +3988,7 @@ static int bcmgenet_probe(struct platfor
+ goto err;
+ }
+
++ spin_lock_init(&priv->reg_lock);
+ spin_lock_init(&priv->lock);
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+@@ -572,6 +572,8 @@ struct bcmgenet_rxnfc_rule {
+ /* device context */
+ struct bcmgenet_priv {
+ void __iomem *base;
++ /* reg_lock: lock to serialize access to shared registers */
++ spinlock_t reg_lock;
+ enum bcmgenet_version version;
+ struct net_device *dev;
+
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+@@ -133,6 +133,7 @@ int bcmgenet_wol_power_down_cfg(struct b
+ }
+
+ /* Can't suspend with WoL if MAC is still in reset */
++ spin_lock_bh(&priv->reg_lock);
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ if (reg & CMD_SW_RESET)
+ reg &= ~CMD_SW_RESET;
+@@ -140,6 +141,7 @@ int bcmgenet_wol_power_down_cfg(struct b
+ /* disable RX */
+ reg &= ~CMD_RX_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock_bh(&priv->reg_lock);
+ mdelay(10);
+
+ if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
+@@ -185,6 +187,7 @@ int bcmgenet_wol_power_down_cfg(struct b
+ }
+
+ /* Enable CRC forward */
++ spin_lock_bh(&priv->reg_lock);
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ priv->crc_fwd_en = 1;
+ reg |= CMD_CRC_FWD;
+@@ -192,6 +195,7 @@ int bcmgenet_wol_power_down_cfg(struct b
+ /* Receiver must be enabled for WOL MP detection */
+ reg |= CMD_RX_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock_bh(&priv->reg_lock);
+
+ reg = UMAC_IRQ_MPD_R;
+ if (hfb_enable)
+@@ -238,7 +242,9 @@ void bcmgenet_wol_power_up_cfg(struct bc
+ }
+
+ /* Disable CRC Forward */
++ spin_lock_bh(&priv->reg_lock);
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_CRC_FWD;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock_bh(&priv->reg_lock);
+ }
+--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
+@@ -91,6 +91,7 @@ void bcmgenet_mii_setup(struct net_devic
+ reg |= RGMII_LINK;
+ bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
+
++ spin_lock_bh(&priv->reg_lock);
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
+ CMD_HD_EN |
+@@ -103,6 +104,7 @@ void bcmgenet_mii_setup(struct net_devic
+ reg |= CMD_TX_EN | CMD_RX_EN;
+ }
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
++ spin_unlock_bh(&priv->reg_lock);
+
+ priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
+ bcmgenet_eee_enable_set(dev,
--- /dev/null
+From c57ca512f3b68ddcd62bda9cc24a8f5584ab01b1 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Tue, 6 Feb 2024 17:18:18 -0800
+Subject: net: tls: factor out tls_*crypt_async_wait()
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+commit c57ca512f3b68ddcd62bda9cc24a8f5584ab01b1 upstream.
+
+Factor out waiting for async encrypt and decrypt to finish.
+There are already multiple copies and a subsequent fix will
+need more. No functional changes.
+
+Note that crypto_wait_req() returns wait->err
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: aec7961916f3 ("tls: fix race between async notify and socket close")
+[v5.15: removed changes in tls_sw_splice_eof and adjusted waiting factor out for
+async descrypt in tls_sw_recvmsg]
+Cc: <stable@vger.kernel.org> # 5.15
+Signed-off-by: Shaoying Xu <shaoyi@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tls/tls_sw.c | 90 +++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 49 insertions(+), 41 deletions(-)
+
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -226,6 +226,20 @@ static void tls_decrypt_done(struct cryp
+ spin_unlock_bh(&ctx->decrypt_compl_lock);
+ }
+
++static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx)
++{
++ int pending;
++
++ spin_lock_bh(&ctx->decrypt_compl_lock);
++ reinit_completion(&ctx->async_wait.completion);
++ pending = atomic_read(&ctx->decrypt_pending);
++ spin_unlock_bh(&ctx->decrypt_compl_lock);
++ if (pending)
++ crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
++
++ return ctx->async_wait.err;
++}
++
+ static int tls_do_decryption(struct sock *sk,
+ struct sk_buff *skb,
+ struct scatterlist *sgin,
+@@ -496,6 +510,28 @@ static void tls_encrypt_done(struct cryp
+ schedule_delayed_work(&ctx->tx_work.work, 1);
+ }
+
++static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx)
++{
++ int pending;
++
++ spin_lock_bh(&ctx->encrypt_compl_lock);
++ ctx->async_notify = true;
++
++ pending = atomic_read(&ctx->encrypt_pending);
++ spin_unlock_bh(&ctx->encrypt_compl_lock);
++ if (pending)
++ crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
++ else
++ reinit_completion(&ctx->async_wait.completion);
++
++ /* There can be no concurrent accesses, since we have no
++ * pending encrypt operations
++ */
++ WRITE_ONCE(ctx->async_notify, false);
++
++ return ctx->async_wait.err;
++}
++
+ static int tls_do_encryption(struct sock *sk,
+ struct tls_context *tls_ctx,
+ struct tls_sw_context_tx *ctx,
+@@ -946,7 +982,6 @@ int tls_sw_sendmsg(struct sock *sk, stru
+ int num_zc = 0;
+ int orig_size;
+ int ret = 0;
+- int pending;
+
+ if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
+ MSG_CMSG_COMPAT))
+@@ -1115,24 +1150,12 @@ trim_sgl:
+ if (!num_async) {
+ goto send_end;
+ } else if (num_zc) {
+- /* Wait for pending encryptions to get completed */
+- spin_lock_bh(&ctx->encrypt_compl_lock);
+- ctx->async_notify = true;
+-
+- pending = atomic_read(&ctx->encrypt_pending);
+- spin_unlock_bh(&ctx->encrypt_compl_lock);
+- if (pending)
+- crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
+- else
+- reinit_completion(&ctx->async_wait.completion);
++ int err;
+
+- /* There can be no concurrent accesses, since we have no
+- * pending encrypt operations
+- */
+- WRITE_ONCE(ctx->async_notify, false);
+-
+- if (ctx->async_wait.err) {
+- ret = ctx->async_wait.err;
++ /* Wait for pending encryptions to get completed */
++ err = tls_encrypt_async_wait(ctx);
++ if (err) {
++ ret = err;
+ copied = 0;
+ }
+ }
+@@ -1910,22 +1933,14 @@ pick_next_record:
+
+ recv_end:
+ if (async) {
+- int pending;
+-
+ /* Wait for all previously submitted records to be decrypted */
+- spin_lock_bh(&ctx->decrypt_compl_lock);
+- reinit_completion(&ctx->async_wait.completion);
+- pending = atomic_read(&ctx->decrypt_pending);
+- spin_unlock_bh(&ctx->decrypt_compl_lock);
+- if (pending) {
+- err = crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
+- if (err) {
+- /* one of async decrypt failed */
+- tls_err_abort(sk, err);
+- copied = 0;
+- decrypted = 0;
+- goto end;
+- }
++ err = tls_decrypt_async_wait(ctx);
++ if (err) {
++ /* one of async decrypt failed */
++ tls_err_abort(sk, err);
++ copied = 0;
++ decrypted = 0;
++ goto end;
+ }
+
+ /* Drain records from the rx_list & copy if required */
+@@ -2144,16 +2159,9 @@ void tls_sw_release_resources_tx(struct
+ struct tls_context *tls_ctx = tls_get_ctx(sk);
+ struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
+ struct tls_rec *rec, *tmp;
+- int pending;
+
+ /* Wait for any pending async encryptions to complete */
+- spin_lock_bh(&ctx->encrypt_compl_lock);
+- ctx->async_notify = true;
+- pending = atomic_read(&ctx->encrypt_pending);
+- spin_unlock_bh(&ctx->encrypt_compl_lock);
+-
+- if (pending)
+- crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
++ tls_encrypt_async_wait(ctx);
+
+ tls_tx_records(sk, -1);
+
--- /dev/null
+From 8590541473188741055d27b955db0777569438e3 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Tue, 6 Feb 2024 17:18:21 -0800
+Subject: net: tls: handle backlogging of crypto requests
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+commit 8590541473188741055d27b955db0777569438e3 upstream.
+
+Since we're setting the CRYPTO_TFM_REQ_MAY_BACKLOG flag on our
+requests to the crypto API, crypto_aead_{encrypt,decrypt} can return
+ -EBUSY instead of -EINPROGRESS in valid situations. For example, when
+the cryptd queue for AESNI is full (easy to trigger with an
+artificially low cryptd.cryptd_max_cpu_qlen), requests will be enqueued
+to the backlog but still processed. In that case, the async callback
+will also be called twice: first with err == -EINPROGRESS, which it
+seems we can just ignore, then with err == 0.
+
+Compared to Sabrina's original patch this version uses the new
+tls_*crypt_async_wait() helpers and converts the EBUSY to
+EINPROGRESS to avoid having to modify all the error handling
+paths. The handling is identical.
+
+Fixes: a54667f6728c ("tls: Add support for encryption using async offload accelerator")
+Fixes: 94524d8fc965 ("net/tls: Add support for async decryption of tls records")
+Co-developed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://lore.kernel.org/netdev/9681d1febfec295449a62300938ed2ae66983f28.1694018970.git.sd@queasysnail.net/
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[v5.15: fixed contextual merge-conflicts in tls_decrypt_done and tls_encrypt_done]
+Cc: <stable@vger.kernel.org> # 5.15
+Signed-off-by: Shaoying Xu <shaoyi@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tls/tls_sw.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -175,6 +175,17 @@ static void tls_decrypt_done(struct cryp
+ struct sk_buff *skb;
+ unsigned int pages;
+
++ /* If requests get too backlogged crypto API returns -EBUSY and calls
++ * ->complete(-EINPROGRESS) immediately followed by ->complete(0)
++ * to make waiting for backlog to flush with crypto_wait_req() easier.
++ * First wait converts -EBUSY -> -EINPROGRESS, and the second one
++ * -EINPROGRESS -> 0.
++ * We have a single struct crypto_async_request per direction, this
++ * scheme doesn't help us, so just ignore the first ->complete().
++ */
++ if (err == -EINPROGRESS)
++ return;
++
+ skb = (struct sk_buff *)req->data;
+ tls_ctx = tls_get_ctx(skb->sk);
+ ctx = tls_sw_ctx_rx(tls_ctx);
+@@ -273,6 +284,10 @@ static int tls_do_decryption(struct sock
+ }
+
+ ret = crypto_aead_decrypt(aead_req);
++ if (ret == -EBUSY) {
++ ret = tls_decrypt_async_wait(ctx);
++ ret = ret ?: -EINPROGRESS;
++ }
+ if (ret == -EINPROGRESS) {
+ if (darg->async)
+ return 0;
+@@ -455,6 +470,9 @@ static void tls_encrypt_done(struct cryp
+ struct tls_rec *rec;
+ bool ready = false;
+
++ if (err == -EINPROGRESS) /* see the comment in tls_decrypt_done() */
++ return;
++
+ rec = container_of(aead_req, struct tls_rec, aead_req);
+ msg_en = &rec->msg_encrypted;
+
+@@ -551,6 +569,10 @@ static int tls_do_encryption(struct sock
+ atomic_inc(&ctx->encrypt_pending);
+
+ rc = crypto_aead_encrypt(aead_req);
++ if (rc == -EBUSY) {
++ rc = tls_encrypt_async_wait(ctx);
++ rc = rc ?: -EINPROGRESS;
++ }
+ if (!rc || rc != -EINPROGRESS) {
+ atomic_dec(&ctx->encrypt_pending);
+ sge->offset -= prot->prepend_size;
--- /dev/null
+From harshit.m.mogalapalli@oracle.com Thu May 23 13:27:11 2024
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Date: Mon, 6 May 2024 01:46:35 -0700
+Subject: Revert "selftests: mm: fix map_hugetlb failure on 64K page size systems"
+To: stable@vger.kernel.org
+Cc: sashal@kernel.org, vegard.nossum@oracle.com, darren.kenny@oracle.com, Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Message-ID: <20240506084635.2942238-1-harshit.m.mogalapalli@oracle.com>
+
+
+This reverts commit 0d29b474fb90ff35920642f378d9baace9b47edd which is
+commit 91b80cc5b39f00399e8e2d17527cad2c7fa535e2 upstream.
+
+map_hugetlb.c:18:10: fatal error: vm_util.h: No such file or directory
+ 18 | #include "vm_util.h"
+ | ^~~~~~~~~~~
+compilation terminated.
+
+vm_util.h is not present in 5.15.y, as commit:642bc52aed9c ("selftests:
+vm: bring common functions to a new file") is not present in stable
+kernels <=6.1.y
+
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+---
+ tools/testing/selftests/vm/map_hugetlb.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/tools/testing/selftests/vm/map_hugetlb.c
++++ b/tools/testing/selftests/vm/map_hugetlb.c
+@@ -15,7 +15,6 @@
+ #include <unistd.h>
+ #include <sys/mman.h>
+ #include <fcntl.h>
+-#include "vm_util.h"
+
+ #define LENGTH (256UL*1024*1024)
+ #define PROTECTION (PROT_READ | PROT_WRITE)
+@@ -71,16 +70,10 @@ int main(int argc, char **argv)
+ {
+ void *addr;
+ int ret;
+- size_t hugepage_size;
+ size_t length = LENGTH;
+ int flags = FLAGS;
+ int shift = 0;
+
+- hugepage_size = default_huge_page_size();
+- /* munmap with fail if the length is not page aligned */
+- if (hugepage_size > length)
+- length = hugepage_size;
+-
+ if (argc > 1)
+ length = atol(argv[1]) << 20;
+ if (argc > 2) {
pinctrl-core-handle-radix_tree_insert-errors-in-pinctrl_register_one_pin.patch
nfsd-don-t-allow-nfsd-threads-to-be-signalled.patch
keys-trusted-fix-memory-leak-in-tpm2_key_encode.patch
+revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch
+net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch
+net-bcmgenet-synchronize-umac_cmd-access.patch
+tls-rx-simplify-async-wait.patch
+tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch
+net-tls-factor-out-tls_-crypt_async_wait.patch
+tls-fix-race-between-async-notify-and-socket-close.patch
+net-tls-handle-backlogging-of-crypto-requests.patch
--- /dev/null
+From 615580cbc99af0da2d1c7226fab43a3d5003eb97 Mon Sep 17 00:00:00 2001
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Mon, 9 Oct 2023 22:50:46 +0200
+Subject: tls: extract context alloc/initialization out of tls_set_sw_offload
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+commit 615580cbc99af0da2d1c7226fab43a3d5003eb97 upstream.
+
+Simplify tls_set_sw_offload a bit.
+
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: aec7961916f3 ("tls: fix race between async notify and socket close")
+[v5.15: fixed contextual conflicts from unavailable init_waitqueue_head and
+skb_queue_head_init calls in tls_set_sw_offload and init_ctx_rx]
+Cc: <stable@vger.kernel.org> # 5.15
+Signed-off-by: Shaoying Xu <shaoyi@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tls/tls_sw.c | 82 ++++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 49 insertions(+), 33 deletions(-)
+
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -2291,6 +2291,46 @@ void tls_sw_strparser_arm(struct sock *s
+ strp_check_rcv(&rx_ctx->strp);
+ }
+
++static struct tls_sw_context_tx *init_ctx_tx(struct tls_context *ctx, struct sock *sk)
++{
++ struct tls_sw_context_tx *sw_ctx_tx;
++
++ if (!ctx->priv_ctx_tx) {
++ sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL);
++ if (!sw_ctx_tx)
++ return NULL;
++ } else {
++ sw_ctx_tx = ctx->priv_ctx_tx;
++ }
++
++ crypto_init_wait(&sw_ctx_tx->async_wait);
++ spin_lock_init(&sw_ctx_tx->encrypt_compl_lock);
++ INIT_LIST_HEAD(&sw_ctx_tx->tx_list);
++ INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler);
++ sw_ctx_tx->tx_work.sk = sk;
++
++ return sw_ctx_tx;
++}
++
++static struct tls_sw_context_rx *init_ctx_rx(struct tls_context *ctx)
++{
++ struct tls_sw_context_rx *sw_ctx_rx;
++
++ if (!ctx->priv_ctx_rx) {
++ sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL);
++ if (!sw_ctx_rx)
++ return NULL;
++ } else {
++ sw_ctx_rx = ctx->priv_ctx_rx;
++ }
++
++ crypto_init_wait(&sw_ctx_rx->async_wait);
++ spin_lock_init(&sw_ctx_rx->decrypt_compl_lock);
++ skb_queue_head_init(&sw_ctx_rx->rx_list);
++
++ return sw_ctx_rx;
++}
++
+ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
+ {
+ struct tls_context *tls_ctx = tls_get_ctx(sk);
+@@ -2317,46 +2357,22 @@ int tls_set_sw_offload(struct sock *sk,
+ }
+
+ if (tx) {
+- if (!ctx->priv_ctx_tx) {
+- sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL);
+- if (!sw_ctx_tx) {
+- rc = -ENOMEM;
+- goto out;
+- }
+- ctx->priv_ctx_tx = sw_ctx_tx;
+- } else {
+- sw_ctx_tx =
+- (struct tls_sw_context_tx *)ctx->priv_ctx_tx;
+- }
+- } else {
+- if (!ctx->priv_ctx_rx) {
+- sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL);
+- if (!sw_ctx_rx) {
+- rc = -ENOMEM;
+- goto out;
+- }
+- ctx->priv_ctx_rx = sw_ctx_rx;
+- } else {
+- sw_ctx_rx =
+- (struct tls_sw_context_rx *)ctx->priv_ctx_rx;
+- }
+- }
++ ctx->priv_ctx_tx = init_ctx_tx(ctx, sk);
++ if (!ctx->priv_ctx_tx)
++ return -ENOMEM;
+
+- if (tx) {
+- crypto_init_wait(&sw_ctx_tx->async_wait);
+- spin_lock_init(&sw_ctx_tx->encrypt_compl_lock);
++ sw_ctx_tx = ctx->priv_ctx_tx;
+ crypto_info = &ctx->crypto_send.info;
+ cctx = &ctx->tx;
+ aead = &sw_ctx_tx->aead_send;
+- INIT_LIST_HEAD(&sw_ctx_tx->tx_list);
+- INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler);
+- sw_ctx_tx->tx_work.sk = sk;
+ } else {
+- crypto_init_wait(&sw_ctx_rx->async_wait);
+- spin_lock_init(&sw_ctx_rx->decrypt_compl_lock);
++ ctx->priv_ctx_rx = init_ctx_rx(ctx);
++ if (!ctx->priv_ctx_rx)
++ return -ENOMEM;
++
++ sw_ctx_rx = ctx->priv_ctx_rx;
+ crypto_info = &ctx->crypto_recv.info;
+ cctx = &ctx->rx;
+- skb_queue_head_init(&sw_ctx_rx->rx_list);
+ aead = &sw_ctx_rx->aead_recv;
+ }
+
--- /dev/null
+From aec7961916f3f9e88766e2688992da6980f11b8d Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Tue, 6 Feb 2024 17:18:19 -0800
+Subject: tls: fix race between async notify and socket close
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+commit aec7961916f3f9e88766e2688992da6980f11b8d upstream.
+
+The submitting thread (one which called recvmsg/sendmsg)
+may exit as soon as the async crypto handler calls complete()
+so any code past that point risks touching already freed data.
+
+Try to avoid the locking and extra flags altogether.
+Have the main thread hold an extra reference, this way
+we can depend solely on the atomic ref counter for
+synchronization.
+
+Don't futz with reiniting the completion, either, we are now
+tightly controlling when completion fires.
+
+Reported-by: valis <sec@valis.email>
+Fixes: 0cada33241d9 ("net/tls: fix race condition causing kernel panic")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[v5.15: fixed contextual conflicts in struct tls_sw_context_rx and func
+init_ctx_rx; replaced DEBUG_NET_WARN_ON_ONCE with BUILD_BUG_ON_INVALID
+since they're equivalent when DEBUG_NET is not defined]
+Cc: <stable@vger.kernel.org> # 5.15
+Signed-off-by: Shaoying Xu <shaoyi@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/tls.h | 5 -----
+ net/tls/tls_sw.c | 43 ++++++++++---------------------------------
+ 2 files changed, 10 insertions(+), 38 deletions(-)
+
+--- a/include/net/tls.h
++++ b/include/net/tls.h
+@@ -128,9 +128,6 @@ struct tls_sw_context_tx {
+ struct tls_rec *open_rec;
+ struct list_head tx_list;
+ atomic_t encrypt_pending;
+- /* protect crypto_wait with encrypt_pending */
+- spinlock_t encrypt_compl_lock;
+- int async_notify;
+ u8 async_capable:1;
+
+ #define BIT_TX_SCHEDULED 0
+@@ -148,8 +145,6 @@ struct tls_sw_context_rx {
+ struct sk_buff *recv_pkt;
+ u8 async_capable:1;
+ atomic_t decrypt_pending;
+- /* protect crypto_wait with decrypt_pending*/
+- spinlock_t decrypt_compl_lock;
+ };
+
+ struct tls_record_info {
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -220,22 +220,15 @@ static void tls_decrypt_done(struct cryp
+
+ kfree(aead_req);
+
+- spin_lock_bh(&ctx->decrypt_compl_lock);
+- if (!atomic_dec_return(&ctx->decrypt_pending))
++ if (atomic_dec_and_test(&ctx->decrypt_pending))
+ complete(&ctx->async_wait.completion);
+- spin_unlock_bh(&ctx->decrypt_compl_lock);
+ }
+
+ static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx)
+ {
+- int pending;
+-
+- spin_lock_bh(&ctx->decrypt_compl_lock);
+- reinit_completion(&ctx->async_wait.completion);
+- pending = atomic_read(&ctx->decrypt_pending);
+- spin_unlock_bh(&ctx->decrypt_compl_lock);
+- if (pending)
++ if (!atomic_dec_and_test(&ctx->decrypt_pending))
+ crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
++ atomic_inc(&ctx->decrypt_pending);
+
+ return ctx->async_wait.err;
+ }
+@@ -271,6 +264,7 @@ static int tls_do_decryption(struct sock
+ aead_request_set_callback(aead_req,
+ CRYPTO_TFM_REQ_MAY_BACKLOG,
+ tls_decrypt_done, skb);
++ BUILD_BUG_ON_INVALID(atomic_read(&ctx->decrypt_pending) < 1);
+ atomic_inc(&ctx->decrypt_pending);
+ } else {
+ aead_request_set_callback(aead_req,
+@@ -460,7 +454,6 @@ static void tls_encrypt_done(struct cryp
+ struct sk_msg *msg_en;
+ struct tls_rec *rec;
+ bool ready = false;
+- int pending;
+
+ rec = container_of(aead_req, struct tls_rec, aead_req);
+ msg_en = &rec->msg_encrypted;
+@@ -495,12 +488,8 @@ static void tls_encrypt_done(struct cryp
+ ready = true;
+ }
+
+- spin_lock_bh(&ctx->encrypt_compl_lock);
+- pending = atomic_dec_return(&ctx->encrypt_pending);
+-
+- if (!pending && ctx->async_notify)
++ if (atomic_dec_and_test(&ctx->encrypt_pending))
+ complete(&ctx->async_wait.completion);
+- spin_unlock_bh(&ctx->encrypt_compl_lock);
+
+ if (!ready)
+ return;
+@@ -512,22 +501,9 @@ static void tls_encrypt_done(struct cryp
+
+ static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx)
+ {
+- int pending;
+-
+- spin_lock_bh(&ctx->encrypt_compl_lock);
+- ctx->async_notify = true;
+-
+- pending = atomic_read(&ctx->encrypt_pending);
+- spin_unlock_bh(&ctx->encrypt_compl_lock);
+- if (pending)
++ if (!atomic_dec_and_test(&ctx->encrypt_pending))
+ crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
+- else
+- reinit_completion(&ctx->async_wait.completion);
+-
+- /* There can be no concurrent accesses, since we have no
+- * pending encrypt operations
+- */
+- WRITE_ONCE(ctx->async_notify, false);
++ atomic_inc(&ctx->encrypt_pending);
+
+ return ctx->async_wait.err;
+ }
+@@ -571,6 +547,7 @@ static int tls_do_encryption(struct sock
+
+ /* Add the record in tx_list */
+ list_add_tail((struct list_head *)&rec->list, &ctx->tx_list);
++ BUILD_BUG_ON_INVALID(atomic_read(&ctx->encrypt_pending) < 1);
+ atomic_inc(&ctx->encrypt_pending);
+
+ rc = crypto_aead_encrypt(aead_req);
+@@ -2312,7 +2289,7 @@ static struct tls_sw_context_tx *init_ct
+ }
+
+ crypto_init_wait(&sw_ctx_tx->async_wait);
+- spin_lock_init(&sw_ctx_tx->encrypt_compl_lock);
++ atomic_set(&sw_ctx_tx->encrypt_pending, 1);
+ INIT_LIST_HEAD(&sw_ctx_tx->tx_list);
+ INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler);
+ sw_ctx_tx->tx_work.sk = sk;
+@@ -2333,7 +2310,7 @@ static struct tls_sw_context_rx *init_ct
+ }
+
+ crypto_init_wait(&sw_ctx_rx->async_wait);
+- spin_lock_init(&sw_ctx_rx->decrypt_compl_lock);
++ atomic_set(&sw_ctx_rx->decrypt_pending, 1);
+ skb_queue_head_init(&sw_ctx_rx->rx_list);
+
+ return sw_ctx_rx;
--- /dev/null
+From 37943f047bfb88ba4dfc7a522563f57c86d088a0 Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Fri, 8 Apr 2022 11:31:27 -0700
+Subject: tls: rx: simplify async wait
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+commit 37943f047bfb88ba4dfc7a522563f57c86d088a0 upstream.
+
+Since we are protected from async completions by decrypt_compl_lock
+we can drop the async_notify and reinit the completion before we
+start waiting.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: aec7961916f3 ("tls: fix race between async notify and socket close")
+Signed-off-by: Shaoying Xu <shaoyi@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/tls.h | 1 -
+ net/tls/tls_sw.c | 14 ++------------
+ 2 files changed, 2 insertions(+), 13 deletions(-)
+
+--- a/include/net/tls.h
++++ b/include/net/tls.h
+@@ -150,7 +150,6 @@ struct tls_sw_context_rx {
+ atomic_t decrypt_pending;
+ /* protect crypto_wait with decrypt_pending*/
+ spinlock_t decrypt_compl_lock;
+- bool async_notify;
+ };
+
+ struct tls_record_info {
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -174,7 +174,6 @@ static void tls_decrypt_done(struct cryp
+ struct scatterlist *sg;
+ struct sk_buff *skb;
+ unsigned int pages;
+- int pending;
+
+ skb = (struct sk_buff *)req->data;
+ tls_ctx = tls_get_ctx(skb->sk);
+@@ -222,9 +221,7 @@ static void tls_decrypt_done(struct cryp
+ kfree(aead_req);
+
+ spin_lock_bh(&ctx->decrypt_compl_lock);
+- pending = atomic_dec_return(&ctx->decrypt_pending);
+-
+- if (!pending && ctx->async_notify)
++ if (!atomic_dec_return(&ctx->decrypt_pending))
+ complete(&ctx->async_wait.completion);
+ spin_unlock_bh(&ctx->decrypt_compl_lock);
+ }
+@@ -1917,7 +1914,7 @@ recv_end:
+
+ /* Wait for all previously submitted records to be decrypted */
+ spin_lock_bh(&ctx->decrypt_compl_lock);
+- ctx->async_notify = true;
++ reinit_completion(&ctx->async_wait.completion);
+ pending = atomic_read(&ctx->decrypt_pending);
+ spin_unlock_bh(&ctx->decrypt_compl_lock);
+ if (pending) {
+@@ -1929,15 +1926,8 @@ recv_end:
+ decrypted = 0;
+ goto end;
+ }
+- } else {
+- reinit_completion(&ctx->async_wait.completion);
+ }
+
+- /* There can be no concurrent accesses, since we have no
+- * pending decrypt operations
+- */
+- WRITE_ONCE(ctx->async_notify, false);
+-
+ /* Drain records from the rx_list & copy if required */
+ if (is_peek || is_kvec)
+ err = process_rx_list(ctx, msg, &control, copied,