From patchwork Thu Jan 30 12:46:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 315325 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 0CA662C0082 for ; Thu, 30 Jan 2014 23:46:42 +1100 (EST) Received: from localhost ([::1]:48326 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8r0x-0000cr-3p for incoming@patchwork.ozlabs.org; Thu, 30 Jan 2014 07:46:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50999) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8r0b-0000Dv-OA for qemu-devel@nongnu.org; Thu, 30 Jan 2014 07:46:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W8r0X-0002F2-12 for qemu-devel@nongnu.org; Thu, 30 Jan 2014 07:46:17 -0500 Received: from smtp02.citrix.com ([66.165.176.63]:38412) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8r0W-0002Es-TA for qemu-devel@nongnu.org; Thu, 30 Jan 2014 07:46:12 -0500 X-IronPort-AV: E=Sophos;i="4.95,749,1384300800"; d="scan'208";a="96104410" Received: from accessns.citrite.net (HELO FTLPEX01CL03.citrite.net) ([10.9.154.239]) by FTLPIPO02.CITRIX.COM with ESMTP; 30 Jan 2014 12:46:11 +0000 Received: from ukmail1.uk.xensource.com (10.80.16.128) by smtprelay.citrix.com (10.13.107.80) with Microsoft SMTP Server id 14.2.342.4; Thu, 30 Jan 2014 07:46:10 -0500 Received: from kaball.uk.xensource.com ([10.80.2.59]) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1W8r0U-0004nO-Mi; Thu, 30 Jan 2014 12:46:10 +0000 Date: Thu, 30 Jan 2014 12:46:05 +0000 From: Stefano Stabellini X-X-Sender: sstabellini@kaball.uk.xensource.com To: Paolo Bonzini Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 X-DLP: MIA1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 66.165.176.63 Cc: Anthony PERARD , george.dunlap@eu.citrix.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org, Stefano Stabellini Subject: [Qemu-devel] [PATCH] address_space_translate: do not cross page boundaries X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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) {