summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.mailmap18
-rw-r--r--VERSION2
-rw-r--r--accel/tcg/tcg-runtime-gvec.c2
-rw-r--r--block/file-posix.c19
-rw-r--r--block/gluster.c21
-rw-r--r--block/rbd.c7
-rw-r--r--blockjob.c28
-rwxr-xr-xconfigure11
-rw-r--r--contrib/libvhost-user/libvhost-user.h1
-rw-r--r--docs/interop/vhost-user.txt21
-rw-r--r--dump.c4
-rw-r--r--exec.c1
-rw-r--r--gdbstub.c3
-rw-r--r--hw/block/vhost-user-blk.c4
-rw-r--r--hw/char/virtio-serial-bus.c7
-rw-r--r--hw/dma/i82374.c9
-rw-r--r--hw/i386/kvm/clock.c14
-rw-r--r--hw/s390x/ipl.c112
-rw-r--r--hw/s390x/s390-virtio-ccw.c5
-rw-r--r--hw/scsi/scsi-disk.c39
-rw-r--r--hw/scsi/scsi-generic.c48
-rw-r--r--hw/vfio/ccw.c2
-rw-r--r--hw/vfio/common.c11
-rw-r--r--hw/vfio/trace-events1
-rw-r--r--hw/virtio/vhost-user.c22
-rw-r--r--hw/virtio/vhost.c16
-rw-r--r--include/hw/scsi/scsi.h2
-rw-r--r--include/qemu/memfd.h1
-rw-r--r--include/ui/console.h2
-rw-r--r--linux-user/signal.c8
-rw-r--r--linux-user/syscall.c7
-rw-r--r--linux-user/syscall_defs.h5
-rwxr-xr-xpc-bios/hppa-firmware.imgbin215696 -> 215936 bytes
-rw-r--r--pc-bios/s390-ccw.imgbin34568 -> 30520 bytes
-rw-r--r--pc-bios/s390-ccw/bootmap.c7
-rw-r--r--pc-bios/s390-ccw/iplb.h15
-rw-r--r--pc-bios/s390-ccw/virtio.c2
-rw-r--r--pc-bios/s390-netboot.imgbin83776 -> 83856 bytes
-rw-r--r--qemu-doc.texi364
-rw-r--r--qemu-options.hx11
m---------roms/seabios-hppa0
-rwxr-xr-xscripts/checkpatch.pl15
-rwxr-xr-xscripts/device-crash-test1
-rw-r--r--scsi/qemu-pr-helper.c18
-rw-r--r--target/i386/cpu.c1
-rw-r--r--target/i386/cpu.h1
-rw-r--r--target/i386/kvm.c56
-rw-r--r--target/i386/sev.c4
-rw-r--r--target/i386/translate.c6
-rw-r--r--target/i386/whpx-all.c79
-rw-r--r--target/s390x/helper.c10
-rw-r--r--target/s390x/kvm.c2
-rw-r--r--target/s390x/mmu_helper.c2
-rwxr-xr-xtests/docker/common.rc4
-rw-r--r--tests/docker/dockerfiles/fedora.docker13
-rwxr-xr-xtests/docker/run2
-rw-r--r--tests/qemu-iotests/051.pc.out20
-rwxr-xr-xtests/qemu-iotests/10624
-rw-r--r--tests/qemu-iotests/106.out10
-rwxr-xr-xtests/qemu-iotests/12247
-rw-r--r--tests/qemu-iotests/122.out33
-rwxr-xr-xtests/qemu-iotests/1866
-rw-r--r--tests/qemu-iotests/186.out84
-rwxr-xr-xtests/qemu-iotests/2082
-rwxr-xr-xtests/qemu-iotests/check4
-rw-r--r--tests/qemu-iotests/common.config1
-rw-r--r--tests/qemu-iotests/common.filter5
-rw-r--r--tests/test-crypto-tlssession.c1
-rw-r--r--tests/test-io-channel-tls.c1
-rwxr-xr-xtests/vm/basevm.py5
-rw-r--r--ui/console.c15
-rw-r--r--ui/gtk.c4
-rw-r--r--ui/sdl2-gl.c2
-rw-r--r--ui/sdl2-input.c46
-rw-r--r--util/memfd.c34
-rw-r--r--util/sys_membarrier.c6
76 files changed, 1045 insertions, 371 deletions
diff --git a/.mailmap b/.mailmap
index cf689b9ec9..778a4d4e2c 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,6 +1,7 @@
-# This mailmap just translates the weird addresses from the original import into git
-# into proper addresses so that they are counted properly in git shortlog output.
-#
+# This mailmap fixes up author names/addresses.
+
+# The first section translates weird addresses from the original git import
+# into proper addresses so that they are counted properly by git shortlog.
 Andrzej Zaborowski <balrogg@gmail.com> balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>
 Anthony Liguori <anthony@codemonkey.ws> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
 Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
@@ -15,10 +16,19 @@ Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com>
 Paul Burton <paul.burton@mips.com> <paul@archlinuxmips.org>
 Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
 malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
+
 # There is also a:
 #    (no author) <(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
 # for the cvs2svn initialization commit e63c3dc74bf.
-#
+
+# Next, translate a few commits where mailman rewrote the From: line due
+# to strict SPF, although we prefer to avoid adding more entries like that.
+Ed Swierk <eswierk@skyportsystems.com> Ed Swierk via Qemu-devel <qemu-devel@nongnu.org>
+Ian McKellar <ianloic@google.com> Ian McKellar via Qemu-devel <qemu-devel@nongnu.org>
+Julia Suvorova <jusual@mail.ru> Julia Suvorova via Qemu-devel <qemu-devel@nongnu.org>
+Justin Terry (VM) <juterry@microsoft.com> Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org>
+
+
 # Also list preferred name forms where people have changed their
 # git author config
 Daniel P. Berrangé <berrange@redhat.com>
diff --git a/VERSION b/VERSION
index 5610569c0d..d7b11949fc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.11.91
+2.11.92
diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index 8bf8d63912..90340e56e0 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -705,7 +705,7 @@ void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc)                \
 {                                                                          \
     intptr_t oprsz = simd_oprsz(desc);                                     \
     intptr_t i;                                                            \
-    for (i = 0; i < oprsz; i += sizeof(vec64)) {                           \
+    for (i = 0; i < oprsz; i += sizeof(TYPE)) {                            \
         *(TYPE *)(d + i) = DO_CMP0(*(TYPE *)(a + i) OP *(TYPE *)(b + i));  \
     }                                                                      \
     clear_high(d, oprsz, desc);                                            \
diff --git a/block/file-posix.c b/block/file-posix.c
index d7fb772c14..3794c0007a 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1701,6 +1701,7 @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc,
     case PREALLOC_MODE_FULL:
     {
         int64_t num = 0, left = offset - current_length;
+        off_t seek_result;
 
         /*
          * Knowing the final size from the beginning could allow the file
@@ -1715,8 +1716,8 @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc,
 
         buf = g_malloc0(65536);
 
-        result = lseek(fd, current_length, SEEK_SET);
-        if (result < 0) {
+        seek_result = lseek(fd, current_length, SEEK_SET);
+        if (seek_result < 0) {
             result = -errno;
             error_setg_errno(errp, -result,
                              "Failed to seek to the old end of file");
@@ -2114,7 +2115,12 @@ static int find_allocation(BlockDriverState *bs, off_t start,
     if (offs < 0) {
         return -errno;          /* D3 or D4 */
     }
-    assert(offs >= start);
+
+    if (offs < start) {
+        /* This is not a valid return by lseek().  We are safe to just return
+         * -EIO in this case, and we'll treat it like D4. */
+        return -EIO;
+    }
 
     if (offs > start) {
         /* D2: in hole, next data at offs */
@@ -2146,7 +2152,12 @@ static int find_allocation(BlockDriverState *bs, off_t start,
     if (offs < 0) {
         return -errno;          /* D1 and (H3 or H4) */
     }
-    assert(offs >= start);
+
+    if (offs < start) {
+        /* This is not a valid return by lseek().  We are safe to just return
+         * -EIO in this case, and we'll treat it like H4. */
+        return -EIO;
+    }
 
     if (offs > start) {
         /*
diff --git a/block/gluster.c b/block/gluster.c
index 296e036b3d..4adc1a875b 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -167,7 +167,12 @@ static QemuOptsList runtime_unix_opts = {
         {
             .name = GLUSTER_OPT_SOCKET,
             .type = QEMU_OPT_STRING,
-            .help = "socket file path)",
+            .help = "socket file path (legacy)",
+        },
+        {
+            .name = GLUSTER_OPT_PATH,
+            .type = QEMU_OPT_STRING,
+            .help = "socket file path (QAPI)",
         },
         { /* end of list */ }
     },
@@ -615,10 +620,18 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
                 goto out;
             }
 
-            ptr = qemu_opt_get(opts, GLUSTER_OPT_SOCKET);
+            ptr = qemu_opt_get(opts, GLUSTER_OPT_PATH);
+            if (!ptr) {
+                ptr = qemu_opt_get(opts, GLUSTER_OPT_SOCKET);
+            } else if (qemu_opt_get(opts, GLUSTER_OPT_SOCKET)) {
+                error_setg(&local_err,
+                           "Conflicting parameters 'path' and 'socket'");
+                error_append_hint(&local_err, GERR_INDEX_HINT, i);
+                goto out;
+            }
             if (!ptr) {
                 error_setg(&local_err, QERR_MISSING_PARAMETER,
-                           GLUSTER_OPT_SOCKET);
+                           GLUSTER_OPT_PATH);
                 error_append_hint(&local_err, GERR_INDEX_HINT, i);
                 goto out;
             }
@@ -684,7 +697,7 @@ static int qemu_gluster_parse(BlockdevOptionsGluster *gconf,
                              "file.server.0.host=1.2.3.4,"
                              "file.server.0.port=24007,"
                              "file.server.1.transport=unix,"
-                             "file.server.1.socket=/var/run/glusterd.socket ..."
+                             "file.server.1.path=/var/run/glusterd.socket ..."
                              "\n");
             return ret;
         }
diff --git a/block/rbd.c b/block/rbd.c
index 5b64849dc6..c9359d0ad8 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -623,6 +623,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
     BlockdevOptionsRbd *opts = NULL;
     Visitor *v;
     QObject *crumpled = NULL;
+    const QDictEntry *e;
     Error *local_err = NULL;
     const char *filename;
     char *keypairs, *secretid;
@@ -671,6 +672,12 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
         goto out;
     }
 
+    /* Remove the processed options from the QDict (the visitor processes
+     * _all_ options in the QDict) */
+    while ((e = qdict_first(options))) {
+        qdict_del(options, e->key);
+    }
+
     r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts,
                          !(flags & BDRV_O_NOCACHE), keypairs, secretid, errp);
     if (r < 0) {
diff --git a/blockjob.c b/blockjob.c
index ef3ed69ff1..27f957e571 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -75,10 +75,8 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
     assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
     trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
                                      "allowed" : "disallowed",
-                                     qapi_enum_lookup(&BlockJobStatus_lookup,
-                                                      s0),
-                                     qapi_enum_lookup(&BlockJobStatus_lookup,
-                                                      s1));
+                                     BlockJobStatus_str(s0),
+                                     BlockJobStatus_str(s1));
     assert(BlockJobSTT[s0][s1]);
     job->status = s1;
 }
@@ -86,17 +84,15 @@ static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
 static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
 {
     assert(bv >= 0 && bv <= BLOCK_JOB_VERB__MAX);
-    trace_block_job_apply_verb(job, qapi_enum_lookup(&BlockJobStatus_lookup,
-                                                     job->status),
-                               qapi_enum_lookup(&BlockJobVerb_lookup, bv),
+    trace_block_job_apply_verb(job, BlockJobStatus_str(job->status),
+                               BlockJobVerb_str(bv),
                                BlockJobVerbTable[bv][job->status] ?
                                "allowed" : "prohibited");
     if (BlockJobVerbTable[bv][job->status]) {
         return 0;
     }
     error_setg(errp, "Job '%s' in state '%s' cannot accept command verb '%s'",
-               job->id, qapi_enum_lookup(&BlockJobStatus_lookup, job->status),
-               qapi_enum_lookup(&BlockJobVerb_lookup, bv));
+               job->id, BlockJobStatus_str(job->status), BlockJobVerb_str(bv));
     return -EPERM;
 }
 
@@ -204,6 +200,15 @@ void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
     block_job_txn_ref(txn);
 }
 
+static void block_job_txn_del_job(BlockJob *job)
+{
+    if (job->txn) {
+        QLIST_REMOVE(job, txn_list);
+        block_job_txn_unref(job->txn);
+        job->txn = NULL;
+    }
+}
+
 static void block_job_pause(BlockJob *job)
 {
     job->pause_count++;
@@ -232,6 +237,7 @@ void block_job_unref(BlockJob *job)
 {
     if (--job->refcnt == 0) {
         assert(job->status == BLOCK_JOB_STATUS_NULL);
+        assert(!job->txn);
         BlockDriverState *bs = blk_bs(job->blk);
         QLIST_REMOVE(job, job_list);
         bs->job = NULL;
@@ -392,6 +398,7 @@ static void block_job_decommission(BlockJob *job)
     job->busy = false;
     job->paused = false;
     job->deferred_to_main_loop = true;
+    block_job_txn_del_job(job);
     block_job_state_transition(job, BLOCK_JOB_STATUS_NULL);
     block_job_unref(job);
 }
@@ -481,8 +488,7 @@ static int block_job_finalize_single(BlockJob *job)
         }
     }
 
