From 965eb2fcdfe919ecced6c34803535ad32dc1249c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 17 Jun 2015 10:40:27 +0200 Subject: exec: do not clamp accesses to MMIO regions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is common for MMIO registers to overlap, for example a 4 byte register at 0xcf8 (totally random choice... :)) and a 1 byte register at 0xcf9. If these registers are implemented via separate MemoryRegions, it is wrong to clamp the accesses as the value written would be truncated. Hence for these regions the effects of commit 23820db (exec: Respect as_translate_internal length clamp, 2015-03-16, previously applied as commit c3c1bb99) must be skipped. Tested-by: Hervé Poussineau Tested-by: Mark Cave-Ayland Signed-off-by: Paolo Bonzini --- exec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 76bfc4ac4a..d00e017e19 100644 --- a/exec.c +++ b/exec.c @@ -341,6 +341,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x hwaddr *plen, bool resolve_subpage) { MemoryRegionSection *section; + MemoryRegion *mr; Int128 diff; section = address_space_lookup_region(d, addr, resolve_subpage); @@ -350,8 +351,11 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x /* Compute offset within MemoryRegion */ *xlat = addr + section->offset_within_region; - diff = int128_sub(section->mr->size, int128_make64(addr)); - *plen = int128_get64(int128_min(diff, int128_make64(*plen))); + mr = section->mr; + if (memory_region_is_ram(mr)) { + diff = int128_sub(mr->size, int128_make64(addr)); + *plen = int128_get64(int128_min(diff, int128_make64(*plen))); + } return section; } -- cgit 1.4.1 From e4a511f8cc6f4a46d409fb5c9f72c38ba45f8d83 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 17 Jun 2015 10:36:54 +0200 Subject: exec: clamp accesses against the MemoryRegionSection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because the clamping was done against the MemoryRegion, address_space_rw was effectively broken if a write spanned multiple sections that are not linear in underlying memory (with the memory not being under an IOMMU). This is visible with the MIPS rc4030 IOMMU, which is implemented as a series of alias memory regions that point to the actual RAM. Tested-by: Hervé Poussineau Tested-by: Mark Cave-Ayland Signed-off-by: Paolo Bonzini --- exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index d00e017e19..f7883d2246 100644 --- a/exec.c +++ b/exec.c @@ -353,7 +353,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x mr = section->mr; if (memory_region_is_ram(mr)) { - diff = int128_sub(mr->size, int128_make64(addr)); + diff = int128_sub(section->size, int128_make64(addr)); *plen = int128_get64(int128_min(diff, int128_make64(*plen))); } return section; -- cgit 1.4.1