Blob Blame History Raw
From: Jacob Keller <jacob.e.keller@intel.com>
Date: Tue, 31 Jul 2018 03:41:48 -0700
Subject: i40e: fix i40e_add_queue_stats data pointer update
Patch-mainline: v4.19-rc1
Git-commit: 333e2f2cea6cbffd75aa4969afad7409d7fad74c
References: bsc#1111981 FATE#326312 FATE#326313

This function accidentally failed to update the data pointer, which
caused the reported stats to be incorrect. Additionally, statistics
which follow queue stats in the output would potentially read non-zeroed
garbage data from the ethtool buffer.

This occurred because the data double pointer was not dereferenced
before incrementing the size.

Additionally, make sure this issue is more visible by adding a WARN_ONCE
to the i40e_get_ethtool_stats function. This warning will trigger
whenever the data pointer is not at the expected address, similar to the
check that we make in the i40e_get_stat_strings() function.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1883,6 +1883,7 @@ static void i40e_get_ethtool_stats(struc
 	unsigned int i;
 	unsigned int start;
 	bool veb_stats;
+	u64 *p = data;
 
 	i40e_update_stats(vsi);
 
@@ -1925,7 +1926,7 @@ static void i40e_get_ethtool_stats(struc
 	}
 	rcu_read_unlock();
 	if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
-		return;
+		goto check_data_pointer;
 
 	veb_stats = ((pf->lan_veb != I40E_NO_VEB) &&
 		     (pf->flags & I40E_FLAG_VEB_STATS_ENABLED));
@@ -1948,6 +1949,10 @@ static void i40e_get_ethtool_stats(struc
 
 		i40e_add_ethtool_stats(&data, &pfc, i40e_gstrings_pfc_stats);
 	}
+
+check_data_pointer:
+	WARN_ONCE(data - p != i40e_get_stats_count(netdev),
+		  "ethtool stats count mismatch!");
 }
 
 /**