From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47402) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGlKS-0006uf-9F for qemu-devel@nongnu.org; Fri, 21 Feb 2014 03:19:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WGlKI-00026U-6G for qemu-devel@nongnu.org; Fri, 21 Feb 2014 03:19:28 -0500 Received: from e33.co.us.ibm.com ([32.97.110.151]:41333) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGlKH-00025N-Na for qemu-devel@nongnu.org; Fri, 21 Feb 2014 03:19:17 -0500 Received: from /spool/local by e33.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 21 Feb 2014 01:19:17 -0700 From: Michael Roth Date: Fri, 21 Feb 2014 02:17:26 -0600 Message-Id: <1392970647-21528-51-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1392970647-21528-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1392970647-21528-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 50/51] memory: fix limiting of translation at a page boundary List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: lersek@redhat.com, qemu-stable@nongnu.org, Petar.Jovanovic@imgtec.com From: Paolo Bonzini Commit 360e607 (address_space_translate: do not cross page boundaries, 2014-01-30) broke MMIO accesses in cases where the section is shorter than the full register width. This can happen for example with the Bochs DISPI registers, which are 16 bits wide but have only a 1-byte long MemoryRegion (if you write to the "second byte" of the register your access is discarded; it doesn't write only to half of the register). Restrict the action of commit 360e607 to direct RAM accesses. This is enough for Xen, since MMIO will not go through the mapcache. Reported-by: Mark Cave-Ayland Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini Tested-by: Mark Cave-Ayland Signed-off-by: Peter Maydell (cherry picked from commit a87f39543a9259f671c5413723311180ee2ad2a8) Signed-off-by: Michael Roth --- exec.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/exec.c b/exec.c index df94429..b324fcc 100644 --- a/exec.c +++ b/exec.c @@ -266,6 +266,18 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x return section; } +static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) +{ + if (memory_region_is_ram(mr)) { + return !(is_write && mr->readonly); + } + if (memory_region_is_romd(mr)) { + return !is_write; + } + + return false; +} + MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, hwaddr *xlat, hwaddr *plen, bool is_write) @@ -295,6 +307,11 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, as = iotlb.target_as; } + if (memory_access_is_direct(mr, is_write)) { + hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; + len = MIN(page, len); + } + *plen = len; *xlat = addr; return mr; @@ -1815,18 +1832,6 @@ static void invalidate_and_set_dirty(hwaddr addr, xen_modified_memory(addr, length); } -static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) -{ - if (memory_region_is_ram(mr)) { - return !(is_write && mr->readonly); - } - if (memory_region_is_romd(mr)) { - return !is_write; - } - - return false; -} - static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) { unsigned access_size_max = mr->ops->valid.max_access_size; -- 1.7.9.5