From nobody Thu Jun 25 00:33:54 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (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 6194738A701 for ; Mon, 8 Jun 2026 20:31:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780950695; cv=none; b=aFIGI022mBwF0p0RxmeulADtenhvzIg8EYs1AqLBB7Fyy2pZAhDz38gsHRJVVb4Y6xbVp0sh0gtd2eIh3oFzBfT51GHgISFggMJs2zomhhAyD0viFrDKIjUmoZcUQAVzaFWDbzdJ7lxwmIY+d1smCRPtNcMknrqUW1cezI+xLXk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780950695; c=relaxed/simple; bh=g+hB/yLQ6vKKkVlN8bF6XCd8McWiw35mowG9ThCTB7Y=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=OQaLrijRKUtfK/xoTGBp8lF4mHuxpsfTFxw+HJWEM2gIrXHWNNxrb4CLanC6LgKT5XsCc57j0aWf83xiylRchdKfoSXuQtKKRdUynQDz3twISw0Z+L29FC2uSY1hK6qSrbWupblNBAlT8H/NbMuOr4rKKn5e61fZrtWLXgxHjOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=dama.to; spf=none smtp.mailfrom=dama.to; dkim=pass (2048-bit key) header.d=dama-to.20251104.gappssmtp.com header.i=@dama-to.20251104.gappssmtp.com header.b=UPhOH13r; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=dama.to Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=dama.to Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=dama-to.20251104.gappssmtp.com header.i=@dama-to.20251104.gappssmtp.com header.b="UPhOH13r" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-c858cc9870aso2530078a12.0 for ; Mon, 08 Jun 2026 13:31:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dama-to.20251104.gappssmtp.com; s=20251104; t=1780950694; x=1781555494; 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=gwfi1hNRVN18tx6MvutAXdjRReqdu40MZi3rUahoZ8o=; b=UPhOH13r6lLqSx6YrNSgIY1lhaFxRo7ZrVw9xzxUrna1VUg0TyYdTdzG55X1doURsM YrWs1reysVtG0FpYGb1MRokQauO/DRlVh2ut2R7EoO4HMaeNwmG7tHQxCgW2d3pA1O8F GVIw7ZCuPLMKhcA4g9pplMsXljeuv6Hrc6UecfpJFBkrCcFIBo1Vz6TFGSHGbVz9lLW5 6t4oBbzIOkq2hWE7tNJk5R0O1i60EFD0hitC3b9ikj0BhXzqjLuOHsM7woR/4n2Zi9/d WZFLIV1oExHYuQVYY5zuDeN4/QjI9wIxLltnD+J6IyRaj7nZyjyd+CM3dQ01GkkST81v UMMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780950694; x=1781555494; 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=gwfi1hNRVN18tx6MvutAXdjRReqdu40MZi3rUahoZ8o=; b=JH1VCygbke/ZCUDmBnRxdQ6t9WlWPYDAq+reA0ETzQCvvyGZvvT2SHdmW0peLqCTkr CzxOj3Pg3gtX5NZi7MZ82wWHggDCPDbz+nrJbv0dW6W0kWQbvT8jDOQrYlwrhCWquxr/ KBWHNTQIc70IgUSNY/af2IBve0iz0wTIYj9OyGWTZWdhs3UGw5UvwCddZLTxLBBUpiu+ 1xHdzCZU+Xv9ioPO2se8Aozg4Gi0FWlqfh0AuduwOQXeC/flRc9WN7eQ+Q/8cebjZtS9 SEweEJAu7qnMe2DRPFTnqYMxa8d95/EflShueIjVCLMtr9JZtxlGsRibF4jfm0xEElyr 0WLw== X-Forwarded-Encrypted: i=1; AFNElJ9IirgJIsZRNStjbePXV2pIV9gohuHKPUloqiQbrPqdpzwcSU0nPDCWDyxQq330BEIOhabVcf0crrRNXm0=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+veIDYtGoJGKJUsF0g7nvKFgHmcgjc7x046GZ/0L0ycg2nB+s pjp9b9brJjus803U187Pmzf4VG4meO9SkLPcLrbBzar0I2GeIDuS1Xm6tQgYETJmT6U= X-Gm-Gg: Acq92OGnQjLnfdwlW1L9Bt4xYX60KmhMkSxoz2ug2jfcAKDiovyQ6mhhX5X2Dd/Jrfg p3LMKeSX7DIRSChLD1PSanOrqwU5O+42Eqz1dw+5ewAwggQN3OokbtITC7hTCfcT+AvCkAQm2JQ ZBAv/grUg+jAbvrJJGC5d8ha+VkoGRnI2PpBaippV4E47954WEzuqZYiDZQ6GCiAQZfJVjyPKSy rkfMArbYJfp9VVrgRm2KFpOQz0T1eSOPPKijxVmPzjaqqwSJZ8VNmBjWz2t8w3ZL7b8hu+z1+MF /czU1cWUGbrj36SU1AV15B1jgtOt1lu/gdwkmo5EyDVZgZCfXy1P2pmgE3VIsraob9WwgNclHw+ T1xadcNFnduKvNAwY4Ub2h5MaWsOlwfmsPbYkzc9YifcKWgMoGx/q/OxLG9Ktg0E6iKUFdcJjLG em6NqR+JzQUuiHzD+yqrSj9RLY X-Received: by 2002:a17:902:e5ca:b0:2c0:fa52:1c47 with SMTP id d9443c01a7336-2c1ec906ca3mr146009545ad.25.1780950693780; Mon, 08 Jun 2026 13:31:33 -0700 (PDT) Received: from localhost ([2a03:2880:2ff:e::]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c164f8429fsm235533945ad.18.2026.06.08.13.31.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jun 2026 13:31:33 -0700 (PDT) From: Joe Damato To: netdev@vger.kernel.org, Michael Chan , Pavan Chebbi , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Alexei Starovoitov , Daniel Borkmann , Jesper Dangaard Brouer , John Fastabend , Stanislav Fomichev , Somnath Kotur , Andy Gospodarek Cc: horms@kernel.org, Joe Damato , linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH net] bnxt: fix head underflow on XDP head-grow Date: Mon, 8 Jun 2026 13:31:28 -0700 Message-ID: <20260608203129.920104-1-joe@dama.to> X-Mailer: git-send-email 2.52.0 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" The xdp.py test test_xdp_native_adjst_head_grow_data crashes when run on a bnxt machine (and also crashes in NIPA). It seems that the bug is an underflow in bnxt_rx_multi_page_skb, which builds the skb head: napi_build_skb(data_ptr - bp->rx_offset, rxr->rx_page_size); The problem with this expression is that in page mode rx_offset is: bp->rx_offset =3D NET_IP_ALIGN + XDP_PACKET_HEADROOM; Which evaluates (at least on x86_64) to 258. The test test_xdp_native_adjst_head_grow_data tests a case where the head is adjusted by -256. When this test runs, data_ptr is shifted to frag_start + 2 (where frag_start =3D page_address(page) + offset). Then, bnxt_rx_multi_page_skb is invoked and the napi_build_skb expression subtracts 258, landing at an address before frag_start. This could be either the previous fragment or the previous physical page when the frag_offset is < 256 (e.g. if the fragment started at offset 0). When the skb is freed, the page pool fragment reference is dropped on either the wrong page or the wrong frag of the right page. In either case, the corrupted reference count can lead to the page being prematurely recycled while still in use. Once (incorrectly) recycled, it can be handed out again and on driver teardown this would result in a double free. The commit under fixes updated this code to handle the case where the native page size is >=3D 64k, but it unintentionally broke the head grow case. To fix this, we need to do a bit of math to recover the offset if this is a page fragment since it is not passed into rx_skb_func (bnxt_rx_multi_page_skb, in this case). Once the offset is recovered, build the skb at the start of the fragment and then use skb_reserve to adjust the layout. There are two cases, the non-adjustment case and the adjustment case. In both cases, the skb is built at page_address(page) + frag_offset to account for the case where the native page size >=3D 64K and skb_reserve is called with data_ptr - (page_address(page) + frag_offset). That difference equals bp->rx_offset when data_ptr was not moved, or bp->rx_offset + xdp_adjust when XDP adjusted the head. Re-running the failing test with this commit applied causes the test to run successfully to completion. The other rx_skb_func implementations don't have this issue. Fixes: f6974b4c2d8e ("bnxt_en: Fix page pool logic for page size >=3D 64K") Signed-off-by: Joe Damato --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethern= et/broadcom/bnxt/bnxt.c index 35e1f8f663c7..448609cc1617 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1174,7 +1174,9 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct = bnxt *bp, unsigned int len =3D offset_and_len & 0xffff; struct page *page =3D data; u16 prod =3D rxr->rx_prod; + unsigned int frag_off; struct sk_buff *skb; + void *frag_start; int err; =20 err =3D bnxt_alloc_rx_data(bp, rxr, prod, GFP_ATOMIC); @@ -1185,13 +1187,15 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struc= t bnxt *bp, dma_addr -=3D bp->rx_dma_offset; dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr, rxr->rx_page_size, bp->rx_dir); - skb =3D napi_build_skb(data_ptr - bp->rx_offset, rxr->rx_page_size); + frag_off =3D dma_addr - page_pool_get_dma_addr(page); + frag_start =3D page_address(page) + frag_off; + skb =3D napi_build_skb(frag_start, rxr->rx_page_size); if (!skb) { page_pool_recycle_direct(rxr->page_pool, page); return NULL; } skb_mark_for_recycle(skb); - skb_reserve(skb, bp->rx_offset); + skb_reserve(skb, data_ptr - (u8 *)frag_start); __skb_put(skb, len); =20 return skb; base-commit: 9772589b57e44aedc240211c5c3f7a684a034d3a --=20 2.53.0-Meta