]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 May 2024 11:48:16 +0000 (13:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 May 2024 11:48:16 +0000 (13:48 +0200)
added patches:
net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch
net-bcmgenet-synchronize-umac_cmd-access.patch
net-tls-factor-out-tls_-crypt_async_wait.patch
net-tls-handle-backlogging-of-crypto-requests.patch
revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch
tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch
tls-fix-race-between-async-notify-and-socket-close.patch
tls-rx-simplify-async-wait.patch

queue-5.15/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch [new file with mode: 0644]
queue-5.15/net-bcmgenet-synchronize-umac_cmd-access.patch [new file with mode: 0644]
queue-5.15/net-tls-factor-out-tls_-crypt_async_wait.patch [new file with mode: 0644]
queue-5.15/net-tls-handle-backlogging-of-crypto-requests.patch [new file with mode: 0644]
queue-5.15/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch [new file with mode: 0644]
queue-5.15/tls-fix-race-between-async-notify-and-socket-close.patch [new file with mode: 0644]
queue-5.15/tls-rx-simplify-async-wait.patch [new file with mode: 0644]

diff --git a/queue-5.15/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch b/queue-5.15/net-bcmgenet-synchronize-ext_rgmii_oob_ctrl-access.patch
new file mode 100644 (file)
index 0000000..0ae8c9e
--- /dev/null
@@ -0,0 +1,48 @@
+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)
diff --git a/queue-5.15/net-bcmgenet-synchronize-umac_cmd-access.patch b/queue-5.15/net-bcmgenet-synchronize-umac_cmd-access.patch
new file mode 100644 (file)
index 0000000..325585d
--- /dev/null
@@ -0,0 +1,167 @@
+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,
diff --git a/queue-5.15/net-tls-factor-out-tls_-crypt_async_wait.patch b/queue-5.15/net-tls-factor-out-tls_-crypt_async_wait.patch
new file mode 100644 (file)
index 0000000..dda20e4
--- /dev/null
@@ -0,0 +1,167 @@
+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);
diff --git a/queue-5.15/net-tls-handle-backlogging-of-crypto-requests.patch b/queue-5.15/net-tls-handle-backlogging-of-crypto-requests.patch
new file mode 100644 (file)
index 0000000..4de05d8
--- /dev/null
@@ -0,0 +1,91 @@
+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;
diff --git a/queue-5.15/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch b/queue-5.15/revert-selftests-mm-fix-map_hugetlb-failure-on-64k-page-size-systems.patch
new file mode 100644 (file)
index 0000000..db2daf9
--- /dev/null
@@ -0,0 +1,53 @@
+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) {
index e1ceebb111ca13bc10f15567013211e3ef63f172..864900181874fbe50ad16f2606bfd992b7185606 100644 (file)
@@ -2,3 +2,11 @@ drm-amd-display-fix-division-by-zero-in-setup_dsc_config.patch
 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
diff --git a/queue-5.15/tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch b/queue-5.15/tls-extract-context-alloc-initialization-out-of-tls_set_sw_offload.patch
new file mode 100644 (file)
index 0000000..7130671
--- /dev/null
@@ -0,0 +1,128 @@
+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;
+       }
diff --git a/queue-5.15/tls-fix-race-between-async-notify-and-socket-close.patch b/queue-5.15/tls-fix-race-between-async-notify-and-socket-close.patch
new file mode 100644 (file)
index 0000000..da5ee5b
--- /dev/null
@@ -0,0 +1,169 @@
+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;
diff --git a/queue-5.15/tls-rx-simplify-async-wait.patch b/queue-5.15/tls-rx-simplify-async-wait.patch
new file mode 100644 (file)
index 0000000..79d713a
--- /dev/null
@@ -0,0 +1,79 @@
+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,