summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--MAINTAINERS6
-rw-r--r--Makefile10
-rw-r--r--acl.c4
-rwxr-xr-xconfigure7
-rw-r--r--cpu-all.h4
-rw-r--r--cpus.c14
-rw-r--r--cpus.h1
-rw-r--r--darwin-user/main.c2
-rw-r--r--docs/qapi-code-gen.txt4
-rw-r--r--docs/tracing.txt9
-rw-r--r--exec.c13
-rw-r--r--hw/fw_cfg.c102
-rw-r--r--hw/opencores_eth.c29
-rw-r--r--hw/qxl-render.c36
-rw-r--r--hw/qxl.c26
-rw-r--r--hw/qxl.h3
-rw-r--r--hw/sysbus.c2
-rw-r--r--ia64-dis.c3
-rw-r--r--migration-fd.c23
-rw-r--r--migration.c2
-rw-r--r--net/tap-linux.c6
-rw-r--r--oslib-posix.c22
-rw-r--r--qemu-barrier.h2
-rw-r--r--qemu-tls.h52
-rw-r--r--trace/simple.c19
-rw-r--r--trace/stderr.c17
27 files changed, 294 insertions, 128 deletions
diff --git a/.gitignore b/.gitignore
index 6d2acab09a..406f75f2b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,10 @@ libhw64
 libuser
 linux-headers/asm
 qapi-generated
+qapi-types.[ch]
+qapi-visit.[ch]
+qmp-commands.h
+qmp-marshal.c
 qemu-doc.html
 qemu-tech.html
 qemu-doc.info
diff --git a/MAINTAINERS b/MAINTAINERS
index 4535eeb61f..bccdd4f78f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -303,9 +303,9 @@ M: Alexander Graf <agraf@suse.de>
 S: Maintained
 F: hw/ppc_oldworld.c
 
-Prep
-M: qemu-devel@nongnu.org
-S: Orphan
+PReP
+M: Andreas Färber <andreas.faerber@web.de>
+S: Odd Fixes
 F: hw/ppc_prep.c
 
 SH4 Machines
diff --git a/Makefile b/Makefile
index ba8d738d9b..4f6eaa4ba6 100644
--- a/Makefile
+++ b/Makefile
@@ -75,7 +75,7 @@ defconfig:
 
 -include config-all-devices.mak
 
-build-all: $(DOCS) $(TOOLS) recurse-all
+build-all: $(DOCS) $(TOOLS) $(CHECKS) recurse-all
 
 config-host.h: config-host.h-timestamp
 config-host.h-timestamp: config-host.mak
@@ -219,7 +219,7 @@ clean:
 # avoid old build problems by removing potentially incorrect old files
 	rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
 	rm -f qemu-options.def
-	rm -f *.o *.d *.a *.lo $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~
+	rm -f *.o *.d *.a *.lo $(TOOLS) $(CHECKS) qemu-ga TAGS cscope.* *.pod *~ */*~
 	rm -Rf .libs
 	rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
 	rm -f qemu-img-cmds.h
@@ -305,6 +305,12 @@ endif
 test speed: all
 	$(MAKE) -C tests $@
 
+.PHONY: check
+check: $(patsubst %,run-check-%,$(CHECKS))
+
+run-check-%: %
+	./$<
+
 .PHONY: TAGS
 TAGS:
 	find "$(SRC_PATH)" -name '*.[hc]' -print0 | xargs -0 etags
diff --git a/acl.c b/acl.c
index 0654f38f72..e840b9b633 100644
--- a/acl.c
+++ b/acl.c
@@ -95,13 +95,13 @@ int qemu_acl_party_is_allowed(qemu_acl *acl,
 
 void qemu_acl_reset(qemu_acl *acl)
 {
-    qemu_acl_entry *entry;
+    qemu_acl_entry *entry, *next_entry;
 
     /* Put back to deny by default, so there is no window
      * of "open access" while the user re-initializes the
      * access control list */
     acl->defaultDeny = 1;
