Blame SOURCES/kvm-exec-Fix-MAP_RAM-for-cached-access.patch

7711c0
From 8bd172d00ceb35cd2a625f1a86fe50a786d8564a Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Fri, 25 Jan 2019 22:50:06 +0100
7711c0
Subject: [PATCH 06/23] exec: Fix MAP_RAM for cached access
7711c0
MIME-Version: 1.0
7711c0
Content-Type: text/plain; charset=UTF-8
7711c0
Content-Transfer-Encoding: 8bit
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190125225007.8197-7-jsnow@redhat.com>
7711c0
Patchwork-id: 84123
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH v2 6/7] exec: Fix MAP_RAM for cached access
7711c0
Bugzilla: 1597482
7711c0
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
7711c0
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7711c0
RH-Acked-by: Peter Xu <peterx@redhat.com>
7711c0
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
7711c0
7711c0
From: Eric Auger <eric.auger@redhat.com>
7711c0
7711c0
When an IOMMUMemoryRegion is in front of a virtio device,
7711c0
address_space_cache_init does not set cache->ptr as the memory
7711c0
region is not RAM. However when the device performs an access,
7711c0
we end up in glue() which performs the translation and then uses
7711c0
MAP_RAM. This latter uses the unset ptr and returns a wrong value
7711c0
which leads to a SIGSEV in address_space_lduw_internal_cached_slow,
7711c0
for instance.
7711c0
7711c0
In slow path cache->ptr is NULL and MAP_RAM must redirect to
7711c0
qemu_map_ram_ptr((mr)->ram_block, ofs).
7711c0
7711c0
As MAP_RAM, IS_DIRECT and INVALIDATE are the same in _cached_slow
7711c0
and non cached mode, let's remove those macros.
7711c0
7711c0
This fixes the use cases featuring vIOMMU (Intel and ARM SMMU)
7711c0
which lead to a SIGSEV.
7711c0
7711c0
Fixes: 48564041a73a (exec: reintroduce MemoryRegion caching)
7711c0
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7711c0
7711c0
Message-Id: <1528895946-28677-1-git-send-email-eric.auger@redhat.com>
7711c0
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7711c0
(cherry picked from commit a99761d3c85679da380c0f597468acd3dc1b53b3)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 exec.c            |  6 ------
7711c0
 memory_ldst.inc.c | 47 ++++++++++++++++++++++-------------------------
7711c0
 2 files changed, 22 insertions(+), 31 deletions(-)
7711c0
7711c0
diff --git a/exec.c b/exec.c
7711c0
index 805a2d4..d87a51a 100644
7711c0
--- a/exec.c
7711c0
+++ b/exec.c
7711c0
@@ -3643,9 +3643,6 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr len,
7711c0
 #define ARG1                     as
7711c0
 #define SUFFIX
7711c0
 #define TRANSLATE(...)           address_space_translate(as, __VA_ARGS__)
7711c0
-#define IS_DIRECT(mr, is_write)  memory_access_is_direct(mr, is_write)
7711c0
-#define MAP_RAM(mr, ofs)         qemu_map_ram_ptr((mr)->ram_block, ofs)
7711c0
-#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
7711c0
 #define RCU_READ_LOCK(...)       rcu_read_lock()
7711c0
 #define RCU_READ_UNLOCK(...)     rcu_read_unlock()
7711c0
 #include "memory_ldst.inc.c"
7711c0
@@ -3775,9 +3772,6 @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
7711c0
 #define ARG1                     cache
7711c0
 #define SUFFIX                   _cached_slow
7711c0
 #define TRANSLATE(...)           address_space_translate_cached(cache, __VA_ARGS__)
7711c0
-#define IS_DIRECT(mr, is_write)  memory_access_is_direct(mr, is_write)
7711c0
-#define MAP_RAM(mr, ofs)         (cache->ptr + (ofs - cache->xlat))
7711c0
-#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
7711c0
 #define RCU_READ_LOCK()          ((void)0)
7711c0
 #define RCU_READ_UNLOCK()        ((void)0)
7711c0
 #include "memory_ldst.inc.c"
