From: Sasha Levin Date: Wed, 4 Oct 2023 09:28:36 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v6.5.6~38 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f3b7b39dd143d261c60d914f1f70b05dbe0a2d5;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- 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 index 00000000000..b9b906c84a4 --- /dev/null +++ b/queue-5.4/i40e-always-propagate-error-value-in-i40e_set_vsi_pr.patch @@ -0,0 +1,74 @@ +From eac84bb0e8dd32af4256c8d1281c418f6a8ec2c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Aug 2020 13:53:12 +0200 +Subject: i40e: always propagate error value in i40e_set_vsi_promisc() + +From: Stefan Assmann + +[ 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 +Signed-off-by: Stefan Assmann +Tested-by: Aaron Brown +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b1dadfe233b --- /dev/null +++ b/queue-5.4/i40e-fix-return-of-uninitialized-aq_ret-in-i40e_set_.patch @@ -0,0 +1,79 @@ +From 3d74e2838b1b7eb7ce5c01b2f6282cd5b7d64dbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Jakub Kicinski +Tested-by: Aaron Brown +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c4d5991980f --- /dev/null +++ b/queue-5.4/i40e-improve-locking-of-mac_filter_hash.patch @@ -0,0 +1,86 @@ +From 47d4b0c7e3901cd66744a24f5ba7f0a2cec86a68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Mar 2021 10:34:30 +0100 +Subject: i40e: improve locking of mac_filter_hash + +From: Stefan Assmann + +[ 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 +Signed-off-by: Stefan Assmann +Tested-by: Konrad Jankowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-5.4/series b/queue-5.4/series index 4e7d5ff123d..0845206a42d 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -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