mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
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 <chenliang88@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Orit Wasserman <owasserm@redhat.com> Signed-off-by: GongLei <arei.gonglei@huawei.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
parent
c91e681a55
commit
905f26f222
22
arch_init.c
22
arch_init.c
@ -164,17 +164,15 @@ static struct {
|
|||||||
uint8_t *encoded_buf;
|
uint8_t *encoded_buf;
|
||||||
/* buffer for storing page content */
|
/* buffer for storing page content */
|
||||||
uint8_t *current_buf;
|
uint8_t *current_buf;
|
||||||
/* buffer used for XBZRLE decoding */
|
|
||||||
uint8_t *decoded_buf;
|
|
||||||
/* Cache for XBZRLE */
|
/* Cache for XBZRLE */
|
||||||
PageCache *cache;
|
PageCache *cache;
|
||||||
} XBZRLE = {
|
} XBZRLE = {
|
||||||
.encoded_buf = NULL,
|
.encoded_buf = NULL,
|
||||||
.current_buf = NULL,
|
.current_buf = NULL,
|
||||||
.decoded_buf = NULL,
|
|
||||||
.cache = NULL,
|
.cache = NULL,
|
||||||
};
|
};
|
||||||
|
/* buffer used for XBZRLE decoding */
|
||||||
|
static uint8_t *xbzrle_decoded_buf;
|
||||||
|
|
||||||
int64_t xbzrle_cache_resize(int64_t new_size)
|
int64_t xbzrle_cache_resize(int64_t new_size)
|
||||||
{
|
{
|
||||||
@ -606,6 +604,12 @@ uint64_t ram_bytes_total(void)
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_xbzrle_decoded_buf(void)
|
||||||
|
{
|
||||||
|
g_free(xbzrle_decoded_buf);
|
||||||
|
xbzrle_decoded_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void migration_end(void)
|
static void migration_end(void)
|
||||||
{
|
{
|
||||||
if (migration_bitmap) {
|
if (migration_bitmap) {
|
||||||
@ -619,11 +623,9 @@ static void migration_end(void)
|
|||||||
g_free(XBZRLE.cache);
|
g_free(XBZRLE.cache);
|
||||||
g_free(XBZRLE.encoded_buf);
|
g_free(XBZRLE.encoded_buf);
|
||||||
g_free(XBZRLE.current_buf);
|
g_free(XBZRLE.current_buf);
|
||||||
g_free(XBZRLE.decoded_buf);
|
|
||||||
XBZRLE.cache = NULL;
|
XBZRLE.cache = NULL;
|
||||||
XBZRLE.encoded_buf = NULL;
|
XBZRLE.encoded_buf = NULL;
|
||||||
XBZRLE.current_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;
|
unsigned int xh_len;
|
||||||
int xh_flags;
|
int xh_flags;
|
||||||
|
|
||||||
if (!XBZRLE.decoded_buf) {
|
if (!xbzrle_decoded_buf) {
|
||||||
XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE);
|
xbzrle_decoded_buf = g_malloc(TARGET_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract RLE header */
|
/* extract RLE header */
|
||||||
@ -832,10 +834,10 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* load data and decode */
|
/* load data and decode */
|
||||||
qemu_get_buffer(f, XBZRLE.decoded_buf, xh_len);
|
qemu_get_buffer(f, xbzrle_decoded_buf, xh_len);
|
||||||
|
|
||||||
/* decode RLE */
|
/* 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);
|
TARGET_PAGE_SIZE);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");
|
fprintf(stderr, "Failed to load XBZRLE page - decode error!\n");
|
||||||
|
@ -109,6 +109,7 @@ MigrationState *migrate_get_current(void);
|
|||||||
uint64_t ram_bytes_remaining(void);
|
uint64_t ram_bytes_remaining(void);
|
||||||
uint64_t ram_bytes_transferred(void);
|
uint64_t ram_bytes_transferred(void);
|
||||||
uint64_t ram_bytes_total(void);
|
uint64_t ram_bytes_total(void);
|
||||||
|
void free_xbzrle_decoded_buf(void);
|
||||||
|
|
||||||
void acct_update_position(QEMUFile *f, size_t size, bool zero);
|
void acct_update_position(QEMUFile *f, size_t size, bool zero);
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ static void process_incoming_migration_co(void *opaque)
|
|||||||
|
|
||||||
ret = qemu_loadvm_state(f);
|
ret = qemu_loadvm_state(f);
|
||||||
qemu_fclose(f);
|
qemu_fclose(f);
|
||||||
|
free_xbzrle_decoded_buf();
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "load of migration failed\n");
|
fprintf(stderr, "load of migration failed\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
Loading…
Reference in New Issue
Block a user