-    QLIST_REMOVE(job, txn_list);
-    block_job_txn_unref(job->txn);
+    block_job_txn_del_job(job);
     block_job_conclude(job);
     return 0;
 }
diff --git a/configure b/configure
index 4d0e92c96c..752dd9ef32 100755
--- a/configure
+++ b/configure
@@ -1497,16 +1497,19 @@ Advanced options (experts only):
   --install=INSTALL        use specified install [$install]
   --python=PYTHON          use specified python [$python]
   --smbd=SMBD              use specified smbd [$smbd]
+  --with-git=GIT           use specified git [$git]
   --static                 enable static build [$static]
   --mandir=PATH            install man pages in PATH
   --datadir=PATH           install firmware in PATH$confsuffix
   --docdir=PATH            install documentation in PATH$confsuffix
   --bindir=PATH            install binaries in PATH
   --libdir=PATH            install libraries in PATH
+  --libexecdir=PATH        install helper binaries in PATH
   --sysconfdir=PATH        install config in PATH$confsuffix
   --localstatedir=PATH     install local state in PATH (set at runtime on win32)
   --firmwarepath=PATH      search PATH for firmware files
   --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
+  --with-pkgversion=VERS   use specified string as sub-version of the package
   --enable-debug           enable common debug build options
   --enable-sanitizers      enable default sanitizers
   --disable-strip          disable stripping binaries
@@ -5054,6 +5057,14 @@ static S2 c2;
 static S4 c4;
 static S8 c8;
 static int i;
+void helper(void *d, void *a, int shift, int i);
+void helper(void *d, void *a, int shift, int i)
+{
+  *(U1 *)(d + i) = *(U1 *)(a + i) << shift;
+  *(U2 *)(d + i) = *(U2 *)(a + i) << shift;
+  *(U4 *)(d + i) = *(U4 *)(a + i) << shift;
+  *(U8 *)(d + i) = *(U8 *)(a + i) << shift;
+}
 int main(void)
 {
   a1 += b1; a2 += b2; a4 += b4; a8 += b8;
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index 79f7a53ee8..b27075ea3b 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -50,6 +50,7 @@ enum VhostUserProtocolFeature {
     VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
     VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
     VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
+    VHOST_USER_PROTOCOL_F_CONFIG = 9,
 
     VHOST_USER_PROTOCOL_F_MAX
 };
diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
index c058c407df..534caab18a 100644
--- a/docs/interop/vhost-user.txt
+++ b/docs/interop/vhost-user.txt
@@ -379,6 +379,7 @@ Protocol features
 #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN   6
 #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
 #define VHOST_USER_PROTOCOL_F_PAGEFAULT      8
+#define VHOST_USER_PROTOCOL_F_CONFIG         9
 
 Master message types
 --------------------
@@ -664,7 +665,8 @@ Master message types
       Master payload: virtio device config space
       Slave payload: virtio device config space
 
-      Submitted by the vhost-user master to fetch the contents of the virtio
+      When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is
+      submitted by the vhost-user master to fetch the contents of the virtio
       device configuration space, vhost-user slave's payload size MUST match
       master's request, vhost-user slave uses zero length of payload to
       indicate an error to vhost-user master. The vhost-user master may
@@ -677,7 +679,8 @@ Master message types
       Master payload: virtio device config space
       Slave payload: N/A
 
-      Submitted by the vhost-user master when the Guest changes the virtio
+      When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is
+      submitted by the vhost-user master when the Guest changes the virtio
       device configuration space and also can be used for live migration
       on the destination host. The vhost-user slave must check the flags
       field, and slaves MUST NOT accept SET_CONFIG for read-only
@@ -766,13 +769,13 @@ Slave message types
      Slave payload: N/A
      Master payload: N/A
 
-     Vhost-user slave sends such messages to notify that the virtio device's
-     configuration space has changed, for those host devices which can support
-     such feature, host driver can send VHOST_USER_GET_CONFIG message to slave
-     to get the latest content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is
-     negotiated, and slave set the VHOST_USER_NEED_REPLY flag, master must
-     respond with zero when operation is successfully completed, or non-zero
-     otherwise.
+     When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, vhost-user slave sends
+     such messages to notify that the virtio device's configuration space has
+     changed, for those host devices which can support such feature, host
+     driver can send VHOST_USER_GET_CONFIG message to slave to get the latest
+     content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is negotiated, and slave set
+     the VHOST_USER_NEED_REPLY flag, master must respond with zero when
+     operation is successfully completed, or non-zero otherwise.
 
 VHOST_USER_PROTOCOL_F_REPLY_ACK:
 -------------------------------
diff --git a/dump.c b/dump.c
index 669f715274..b54cd42b21 100644
--- a/dump.c
+++ b/dump.c
@@ -814,7 +814,7 @@ static void create_header32(DumpState *s, Error **errp)
     size = sizeof(DiskDumpHeader32);
     dh = g_malloc0(size);
 
-    strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+    memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
     dh->header_version = cpu_to_dump32(s, 6);
     block_size = s->dump_info.page_size;
     dh->block_size = cpu_to_dump32(s, block_size);
@@ -926,7 +926,7 @@ static void create_header64(DumpState *s, Error **errp)
     size = sizeof(DiskDumpHeader64);
     dh = g_malloc0(size);
 
-    strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+    memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
     dh->header_version = cpu_to_dump32(s, 6);
     block_size = s->dump_info.page_size;
     dh->block_size = cpu_to_dump32(s, block_size);
diff --git a/exec.c b/exec.c
index c09bd93df3..02b1efebb7 100644
--- a/exec.c
+++ b/exec.c
@@ -1495,6 +1495,7 @@ static int find_max_supported_pagesize(Object *obj, void *opaque)
         mem_path = object_property_get_str(obj, "mem-path", NULL);
         if (mem_path) {
             long hpsize = qemu_mempath_getpagesize(mem_path);
+            g_free(mem_path);
             if (hpsize < *hpsize_min) {
                 *hpsize_min = hpsize;
             }
diff --git a/gdbstub.c b/gdbstub.c
index a76b2fa481..3c3807358c 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -507,6 +507,7 @@ static inline int tohex(int v)
         return v - 10 + 'a';
 }
 
+/* writes 2*len+1 bytes in buf */
 static void memtohex(char *buf, const uint8_t *mem, int len)
 {
     int i, c;
@@ -999,8 +1000,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     const char *p;
     uint32_t thread;
     int ch, reg_size, type, res;
-    char buf[MAX_PACKET_LENGTH];
     uint8_t mem_buf[MAX_PACKET_LENGTH];
+    char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
     uint8_t *registers;
     target_ulong addr, len;
 
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index f840f07dfe..262baca432 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -259,6 +259,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
     s->dev.vq_index = 0;
     s->dev.backend_features = 0;
 
+    vhost_dev_set_config_notifier(&s->dev, &blk_ops);
+
     ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0);
     if (ret < 0) {
         error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
@@ -277,8 +279,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
         s->blkcfg.num_queues = s->num_queues;
     }
 
-    vhost_dev_set_config_notifier(&s->dev, &blk_ops);
-
     return;
 
 vhost_err:
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 9470bd7be7..d2dd8ab502 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -580,13 +580,16 @@ static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
     VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
     struct virtio_console_config *config =
         (struct virtio_console_config *)config_data;
-    uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr);
     VirtIOSerialPort *port = find_first_connected_console(vser);
     VirtIOSerialPortClass *vsc;
+    uint8_t emerg_wr_lo;
 
-    if (!config->emerg_wr) {
+    if (!virtio_has_feature(vser->host_features,
+        VIRTIO_CONSOLE_F_EMERG_WRITE) || !config->emerg_wr) {
         return;
     }
+
+    emerg_wr_lo = le32_to_cpu(config->emerg_wr);
     /* Make sure we don't misdetect an emergency write when the guest
      * does a short config write after an emergency write. */
     config->emerg_wr = 0;
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index 83c87d92e0..892f655a7e 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "hw/isa/isa.h"
 #include "hw/dma/i8257.h"
 
@@ -118,13 +119,19 @@ static const MemoryRegionPortio i82374_portio_list[] = {
 static void i82374_realize(DeviceState *dev, Error **errp)
 {
     I82374State *s = I82374(dev);
+    ISABus *isa_bus = isa_bus_from_device(ISA_DEVICE(dev));
+
+    if (isa_get_dma(isa_bus, 0)) {
+        error_setg(errp, "DMA already initialized on ISA bus");
+        return;
+    }
+    i8257_dma_init(isa_bus, true);
 
     portio_list_init(&s->port_list, OBJECT(s), i82374_portio_list, s,
                      "i82374");
     portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj),
                     s->iobase);
 
-    i8257_dma_init(isa_bus_from_device(ISA_DEVICE(dev)), true);
     memset(s->commands, 0, sizeof(s->commands));
 }
 
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 1707434db3..7dac319403 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -242,6 +242,19 @@ static const VMStateDescription kvmclock_reliable_get_clock = {
 };
 
 /*
+ * When migrating, assume the source has an unreliable
+ * KVM_GET_CLOCK unless told otherwise.
+ */
+static int kvmclock_pre_load(void *opaque)
+{
+    KVMClockState *s = opaque;
+
+    s->clock_is_reliable = false;
+
+    return 0;
+}
+
+/*
  * When migrating, read the clock just before migration,
  * so that the guest clock counts during the events
  * between:
@@ -268,6 +281,7 @@ static const VMStateDescription kvmclock_vmsd = {
     .name = "kvmclock",
     .version_id = 1,
     .minimum_version_id = 1,
+    .pre_load = kvmclock_pre_load,
     .pre_save = kvmclock_pre_save,
     .fields = (VMStateField[]) {
         VMSTATE_UINT64(clock, KVMClockState),
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index fdeaec3a58..fb554ab156 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -279,44 +279,52 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
     *timeout = cpu_to_be32(splash_time);
 }
 
+static CcwDevice *s390_get_ccw_device(DeviceState *dev_st)
+{
+    CcwDevice *ccw_dev = NULL;
+
+    if (dev_st) {
+        VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
+            object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
+                                TYPE_VIRTIO_CCW_DEVICE);
+        if (virtio_ccw_dev) {
+            ccw_dev = CCW_DEVICE(virtio_ccw_dev);
+        } else {
+            SCSIDevice *sd = (SCSIDevice *)
+                object_dynamic_cast(OBJECT(dev_st),
+                                    TYPE_SCSI_DEVICE);
+            if (sd) {
+                SCSIBus *bus = scsi_bus_from_device(sd);
+                VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus);
+                VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw,
+                                                       vdev);
+
+                ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw),
+                                                           TYPE_CCW_DEVICE);
+            }
+        }
+    }
+    return ccw_dev;
+}
+
 static bool s390_gen_initial_iplb(S390IPLState *ipl)
 {
     DeviceState *dev_st;
+    CcwDevice *ccw_dev = NULL;
 
     dev_st = get_boot_device(0);
     if (dev_st) {
-        VirtioCcwDevice *virtio_ccw_dev = (VirtioCcwDevice *)
-            object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
-                TYPE_VIRTIO_CCW_DEVICE);
+        ccw_dev = s390_get_ccw_device(dev_st);
+    }
+
+    /*
+     * Currently allow IPL only from CCW devices.
+     */
+    if (ccw_dev) {
         SCSIDevice *sd = (SCSIDevice *) object_dynamic_cast(OBJECT(dev_st),
                                                             TYPE_SCSI_DEVICE);
-        VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
-                                                          TYPE_VIRTIO_NET);
-
-        if (vn) {
-            ipl->netboot = true;
-        }
-        if (virtio_ccw_dev) {
-            CcwDevice *ccw_dev = CCW_DEVICE(virtio_ccw_dev);
-
-            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
-            ipl->iplb.blk0_len =
-                cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
-            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
-            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
-            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
-        } else if (sd) {
-            SCSIBus *bus = scsi_bus_from_device(sd);
-            VirtIOSCSI *vdev = container_of(bus, VirtIOSCSI, bus);
-            VirtIOSCSICcw *scsi_ccw = container_of(vdev, VirtIOSCSICcw, vdev);
-            CcwDevice *ccw_dev;
-
-            ccw_dev = (CcwDevice *)object_dynamic_cast(OBJECT(scsi_ccw),
-                                                       TYPE_CCW_DEVICE);
-            if (!ccw_dev) {       /* It might be a PCI device instead */
-                return false;
-            }
 
+        if (sd) {
             ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
             ipl->iplb.blk0_len =
                 cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
@@ -327,12 +335,25 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
             ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
             ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
         } else {
-            return false; /* unknown device */
+            VirtIONet *vn = (VirtIONet *) object_dynamic_cast(OBJECT(dev_st),
+                                                              TYPE_VIRTIO_NET);
+
+            ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+            ipl->iplb.blk0_len =
+                cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
+            ipl->iplb.pbt = S390_IPL_TYPE_CCW;
+            ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+            ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
+
+            if (vn) {
+                ipl->netboot = true;
+            }
         }
 
         if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) {
             ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
         }
+
         return true;
     }
 
