From nobody Sat May 30 17:35:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=sangfor.com.cn Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1779888215082389.95881596508843; Wed, 27 May 2026 06:23:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSEDp-0001WM-Ah; Wed, 27 May 2026 09:23:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wSAVp-0008Jn-G9 for qemu-devel@nongnu.org; Wed, 27 May 2026 05:25:19 -0400 Received: from mail-m8166.xmail.ntesmail.com ([156.224.81.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wSAVj-0001Za-Q8 for qemu-devel@nongnu.org; Wed, 27 May 2026 05:25:16 -0400 Received: from localhost.localdomain (unknown [43.247.70.80]) by smtp.qiye.163.com (Hmail) with ESMTP id 4004fb7bd; Wed, 27 May 2026 17:17:50 +0800 (GMT+08:00) From: Liu Gang To: qemu-devel@nongnu.org Cc: jasowang@redhat.com, LiuGang , Ding Hui Subject: [PATCH] hw/net/e1000: Use address_space_stb for Rx descriptor status write on aarch64 Date: Wed, 27 May 2026 17:17:11 +0800 Message-Id: <20260527091711.3901-1-liugang24219@sangfor.com.cn> X-Mailer: git-send-email 2.36.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-HM-Tid: 0a9e68b9cc2003abkunm5521e4672ea553 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVlCGBkZVk8YGR9LSk0YTRhNTVYVFA kWGhdVEwETFhoSFyQUDg9ZV1kYEgtZQVlPSFVJT0xVTEtVQ0tZV1kWGg8SFR0UWUFZT0tIVUpLSE pPSExVSktLVUpCS0tZBg++ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=156.224.81.66; envelope-from=liugang24219@sangfor.com.cn; helo=mail-m8166.xmail.ntesmail.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 27 May 2026 09:22:45 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1779888216431158500 Content-Type: text/plain; charset="utf-8" From: LiuGang In x86 environments, writing the Rx descriptor status byte with a single pci_dma_write() works correctly. However, on aarch64 with glibc 2.24+, the memcpy/memmove implementation uses a branchless sequence that copies the same byte three times when count =3D=3D 1. This results in three consecutive STRB operations. Ref: https://sourceware.org/git/?p=3Dglibc.git;a=3Dblob;f=3Dsysdeps/aarch64= /memcpy.S;hb=3Drefs/heads/release/2.24/master#l124 When the guest uses an e1000 NIC and DPDK, this behavior can cause packet reception to stop or packets to be dropped repeatedly. Under normal operation, DPDK clears the DD flag after processing a packet and then updates RDT. But due to the triple STRB from memcpy/memmove, the DD flag may be cleared and then immediately set again. This causes DPDK to consume the same packet twice, making RDT be incremented by one extra. As a result, RDH =3D=3D RDT, and QEMU mistakenly considers the receive queue full, stopping packet reception. The issue can be reproduced on aarch64 using the adapted test program: https://github.com/cdkey/e1000_poc Replace pci_dma_write() with address_space_stb() to write the DD status byte directly, avoiding the problematic memcpy/memmove sequence and resolving the issue. Fixes: 034d00d48581("e1000: set RX descriptor status in a separate operation") Signed-off-by: Liu Gang Signed-off-by: Ding Hui --- hw/net/e1000.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 202ad40401..f7be035e0f 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -869,6 +869,14 @@ e1000_receiver_overrun(E1000State *s, size_t size) set_ics(s, 0, E1000_ICS_RXO); } =20 +static inline void +e1000_dma_write_byte(PCIDevice *d, dma_addr_t addr, uint8_t val) +{ + AddressSpace *as =3D pci_get_address_space(d); + dma_barrier(as, DMA_DIRECTION_FROM_DEVICE); + address_space_stb(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); +} + static ssize_t e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) { @@ -980,8 +988,8 @@ e1000_receive_iov(NetClientState *nc, const struct iove= c *iov, int iovcnt) } pci_dma_write(d, base, &desc, sizeof(desc)); desc.status |=3D (vlan_status | E1000_RXD_STAT_DD); - pci_dma_write(d, base + offsetof(struct e1000_rx_desc, status), - &desc.status, sizeof(desc.status)); + e1000_dma_write_byte(d, base + offsetof(struct e1000_rx_desc, stat= us), + desc.status); =20 if (++s->mac_reg[RDH] * sizeof(desc) >=3D s->mac_reg[RDLEN]) s->mac_reg[RDH] =3D 0; --=20 2.36.0.windows.1