]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Wed, 4 Oct 2023 09:28:36 +0000 (05:28 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 4 Oct 2023 09:28:36 +0000 (05:28 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/i40e-always-propagate-error-value-in-i40e_set_vsi_pr.patch [new file with mode: 0644]
queue-5.4/i40e-fix-return-of-uninitialized-aq_ret-in-i40e_set_.patch [new file with mode: 0644]
queue-5.4/i40e-improve-locking-of-mac_filter_hash.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/i40e-always-propagate-error-value-in-i40e_set_vsi_pr.patch b/queue-5.4/i40e-always-propagate-error-value-in-i40e_set_vsi_pr.patch
new file mode 100644 (file)
index 0000000..b9b906c
--- /dev/null
@@ -0,0 +1,74 @@
+From eac84bb0e8dd32af4256c8d1281c418f6a8ec2c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Aug 2020 13:53:12 +0200
+Subject: i40e: always propagate error value in i40e_set_vsi_promisc()
+
+From: Stefan Assmann <sassmann@kpanic.de>
+
+[ Upstream commit b6f23d3817b965bcd6d72aab1f438ff6d16a0691 ]
+
+The for loop in i40e_set_vsi_promisc() reports errors via dev_err() but
+does not propagate the error up the call chain. Instead it continues the
+loop and potentially overwrites the reported error value.
+This results in the error being recorded in the log buffer, but the
+caller might never know anything went the wrong way.
+
+To avoid this situation i40e_set_vsi_promisc() needs to temporarily store
+the error after reporting it. This is still not optimal as multiple
+different errors may occur, so store the first error and hope that's
+the main issue.
+
+Fixes: 37d318d7805f (i40e: Remove scheduling while atomic possibility)
+Reported-by: Michal Schmidt <mschmidt@redhat.com>
+Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 291ee55b125f8..30abaf939a76f 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1198,9 +1198,9 @@ static i40e_status
+ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+                    bool unicast_enable, s16 *vl, int num_vlans)
+ {
++      i40e_status aq_ret, aq_tmp = 0;
+       struct i40e_pf *pf = vf->pf;
+       struct i40e_hw *hw = &pf->hw;
+-      i40e_status aq_ret;
+       int i;
+       /* No VLAN to set promisc on, set on VSI */
+@@ -1249,6 +1249,9 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+                               vf->vf_id,
+                               i40e_stat_str(&pf->hw, aq_ret),
+                               i40e_aq_str(&pf->hw, aq_err));
++
++                      if (!aq_tmp)
++                              aq_tmp = aq_ret;
+               }
+               aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, seid,
+@@ -1262,8 +1265,15 @@ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+                               vf->vf_id,
+                               i40e_stat_str(&pf->hw, aq_ret),
+                               i40e_aq_str(&pf->hw, aq_err));
++
++                      if (!aq_tmp)
++                              aq_tmp = aq_ret;
+               }
+       }
++
++      if (aq_tmp)
++              aq_ret = aq_tmp;
++
+       return aq_ret;
+ }
+-- 
+2.40.1
+
diff --git a/queue-5.4/i40e-fix-return-of-uninitialized-aq_ret-in-i40e_set_.patch b/queue-5.4/i40e-fix-return-of-uninitialized-aq_ret-in-i40e_set_.patch
new file mode 100644 (file)
index 0000000..b1dadfe
--- /dev/null
@@ -0,0 +1,79 @@
+From 3d74e2838b1b7eb7ce5c01b2f6282cd5b7d64dbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 13:26:38 +0200
+Subject: i40e: fix return of uninitialized aq_ret in i40e_set_vsi_promisc
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stefan Assmann <sassmann@kpanic.de>
+
+[ Upstream commit e1e1b5356eb48dce4307f5cae10e4d6d5bd3df74 ]
+
+drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c: In function ‘i40e_set_vsi_promisc’:
+drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c:1176:14: error: ‘aq_ret’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
+  i40e_status aq_ret;
+
+In case the code inside the if statement and the for loop does not get
+executed aq_ret will be uninitialized when the variable gets returned at
+the end of the function.
+
+Avoid this by changing num_vlans from int to u16, so aq_ret always gets
+set. Making this change in additional places as num_vlans should never
+be negative.
+
+Fixes: 37d318d7805f ("i40e: Remove scheduling while atomic possibility")
+Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 30abaf939a76f..37ce764ed3730 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1125,7 +1125,7 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)
+ static int __i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
+ {
+       struct i40e_mac_filter *f;
+-      int num_vlans = 0, bkt;
++      u16 num_vlans = 0, bkt;
+       hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
+               if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID)
+@@ -1161,8 +1161,8 @@ static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
+  *
+  * Called to get number of VLANs and VLAN list present in mac_filter_hash.
+  **/
+-static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, int *num_vlans,
+-                                         s16 **vlan_list)
++static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, u16 *num_vlans,
++                                  s16 **vlan_list)
+ {
+       struct i40e_mac_filter *f;
+       int i = 0;
+@@ -1196,7 +1196,7 @@ static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, int *num_vlans,
+  **/
+ static i40e_status
+ i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable,
+-                   bool unicast_enable, s16 *vl, int num_vlans)
++                   bool unicast_enable, s16 *vl, u16 num_vlans)
+ {
+       i40e_status aq_ret, aq_tmp = 0;
+       struct i40e_pf *pf = vf->pf;
+@@ -1295,7 +1295,7 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
+       i40e_status aq_ret = I40E_SUCCESS;
+       struct i40e_pf *pf = vf->pf;
+       struct i40e_vsi *vsi;
+-      int num_vlans;
++      u16 num_vlans;
+       s16 *vl;
+       vsi = i40e_find_vsi_from_id(pf, vsi_id);
+-- 
+2.40.1
+
diff --git a/queue-5.4/i40e-improve-locking-of-mac_filter_hash.patch b/queue-5.4/i40e-improve-locking-of-mac_filter_hash.patch
new file mode 100644 (file)
index 0000000..c4d5991
--- /dev/null
@@ -0,0 +1,86 @@
+From 47d4b0c7e3901cd66744a24f5ba7f0a2cec86a68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Mar 2021 10:34:30 +0100
+Subject: i40e: improve locking of mac_filter_hash
+
+From: Stefan Assmann <sassmann@kpanic.de>
+
+[ Upstream commit 8b4b06919fd66caf49fdf4fe59f9d6312cf7956d ]
+
+i40e_config_vf_promiscuous_mode() calls
+i40e_getnum_vf_vsi_vlan_filters() without acquiring the
+mac_filter_hash_lock spinlock.
+
+This is unsafe because mac_filter_hash may get altered in another thread
+while i40e_getnum_vf_vsi_vlan_filters() traverses the hashes.
+
+Simply adding the spinlock in i40e_getnum_vf_vsi_vlan_filters() is not
+possible as it already gets called in i40e_get_vlan_list_sync() with the
+spinlock held. Therefore adding a wrapper that acquires the spinlock and
+call the correct function where appropriate.
+
+Fixes: 37d318d7805f ("i40e: Remove scheduling while atomic possibility")
+Fix-suggested-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/intel/i40e/i40e_virtchnl_pf.c    | 23 ++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 1a3017e5f44c1..291ee55b125f8 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1117,12 +1117,12 @@ static int i40e_quiesce_vf_pci(struct i40e_vf *vf)
+ }
+ /**
+- * i40e_getnum_vf_vsi_vlan_filters
++ * __i40e_getnum_vf_vsi_vlan_filters
+  * @vsi: pointer to the vsi
+  *
+  * called to get the number of VLANs offloaded on this VF
+  **/
+-static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
++static int __i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
+ {
+       struct i40e_mac_filter *f;
+       int num_vlans = 0, bkt;
+@@ -1135,6 +1135,23 @@ static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
+       return num_vlans;
+ }
++/**
++ * i40e_getnum_vf_vsi_vlan_filters
++ * @vsi: pointer to the vsi
++ *
++ * wrapper for __i40e_getnum_vf_vsi_vlan_filters() with spinlock held
++ **/
++static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi)
++{
++      int num_vlans;
++
++      spin_lock_bh(&vsi->mac_filter_hash_lock);
++      num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi);
++      spin_unlock_bh(&vsi->mac_filter_hash_lock);
++
++      return num_vlans;
++}
++
+ /**
+  * i40e_get_vlan_list_sync
+  * @vsi: pointer to the VSI
+@@ -1152,7 +1169,7 @@ static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, int *num_vlans,
+       int bkt;
+       spin_lock_bh(&vsi->mac_filter_hash_lock);
+-      *num_vlans = i40e_getnum_vf_vsi_vlan_filters(vsi);
++      *num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi);
+       *vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC);
+       if (!(*vlan_list))
+               goto err;
+-- 
+2.40.1
+
index 4e7d5ff123d85c13f3594ab5f98d9bac3f88ee88..0845206a42d78796b7116fb8977d7f66a2a09179 100644 (file)
@@ -67,3 +67,6 @@ fbdev-sh7760fb-depend-on-fb-y.patch
 nvme-pci-do-not-set-the-numa-node-of-device-if-it-ha.patch
 watchdog-itco_wdt-no-need-to-stop-the-timer-in-probe.patch
 watchdog-itco_wdt-set-no_reboot-if-the-watchdog-is-n.patch
+i40e-improve-locking-of-mac_filter_hash.patch
+i40e-always-propagate-error-value-in-i40e_set_vsi_pr.patch
+i40e-fix-return-of-uninitialized-aq_ret-in-i40e_set_.patch