From patchwork Tue Mar 24 21:01:35 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yaniv Kamay X-Patchwork-Id: 14099 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2OL1mrh031273 for ; Tue, 24 Mar 2009 21:01:48 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751338AbZCXVBk (ORCPT ); Tue, 24 Mar 2009 17:01:40 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751335AbZCXVBj (ORCPT ); Tue, 24 Mar 2009 17:01:39 -0400 Received: from mx2.redhat.com ([66.187.237.31]:34172 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751201AbZCXVBj (ORCPT ); Tue, 24 Mar 2009 17:01:39 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2OL1b0A008804 for ; Tue, 24 Mar 2009 17:01:37 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n2OL1Vhw025278 for ; Tue, 24 Mar 2009 17:01:31 -0400 Received: from [10.35.1.39] (dhcp-1-39.tlv.redhat.com [10.35.1.39]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n2OL1Zv6011661 for ; Tue, 24 Mar 2009 17:01:36 -0400 Message-ID: <49C94A2F.9070706@redhat.com> Date: Tue, 24 Mar 2009 23:01:35 +0200 From: Yaniv Kamay User-Agent: Thunderbird 2.0.0.18 (X11/20081119) MIME-Version: 1.0 To: kvm@vger.kernel.org Subject: [PATCH] fix bad physical address in kvm_update_dirty_pages_log() X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Hi, Attaching patch that fix updating qemu dirty region. Previous kvm_update_dirty_pages_log() imp treat physical ram as if it is linear mapped to guest physical memory. This patch fix it by mapping physical ram to guest physical memory areas and for etch area call kvm_get_dirty_pages_range() with the correct address and size. Thanks, Yaniv From 1179bb5123a53392d705801dc37e491f0766957c Mon Sep 17 00:00:00 2001 From: Yaniv Kamay Date: Tue, 24 Mar 2009 20:49:07 +0200 Subject: [PATCH] fix bad physical address in kvm_update_dirty_pages_log() --- qemu/qemu-kvm.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 57 insertions(+), 4 deletions(-) diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index 4164368..71cd3dc 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -1216,6 +1216,27 @@ static int kvm_get_dirty_bitmap_cb(unsigned long start, unsigned long len, return kvm_get_dirty_pages_log_range(start, bitmap, start, len); } +static int find_phys_area(ram_addr_t phys_ram_offset, ram_addr_t *offset, target_phys_addr_t *start, + ram_addr_t *size) +{ + struct mapping *now = NULL; + struct mapping *map; + + for (map = mappings; map < mappings + nr_mappings; ++map) { + if (map->ram >= phys_ram_offset && (!now || map->ram < now->ram)) { + now = map; + } + } + + if (!now) { + return -1; + } + + *offset = now->ram - phys_ram_offset; + *start = now->phys; + *size = now->len; + return 0; +} /* * get kvm's dirty pages bitmap and update qemu's * we only care about physical ram, which resides in slots 0 and 3 @@ -1223,12 +1244,44 @@ static int kvm_get_dirty_bitmap_cb(unsigned long start, unsigned long len, int kvm_update_dirty_pages_log(void) { int r = 0; + ram_addr_t now = 0; + ram_addr_t end = phys_ram_size; + ram_addr_t offset; + target_phys_addr_t area_start; + ram_addr_t area_size; + unsigned char *dirty_bitmap = kvm_dirty_bitmap; + + if (!dirty_bitmap) { + printf("%s: no dirty bitmap\n", __FUNCTION__); + return -1; + } + while (now < end && !find_phys_area(now, &offset, &area_start, &area_size)) { + if ((offset & ~TARGET_PAGE_MASK) || (area_start & ~TARGET_PAGE_MASK) || + (area_size & ~TARGET_PAGE_MASK)) { + printf("%s: invalid mem area\n", __FUNCTION__); + return -1; + } - r = kvm_get_dirty_pages_range(kvm_context, 0, phys_ram_size, - kvm_dirty_bitmap, NULL, - kvm_get_dirty_bitmap_cb); - return r; + if ((now += offset) >= end) { + break; + } + + if (area_size > end - now) { + return -1; + } + dirty_bitmap += offset / TARGET_PAGE_SIZE / 8; + if ((r = kvm_get_dirty_pages_range(kvm_context, area_start, area_size, dirty_bitmap, NULL, + kvm_get_dirty_bitmap_cb))) { + return r; + } + dirty_bitmap += area_size / TARGET_PAGE_SIZE / 8; + now += area_size; + if (!now) { + break; + } + } + return 0; } void kvm_qemu_log_memory(target_phys_addr_t start, target_phys_addr_t size, -- 1.6.0.2