summaryrefslogtreecommitdiffstats
path: root/arch_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch_init.c')
-rw-r--r--arch_init.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/arch_init.c b/arch_init.c
index 77912e7..80574a0 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -164,20 +164,22 @@ 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)
{
+ if (new_size < TARGET_PAGE_SIZE) {
+ return -1;
+ }
+
if (XBZRLE.cache != NULL) {
return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) *
TARGET_PAGE_SIZE;
@@ -282,7 +284,9 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
if (!cache_is_cached(XBZRLE.cache, current_addr)) {
if (!last_stage) {
- cache_insert(XBZRLE.cache, current_addr, current_data);
+ if (cache_insert(XBZRLE.cache, current_addr, current_data) == -1) {
+ return -1;
+ }
}
acct_info.xbzrle_cache_miss++;
return -1;
@@ -602,6 +606,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 +625,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;
}
}
@@ -655,8 +666,22 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
DPRINTF("Error creating cache\n");
return -1;
}
- XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
- XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE);
+
+ /* We prefer not to abort if there is no memory */
+ XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
+ if (!XBZRLE.encoded_buf) {
+ DPRINTF("Error allocating encoded_buf\n");
+ return -1;
+ }
+
+ XBZRLE.current_buf = g_try_malloc(TARGET_PAGE_SIZE);
+ if (!XBZRLE.current_buf) {
+ DPRINTF("Error allocating current_buf\n");
+ g_free(XBZRLE.encoded_buf);
+ XBZRLE.encoded_buf = NULL;
+ return -1;
+ }
+
acct_clear();
}
@@ -807,8 +832,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 +850,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");
OpenPOWER on IntegriCloud