Blame SOURCES/kvm-exec-add-page_mask-for-address_space_do_translate.patch

9bac43
From 59ad61373f73de6a3eb17e0c1989bc048b51b55c Mon Sep 17 00:00:00 2001
9bac43
From: Maxime Coquelin <maxime.coquelin@redhat.com>
9bac43
Date: Fri, 20 Oct 2017 14:17:06 +0200
9bac43
Subject: [PATCH 04/19] exec: add page_mask for address_space_do_translate
9bac43
9bac43
RH-Author: Maxime Coquelin <maxime.coquelin@redhat.com>
9bac43
Message-id: <20171020141707.17637-2-maxime.coquelin@redhat.com>
9bac43
Patchwork-id: 77417
9bac43
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/2] exec: add page_mask for address_space_do_translate
9bac43
Bugzilla: 1498817
9bac43
RH-Acked-by: Peter Xu <peterx@redhat.com>
9bac43
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
9bac43
RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
9bac43
9bac43
From: Peter Xu <peterx@redhat.com>
9bac43
9bac43
The function is originally used for address_space_space_translate() and
9bac43
what we care about most is (xlat, plen) range. However for iotlb
9bac43
requests, we don't really care about "plen", but the size of the page
9bac43
that "xlat" is located on. While, plen cannot really contain this
9bac43
information.
9bac43
9bac43
A simple example to show why "plen" is not good for IOTLB translations:
9bac43
9bac43
E.g., for huge pages, it is possible that guest mapped 1G huge page on
9bac43
device side that used this GPA range:
9bac43
9bac43
  0x100000000 - 0x13fffffff
9bac43
9bac43
Then let's say we want to translate one IOVA that finally mapped to GPA
9bac43
0x13ffffe00 (which is located on this 1G huge page). Then here we'll
9bac43
get:
9bac43
9bac43
  (xlat, plen) = (0x13fffe00, 0x200)
9bac43
9bac43
So the IOTLB would be only covering a very small range since from
9bac43
"plen" (which is 0x200 bytes) we cannot tell the size of the page.
9bac43
9bac43
Actually we can really know that this is a huge page - we just throw the
9bac43
information away in address_space_do_translate().
9bac43
9bac43
This patch introduced "page_mask" optional parameter to capture that
9bac43
page mask info. Also, I made "plen" an optional parameter as well, with
9bac43
some comments for the whole function.
9bac43
9bac43
No functional change yet.
9bac43
9bac43
Signed-off-by: Peter Xu <peterx@redhat.com>
9bac43
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
9bac43
Message-Id: <20171010094247.10173-2-maxime.coquelin@redhat.com>
9bac43
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9bac43
(cherry picked from commit d5e5fafd11be4458443c43f19c1ebdd24d99a751)
9bac43
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
9bac43
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9bac43
9bac43
Conflicts:
9bac43
	exec.c (Skipping 166206845f7f)
9bac43
---
9bac43
 exec.c | 32 +++++++++++++++++++++++++++-----
9bac43
 1 file changed, 27 insertions(+), 5 deletions(-)
9bac43
9bac43
diff --git a/exec.c b/exec.c
9bac43
index d20c34c..e5f97fd 100644
9bac43
--- a/exec.c
9bac43
+++ b/exec.c
9bac43
@@ -475,7 +475,8 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
9bac43
 static MemoryRegionSection address_space_do_translate(AddressSpace *as,
9bac43
                                                       hwaddr addr,
9bac43
                                                       hwaddr *xlat,
9bac43
-                                                      hwaddr *plen,
9bac43
+                                                      hwaddr *plen_out,
9bac43
+                                                      hwaddr *page_mask_out,
9bac43
                                                       bool is_write,
9bac43
                                                       bool is_mmio)
9bac43
 {
9bac43
@@ -483,10 +484,16 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
9bac43
     MemoryRegionSection *section;
9bac43
     IOMMUMemoryRegion *iommu_mr;
9bac43
     IOMMUMemoryRegionClass *imrc;
9bac43
+    hwaddr page_mask = (hwaddr)(-1);
9bac43
+    hwaddr plen = (hwaddr)(-1);
9bac43
+
9bac43
+    if (plen_out) {
9bac43
+        plen = *plen_out;
9bac43
+    }
9bac43
 
9bac43
     for (;;) {
9bac43
         AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
9bac43
-        section = address_space_translate_internal(d, addr, &addr, plen, is_mmio);
9bac43
+        section = address_space_translate_internal(d, addr, &addr, &plen, is_mmio);
9bac43
 
9bac43
         iommu_mr = memory_region_get_iommu(section->mr);
9bac43
         if (!iommu_mr) {
9bac43
@@ -498,7 +505,8 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
9bac43
                                 IOMMU_WO : IOMMU_RO);
9bac43
         addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
9bac43
                 | (addr & iotlb.addr_mask));
9bac43
-        *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
9bac43
+        page_mask &= iotlb.addr_mask;
9bac43
+        plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1);
9bac43
         if (!(iotlb.perm & (1 << is_write))) {
9bac43
             goto translate_fail;
9bac43
         }
9bac43
@@ -508,6 +516,19 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
9bac43
 
9bac43
     *xlat = addr;
9bac43
 
9bac43
+    if (page_mask == (hwaddr)(-1)) {
9bac43
+        /* Not behind an IOMMU, use default page size. */
9bac43
+        page_mask = ~TARGET_PAGE_MASK;
9bac43
+    }
9bac43
+
9bac43
+    if (page_mask_out) {
9bac43
+        *page_mask_out = page_mask;
9bac43
+    }
9bac43
+
9bac43
+    if (plen_out) {
9bac43
+        *plen_out = plen;
9bac43
+    }
9bac43
+
9bac43
     return *section;
9bac43
 
9bac43
 translate_fail:
9bac43
@@ -526,7 +547,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
9bac43
 
9bac43
     /* This can never be MMIO. */
9bac43
     section = address_space_do_translate(as, addr, &xlat, &plen,
9bac43
-                                         is_write, false);
9bac43
+                                         NULL, is_write, false);
9bac43
 
9bac43
     /* Illegal translation */
9bac43
     if (section.mr == &io_mem_unassigned) {
9bac43
@@ -570,7 +591,8 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
9bac43
     MemoryRegionSection section;
9bac43
 
9bac43
     /* This can be MMIO, so setup MMIO bit. */
9bac43
-    section = address_space_do_translate(as, addr, xlat, plen, is_write, true);
9bac43
+    section = address_space_do_translate(as, addr, xlat, plen, NULL,
9bac43
+                                         is_write, true);
9bac43
     mr = section.mr;
9bac43
 
9bac43
     if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
9bac43
-- 
9bac43
1.8.3.1
9bac43