@@ -406,7 +427,8 @@ unref_mr:
     return img_size;
 }
 
-static bool is_virtio_net_device(IplParameterBlock *iplb)
+static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
+                                         int virtio_id)
 {
     uint8_t cssid;
     uint8_t ssid;
@@ -426,13 +448,23 @@ static bool is_virtio_net_device(IplParameterBlock *iplb)
             sch = css_find_subch(1, cssid, ssid, schid);
 
             if (sch && sch->devno == devno) {
-                return sch->id.cu_model == VIRTIO_ID_NET;
+                return sch->id.cu_model == virtio_id;
             }
         }
     }
     return false;
 }
 
+static bool is_virtio_net_device(IplParameterBlock *iplb)
+{
+    return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET);
+}
+
+static bool is_virtio_scsi_device(IplParameterBlock *iplb)
+{
+    return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
+}
+
 void s390_ipl_update_diag308(IplParameterBlock *iplb)
 {
     S390IPLState *ipl = get_ipl_device();
@@ -457,6 +489,22 @@ void s390_reipl_request(void)
     S390IPLState *ipl = get_ipl_device();
 
     ipl->reipl_requested = true;
+    if (ipl->iplb_valid &&
+        !ipl->netboot &&
+        ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
+        is_virtio_scsi_device(&ipl->iplb)) {
+        CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0));
+
+        if (ccw_dev &&
+            cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno &&
+            (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) {
+            /*
+             * this is the original boot device's SCSI
+             * so restore IPL parameter info from it
+             */
+            ipl->iplb_valid = s390_gen_initial_iplb(ipl);
+        }
+    }
     qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 }
 
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 864145a7c6..435f7c99e7 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -246,6 +246,7 @@ static void s390_init_ipl_dev(const char *kernel_filename,
 {
     Object *new = object_new(TYPE_S390_IPL);
     DeviceState *dev = DEVICE(new);
+    char *netboot_fw_prop;
 
     if (kernel_filename) {
         qdev_prop_set_string(dev, "kernel", kernel_filename);
@@ -256,9 +257,11 @@ static void s390_init_ipl_dev(const char *kernel_filename,
     qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
     qdev_prop_set_string(dev, "firmware", firmware);
     qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
-    if (!strlen(object_property_get_str(new, "netboot_fw", &error_abort))) {
+    netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort);
+    if (!strlen(netboot_fw_prop)) {
         qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
     }
+    g_free(netboot_fw_prop);
     object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
                               new, NULL);
     object_unref(new);
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index f5ab767ab5..ded23d36ca 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -714,10 +714,12 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
 
                 /* min_io_size and opt_io_size can't be greater than
                  * max_io_sectors */
-                min_io_size =
-                    MIN_NON_ZERO(min_io_size, max_io_sectors);
-                opt_io_size =
-                    MIN_NON_ZERO(opt_io_size, max_io_sectors);
+                if (min_io_size) {
+                    min_io_size = MIN(min_io_size, max_io_sectors);
+                }
+                if (opt_io_size) {
+                    opt_io_size = MIN(opt_io_size, max_io_sectors);
+                }
             }
             /* required VPD size with unmap support */
             buflen = 0x40;
@@ -823,7 +825,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
      * block characteristics VPD page by default.  Not all of SPC-3
      * is actually implemented, but we're good enough.
      */
-    outbuf[2] = 5;
+    outbuf[2] = s->qdev.default_scsi_version;
     outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
 
     if (buflen > 36) {
@@ -2191,7 +2193,11 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
     case READ_12:
     case READ_16:
         DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);
-        if (r->req.cmd.buf[1] & 0xe0) {
+        /* Protection information is not supported.  For SCSI versions 2 and
+         * older (as determined by snooping the guest's INQUIRY commands),
+         * there is no RD/WR/VRPROTECT, so skip this check in these versions.
+         */
+        if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) {
             goto illegal_request;
         }
         if (!check_lba_range(s, r->req.cmd.lba, len)) {
@@ -2222,7 +2228,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
          * As far as DMA is concerned, we can treat it the same as a write;
          * scsi_block_do_sgio will send VERIFY commands.
          */
-        if (r->req.cmd.buf[1] & 0xe0) {
+        if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) {
             goto illegal_request;
         }
         if (!check_lba_range(s, r->req.cmd.lba, len)) {
@@ -2268,6 +2274,8 @@ static void scsi_disk_reset(DeviceState *dev)
     /* reset tray statuses */
     s->tray_locked = 0;
     s->tray_open = 0;
+
+    s->qdev.scsi_version = s->qdev.default_scsi_version;
 }
 
 static void scsi_disk_resize_cb(void *opaque)
@@ -2812,6 +2820,8 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
 static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
 {
     SCSIBlockReq *r = (SCSIBlockReq *)req;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
+
     r->cmd = req->cmd.buf[0];
     switch (r->cmd >> 5) {
     case 0:
@@ -2837,8 +2847,11 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
         abort();
     }
 
-    if (r->cdb1 & 0xe0) {
-        /* Protection information is not supported.  */
+    /* Protection information is not supported.  For SCSI versions 2 and
+     * older (as determined by snooping the guest's INQUIRY commands),
+     * there is no RD/WR/VRPROTECT, so skip this check in these versions.
+     */
+    if (s->qdev.scsi_version > 2 && (req->cmd.buf[1] & 0xe0)) {
         scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD));
         return 0;
     }
@@ -2950,6 +2963,8 @@ static Property scsi_hd_properties[] = {
     DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
                        DEFAULT_MAX_IO_SIZE),
     DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
+    DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+                      5),
     DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -2995,6 +3010,8 @@ static Property scsi_cd_properties[] = {
     DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
     DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
                        DEFAULT_MAX_IO_SIZE),
+    DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+                      5),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -3023,6 +3040,8 @@ static Property scsi_block_properties[] = {
     DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
     DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false),
     DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
+    DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+                      -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -3063,6 +3082,8 @@ static Property scsi_disk_properties[] = {
                        DEFAULT_MAX_UNMAP_SIZE),
     DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
                        DEFAULT_MAX_IO_SIZE),
+    DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
+                      5),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 4753f8738f..381f04e339 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -194,17 +194,40 @@ static void scsi_read_complete(void * opaque, int ret)
             r->buf[3] |= 0x80;
         }
     }
-    if (s->type == TYPE_DISK &&
-        r->req.cmd.buf[0] == INQUIRY &&
-        r->req.cmd.buf[2] == 0xb0) {
-        uint32_t max_transfer =
-            blk_get_max_transfer(s->conf.blk) / s->blocksize;
-
-        assert(max_transfer);
-        stl_be_p(&r->buf[8], max_transfer);
-        /* Also take care of the opt xfer len. */
-        stl_be_p(&r->buf[12],
-                 MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
+    if (r->req.cmd.buf[0] == INQUIRY) {
+        /*
+         *  EVPD set to zero returns the standard INQUIRY data.
+         *
+         *  Check if scsi_version is unset (-1) to avoid re-defining it
+         *  each time an INQUIRY with standard data is received.
+         *  scsi_version is initialized with -1 in scsi_generic_reset
+         *  and scsi_disk_reset, making sure that we'll set the
+         *  scsi_version after a reset. If the version field of the
+         *  INQUIRY response somehow changes after a guest reboot,
+         *  we'll be able to keep track of it.
+         *
+         *  On SCSI-2 and older, first 3 bits of byte 2 is the
+         *  ANSI-approved version, while on later versions the
+         *  whole byte 2 contains the version. Check if we're dealing
+         *  with a newer version and, in that case, assign the
+         *  whole byte.
+         */
+        if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) {
+            s->scsi_version = r->buf[2] & 0x07;
+            if (s->scsi_version > 2) {
+                s->scsi_version = r->buf[2];
+            }
+        }
+        if (s->type == TYPE_DISK && r->req.cmd.buf[2] == 0xb0) {
+            uint32_t max_transfer =
+                blk_get_max_transfer(s->conf.blk) / s->blocksize;
+
+            assert(max_transfer);
+            stl_be_p(&r->buf[8], max_transfer);
+            /* Also take care of the opt xfer len. */
+            stl_be_p(&r->buf[12],
+                     MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
+        }
     }
     scsi_req_data(&r->req, len);
     scsi_req_unref(&r->req);
@@ -474,6 +497,7 @@ static void scsi_generic_reset(DeviceState *dev)
 {
     SCSIDevice *s = SCSI_DEVICE(dev);
 
+    s->scsi_version = s->default_scsi_version;
     scsi_device_purge_requests(s, SENSE_CODE(RESET));
 }
 
@@ -549,6 +573,8 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
 
     DPRINTF("block size %d\n", s->blocksize);
 
+    /* Only used by scsi-block, but initialize it nevertheless to be clean.  */
+    s->default_scsi_version = -1;
     scsi_generic_read_device_identification(s);
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 4e5855741a..fe34b50769 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -357,11 +357,13 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
         if (strcmp(vbasedev->name, vcdev->vdev.name) == 0) {
             error_setg(&err, "vfio: subchannel %s has already been attached",
                        vcdev->vdev.name);
+            g_free(vcdev->vdev.name);
             goto out_device_err;
         }
     }
 
     if (vfio_get_device(group, cdev->mdevid, &vcdev->vdev, &err)) {
+        g_free(vcdev->vdev.name);
         goto out_device_err;
     }
 
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 5e84716218..07ffa0ba10 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -548,12 +548,11 @@ static void vfio_listener_region_add(MemoryListener *listener,
         hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
 
         if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) {
-            error_report("Region 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx
-                         " is not aligned to 0x%"HWADDR_PRIx
-                         " and cannot be mapped for DMA",
-                         section->offset_within_region,
-                         int128_getlo(section->size),
-                         pgmask + 1);
+            trace_vfio_listener_region_add_no_dma_map(
+                memory_region_name(section->mr),
+                section->offset_within_address_space,
+                int128_getlo(section->size),
+                pgmask + 1);
             return;
         }
     }
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 79f63a2ff6..20109cb758 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -90,6 +90,7 @@ vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "i
 vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add 0x%"PRIx64" - 0x%"PRIx64
 vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] 0x%"PRIx64" - 0x%"PRIx64
 vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
+vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
 vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del 0x%"PRIx64" - 0x%"PRIx64
 vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
 vfio_disconnect_container(int fd) "close container->fd=%d"
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 44aea5c0a8..38da8692bb 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -46,6 +46,7 @@ enum VhostUserProtocolFeature {
     VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
     VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
     VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
+    VHOST_USER_PROTOCOL_F_CONFIG = 9,
     VHOST_USER_PROTOCOL_F_MAX
 };
 
@@ -1211,6 +1212,17 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
 
         dev->protocol_features =
             protocol_features & VHOST_USER_PROTOCOL_FEATURE_MASK;
+
+        if (!dev->config_ops || !dev->config_ops->vhost_dev_config_notifier) {
+            /* Don't acknowledge CONFIG feature if device doesn't support it */
+            dev->protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
+        } else if (!(protocol_features &
+                    (1ULL << VHOST_USER_PROTOCOL_F_CONFIG))) {
+            error_report("Device expects VHOST_USER_PROTOCOL_F_CONFIG "
+                    "but backend does not support it.");
+            return -1;
+        }
+
         err = vhost_user_set_protocol_features(dev, dev->protocol_features);
         if (err < 0) {
             return err;
@@ -1405,6 +1417,11 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
         .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + config_len,
     };
 
+    if (!virtio_has_feature(dev->protocol_features,
+                VHOST_USER_PROTOCOL_F_CONFIG)) {
+        return -1;
+    }
+
     if (config_len > VHOST_USER_MAX_CONFIG_SIZE) {
         return -1;
     }
@@ -1448,6 +1465,11 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data,
         .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + size,
     };
 
+    if (!virtio_has_feature(dev->protocol_features,
+                VHOST_USER_PROTOCOL_F_CONFIG)) {
+        return -1;
+    }
+
     if (reply_supported) {
         msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
     }
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 250f886acb..f51bf573d5 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -595,10 +595,15 @@ static void vhost_region_add_section(struct vhost_dev *dev,
                                         prev_sec->offset_within_address_space,
                                         prev_sec->offset_within_region);
             } else {
-                error_report("%s: Overlapping but not coherent sections "
-                             "at %"PRIx64,
-                             __func__, mrs_gpa);
-                return;
+                /* adjoining regions are fine, but overlapping ones with
+                 * different blocks/offsets shouldn't happen
+                 */
+                if (mrs_gpa != prev_gpa_end + 1) {
+                    error_report("%s: Overlapping but not coherent sections "
+                                 "at %"PRIx64,
+                                 __func__, mrs_gpa);
+                    return;
+                }
             }
         }
     }
@@ -1223,7 +1228,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
         if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
             error_setg(&hdev->migration_blocker,
                        "Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
-        } else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_check()) {
+        } else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_alloc_check()) {
             error_setg(&hdev->migration_blocker,
                        "Migration disabled: failed to allocate shared memory");
         }
@@ -1451,7 +1456,6 @@ int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data,
 void vhost_dev_set_config_notifier(struct vhost_dev *hdev,
                                    const VhostDevConfigOps *ops)
 {
-    assert(hdev->vhost_ops);
     hdev->config_ops = ops;
 }
 
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 7ecaddac9d..e35137ea78 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -85,6 +85,8 @@ struct SCSIDevice
     uint64_t max_lba;
     uint64_t wwn;
     uint64_t port_wwn;
