From nobody Tue Feb 10 05:45:24 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=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1770067366; cv=none; d=zohomail.com; s=zohoarc; b=nSCQAvHckFCRfrGl82WxUjGdKKPggygRgE7EDvcIlwJwUqfHpeYIVa+cyewDscJzTciWe3tjMlYtr0akOgH4aM4YaR38VT6crzWcn7XqUwQoxTCp3zyeRoK3mAjFnGiRDo9yeZBpwFOLfLiSMgYc9M64YQEDQC00EIQ2AB/hLyw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770067366; h=Content-Type:Content-Transfer-Encoding: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:Cc; bh=WuWggxfl7YWGc0iIVpyLoNSrAHblpQuEzJfAm/Kjzwc=; b=WH+YZftfBr892BJQE7mSdFlA3MdQHxtXRdVWmlQ5I+vruAo4gT5nHj9v1y2CKLv+6GOcMO1YoBcC3QI5tVuIuC3NrWpR8P5tbt+xVBhZkdZioUTtAurL7pgWQIVeGz/lAHLU73x5LgH3qhSODxA4rYC3j10xtTNxeQVZiQWJo5M= 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=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1770067365877171.72848264077538; Mon, 2 Feb 2026 13:22:45 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vn1N1-00057U-MX; Mon, 02 Feb 2026 16:22:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vn1Mi-00053j-KG for qemu-devel@nongnu.org; Mon, 02 Feb 2026 16:21:49 -0500 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vn1Me-0007Ps-U2 for qemu-devel@nongnu.org; Mon, 02 Feb 2026 16:21:47 -0500 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-4807068eacbso41294445e9.2 for ; Mon, 02 Feb 2026 13:21:40 -0800 (PST) Received: from localhost.localdomain (88-187-86-199.subs.proxad.net. [88.187.86.199]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435e131cfd4sm44575192f8f.25.2026.02.02.13.21.37 for (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 02 Feb 2026 13:21:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1770067298; x=1770672098; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=WuWggxfl7YWGc0iIVpyLoNSrAHblpQuEzJfAm/Kjzwc=; b=DjNfFtzRkAT5Oi9cZMsQuACeLKLEwHX97ZdaWB/8FNv2HO3Y83AAwKHj3vAma3HgU2 FoVlVO8bV1T6EoMLEpSntgSAjJTcE01HB7hWkM6UaGzACbEwJJtN7WbpnUCcccuKS6h1 tREq9iHCesYiD2E6cpITqozgdPc7lyI7uV6GWxZsYGjZbK+Murt1qP8f2N0Pn/mBxnDn 20z1f/RNDQof53g+JokNwOF/F4XYfSkKsBfZhfmbLPzBz++XgnWb8sCQ3R0T+5glriBA IssSVLlekDV+3Vt8udooqIRmjjNioFhP2+35XpmRTIbvGLuoN9EPtymiqf/CXMjK/TAT cJpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770067298; x=1770672098; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=WuWggxfl7YWGc0iIVpyLoNSrAHblpQuEzJfAm/Kjzwc=; b=VH9XkXoKlOmUhiFRrRv7kY8x4qM0UNeLj0vWWyuh7aYQH9Lr51SduUI065BFDZYpUP DntIaRl3qXz4acbx3xyapT5S8T+bvLlSSn2Mg3jobwX0WHcQerpVf0VUCTjR2l3nLeKP hsi9my+f4HNQMJ12ePwfzqJRaKKeWLiBOH5w5DeFfzPuUrQQVXFGXpd7GyIKY+itII/E 06LzPtDRN3htAQbGiSZACDRgddGhF8Nh8QZ5Gj2bVHb6kKwnG+e06RzWaI4DTSzEZHDr mA3I6xpiv1JDLkoSj0UnH0p9WynGwCFfGk2qoUTFJV+Npm2cKeK2yi0rzlKNg/2y7ABH iqAA== X-Gm-Message-State: AOJu0YyN9V+p4jHjX4j3UlcNvhAczzu36+nXMuLj7e6gfDP3TSCDsjwJ nUhLwOQSRVMlDnCbLERYDM7RaMB4+6N0/ocIDW9Fm7aqnAqqKlA8iyJ9GWHsMTBZxzP7M9+C7h5 6orwjaDE= X-Gm-Gg: AZuq6aLnW2WRLXCkrv/pSHl10UotIRxDEvjSyO7hSIGUKCxCFodDnY2OFVUow30YZCe Hez/u0gpEKeMkf29t2amp+ukWIR2oqHwC4osJlwmMjLZpzhXtJTfZ/edLiyG44I8D9991cX6oRq s5YDekOKEhaQDEqi3JqZfPwE1rWUMMtFRDZvWCXFhJJVZlSivOKkbLlTcfgUwlE1ba2j69CcQvx ZfDP4jKE6AeDhwuD/TKdbH/bnT11ZwPLCOu3TFrKKNORlmsndLv/r5IGW5FG+D2XVLwS/JxN0r2 NDbC4pXCiRkABpaq3M4rg6ioR5C2lmJZkNSshsV9vYVCLWAEBJpqxU1duE+IoZ3/7CSy27eKiQt XRtLrYtpFBYEVf3aSdYbAYDx5NMOIp2RnIRlqu2M6qqviNjoqZ/TyoeezOYs2uU5RkxKGugxs7k G4U79i0QlvkS7WDTlrK7hbfS9cXV8iPhSvtT+1sjZw/wUFcVUuveS0DzkXXc2r X-Received: by 2002:a05:600c:a00a:b0:480:4a90:1b00 with SMTP id 5b1f17b1804b1-482db47d460mr168420295e9.20.1770067298426; Mon, 02 Feb 2026 13:21:38 -0800 (PST) From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Subject: [PULL 11/16] accel/tcg: Fix iotlb_to_section() for different AddressSpace Date: Mon, 2 Feb 2026 22:20:14 +0100 Message-ID: <20260202212019.94205-12-philmd@linaro.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260202212019.94205-1-philmd@linaro.org> References: <20260202212019.94205-1-philmd@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::32e; envelope-from=philmd@linaro.org; helo=mail-wm1-x32e.google.com X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_SBL=1.623 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 @linaro.org) X-ZM-MESSAGEID: 1770067368941154100 From: Jim Shu 'CPUTLBEntryFull.xlat_section' stores section_index in last 12 bits to find the correct section when CPU access the IO region over the IOTLB. However, section_index is only unique inside single AddressSpace. If address space translation is over IOMMUMemoryRegion, it could return section from other AddressSpace. 'iotlb_to_section()' API only finds the sections from CPU's AddressSpace so that it couldn't find section in other AddressSpace. Thus, using 'iotlb_to_section()' API will find the wrong section and QEMU will have wrong load/store access. To fix this bug of iotlb_to_section(), store complete MemoryRegionSection pointer in CPUTLBEntryFull to replace the section_index in xlat_section. Rename 'xlat_section' to 'xlat' as we remove last 12 bits section_index inside. Also, since we directly use section pointer in the CPUTLBEntryFull (full->section), we can remove the unused functions: iotlb_to_section(), memory_region_section_get_iotlb(). This bug occurs only when (1) IOMMUMemoryRegion is in the path of CPU access. (2) IOMMUMemoryRegion returns different target_as and the section is in the IO region. Common IOMMU devices don't have this issue since they are only in the path of DMA access. Currently, the bug only occurs when ARM MPC device (hw/misc/tz-mpc.c) returns 'blocked_io_as' to emulate blocked access handling. Upcoming RISC-V wgChecker [1] and IOPMP [2] devices are also affected by this bug. [1] RISC-V WG: https://patchew.org/QEMU/20251021155548.584543-1-jim.shu@sifive.com/ [2] RISC-V IOPMP: https://patchew.org/QEMU/20250312093735.1517740-1-ethan84@andestech.com/ Signed-off-by: Jim Shu Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Mark Burton Reviewed-by: Pierrick Bouvier Message-ID: <20260128152348.2095427-3-jim.shu@sifive.com> Signed-off-by: Philippe Mathieu-Daud=C3=A9 --- include/accel/tcg/iommu.h | 15 --------------- include/exec/cputlb.h | 4 ++-- include/hw/core/cpu.h | 17 +++++++++-------- accel/tcg/cputlb.c | 22 ++++++++++------------ system/physmem.c | 25 ------------------------- 5 files changed, 21 insertions(+), 62 deletions(-) diff --git a/include/accel/tcg/iommu.h b/include/accel/tcg/iommu.h index 90cfd6c0ed1..547f8ea0ef0 100644 --- a/include/accel/tcg/iommu.h +++ b/include/accel/tcg/iommu.h @@ -14,18 +14,6 @@ #include "exec/hwaddr.h" #include "exec/memattrs.h" =20 -/** - * iotlb_to_section: - * @cpu: CPU performing the access - * @index: TCG CPU IOTLB entry - * - * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that - * it refers to. @index will have been initially created and returned - * by memory_region_section_get_iotlb(). - */ -MemoryRegionSection *iotlb_to_section(CPUState *cpu, - hwaddr index, MemTxAttrs attrs); - MemoryRegionSection *address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, @@ -34,8 +22,5 @@ MemoryRegionSection *address_space_translate_for_iotlb(CP= UState *cpu, MemTxAttrs attrs, int *prot); =20 -hwaddr memory_region_section_get_iotlb(CPUState *cpu, - MemoryRegionSection *section); - #endif =20 diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index 0d1d46429c9..3a9603a6965 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -44,8 +44,8 @@ void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr= _t length); * @full: the details of the tlb entry * * Add an entry to @cpu tlb index @mmu_idx. All of the fields of - * @full must be filled, except for xlat_section, and constitute - * the complete description of the translated page. + * @full must be filled, except for xlat_offset & section, and + * constitute the complete description of the translated page. * * This is generally called by the target tlb_fill function after * having performed a successful page table walk to find the physical diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 61da2ea4331..98678704a64 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -219,15 +219,16 @@ typedef uint32_t MMUIdxMap; */ struct CPUTLBEntryFull { /* - * @xlat_section contains: - * - in the lower TARGET_PAGE_BITS, a physical section number - * - with the lower TARGET_PAGE_BITS masked off, an offset which - * must be added to the virtual address to obtain: - * + the ram_addr_t of the target RAM (if the physical section - * number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM) - * + the offset within the target MemoryRegion (otherwise) + * @xlat_offset: TARGET_PAGE_BITS aligned offset which must be added to + * the virtual address to obtain: + * + the ram_addr_t of the target RAM (if the physical section + * number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM) + * + the offset within the target MemoryRegion (otherwise) */ - hwaddr xlat_section; + hwaddr xlat_offset; + + /* @section contains physical section. */ + MemoryRegionSection *section; =20 /* * @phys_addr contains the physical address in the address space diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 82c9b6389dc..76546c66515 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1090,7 +1090,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, } } else { /* I/O or ROMD */ - iotlb =3D memory_region_section_get_iotlb(cpu, section) + xlat; + iotlb =3D xlat; /* * Writes to romd devices must go through MMIO to enable write. * Reads to romd devices go through the ram_ptr found above, @@ -1141,10 +1141,9 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, /* * When memory region is ram, iotlb contains a TARGET_PAGE_BITS * aligned ram_addr_t of the page base of the target RAM. - * Otherwise, iotlb contains - * - a physical section number in the lower TARGET_PAGE_BITS - * - the offset within section->mr of the page base (I/O, ROMD) with = the - * TARGET_PAGE_BITS masked off. + * Otherwise, iotlb contains a TARGET_PAGE_BITS aligned + * offset within section->mr of the page base (I/O, ROMD) + * * We subtract addr_page (which is page aligned and thus won't * disturb the low bits) to give an offset which can be added to the * (non-page-aligned) vaddr of the eventual memory access to get @@ -1154,7 +1153,8 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, */ desc->fulltlb[index] =3D *full; full =3D &desc->fulltlb[index]; - full->xlat_section =3D iotlb - addr_page; + full->xlat_offset =3D iotlb - addr_page; + full->section =3D section; full->phys_addr =3D paddr_page; =20 /* Now calculate the new entry */ @@ -1276,8 +1276,8 @@ io_prepare(hwaddr *out_offset, CPUState *cpu, CPUTLBE= ntryFull *full, MemoryRegionSection *section; hwaddr mr_offset; =20 - section =3D iotlb_to_section(cpu, full->xlat_section, attrs); - mr_offset =3D (full->xlat_section & TARGET_PAGE_MASK) + addr; + section =3D full->section; + mr_offset =3D full->xlat_offset + addr; cpu->mem_io_pc =3D retaddr; if (!cpu->neg.can_do_io) { cpu_io_recompile(cpu, retaddr); @@ -1336,7 +1336,7 @@ static bool victim_tlb_hit(CPUState *cpu, size_t mmu_= idx, size_t index, static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size, CPUTLBEntryFull *full, uintptr_t retaddr) { - ram_addr_t ram_addr =3D mem_vaddr + full->xlat_section; + ram_addr_t ram_addr =3D mem_vaddr + full->xlat_offset; =20 trace_memory_notdirty_write_access(mem_vaddr, ram_addr, size); =20 @@ -1593,9 +1593,7 @@ bool tlb_plugin_lookup(CPUState *cpu, vaddr addr, int= mmu_idx, =20 /* We must have an iotlb entry for MMIO */ if (tlb_addr & TLB_MMIO) { - MemoryRegionSection *section =3D - iotlb_to_section(cpu, full->xlat_section & ~TARGET_PAGE_MASK, - full->attrs); + MemoryRegionSection *section =3D full->section; data->is_io =3D true; data->mr =3D section->mr; } else { diff --git a/system/physmem.c b/system/physmem.c index b0311f45312..d17596a77fb 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -747,31 +747,6 @@ translate_fail: return &d->map.sections[PHYS_SECTION_UNASSIGNED]; } =20 -MemoryRegionSection *iotlb_to_section(CPUState *cpu, - hwaddr index, MemTxAttrs attrs) -{ - int asidx =3D cpu_asidx_from_attrs(cpu, attrs); - CPUAddressSpace *cpuas =3D &cpu->cpu_ases[asidx]; - AddressSpaceDispatch *d =3D address_space_to_dispatch(cpuas->as); - int section_index =3D index & ~TARGET_PAGE_MASK; - MemoryRegionSection *ret; - - assert(section_index < d->map.sections_nb); - ret =3D d->map.sections + section_index; - assert(ret->mr); - assert(ret->mr->ops); - - return ret; -} - -/* Called from RCU critical section */ -hwaddr memory_region_section_get_iotlb(CPUState *cpu, - MemoryRegionSection *section) -{ - AddressSpaceDispatch *d =3D flatview_to_dispatch(section->fv); - return section - d->map.sections; -} - #endif /* CONFIG_TCG */ =20 void cpu_address_space_init(CPUState *cpu, int asidx, --=20 2.52.0