Browse Source

exec: Fix MAP_RAM for cached access

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: 48564041a7 (exec: reintroduce MemoryRegion caching)
Signed-off-by: Eric Auger <eric.auger@redhat.com>

Message-Id: <1528895946-28677-1-git-send-email-eric.auger@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
tags/v3.0.0-rc0
Eric Auger 1 year ago
parent
commit
a99761d3c8
2 changed files with 22 additions and 31 deletions
  1. 0
    6
      exec.c
  2. 22
    25
      memory_ldst.inc.c

+ 0
- 6
exec.c View File

@@ -3702,9 +3702,6 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr len,
3702 3702
 #define ARG1                     as
3703 3703
 #define SUFFIX
3704 3704
 #define TRANSLATE(...)           address_space_translate(as, __VA_ARGS__)
3705
-#define IS_DIRECT(mr, is_write)  memory_access_is_direct(mr, is_write)
3706
-#define MAP_RAM(mr, ofs)         qemu_map_ram_ptr((mr)->ram_block, ofs)
3707
-#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
3708 3705
 #define RCU_READ_LOCK(...)       rcu_read_lock()
3709 3706
 #define RCU_READ_UNLOCK(...)     rcu_read_unlock()
3710 3707
 #include "memory_ldst.inc.c"
@@ -3841,9 +3838,6 @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
3841 3838
 #define ARG1                     cache
3842 3839
 #define SUFFIX                   _cached_slow
3843 3840
 #define TRANSLATE(...)           address_space_translate_cached(cache, __VA_ARGS__)
3844
-#define IS_DIRECT(mr, is_write)  memory_access_is_direct(mr, is_write)
3845
-#define MAP_RAM(mr, ofs)         (cache->ptr + (ofs - cache->xlat))
3846
-#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
3847 3841
 #define RCU_READ_LOCK()          ((void)0)
3848 3842
 #define RCU_READ_UNLOCK()        ((void)0)
3849 3843
 #include "memory_ldst.inc.c"

+ 22
- 25
memory_ldst.inc.c View File

@@ -34,7 +34,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
34 34
 
35 35
     RCU_READ_LOCK();
36 36
     mr = TRANSLATE(addr, &addr1, &l, false, attrs);
