From nobody Fri Apr 17 07:13:24 2026 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4593A1FE47B for ; Tue, 24 Feb 2026 05:45:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771911941; cv=none; b=UVY7/O5XqxIq5JHOP7aARRJZflldKelR/5V58sQp7ZZyV3zFzWXpVApVP0WnNFAcCoxomZghjYrHXZpYsMkxzsF01solQccE5K5Ng4RQsZIUQ9w1/LqyqWG6Tks6IxVNoJFTcNQKjQcm1HAyPJSq9Yj31e55vzIs5RcHXPRORhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771911941; c=relaxed/simple; bh=FOCU7ky6atLZJIqo4lqdbHNvOqA+ZkuKyKkbuO881Zo=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=QmvnfNe+ifUIV/7Wzp+FJy85GvIZv+rAFEyIAdQ20Wov2vJX6q7QZ/941N95Z4uo+DpcY5xMhbHEMd7nQtARMI6BslHagZQmBXVv++jvU49rqZLbNnYVgDn7XY8Kf7TbiDO1AR38ar5NFr55VvNmfkPjFULu+YJ6si5h1kqwTfo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=E+bjJesk; arc=none smtp.client-ip=209.85.214.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="E+bjJesk" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-2a9296b3926so35582855ad.1 for ; Mon, 23 Feb 2026 21:45:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771911939; x=1772516739; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Uq//eKnU0VIy+iDlWT3coRvXqAavfDjJ0UDudhoedEQ=; b=E+bjJeskrcTMXJBRoFNNND6nPWkHroLBekPCAmqr4mS5uRU7lXguBrX8bYPMHI4XA3 N/jyARIVxUzM4yoGPiHneXKBX159CeYEf5yuYIUll+HoR63U+liaklDQMv+Aip4n9nGK iKncDOrlgiWT308a/6TsLs4z/gDFOwvgJbx72MTRlMzTj/U8Fiwd+J65QajwrKC3dxEo iGBQWu7ZdX2MjJuW6I0hrL6rVrvMk8HD21djfx9IW8PcRpxTwo5f5TA84pdXAMPaQv6a Bbgh9JD8YdG+zKufbn3PMtqkNMUHXnh9YbkydcNql6uMEWIycbgxZLMbQQGFOUl7DOUE S68A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771911939; x=1772516739; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Uq//eKnU0VIy+iDlWT3coRvXqAavfDjJ0UDudhoedEQ=; b=FSmx21gyjZyevv7cJXM8/P3u6ULkJsSUixqaSAwVTeW3mzBVTUZb+zHXU0HZglmwEt kFsK9brTYWjTx2yRvR0XHoeD0fhvt+6y5WGCj9IyA3fXAqOzvx/OdP3XorSQ7BsuzvT3 LAChfOUasgJwO4Eu998xPxlOc/qlnl67AjbmLrQvfKAEAJ5ruhODAmeiZcr01Cv6qJd7 iCQev5zeebe2VG6tlJDTPhjGP87DRiGweIhMSq8ZX0/AAJ07/bp2X+nFem+d0SSNNh0R dXv/X6Nrk5b7fISy1BPMFS0rCioPE6yxsHmOweeNWlAbw01B6pIFGnoOlDMakOoAR/+L Ol1w== X-Forwarded-Encrypted: i=1; AJvYcCXWF8+3eO2CCBCPPidL0vVdzFy5LbUe0TXJHBKrB39kySA5I2+sMWfpzPLYn3uwtbl7jUwGK9a2w86EZo4=@vger.kernel.org X-Gm-Message-State: AOJu0Yxfc6C2Bz3+N+kMPBV+FRWNO7+2qCjifQDWcb6kxXdiI3e+Vry5 iEkuPDkpPKc6Vlw18W4b/qzLmE8TfNsAmNu8pbTn4iETGrf9IlLlaNzP X-Gm-Gg: ATEYQzyNHKzswQVftRpIUA7hUg0PYNySaxsnHDPysQqCI66pxKkz0yKKrhyd4E1GbEF pZ/Rzno4MeKQLOrPrNx0aQRbXOa9z94mkhA+gQfaQabcTVRwkCC4hvzxGhinSNqDZmKMJUTVF2G T7gX7iX1180j2LB1uXmWDmrRGNTC7vmQ5h3zfXSgQFkxot7esTfkkQWReIGR8a7bauYwEeJQ2Xd id/aTE3wf0n5ATjsJcrZ09Y04xsBaFWEONsTm8N8vz8lqwp+8wSNpPIJ+GIa6UvdCh03fUh8i9O qYKFtNJDTBYalDZFZ37AKPCDN57H3DpE7fh89tHvLbCoip8mOWn5aIsP8/c8WfkTwJ1SwX/DUMB AWVmoLcPXOD+Z2VfjLLRv+fOW6+jBZKI2ZsLC1MAH1C0CV5CKuU2ag4wN5yKNEY2kCfXvdPwbHP NWFGYdqZC84LXJdlKO7+Y/eFujnzhL9kWGYxfWLtsGvNPls0pAIPV6HFmYKanddJk63Z/XPxHWR y75Hr3GIzWy X-Received: by 2002:a17:902:ea02:b0:2a9:602c:159 with SMTP id d9443c01a7336-2ad74438618mr91322915ad.19.1771911939394; Mon, 23 Feb 2026 21:45:39 -0800 (PST) Received: from dpc2500057.. (fsb6a9315e.tkyc502.ap.nuro.jp. [182.169.49.94]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ad7500e062sm125920765ad.48.2026.02.23.21.45.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 21:45:39 -0800 (PST) From: Keita Morisaki To: Tony Nguyen , Przemek Kitszel , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Alice Michael , Aleksandr Loktionov , Maciej Fijalkowski , Paul Greenwalt , intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Keita Morisaki Subject: [PATCH net v2 RESEND] ice: fix race condition in TX timestamp ring cleanup Date: Tue, 24 Feb 2026 14:45:33 +0900 Message-Id: <20260224054533.3372943-1-kmta1236@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix a race condition between ice_free_tx_tstamp_ring() and ice_tx_map() that can cause a NULL pointer dereference. ice_free_tx_tstamp_ring currently clears the ICE_TX_FLAGS_TXTIME flag after NULLing the tstamp_ring. This could allow a concurrent ice_tx_map call on another CPU to dereference the tstamp_ring, which could lead to a NULL pointer dereference. CPU A:ice_free_tx_tstamp_ring() | CPU B:ice_tx_map() --------------------------------|--------------------------------- tx_ring->tstamp_ring =3D NULL | | ice_is_txtime_cfg() -> true | tstamp_ring =3D tx_ring->tstamp_ring | tstamp_ring->count // NULL deref! flags &=3D ~ICE_TX_FLAGS_TXTIME | Fix by: 1. Reordering ice_free_tx_tstamp_ring() to clear the flag before NULLing the pointer, with smp_wmb() to ensure proper ordering. 2. Adding smp_rmb() in ice_tx_map() after the flag check to order the flag read before the pointer read, using READ_ONCE() for the pointer, and adding a NULL check as a safety net. 3. Converting tx_ring->flags from u8 to DECLARE_BITMAP() and using atomic bitops (set_bit(), clear_bit(), test_bit()) for all flag operations throughout the driver: - ICE_TX_RING_FLAGS_XDP - ICE_TX_RING_FLAGS_VLAN_L2TAG1 - ICE_TX_RING_FLAGS_VLAN_L2TAG2 - ICE_TX_RING_FLAGS_TXTIME Fixes: ccde82e909467 ("ice: add E830 Earliest TxTime First Offload support") Signed-off-by: Keita Morisaki Reviewed-by: Aleksandr Loktionov Tested-by: Rinitha S (A Contingent worker at Intel) --- Changes in v2: - Convert tx_ring->flags from u8 to DECLARE_BITMAP() and use atomic bitops (set_bit(), clear_bit(), test_bit()) for all flag operations instead of WRITE_ONCE() for flag updates - Rename flags from ICE_TX_FLAGS_RING_* to ICE_TX_RING_FLAGS_* to distinguish from per-packet flags (ICE_TX_FLAGS_*) drivers/net/ethernet/intel/ice/ice.h | 4 ++-- drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 2 +- drivers/net/ethernet/intel/ice/ice_lib.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_txrx.c | 23 ++++++++++++++------ drivers/net/ethernet/intel/ice/ice_txrx.h | 16 +++++++++----- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/in= tel/ice/ice.h index 00f75d87c73f9..5baeca824cd99 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -753,7 +753,7 @@ static inline bool ice_is_xdp_ena_vsi(struct ice_vsi *v= si) =20 static inline void ice_set_ring_xdp(struct ice_tx_ring *ring) { - ring->flags |=3D ICE_TX_FLAGS_RING_XDP; + set_bit(ICE_TX_RING_FLAGS_XDP, ring->flags); } =20 /** @@ -778,7 +778,7 @@ static inline bool ice_is_txtime_ena(const struct ice_t= x_ring *ring) */ static inline bool ice_is_txtime_cfg(const struct ice_tx_ring *ring) { - return !!(ring->flags & ICE_TX_FLAGS_TXTIME); + return test_bit(ICE_TX_RING_FLAGS_TXTIME, ring->flags); } =20 /** diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/eth= ernet/intel/ice/ice_dcb_lib.c index 9fc8681cc58ea..bd74344271f3f 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c @@ -943,7 +943,7 @@ ice_tx_prepare_vlan_flags_dcb(struct ice_tx_ring *tx_ri= ng, /* if this is not already set it means a VLAN 0 + priority needs * to be offloaded */ - if (tx_ring->flags & ICE_TX_FLAGS_RING_VLAN_L2TAG2) + if (test_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG2, tx_ring->flags)) first->tx_flags |=3D ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN; else first->tx_flags |=3D ICE_TX_FLAGS_HW_VLAN; diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/etherne= t/intel/ice/ice_lib.c index d47af94f31a99..55ff0708d136e 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1412,9 +1412,9 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi) ring->count =3D vsi->num_tx_desc; ring->txq_teid =3D ICE_INVAL_TEID; if (dvm_ena) - ring->flags |=3D ICE_TX_FLAGS_RING_VLAN_L2TAG2; + set_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG2, ring->flags); else - ring->flags |=3D ICE_TX_FLAGS_RING_VLAN_L2TAG1; + set_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG1, ring->flags); WRITE_ONCE(vsi->tx_rings[i], ring); } =20 diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethern= et/intel/ice/ice_txrx.c index ad76768a42323..564e4e33ecbc3 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -190,9 +190,10 @@ void ice_free_tstamp_ring(struct ice_tx_ring *tx_ring) void ice_free_tx_tstamp_ring(struct ice_tx_ring *tx_ring) { ice_free_tstamp_ring(tx_ring); + clear_bit(ICE_TX_RING_FLAGS_TXTIME, tx_ring->flags); + smp_wmb(); /* order flag clear before pointer NULL */ kfree_rcu(tx_ring->tstamp_ring, rcu); - tx_ring->tstamp_ring =3D NULL; - tx_ring->flags &=3D ~ICE_TX_FLAGS_TXTIME; + WRITE_ONCE(tx_ring->tstamp_ring, NULL); } =20 /** @@ -405,7 +406,7 @@ static int ice_alloc_tstamp_ring(struct ice_tx_ring *tx= _ring) tx_ring->tstamp_ring =3D tstamp_ring; tstamp_ring->desc =3D NULL; tstamp_ring->count =3D ice_calc_ts_ring_count(tx_ring); - tx_ring->flags |=3D ICE_TX_FLAGS_TXTIME; + set_bit(ICE_TX_RING_FLAGS_TXTIME, tx_ring->flags); return 0; } =20 @@ -1519,13 +1520,20 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_= tx_buf *first, return; =20 if (ice_is_txtime_cfg(tx_ring)) { - struct ice_tstamp_ring *tstamp_ring =3D tx_ring->tstamp_ring; - u32 tstamp_count =3D tstamp_ring->count; - u32 j =3D tstamp_ring->next_to_use; + struct ice_tstamp_ring *tstamp_ring; + u32 tstamp_count, j; struct ice_ts_desc *ts_desc; struct timespec64 ts; u32 tstamp; =20 + smp_rmb(); /* order flag read before pointer read */ + tstamp_ring =3D READ_ONCE(tx_ring->tstamp_ring); + if (unlikely(!tstamp_ring)) + goto ring_kick; + + tstamp_count =3D tstamp_ring->count; + j =3D tstamp_ring->next_to_use; + ts =3D ktime_to_timespec64(first->skb->tstamp); tstamp =3D ts.tv_nsec >> ICE_TXTIME_CTX_RESOLUTION_128NS; =20 @@ -1553,6 +1561,7 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx= _buf *first, tstamp_ring->next_to_use =3D j; writel_relaxed(j, tstamp_ring->tail); } else { +ring_kick: writel_relaxed(i, tx_ring->tail); } return; @@ -1812,7 +1821,7 @@ ice_tx_prepare_vlan_flags(struct ice_tx_ring *tx_ring= , struct ice_tx_buf *first) */ if (skb_vlan_tag_present(skb)) { first->vid =3D skb_vlan_tag_get(skb); - if (tx_ring->flags & ICE_TX_FLAGS_RING_VLAN_L2TAG2) + if (test_bit(ICE_TX_RING_FLAGS_VLAN_L2TAG2, tx_ring->flags)) first->tx_flags |=3D ICE_TX_FLAGS_HW_OUTER_SINGLE_VLAN; else first->tx_flags |=3D ICE_TX_FLAGS_HW_VLAN; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethern= et/intel/ice/ice_txrx.h index e440c55d9e9f0..d35ffdc3dc84d 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -181,6 +181,14 @@ enum ice_rx_dtype { ICE_RX_DTYPE_SPLIT_ALWAYS =3D 2, }; =20 +enum ice_tx_ring_flags { + ICE_TX_RING_FLAGS_XDP, + ICE_TX_RING_FLAGS_VLAN_L2TAG1, + ICE_TX_RING_FLAGS_VLAN_L2TAG2, + ICE_TX_RING_FLAGS_TXTIME, + ICE_TX_RING_FLAGS_NBITS, +}; + struct ice_pkt_ctx { u64 cached_phctime; __be16 vlan_proto; @@ -333,11 +341,7 @@ struct ice_tx_ring { u32 txq_teid; /* Added Tx queue TEID */ /* CL4 - 4th cacheline starts here */ struct ice_tstamp_ring *tstamp_ring; -#define ICE_TX_FLAGS_RING_XDP BIT(0) -#define ICE_TX_FLAGS_RING_VLAN_L2TAG1 BIT(1) -#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2) -#define ICE_TX_FLAGS_TXTIME BIT(3) - u8 flags; + DECLARE_BITMAP(flags, ICE_TX_RING_FLAGS_NBITS); u8 dcb_tc; /* Traffic class of ring */ u16 quanta_prof_id; } ____cacheline_internodealigned_in_smp; @@ -349,7 +353,7 @@ static inline bool ice_ring_ch_enabled(struct ice_tx_ri= ng *ring) =20 static inline bool ice_ring_is_xdp(struct ice_tx_ring *ring) { - return !!(ring->flags & ICE_TX_FLAGS_RING_XDP); + return test_bit(ICE_TX_RING_FLAGS_XDP, ring->flags); } =20 enum ice_container_type { base-commit: 18f7fcd5e69a04df57b563360b88be72471d6b62 --=20 2.34.1