+    int scsi_version;
+    int default_scsi_version;
 };
 
 extern const VMStateDescription vmstate_scsi_device;
diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h
index de10198ed6..49e79634da 100644
--- a/include/qemu/memfd.h
+++ b/include/qemu/memfd.h
@@ -18,6 +18,7 @@
 
 int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
                       uint64_t hugetlbsize, unsigned int seals, Error **errp);
+bool qemu_memfd_alloc_check(void);
 void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
                        int *fd, Error **errp);
 void qemu_memfd_free(void *ptr, size_t size, int fd);
diff --git a/include/ui/console.h b/include/ui/console.h
index 6d2c052068..37a8d68d29 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -99,7 +99,7 @@ void hmp_mouse_set(Monitor *mon, const QDict *qdict);
 #define QEMU_KEY_CTRL_PAGEDOWN   0xe407
 
 void kbd_put_keysym_console(QemuConsole *s, int keysym);
-bool kbd_put_qcode_console(QemuConsole *s, int qcode);
+bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl);
 void kbd_put_string_console(QemuConsole *s, const char *str, int len);
 void kbd_put_keysym(int keysym);
 
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 33d5ced30c..046d4c8aa0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2920,8 +2920,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     env->pc = ka->_sa_handler;
     env->npc = (env->pc + 4);
     /* 5. return to kernel instructions */
-    if (ka->sa_restorer) {
-        env->regwptr[UREG_I7] = ka->sa_restorer;
+    if (ka->ka_restorer) {
+        env->regwptr[UREG_I7] = ka->ka_restorer;
     } else {
         uint32_t val32;
 
@@ -6367,7 +6367,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
                    &frame->retcode[1]);
         __put_user(INSN_CALLSYS, &frame->retcode[2]);
         /* imb() */
-        r26 = frame_addr;
+        r26 = frame_addr + offsetof(struct target_sigframe, retcode);
     }
 
     unlock_user_struct(frame, frame_addr, 1);
@@ -6424,7 +6424,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
                    &frame->retcode[1]);
         __put_user(INSN_CALLSYS, &frame->retcode[2]);
         /* imb(); */
-        r26 = frame_addr;
+        r26 = frame_addr + offsetof(struct target_sigframe, retcode);
     }
 
     if (err) {
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0eab5cc6ad..643b8833de 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8717,6 +8717,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 target_siginitset(&act.sa_mask, old_act->sa_mask);
                 act.sa_flags = old_act->sa_flags;
                 act.sa_restorer = old_act->sa_restorer;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+                act.ka_restorer = 0;
+#endif
                 unlock_user_struct(old_act, arg2, 0);
                 pact = &act;
             } else {
@@ -8791,8 +8794,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
                     goto efault;
                 }
