|
|
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 |
|