patch 'net/i40e/base: fix integer overflow in NVM timing logic' has been queued to stable release 24.11.7
luca.boccassi at gmail.com
luca.boccassi at gmail.com
Thu Jun 11 15:20:02 CEST 2026
Hi,
FYI, your patch has been queued to stable release 24.11.7
Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 06/13/26. So please
shout if anyone has objections.
Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.
Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable
This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/fa6ab66bcb42d2ceafa76aedac3a01786f3ec51a
Thanks.
Luca Boccassi
---
>From fa6ab66bcb42d2ceafa76aedac3a01786f3ec51a Mon Sep 17 00:00:00 2001
From: Chinh Cao <chinh.t.cao at intel.com>
Date: Tue, 19 May 2026 14:52:21 +0000
Subject: [PATCH] net/i40e/base: fix integer overflow in NVM timing logic
[ upstream commit cc145db6818caa5c39b92503deb7dcdc70430fa8 ]
Rename gtime to gtime_start/gtime_current with elapsed tracking
to avoid signed/unsigned comparison overflow. Widen sr_size from
u16 to u32 and NVM buffer offset parameters from u16 to u32.
Add helper get_elapsed_time() for wrap-safe timer arithmetic.
Fixes: c61390d94d46 ("net/i40e/base: make semaphore timeout 32-bit")
Fixes: cb593a832630 ("net/i40e/base: reduce size of time variables")
Fixes: 8db9e2a1b232 ("i40e: base driver")
Signed-off-by: Chinh Cao <chinh.t.cao at intel.com>
Signed-off-by: Ciara Loftus <ciara.loftus at intel.com>
Acked-by: Bruce Richardson <bruce.richardson at intel.com>
---
drivers/net/i40e/base/i40e_nvm.c | 67 +++++++++++++++++---------
drivers/net/i40e/base/i40e_prototype.h | 2 +-
drivers/net/i40e/base/i40e_type.h | 2 +-
drivers/net/i40e/i40e_ethdev.c | 3 +-
4 files changed, 49 insertions(+), 25 deletions(-)
diff --git a/drivers/net/i40e/base/i40e_nvm.c b/drivers/net/i40e/base/i40e_nvm.c
index 00a207ca81..fd1a987c56 100644
--- a/drivers/net/i40e/base/i40e_nvm.c
+++ b/drivers/net/i40e/base/i40e_nvm.c
@@ -49,6 +49,20 @@ enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
return ret_code;
}
+/**
+ * get_elapsed_time - Compute elapsed hardware timer ticks
+ * @from: The start timer value
+ * @to: The current timer value
+ *
+ * Returns the elapsed time as the difference between the current and start
+ * timer values. The subtraction is wrap-safe for unsigned 32-bit values,
+ * meaning it correctly handles timer wrap-around.
+ **/
+static u32 get_elapsed_time(u32 from, u32 to)
+{
+ return (u32)(to - from); /* wrap-safe */
+}
+
/**
* i40e_acquire_nvm - Generic request for acquiring the NVM ownership
* @hw: pointer to the HW structure
@@ -61,7 +75,7 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
enum i40e_aq_resource_access_type access)
{
enum i40e_status_code ret_code = I40E_SUCCESS;
- u32 gtime, timeout;
+ u32 gtime_start, gtime_current, timeout, elapsed;
u32 time_left = 0;
DEBUGFUNC("i40e_acquire_nvm");
@@ -72,10 +86,12 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
0, &time_left, NULL);
/* Reading the Global Device Timer */
- gtime = rd32(hw, I40E_GLVFGEN_TIMER);
+ gtime_start = rd32(hw, I40E_GLVFGEN_TIMER);
+ gtime_current = gtime_start;
+ elapsed = 0;
/* Store the timeout */
- hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
+ hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime_start;
if (ret_code)
i40e_debug(hw, I40E_DEBUG_NVM,
@@ -84,17 +100,20 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
if (ret_code && time_left) {
/* Poll until the current NVM owner timeouts */
- timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
- while ((s32)(gtime - timeout) < 0 && time_left) {
+ timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT);
+
+ while (elapsed < timeout && time_left) {
i40e_msec_delay(10);
- gtime = rd32(hw, I40E_GLVFGEN_TIMER);
+ gtime_current = rd32(hw, I40E_GLVFGEN_TIMER);
+ elapsed = get_elapsed_time(gtime_start, gtime_current);
ret_code = i40e_aq_request_resource(hw,
I40E_NVM_RESOURCE_ID,
access, 0, &time_left,
NULL);
if (ret_code == I40E_SUCCESS) {
hw->nvm.hw_semaphore_timeout =
- I40E_MS_TO_GTIME(time_left) + gtime;
+ I40E_MS_TO_GTIME(time_left) +
+ gtime_current;
break;
}
}
@@ -110,7 +129,6 @@ i40e_i40e_acquire_nvm_exit:
return ret_code;
}
-
/**
* i40e_acquire_nvm_ex - Specific request only for
* OID_INTEL_FLASH_INFO_TIMEOUT for acquiring the NVM ownership
@@ -121,13 +139,12 @@ i40e_i40e_acquire_nvm_exit:
* This function will request NVM ownership for reading
* via the proper Admin Command.
**/
-
enum i40e_status_code i40e_acquire_nvm_ex(struct i40e_hw *hw,
enum i40e_aq_resource_access_type access,
u32 custom_timeout)
{
enum i40e_status_code ret_code = I40E_SUCCESS;
- u32 gtime, timeout;
+ u32 gtime_start, gtime_current, timeout, elapsed;
u32 time_left = 0;
DEBUGFUNC("i40e_acquire_nvm");
@@ -138,10 +155,12 @@ enum i40e_status_code i40e_acquire_nvm_ex(struct i40e_hw *hw,
ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
0, &time_left, NULL);
/* Reading the Global Device Timer */
- gtime = rd32(hw, I40E_GLVFGEN_TIMER);
+ gtime_start = rd32(hw, I40E_GLVFGEN_TIMER);
+ gtime_current = gtime_start;
+ elapsed = 0;
/* Store the timeout */
- hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
+ hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime_start;
if (ret_code)
i40e_debug(hw, I40E_DEBUG_NVM,
@@ -151,17 +170,20 @@ enum i40e_status_code i40e_acquire_nvm_ex(struct i40e_hw *hw,
if (ret_code && time_left) {
/* Poll until the current NVM owner timeouts */
- timeout = I40E_MS_TO_GTIME(custom_timeout) + gtime;
- while ((gtime < timeout) && time_left) {
+ timeout = I40E_MS_TO_GTIME(custom_timeout);
+
+ while (elapsed < timeout && time_left) {
i40e_msec_delay(10);
- gtime = rd32(hw, I40E_GLVFGEN_TIMER);
+ gtime_current = rd32(hw, I40E_GLVFGEN_TIMER);
+ elapsed = get_elapsed_time(gtime_start, gtime_current);
ret_code = i40e_aq_request_resource(hw,
I40E_NVM_RESOURCE_ID,
access, 0, &time_left,
NULL);
if (ret_code == I40E_SUCCESS) {
hw->nvm.hw_semaphore_timeout =
- I40E_MS_TO_GTIME(time_left) + gtime;
+ I40E_MS_TO_GTIME(time_left) +
+ gtime_current;
break;
}
}
@@ -245,7 +267,7 @@ static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
* Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
**/
STATIC enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw,
- u16 offset,
+ u32 offset,
u16 *data)
{
enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
@@ -516,11 +538,12 @@ i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset,
* method. The buffer read is preceded by the NVM ownership take
* and followed by the release.
**/
-STATIC enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
+STATIC enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u32 offset,
u16 *words, u16 *data)
{
enum i40e_status_code ret_code = I40E_SUCCESS;
- u16 index, word;
+ u32 index;
+ u16 word;
DEBUGFUNC("i40e_read_nvm_buffer_srctl");
@@ -549,7 +572,7 @@ STATIC enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16
* method. The buffer read is preceded by the NVM ownership take
* and followed by the release.
**/
-STATIC enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
+STATIC enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u32 offset,
u16 *words, u16 *data)
{
enum i40e_status_code ret_code;
@@ -608,7 +631,7 @@ read_nvm_buffer_aq_exit:
* method.
**/
enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw,
- u16 offset,
+ u32 offset,
u16 *words, u16 *data)
{
if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
@@ -767,7 +790,7 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
u16 checksum_local = 0;
u16 vpd_module = 0;
u16 *data;
- u16 i = 0;
+ u32 i = 0;
DEBUGFUNC("i40e_calc_nvm_checksum");
diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
index e7e6d4c427..6f6bafa43c 100644
--- a/drivers/net/i40e/base/i40e_prototype.h
+++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -482,7 +482,7 @@ enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module,
bool last_command);
enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
u16 *data);
-enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
+enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw, u32 offset,
u16 *words, u16 *data);
enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
void *data);
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 968e1982a6..05a08b2057 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -449,7 +449,7 @@ enum i40e_aq_resource_access_type {
struct i40e_nvm_info {
u32 hw_semaphore_timeout; /* usec global time (GTIME resolution) */
u32 timeout; /* [ms] */
- u16 sr_size; /* Shadow RAM size in words */
+ u32 sr_size; /* Shadow RAM size in words */
bool blank_nvm_mode; /* is NVM empty (no FW present)*/
u16 version; /* NVM package version */
u32 eetrack; /* NVM data version */
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 619e91a0ce..abd6698ce9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -11421,7 +11421,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t *data = eeprom->data;
- uint16_t offset, length, cnt_words;
+ uint32_t offset, length;
+ uint16_t cnt_words;
int ret_code;
offset = eeprom->offset >> 1;
--
2.47.3
---
Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- - 2026-06-11 14:20:03.425848473 +0100
+++ 0053-net-i40e-base-fix-integer-overflow-in-NVM-timing-log.patch 2026-06-11 14:20:01.254746954 +0100
@@ -1 +1 @@
-From cc145db6818caa5c39b92503deb7dcdc70430fa8 Mon Sep 17 00:00:00 2001
+From fa6ab66bcb42d2ceafa76aedac3a01786f3ec51a Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit cc145db6818caa5c39b92503deb7dcdc70430fa8 ]
+
@@ -14 +15,0 @@
-Cc: stable at dpdk.org
@@ -20,4 +21,4 @@
- drivers/net/intel/i40e/base/i40e_nvm.c | 67 +++++++++++++-------
- drivers/net/intel/i40e/base/i40e_prototype.h | 2 +-
- drivers/net/intel/i40e/base/i40e_type.h | 2 +-
- drivers/net/intel/i40e/i40e_ethdev.c | 3 +-
+ drivers/net/i40e/base/i40e_nvm.c | 67 +++++++++++++++++---------
+ drivers/net/i40e/base/i40e_prototype.h | 2 +-
+ drivers/net/i40e/base/i40e_type.h | 2 +-
+ drivers/net/i40e/i40e_ethdev.c | 3 +-
@@ -26 +27 @@
-diff --git a/drivers/net/intel/i40e/base/i40e_nvm.c b/drivers/net/intel/i40e/base/i40e_nvm.c
+diff --git a/drivers/net/i40e/base/i40e_nvm.c b/drivers/net/i40e/base/i40e_nvm.c
@@ -28,2 +29,2 @@
---- a/drivers/net/intel/i40e/base/i40e_nvm.c
-+++ b/drivers/net/intel/i40e/base/i40e_nvm.c
+--- a/drivers/net/i40e/base/i40e_nvm.c
++++ b/drivers/net/i40e/base/i40e_nvm.c
@@ -214 +215 @@
-diff --git a/drivers/net/intel/i40e/base/i40e_prototype.h b/drivers/net/intel/i40e/base/i40e_prototype.h
+diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h
@@ -216,2 +217,2 @@
---- a/drivers/net/intel/i40e/base/i40e_prototype.h
-+++ b/drivers/net/intel/i40e/base/i40e_prototype.h
+--- a/drivers/net/i40e/base/i40e_prototype.h
++++ b/drivers/net/i40e/base/i40e_prototype.h
@@ -227 +228 @@
-diff --git a/drivers/net/intel/i40e/base/i40e_type.h b/drivers/net/intel/i40e/base/i40e_type.h
+diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
@@ -229,2 +230,2 @@
---- a/drivers/net/intel/i40e/base/i40e_type.h
-+++ b/drivers/net/intel/i40e/base/i40e_type.h
+--- a/drivers/net/i40e/base/i40e_type.h
++++ b/drivers/net/i40e/base/i40e_type.h
@@ -240,5 +241,5 @@
-diff --git a/drivers/net/intel/i40e/i40e_ethdev.c b/drivers/net/intel/i40e/i40e_ethdev.c
-index 100a751225..13f3c23fef 100644
---- a/drivers/net/intel/i40e/i40e_ethdev.c
-+++ b/drivers/net/intel/i40e/i40e_ethdev.c
-@@ -11357,7 +11357,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
+diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
+index 619e91a0ce..abd6698ce9 100644
+--- a/drivers/net/i40e/i40e_ethdev.c
++++ b/drivers/net/i40e/i40e_ethdev.c
+@@ -11421,7 +11421,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
More information about the stable
mailing list