From nobody Mon Sep 28 02:07:47 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1785208735; cv=none; d=zohomail.com; s=zohoarc; b=PHh5SCfOUfBceQrwqrqYU7f0pNoID+POo8SYXVnVA9FPO86gNYgtr/C6wNcrBXidSlqz3FIcTjIK6zhCwj3gjOsz0Y932qiUygGPmQ/zO8pivUUikfyhUcOXzExFb663/lKdMPbQozt/ho0Xp73ZT3tP+Z4e1kHKJKC9qDRMUs8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785208735; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=eAsvla5tQhA1spQqTDncWeqaXeCjHrIHBvdG7EtAFEQ=; b=KCNTU+K+edSC3y8K0PmZNf0GORxauRU2+oFPLNb87lRUH3QnAKub6YsMt07eobu4JbHhpFlWELsM8b196yJe6nb2V+NB0JSIUDXPxI+WrvvFeE7H/viPCwMMZ6Ig7jj42lazbUr3udrCYyBO77uuUh2liXMZEYu1L5isI3lHA9c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785208735872177.59679724228363; Mon, 27 Jul 2026 20:18:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1woYKZ-0003IC-Dc; Mon, 27 Jul 2026 23:18:11 -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 1woYKX-0003Hu-7X for qemu-devel@nongnu.org; Mon, 27 Jul 2026 23:18:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1woYKV-0005Wa-OK for qemu-devel@nongnu.org; Mon, 27 Jul 2026 23:18:08 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-208-XGbrgoa0OiCCtA2aVfoXWA-1; Mon, 27 Jul 2026 23:18:05 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4055B18007EC; Tue, 28 Jul 2026 03:18:03 +0000 (UTC) Received: from gshan-thinkpadx1nanogen2.rmtau.csb (unknown [10.64.136.50]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 21D855B2; Tue, 28 Jul 2026 03:17:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785208686; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eAsvla5tQhA1spQqTDncWeqaXeCjHrIHBvdG7EtAFEQ=; b=M3u36zBUBRWMdNyzC1q0ZGUMyBpCSzy+sTSrRG2rE8NxNgDSTQLa8r1JDQgAcf8pMfp8fP TJLyHW3asmjvD8SDsQHKRFkuP2Y+UvvGZTXi0WnZMEcAnR4RDTBnUQuXvdCpWBibGFHUd3 tIomcpluUo4182rJuqUE9PyEIo0wrS4= X-MC-Unique: XGbrgoa0OiCCtA2aVfoXWA-1 X-Mimecast-MFC-AGG-ID: XGbrgoa0OiCCtA2aVfoXWA_1785208683 From: Gavin Shan To: qemu-arm@nongnu.org Cc: qemu-devel@nongnu.org, peterx@redhat.com, mst@redhat.com, philmd@oss.qualcomm.com, peter.maydell@linaro.org, richard.henderson@linaro.org, alex@shazbot.org, berrange@redhat.com, philmd@mailo.com, david@kernel.org, clg@redhat.com, pbonzini@redhat.com, phrdina@redhat.com, jugraham@redhat.com, liugang24219@sangfor.com.cn, dinghui@sangfor.com.cn, shan.gavin@gmail.com Subject: [PATCH v5 1/3] system/memory: Use memmove() for directly accessible regions Date: Tue, 28 Jul 2026 13:17:29 +1000 Message-ID: <20260728031731.286666-2-gshan@redhat.com> In-Reply-To: <20260728031731.286666-1-gshan@redhat.com> References: <20260728031731.286666-1-gshan@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 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=170.10.133.124; envelope-from=gshan@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -36 X-Spam_score: -3.7 X-Spam_bar: --- X-Spam_report: (-3.7 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.58, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1785208737154158500 Content-Type: text/plain; charset="utf-8" Similar to what's done in commit 4a73aee88140 ("softmmu: Use memmove in flatview_write_continue"), there are more sites where the overlapping source and destination buffer are allowed for the directly accessible regions. Use memmove() in those sites, listed as below. hw/remote/vfio-user-obj.c::vfu_object_mr_rw include/system/memory.h::address_space_read system/physmem.c::flatview_read_continue_step Signed-off-by: Gavin Shan Reviewed-by: Peter Maydell Reviewed-by: Peter Xu Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/remote/vfio-user-obj.c | 4 ++-- include/system/memory.h | 2 +- system/physmem.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index 87fa7b6572..ea50270628 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -375,9 +375,9 @@ static int vfu_object_mr_rw(MemoryRegion *mr, uint8_t *= buf, hwaddr offset, ram_ptr =3D memory_region_get_ram_ptr(mr); =20 if (is_write) { - memcpy((ram_ptr + offset), buf, size); + memmove((ram_ptr + offset), buf, size); } else { - memcpy(buf, (ram_ptr + offset), size); + memmove(buf, (ram_ptr + offset), size); } =20 return 0; diff --git a/include/system/memory.h b/include/system/memory.h index 2192fc9bdc..336d4e84a6 100644 --- a/include/system/memory.h +++ b/include/system/memory.h @@ -2741,7 +2741,7 @@ MemTxResult address_space_read(const AddressSpace *as= , hwaddr addr, mr =3D flatview_translate(fv, addr, &addr1, &l, false, attrs); if (len =3D=3D l && memory_access_is_direct(mr, false, attrs))= { ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); - memcpy(buf, ptr, len); + memmove(buf, ptr, len); } else { result =3D flatview_read_continue(fv, addr, attrs, buf, le= n, addr1, l, mr); diff --git a/system/physmem.c b/system/physmem.c index c21ea92915..2c42e365cb 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -3363,7 +3363,7 @@ static MemTxResult flatview_read_continue_step(MemTxA= ttrs attrs, uint8_t *buf, uint8_t *ram_ptr =3D qemu_ram_ptr_length(mr->ram_block, mr_addr, l, false, false); =20 - memcpy(buf, ram_ptr, *l); + memmove(buf, ram_ptr, *l); =20 return MEMTX_OK; } --=20 2.55.0 From nobody Mon Sep 28 02:07:47 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1785208728; cv=none; d=zohomail.com; s=zohoarc; b=JGFMAwAnpD6oZjVQ+8seH3GvymtG6agCYR7nJujE+jX0wWUU42xHW52el2b9tK8ANgjsgrhKQW64kSVhVoJhUbgmbrLhSpJ6lugUxsIGH7vbm5WS6Ocpm8EUJbqNC5JsfyZ+GK2sfPh/6B7Kv/xG/yWrcAZ+zzlI4Oc9qk4VQGo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785208728; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ASUGxUCA4QZ2aQU6sSdjSxM8dSAshvNHAeWheHGZUK8=; b=U+uYsUc1YWZobQyicofv629wM3KjiDgi67KFbx/1ZxUTnbpvvRBC1igg+3gtzTq6KBUADkEDeqhiQp1GBjmJPQk98I/mm5ZWSkStZGxuNOdjEPUcIzNfEgy9VcfnVKmrU0pmB3reDA6jFqTTwcsPF5Nh/LU8iZRdhsU46C9aajw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785208728894986.7576723916142; Mon, 27 Jul 2026 20:18:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1woYKm-0003Jq-CG; Mon, 27 Jul 2026 23:18:24 -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 1woYKk-0003JS-Sj for qemu-devel@nongnu.org; Mon, 27 Jul 2026 23:18:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1woYKi-0005XB-SU for qemu-devel@nongnu.org; Mon, 27 Jul 2026 23:18:22 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-336-TIQrMKkCPxCEjXQ-c0-ybg-1; Mon, 27 Jul 2026 23:18:15 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9377E1954B28; Tue, 28 Jul 2026 03:18:13 +0000 (UTC) Received: from gshan-thinkpadx1nanogen2.rmtau.csb (unknown [10.64.136.50]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2316F5B2; Tue, 28 Jul 2026 03:18:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785208700; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ASUGxUCA4QZ2aQU6sSdjSxM8dSAshvNHAeWheHGZUK8=; b=aVdXeoe9ozS8x0znegrE/SIse5vYBoziAtH0kdan6r5RgVX8R5Wy8R3FcW16goejYxGvQJ 2bzbZjkuvzI2tkjmnZccA5XPYb8FOa+TZ6XceeOUH/1A/mpCou//zu6iYZlyHLgcyv+Zp7 QVRmRltZ0fXQBYKMi7f3gFvPKPUFG2Q= X-MC-Unique: TIQrMKkCPxCEjXQ-c0-ybg-1 X-Mimecast-MFC-AGG-ID: TIQrMKkCPxCEjXQ-c0-ybg_1785208694 From: Gavin Shan To: qemu-arm@nongnu.org Cc: qemu-devel@nongnu.org, peterx@redhat.com, mst@redhat.com, philmd@oss.qualcomm.com, peter.maydell@linaro.org, richard.henderson@linaro.org, alex@shazbot.org, berrange@redhat.com, philmd@mailo.com, david@kernel.org, clg@redhat.com, pbonzini@redhat.com, phrdina@redhat.com, jugraham@redhat.com, liugang24219@sangfor.com.cn, dinghui@sangfor.com.cn, shan.gavin@gmail.com Subject: [PATCH v5 2/3] system/memory: Use qemu_ram_move() for directly accessible regions Date: Tue, 28 Jul 2026 13:17:30 +1000 Message-ID: <20260728031731.286666-3-gshan@redhat.com> In-Reply-To: <20260728031731.286666-1-gshan@redhat.com> References: <20260728031731.286666-1-gshan@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 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=170.10.133.124; envelope-from=gshan@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -2 X-Spam_score: -0.3 X-Spam_bar: / X-Spam_report: (-0.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.58, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action 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-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1785208731552158500 Content-Type: text/plain; charset="utf-8" All ram device regions were turned to be indirectly accessible by commit 4a2e242bbb ("memory: Don't use memcpy for ram_device regions"). This leads to guest hang on attempt to build 'cuda-samples' as reported by Julia. The guest is started by the following command lines, with GH100 GPU card passed from the host. host$ lspci | grep GH100 0009:01:00.0 3D controller: NVIDIA Corporation GH100 [GH200 120GB / 480G= B] (rev a1) host$ /home/sandbox/gavin/qemu.main/build/qemu-system-aarch64 = \ -machine virt,gic-version=3Dhost,ras=3Don,highmem-mmio-size=3D4T = \ -accel kvm -cpu host -smp cpus=3D48 -m size=3D8G = \ -drive file=3D/home/gavin/sandbox/images/disk.qcow2,if=3Dnone,id= =3Dd0 \ -device virtio-blk-pci,id=3Dvb0,bus=3Dpcie.0,drive=3Dd0,num-queues= =3D4 \ -device vfio-pci-nohotplug,host=3D0009:01:00.0,bus=3Dpcie.1.0 : guest$ cd cuda-samples/build guest$ make -j 20 clean guest$ make -j 20 : [ 54%] Linking CUDA executable graphMemoryNodes [ 54%] Built target graphMemoryNodes guest$ qemu-system-aarch64: virtio: bogus descriptor or out of resources [ 555.814025] virtio_blk virtio0: [vda] new size: 268435456 512-byte lo= gical blocks (137 GB/128 GiB) When the GPU's driver (NVidia open driver) is loaded on guest bootup, the memory blocks residing in the PCI BAR#4 of the GH100 GPU card can be presented to the guest through memory hot-add. The page cache can then be allocated from the hot added memory blocks when cuda-samples is being built. Afterwards, the page cache is sent to QEMU's virtio-blk device as part of the DMA request, the bounce buffer has to be used to accomodate the request as the corresponding memory region (MemoryRegion) is an indirectly accessible ram device region in qemu. However, the max bounce bufer size is only 4096 bytes by default and that is exhausted quickly, leading to a reset on the virtio-blk device and frozen guest eventually. QEMU =3D=3D=3D=3D virtio_blk_handle_output virtio_blk_handle_vq virtio_blk_get_request virtqueue_pop virtqueue_split_pop virtqueue_map_desc address_space_map memory_access_is_direct # Return false memory_region_supports_direct_access (qemu) info mtree memory-region: pci_bridge_pci 0000000000000000-ffffffffffffffff (prio 0, container): pci_bridge_pci 0000042000000000-0000043fffffffff (prio 1, i/o): 0009:01:00.0 base BA= R 4 0000042000000000-0000043fffffffff (prio 0, i/o): 0009:01:00.0 BAR 4 0000042000000000-000004379fffffff (prio 0, ramd): 0009:01:00.0 BA= R 4 mmaps[0] This adds qemu_ram_move() where the aligned and small-sized accesses are handled by qatomics, and fall back to memmove() otherwise. The memove() for the directly accessible regions is replaced by qemu_ram_move() so that the issue covered by commit 4a2e242bbb (MMIO access instructions were optimized to SSE instructions) is fixed. This makes 'ram_device_mem_ops' redundant, paving the way to revert that commit to make the ram device region directly accessible again in the next patch. Besides, this also fixes the issue of the unexpected frozen reception on e1000 NIC in the scenario of DPDK due to the wrong Rx queue full indication caused by the following memcpy(), which is turned to 3 consective 'strb' instructions to the same location by glibc-2.24+ for aarch64. With this applied, the syntax of one-byte store is strictly ensured by a one-byte qatomic set. QEMU =3D=3D=3D=3D e1000_receive_iov pci_dma_write pci_dma_rw dma_memory_rw dma_memory_rw_relaxed address_space_rw address_space_write flatview_write flatview_write_continue flatview_write_continue_step memcpy # 3 consective 'strb' instructions Reported-by: Julia Graham Reported-by: Liu Gang Reported-by: Ding Hui Suggested-by: Michael S. Tsirkin Suggested-by: Peter Xu Suggested-by: Richard Henderson Suggested-by: Peter Maydell Signed-off-by: Gavin Shan --- v5: Improved commit log and comments to qemu_ram_move() --- hw/remote/vfio-user-obj.c | 4 ++-- include/system/memory.h | 35 ++++++++++++++++++++++++++++++- system/physmem.c | 43 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index ea50270628..a0498d218f 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -375,9 +375,9 @@ static int vfu_object_mr_rw(MemoryRegion *mr, uint8_t *= buf, hwaddr offset, ram_ptr =3D memory_region_get_ram_ptr(mr); =20 if (is_write) { - memmove((ram_ptr + offset), buf, size); + qemu_ram_move((ram_ptr + offset), buf, size); } else { - memmove(buf, (ram_ptr + offset), size); + qemu_ram_move(buf, (ram_ptr + offset), size); } =20 return 0; diff --git a/include/system/memory.h b/include/system/memory.h index 336d4e84a6..2965d922de 100644 --- a/include/system/memory.h +++ b/include/system/memory.h @@ -2668,6 +2668,39 @@ void address_space_register_map_client(AddressSpace = *as, QEMUBH *bh); void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh); =20 /* Internal functions, part of the implementation of address_space_read. = */ + +/** + * qemu_ram_move: move data from or to ramblock + * + * @dst: destination where the data is moved to + * @src: source where the data is moved from + * @n: length of data to be moved + * + * Move @n bytes from @src to @dst, the memory areas may overlap. This + * provides the same semantics as memmove(), plus an additional stronger + * guarantee: if @n is 1, 2 or 4 or 8 bytes, and @src and @dst are both + * naturally aligned for that access size, and the memory areas do not + * overlap, then both the load and the store will be done as a single + * atomic access (with the semantics of qatomic_read() and qatomic_set()). + * + * This is the underlying function that we use to implement accesses by + * a guest vCPU or a device DMA operation to a ram block. The atomic + * guarantee is needed for two major cases: (A) When the ram block is + * backed by a PCI BAR passed through from a host device (and so it might + * be hardware registers that must be accessed exactly once at the right + * width); (B) When an emulated device updates a data structure shared in + * guest memory with guest software (e.g. a network device's set of tx and + * rx descriptor blocks), if a write to memory is accidentally performed + * multiple times then it can break the guest code when it busy polls the + * guest memory. + * + * We don't attempt to perform the exact access when it would be unaligned + * because this can't be done on all host architectures. Although this is + * strictly speaking not doing what would happen on real hardware, we don't + * think there are going to be situations where that matters in practice. + */ +void qemu_ram_move(void *dst, const void *src, size_t n); + MemTxResult address_space_read_full(const AddressSpace *as, hwaddr addr, MemTxAttrs attrs, void *buf, hwaddr le= n); MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, @@ -2741,7 +2774,7 @@ MemTxResult address_space_read(const AddressSpace *as= , hwaddr addr, mr =3D flatview_translate(fv, addr, &addr1, &l, false, attrs); if (len =3D=3D l && memory_access_is_direct(mr, false, attrs))= { ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); - memmove(buf, ptr, len); + qemu_ram_move(buf, ptr, len); } else { result =3D flatview_read_continue(fv, addr, attrs, buf, le= n, addr1, l, mr); diff --git a/system/physmem.c b/system/physmem.c index 2c42e365cb..fbe7df2391 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -3158,6 +3158,45 @@ void memory_region_flush_rom_device(MemoryRegion *mr= , hwaddr addr, hwaddr size) invalidate_and_set_dirty(mr, addr, size); } =20 +void qemu_ram_move(void *dst, const void *src, size_t n) +{ + uintptr_t test, len; + + if (src =3D=3D dst || n =3D=3D 0) { + return; + } + + /* + * Maximal length of aligned access that are determined by @src, + * @dst and @n + */ + test =3D (uintptr_t)src | (uintptr_t)dst | n; + len =3D test & -test; + + /* Overlapping buffers, unaligned or oversized access */ + if (n > 8 || len !=3D n) { + memmove(dst, src, n); + return; + } + + switch (len) { + case 1: + qatomic_set((uint8_t *)dst, qatomic_read((uint8_t *)src)); + break; + case 2: + qatomic_set((uint16_t *)dst, qatomic_read((uint16_t *)src)); + break; + case 4: + qatomic_set((uint32_t *)dst, qatomic_read((uint32_t *)src)); + break; + case 8: + qatomic_set((uint64_t *)dst, qatomic_read((uint64_t *)src)); + break; + default: + g_assert_not_reached(); + } +} + int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) { unsigned access_size_max =3D mr->ops->valid.max_access_size; @@ -3270,7 +3309,7 @@ static MemTxResult flatview_write_continue_step(MemTx= Attrs attrs, uint8_t *ram_ptr =3D qemu_ram_ptr_length(mr->ram_block, mr_addr, l, false, true); =20 - memmove(ram_ptr, buf, *l); + qemu_ram_move(ram_ptr, buf, *l); invalidate_and_set_dirty(mr, mr_addr, *l); =20 return MEMTX_OK; @@ -3363,7 +3402,7 @@ static MemTxResult flatview_read_continue_step(MemTxA= ttrs attrs, uint8_t *buf, uint8_t *ram_ptr =3D qemu_ram_ptr_length(mr->ram_block, mr_addr, l, false, false); =20 - memmove(buf, ram_ptr, *l); + qemu_ram_move(buf, ram_ptr, *l); =20 return MEMTX_OK; } --=20 2.55.0 From nobody Mon Sep 28 02:07:47 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1785208754; cv=none; d=zohomail.com; s=zohoarc; b=J0eTI3sTxFZbXxLTQs6mk3guhyqAQ9EHhal2cbBUGY7CA+QrJtRppP86dumi9GZ8hDe0SqmWX9cMcDfwaDpY8Pjvkzj/VCJzA/s+fWes2YwK4dWqoxKrLzHgQOYfi9H30VYk6SVj5I1EGfFUNi7juKbthdf3ckEMXEA9W4XQrqs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785208754; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=8sCFvVSDQ3//CPWi+9BWF+8046Ug5/Bej/Dzg+yFmRY=; b=TNFN1YLptrsx1J8DHtYqrB3Np7xZWhzg7LM4uZCIZjx0C+DD9YpvY77B6Bi0T7gCfxfow6v5IYy0FfHJAf+xS5fc7gNJaJs/vwdw++BJmgUHMxgzIN6IJbfZYH4iJxU5iS7LTf0h5dYkPYk2+IweuayRe213h/oShDWR8chWRLo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785208754897765.5086606109289; Mon, 27 Jul 2026 20:19:14 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1woYKu-0003LE-Ti; Mon, 27 Jul 2026 23:18:32 -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 1woYKt-0003Kq-EY for qemu-devel@nongnu.org; Mon, 27 Jul 2026 23:18:31 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1woYKr-0005XZ-Tp for qemu-devel@nongnu.org; Mon, 27 Jul 2026 23:18:31 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-169-YUNT_ExDNgGMtjONsMzlIQ-1; Mon, 27 Jul 2026 23:18:25 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 621B91956079; Tue, 28 Jul 2026 03:18:23 +0000 (UTC) Received: from gshan-thinkpadx1nanogen2.rmtau.csb (unknown [10.64.136.50]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4059E5B2; Tue, 28 Jul 2026 03:18:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1785208709; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8sCFvVSDQ3//CPWi+9BWF+8046Ug5/Bej/Dzg+yFmRY=; b=H8WNOkd2gOpUBBZ4ZkAlOhjY5JvGSC04Y3ckqYoI/3UHG1gi8kqXhzdHN9d+9zj43EoR4K AIw5htLLifKe7A/g/dUL0fDGG+sUYxPdyx1vHCNz0jQGGXW/eBO6MLpJJltKNDTSczDX5N x1eKmqeSKb7lCEaapXKFfFvOxq345jU= X-MC-Unique: YUNT_ExDNgGMtjONsMzlIQ-1 X-Mimecast-MFC-AGG-ID: YUNT_ExDNgGMtjONsMzlIQ_1785208703 From: Gavin Shan To: qemu-arm@nongnu.org Cc: qemu-devel@nongnu.org, peterx@redhat.com, mst@redhat.com, philmd@oss.qualcomm.com, peter.maydell@linaro.org, richard.henderson@linaro.org, alex@shazbot.org, berrange@redhat.com, philmd@mailo.com, david@kernel.org, clg@redhat.com, pbonzini@redhat.com, phrdina@redhat.com, jugraham@redhat.com, liugang24219@sangfor.com.cn, dinghui@sangfor.com.cn, shan.gavin@gmail.com Subject: [PATCH v5 3/3] system/memory: Make ram device region directly accessible Date: Tue, 28 Jul 2026 13:17:31 +1000 Message-ID: <20260728031731.286666-4-gshan@redhat.com> In-Reply-To: <20260728031731.286666-1-gshan@redhat.com> References: <20260728031731.286666-1-gshan@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 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=170.10.129.124; envelope-from=gshan@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -2 X-Spam_score: -0.3 X-Spam_bar: / X-Spam_report: (-0.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.58, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action 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-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1785208760807158500 Content-Type: text/plain; charset="utf-8" This basically reverts 4a2e242bbb30 ("memory: Don't use memcpy for ram_device regions") to make ram device region directly accessible again. With this, the bounce buffer is bypassed in address_space_map() when a ram device region is involved, potentially avoid to overrun the (small) bounce buffer. Reported-by: Julia Graham Suggested-by: Michael S. Tsirkin Suggested-by: Peter Xu Suggested-by: Richard Henderson Suggested-by: Peter Maydell Signed-off-by: Gavin Shan Reviewed-by: Peter Maydell --- include/system/memory.h | 11 ++--------- system/memory.c | 41 +---------------------------------------- system/trace-events | 2 -- 3 files changed, 3 insertions(+), 51 deletions(-) diff --git a/include/system/memory.h b/include/system/memory.h index 2965d922de..dbc17741ac 100644 --- a/include/system/memory.h +++ b/include/system/memory.h @@ -2718,15 +2718,8 @@ static inline bool memory_region_supports_direct_acc= ess(const MemoryRegion *mr) if (memory_region_is_romd(mr)) { return true; } - if (!memory_region_is_ram(mr)) { - return false; - } - /* - * RAM DEVICE regions can be accessed directly using memcpy, but it mi= ght - * be MMIO and access using mempy can be wrong (e.g., using instructio= ns not - * intended for MMIO access). So we treat this as IO. - */ - return !memory_region_is_ram_device(mr); + + return memory_region_is_ram(mr); } =20 static inline bool memory_access_is_direct(const MemoryRegion *mr, diff --git a/system/memory.c b/system/memory.c index 5fc36708ec..da710bbade 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1364,43 +1364,6 @@ const MemoryRegionOps unassigned_mem_ops =3D { .endianness =3D DEVICE_NATIVE_ENDIAN, }; =20 -static uint64_t memory_region_ram_device_read(void *opaque, - hwaddr addr, unsigned size) -{ - MemoryRegion *mr =3D opaque; - uint64_t data =3D ldn_he_p(mr->ram_block->host + addr, size); - - trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, s= ize); - - return data; -} - -static void memory_region_ram_device_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size) -{ - MemoryRegion *mr =3D opaque; - - trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, = size); - - stn_he_p(mr->ram_block->host + addr, size, data); -} - -static const MemoryRegionOps ram_device_mem_ops =3D { - .read =3D memory_region_ram_device_read, - .write =3D memory_region_ram_device_write, - .endianness =3D HOST_BIG_ENDIAN ? DEVICE_BIG_ENDIAN : DEVICE_LITTLE_EN= DIAN, - .valid =3D { - .min_access_size =3D 1, - .max_access_size =3D 8, - .unaligned =3D true, - }, - .impl =3D { - .min_access_size =3D 1, - .max_access_size =3D 8, - .unaligned =3D true, - }, -}; - bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, @@ -1692,10 +1655,8 @@ void memory_region_init_ram_device_ptr(MemoryRegion = *mr, Object *owner, const char *name, uint64_t size, void *ptr) { - memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size); - mr->ram =3D true; + memory_region_init_ram_ptr(mr, owner, name, size, ptr); mr->ram_device =3D true; - memory_region_set_ram_ptr(mr, size, ptr); } =20 void memory_region_init_alias(MemoryRegion *mr, Object *owner, diff --git a/system/trace-events b/system/trace-events index 51b4a4679a..d483b31419 100644 --- a/system/trace-events +++ b/system/trace-events @@ -20,8 +20,6 @@ memory_region_ops_read(int cpu_index, void *mr, uint64_t = addr, uint64_t value, u memory_region_ops_write(int cpu_index, void *mr, uint64_t addr, uint64_t v= alue, unsigned size, const char *name) "cpu %d mr %p addr 0x%"PRIx64" value= 0x%"PRIx64" size %u name '%s'" memory_region_subpage_read(int cpu_index, void *mr, uint64_t offset, uint6= 4_t value, unsigned size) "cpu %d mr %p offset 0x%"PRIx64" value 0x%"PRIx64= " size %u" memory_region_subpage_write(int cpu_index, void *mr, uint64_t offset, uint= 64_t value, unsigned size) "cpu %d mr %p offset 0x%"PRIx64" value 0x%"PRIx6= 4" size %u" -memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint= 64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64"= size %u" -memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uin= t64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64= " size %u" memory_region_sync_dirty(const char *mr, const char *listener, int global)= "mr '%s' listener '%s' synced (global=3D%d)" flatview_new(void *view, void *root) "%p (root %p)" flatview_destroy(void *view, void *root) "%p (root %p)" --=20 2.55.0