From nobody Wed Oct 29 06:43:40 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1524664139985662.7656588995122; Wed, 25 Apr 2018 06:48:59 -0700 (PDT) Received: from localhost ([::1]:37009 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBKmv-0004TM-QS for importer@patchew.org; Wed, 25 Apr 2018 09:48:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46383) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fBKlN-0003qc-0A for qemu-devel@nongnu.org; Wed, 25 Apr 2018 09:47:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fBKlI-00072X-7Z for qemu-devel@nongnu.org; Wed, 25 Apr 2018 09:47:13 -0400 Received: from smtp03.citrix.com ([162.221.156.55]:43086) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fBKlH-0006zE-Th for qemu-devel@nongnu.org; Wed, 25 Apr 2018 09:47:08 -0400 X-IronPort-AV: E=Sophos;i="5.49,326,1520899200"; d="scan'208";a="52699921" From: Igor Druzhinin To: , Date: Wed, 25 Apr 2018 14:46:47 +0100 Message-ID: <1524664007-12687-1-git-send-email-igor.druzhinin@citrix.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PATCH] xen/hvm: correct reporting of modified memory under physmap during migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: anthony.perard@citrix.com, pbonzini@redhat.com, sstabellini@kernel.org, paul.durrant@citrix.com, Igor Druzhinin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When global_log_dirty is enabled VRAM modification tracking never worked correctly. The address that is passed to xen_hvm_modified_memory() is not the effective PFN but RAM block address which is not the same for VRAM. We need to make a translation for this address into PFN using physmap. Since there is no way to access physmap properly inside xen_hvm_modified_memory() let's make it a global structure. Signed-off-by: Igor Druzhinin Acked-by: Anthony PERARD --- hw/i386/xen/xen-hvm.c | 37 +++++++++++++++++++------------------ hw/i386/xen/xen-mapcache.c | 2 +- include/sysemu/xen-mapcache.h | 5 ++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index cb85541..0cc0124 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -89,6 +89,8 @@ typedef struct XenPhysmap { QLIST_ENTRY(XenPhysmap) list; } XenPhysmap; =20 +static QLIST_HEAD(, XenPhysmap) xen_physmap; + typedef struct XenIOState { ioservid_t ioservid; shared_iopage_t *shared_page; @@ -109,7 +111,6 @@ typedef struct XenIOState { MemoryListener memory_listener; MemoryListener io_listener; DeviceListener device_listener; - QLIST_HEAD(, XenPhysmap) physmap; hwaddr free_phys_offset; const XenPhysmap *log_for_dirtybit; =20 @@ -276,14 +277,13 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t si= ze, MemoryRegion *mr, g_free(pfn_list); } =20 -static XenPhysmap *get_physmapping(XenIOState *state, - hwaddr start_addr, ram_addr_t size) +static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size) { XenPhysmap *physmap =3D NULL; =20 start_addr &=3D TARGET_PAGE_MASK; =20 - QLIST_FOREACH(physmap, &state->physmap, list) { + QLIST_FOREACH(physmap, &xen_physmap, list) { if (range_covers_byte(physmap->start_addr, physmap->size, start_ad= dr)) { return physmap; } @@ -291,23 +291,21 @@ static XenPhysmap *get_physmapping(XenIOState *state, return NULL; } =20 -#ifdef XEN_COMPAT_PHYSMAP -static hwaddr xen_phys_offset_to_gaddr(hwaddr start_addr, - ram_addr_t size, void *= opaque) +static hwaddr xen_phys_offset_to_gaddr(hwaddr phys_offset, ram_addr_t size) { - hwaddr addr =3D start_addr & TARGET_PAGE_MASK; - XenIOState *xen_io_state =3D opaque; + hwaddr addr =3D phys_offset & TARGET_PAGE_MASK; XenPhysmap *physmap =3D NULL; =20 - QLIST_FOREACH(physmap, &xen_io_state->physmap, list) { + QLIST_FOREACH(physmap, &xen_physmap, list) { if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) { - return physmap->start_addr; + return physmap->start_addr + (phys_offset - physmap->phys_offs= et); } } =20 - return start_addr; + return phys_offset; } =20 +#ifdef XEN_COMPAT_PHYSMAP static int xen_save_physmap(XenIOState *state, XenPhysmap *physmap) { char path[80], value[17]; @@ -357,7 +355,7 @@ static int xen_add_to_physmap(XenIOState *state, hwaddr phys_offset =3D memory_region_get_ram_addr(mr); const char *mr_name; =20 - if (get_physmapping(state, start_addr, size)) { + if (get_physmapping(start_addr, size)) { return 0; } if (size <=3D 0) { @@ -386,7 +384,7 @@ go_physmap: physmap->name =3D mr_name; physmap->phys_offset =3D phys_offset; =20 - QLIST_INSERT_HEAD(&state->physmap, physmap, list); + QLIST_INSERT_HEAD(&xen_physmap, physmap, list); =20 if (runstate_check(RUN_STATE_INMIGRATE)) { /* Now when we have a physmap entry we can replace a dummy mapping= with @@ -425,7 +423,7 @@ static int xen_remove_from_physmap(XenIOState *state, XenPhysmap *physmap =3D NULL; hwaddr phys_offset =3D 0; =20 - physmap =3D get_physmapping(state, start_addr, size); + physmap =3D get_physmapping(start_addr, size); if (physmap =3D=3D NULL) { return -1; } @@ -593,7 +591,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state, int rc, i, j; const XenPhysmap *physmap =3D NULL; =20 - physmap =3D get_physmapping(state, start_addr, size); + physmap =3D get_physmapping(start_addr, size); if (physmap =3D=3D NULL) { /* not handled */ return; @@ -1219,7 +1217,7 @@ static void xen_read_physmap(XenIOState *state) xen_domid, entries[i]); physmap->name =3D xs_read(state->xenstore, 0, path, &len); =20 - QLIST_INSERT_HEAD(&state->physmap, physmap, list); + QLIST_INSERT_HEAD(&xen_physmap, physmap, list); } free(entries); } @@ -1356,7 +1354,6 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion = **ram_memory) qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state); =20 state->memory_listener =3D xen_memory_listener; - QLIST_INIT(&state->physmap); memory_listener_register(&state->memory_listener, &address_space_memor= y); state->log_for_dirtybit =3D NULL; =20 @@ -1372,6 +1369,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion = **ram_memory) goto err; } xen_be_register_common(); + + QLIST_INIT(&xen_physmap); xen_read_physmap(state); =20 /* Disable ACPI build because Xen handles it */ @@ -1474,6 +1473,8 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_ad= dr_t length) int rc; ram_addr_t start_pfn, nb_pages; =20 + start =3D xen_phys_offset_to_gaddr(start, length); + if (length =3D=3D 0) { length =3D TARGET_PAGE_SIZE; } diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c index b1bd426..fa086e1 100644 --- a/hw/i386/xen/xen-mapcache.c +++ b/hw/i386/xen/xen-mapcache.c @@ -318,7 +318,7 @@ tryagain: mapcache->last_entry =3D NULL; #ifdef XEN_COMPAT_PHYSMAP if (!translated && mapcache->phys_offset_to_gaddr) { - phys_addr =3D mapcache->phys_offset_to_gaddr(phys_addr, size, = mapcache->opaque); + phys_addr =3D mapcache->phys_offset_to_gaddr(phys_addr, size); translated =3D true; goto tryagain; } diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h index bd4d49e..a03e2f1 100644 --- a/include/sysemu/xen-mapcache.h +++ b/include/sysemu/xen-mapcache.h @@ -9,9 +9,8 @@ #ifndef XEN_MAPCACHE_H #define XEN_MAPCACHE_H =20 -typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr start_addr, - ram_addr_t size, - void *opaque); +typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset, + ram_addr_t size); #ifdef CONFIG_XEN =20 void xen_map_cache_init(phys_offset_to_gaddr_t f, --=20 2.7.4