From patchwork Fri Apr 29 03:15:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 93375 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CA43F1007D7 for ; Fri, 29 Apr 2011 13:15:37 +1000 (EST) Received: from localhost ([::1]:56942 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QFeB4-0003LQ-08 for incoming@patchwork.ozlabs.org; Thu, 28 Apr 2011 23:15:33 -0400 Received: from eggs.gnu.org ([140.186.70.92]:42175) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QFeAx-0003LL-8T for qemu-devel@nongnu.org; Thu, 28 Apr 2011 23:15:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QFeAw-0001br-Cd for qemu-devel@nongnu.org; Thu, 28 Apr 2011 23:15:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41794) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QFeAw-0001bn-39 for qemu-devel@nongnu.org; Thu, 28 Apr 2011 23:15:26 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p3T3FPcv019784 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 28 Apr 2011 23:15:25 -0400 Received: from s20.home (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p3T3FNjT023095; Thu, 28 Apr 2011 23:15:24 -0400 From: Alex Williamson To: qemu-devel@nongnu.org, mst@redhat.com Date: Thu, 28 Apr 2011 21:15:23 -0600 Message-ID: <20110429031437.3796.49456.stgit@s20.home> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: alex.williamson@redhat.com Subject: [Qemu-devel] [PATCH] Fix phys memory client - pass guest physical address not region offset 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 When we're trying to get a newly registered phys memory client updated with the current page mappings, we end up passing the region offset (a ram_addr_t) as the start address rather than the actual guest physical memory address (target_phys_addr_t). If your guest has less than 3.5G of memory, these are coincidentally the same thing. If there's more, the region offset for the memory above 4G starts over at 0, so the set_memory client will overwrite it's lower memory entries. Instead, keep track of the guest phsyical address as we're walking the tables and pass that to the set_memory client. Signed-off-by: Alex Williamson Acked-by: Michael S. Tsirkin --- exec.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index 4752af1..e670929 100644 --- a/exec.c +++ b/exec.c @@ -1742,7 +1742,7 @@ static int cpu_notify_migration_log(int enable) } static void phys_page_for_each_1(CPUPhysMemoryClient *client, - int level, void **lp) + int level, void **lp, target_phys_addr_t addr) { int i; @@ -1751,16 +1751,18 @@ static void phys_page_for_each_1(CPUPhysMemoryClient *client, } if (level == 0) { PhysPageDesc *pd = *lp; + addr <<= L2_BITS + TARGET_PAGE_BITS; for (i = 0; i < L2_SIZE; ++i) { if (pd[i].phys_offset != IO_MEM_UNASSIGNED) { - client->set_memory(client, pd[i].region_offset, + client->set_memory(client, addr | i << TARGET_PAGE_BITS, TARGET_PAGE_SIZE, pd[i].phys_offset); } } } else { void **pp = *lp; for (i = 0; i < L2_SIZE; ++i) { - phys_page_for_each_1(client, level - 1, pp + i); + phys_page_for_each_1(client, level - 1, pp + i, + (addr << L2_BITS) | i); } } } @@ -1770,7 +1772,7 @@ static void phys_page_for_each(CPUPhysMemoryClient *client) int i; for (i = 0; i < P_L1_SIZE; ++i) { phys_page_for_each_1(client, P_L1_SHIFT / L2_BITS - 1, - l1_phys_map + i); + l1_phys_map + i, i); } }