-#ifdef TARGET_SPARC
-                act->sa_restorer = restorer;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+                act->ka_restorer = restorer;
 #endif
             } else {
                 act = NULL;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 13fe840239..23f5bccf0e 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -435,6 +435,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
 #define TARGET_SA_NODEFER      0x20u
 #define TARGET_SA_RESETHAND    4u
 #define TARGET_ARCH_HAS_SA_RESTORER 1
+#define TARGET_ARCH_HAS_KA_RESTORER 1
 #elif defined(TARGET_MIPS)
 #define TARGET_SA_NOCLDSTOP	0x00000001
 #define TARGET_SA_NOCLDWAIT	0x00010000
@@ -742,6 +743,9 @@ struct target_sigaction {
         abi_ulong sa_restorer;
 #endif
         target_sigset_t sa_mask;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+        abi_ulong ka_restorer;
+#endif
 };
 #endif
 
@@ -2561,6 +2565,7 @@ struct target_statfs64 {
 #define TARGET_O_CLOEXEC      0x400000
 #define TARGET___O_SYNC       0x800000
 #define TARGET_O_PATH        0x1000000
+#define TARGET___O_TMPFILE   0x2000000
 #endif
 
 /* <asm-generic/fcntl.h> values follow.  */
diff --git a/pc-bios/hppa-firmware.img b/pc-bios/hppa-firmware.img
index d2098f1fd9..4ec0dbfc4a 100755
--- a/pc-bios/hppa-firmware.img
+++ b/pc-bios/hppa-firmware.img
Binary files differdiff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index fbd76bb55e..fdd6809c70 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differdiff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index fc2a9fe33b..9287b7a70f 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -70,6 +70,13 @@ static void jump_to_IPL_code(uint64_t address)
 {
     /* store the subsystem information _after_ the bootmap was loaded */
     write_subsystem_identification();
+
+    /* prevent unknown IPL types in the guest */
+    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
+        iplb.pbt = S390_IPL_TYPE_CCW;
+        set_iplb(&iplb);
+    }
+
     /*
      * The IPL PSW is at address 0. We also must not overwrite the
      * content of non-BIOS memory after we loaded the guest, so we
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 7dfce4fbcf..5357a36d51 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -97,16 +97,27 @@ extern QemuIplParameters qipl;
 #define S390_IPL_TYPE_CCW 0x02
 #define S390_IPL_TYPE_QEMU_SCSI 0xff
 
-static inline bool store_iplb(IplParameterBlock *iplb)
+static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
 {
     register unsigned long addr asm("0") = (unsigned long) iplb;
     register unsigned long rc asm("1") = 0;
 
     asm volatile ("diag %0,%2,0x308\n"
                   : "+d" (addr), "+d" (rc)
-                  : "d" (6)
+                  : "d" (store ? 6 : 5)
                   : "memory", "cc");
     return rc == 0x01;
 }
 
+
+static inline bool store_iplb(IplParameterBlock *iplb)
+{
+    return manage_iplb(iplb, true);
+}
+
+static inline bool set_iplb(IplParameterBlock *iplb)
+{
+    return manage_iplb(iplb, false);
+}
+
 #endif /* IPLB_H */
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 817e7f56ea..cdb66f459e 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -14,7 +14,7 @@
 #include "virtio-scsi.h"
 #include "bswap.h"
 
-#define VRING_WAIT_REPLY_TIMEOUT 3
+#define VRING_WAIT_REPLY_TIMEOUT 30
 
 static VRing block[VIRTIO_MAX_VQS];
 static char ring_area[VIRTIO_RING_SIZE * VIRTIO_MAX_VQS]
diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img
index 9f5926b534..31f3d141cd 100644
--- a/pc-bios/s390-netboot.img
+++ b/pc-bios/s390-netboot.img
Binary files differdiff --git a/qemu-doc.texi b/qemu-doc.texi
index 89fa80518a..5813d27615 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -140,6 +140,7 @@ accelerator is required to use more than one host CPU for emulation.
 * direct_linux_boot::  Direct Linux Boot
 * pcsys_usb::          USB emulation
 * vnc_security::       VNC security
+* network_tls::        TLS setup for network services
 * gdb_usage::          GDB usage
 * pcsys_os_specific::  Target OS specific information
 @end menu
@@ -1041,7 +1042,6 @@ considerations depending on the deployment scenarios.
 * vnc_sec_certificate_pw::
 * vnc_sec_sasl::
 * vnc_sec_certificate_sasl::
-* vnc_generate_cert::
 * vnc_setup_sasl::
 @end menu
 @node vnc_sec_none
@@ -1161,25 +1161,105 @@ with the aforementioned TLS + x509 options:
 qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
 @end example
 
+@node vnc_setup_sasl
 
-@node vnc_generate_cert
-@subsection Generating certificates for VNC
+@subsection Configuring SASL mechanisms
 
-The GNU TLS packages provides a command called @code{certtool} which can
-be used to generate certificates and keys in PEM format. At a minimum it
-is necessary to setup a certificate authority, and issue certificates to
-each server. If using certificates for authentication, then each client
-will also need to be issued a certificate. The recommendation is for the
-server to keep its certificates in either @code{/etc/pki/qemu} or for
-unprivileged users in @code{$HOME/.pki/qemu}.
+The following documentation assumes use of the Cyrus SASL implementation on a
+Linux host, but the principles should apply to any other SASL implementation
+or host. When SASL is enabled, the mechanism configuration will be loaded from
+system default SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
+unprivileged user, an environment variable SASL_CONF_PATH can be used to make
+it search alternate locations for the service config file.
+
+If the TLS option is enabled for VNC, then it will provide session encryption,
+otherwise the SASL mechanism will have to provide encryption. In the latter
+case the list of possible plugins that can be used is drastically reduced. In
+fact only the GSSAPI SASL mechanism provides an acceptable level of security
+by modern standards. Previous versions of QEMU referred to the DIGEST-MD5
+mechanism, however, it has multiple serious flaws described in detail in
+RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism
+provides a simple username/password auth facility similar to DIGEST-MD5, but
+does not support session encryption, so can only be used in combination with
+TLS.
+
+When not using TLS the recommended configuration is
+
+@example
+mech_list: gssapi
+keytab: /etc/qemu/krb5.tab
+@end example
+
+This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with
+the server principal stored in /etc/qemu/krb5.tab. For this to work the
+administrator of your KDC must generate a Kerberos principal for the server,
+with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
+'somehost.example.com' with the fully qualified host name of the machine
+running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
+
+When using TLS, if username+password authentication is desired, then a
+reasonable configuration is
+
+@example
+mech_list: scram-sha-1
+sasldb_path: /etc/qemu/passwd.db
+@end example
+
+The @code{saslpasswd2} program can be used to populate the @code{passwd.db}
+file with accounts.
+
+Other SASL configurations will be left as an exercise for the reader. Note that
+all mechanisms, except GSSAPI, should be combined with use of TLS to ensure a
+secure data channel.
+
+
+@node network_tls
+@section TLS setup for network services
+
+Almost all network services in QEMU have the ability to use TLS for
+session data encryption, along with x509 certificates for simple
+client authentication. What follows is a description of how to
+generate certificates suitable for usage with QEMU, and applies to
+the VNC server, character devices with the TCP backend, NBD server
+and client, and migration server and client.
+
+At a high level, QEMU requires certificates and private keys to be
+provided in PEM format. Aside from the core fields, the certificates
+should include various extension data sets, including v3 basic
+constraints data, key purpose, key usage and subject alt name.
+
+The GnuTLS package includes a command called @code{certtool} which can
+be used to easily generate certificates and keys in the required format
+with expected data present. Alternatively a certificate management
+service may be used.
+
+At a minimum it is necessary to setup a certificate authority, and
+issue certificates to each server. If using x509 certificates for
+authentication, then each client will also need to be issued a
+certificate.
+
+Assuming that the QEMU network services will only ever be exposed to
+clients on a private intranet, there is no need to use a commercial
+certificate authority to create certificates. A self-signed CA is
+sufficient, and in fact likely to be more secure since it removes
+the ability of malicious 3rd parties to trick the CA into mis-issuing
+certs for impersonating your services. The only likely exception
+where a commercial CA might be desirable is if enabling the VNC
+websockets server and exposing it directly to remote browser clients.
+In such a case it might be useful to use a commercial CA to avoid
+needing to install custom CA certs in the web browsers.
+
+The recommendation is for the server to keep its certificates in either
+@code{/etc/pki/qemu} or for unprivileged users in @code{$HOME/.pki/qemu}.
 
 @menu
-* vnc_generate_ca::
-* vnc_generate_server::
-* vnc_generate_client::
+* tls_generate_ca::
+* tls_generate_server::
+* tls_generate_client::
+* tls_creds_setup::
 @end menu
-@node vnc_generate_ca
-@subsubsection Setup the Certificate Authority
+@node tls_generate_ca
+@subsection Setup the Certificate Authority
 
 This step only needs to be performed once per organization / organizational
 unit. First the CA needs a private key. This key must be kept VERY secret
@@ -1190,11 +1270,10 @@ issued with it is lost.
 # certtool --generate-privkey > ca-key.pem
 @end example
 
-A CA needs to have a public certificate. For simplicity it can be a self-signed
-certificate, or one issue by a commercial certificate issuing authority. To
-generate a self-signed certificate requires one core piece of information, the
-name of the organization.
-
+To generate a self-signed certificate requires one core piece of information,
+the name of the organization. A template file @code{ca.info} should be
+populated with the desired data to avoid having to deal with interactive
+prompts from certtool:
 @example
 # cat > ca.info <<EOF
 cn = Name of your organization
@@ -1207,123 +1286,224 @@ EOF
            --outfile ca-cert.pem
 @end example
 
-The @code{ca-cert.pem} file should be copied to all servers and clients wishing to utilize
-TLS support in the VNC server. The @code{ca-key.pem} must not be disclosed/copied at all.
+The @code{ca} keyword in the template sets the v3 basic constraints extension
+to indicate this certificate is for a CA, while @code{cert_signing_key} sets
+the key usage extension to indicate this will be used for signing other keys.
+The generated @code{ca-cert.pem} file should be copied to all servers and
+clients wishing to utilize TLS support in the VNC server. The @code{ca-key.pem}
+must not be disclosed/copied anywhere except the host responsible for issuing
+certificates.
 
-@node vnc_generate_server
-@subsubsection Issuing server certificates
+@node tls_generate_server
+@subsection Issuing server certificates
 
 Each server (or host) needs to be issued with a key and certificate. When connecting
 the certificate is sent to the client which validates it against the CA certificate.
-The core piece of information for a server certificate is the hostname. This should
-be the fully qualified hostname that the client will connect with, since the client
-will typically also verify the hostname in the certificate. On the host holding the
-secure CA private key:
-
-@example
-# cat > server.info <<EOF
+The core pieces of information for a server certificate are the hostnames and/or IP
+addresses that will be used by clients when connecting. The hostname / IP address
+that the client specifies when connecting will be validated against the hostname(s)
+and IP address(es) recorded in the server certificate, and if no match is found
+the client will close the connection.
+
+Thus it is recommended that the server certificate include both the fully qualified
+and unqualified hostnames. If the server will have permanently assigned IP address(es),
+and clients are likely to use them when connecting, they may also be included in the
+certificate. Both IPv4 and IPv6 addresses are supported. Historically certificates
+only included 1 hostname in the @code{CN} field, however, usage of this field for
+validation is now deprecated. Instead modern TLS clients will validate against the
+Subject Alt Name extension data, which allows for multiple entries. In the future
+usage of the @code{CN} field may be discontinued entirely, so providing SAN
+extension data is strongly recommended.
+
+On the host holding the CA, create template files containing the information
+for each server, and use it to issue server certificates.
+
+@example
+# cat > server-hostNNN.info <<EOF
 organization = Name  of your organization
-cn = server.foo.example.com
+cn = hostNNN.foo.example.com
+dns_name = hostNNN
+dns_name = hostNNN.foo.example.com
+ip_address = 10.0.1.87
+ip_address = 192.8.0.92
+ip_address = 2620:0:cafe::87
+ip_address = 2001:24::92
 tls_www_server
 encryption_key
 signing_key
 EOF
-# certtool --generate-privkey > server-key.pem
+# certtool --generate-privkey > server-hostNNN-key.pem
 # certtool --generate-certificate \
            --load-ca-certificate ca-cert.pem \
            --load-ca-privkey ca-key.pem \
-           --load-privkey server-key.pem \
-           --template server.info \
-           --outfile server-cert.pem
+           --load-privkey server-hostNNN-key.pem \
+           --template server-hostNNN.info \
+           --outfile server-hostNNN-cert.pem
 @end example
 
-The @code{server-key.pem} and @code{server-cert.pem} files should now be securely copied
-to the server for which they were generated. The @code{server-key.pem} is security
-sensitive and should be kept protected with file mode 0600 to prevent disclosure.
+The @code{dns_name} and @code{ip_address} fields in the template are setting
+the subject alt name extension data. The @code{tls_www_server} keyword is the
+key purpose extension to indicate this certificate is intended for usage in
+a web server. Although QEMU network services are not in fact HTTP servers
+(except for VNC websockets), setting this key purpose is still recommended.
+The @code{encryption_key} and @code{signing_key} keyword is the key usage
+extension to indicate this certificate is intended for usage in the data
+session.
 
-@node vnc_generate_client
-@subsubsection Issuing client certificates
+The @code{server-hostNNN-key.pem} and @code{server-hostNNN-cert.pem} files
+should now be securely copied to the server for which they were generated,
+and renamed to @code{server-key.pem} and @code{server-cert.pem} when added
+to the @code{/etc/pki/qemu} directory on the target host. The @code{server-key.pem}
+file is security sensitive and should be kept protected with file mode 0600
+to prevent disclosure.
+
+@node tls_generate_client
+@subsection Issuing client certificates
+
+The QEMU x509 TLS credential setup defaults to enabling client verification
+using certificates, providing a simple authentication mechanism. If this
+default is used, each client also needs to be issued a certificate. The client
+certificate contains enough metadata to uniquely identify the client with the
+scope of the certificate authority. The client certificate would typically
+include fields for organization, state, city, building, etc.
+
+Once again on the host holding the CA, create template files containing the
+information for each client, and use it to issue client certificates.
 
-If the QEMU VNC server is to use the @code{x509verify} option to validate client
-certificates as its authentication mechanism, each client also needs to be issued
-a certificate. The client certificate contains enough metadata to uniquely identify
-the client, typically organization, state, city, building, etc. On the host holding
-the secure CA private key:
 
 @example
-# cat > client.info <<EOF
+# cat > client-hostNNN.info <<EOF
 country = GB
 state = London
-locality = London
+locality = City Of London
 organization = Name of your organization
-cn = client.foo.example.com
+cn = hostNNN.foo.example.com
 tls_www_client
 encryption_key
 signing_key
 EOF
-# certtool --generate-privkey > client-key.pem
+# certtool --generate-privkey > client-hostNNN-key.pem
 # certtool --generate-certificate \
            --load-ca-certificate ca-cert.pem \
            --load-ca-privkey ca-key.pem \
-           --load-privkey client-key.pem \
-           --template client.info \
-           --outfile client-cert.pem
+           --load-privkey client-hostNNN-key.pem \
+           --template client-hostNNN.info \
+           --outfile client-hostNNN-cert.pem
+@end example
+
+The subject alt name extension data is not required for clients, so the
+the @code{dns_name} and @code{ip_address} fields are not included.
+The @code{tls_www_client} keyword is the key purpose extension to indicate
+this certificate is intended for usage in a web client. Although QEMU
+network clients are not in fact HTTP clients, setting this key purpose is
+still recommended. The @code{encryption_key} and @code{signing_key} keyword
+is the key usage extension to indicate this certificate is intended for
+usage in the data session.
+
+The @code{client-hostNNN-key.pem} and @code{client-hostNNN-cert.pem} files
+should now be securely copied to the client for which they were generated,
+and renamed to @code{client-key.pem} and @code{client-cert.pem} when added
+to the @code{/etc/pki/qemu} directory on the target host. The @code{client-key.pem}
+file is security sensitive and should be kept protected with file mode 0600
+to prevent disclosure.
+
+If a single host is going to be using TLS in both a client and server
+role, it is possible to create a single certificate to cover both roles.
+This would be quite common for the migration and NBD services, where a
+QEMU process will be started by accepting a TLS protected incoming migration,
+and later itself be migrated out to another host. To generate a single
+certificate, simply include the template data from both the client and server
+instructions in one.
+
+@example
+# cat > both-hostNNN.info <<EOF
+country = GB
+state = London
+locality = City Of London
+organization = Name of your organization
+cn = hostNNN.foo.example.com
+dns_name = hostNNN
+dns_name = hostNNN.foo.example.com
+ip_address = 10.0.1.87
+ip_address = 192.8.0.92
+ip_address = 2620:0:cafe::87
+ip_address = 2001:24::92
+tls_www_server
+tls_www_client
+encryption_key
+signing_key
+EOF
+# certtool --generate-privkey > both-hostNNN-key.pem
+# certtool --generate-certificate \
+           --load-ca-certificate ca-cert.pem \
+           --load-ca-privkey ca-key.pem \
+           --load-privkey both-hostNNN-key.pem \
+           --template both-hostNNN.info \
+           --outfile both-hostNNN-cert.pem
 @end example
 
-The @code{client-key.pem} and @code{client-cert.pem} files should now be securely
-copied to the client for which they were generated.
+When copying the PEM files to the target host, save them twice,
+once as @code{server-cert.pem} and @code{server-key.pem}, and
+again as @code{client-cert.pem} and @code{client-key.pem}.
 
+@node tls_creds_setup
+@subsection TLS x509 credential configuration
 
-@node vnc_setup_sasl
+QEMU has a standard mechanism for loading x509 credentials that will be
+used for network services and clients. It requires specifying the
+@code{tls-creds-x509} class name to the @code{--object} command line
+argument for the system emulators.  Each set of credentials loaded should
+be given a unique string identifier via the @code{id} parameter. A single
+set of TLS credentials can be used for multiple network backends, so VNC,
+migration, NBD, character devices can all share the same credentials. Note,
+however, that credentials for use in a client endpoint must be loaded
+separately from those used in a server endpoint.
 
-@subsection Configuring SASL mechanisms
+When specifying the object, the @code{dir} parameters specifies which
+directory contains the credential files. This directory is expected to
+contain files with the names mentioned previously, @code{ca-cert.pem},
+@code{server-key.pem}, @code{server-cert.pem}, @code{client-key.pem}
+and @code{client-cert.pem} as appropriate. It is also possible to
+include a set of pre-generated Diffie-Hellman (DH) parameters in a file
+@code{dh-params.pem}, which can be created using the
+@code{certtool --generate-dh-params} command. If omitted, QEMU will
+dynamically generate DH parameters when loading the credentials.
 
-The following documentation assumes use of the Cyrus SASL implementation on a
-Linux host, but the principals should apply to any other SASL impl. When SASL
-is enabled, the mechanism configuration will be loaded from system default
-SASL service config /etc/sasl2/qemu.conf. If running QEMU as an
-unprivileged user, an environment variable SASL_CONF_PATH can be used
-to make it search alternate locations for the service config.
+The @code{endpoint} parameter indicates whether the credentials will
+be used for a network client or server, and determines which PEM
+files are loaded.
 
-If the TLS option is enabled for VNC, then it will provide session encryption,
-otherwise the SASL mechanism will have to provide encryption. In the latter
-case the list of possible plugins that can be used is drastically reduced. In
-fact only the GSSAPI SASL mechanism provides an acceptable level of security
-by modern standards. Previous versions of QEMU referred to the DIGEST-MD5
-mechanism, however, it has multiple serious flaws described in detail in
-RFC 6331 and thus should never be used any more. The SCRAM-SHA-1 mechanism
-provides a simple username/password auth facility similar to DIGEST-MD5, but
-does not support session encryption, so can only be used in combination with
-TLS.
+The @code{verify} parameter determines whether x509 certificate
+validation should be performed. This defaults to enabled, meaning
+clients will always validate the server hostname against the
+certificate subject alt name fields and/or CN field. It also
+means that servers will request that clients provide a certificate
+and validate them. Verification should never be turned off for
+client endpoints, however, it may be turned off for server endpoints
+if an alternative mechanism is used to authenticate clients. For
+example, the VNC server can use SASL to authenticate clients
+instead.
 
-When not using TLS the recommended configuration is
+To load server credentials with client certificate validation
+enabled
 
 @example
-mech_list: gssapi
-keytab: /etc/qemu/krb5.tab
+$QEMU -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
 @end example
 
-This says to use the 'GSSAPI' mechanism with the Kerberos v5 protocol, with
-the server principal stored in /etc/qemu/krb5.tab. For this to work the
-administrator of your KDC must generate a Kerberos principal for the server,
-with a name of 'qemu/somehost.example.com@@EXAMPLE.COM' replacing
-'somehost.example.com' with the fully qualified host name of the machine
-running QEMU, and 'EXAMPLE.COM' with the Kerberos Realm.
-
-When using TLS, if username+password authentication is desired, then a
-reasonable configuration is
+while to load client credentials use
 
 @example
-mech_list: scram-sha-1
-sasldb_path: /etc/qemu/passwd.db
+$QEMU -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
 @end example
 
-The saslpasswd2 program can be used to populate the passwd.db file with
-accounts.
+Network services which support TLS will all have a @code{tls-creds}
+parameter which expects the ID of the TLS credentials object. For
+example with VNC:
 
-Other SASL configurations will be left as an exercise for the reader. Note that
-all mechanisms except GSSAPI, should be combined with use of TLS to ensure a
-secure data channel.
+@example
+$QEMU -vnc 0.0.0.0:0,tls-creds=tls0
+@end example
 
 @node gdb_usage
 @section GDB usage
diff --git a/qemu-options.hx b/qemu-options.hx
index 3ece30d216..ca4e412f2f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4112,7 +4112,7 @@ expensive operation that consumes random pool entropy, so it is
 recommended that a persistent set of parameters be generated
 upfront and saved.
 
-@item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},verify-peer=@var{on|off},passwordid=@var{id}
+@item -object tls-creds-x509,id=@var{id},endpoint=@var{endpoint},dir=@var{/path/to/cred/dir},priority=@var{priority},verify-peer=@var{on|off},passwordid=@var{id}
 
 Creates a TLS anonymous credentials object, which can be used to provide
 TLS support on network backends. The @option{id} parameter is a unique
@@ -4145,6 +4145,15 @@ version by providing the @var{passwordid} parameter. This provides
 the ID of a previously created @code{secret} object containing the
 password for decryption.
 
+The @var{priority} parameter allows to override the global default
+priority used by gnutls. This can be useful if the system administrator
+needs to use a weaker set of crypto priorities for QEMU without
+potentially forcing the weakness onto all applications. Or conversely
+if one wants wants a stronger default for QEMU than for all other
+applications, they can do this through this parameter. Its format is
+a gnutls priority string as described at
+@url{https://gnutls.org/manual/html_node/Priority-Strings.html}.
+
 @item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}]
 
 Interval @var{t} can't be 0, this filter batches the packet delivery: all