7711c0
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
7711c0
index 25d6125..e09c2b5 100644
7711c0
--- a/memory_ldst.inc.c
7711c0
+++ b/memory_ldst.inc.c
7711c0
@@ -34,7 +34,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, false);
7711c0
-    if (l < 4 || !IS_DIRECT(mr, false)) {
7711c0
+    if (l < 4 || !memory_access_is_direct(mr, false)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
         /* I/O case */
7711c0
@@ -50,7 +50,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
7711c0
 #endif
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         switch (endian) {
7711c0
         case DEVICE_LITTLE_ENDIAN:
7711c0
             val = ldl_le_p(ptr);
7711c0
@@ -110,7 +110,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, false);
7711c0
-    if (l < 8 || !IS_DIRECT(mr, false)) {
7711c0
+    if (l < 8 || !memory_access_is_direct(mr, false)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
         /* I/O case */
7711c0
@@ -126,7 +126,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
7711c0
 #endif
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         switch (endian) {
7711c0
         case DEVICE_LITTLE_ENDIAN:
7711c0
             val = ldq_le_p(ptr);
7711c0
@@ -184,14 +184,14 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, false);
7711c0
-    if (!IS_DIRECT(mr, false)) {
7711c0
+    if (!memory_access_is_direct(mr, false)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
         /* I/O case */
7711c0
         r = memory_region_dispatch_read(mr, addr1, &val, 1, attrs);
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         val = ldub_p(ptr);
7711c0
         r = MEMTX_OK;
7711c0
     }
7711c0
@@ -220,7 +220,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, false);
7711c0
-    if (l < 2 || !IS_DIRECT(mr, false)) {
7711c0
+    if (l < 2 || !memory_access_is_direct(mr, false)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
         /* I/O case */
7711c0
@@ -236,7 +236,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
7711c0
 #endif
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         switch (endian) {
7711c0
         case DEVICE_LITTLE_ENDIAN:
7711c0
             val = lduw_le_p(ptr);
7711c0
@@ -297,12 +297,12 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, true);
7711c0
-    if (l < 4 || !IS_DIRECT(mr, true)) {
7711c0
+    if (l < 4 || !memory_access_is_direct(mr, true)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
7711c0
     } else {
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         stl_p(ptr, val);
7711c0
 
7711c0
         dirty_log_mask = memory_region_get_dirty_log_mask(mr);
7711c0
@@ -334,7 +334,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, true);
7711c0
-    if (l < 4 || !IS_DIRECT(mr, true)) {
7711c0
+    if (l < 4 || !memory_access_is_direct(mr, true)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
 #if defined(TARGET_WORDS_BIGENDIAN)
7711c0
@@ -349,7 +349,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
7711c0
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         switch (endian) {
7711c0
         case DEVICE_LITTLE_ENDIAN:
7711c0
             stl_le_p(ptr, val);
7711c0
@@ -361,7 +361,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
7711c0
             stl_p(ptr, val);
7711c0
             break;
7711c0
         }
7711c0
-        INVALIDATE(mr, addr1, 4);
7711c0
+        invalidate_and_set_dirty(mr, addr1, 4);
7711c0
         r = MEMTX_OK;
7711c0
     }
7711c0
     if (result) {
7711c0
@@ -406,14 +406,14 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, true);
7711c0
-    if (!IS_DIRECT(mr, true)) {
7711c0
+    if (!memory_access_is_direct(mr, true)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
         r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         stb_p(ptr, val);
7711c0
-        INVALIDATE(mr, addr1, 1);
7711c0
+        invalidate_and_set_dirty(mr, addr1, 1);
7711c0
         r = MEMTX_OK;
7711c0
     }
7711c0
     if (result) {
7711c0
@@ -439,7 +439,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, true);
7711c0
-    if (l < 2 || !IS_DIRECT(mr, true)) {
7711c0
+    if (l < 2 || !memory_access_is_direct(mr, true)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
 #if defined(TARGET_WORDS_BIGENDIAN)
7711c0
@@ -454,7 +454,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
7711c0
         r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         switch (endian) {
7711c0
         case DEVICE_LITTLE_ENDIAN:
7711c0
             stw_le_p(ptr, val);
7711c0
@@ -466,7 +466,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
7711c0
             stw_p(ptr, val);
7711c0
             break;
7711c0
         }
7711c0
-        INVALIDATE(mr, addr1, 2);
7711c0
+        invalidate_and_set_dirty(mr, addr1, 2);
7711c0
         r = MEMTX_OK;
7711c0
     }
7711c0
     if (result) {
7711c0
@@ -512,7 +512,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
7711c0
 
7711c0
     RCU_READ_LOCK();
7711c0
     mr = TRANSLATE(addr, &addr1, &l, true);
7711c0
-    if (l < 8 || !IS_DIRECT(mr, true)) {
7711c0
+    if (l < 8 || !memory_access_is_direct(mr, true)) {
7711c0
         release_lock |= prepare_mmio_access(mr);
7711c0
 
7711c0
 #if defined(TARGET_WORDS_BIGENDIAN)
7711c0
@@ -527,7 +527,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
7711c0
         r = memory_region_dispatch_write(mr, addr1, val, 8, attrs);
7711c0
     } else {
7711c0
         /* RAM case */
7711c0
-        ptr = MAP_RAM(mr, addr1);
7711c0
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
7711c0
         switch (endian) {
7711c0
         case DEVICE_LITTLE_ENDIAN:
7711c0
             stq_le_p(ptr, val);
7711c0
@@ -539,7 +539,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
7711c0
             stq_p(ptr, val);
7711c0
             break;
7711c0
         }
7711c0
-        INVALIDATE(mr, addr1, 8);
7711c0
+        invalidate_and_set_dirty(mr, addr1, 8);
7711c0
         r = MEMTX_OK;
7711c0
     }
7711c0
     if (result) {
7711c0
@@ -576,8 +576,5 @@ void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
7711c0
 #undef ARG1
7711c0
 #undef SUFFIX
7711c0
 #undef TRANSLATE
7711c0
-#undef IS_DIRECT
7711c0
-#undef MAP_RAM
7711c0
-#undef INVALIDATE
7711c0
 #undef RCU_READ_LOCK
7711c0
 #undef RCU_READ_UNLOCK
7711c0
-- 
7711c0
1.8.3.1
7711c0