From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Bonzini Subject: Re: [PATCH] address_space_translate: do not cross page boundaries Date: Thu, 30 Jan 2014 14:38:46 +0100 Message-ID: <52EA55E6.90708@redhat.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org Sender: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org To: Stefano Stabellini Cc: Anthony PERARD , george.dunlap@eu.citrix.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, qemu-stable@nongnu.org List-Id: xen-devel@lists.xenproject.org Il 30/01/2014 13:46, Stefano Stabellini ha scritto: > The following commit: > > commit 149f54b53b7666a3facd45e86eece60ce7d3b114 > Author: Paolo Bonzini > Date: Fri May 24 12:59:37 2013 +0200 > > memory: add address_space_translate > > breaks Xen support in QEMU, in particular the Xen mapcache. The effect > is that one Windows XP installation out of ten would end up with BSOD. > > The reason is that after this commit l in address_space_rw can span a > page boundary, however qemu_get_ram_ptr still calls xen_map_cache asking > to map a single page (if block->offset == 0). > > Fix the issue by reverting to the previous behaviour: do not return a > length from address_space_translate_internal that can span a page > boundary. > > Also in address_space_translate do not ignore the length returned by > address_space_translate_internal. > > This patch should be backported to QEMU 1.6.x. > > Signed-off-by: Stefano Stabellini > Signed-off-by: Anthony Perard Tested-by: Paolo Bonzini Acked-by: Paolo Bonzini Cc: qemu-stable@nongnu.org > --- > exec.c | 6 ++++-- > 1 files changed, 4 insertions(+), 2 deletions(-) > > diff --git a/exec.c b/exec.c > index 667a718..f3797b7 100644 > --- a/exec.c > +++ b/exec.c > @@ -251,7 +251,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 */ > @@ -260,7 +260,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; > } > @@ -275,7 +277,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) { > >