aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-01 20:43:07 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-01 20:45:43 +0000
commitbd88091cfbc3627ac436b5a554340cd263c93b56 (patch)
tree338c47790d5270942a769c8781a42425683548cc
parent89e4a51ca9546a7bbe1998c4e3d4a3ac3a0c19be (diff)
parent360e607b88a23d378f6efaa769c76d26f538234d (diff)
Merge remote-tracking branch 'remotes/sstabellini/xen-140130' into staging
* remotes/sstabellini/xen-140130: address_space_translate: do not cross page boundaries Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--exec.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/exec.c b/exec.c
index 2435d9ecd9..9ad0a4b045 100644
--- a/exec.c
+++ b/exec.c
@@ -325,7 +325,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
hwaddr *plen, bool resolve_subpage)
{
MemoryRegionSection *section;
- Int128 diff;
+ Int128 diff, diff_page;
section = address_space_lookup_region(d, addr, resolve_subpage);
/* Compute offset within MemoryRegionSection */
@@ -334,7 +334,9 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
/* Compute offset within MemoryRegion */
*xlat = addr + section->offset_within_region;
+ diff_page = int128_make64(((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr);
diff = int128_sub(section->mr->size, int128_make64(addr));
+ diff = int128_min(diff, diff_page);
*plen = int128_get64(int128_min(diff, int128_make64(*plen)));
return section;
}
@@ -349,7 +351,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
hwaddr len = *plen;
for (;;) {
- section = address_space_translate_internal(as->dispatch, addr, &addr, plen, true);
+ section = address_space_translate_internal(as->dispatch, addr, &addr, &len, true);
mr = section->mr;
if (!mr->iommu_ops) {