From patchwork Thu Jan 30 07:14:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Orit Wasserman X-Patchwork-Id: 315271 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 450D52C00C1 for ; Thu, 30 Jan 2014 18:14:41 +1100 (EST) Received: from localhost ([::1]:46732 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8lpe-0000IM-Mj for incoming@patchwork.ozlabs.org; Thu, 30 Jan 2014 02:14:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43213) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8lp6-00007r-J4 for qemu-devel@nongnu.org; Thu, 30 Jan 2014 02:14:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W8lp2-0003fn-3w for qemu-devel@nongnu.org; Thu, 30 Jan 2014 02:14:04 -0500 Received: from mx1.redhat.com ([209.132.183.28]:20878) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8lp1-0003fh-S9 for qemu-devel@nongnu.org; Thu, 30 Jan 2014 02:14:00 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s0U7Dswj032100 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 30 Jan 2014 02:13:54 -0500 Received: from dhcp-1-120.tlv.redhat.com (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s0U7DhZp011122; Thu, 30 Jan 2014 02:13:52 -0500 From: Orit Wasserman To: qemu-devel@nongnu.org Date: Thu, 30 Jan 2014 09:14:12 +0200 Message-Id: <1391066055-17024-4-git-send-email-owasserm@redhat.com> In-Reply-To: <1391066055-17024-1-git-send-email-owasserm@redhat.com> References: <1391066055-17024-1-git-send-email-owasserm@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: ChenLiang , peter.maydell@linaro.org, "Gonglei \(Arei\)" , anthony@codemonkey.ws, quintela@redhat.com Subject: [Qemu-devel] [PATCH 3/6] migration:fix free XBZRLE decoded_buf wrong 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 From: "Gonglei (Arei)" When qemu do live migration with xbzrle, qemu malloc decoded_buf at destination end but free it at source end. It will crash qemu by double free error in some scenarios. Splitting the XBZRLE structure for clear logic distinguishing src/dst side. Signed-off-by: ChenLiang Reviewed-by: Peter Maydell Reviewed-by: Orit Wasserman Signed-off-by: GongLei Reviewed-by: Juan Quintela --- arch_init.c | 22 ++++++++++++---------- include/migration/migration.h | 1 + migration.c | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/arch_init.c b/arch_init.c index 8edeabe..5eff80b 100644 --- a/arch_init.c +++ b/arch_init.c @@ -164,17 +164,15 @@ static struct { uint8_t *encoded_buf; /* buffer for storing page content */ uint8_t *current_buf; - /* buffer used for XBZRLE decoding */ - uint8_t *decoded_buf; /* Cache for XBZRLE */ PageCache *cache; } XBZRLE = { .encoded_buf = NULL, .current_buf = NULL, - .decoded_buf = NULL, .cache = NULL, }; - +/* buffer used for XBZRLE decoding */ +static uint8_t *xbzrle_decoded_buf; int64_t xbzrle_cache_resize(int64_t new_size) { @@ -606,6 +604,12 @@ uint64_t ram_bytes_total(void) return total; } +void free_xbzrle_decoded_buf(void) +{ + g_free(xbzrle_decoded_buf); + xbzrle_decoded_buf = NULL; +} + static void migration_end(void) { if (migration_bitmap) { @@ -619,11 +623,9 @@ static void migration_end(void) g_free(XBZRLE.cache); g_free(XBZRLE.encoded_buf); g_free(XBZRLE.current_buf); - g_free(XBZRLE.decoded_buf); XBZRLE.cache = NULL; XBZRLE.encoded_buf = NULL; XBZRLE.current_buf = NULL; - XBZRLE.decoded_buf = NULL; } } @@ -814,8 +816,8 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) unsigned int xh_len; int xh_flags; - if (!XBZRLE.decoded_buf) { - XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE); + if (!xbzrle_decoded_buf) { + xbzrle_decoded_buf = g_malloc(TARGET_PAGE_SIZE); } /* extract RLE header */ @@ -832,10 +834,10 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) return -1; } /* load data and decode */ - qemu_get_buffer(f, XBZRLE.decoded_buf, xh_len); + qemu_get_buffer(f, xbzrle_decoded_buf, xh_len); /* decode RLE */ - ret = xbzrle_decode_buffer(XBZRLE.decoded_buf, xh_len, host, + ret = xbzrle_decode_buffer(xbzrle_decoded_buf, xh_len, host, TARGET_PAGE_SIZE); if (ret == -1) { fprintf(stderr, "Failed to load XBZRLE page - decode error!\n"); diff --git a/include/migration/migration.h b/include/migration/migration.h index bfa3951..3e1e6c7 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -109,6 +109,7 @@ MigrationState *migrate_get_current(void); uint64_t ram_bytes_remaining(void); uint64_t ram_bytes_transferred(void); uint64_t ram_bytes_total(void); +void free_xbzrle_decoded_buf(void); void acct_update_position(QEMUFile *f, size_t size, bool zero); diff --git a/migration.c b/migration.c index 84587e9..46a7305 100644 --- a/migration.c +++ b/migration.c @@ -105,6 +105,7 @@ static void process_incoming_migration_co(void *opaque) ret = qemu_loadvm_state(f); qemu_fclose(f); + free_xbzrle_decoded_buf(); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); exit(EXIT_FAILURE);