]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Sep 2025 11:26:06 +0000 (13:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Sep 2025 11:26:06 +0000 (13:26 +0200)
added patches:
i40e-add-mask-to-apply-valid-bits-for-itr_idx.patch
i40e-add-validation-for-ring_len-param.patch
i40e-fix-idx-validation-in-config-queues-msg.patch
i40e-fix-validation-of-vf-state-in-get-resources.patch
i40e-increase-max-descriptors-for-xl710.patch
mm-hugetlb-fix-folio-is-still-mapped-when-deleted.patch

queue-5.4/i40e-add-mask-to-apply-valid-bits-for-itr_idx.patch [new file with mode: 0644]
queue-5.4/i40e-add-validation-for-ring_len-param.patch [new file with mode: 0644]
queue-5.4/i40e-fix-idx-validation-in-config-queues-msg.patch [new file with mode: 0644]
queue-5.4/i40e-fix-validation-of-vf-state-in-get-resources.patch [new file with mode: 0644]
queue-5.4/i40e-increase-max-descriptors-for-xl710.patch [new file with mode: 0644]
queue-5.4/mm-hugetlb-fix-folio-is-still-mapped-when-deleted.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/i40e-add-mask-to-apply-valid-bits-for-itr_idx.patch b/queue-5.4/i40e-add-mask-to-apply-valid-bits-for-itr_idx.patch
new file mode 100644 (file)
index 0000000..f567f3d
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-181953-greg=kroah.com@vger.kernel.org Mon Sep 29 18:02:41 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 12:02:25 -0400
+Subject: i40e: add mask to apply valid bits for itr_idx
+To: stable@vger.kernel.org
+Cc: Lukasz Czapnik <lukasz.czapnik@intel.com>, Aleksandr Loktionov <aleksandr.loktionov@intel.com>, Przemek Kitszel <przemyslaw.kitszel@intel.com>, Simon Horman <horms@kernel.org>, Rafal Romanowski <rafal.romanowski@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250929160225.145538-1-sashal@kernel.org>
+
+From: Lukasz Czapnik <lukasz.czapnik@intel.com>
+
+[ Upstream commit eac04428abe9f9cb203ffae4600791ea1d24eb18 ]
+
+The ITR index (itr_idx) is only 2 bits wide. When constructing the
+register value for QINT_RQCTL, all fields are ORed together. Without
+masking, higher bits from itr_idx may overwrite adjacent fields in the
+register.
+
+Apply I40E_QINT_RQCTL_ITR_INDX_MASK to ensure only the intended bits are
+set.
+
+Fixes: 5c3c48ac6bf5 ("i40e: implement virtual device interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lukasz Czapnik <lukasz.czapnik@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+[ Added missing linux/bitfield.h header for FIELD_PREP macro ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /* Copyright(c) 2013 - 2018 Intel Corporation. */
++#include <linux/bitfield.h>
+ #include "i40e.h"
+ /*********************notification routines***********************/
+@@ -393,7 +394,7 @@ static void i40e_config_irq_link_list(st
+                   (qtype << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) |
+                   (pf_queue_id << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) |
+                   BIT(I40E_QINT_RQCTL_CAUSE_ENA_SHIFT) |
+-                  (itr_idx << I40E_QINT_RQCTL_ITR_INDX_SHIFT);
++                  FIELD_PREP(I40E_QINT_RQCTL_ITR_INDX_MASK, itr_idx);
+               wr32(hw, reg_idx, reg);
+       }
diff --git a/queue-5.4/i40e-add-validation-for-ring_len-param.patch b/queue-5.4/i40e-add-validation-for-ring_len-param.patch
new file mode 100644 (file)
index 0000000..effa547
--- /dev/null
@@ -0,0 +1,66 @@
+From stable+bounces-181938-greg=kroah.com@vger.kernel.org Mon Sep 29 16:54:25 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 10:53:52 -0400
+Subject: i40e: add validation for ring_len param
+To: stable@vger.kernel.org
+Cc: Lukasz Czapnik <lukasz.czapnik@intel.com>, Aleksandr Loktionov <aleksandr.loktionov@intel.com>, Przemek Kitszel <przemyslaw.kitszel@intel.com>, Simon Horman <horms@kernel.org>, Rafal Romanowski <rafal.romanowski@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250929145352.110268-2-sashal@kernel.org>
+
+From: Lukasz Czapnik <lukasz.czapnik@intel.com>
+
+[ Upstream commit 55d225670def06b01af2e7a5e0446fbe946289e8 ]
+
+The `ring_len` parameter provided by the virtual function (VF)
+is assigned directly to the hardware memory context (HMC) without
+any validation.
+
+To address this, introduce an upper boundary check for both Tx and Rx
+queue lengths. The maximum number of descriptors supported by the
+hardware is 8k-32.
+Additionally, enforce alignment constraints: Tx rings must be a multiple
+of 8, and Rx rings must be a multiple of 32.
+
+Fixes: 5c3c48ac6bf5 ("i40e: implement virtual device interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lukasz Czapnik <lukasz.czapnik@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -600,6 +600,13 @@ static int i40e_config_vsi_tx_queue(stru
+       /* only set the required fields */
+       tx_ctx.base = info->dma_ring_addr / 128;
++
++      /* ring_len has to be multiple of 8 */
++      if (!IS_ALIGNED(info->ring_len, 8) ||
++          info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
++              ret = -EINVAL;
++              goto error_context;
++      }
+       tx_ctx.qlen = info->ring_len;
+       tx_ctx.rdylist = le16_to_cpu(vsi->info.qs_handle[0]);
+       tx_ctx.rdylist_act = 0;
+@@ -665,6 +672,13 @@ static int i40e_config_vsi_rx_queue(stru
+       /* only set the required fields */
+       rx_ctx.base = info->dma_ring_addr / 128;
++
++      /* ring_len has to be multiple of 32 */
++      if (!IS_ALIGNED(info->ring_len, 32) ||
++          info->ring_len > I40E_MAX_NUM_DESCRIPTORS_XL710) {
++              ret = -EINVAL;
++              goto error_param;
++      }
+       rx_ctx.qlen = info->ring_len;
+       if (info->splithdr_enabled) {
diff --git a/queue-5.4/i40e-fix-idx-validation-in-config-queues-msg.patch b/queue-5.4/i40e-fix-idx-validation-in-config-queues-msg.patch
new file mode 100644 (file)
index 0000000..21e86ee
--- /dev/null
@@ -0,0 +1,50 @@
+From stable+bounces-181943-greg=kroah.com@vger.kernel.org Mon Sep 29 16:58:48 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 10:58:37 -0400
+Subject: i40e: fix idx validation in config queues msg
+To: stable@vger.kernel.org
+Cc: Lukasz Czapnik <lukasz.czapnik@intel.com>, Aleksandr Loktionov <aleksandr.loktionov@intel.com>, Przemek Kitszel <przemyslaw.kitszel@intel.com>, Simon Horman <horms@kernel.org>, Kamakshi Nellore <nellorex.kamakshi@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250929145838.112568-1-sashal@kernel.org>
+
+From: Lukasz Czapnik <lukasz.czapnik@intel.com>
+
+[ Upstream commit f1ad24c5abe1eaef69158bac1405a74b3c365115 ]
+
+Ensure idx is within range of active/initialized TCs when iterating over
+vf->ch[idx] in i40e_vc_config_queues_msg().
+
+Fixes: c27eac48160d ("i40e: Enable ADq and create queue channel/s on VF")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lukasz Czapnik <lukasz.czapnik@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Kamakshi Nellore <nellorex.kamakshi@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+[ Adjust context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -2320,7 +2320,7 @@ static int i40e_vc_config_queues_msg(str
+               }
+               if (vf->adq_enabled) {
+-                      if (idx >= ARRAY_SIZE(vf->ch)) {
++                      if (idx >= vf->num_tc) {
+                               aq_ret = I40E_ERR_NO_AVAILABLE_VSI;
+                               goto error_param;
+                       }
+@@ -2341,7 +2341,7 @@ static int i40e_vc_config_queues_msg(str
+                * to its appropriate VSIs based on TC mapping
+                */
+               if (vf->adq_enabled) {
+-                      if (idx >= ARRAY_SIZE(vf->ch)) {
++                      if (idx >= vf->num_tc) {
+                               aq_ret = I40E_ERR_NO_AVAILABLE_VSI;
+                               goto error_param;
+                       }
diff --git a/queue-5.4/i40e-fix-validation-of-vf-state-in-get-resources.patch b/queue-5.4/i40e-fix-validation-of-vf-state-in-get-resources.patch
new file mode 100644 (file)
index 0000000..adeaca1
--- /dev/null
@@ -0,0 +1,77 @@
+From stable+bounces-181944-greg=kroah.com@vger.kernel.org Mon Sep 29 17:02:09 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 11:02:01 -0400
+Subject: i40e: fix validation of VF state in get resources
+To: stable@vger.kernel.org
+Cc: Lukasz Czapnik <lukasz.czapnik@intel.com>, Aleksandr Loktionov <aleksandr.loktionov@intel.com>, Przemek Kitszel <przemyslaw.kitszel@intel.com>, Simon Horman <horms@kernel.org>, Rafal Romanowski <rafal.romanowski@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250929150201.114123-1-sashal@kernel.org>
+
+From: Lukasz Czapnik <lukasz.czapnik@intel.com>
+
+[ Upstream commit 877b7e6ffc23766448236e8732254534c518ba42 ]
+
+VF state I40E_VF_STATE_ACTIVE is not the only state in which
+VF is actually active so it should not be used to determine
+if a VF is allowed to obtain resources.
+
+Use I40E_VF_STATE_RESOURCES_LOADED that is set only in
+i40e_vc_get_vf_resources_msg() and cleared during reset.
+
+Fixes: 61125b8be85d ("i40e: Fix failed opcode appearing if handling messages from VF")
+Cc: stable@vger.kernel.org
+Signed-off-by: Lukasz Czapnik <lukasz.czapnik@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+[ Adjust context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |    7 ++++++-
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h |    3 ++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1389,6 +1389,7 @@ static void i40e_trigger_vf_reset(struct
+        * functions that may still be running at this point.
+        */
+       clear_bit(I40E_VF_STATE_INIT, &vf->vf_states);
++      clear_bit(I40E_VF_STATE_RESOURCES_LOADED, &vf->vf_states);
+       /* In the case of a VFLR, the HW has already reset the VF and we
+        * just need to clean up, so don't hit the VFRTRIG register.
+@@ -2062,7 +2063,10 @@ static int i40e_vc_get_vf_resources_msg(
+       size_t len = 0;
+       int ret;
+-      if (!i40e_sync_vf_state(vf, I40E_VF_STATE_INIT)) {
++      i40e_sync_vf_state(vf, I40E_VF_STATE_INIT);
++
++      if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states) ||
++          test_bit(I40E_VF_STATE_RESOURCES_LOADED, &vf->vf_states)) {
+               aq_ret = I40E_ERR_PARAM;
+               goto err;
+       }
+@@ -2158,6 +2162,7 @@ static int i40e_vc_get_vf_resources_msg(
+                               vf->default_lan_addr.addr);
+       }
+       set_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states);
++      set_bit(I40E_VF_STATE_RESOURCES_LOADED, &vf->vf_states);
+ err:
+       /* send the response back to the VF */
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+@@ -41,7 +41,8 @@ enum i40e_vf_states {
+       I40E_VF_STATE_MC_PROMISC,
+       I40E_VF_STATE_UC_PROMISC,
+       I40E_VF_STATE_PRE_ENABLE,
+-      I40E_VF_STATE_RESETTING
++      I40E_VF_STATE_RESETTING,
++      I40E_VF_STATE_RESOURCES_LOADED,
+ };
+ /* VF capabilities */
diff --git a/queue-5.4/i40e-increase-max-descriptors-for-xl710.patch b/queue-5.4/i40e-increase-max-descriptors-for-xl710.patch
new file mode 100644 (file)
index 0000000..a483bbc
--- /dev/null
@@ -0,0 +1,105 @@
+From stable+bounces-181937-greg=kroah.com@vger.kernel.org Mon Sep 29 16:54:01 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 10:53:51 -0400
+Subject: i40e: increase max descriptors for XL710
+To: stable@vger.kernel.org
+Cc: Justin Bronder <jsbronder@cold-front.org>, Jacob Keller <jacob.e.keller@intel.com>, Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250929145352.110268-1-sashal@kernel.org>
+
+From: Justin Bronder <jsbronder@cold-front.org>
+
+[ Upstream commit aa6908ca3bd1e713fd6cd8d7193a008f060bf7d9 ]
+
+In Tables 8-12 and 8-22 in the X710/XXV710/XL710 datasheet, the QLEN
+description states that the maximum size of the descriptor queue is 8k
+minus 32, or 8160.
+
+Signed-off-by: Justin Bronder <jsbronder@cold-front.org>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.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>
+Link: https://lore.kernel.org/r/20231113231047.548659-2-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 55d225670def ("i40e: add validation for ring_len param")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e.h         |    1 +
+ drivers/net/ethernet/intel/i40e/i40e_ethtool.c |   25 +++++++++++++++++++------
+ 2 files changed, 20 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e.h
++++ b/drivers/net/ethernet/intel/i40e/i40e.h
+@@ -48,6 +48,7 @@
+ #define I40E_MAX_VEB                  16
+ #define I40E_MAX_NUM_DESCRIPTORS      4096
++#define I40E_MAX_NUM_DESCRIPTORS_XL710        8160
+ #define I40E_MAX_CSR_SPACE            (4 * 1024 * 1024 - 64 * 1024)
+ #define I40E_DEFAULT_NUM_DESCRIPTORS  512
+ #define I40E_REQ_DESCRIPTOR_MULTIPLE  32
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -1914,6 +1914,18 @@ static void i40e_get_drvinfo(struct net_
+               drvinfo->n_priv_flags += I40E_GL_PRIV_FLAGS_STR_LEN;
+ }
++static u32 i40e_get_max_num_descriptors(struct i40e_pf *pf)
++{
++      struct i40e_hw *hw = &pf->hw;
++
++      switch (hw->mac.type) {
++      case I40E_MAC_XL710:
++              return I40E_MAX_NUM_DESCRIPTORS_XL710;
++      default:
++              return I40E_MAX_NUM_DESCRIPTORS;
++      }
++}
++
+ static void i40e_get_ringparam(struct net_device *netdev,
+                              struct ethtool_ringparam *ring)
+ {
+@@ -1921,8 +1933,8 @@ static void i40e_get_ringparam(struct ne
+       struct i40e_pf *pf = np->vsi->back;
+       struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+-      ring->rx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
+-      ring->tx_max_pending = I40E_MAX_NUM_DESCRIPTORS;
++      ring->rx_max_pending = i40e_get_max_num_descriptors(pf);
++      ring->tx_max_pending = i40e_get_max_num_descriptors(pf);
+       ring->rx_mini_max_pending = 0;
+       ring->rx_jumbo_max_pending = 0;
+       ring->rx_pending = vsi->rx_rings[0]->count;
+@@ -1945,12 +1957,12 @@ static bool i40e_active_tx_ring_index(st
+ static int i40e_set_ringparam(struct net_device *netdev,
+                             struct ethtool_ringparam *ring)
+ {
++      u32 new_rx_count, new_tx_count, max_num_descriptors;
+       struct i40e_ring *tx_rings = NULL, *rx_rings = NULL;
+       struct i40e_netdev_priv *np = netdev_priv(netdev);
+       struct i40e_hw *hw = &np->vsi->back->hw;
+       struct i40e_vsi *vsi = np->vsi;
+       struct i40e_pf *pf = vsi->back;
+-      u32 new_rx_count, new_tx_count;
+       u16 tx_alloc_queue_pairs;
+       int timeout = 50;
+       int i, err = 0;
+@@ -1958,14 +1970,15 @@ static int i40e_set_ringparam(struct net
+       if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+               return -EINVAL;
+-      if (ring->tx_pending > I40E_MAX_NUM_DESCRIPTORS ||
++      max_num_descriptors = i40e_get_max_num_descriptors(pf);
++      if (ring->tx_pending > max_num_descriptors ||
+           ring->tx_pending < I40E_MIN_NUM_DESCRIPTORS ||
+-          ring->rx_pending > I40E_MAX_NUM_DESCRIPTORS ||
++          ring->rx_pending > max_num_descriptors ||
+           ring->rx_pending < I40E_MIN_NUM_DESCRIPTORS) {
+               netdev_info(netdev,
+                           "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d]\n",
+                           ring->tx_pending, ring->rx_pending,
+-                          I40E_MIN_NUM_DESCRIPTORS, I40E_MAX_NUM_DESCRIPTORS);
++                          I40E_MIN_NUM_DESCRIPTORS, max_num_descriptors);
+               return -EINVAL;
+       }
diff --git a/queue-5.4/mm-hugetlb-fix-folio-is-still-mapped-when-deleted.patch b/queue-5.4/mm-hugetlb-fix-folio-is-still-mapped-when-deleted.patch
new file mode 100644 (file)
index 0000000..e9b4dc6
--- /dev/null
@@ -0,0 +1,91 @@
+From stable+bounces-181998-greg=kroah.com@vger.kernel.org Tue Sep 30 00:35:44 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 18:35:35 -0400
+Subject: mm/hugetlb: fix folio is still mapped when deleted
+To: stable@vger.kernel.org
+Cc: Jinjiang Tu <tujinjiang@huawei.com>, David Hildenbrand <david@redhat.com>, Kefeng Wang <wangkefeng.wang@huawei.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, Muchun Song <muchun.song@linux.dev>, Oscar Salvador <osalvador@suse.de>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250929223535.568376-1-sashal@kernel.org>
+
+From: Jinjiang Tu <tujinjiang@huawei.com>
+
+[ Upstream commit 7b7387650dcf2881fd8bb55bcf3c8bd6c9542dd7 ]
+
+Migration may be raced with fallocating hole.  remove_inode_single_folio
+will unmap the folio if the folio is still mapped.  However, it's called
+without folio lock.  If the folio is migrated and the mapped pte has been
+converted to migration entry, folio_mapped() returns false, and won't
+unmap it.  Due to extra refcount held by remove_inode_single_folio,
+migration fails, restores migration entry to normal pte, and the folio is
+mapped again.  As a result, we triggered BUG in filemap_unaccount_folio.
+
+The log is as follows:
+ BUG: Bad page cache in process hugetlb  pfn:156c00
+ page: refcount:515 mapcount:0 mapping:0000000099fef6e1 index:0x0 pfn:0x156c00
+ head: order:9 mapcount:1 entire_mapcount:1 nr_pages_mapped:0 pincount:0
+ aops:hugetlbfs_aops ino:dcc dentry name(?):"my_hugepage_file"
+ flags: 0x17ffffc00000c1(locked|waiters|head|node=0|zone=2|lastcpupid=0x1fffff)
+ page_type: f4(hugetlb)
+ page dumped because: still mapped when deleted
+ CPU: 1 UID: 0 PID: 395 Comm: hugetlb Not tainted 6.17.0-rc5-00044-g7aac71907bde-dirty #484 NONE
+ Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x4f/0x70
+  filemap_unaccount_folio+0xc4/0x1c0
+  __filemap_remove_folio+0x38/0x1c0
+  filemap_remove_folio+0x41/0xd0
+  remove_inode_hugepages+0x142/0x250
+  hugetlbfs_fallocate+0x471/0x5a0
+  vfs_fallocate+0x149/0x380
+
+Hold folio lock before checking if the folio is mapped to avold race with
+migration.
+
+Link: https://lkml.kernel.org/r/20250912074139.3575005-1-tujinjiang@huawei.com
+Fixes: 4aae8d1c051e ("mm/hugetlbfs: unmap pages if page fault raced with hole punch")
+Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ folio -> page ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hugetlbfs/inode.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -502,13 +502,13 @@ static void remove_inode_hugepages(struc
+                       /*
+                        * If page is mapped, it was faulted in after being
+-                       * unmapped in caller.  Unmap (again) now after taking
+-                       * the fault mutex.  The mutex will prevent faults
+-                       * until we finish removing the page.
+-                       *
+-                       * This race can only happen in the hole punch case.
+-                       * Getting here in a truncate operation is a bug.
++                       * unmapped in caller or hugetlb_vmdelete_list() skips
++                       * unmapping it due to fail to grab lock.  Unmap (again)
++                       * while holding the fault mutex.  The mutex will prevent
++                       * faults until we finish removing the page.  Hold page
++                       * lock to guarantee no concurrent migration.
+                        */
++                      lock_page(page);
+                       if (unlikely(page_mapped(page))) {
+                               BUG_ON(truncate_op);
+@@ -518,8 +518,6 @@ static void remove_inode_hugepages(struc
+                                       (index + 1) * pages_per_huge_page(h));
+                               i_mmap_unlock_write(mapping);
+                       }
+-
+-                      lock_page(page);
+                       /*
+                        * We must free the huge page and remove from page
+                        * cache (remove_huge_page) BEFORE removing the
index 15ffdb97f53f1ef1f16094aa84f18e32a98c8a36..ebee21f8d065f07a44a6d2f2d865d972a5b1d334 100644 (file)
@@ -73,3 +73,9 @@ i40e-add-max-boundary-check-for-vf-filters.patch
 fbcon-fix-integer-overflow-in-fbcon_do_set_font.patch
 fbcon-fix-oob-access-in-font-allocation.patch
 mm-migrate_device-don-t-add-folio-to-be-freed-to-lru-in-migrate_device_finalize.patch
+i40e-increase-max-descriptors-for-xl710.patch
+i40e-add-validation-for-ring_len-param.patch
+i40e-fix-idx-validation-in-config-queues-msg.patch
+i40e-fix-validation-of-vf-state-in-get-resources.patch
+i40e-add-mask-to-apply-valid-bits-for-itr_idx.patch
+mm-hugetlb-fix-folio-is-still-mapped-when-deleted.patch