yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-memory-clamp-cached-translation-in-case-it-points-to.patch

c687bc
From 354946f1e5fee0a69282bdf284c969b03a78a53e Mon Sep 17 00:00:00 2001
c687bc
From: Jon Maloy <jmaloy@redhat.com>
c687bc
Date: Wed, 13 Jan 2021 00:42:23 -0500
c687bc
Subject: [PATCH 15/17] memory: clamp cached translation in case it points to
c687bc
 an MMIO region
c687bc
c687bc
RH-Author: Jon Maloy <jmaloy@redhat.com>
c687bc
Message-id: <20210113004223.871394-2-jmaloy@redhat.com>
c687bc
Patchwork-id: 100618
c687bc
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] memory: clamp cached translation in case it points to an MMIO region
c687bc
Bugzilla: 1904393
c687bc
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
c687bc
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
c687bc
RH-Acked-by: Thomas Huth <thuth@redhat.com>
c687bc
c687bc
From: Paolo Bonzini <pbonzini@redhat.com>
c687bc
c687bc
In using the address_space_translate_internal API, address_space_cache_init
c687bc
forgot one piece of advice that can be found in the code for
c687bc
address_space_translate_internal:
c687bc
c687bc
    /* MMIO registers can be expected to perform full-width accesses based only
c687bc
     * on their address, without considering adjacent registers that could
c687bc
     * decode to completely different MemoryRegions.  When such registers
c687bc
     * exist (e.g. I/O ports 0xcf8 and 0xcf9 on most PC chipsets), MMIO
c687bc
     * regions overlap wildly.  For this reason we cannot clamp the accesses
c687bc
     * here.
c687bc
     *
c687bc
     * If the length is small (as is the case for address_space_ldl/stl),
c687bc
     * everything works fine.  If the incoming length is large, however,
c687bc
     * the caller really has to do the clamping through memory_access_size.
c687bc
     */
c687bc
c687bc
address_space_cache_init is exactly one such case where "the incoming length
c687bc
is large", therefore we need to clamp the resulting length---not to
c687bc
memory_access_size though, since we are not doing an access yet, but to
c687bc
the size of the resulting section.  This ensures that subsequent accesses
c687bc
to the cached MemoryRegionSection will be in range.
c687bc
c687bc
With this patch, the enclosed testcase notices that the used ring does
c687bc
not fit into the MSI-X table and prints a "qemu-system-x86_64: Cannot map used"
c687bc
error.
c687bc
c687bc
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
c687bc
c687bc
(cherry picked from 4bfb024bc76973d40a359476dc0291f46e435442)
c687bc
- Manually applied to file exec.c, where the code to correct
c687bc
  is located in this version.
c687bc
- Skipped the fuzzing test part, which is hard to apply on this code.
c687bc
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
c687bc
c687bc
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
c687bc
---
c687bc
 exec.c | 10 ++++++++++
c687bc
 1 file changed, 10 insertions(+)
c687bc
c687bc
diff --git a/exec.c b/exec.c
c687bc
index ffdb5185353..09ed0cfc756 100644
c687bc
--- a/exec.c
c687bc
+++ b/exec.c
c687bc
@@ -3620,6 +3620,7 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
c687bc
     AddressSpaceDispatch *d;
c687bc
     hwaddr l;
c687bc
     MemoryRegion *mr;
c687bc
+    Int128 diff;
c687bc
 
c687bc
     assert(len > 0);
c687bc
 
c687bc
@@ -3628,6 +3629,15 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
c687bc
     d = flatview_to_dispatch(cache->fv);
c687bc
     cache->mrs = *address_space_translate_internal(d, addr, &cache->xlat, &l, true);
c687bc
 
c687bc
+    /*
c687bc
+     * cache->xlat is now relative to cache->mrs.mr, not to the section itself.
c687bc
+     * Take that into account to compute how many bytes are there between
c687bc
+     * cache->xlat and the end of the section.
c687bc
+     */
c687bc
+    diff = int128_sub(cache->mrs.size,
c687bc
+                      int128_make64(cache->xlat - cache->mrs.offset_within_region));
c687bc
+    l = int128_get64(int128_min(diff, int128_make64(l)));
c687bc
+
c687bc
     mr = cache->mrs.mr;
c687bc
     memory_region_ref(mr);
c687bc
     if (memory_access_is_direct(mr, is_write)) {
c687bc
-- 
c687bc
2.27.0
c687bc