-    QTAILQ_FOREACH(entry, &acl->entries, next) {
+    QTAILQ_FOREACH_SAFE(entry, &acl->entries, next, next_entry) {
         QTAILQ_REMOVE(&acl->entries, entry, next);
         free(entry->match);
         free(entry);
diff --git a/configure b/configure
index a6cf6d680d..28667fe35b 100755
--- a/configure
+++ b/configure
@@ -169,7 +169,7 @@ mixemu="no"
 aix="no"
 blobs="yes"
 pkgversion=""
-check_utests="no"
+check_utests=""
 user_pie="no"
 zero_malloc=""
 trace_backend="nop"
@@ -2668,8 +2668,8 @@ if test "$softmmu" = yes ; then
       tools="qemu-ga\$(EXESUF) $tools"
     fi
     if [ "$check_utests" = "yes" ]; then
-      tools="check-qint check-qstring check-qdict check-qlist $tools"
-      tools="check-qfloat check-qjson $tools"
+      checks="check-qint check-qstring check-qdict check-qlist"
+      checks="check-qfloat check-qjson test-coroutine $checks"
     fi
   fi
 fi
@@ -3143,6 +3143,7 @@ if test "$trace_default" = "yes"; then
 fi
 
 echo "TOOLS=$tools" >> $config_host_mak
+echo "CHECKS=$checks" >> $config_host_mak
 echo "ROMS=$roms" >> $config_host_mak
 echo "MAKE=$make" >> $config_host_mak
 echo "INSTALL=$install" >> $config_host_mak
diff --git a/cpu-all.h b/cpu-all.h
index 42a5fa0a7c..5f47ab8df9 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -20,6 +20,7 @@
 #define CPU_ALL_H
 
 #include "qemu-common.h"
+#include "qemu-tls.h"
 #include "cpu-common.h"
 
 /* some important defines:
@@ -334,7 +335,8 @@ void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
 void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 extern CPUState *first_cpu;
-extern CPUState *cpu_single_env;
+DECLARE_TLS(CPUState *,cpu_single_env);
+#define cpu_single_env get_tls(cpu_single_env)
 
 /* Flags for use in ENV->INTERRUPT_PENDING.
 
diff --git a/cpus.c b/cpus.c
index f768683ad6..6aff425235 100644
--- a/cpus.c
+++ b/cpus.c
@@ -748,6 +748,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     return NULL;
 }
 
+static void tcg_exec_all(void);
+
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
@@ -769,7 +771,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     }
 
     while (1) {
-        cpu_exec_all();
+        tcg_exec_all();
         if (use_icount && qemu_clock_deadline(vm_clock) <= 0) {
             qemu_notify_event();
         }
@@ -1016,7 +1018,7 @@ static int tcg_cpu_exec(CPUState *env)
     return ret;
 }
 
-bool cpu_exec_all(void)
+static void tcg_exec_all(void)
 {
     int r;
 
@@ -1033,12 +1035,7 @@ bool cpu_exec_all(void)
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
         if (cpu_can_run(env)) {
-            if (kvm_enabled()) {
-                r = kvm_cpu_exec(env);
-                qemu_kvm_eat_signals(env);
-            } else {
-                r = tcg_cpu_exec(env);
-            }
+            r = tcg_cpu_exec(env);
             if (r == EXCP_DEBUG) {
                 cpu_handle_guest_debug(env);
                 break;
@@ -1048,7 +1045,6 @@ bool cpu_exec_all(void)
         }
     }
     exit_request = 0;
-    return !all_cpu_threads_idle();
 }
 
 void set_numa_modes(void)
diff --git a/cpus.h b/cpus.h
index 3525375756..4ea2fe2c22 100644
--- a/cpus.h
+++ b/cpus.h
@@ -14,7 +14,6 @@ void cpu_synchronize_all_post_init(void);
 /* vl.c */
 extern int smp_cores;
 extern int smp_threads;
-bool cpu_exec_all(void);
 void set_numa_modes(void);
 void set_cpu_log(const char *optarg);
 void set_cpu_log_filename(const char *optarg);
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 1a881a0a60..c0f14f8260 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -729,8 +729,6 @@ static void usage(void)
 
 /* XXX: currently only used for async signals (see signal.c) */
 CPUState *global_env;
-/* used only if single thread */
-CPUState *cpu_single_env = NULL;
 
 /* used to free thread contexts */
 TaskState *first_task_state;
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index f345866f57..c0a9325db8 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -41,7 +41,7 @@ dictionary.  This corresponds to a struct in C or an Object in JSON.  An
 example of a complex type is:
 
  { 'type': 'MyType',
-   'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
+   'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
 
 The use of '*' as a prefix to the name means the member is optional.  Optional
 members should always be added to the end of the dictionary to preserve
@@ -63,7 +63,7 @@ An example command is:
 
  { 'command': 'my-command',
    'data': { 'arg1': 'str', '*arg2': 'str' },
-   'returns': 'str' ]
+   'returns': 'str' }
 
 Command names should be all lower case with words separated by a hyphen.
 
diff --git a/docs/tracing.txt b/docs/tracing.txt
index 95ca16c05d..ea29f2c222 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -132,12 +132,19 @@ This functionality is also provided through monitor commands:
   means disabled.
 
 * trace-event NAME on|off
-  Enable/disable a given trace event.
+  Enable/disable a given trace event or a group of events having common prefix
+  through wildcard.
 
 The "-trace events=<file>" command line argument can be used to enable the
 events listed in <file> from the very beginning of the program. This file must
 contain one event name per line.
 
+A basic wildcard matching is supported in both the monitor command "trace
+-event" and the events list file. That means you can enable/disable the events
+having a common prefix in a batch. For example, virtio-blk trace events could
+be enabled using:
+  trace-event virtio_blk_* on
+
 == Trace backends ==
 
 The "tracetool" script automates tedious trace event code generation and also
diff --git a/exec.c b/exec.c
index 2f3c6a0ce3..6b92198e62 100644
--- a/exec.c
+++ b/exec.c
@@ -120,7 +120,7 @@ static MemoryRegion *system_io;
 CPUState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
-CPUState *cpu_single_env;
+DEFINE_TLS(CPUState *,cpu_single_env);
 /* 0 = Do not count executed instructions.
    1 = Precise instruction counting.
    2 = Adaptive rate instruction counting.  */
@@ -2873,7 +2873,7 @@ static void *file_ram_alloc(RAMBlock *block,
 static ram_addr_t find_ram_offset(ram_addr_t size)
 {
     RAMBlock *block, *next_block;
-    ram_addr_t offset = 0, mingap = RAM_ADDR_MAX;
+    ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX;
 
     if (QLIST_EMPTY(&ram_list.blocks))
         return 0;
@@ -2889,10 +2889,17 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
             }
         }
         if (next - end >= size && next - end < mingap) {
-            offset =  end;
+            offset = end;
             mingap = next - end;
         }
     }
+
+    if (offset == RAM_ADDR_MAX) {
+        fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n",
+                (uint64_t)size);
+        abort();
+    }
+
     return offset;
 }
 
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 8df265c61d..dbcb888bbd 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -60,71 +60,55 @@ struct FWCfgState {
 #define JPG_FILE 0
 #define BMP_FILE 1
 
-static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep)
+static char *read_splashfile(char *filename, int *file_sizep, int *file_typep)
 {
-    FILE *fp = NULL;
-    int fop_ret;
-    int file_size;
+    GError *err = NULL;
+    gboolean res;
+    gchar *content;
     int file_type = -1;
-    unsigned char buf[2] = {0, 0};
-    unsigned int filehead_value = 0;
+    unsigned int filehead = 0;
     int bmp_bpp;
 
-    fp = fopen(filename, "rb");
-    if (fp == NULL) {
-        error_report("failed to open file '%s'.", filename);
-        return fp;
+    res = g_file_get_contents(filename, &content, (gsize *)file_sizep, &err);
+    if (res == FALSE) {
+        error_report("failed to read splash file '%s'", filename);
+        g_error_free(err);
+        return NULL;
     }
+
     /* check file size */
-    fseek(fp, 0L, SEEK_END);
-    file_size = ftell(fp);
-    if (file_size < 2) {
-        error_report("file size is less than 2 bytes '%s'.", filename);
-        fclose(fp);
-        fp = NULL;
-        return fp;
+    if (*file_sizep < 30) {
+        goto error;
     }
+
     /* check magic ID */
-    fseek(fp, 0L, SEEK_SET);
-    fop_ret = fread(buf, 1, 2, fp);
-    if (fop_ret != 2) {
-        error_report("Could not read header from '%s': %s",
-                     filename, strerror(errno));
-        fclose(fp);
-        fp = NULL;
-        return fp;
-    }
-    filehead_value = (buf[0] + (buf[1] << 8)) & 0xffff;
-    if (filehead_value == 0xd8ff) {
+    filehead = ((content[0] & 0xff) + (content[1] << 8)) & 0xffff;
+    if (filehead == 0xd8ff) {
         file_type = JPG_FILE;
+    } else if (filehead == 0x4d42) {
+        file_type = BMP_FILE;
     } else {
-        if (filehead_value == 0x4d42) {
-            file_type = BMP_FILE;
-        }
-    }
-    if (file_type < 0) {
-        error_report("'%s' not jpg/bmp file,head:0x%x.",
-                         filename, filehead_value);
-        fclose(fp);
-        fp = NULL;
-        return fp;
+        goto error;
     }
+
     /* check BMP bpp */
     if (file_type == BMP_FILE) {
-        fseek(fp, 28, SEEK_SET);
-        fop_ret = fread(buf, 1, 2, fp);
-        bmp_bpp = (buf[0] + (buf[1] << 8)) & 0xffff;
+        bmp_bpp = (content[28] + (content[29] << 8)) & 0xffff;
         if (bmp_bpp != 24) {
-            error_report("only 24bpp bmp file is supported.");
-            fclose(fp);
-            fp = NULL;
-            return fp;
+            goto error;
         }
     }
+
     /* return values */
-    *file_sizep = file_size;
     *file_typep = file_type;
-    return fp;
+
+    return content;
+
+error:
+    error_report("splash file '%s' format not recognized; must be JPEG "
+                 "or 24 bit BMP", filename);
+    g_free(content);
+    return NULL;
 }
 
 static void fw_cfg_bootsplash(FWCfgState *s)
@@ -132,9 +116,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
     int boot_splash_time = -1;
     const char *boot_splash_filename = NULL;
     char *p;
-    char *filename;
-    FILE *fp;
-    int fop_ret;
+    char *filename, *file_data;
     int file_size;
     int file_type = -1;
     const char *temp;
@@ -174,27 +156,19 @@ static void fw_cfg_bootsplash(FWCfgState *s)
             error_report("failed to find file '%s'.", boot_splash_filename);
             return;
         }
-        /* probing the file */
-        fp = probe_splashfile(filename, &file_size, &file_type);
-        if (fp == NULL) {
+
+        /* loading file data */
+        file_data = read_splashfile(filename, &file_size, &file_type);
+        if (file_data == NULL) {
             g_free(filename);
             return;
         }
-        /* loading file data */
         if (boot_splash_filedata != NULL) {
             g_free(boot_splash_filedata);
         }
-        boot_splash_filedata = g_malloc(file_size);
+        boot_splash_filedata = (uint8_t *)file_data;
         boot_splash_filedata_size = file_size;
-        fseek(fp, 0L, SEEK_SET);
-        fop_ret = fread(boot_splash_filedata, 1, file_size, fp);
-        if (fop_ret != file_size) {
-            error_report("failed to read data from '%s'.",
-                         boot_splash_filename);
-            fclose(fp);
-            return;
-        }
-        fclose(fp);
+
         /* insert data */
         if (file_type == JPG_FILE) {
             fw_cfg_add_file(s, "bootsplash.jpg",
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index 64b616ec1c..2c1e475395 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -382,6 +382,7 @@ static ssize_t open_eth_receive(VLANClientState *nc,
     OpenEthState *s = DO_UPCAST(NICState, nc, nc)->opaque;
     size_t maxfl = GET_REGFIELD(s, PACKETLEN, MAXFL);
     size_t minfl = GET_REGFIELD(s, PACKETLEN, MINFL);
+    size_t fcsl = 4;
     bool miss = true;
 
     trace_open_eth_receive((unsigned)size);
@@ -418,6 +419,7 @@ static ssize_t open_eth_receive(VLANClientState *nc,
 #else
     {
 #endif
+        static const uint8_t zero[64] = {0};
         desc *desc = rx_desc(s);
         size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl;
 
@@ -426,11 +428,13 @@ static ssize_t open_eth_receive(VLANClientState *nc,
 
         if (copy_size > size) {
             copy_size = size;
+        } else {
+            fcsl = 0;
         }
         if (miss) {
             desc->len_flags |= RXD_M;
         }
-        if (size > maxfl) {
+        if (GET_REGBIT(s, MODER, HUGEN) && size > maxfl) {
             desc->len_flags |= RXD_TL;
         }
 #ifdef USE_RECSMALL
@@ -442,13 +446,28 @@ static ssize_t open_eth_receive(VLANClientState *nc,
         cpu_physical_memory_write(desc->buf_ptr, buf, copy_size);
 
         if (GET_REGBIT(s, MODER, PAD) && copy_size < minfl) {
-            static const uint8_t zero[65536] = {0};
+            if (minfl - copy_size > fcsl) {
+                fcsl = 0;
+            } else {
+                fcsl -= minfl - copy_size;
+            }
+            while (copy_size < minfl) {
+                size_t zero_sz = minfl - copy_size < sizeof(zero) ?
+                    minfl - copy_size : sizeof(zero);
 
-            cpu_physical_memory_write(desc->buf_ptr + copy_size,
-                    zero, minfl - copy_size);
-            copy_size = minfl;
+                cpu_physical_memory_write(desc->buf_ptr + copy_size,
+                        zero, zero_sz);
+                copy_size += zero_sz;
+            }
         }
 
+        /* There's no FCS in the frames handed to us by the QEMU, zero fill it.
+         * Don't do it if the frame is cut at the MAXFL or padded with 4 or
+         * more bytes to the MINFL.
+         */
+        cpu_physical_memory_write(desc->buf_ptr + copy_size, zero, fcsl);
+        copy_size += fcsl;
+
         SET_FIELD(desc->len_flags, RXD_LEN, copy_size);
 
         if ((desc->len_flags & RXD_WRAP) || s->rx_desc == 0x7f) {
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index c290739de0..2c51ba9806 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -28,16 +28,16 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect)
     int len, i;
 
     src += (qxl->guest_primary.surface.height - rect->top - 1) *
-        qxl->guest_primary.stride;
-    dst += rect->top  * qxl->guest_primary.stride;
+        qxl->guest_primary.abs_stride;
+    dst += rect->top  * qxl->guest_primary.abs_stride;
     src += rect->left * qxl->guest_primary.bytes_pp;
     dst += rect->left * qxl->guest_primary.bytes_pp;
     len  = (rect->right - rect->left) * qxl->guest_primary.bytes_pp;
 
     for (i = rect->top; i < rect->bottom; i++) {
         memcpy(dst, src, len);
-        dst += qxl->guest_primary.stride;
-        src -= qxl->guest_primary.stride;
+        dst += qxl->guest_primary.abs_stride;
+        src -= qxl->guest_primary.abs_stride;
     }
 }
 
@@ -45,7 +45,8 @@ void qxl_render_resize(PCIQXLDevice *qxl)
 {
     QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
 
-    qxl->guest_primary.stride = sc->stride;
+    qxl->guest_primary.qxl_stride = sc->stride;
+    qxl->guest_primary.abs_stride = abs(sc->stride);
     qxl->guest_primary.resized++;
     switch (sc->format) {
     case SPICE_SURFACE_FMT_16_555:
@@ -75,7 +76,14 @@ void qxl_render_update(PCIQXLDevice *qxl)
     VGACommonState *vga = &qxl->vga;
     QXLRect dirty[32], update;
     void *ptr;
-    int i;
+    int i, redraw = 0;
+
+    if (!is_buffer_shared(vga->ds->surface)) {
+        dprint(qxl, 1, "%s: restoring shared displaysurface\n", __func__);
+        qxl->guest_primary.resized++;
+        qxl->guest_primary.commands++;
+        redraw = 1;
+    }
 
     if (qxl->guest_primary.resized) {
         qxl->guest_primary.resized = 0;
@@ -87,11 +95,11 @@ void qxl_render_update(PCIQXLDevice *qxl)
         qemu_free_displaysurface(vga->ds);
 
         qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
-        if (qxl->guest_primary.stride < 0) {
+        if (qxl->guest_primary.qxl_stride < 0) {
             /* spice surface is upside down -> need extra buffer to flip */
-            qxl->guest_primary.stride = -qxl->guest_primary.stride;
-            qxl->guest_primary.flipped = g_malloc(qxl->guest_primary.surface.width *
-                                                     qxl->guest_primary.stride);
+            qxl->guest_primary.flipped =
+                g_malloc(qxl->guest_primary.surface.width *
+                         qxl->guest_primary.abs_stride);
             ptr = qxl->guest_primary.flipped;
         } else {
             ptr = qxl->guest_primary.data;
@@ -100,7 +108,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
                __FUNCTION__,
                qxl->guest_primary.surface.width,
                qxl->guest_primary.surface.height,
-               qxl->guest_primary.stride,
+               qxl->guest_primary.qxl_stride,
                qxl->guest_primary.bytes_pp,
                qxl->guest_primary.bits_pp,
                qxl->guest_primary.flipped ? "yes" : "no");
@@ -108,7 +116,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
             qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
                                             qxl->guest_primary.surface.height,
                                             qxl->guest_primary.bits_pp,
-                                            qxl->guest_primary.stride,
+                                            qxl->guest_primary.abs_stride,
                                             ptr);
         dpy_resize(vga->ds);
     }
@@ -126,6 +134,10 @@ void qxl_render_update(PCIQXLDevice *qxl)
     memset(dirty, 0, sizeof(dirty));
     qxl_spice_update_area(qxl, 0, &update,
                           dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
+    if (redraw) {
+        memset(dirty, 0, sizeof(dirty));
+        dirty[0] = update;
+    }
 
     for (i = 0; i < ARRAY_SIZE(dirty); i++) {
         if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 12f71aa56c..84ffd45c0c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1663,12 +1663,25 @@ static int qxl_pre_load(void *opaque)
     return 0;
 }
 
+static void qxl_create_memslots(PCIQXLDevice *d)
+{
+    int i;
+
+    for (i = 0; i < NUM_MEMSLOTS; i++) {
+        if (!d->guest_slots[i].active) {
+            continue;
+        }
+        dprint(d, 1, "%s: restoring guest slot %d\n", __func__, i);
+        qxl_add_memslot(d, i, 0, QXL_SYNC);
+    }
+}
+
 static int qxl_post_load(void *opaque, int version)
 {
     PCIQXLDevice* d = opaque;
     uint8_t *ram_start = d->vga.vram_ptr;
     QXLCommandExt *cmds;
-    int in, out, i, newmode;
+    int in, out, newmode;
 
     dprint(d, 1, "%s: start\n", __FUNCTION__);
 
@@ -1685,19 +1698,16 @@ static int qxl_post_load(void *opaque, int version)
         qxl_mode_to_string(d->mode));
     newmode = d->mode;
     d->mode = QXL_MODE_UNDEFINED;
+
     switch (newmode) {
     case QXL_MODE_UNDEFINED:
         break;
     case QXL_MODE_VGA:
+        qxl_create_memslots(d);
         qxl_enter_vga_mode(d);
         break;
     case QXL_MODE_NATIVE:
-        for (i = 0; i < NUM_MEMSLOTS; i++) {
-            if (!d->guest_slots[i].active) {
-                continue;
-            }
-            qxl_add_memslot(d, i, 0, QXL_SYNC);
-        }
+        qxl_create_memslots(d);
         qxl_create_guest_primary(d, 1, QXL_SYNC);
 
         /* replay surface-create and cursor-set commands */
@@ -1722,6 +1732,8 @@ static int qxl_post_load(void *opaque, int version)
 
         break;
     case QXL_MODE_COMPAT:
+        /* note: no need to call qxl_create_memslots, qxl_set_mode
+         * creates the mem slot. */
         qxl_set_mode(d, d->shadow_rom.mode, 1);
         break;
     }
diff --git a/hw/qxl.h b/hw/qxl.h
index 37b2619e55..766aa6d68e 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -48,7 +48,8 @@ typedef struct PCIQXLDevice {
         QXLSurfaceCreate surface;
         uint32_t       commands;
         uint32_t       resized;
-        int32_t        stride;
+        int32_t        qxl_stride;
+        uint32_t       abs_stride;
         uint32_t       bits_pp;
         uint32_t       bytes_pp;
         uint8_t        *data, *flipped;
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 4fab5a41b2..fd2fc6a51d 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -198,6 +198,7 @@ DeviceState *sysbus_create_varargs(const char *name,
         sysbus_connect_irq(s, n, irq);
         n++;
     }
+    va_end(va);
     return dev;
 }
 
@@ -229,6 +230,7 @@ DeviceState *sysbus_try_create_varargs(const char *name,
         sysbus_connect_irq(s, n, irq);
         n++;
     }
+    va_end(va);
     return dev;
 }
 
diff --git a/ia64-dis.c b/ia64-dis.c
index 2886df3614..2a103e6b5c 100644
--- a/ia64-dis.c
+++ b/ia64-dis.c
@@ -781,6 +781,9 @@ ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
   return 0;
 }
 
+/* glib.h defines ABS so we must undefine it to avoid a clash */
+#undef ABS
+
 #define CST	IA64_OPND_CLASS_CST
 #define REG	IA64_OPND_CLASS_REG
 #define IND	IA64_OPND_CLASS_IND
diff --git a/migration-fd.c b/migration-fd.c
index d0aec89e8d..6211124a05 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -42,10 +42,31 @@ static int fd_write(MigrationState *s, const void * buf, size_t size)
 
 static int fd_close(MigrationState *s)
 {
+    struct stat st;
+    int ret;
+
     DPRINTF("fd_close\n");
     if (s->fd != -1) {
-        close(s->fd);
+        ret = fstat(s->fd, &st);
+        if (ret == 0 && S_ISREG(st.st_mode)) {
+            /*
+             * If the file handle is a regular file make sure the
+             * data is flushed to disk before signaling success.
+             */
+            ret = fsync(s->fd);
+            if (ret != 0) {
+                ret = -errno;
+                perror("migration-fd: fsync");
+                return ret;
+            }
+        }
+        ret = close(s->fd);
         s->fd = -1;
+        if (ret != 0) {
+            ret = -errno;
+            perror("migration-fd: close");
+            return ret;
+        }
     }
     return 0;
 }
diff --git a/migration.c b/migration.c
index 3b4abbde64..4b17566857 100644
--- a/migration.c
+++ b/migration.c
@@ -216,7 +216,7 @@ static void migrate_fd_put_notify(void *opaque)
 
     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
     qemu_file_put_notify(s->file);
-    if (qemu_file_get_error(s->file)) {
+    if (s->file && qemu_file_get_error(s->file)) {
         migrate_fd_error(s);
     }
 }
diff --git a/net/tap-linux.c b/net/tap-linux.c
index ff8cad0ea0..41d581b734 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -73,7 +73,11 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
         pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
     ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
     if (ret != 0) {
-        error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name);
+        if (ifname[0] != '\0') {
+            error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name);
+        } else {
+            error_report("could not configure %s: %m", PATH_NET_TUN);
+        }
         close(fd);
         return -1;
     }
diff --git a/oslib-posix.c b/oslib-posix.c
index dbc8ee8960..6f297626c7 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -36,8 +36,11 @@ extern int daemon(int, int);
 #endif
 
 #if defined(__linux__) && defined(__x86_64__)
-   /* Use 2MB alignment so transparent hugepages can be used by KVM */
+   /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
+      Valgrind does not support alignments larger than 1 MiB,
+      therefore we need special code which handles running on Valgrind. */
 #  define QEMU_VMALLOC_ALIGN (512 * 4096)
+#  define CONFIG_VALGRIND
 #else
 #  define QEMU_VMALLOC_ALIGN getpagesize()
 #endif
@@ -47,7 +50,11 @@ extern int daemon(int, int);
 #include "trace.h"
 #include "qemu_socket.h"
 
-
+#if defined(CONFIG_VALGRIND)
+static int running_on_valgrind = -1;
+#else
+#  define running_on_valgrind 0
+#endif
 
 int qemu_daemon(int nochdir, int noclose)
 {
@@ -89,7 +96,16 @@ void *qemu_vmalloc(size_t size)
     void *ptr;
     size_t align = QEMU_VMALLOC_ALIGN;
 
-    if (size < align) {
+#if defined(CONFIG_VALGRIND)
+    if (running_on_valgrind < 0) {
+        /* First call, test whether we are running on Valgrind.
+           This is a substitute for RUNNING_ON_VALGRIND from valgrind.h. */
+        const char *ld = getenv("LD_PRELOAD");
+        running_on_valgrind = (ld != NULL && strstr(ld, "vgpreload"));
+    }
+#endif
+
+    if (size < align || running_on_valgrind) {
         align = getpagesize();
     }
     ptr = qemu_memalign(align, size);
diff --git a/qemu-barrier.h b/qemu-barrier.h
index 735eea6cf9..c11bb2b59f 100644
--- a/qemu-barrier.h
+++ b/qemu-barrier.h
@@ -14,7 +14,7 @@
  */
 #define smp_wmb()   barrier()
 
-#elif defined(__powerpc__)
+#elif defined(_ARCH_PPC)
 
 /*
  * We use an eieio() for a wmb() on powerpc.  This assumes we don't
diff --git a/qemu-tls.h b/qemu-tls.h
new file mode 100644
index 0000000000..5b70f10f8f
--- /dev/null
+++ b/qemu-tls.h
@@ -0,0 +1,52 @@
+/*
+ * Abstraction layer for defining and using TLS variables
+ *
+ * Copyright (c) 2011 Red Hat, Inc
+ * Copyright (c) 2011 Linaro Limited
+ *
+ * Authors:
+ *  Paolo Bonzini <pbonzini@redhat.com>
+ *  Peter Maydell <peter.maydell@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_TLS_H
+#define QEMU_TLS_H
+
+/* Per-thread variables. Note that we only have implementations
+ * which are really thread-local on Linux; the dummy implementations
+ * define plain global variables.
+ *
+ * This means that for the moment use should be restricted to
+ * per-VCPU variables, which are OK because:
+ *  - the only -user mode supporting multiple VCPU threads is linux-user
+ *  - TCG system mode is single-threaded regarding VCPUs
+ *  - KVM system mode is multi-threaded but limited to Linux
+ *
+ * TODO: proper implementations via Win32 .tls sections and
+ * POSIX pthread_getspecific.
+ */
+#ifdef __linux__
+#define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x)
+#define DEFINE_TLS(type, x)  __thread __typeof__(type) tls__##x
+#define get_tls(x)           tls__##x
+#else
+/* Dummy implementations which define plain global variables */
+#define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x)
+#define DEFINE_TLS(type, x)  __typeof__(type) tls__##x
+#define get_tls(x)           tls__##x
+#endif
+
+#endif
diff --git a/trace/simple.c b/trace/simple.c
index b639dda806..6339152d27 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -324,14 +324,29 @@ void trace_print_events(FILE *stream, fprintf_function stream_printf)
 bool trace_event_set_state(const char *name, bool state)
 {
     unsigned int i;
-
+    unsigned int len;
+    bool wildcard = false;
+    bool matched = false;
+
+    len = strlen(name);
+    if (len > 0 && name[len - 1] == '*') {
+        wildcard = true;
+        len -= 1;
+    }
     for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        if (wildcard) {
+            if (!strncmp(trace_list[i].tp_name, name, len)) {
+                trace_list[i].state = state;
+                matched = true;
+            }
+            continue;
+        }
         if (!strcmp(trace_list[i].tp_name, name)) {
             trace_list[i].state = state;
             return true;
         }
     }
-    return false;
+    return matched;
 }
 
 /* Helper function to create a thread with signals blocked.  Use glib's
diff --git a/trace/stderr.c b/trace/stderr.c
index 7107c4a131..0810d6f956 100644
--- a/trace/stderr.c
+++ b/trace/stderr.c
@@ -15,14 +15,29 @@ void trace_print_events(FILE *stream, fprintf_function stream_printf)
 bool trace_event_set_state(const char *name, bool state)
 {
     unsigned int i;
+    unsigned int len;
+    bool wildcard = false;
+    bool matched = false;
 
+    len = strlen(name);
+    if (len > 0 && name[len - 1] == '*') {
+        wildcard = true;
+        len -= 1;
+    }
     for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        if (wildcard) {
+            if (!strncmp(trace_list[i].tp_name, name, len)) {
+                trace_list[i].state = state;
+                matched = true;
+            }
+            continue;
+        }
         if (!strcmp(trace_list[i].tp_name, name)) {
             trace_list[i].state = state;
             return true;
         }
     }
-    return false;
+    return matched;
 }
 
 bool trace_backend_init(const char *events, const char *file)