Ping...
Best regards, -Gonglei > -----Original Message----- > From: Gonglei (Arei) > Sent: Thursday, January 23, 2014 3:47 PM > To: qemu-devel@nongnu.org > Cc: 'Orit Wasserman'; qemu-devel@nongnu.org; Peter Maydell; > anth...@codemonkey.ws; pbonz...@redhat.com; Luonengjun; chenliang (T); > Huangweidong (Hardware); 'Eric Blake' > Subject: [PATCH v3] migration:fix free XBZRLE decoded_buf wrong > > 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 <chenlian...@huawei.com> > Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> > Reviewed-by: Orit Wasserman <owass...@redhat.com> > Signed-off-by: GongLei <arei.gong...@huawei.com> > --- > Changes: > * Removing excess check for g_free > * The structure of XBZRLE is split into two halves. > * Modify patch format > > arch_init.c | 23 ++++++++++++++--------- > include/migration/migration.h | 1 + > migration.c | 1 + > 3 files changed, 16 insertions(+), 9 deletions(-) > > diff --git a/arch_init.c b/arch_init.c > index 77912e7..dd777f3 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) > { > @@ -602,6 +600,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) { > @@ -615,8 +619,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; > } > } > > @@ -807,8 +812,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 */ > @@ -825,10 +830,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 7235c23..3d46804 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); > -- > 1.6.0.2 > > Best regards, > -Gonglei