37
-    if (l < 4 || !IS_DIRECT(mr, false)) {
37
+    if (l < 4 || !memory_access_is_direct(mr, false)) {
38 38
         release_lock |= prepare_mmio_access(mr);
39 39
 
40 40
         /* I/O case */
@@ -50,7 +50,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
50 50
 #endif
51 51
     } else {
52 52
         /* RAM case */
53
-        ptr = MAP_RAM(mr, addr1);
53
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
54 54
         switch (endian) {
55 55
         case DEVICE_LITTLE_ENDIAN:
56 56
             val = ldl_le_p(ptr);
@@ -110,7 +110,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
110 110
 
111 111
     RCU_READ_LOCK();
112 112
     mr = TRANSLATE(addr, &addr1, &l, false, attrs);
113
-    if (l < 8 || !IS_DIRECT(mr, false)) {
113
+    if (l < 8 || !memory_access_is_direct(mr, false)) {
114 114
         release_lock |= prepare_mmio_access(mr);
115 115
 
116 116
         /* I/O case */
@@ -126,7 +126,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
126 126
 #endif
127 127
     } else {
128 128
         /* RAM case */
129
-        ptr = MAP_RAM(mr, addr1);
129
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
130 130
         switch (endian) {
131 131
         case DEVICE_LITTLE_ENDIAN:
132 132
             val = ldq_le_p(ptr);
@@ -184,14 +184,14 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
184 184
 
185 185
     RCU_READ_LOCK();
186 186
     mr = TRANSLATE(addr, &addr1, &l, false, attrs);
187
-    if (!IS_DIRECT(mr, false)) {
187
+    if (!memory_access_is_direct(mr, false)) {
188 188
         release_lock |= prepare_mmio_access(mr);
189 189
 
190 190
         /* I/O case */
191 191
         r = memory_region_dispatch_read(mr, addr1, &val, 1, attrs);
192 192
     } else {
193 193
         /* RAM case */
194
-        ptr = MAP_RAM(mr, addr1);
194
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
195 195
         val = ldub_p(ptr);
196 196
         r = MEMTX_OK;
197 197
     }
@@ -220,7 +220,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
220 220
 
221 221
     RCU_READ_LOCK();
222 222
     mr = TRANSLATE(addr, &addr1, &l, false, attrs);
223
-    if (l < 2 || !IS_DIRECT(mr, false)) {
223
+    if (l < 2 || !memory_access_is_direct(mr, false)) {
224 224
         release_lock |= prepare_mmio_access(mr);
225 225
 
226 226
         /* I/O case */
@@ -236,7 +236,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
236 236
 #endif
237 237
     } else {
238 238
         /* RAM case */
239
-        ptr = MAP_RAM(mr, addr1);
239
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
240 240
         switch (endian) {
241 241
         case DEVICE_LITTLE_ENDIAN:
242 242
             val = lduw_le_p(ptr);
@@ -297,12 +297,12 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
297 297
 
298 298
     RCU_READ_LOCK();
299 299
     mr = TRANSLATE(addr, &addr1, &l, true, attrs);
300
-    if (l < 4 || !IS_DIRECT(mr, true)) {
300
+    if (l < 4 || !memory_access_is_direct(mr, true)) {
301 301
         release_lock |= prepare_mmio_access(mr);
302 302
 
303 303
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
304 304
     } else {
305
-        ptr = MAP_RAM(mr, addr1);
305
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
306 306
         stl_p(ptr, val);
307 307
 
308 308
         dirty_log_mask = memory_region_get_dirty_log_mask(mr);
@@ -334,7 +334,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
334 334
 
335 335
     RCU_READ_LOCK();
336 336
     mr = TRANSLATE(addr, &addr1, &l, true, attrs);
337
-    if (l < 4 || !IS_DIRECT(mr, true)) {
337
+    if (l < 4 || !memory_access_is_direct(mr, true)) {
338 338
         release_lock |= prepare_mmio_access(mr);
339 339
 
340 340
 #if defined(TARGET_WORDS_BIGENDIAN)
@@ -349,7 +349,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
349 349
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
350 350
     } else {
351 351
         /* RAM case */
352
-        ptr = MAP_RAM(mr, addr1);
352
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
353 353
         switch (endian) {
354 354
         case DEVICE_LITTLE_ENDIAN:
355 355
             stl_le_p(ptr, val);
@@ -361,7 +361,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
361 361
             stl_p(ptr, val);
362 362
             break;
363 363
         }
364
-        INVALIDATE(mr, addr1, 4);
364
+        invalidate_and_set_dirty(mr, addr1, 4);
365 365
         r = MEMTX_OK;
366 366
     }
367 367
     if (result) {
@@ -406,14 +406,14 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
406 406
 
407 407
     RCU_READ_LOCK();
408 408
     mr = TRANSLATE(addr, &addr1, &l, true, attrs);
409
-    if (!IS_DIRECT(mr, true)) {
409
+    if (!memory_access_is_direct(mr, true)) {
410 410
         release_lock |= prepare_mmio_access(mr);
411 411
         r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
412 412
     } else {
413 413
         /* RAM case */
414
-        ptr = MAP_RAM(mr, addr1);
414
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
415 415
         stb_p(ptr, val);
416
-        INVALIDATE(mr, addr1, 1);
416
+        invalidate_and_set_dirty(mr, addr1, 1);
417 417
         r = MEMTX_OK;
418 418
     }
419 419
     if (result) {
@@ -439,7 +439,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
439 439
 
440 440
     RCU_READ_LOCK();
441 441
     mr = TRANSLATE(addr, &addr1, &l, true, attrs);
442
-    if (l < 2 || !IS_DIRECT(mr, true)) {
442
+    if (l < 2 || !memory_access_is_direct(mr, true)) {
443 443
         release_lock |= prepare_mmio_access(mr);
444 444
 
445 445
 #if defined(TARGET_WORDS_BIGENDIAN)
@@ -454,7 +454,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
454 454
         r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
455 455
     } else {
456 456
         /* RAM case */
457
-        ptr = MAP_RAM(mr, addr1);
457
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
458 458
         switch (endian) {
459 459
         case DEVICE_LITTLE_ENDIAN:
460 460
             stw_le_p(ptr, val);
@@ -466,7 +466,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
466 466
             stw_p(ptr, val);
467 467
             break;
468 468
         }
469
-        INVALIDATE(mr, addr1, 2);
469
+        invalidate_and_set_dirty(mr, addr1, 2);
470 470
         r = MEMTX_OK;
471 471
     }
472 472
     if (result) {
@@ -512,7 +512,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
512 512
 
513 513
     RCU_READ_LOCK();
514 514
     mr = TRANSLATE(addr, &addr1, &l, true, attrs);
515
-    if (l < 8 || !IS_DIRECT(mr, true)) {
515
+    if (l < 8 || !memory_access_is_direct(mr, true)) {
516 516
         release_lock |= prepare_mmio_access(mr);
517 517
 
518 518
 #if defined(TARGET_WORDS_BIGENDIAN)
@@ -527,7 +527,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
527 527
         r = memory_region_dispatch_write(mr, addr1, val, 8, attrs);
528 528
     } else {
529 529
         /* RAM case */
530
-        ptr = MAP_RAM(mr, addr1);
530
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
531 531
         switch (endian) {
532 532
         case DEVICE_LITTLE_ENDIAN:
533 533
             stq_le_p(ptr, val);
@@ -539,7 +539,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
539 539
             stq_p(ptr, val);
540 540
             break;
541 541
         }
542
-        INVALIDATE(mr, addr1, 8);
542
+        invalidate_and_set_dirty(mr, addr1, 8);
543 543
         r = MEMTX_OK;
544 544
     }
545 545
     if (result) {
@@ -576,8 +576,5 @@ void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
576 576
 #undef ARG1
577 577
 #undef SUFFIX
578 578
 #undef TRANSLATE
579
-#undef IS_DIRECT
580
-#undef MAP_RAM
581
-#undef INVALIDATE
582 579
 #undef RCU_READ_LOCK
583 580
 #undef RCU_READ_UNLOCK

Loading…
Cancel
Save