From nobody Tue Nov 4 15:26:28 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530216464649957.9094288303129; Thu, 28 Jun 2018 13:07:44 -0700 (PDT) Received: from localhost ([::1]:38290 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYdCf-0000MR-Le for importer@patchew.org; Thu, 28 Jun 2018 16:07:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37774) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYdAM-00072d-OW for qemu-devel@nongnu.org; Thu, 28 Jun 2018 16:05:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fYdAK-0008NM-C3 for qemu-devel@nongnu.org; Thu, 28 Jun 2018 16:05:18 -0400 Received: from mail-wr0-x231.google.com ([2a00:1450:400c:c0c::231]:32829) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fYdAK-0008Lm-1B for qemu-devel@nongnu.org; Thu, 28 Jun 2018 16:05:16 -0400 Received: by mail-wr0-x231.google.com with SMTP id k7-v6so3188824wrq.0 for ; Thu, 28 Jun 2018 13:05:15 -0700 (PDT) Received: from 640k.lan ([82.84.124.111]) by smtp.gmail.com with ESMTPSA id 127-v6sm6211110wmd.18.2018.06.28.13.05.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Jun 2018 13:05:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=wMlfOQHFDxi+nN5eTRbhhKF/fvLQk/+6e3NvTS/+AaI=; b=lZbjP6Y7G0TlZwbk/GgA0mwVi4+RXw8Yvc6BIzFSjTKfMut7N8+CZf6ix8Scr1cF4T T/4qFK795Cr4E7bHiYReg1vEe+2EyMJo1Bt6Ix6nfiOIElDbznQpVg53gfnNfVMbSB5h vB9ZBtdz6z1hMVUf/Fd1OSngalqe4dIIU5+FdRkKM8URRmnDF2nAiiRZ/rZ/hpMUU9ch lOcFlLf85SLkZLjRqV2y8nKWqncONlilhdmor7Fqg33smLf6r3G9F3p7YP7KdaGBwTnT pDE13KcKzNSR94CB0MgadnjEPxLMZ3nA0tx0Kuy3JIAcnVybgUjGZx960BdxSD2kD4jt WtJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=wMlfOQHFDxi+nN5eTRbhhKF/fvLQk/+6e3NvTS/+AaI=; b=kKbJ6zyqVoY9016PM1VZQK25jPGFUw5zqaX05+NNlu7zPuur7EQ+8/qGeSm0Z9F5mn FVyi7MKdz4ABcm4Bh6mD5i6OaWqY30GWlda/h3SfojvMVmgFXhz+oTwKfE+U71Jv+4Ap x695BDqYWgyV34EY/ecSA/onr8XnuTESyMEL9WObViop+DG/xqeskqklXUrApQLQwOSz lEGkKdaooCy1LJJPudL/CQcCXRajCarlq82zUwIi3n8GFARkHhe8o6wDfKnXlVYZ+IWO 3Hgp8bQsuodz0CJzPCQlV2tQ9Lq2rzy03Ugco50oqCZWKOhXtWr3Yn8CXbyUuMWeLnLT SypA== X-Gm-Message-State: APt69E0q/fEevikjSnXn+8xQE49KD9LG3VEF/t3+n01xcyqb1XSN6MFh pJCjYT76nmNH2DbwRFxnERt9xMpm X-Google-Smtp-Source: AAOMgpdNZLIzJLl9acRR+xhb9zpHqk1x18mi4p0pTBLJ0CDe+B575eDVSMM1sfRafQUdD56AQIc+fg== X-Received: by 2002:adf:9736:: with SMTP id r51-v6mr9612670wrb.5.1530216314619; Thu, 28 Jun 2018 13:05:14 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 28 Jun 2018 22:04:11 +0200 Message-Id: <1530216310-52873-2-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1530216310-52873-1-git-send-email-pbonzini@redhat.com> References: <1530216310-52873-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::231 Subject: [Qemu-devel] [PULL 01/60] exec: Fix MAP_RAM for cached access X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Auger Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Eric Auger When an IOMMUMemoryRegion is in front of a virtio device, address_space_cache_init does not set cache->ptr as the memory region is not RAM. However when the device performs an access, we end up in glue() which performs the translation and then uses MAP_RAM. This latter uses the unset ptr and returns a wrong value which leads to a SIGSEV in address_space_lduw_internal_cached_slow, for instance. In slow path cache->ptr is NULL and MAP_RAM must redirect to qemu_map_ram_ptr((mr)->ram_block, ofs). As MAP_RAM, IS_DIRECT and INVALIDATE are the same in _cached_slow and non cached mode, let's remove those macros. This fixes the use cases featuring vIOMMU (Intel and ARM SMMU) which lead to a SIGSEV. Fixes: 48564041a73a (exec: reintroduce MemoryRegion caching) Signed-off-by: Eric Auger Message-Id: <1528895946-28677-1-git-send-email-eric.auger@redhat.com> Signed-off-by: Paolo Bonzini --- exec.c | 6 ------ memory_ldst.inc.c | 47 ++++++++++++++++++++++------------------------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/exec.c b/exec.c index 1e37f75..9f35e34 100644 --- a/exec.c +++ b/exec.c @@ -3702,9 +3702,6 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr l= en, #define ARG1 as #define SUFFIX #define TRANSLATE(...) address_space_translate(as, __VA_ARGS__) -#define IS_DIRECT(mr, is_write) memory_access_is_direct(mr, is_write) -#define MAP_RAM(mr, ofs) qemu_map_ram_ptr((mr)->ram_block, ofs) -#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len) #define RCU_READ_LOCK(...) rcu_read_lock() #define RCU_READ_UNLOCK(...) rcu_read_unlock() #include "memory_ldst.inc.c" @@ -3841,9 +3838,6 @@ address_space_write_cached_slow(MemoryRegionCache *ca= che, hwaddr addr, #define ARG1 cache #define SUFFIX _cached_slow #define TRANSLATE(...) address_space_translate_cached(cache, __V= A_ARGS__) -#define IS_DIRECT(mr, is_write) memory_access_is_direct(mr, is_write) -#define MAP_RAM(mr, ofs) (cache->ptr + (ofs - cache->xlat)) -#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len) #define RCU_READ_LOCK() ((void)0) #define RCU_READ_UNLOCK() ((void)0) #include "memory_ldst.inc.c" diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c index 1548398..acf865b 100644 --- a/memory_ldst.inc.c +++ b/memory_ldst.inc.c @@ -34,7 +34,7 @@ static inline uint32_t glue(address_space_ldl_internal, S= UFFIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, false, attrs); - if (l < 4 || !IS_DIRECT(mr, false)) { + if (l < 4 || !memory_access_is_direct(mr, false)) { release_lock |=3D prepare_mmio_access(mr); =20 /* I/O case */ @@ -50,7 +50,7 @@ static inline uint32_t glue(address_space_ldl_internal, S= UFFIX)(ARG1_DECL, #endif } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: val =3D ldl_le_p(ptr); @@ -110,7 +110,7 @@ static inline uint64_t glue(address_space_ldq_internal,= SUFFIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, false, attrs); - if (l < 8 || !IS_DIRECT(mr, false)) { + if (l < 8 || !memory_access_is_direct(mr, false)) { release_lock |=3D prepare_mmio_access(mr); =20 /* I/O case */ @@ -126,7 +126,7 @@ static inline uint64_t glue(address_space_ldq_internal,= SUFFIX)(ARG1_DECL, #endif } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: val =3D ldq_le_p(ptr); @@ -184,14 +184,14 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, false, attrs); - if (!IS_DIRECT(mr, false)) { + if (!memory_access_is_direct(mr, false)) { release_lock |=3D prepare_mmio_access(mr); =20 /* I/O case */ r =3D memory_region_dispatch_read(mr, addr1, &val, 1, attrs); } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); val =3D ldub_p(ptr); r =3D MEMTX_OK; } @@ -220,7 +220,7 @@ static inline uint32_t glue(address_space_lduw_internal= , SUFFIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, false, attrs); - if (l < 2 || !IS_DIRECT(mr, false)) { + if (l < 2 || !memory_access_is_direct(mr, false)) { release_lock |=3D prepare_mmio_access(mr); =20 /* I/O case */ @@ -236,7 +236,7 @@ static inline uint32_t glue(address_space_lduw_internal= , SUFFIX)(ARG1_DECL, #endif } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: val =3D lduw_le_p(ptr); @@ -297,12 +297,12 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DE= CL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, true, attrs); - if (l < 4 || !IS_DIRECT(mr, true)) { + if (l < 4 || !memory_access_is_direct(mr, true)) { release_lock |=3D prepare_mmio_access(mr); =20 r =3D memory_region_dispatch_write(mr, addr1, val, 4, attrs); } else { - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); stl_p(ptr, val); =20 dirty_log_mask =3D memory_region_get_dirty_log_mask(mr); @@ -334,7 +334,7 @@ static inline void glue(address_space_stl_internal, SUF= FIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, true, attrs); - if (l < 4 || !IS_DIRECT(mr, true)) { + if (l < 4 || !memory_access_is_direct(mr, true)) { release_lock |=3D prepare_mmio_access(mr); =20 #if defined(TARGET_WORDS_BIGENDIAN) @@ -349,7 +349,7 @@ static inline void glue(address_space_stl_internal, SUF= FIX)(ARG1_DECL, r =3D memory_region_dispatch_write(mr, addr1, val, 4, attrs); } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: stl_le_p(ptr, val); @@ -361,7 +361,7 @@ static inline void glue(address_space_stl_internal, SUF= FIX)(ARG1_DECL, stl_p(ptr, val); break; } - INVALIDATE(mr, addr1, 4); + invalidate_and_set_dirty(mr, addr1, 4); r =3D MEMTX_OK; } if (result) { @@ -406,14 +406,14 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, true, attrs); - if (!IS_DIRECT(mr, true)) { + if (!memory_access_is_direct(mr, true)) { release_lock |=3D prepare_mmio_access(mr); r =3D memory_region_dispatch_write(mr, addr1, val, 1, attrs); } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); stb_p(ptr, val); - INVALIDATE(mr, addr1, 1); + invalidate_and_set_dirty(mr, addr1, 1); r =3D MEMTX_OK; } if (result) { @@ -439,7 +439,7 @@ static inline void glue(address_space_stw_internal, SUF= FIX)(ARG1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, true, attrs); - if (l < 2 || !IS_DIRECT(mr, true)) { + if (l < 2 || !memory_access_is_direct(mr, true)) { release_lock |=3D prepare_mmio_access(mr); =20 #if defined(TARGET_WORDS_BIGENDIAN) @@ -454,7 +454,7 @@ static inline void glue(address_space_stw_internal, SUF= FIX)(ARG1_DECL, r =3D memory_region_dispatch_write(mr, addr1, val, 2, attrs); } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: stw_le_p(ptr, val); @@ -466,7 +466,7 @@ static inline void glue(address_space_stw_internal, SUF= FIX)(ARG1_DECL, stw_p(ptr, val); break; } - INVALIDATE(mr, addr1, 2); + invalidate_and_set_dirty(mr, addr1, 2); r =3D MEMTX_OK; } if (result) { @@ -512,7 +512,7 @@ static void glue(address_space_stq_internal, SUFFIX)(AR= G1_DECL, =20 RCU_READ_LOCK(); mr =3D TRANSLATE(addr, &addr1, &l, true, attrs); - if (l < 8 || !IS_DIRECT(mr, true)) { + if (l < 8 || !memory_access_is_direct(mr, true)) { release_lock |=3D prepare_mmio_access(mr); =20 #if defined(TARGET_WORDS_BIGENDIAN) @@ -527,7 +527,7 @@ static void glue(address_space_stq_internal, SUFFIX)(AR= G1_DECL, r =3D memory_region_dispatch_write(mr, addr1, val, 8, attrs); } else { /* RAM case */ - ptr =3D MAP_RAM(mr, addr1); + ptr =3D qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: stq_le_p(ptr, val); @@ -539,7 +539,7 @@ static void glue(address_space_stq_internal, SUFFIX)(AR= G1_DECL, stq_p(ptr, val); break; } - INVALIDATE(mr, addr1, 8); + invalidate_and_set_dirty(mr, addr1, 8); r =3D MEMTX_OK; } if (result) { @@ -576,8 +576,5 @@ void glue(address_space_stq_be, SUFFIX)(ARG1_DECL, #undef ARG1 #undef SUFFIX #undef TRANSLATE -#undef IS_DIRECT -#undef MAP_RAM -#undef INVALIDATE #undef RCU_READ_LOCK #undef RCU_READ_UNLOCK --=20 1.8.3.1