diff --git a/roms/seabios-hppa b/roms/seabios-hppa
-Subproject 649e6202b8d65d46c69f542b1380f840fbe8ab1
+Subproject 1ef99a01572c2581c30e16e6fe69e9ea2ef92ce
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 57daae05ea..d52207a3cc 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2356,6 +2356,18 @@ sub process {
 # check for missing bracing around if etc
 		if ($line =~ /(^.*)\b(?:if|while|for)\b/ &&
 			$line !~ /\#\s*if/) {
+			my $allowed = 0;
+
+			# Check the pre-context.
+			if ($line =~ /(\}.*?)$/) {
+				my $pre = $1;
+
+				if ($line !~ /else/) {
+					print "APW: ALLOWED: pre<$pre> line<$line>\n"
+						if $dbg_adv_apw;
+					$allowed = 1;
+				}
+			}
 			my ($level, $endln, @chunks) =
 				ctx_statement_full($linenr, $realcnt, 1);
                         if ($dbg_adv_apw) {
@@ -2364,7 +2376,6 @@ sub process {
                                 if $#chunks >= 1;
                         }
 			if ($#chunks >= 0 && $level == 0) {
-				my $allowed = 0;
 				my $seen = 0;
 				my $herectx = $here . "\n";
 				my $ln = $linenr - 1;
@@ -2408,7 +2419,7 @@ sub process {
                                             $allowed = 1;
 					}
 				}
-				if ($seen != ($#chunks + 1)) {
+				if ($seen != ($#chunks + 1) && !$allowed) {
 					ERROR("braces {} are necessary for all arms of this statement\n" . $herectx);
 				}
 			}
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 24c7bf5a16..5d17dc68dd 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -217,7 +217,6 @@ ERROR_WHITELIST = [
     {'exitcode':-6, 'log':r"Object .* is not an instance of type generic-pc-machine", 'loglevel':logging.ERROR},
     {'exitcode':-6, 'log':r"Object .* is not an instance of type e500-ccsr", 'loglevel':logging.ERROR},
     {'exitcode':-6, 'log':r"vmstate_register_with_alias_id: Assertion `!se->compat \|\| se->instance_id == 0' failed", 'loglevel':logging.ERROR},
-    {'exitcode':-6, 'device':'isa-fdc', 'loglevel':logging.ERROR, 'expected':True},
     {'exitcode':-11, 'device':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
     {'exitcode':-11, 'device':'mioe3680_pci', 'loglevel':logging.ERROR, 'expected':True},
     {'exitcode':-11, 'device':'pcm3680_pci', 'loglevel':logging.ERROR, 'expected':True},
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
index 21e1b8ea60..d0f83176e1 100644
--- a/scsi/qemu-pr-helper.c
+++ b/scsi/qemu-pr-helper.c
@@ -924,6 +924,7 @@ int main(int argc, char **argv)
     Error *local_err = NULL;
     char *trace_file = NULL;
     bool daemonize = false;
+    bool pidfile_specified = false;
     unsigned socket_activation;
 
     struct sigaction sa_sigterm;
@@ -954,6 +955,7 @@ int main(int argc, char **argv)
         case 'f':
             g_free(pidfile);
             pidfile = g_strdup(optarg);
+            pidfile_specified = true;
             break;
 #ifdef CONFIG_LIBCAP
         case 'u': {
@@ -1081,20 +1083,22 @@ int main(int argc, char **argv)
                                          accept_client,
                                          NULL, NULL);
 
-#ifdef CONFIG_LIBCAP
-    if (drop_privileges() < 0) {
-        error_report("Failed to drop privileges: %s", strerror(errno));
-        exit(EXIT_FAILURE);
-    }
-#endif
-
     if (daemonize) {
         if (daemon(0, 0) < 0) {
             error_report("Failed to daemonize: %s", strerror(errno));
             exit(EXIT_FAILURE);
         }
+    }
+
+    if (daemonize || pidfile_specified)
         write_pidfile();
+
+#ifdef CONFIG_LIBCAP
+    if (drop_privileges() < 0) {
+        error_report("Failed to drop privileges: %s", strerror(errno));
+        exit(EXIT_FAILURE);
     }
+#endif
 
     state = RUNNING;
     do {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 555ae79d29..1a6b082b6f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4761,6 +4761,7 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
     DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
     DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
+    DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
     DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 78db1b833a..1b219fafc4 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1296,6 +1296,7 @@ struct X86CPU {
     bool hyperv_runtime;
     bool hyperv_synic;
     bool hyperv_stimer;
+    bool hyperv_frequencies;
     bool check_cpuid;
     bool enforce_cpuid;
     bool expose_kvm;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index d23fff12f5..6c49954e68 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -632,11 +632,6 @@ static int hyperv_handle_properties(CPUState *cs)
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
 
-    if (cpu->hyperv_time &&
-            kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) <= 0) {
-        cpu->hyperv_time = false;
-    }
-
     if (cpu->hyperv_relaxed_timing) {
         env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
     }
@@ -645,26 +640,61 @@ static int hyperv_handle_properties(CPUState *cs)
         env->features[FEAT_HYPERV_EAX] |= HV_APIC_ACCESS_AVAILABLE;
     }
     if (cpu->hyperv_time) {
+        if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) <= 0) {
+            fprintf(stderr, "Hyper-V clocksources "
+                    "(requested by 'hv-time' cpu flag) "
+                    "are not supported by kernel\n");
+            return -ENOSYS;
+        }
         env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
         env->features[FEAT_HYPERV_EAX] |= HV_TIME_REF_COUNT_AVAILABLE;
         env->features[FEAT_HYPERV_EAX] |= HV_REFERENCE_TSC_AVAILABLE;
-
-        if (has_msr_hv_frequencies && tsc_is_stable_and_known(env)) {
-            env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_FREQUENCY_MSRS;
-            env->features[FEAT_HYPERV_EDX] |= HV_FREQUENCY_MSRS_AVAILABLE;
+    }
+    if (cpu->hyperv_frequencies) {
+        if (!has_msr_hv_frequencies) {
+            fprintf(stderr, "Hyper-V frequency MSRs "
+                    "(requested by 'hv-frequencies' cpu flag) "
+                    "are not supported by kernel\n");
+            return -ENOSYS;
         }
+        env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_FREQUENCY_MSRS;
+        env->features[FEAT_HYPERV_EDX] |= HV_FREQUENCY_MSRS_AVAILABLE;
     }
-    if (cpu->hyperv_crash && has_msr_hv_crash) {
+    if (cpu->hyperv_crash) {
+        if (!has_msr_hv_crash) {
+            fprintf(stderr, "Hyper-V crash MSRs "
+                    "(requested by 'hv-crash' cpu flag) "
+                    "are not supported by kernel\n");
+            return -ENOSYS;
+        }
         env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE;
     }
     env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
-    if (cpu->hyperv_reset && has_msr_hv_reset) {
+    if (cpu->hyperv_reset) {
+        if (!has_msr_hv_reset) {
+            fprintf(stderr, "Hyper-V reset MSR "
+                    "(requested by 'hv-reset' cpu flag) "
+                    "is not supported by kernel\n");
+            return -ENOSYS;
+        }
         env->features[FEAT_HYPERV_EAX] |= HV_RESET_AVAILABLE;
     }
-    if (cpu->hyperv_vpindex && has_msr_hv_vpindex) {
+    if (cpu->hyperv_vpindex) {
+        if (!has_msr_hv_vpindex) {
+            fprintf(stderr, "Hyper-V VP_INDEX MSR "
+                    "(requested by 'hv-vpindex' cpu flag) "
+                    "is not supported by kernel\n");
+            return -ENOSYS;
+        }
         env->features[FEAT_HYPERV_EAX] |= HV_VP_INDEX_AVAILABLE;
     }
-    if (cpu->hyperv_runtime && has_msr_hv_runtime) {
+    if (cpu->hyperv_runtime) {
+        if (!has_msr_hv_runtime) {
+            fprintf(stderr, "Hyper-V VP_RUNTIME MSR "
+                    "(requested by 'hv-runtime' cpu flag) "
+                    "is not supported by kernel\n");
+            return -ENOSYS;
+        }
         env->features[FEAT_HYPERV_EAX] |= HV_VP_RUNTIME_AVAILABLE;
     }
     if (cpu->hyperv_synic) {
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 019d84cef2..c01167143f 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -748,9 +748,11 @@ sev_guest_init(const char *id)
     if (s->sev_fd < 0) {
         error_report("%s: Failed to open %s '%s'", __func__,
                      devname, strerror(errno));
-        goto err;
     }
     g_free(devname);
+    if (s->sev_fd < 0) {
+        goto err;
+    }
 
     ret = sev_platform_ioctl(s->sev_fd, SEV_PLATFORM_STATUS, &status,
                              &fw_error);
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 0135415d92..c9ed8dc709 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -3802,7 +3802,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                 }
                 ot = mo_64_32(s->dflag);
                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
-                tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
+                tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_regs[s->vex_v]);
                 gen_op_mov_reg_v(ot, reg, cpu_T0);
                 gen_op_update1_cc();
                 set_cc_op(s, CC_OP_LOGICB + ot);
@@ -4563,9 +4563,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 #endif
             rex_r = (~vex2 >> 4) & 8;
             if (b == 0xc5) {
+                /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
                 vex3 = vex2;
-                b = x86_ldub_code(env, s);
+                b = x86_ldub_code(env, s) | 0x100;
             } else {
+                /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
 #ifdef TARGET_X86_64
                 s->rex_x = (~vex2 >> 3) & 8;
                 s->rex_b = (~vex2 >> 2) & 8;
diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c
index bf33d320bf..58435178a4 100644
--- a/target/i386/whpx-all.c
+++ b/target/i386/whpx-all.c
@@ -911,12 +911,62 @@ static int whpx_vcpu_run(CPUState *cpu)
             ret = 1;
             break;
 
+        case WHvRunVpExitReasonX64Cpuid: {
+            WHV_REGISTER_VALUE reg_values[5] = {0};
+            WHV_REGISTER_NAME reg_names[5];
+            UINT32 reg_count = 5;
+            UINT64 rip, rax, rcx, rdx, rbx;
+
+            rip = vcpu->exit_ctx.VpContext.Rip +
+                  vcpu->exit_ctx.VpContext.InstructionLength;
+            switch (vcpu->exit_ctx.CpuidAccess.Rax) {
+            case 1:
+                rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax;
+                /* Advertise that we are running on a hypervisor */
+                rcx =
+                    vcpu->exit_ctx.CpuidAccess.DefaultResultRcx |
+                    CPUID_EXT_HYPERVISOR;
+
+                rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx;
+                rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx;
+                break;
+            default:
+                rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax;
+                rcx = vcpu->exit_ctx.CpuidAccess.DefaultResultRcx;
+                rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx;
+                rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx;
+            }
+
+            reg_names[0] = WHvX64RegisterRip;
+            reg_names[1] = WHvX64RegisterRax;
+            reg_names[2] = WHvX64RegisterRcx;
+            reg_names[3] = WHvX64RegisterRdx;
+            reg_names[4] = WHvX64RegisterRbx;
+
+            reg_values[0].Reg64 = rip;
+            reg_values[1].Reg64 = rax;
+            reg_values[2].Reg64 = rcx;
+            reg_values[3].Reg64 = rdx;
+            reg_values[4].Reg64 = rbx;
+
+            hr = WHvSetVirtualProcessorRegisters(whpx->partition,
+                                                 cpu->cpu_index,
+                                                 reg_names,
+                                                 reg_count,
+                                                 reg_values);
+
+            if (FAILED(hr)) {
+                error_report("WHPX: Failed to set CpuidAccess state registers,"
+                             " hr=%08lx", hr);
+            }
+            ret = 0;
+            break;
+        }
         case WHvRunVpExitReasonNone:
         case WHvRunVpExitReasonUnrecoverableException:
         case WHvRunVpExitReasonInvalidVpRegisterValue:
         case WHvRunVpExitReasonUnsupportedFeature:
         case WHvRunVpExitReasonX64MsrAccess:
-        case WHvRunVpExitReasonX64Cpuid:
         case WHvRunVpExitReasonException:
         default:
             error_report("WHPX: Unexpected VP exit code %d",
@@ -1272,6 +1322,33 @@ static int whpx_accel_init(MachineState *ms)
         goto error;
     }
 
+    memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
+    prop.ExtendedVmExits.X64CpuidExit = 1;
+    hr = WHvSetPartitionProperty(whpx->partition,
+                                 WHvPartitionPropertyCodeExtendedVmExits,
+                                 &prop,
+                                 sizeof(WHV_PARTITION_PROPERTY));
+
+    if (FAILED(hr)) {
+        error_report("WHPX: Failed to enable partition extended X64CpuidExit"
+                     " hr=%08lx", hr);
+        ret = -EINVAL;
+        goto error;
+    }
+
+    UINT32 cpuidExitList[] = {1};
+    hr = WHvSetPartitionProperty(whpx->partition,
+                                 WHvPartitionPropertyCodeCpuidExitList,
+                                 cpuidExitList,
+                                 RTL_NUMBER_OF(cpuidExitList) * sizeof(UINT32));
+
+    if (FAILED(hr)) {
+        error_report("WHPX: Failed to set partition CpuidExitList hr=%08lx",
+                     hr);
+        ret = -EINVAL;
+        goto error;
+    }
+
     hr = WHvSetupPartition(whpx->partition);
     if (FAILED(hr)) {
         error_report("WHPX: Failed to setup partition, hr=%08lx", hr);
diff --git a/target/s390x/helper.c b/target/s390x/helper.c
index 615fa24ab9..e8548f340a 100644
--- a/target/s390x/helper.c
+++ b/target/s390x/helper.c
@@ -103,16 +103,18 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
 
     env->psw.addr = addr;
     env->psw.mask = mask;
-    if (tcg_enabled()) {
-        env->cc_op = (mask >> 44) & 3;
+
+    /* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
+    if (!tcg_enabled()) {
+        return;
     }
+    env->cc_op = (mask >> 44) & 3;
 
     if ((old_mask ^ mask) & PSW_MASK_PER) {
         s390_cpu_recompute_watchpoints(CPU(s390_env_get_cpu(env)));
     }
 
-    /* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */
-    if (tcg_enabled() && (mask & PSW_MASK_WAIT)) {
+    if (mask & PSW_MASK_WAIT) {
         s390_handle_wait(s390_env_get_cpu(env));
     }
 }
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index f570896dc1..fb59d92def 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1778,6 +1778,8 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 
     qemu_mutex_lock_iothread();
 
+    cpu_synchronize_state(cs);
+
     switch (run->exit_reason) {
         case KVM_EXIT_S390_SIEIC:
             ret = handle_intercept(cpu);
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
index 1deeb6e6e4..a25deef5dd 100644
--- a/target/s390x/mmu_helper.c
+++ b/target/s390x/mmu_helper.c
@@ -325,7 +325,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
 
     r = mmu_translate_region(env, vaddr, asc, asce, level, raddr, flags, rw,
                              exc);
-    if (rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) {
+    if (!r && rw == MMU_DATA_STORE && !(*flags & PAGE_WRITE)) {
         trigger_prot_fault(env, vaddr, asc, rw, exc);
         return -1;
     }
diff --git a/tests/docker/common.rc b/tests/docker/common.rc
index 7951555e3f..046f8a5921 100755
--- a/tests/docker/common.rc
+++ b/tests/docker/common.rc
@@ -30,7 +30,9 @@ build_qemu()
                  $@"
     echo "Configure options:"
     echo $config_opts
-    $QEMU_SRC/configure $config_opts && make $MAKEFLAGS
+    $QEMU_SRC/configure $config_opts || \
+        { cat config.log && test_fail "Failed to run 'configure'"; }
+    make $MAKEFLAGS
 }
 
 test_fail()
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index a00004319e..b706f42405 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -1,9 +1,16 @@
 FROM fedora:27
 ENV PACKAGES \
     ccache gettext git tar PyYAML sparse flex bison python3 bzip2 hostname \
-    glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
-    gcc gcc-c++ llvm clang make perl which bc findutils libaio-devel \
-    nettle-devel libasan libubsan \
+    gcc gcc-c++ llvm clang make perl which bc findutils glib2-devel \
+    libaio-devel pixman-devel zlib-devel libfdt-devel libasan libubsan \
+    bluez-libs-devel brlapi-devel bzip2-devel \
+    device-mapper-multipath-devel glusterfs-api-devel gnutls-devel \
+    gtk3-devel libattr-devel libcap-devel libcap-ng-devel libcurl-devel \
+    libjpeg-devel libpng-devel librbd-devel libssh2-devel libusbx-devel \
+    libxml2-devel lzo-devel ncurses-devel nettle-devel nss-devel \
+    numactl-devel SDL2-devel snappy-devel spice-server-devel \
+    systemtap-sdt-devel usbredir-devel virglrenderer-devel vte3-devel \
+    xen-devel \
     mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
     mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
     mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
diff --git a/tests/docker/run b/tests/docker/run
index 9dd362bb98..7aebf4b569 100755
--- a/tests/docker/run
+++ b/tests/docker/run
@@ -29,7 +29,7 @@ export TEST_DIR=/tmp/qemu-test
 mkdir -p $TEST_DIR/{src,build,install}
 
 # Extract the source tarballs
-tar -C $TEST_DIR/src -xf $BASE/qemu.tar || prep_fail "Failed to untar source"
+tar -C $TEST_DIR/src -xf $BASE/qemu.tar || { echo "Failed to untar source"; exit 2; }
 if test -f $TEST_DIR/src/Makefile; then
     export FEATURES="$FEATURES dtc"
 fi
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
index 830c11880a..b01f9a90d7 100644
--- a/tests/qemu-iotests/051.pc.out
+++ b/tests/qemu-iotests/051.pc.out
@@ -117,20 +117,10 @@ Testing: -drive if=ide,media=cdrom
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) quit
 
-Testing: -drive if=scsi,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-quit
-
 Testing: -drive if=ide
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: Initialization of device ide-hd failed: Device needs media, but drive is empty
 
-Testing: -drive if=scsi
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi: warning: bus=0,unit=0 is deprecated with this machine type
-QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
-
 Testing: -drive if=virtio
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
@@ -170,20 +160,10 @@ Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) quit
 
-Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type
-quit
-
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: Initialization of device ide-hd failed: Block node is read-only
 
-Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type
-quit
-
 Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) quit
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
index bfe71f4e60..5e51f88a78 100755
--- a/tests/qemu-iotests/106
+++ b/tests/qemu-iotests/106
@@ -86,6 +86,30 @@ for growth_mode in falloc full off; do
     $QEMU_IMG resize -f "$IMGFMT" --shrink --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K
 done
 
+echo
+echo '=== Testing image growth on 2G empty image ==='
+
+for growth_mode in falloc full; do
+    echo
+    echo "--- growth_mode=$growth_mode ---"
+
+    # Maybe we want to do an lseek() to the end of the file before the
+    # preallocation; if the file has a length of 2 GB, that would
+    # return an integer that overflows to negative when put into a
+    # plain int.  We should use the correct type for the result, and
+    # this tests we do.
+
+    _make_test_img 2G
+    $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
+
+    actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
+    actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
+
+    if [ $actual_size -lt $GROWTH_SIZE ]; then
+        echo "ERROR: Image should have at least ${GROWTH_SIZE}K, but has ${actual_size}K"
+    fi
+done
+
 # success, all done
 echo '*** done'
 rm -f $seq.full
diff --git a/tests/qemu-iotests/106.out b/tests/qemu-iotests/106.out
index 0a42312301..c459957660 100644
--- a/tests/qemu-iotests/106.out
+++ b/tests/qemu-iotests/106.out
@@ -47,4 +47,14 @@ qemu-img: Preallocation can only be used for growing images
 
 --- growth_mode=off ---
 Image resized.
+
+=== Testing image growth on 2G empty image ===
+
+--- growth_mode=falloc ---
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
+Image resized.
+
+--- growth_mode=full ---
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
+Image resized.
 *** done
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
index 45b359c2ba..6cf4fcb866 100755
--- a/tests/qemu-iotests/122
+++ b/tests/qemu-iotests/122
@@ -130,6 +130,53 @@ $QEMU_IO -c "read -P 0    1024k 1022k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _fil
 
 
 echo
+echo "=== Corrupted size field in compressed cluster descriptor ==="
+echo
+# Create an empty image and fill half of it with compressed data.
+# The L2 entries of the two compressed clusters are located at
+# 0x800000 and 0x800008, their original values are 0x4008000000a00000
+# and 0x4008000000a00802 (5 sectors for compressed data each).
+_make_test_img 8M -o cluster_size=2M
+$QEMU_IO -c "write -c -P 0x11 0 2M" -c "write -c -P 0x11 2M 2M" "$TEST_IMG" \
+         2>&1 | _filter_qemu_io | _filter_testdir
+
+# Reduce size of compressed data to 4 sectors: this corrupts the image.
+poke_file "$TEST_IMG" $((0x800000)) "\x40\x06"
+$QEMU_IO -c "read  -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+
+# 'qemu-img check' however doesn't see anything wrong because it
+# doesn't try to decompress the data and the refcounts are consistent.
+# TODO: update qemu-img so this can be detected.
+_check_test_img
+
+# Increase size of compressed data to the maximum (8192 sectors).
+# This makes QEMU read more data (8192 sectors instead of 5, host
+# addresses [0xa00000, 0xdfffff]), but the decompression algorithm
+# stops once we have enough to restore the uncompressed cluster, so
+# the rest of the data is ignored.
+poke_file "$TEST_IMG" $((0x800000)) "\x7f\xfe"
+# Do it also for the second compressed cluster (L2 entry at 0x800008).
+# In this case the compressed data would span 3 host clusters
+# (host addresses: [0xa00802, 0xe00801])
+poke_file "$TEST_IMG" $((0x800008)) "\x7f\xfe"
+
+# Here the image is too small so we're asking QEMU to read beyond the
+# end of the image.
+$QEMU_IO -c "read  -P 0x11  0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+# But if we grow the image we won't be reading beyond its end anymore.
+$QEMU_IO -c "write -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+$QEMU_IO -c "read  -P 0x11  0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+
+# The refcount data is however wrong because due to the increased size
+# of the compressed data it now reaches the following host clusters.
+# This can be repaired by qemu-img check by increasing the refcount of
+# those clusters.
+# TODO: update qemu-img to correct the compressed cluster size instead.
+_check_test_img -r all
+$QEMU_IO -c "read  -P 0x11  0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+$QEMU_IO -c "read  -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
+
+echo
 echo "=== Full allocation with -S 0 ==="
 echo
 
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
index 47d8656db8..a6b7fe007e 100644
--- a/tests/qemu-iotests/122.out
+++ b/tests/qemu-iotests/122.out
@@ -99,6 +99,39 @@ read 1024/1024 bytes at offset 1047552
 read 1046528/1046528 bytes at offset 1048576
 1022 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
+=== Corrupted size field in compressed cluster descriptor ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608
+wrote 2097152/2097152 bytes at offset 0
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2097152/2097152 bytes at offset 2097152
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read failed: Input/output error
+No errors were found on the image.
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 4194304/4194304 bytes at offset 4194304
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ERROR cluster 6 refcount=1 reference=3
+ERROR cluster 7 refcount=1 reference=2
+Repairing cluster 6 refcount=1 reference=3
+Repairing cluster 7 refcount=1 reference=2
+Repairing OFLAG_COPIED data cluster: l2_entry=8000000000c00000 refcount=3
+Repairing OFLAG_COPIED data cluster: l2_entry=8000000000e00000 refcount=2
+The following inconsistencies were found and repaired:
+
+    0 leaked clusters
+    4 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 4194304/4194304 bytes at offset 4194304
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
 === Full allocation with -S 0 ===
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
index 44cc01ed87..0aa4395a57 100755
--- a/tests/qemu-iotests/186
+++ b/tests/qemu-iotests/186
@@ -64,7 +64,7 @@ function check_info_block()
 {
     echo "info block" |
     do_run_qemu "$@" | _filter_win32 | _filter_hmp | _filter_qemu |
-        _filter_generated_node_ids
+        _filter_generated_node_ids | _filter_qom_path
 }
 
 
@@ -133,10 +133,6 @@ check_info_block -drive if=ide,driver=null-co
 check_info_block -drive if=ide,media=cdrom
 check_info_block -drive if=ide,driver=null-co,media=cdrom
 
-check_info_block -drive if=scsi,driver=null-co
-check_info_block -drive if=scsi,media=cdrom
-check_info_block -drive if=scsi,driver=null-co,media=cdrom
-
 check_info_block -drive if=virtio,driver=null-co
 
 check_info_block -drive if=pflash,driver=null-co,size=1M
diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
index c8377fe146..716b01ac3d 100644
--- a/tests/qemu-iotests/186.out
+++ b/tests/qemu-iotests/186.out
@@ -7,7 +7,7 @@ Testing: -device floppy
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 /machine/peripheral-anon/device[1]: [not inserted]
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -23,7 +23,7 @@ Testing: -device ide-cd
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 /machine/peripheral-anon/device[1]: [not inserted]
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -39,7 +39,7 @@ Testing: -device scsi-cd
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 /machine/peripheral-anon/device[1]: [not inserted]
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -58,7 +58,7 @@ Testing: -blockdev driver=null-co,node-name=null -device ide-hd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -74,7 +74,7 @@ Testing: -blockdev driver=null-co,node-name=null -device scsi-hd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -90,7 +90,7 @@ Testing: -blockdev driver=null-co,node-name=null -device virtio-blk-pci,drive=nu
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]/virtio-backend
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -98,7 +98,7 @@ Testing: -blockdev driver=null-co,node-name=null -device virtio-blk-pci,drive=nu
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral/qdev_id/virtio-backend
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -106,7 +106,7 @@ Testing: -blockdev driver=null-co,node-name=null -device floppy,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -124,7 +124,7 @@ Testing: -blockdev driver=null-co,node-name=null -device ide-cd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -142,7 +142,7 @@ Testing: -blockdev driver=null-co,node-name=null -device scsi-cd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -191,7 +191,7 @@ none0 (null): null-co:// (null-co)
     Cache mode:       writeback
 
 null: null-co:// (null-co)
-    Attached to:      /machine/peripheral/qdev_id/virtio-backend
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -241,7 +241,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device ide-hd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -257,7 +257,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device scsi-hd,drive=none
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -273,7 +273,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,dri
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]/virtio-backend
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -281,7 +281,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,dri
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral/qdev_id/virtio-backend
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -289,7 +289,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device floppy,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -307,7 +307,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device ide-cd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -325,7 +325,7 @@ Testing: -drive if=none,driver=null-co,node-name=null -device scsi-cd,drive=none
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0 (null): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -353,7 +353,7 @@ Testing: -drive if=none -device floppy,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0: [not inserted]
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -369,7 +369,7 @@ Testing: -drive if=none -device ide-cd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0: [not inserted]
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -385,7 +385,7 @@ Testing: -drive if=none -device scsi-cd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 none0: [not inserted]
-    Attached to:      /machine/peripheral-anon/device[1]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -404,7 +404,7 @@ Testing: -drive if=floppy
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 floppy0: [not inserted]
-    Attached to:      /machine/unattached/device[17]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -412,7 +412,7 @@ Testing: -drive if=floppy,driver=null-co
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 floppy0 (NODE_NAME): null-co:// (null-co)
-    Attached to:      /machine/unattached/device[17]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -421,7 +421,7 @@ Testing: -drive if=ide,driver=null-co
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 ide0-hd0 (NODE_NAME): null-co:// (null-co)
-    Attached to:      /machine/unattached/device[18]
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -429,7 +429,7 @@ Testing: -drive if=ide,media=cdrom
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 ide0-cd0: [not inserted]
-    Attached to:      /machine/unattached/device[18]
+    Attached to:      PATH
     Removable device: not locked, tray closed
 (qemu) quit
 
@@ -437,35 +437,7 @@ Testing: -drive if=ide,driver=null-co,media=cdrom
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 ide0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
-    Attached to:      /machine/unattached/device[18]
-    Removable device: not locked, tray closed
-    Cache mode:       writeback
-(qemu) quit
-
-Testing: -drive if=scsi,driver=null-co
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,driver=null-co: warning: bus=0,unit=0 is deprecated with this machine type
-info block
-scsi0-hd0 (NODE_NAME): null-co:// (null-co)
-    Attached to:      /machine/unattached/device[27]/scsi.0/legacy[0]
-    Cache mode:       writeback
-(qemu) quit
-
-Testing: -drive if=scsi,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-info block
-scsi0-cd0: [not inserted]
-    Attached to:      /machine/unattached/device[27]/scsi.0/legacy[0]
-    Removable device: not locked, tray closed
-(qemu) quit
-
-Testing: -drive if=scsi,driver=null-co,media=cdrom
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) QEMU_PROG: -drive if=scsi,driver=null-co,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-info block
-scsi0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
-    Attached to:      /machine/unattached/device[27]/scsi.0/legacy[0]
+    Attached to:      PATH
     Removable device: not locked, tray closed
     Cache mode:       writeback
 (qemu) quit
@@ -474,7 +446,7 @@ Testing: -drive if=virtio,driver=null-co
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 virtio0 (NODE_NAME): null-co:// (null-co)
-    Attached to:      /machine/peripheral-anon/device[1]/virtio-backend
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
@@ -482,7 +454,7 @@ Testing: -drive if=pflash,driver=null-co,size=1M
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
 pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M"} (null-co)
-    Attached to:      /machine/unattached/device[2]
+    Attached to:      PATH
     Cache mode:       writeback
 (qemu) quit
 
diff --git a/tests/qemu-iotests/208 b/tests/qemu-iotests/208
index 4e82b96c82..18f59ada94 100755
--- a/tests/qemu-iotests/208
+++ b/tests/qemu-iotests/208
@@ -28,7 +28,7 @@ with iotests.FilePath('disk.img') as disk_img_path, \
      iotests.VM() as vm:
 
     img_size = '10M'
-    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk_img_path, img_size)
+    iotests.qemu_img_create('-f', iotests.imgfmt, disk_img_path, img_size)
 
     iotests.log('Launching VM...')
     (vm.add_drive(disk_img_path, 'node-name=drive0-node', interface='none')
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index ec8033350d..aa94c6c7ea 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -538,8 +538,8 @@ if [ -z "$QEMU_PROG" ]
 then
     if [ -x "$build_iotests/qemu" ]; then
         export QEMU_PROG="$build_iotests/qemu"
-    elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
-        export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
+    elif [ -x "$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}" ]; then
+        export QEMU_PROG="$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}"
     else
         pushd "$build_root" > /dev/null
         for binary in *-softmmu/qemu-system-*
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index cdcda54546..102aa6878a 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -23,6 +23,7 @@ PATH=".:$PATH"
 
 HOSTOS=`uname -s`
 arch=`uname -m`
+[[ "$arch" =~ "ppc64" ]] && qemu_arch=ppc64 || qemu_arch="$arch"
 
 export PWD=`pwd`
 
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index cb2be23340..c5f4bcf578 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -32,6 +32,11 @@ _filter_generated_node_ids()
      sed -re 's/\#block[0-9]{3,}/NODE_NAME/'
 }
 
+_filter_qom_path()
+{
+    sed -e 's#\(Attached to: *\) /.*#\1 PATH#'
+}
+
 # replace occurrences of the actual TEST_DIR value with TEST_DIR
 _filter_testdir()
 {
diff --git a/tests/test-crypto-tlssession.c b/tests/test-crypto-tlssession.c
index 1a4a066d76..82f21c27f2 100644
--- a/tests/test-crypto-tlssession.c
+++ b/tests/test-crypto-tlssession.c
@@ -75,6 +75,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
                      "server" : "client"),
         "dir", certdir,
         "verify-peer", "yes",
+        "priority", "NORMAL",
         /* We skip initial sanity checks here because we
          * want to make sure that problems are being
          * detected at the TLS session validation stage,
diff --git a/tests/test-io-channel-tls.c b/tests/test-io-channel-tls.c
index 32743b2c96..bb88ee870f 100644
--- a/tests/test-io-channel-tls.c
+++ b/tests/test-io-channel-tls.c
@@ -78,6 +78,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint,
                      "server" : "client"),
         "dir", certdir,
         "verify-peer", "yes",
+        "priority", "NORMAL",
         /* We skip initial sanity checks here because we
          * want to make sure that problems are being
          * detected at the TLS session validation stage,
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 686d88decf..3a2d508c35 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -107,10 +107,7 @@ class BaseVM(object):
         assert not isinstance(cmd, str)
         ssh_cmd += ["%s@127.0.0.1" % user] + list(cmd)
         logging.debug("ssh_cmd: %s", " ".join(ssh_cmd))
-        r = subprocess.call(ssh_cmd,
-                            stdin=sys.stdin if interactive else self._devnull,
-                            stdout=sys.stdout if interactive else self._stdout,
-                            stderr=sys.stderr if interactive else self._stderr)
+        r = subprocess.call(ssh_cmd)
         if check and r != 0:
             raise Exception("SSH command failed: %s" % cmd)
         return r
diff --git a/ui/console.c b/ui/console.c
index 530a491987..3fb2f4e09f 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1191,11 +1191,22 @@ static const int qcode_to_keysym[Q_KEY_CODE__MAX] = {
     [Q_KEY_CODE_BACKSPACE] = QEMU_KEY_BACKSPACE,
 };
 
-bool kbd_put_qcode_console(QemuConsole *s, int qcode)
+static const int ctrl_qcode_to_keysym[Q_KEY_CODE__MAX] = {
+    [Q_KEY_CODE_UP]     = QEMU_KEY_CTRL_UP,
+    [Q_KEY_CODE_DOWN]   = QEMU_KEY_CTRL_DOWN,
+    [Q_KEY_CODE_RIGHT]  = QEMU_KEY_CTRL_RIGHT,
+    [Q_KEY_CODE_LEFT]   = QEMU_KEY_CTRL_LEFT,
+    [Q_KEY_CODE_HOME]   = QEMU_KEY_CTRL_HOME,
+    [Q_KEY_CODE_END]    = QEMU_KEY_CTRL_END,
+    [Q_KEY_CODE_PGUP]   = QEMU_KEY_CTRL_PAGEUP,
+    [Q_KEY_CODE_PGDN]   = QEMU_KEY_CTRL_PAGEDOWN,
+};
+
+bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl)
 {
     int keysym;
 
-    keysym = qcode_to_keysym[qcode];
+    keysym = ctrl ? ctrl_qcode_to_keysym[qcode] : qcode_to_keysym[qcode];
     if (keysym == 0) {
         return false;
     }
diff --git a/ui/gtk.c b/ui/gtk.c
index ef5bc42094..e98ac4d2fc 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1197,12 +1197,12 @@ static gboolean gd_text_key_down(GtkWidget *widget,
     QemuConsole *con = vc->gfx.dcl.con;
 
     if (key->keyval == GDK_KEY_Delete) {
-        kbd_put_qcode_console(con, Q_KEY_CODE_DELETE);
+        kbd_put_qcode_console(con, Q_KEY_CODE_DELETE, false);
     } else if (key->length) {
         kbd_put_string_console(con, key->string, key->length);
     } else {
         int qcode = gd_map_keycode(key->hardware_keycode);
-        kbd_put_qcode_console(con, qcode);
+        kbd_put_qcode_console(con, qcode, false);
     }
     return TRUE;
 }
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index 5e1073a084..c3683e6b65 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -32,8 +32,6 @@
 #include "ui/sdl2.h"
 #include "sysemu/sysemu.h"
 
-#include <epoxy/gl.h>
-
 static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
 {
     if (scon->scanout_mode == scanout) {
diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c
index 605d781971..1378b63dd9 100644
--- a/ui/sdl2-input.c
+++ b/ui/sdl2-input.c
@@ -60,32 +60,8 @@ void sdl2_process_key(struct sdl2_console *scon,
 
     qcode = qemu_input_map_usb_to_qcode[ev->keysym.scancode];
 
-    if (!qemu_console_is_graphic(con)) {
-        if (ev->type == SDL_KEYDOWN) {
-            switch (ev->keysym.scancode) {
-            case SDL_SCANCODE_RETURN:
-                kbd_put_keysym_console(con, '\n');
-                break;
-            case SDL_SCANCODE_BACKSPACE:
-                kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE);
-                break;
-            default:
-                kbd_put_qcode_console(con, qcode);
-                break;
-            }
-        }
-        return;
-    }
-
+    /* modifier state tracking */
     switch (ev->keysym.scancode) {
-#if 0
-    case SDL_SCANCODE_NUMLOCKCLEAR:
-    case SDL_SCANCODE_CAPSLOCK:
-        /* SDL does not send the key up event, so we generate it */
-        qemu_input_event_send_key_qcode(con, qcode, true);
-        qemu_input_event_send_key_qcode(con, qcode, false);
-        return;
-#endif
     case SDL_SCANCODE_LCTRL:
     case SDL_SCANCODE_LSHIFT:
     case SDL_SCANCODE_LALT:
@@ -99,8 +75,26 @@ void sdl2_process_key(struct sdl2_console *scon,
         } else {
             modifiers_state[ev->keysym.scancode] = 1;
         }
-        /* fall though */
+        break;
     default:
+        /* nothing */
+        break;
+    }
+
+    if (!qemu_console_is_graphic(con)) {
+        bool ctrl = (modifiers_state[SDL_SCANCODE_LCTRL] ||
+                     modifiers_state[SDL_SCANCODE_RCTRL]);
+        if (ev->type == SDL_KEYDOWN) {
+            switch (ev->keysym.scancode) {
+            case SDL_SCANCODE_RETURN:
+                kbd_put_keysym_console(con, '\n');
+                break;
+            default:
+                kbd_put_qcode_console(con, qcode, ctrl);
+                break;
+            }
+        }
+    } else {
         qemu_input_event_send_key_qcode(con, qcode,
                                         ev->type == SDL_KEYDOWN);
     }
diff --git a/util/memfd.c b/util/memfd.c
index 07d579ea7d..b3ecbac19e 100644
--- a/util/memfd.c
+++ b/util/memfd.c
@@ -173,7 +173,13 @@ enum {
     MEMFD_TODO
 };
 
-bool qemu_memfd_check(void)
+/**
+ * qemu_memfd_alloc_check():
+ *
+ * Check if qemu_memfd_alloc() can allocate, including using a
+ * fallback implementation when host doesn't support memfd.
+ */
+bool qemu_memfd_alloc_check(void)
 {
     static int memfd_check = MEMFD_TODO;
 
@@ -188,3 +194,29 @@ bool qemu_memfd_check(void)
 
     return memfd_check == MEMFD_OK;
 }
+
+/**
+ * qemu_memfd_check():
+ *
+ * Check if host supports memfd.
+ */
+bool qemu_memfd_check(void)
+{
+#ifdef CONFIG_LINUX
+    static int memfd_check = MEMFD_TODO;
+
+    if (memfd_check == MEMFD_TODO) {
+        int mfd = memfd_create("test", 0);
+        if (mfd >= 0) {
+            memfd_check = MEMFD_OK;
+            close(mfd);
+        } else {
+            memfd_check = MEMFD_KO;
+        }
+    }
+
+    return memfd_check == MEMFD_OK;
+#else
+    return false;
+#endif
+}
diff --git a/util/sys_membarrier.c b/util/sys_membarrier.c
index 8dcb53e63e..1362c0c4c5 100644
--- a/util/sys_membarrier.c
+++ b/util/sys_membarrier.c
@@ -6,9 +6,9 @@
  * Author: Paolo Bonzini <pbonzini@redhat.com>
  */
 
-#include <qemu/osdep.h>
-#include <qemu/sys_membarrier.h>
-#include <qemu/error-report.h>
+#include "qemu/osdep.h"
+#include "qemu/sys_membarrier.h"
+#include "qemu/error-report.h"
 
 #ifdef CONFIG_LINUX
 #include <linux/membarrier.h>