diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9bb96ef
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+SOURCES/bios-256k.bin
+SOURCES/kvm-unit-tests.git-4ea7633.tar.bz2
+SOURCES/pxe-e1000e.rom
+SOURCES/qemu-2.10.0.tar.xz
+SOURCES/rhel6-e1000.rom
+SOURCES/rhel6-ne2k_pci.rom
+SOURCES/rhel6-pcnet.rom
+SOURCES/rhel6-rtl8139.rom
+SOURCES/rhel6-virtio.rom
diff --git a/.qemu-kvm-ma.metadata b/.qemu-kvm-ma.metadata
new file mode 100644
index 0000000..189fa8b
--- /dev/null
+++ b/.qemu-kvm-ma.metadata
@@ -0,0 +1,9 @@
+5678cee702e664634abf28dce0688d01683611dd SOURCES/bios-256k.bin
+8d79fca1e904b82272ebf96bbb65f858e1c491a9 SOURCES/kvm-unit-tests.git-4ea7633.tar.bz2
+e304721d2b96cdf9dfa89e07947f19ef3e26107e SOURCES/pxe-e1000e.rom
+5d6815fa3ab1c6163c7e886f26153feabdcbb0f8 SOURCES/qemu-2.10.0.tar.xz
+957fd6b653b4550c6be727385331d58f1381e082 SOURCES/rhel6-e1000.rom
+3f183b9c65e959ab346a013828f1d7530bc4a14e SOURCES/rhel6-ne2k_pci.rom
+5bf1eb9f40dc52fa2c9bfecd9330af03a49b35f9 SOURCES/rhel6-pcnet.rom
+adffc84ebaf9faf982ecb707423395c1630186a4 SOURCES/rhel6-rtl8139.rom
+29e633bcdb4ea9604b7bdaaaeaa0a1223774cb1d SOURCES/rhel6-virtio.rom
diff --git a/README.md b/README.md
deleted file mode 100644
index 98f42b4..0000000
--- a/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-The master branch has no content
-
-Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6
-If you find this file in a distro specific branch, it means that no content has been checked in yet
diff --git a/SOURCES/0002-Initial-redhat-build.patch b/SOURCES/0002-Initial-redhat-build.patch
new file mode 100644
index 0000000..b0a528f
--- /dev/null
+++ b/SOURCES/0002-Initial-redhat-build.patch
@@ -0,0 +1,938 @@
+From ba7591ec4a0906121d15ffbf740580bd79ec5814 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Mon, 11 Sep 2017 07:11:00 +0200
+Subject: Initial redhat build
+
+This patch introduces redhat build structure in redhat subdirectory. In addition,
+several issues are fixed in QEMU tree:
+
+- Change of app name for sasl_server_init in VNC code from qemu to qemu-kvm
+ - As we use qemu-kvm as name in all places, this is updated to be consistent
+- Man page renamed from qemu to qemu-kvm
+ - man page is installed using make install so we have to fix it in qemu tree
+- Added live-block-migration configuration option support
+ - Downstream differentiation support
+- Use "/share/qemu-kvm" as SHARE_SUFFIX
+ - We reconfigured our share to qemu-kvm to be consistent with used name
+- Added .gitpublish configuration file
+ - Support for git publish has to be stored in repository root
+
+--
+Rebase notes (2.10.0):
+- live_block_migration option added upstream
+- moved qmp-spec.txt file (upstream)
+- added s390-netboot.img (added upstream)
+- removed qemu_vga.ndrv (added upstream)
+- switch to (rhevh-)rhel-7.5-candidate
+- switched differentiation defaults
+- moved binary files to separate commit
+
+Rebase notes (2.9.0):
+- documentation files handling changes (upstrem)
+- removed --enable-colo option and --disable-archipelago (upstream)
+- bump BuildRequires versions
+- new mandatory argument for tracetool.py (upstream)
+- updated RHEL 6 roms
+- switch from sha1sum to sha256sum
+- Moved adding rhel6-e1000.rom from machine types commit
+- Moved adding pxe-e1000e.rom from device disable commit
+- Use rdma-core instead of librdmacm
+- Add upstream tarballs tar.xz to .gitignore
+- Updated git-backport-diff script
+
+Rebase notes (2.8.0):
+- removed vhdx option (upstream)
+- qemu-tech.html merged to qemu-doc.html (upstream)
+- removed skiboot.lid firmware
+- Changed tracetool.py parameters
+- Added support for easy z-stream switch
+
+Rebase notes (2.7.0):
+- removed kvm_stat
+- added efi-e1000e.rom
+- added efi-vmxnet.rom
+- added linuxboot_dma.bin
+- trace-events renamed to trace-events-all
+- reverted dependency to seccomp on aarch64
+- Add ipxe-qemu-roms ad build dependency to pass tests
+
+Rebase notes (2.6.0):
+- removed q35-acpi-dsdt.aml
+- add enable-gcrypt option
+
+Rebase notes (2.5.0):
+- New seccomp hadling in configure
+- New condition format  in migration/migration.c
+- libcacard extracted
+- vnc fixes
+- libsecomp for aarch64 requirements changed downstream
+
+Rebase notes (2.4.0):
+- remove --enable-ws-vnc
+- use error_setg instead of error_set in migration/migration.c
+- remove target-x86_64.conf
+- create /etc/qemu-kvm on copying of bridge.conf
+- disabled opengl
+- rebased to version 2.3.0-30.el7
+
+Merged patches (rebase 2.10.0)
+- feefd46 qemu-kvm.spec: Enable s390x build
+- 985051e Removing texi2html from build requirements
+- 7c64a2a Update ignore files for redhat usage
+- 8f9a95a Disable replication feature
+- 1b7bbc5 block/vxhs: modularize VXHS via g_module
+- 7511527 Remove the dependencies to seavgabios-bin and ipxe-roms-qemu on s390x
+- aa0891c Downstream: Don't disable SMT on POWER9 hosts
+- a13a0e9 Update configuration for qemu 2.9
+- bbf46dd disable pulseaudio and alsa
+- 9124839 redhat/Makefile: honor BREW_FLAGS like the kernel
+- 53c03bd copy SLIT test reference blobs into tests directory
+- c4c77e6 Differentiation support
+- f1ec0e8 configure: allow to disable VT-d emulation
+- b972023 Disable VT-d for rhel builds
+- 29a0414 RHEL Diff.: Add option in configure to disable live block ops
+- 1f33b29 RHEL Diff.: Unregister live block operations
+- c590551 RHEL Diff.: Disable live block operations in HMP monitor
+- c7e208f RHEL Diff.: Add rpm spec options for live block ops
+- 733af5c pegas: add rpm spec options for vhost-user
+- ff16138 Add support for local build
+- fb426d4 qemu-kvm.spec: Configure vm.allocate_pgste for s390x
+
+Merged patches (rebase 2.9.0)
+- 9c7ab94 Enable seccomp for ppc64/ppc64le architecture
+- f6d7e9d Update qemu-kvm package Summary and Description
+- a9e55b6 Disable usbredir and libcacard for unsupported architectures
+- 0218220 Update configuration for 2.8.0 release
+
+Merged patches (rebase 2.7.0)
+- 2be6077 Fix SLOF dependency
+- dc58590 spec: Remove dependency to ipxe-roms-qemu for aarch64
+- 357ef43 spec: link sgabios.bin only for x86_64
+- 08d82cc spec: Update rules before triggering for kvm device
+- 8980a76 spec: Do not package ivshmem-server and ivshmem-client
+- 027067c spec: add a sample kvm.conf to enable Nested Virtualization
+- ba2ba30 Adjust locked memory limits to allow unprivileged VMs on Power
+- e9740b0 Increase locked memory limit for all users, not just kvm group
+- 8c301be add vgabios-virtio.bin symlink
+- 4d03723 usb: enable streams support
+- 2a9363e Add install dependency required for usb streams
+- 9a54442 Add dump-guest-memory.py to all archs
+- 73fffc9 add e1000e ipxe rom symlink
+- aaaa2a9 Add 'luks' to block driver whitelist
+- c78c3a8 redhat: switch from gcrypt to nettle for crypto
+- bb51a69 redhat: include username and date in RPM N-E-V-R for scratch builds
+
+Merged patches (rebase 2.4.0)
+- 9201274 spec: Remove obsolete differentiation code
+- a938a8c spec: Use external configuration script
+- 5ca8d0e spec: Use configure options to prevent default resolution
+- 5dca391 spec: Ship complete QMP documentation files
+- 7899edd aarch64: allow --enable-seccomp
+- a56fb9c aarch64: redhat spec: enable seccomp
+- a9571e6 rhel: Update package version for SLOF dependency
+- 25c70c4 configure: Add support for tcmalloc
+- db72485 Change fsreeze-hook default location
+- 14b8a9e redhat: add kvm-unit-tests tarball to environment
+- 5ee4238 spec: Build tscdeadline_latency.flat from kvm-unit-tests
+- 6ba800b Downstream-only: Start kvm-setup service before libvirtd service
+- 59b43d6 Do not stop qemu-guest-agent service on target switch
+- 4d851fa provide vhost module config file with max_mem_regions set to 509
+- 0b18027 spec: Require proper version of SLOF
+- 3c436c7 Fix rh-brew-aarch64, rh-brew-ppc rh-brew-ga-ppc target
+
+(cherry picked from commit a4e4a2f66d7a4efc873c5c1cafc502db480ff363)
+---
+ .gitignore                         |    1 +
+ .gitpublish                        |    8 +
+ Makefile                           |    2 +-
+ block/vxhs.c                       |  122 +-
+ configure                          |   56 +-
+ hmp-commands-info.hx               |    4 +
+ hmp-commands.hx                    |   12 +
+ hmp.c                              |   12 +
+ hw/i386/Makefile.objs              |    3 +-
+ include/block/vxhs_shim.h          |  143 +
+ monitor.c                          |   16 +
+ os-posix.c                         |    2 +-
+ redhat/.gitignore                  |    5 +
+ redhat/50-kvm-pgste.conf           |    3 +
+ redhat/80-kvm.rules                |    1 +
+ redhat/85-kvm.preset               |    5 +
+ redhat/95-kvm-memlock.conf         |   10 +
+ redhat/99-qemu-guest-agent.rules   |    2 +
+ redhat/Makefile                    |   90 +
+ redhat/Makefile.common             |   26 +
+ redhat/Makefile.local              |   76 +
+ redhat/README.rhel6-gpxe-source    |    9 +
+ redhat/bridge.conf                 |    1 +
+ redhat/build_configure.sh          |  156 +
+ redhat/ksm.service                 |   13 +
+ redhat/ksm.sysconfig               |    4 +
+ redhat/ksmctl.c                    |   77 +
+ redhat/ksmtuned                    |  138 +
+ redhat/ksmtuned.conf               |   21 +
+ redhat/ksmtuned.service            |   12 +
+ redhat/kvm-setup                   |   40 +
+ redhat/kvm-setup.service           |   14 +
+ redhat/kvm.conf                    |   12 +
+ redhat/kvm.modules                 |   21 +
+ redhat/qemu-ga.sysconfig           |   19 +
+ redhat/qemu-guest-agent.service    |   21 +
+ redhat/qemu-kvm.spec.template      | 6143 ++++++++++++++++++++++++++++++++++++
+ redhat/rpmbuild/BUILD/.gitignore   |    2 +
+ redhat/rpmbuild/RPMS/.gitignore    |    2 +
+ redhat/rpmbuild/SOURCES/.gitignore |    2 +
+ redhat/rpmbuild/SPECS/.gitignore   |    2 +
+ redhat/rpmbuild/SRPMS/.gitignore   |    2 +
+ redhat/scripts/frh.py              |   27 +
+ redhat/scripts/git-backport-diff   |  327 ++
+ redhat/scripts/git-compile-check   |  215 ++
+ redhat/scripts/process-patches.sh  |   81 +
+ redhat/scripts/tarball_checksum.sh |    3 +
+ redhat/vhost.conf                  |    3 +
+ ui/vnc.c                           |    2 +-
+ 49 files changed, 7923 insertions(+), 45 deletions(-)
+ create mode 100644 .gitpublish
+ create mode 100644 include/block/vxhs_shim.h
+ create mode 100644 redhat/.gitignore
+ create mode 100644 redhat/50-kvm-pgste.conf
+ create mode 100644 redhat/80-kvm.rules
+ create mode 100644 redhat/85-kvm.preset
+ create mode 100644 redhat/95-kvm-memlock.conf
+ create mode 100644 redhat/99-qemu-guest-agent.rules
+ create mode 100644 redhat/Makefile
+ create mode 100644 redhat/Makefile.common
+ create mode 100644 redhat/Makefile.local
+ create mode 100644 redhat/README.rhel6-gpxe-source
+ create mode 100644 redhat/bridge.conf
+ create mode 100755 redhat/build_configure.sh
+ create mode 100644 redhat/ksm.service
+ create mode 100644 redhat/ksm.sysconfig
+ create mode 100644 redhat/ksmctl.c
+ create mode 100644 redhat/ksmtuned
+ create mode 100644 redhat/ksmtuned.conf
+ create mode 100644 redhat/ksmtuned.service
+ create mode 100644 redhat/kvm-setup
+ create mode 100644 redhat/kvm-setup.service
+ create mode 100644 redhat/kvm.conf
+ create mode 100644 redhat/kvm.modules
+ create mode 100644 redhat/qemu-ga.sysconfig
+ create mode 100644 redhat/qemu-guest-agent.service
+ create mode 100644 redhat/qemu-kvm.spec.template
+ create mode 100644 redhat/rpmbuild/BUILD/.gitignore
+ create mode 100644 redhat/rpmbuild/RPMS/.gitignore
+ create mode 100644 redhat/rpmbuild/SOURCES/.gitignore
+ create mode 100644 redhat/rpmbuild/SPECS/.gitignore
+ create mode 100644 redhat/rpmbuild/SRPMS/.gitignore
+ create mode 100755 redhat/scripts/frh.py
+ create mode 100755 redhat/scripts/git-backport-diff
+ create mode 100755 redhat/scripts/git-compile-check
+ create mode 100755 redhat/scripts/process-patches.sh
+ create mode 100755 redhat/scripts/tarball_checksum.sh
+ create mode 100644 redhat/vhost.conf
+
+diff --git a/Makefile b/Makefile
+index 81447b1..2cb2442 100644
+--- a/Makefile
++++ b/Makefile
+@@ -570,7 +570,7 @@ install-doc: $(DOCS)
+ 	$(INSTALL_DATA) docs/interop/qemu-qmp-ref.txt "$(DESTDIR)$(qemu_docdir)"
+ ifdef CONFIG_POSIX
+ 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
+-	$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
++	$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1/qemu-kvm.1"
+ 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man7"
+ 	$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
+ ifneq ($(TOOLS),)
+diff --git a/block/vxhs.c b/block/vxhs.c
+index 75cc6c8..a18154c 100644
+--- a/block/vxhs.c
++++ b/block/vxhs.c
+@@ -9,7 +9,8 @@
+  */
+ 
+ #include "qemu/osdep.h"
+-#include <qnio/qnio_api.h>
++#include "block/vxhs_shim.h"
++#include <gmodule.h>
+ #include <sys/param.h>
+ #include "block/block_int.h"
+ #include "qapi/qmp/qerror.h"
+@@ -58,6 +59,96 @@ typedef struct BDRVVXHSState {
+     char *tlscredsid; /* tlscredsid */
+ } BDRVVXHSState;
+ 
++#define LIBVXHS_FULL_PATHNAME "/usr/lib64/qemu/libvxhs.so.1"
++static bool libvxhs_loaded;
++static GModule *libvxhs_handle;
++
++static LibVXHSFuncs libvxhs;
++
++typedef struct LibVXHSSymbols {
++    const char *name;
++    gpointer *addr;
++} LibVXHSSymbols;
++
++static LibVXHSSymbols libvxhs_symbols[] = {
++    {"iio_init",        (gpointer *) &libvxhs.iio_init},
++    {"iio_fini",        (gpointer *) &libvxhs.iio_fini},
++    {"iio_min_version", (gpointer *) &libvxhs.iio_min_version},
++    {"iio_max_version", (gpointer *) &libvxhs.iio_max_version},
++    {"iio_open",        (gpointer *) &libvxhs.iio_open},
++    {"iio_close",       (gpointer *) &libvxhs.iio_close},
++    {"iio_writev",      (gpointer *) &libvxhs.iio_writev},
++    {"iio_readv",       (gpointer *) &libvxhs.iio_readv},
++    {"iio_ioctl",       (gpointer *) &libvxhs.iio_ioctl},
++    {NULL}
++};
++
++static void bdrv_vxhs_set_funcs(GModule *handle, Error **errp)
++{
++    int i = 0;
++    while (libvxhs_symbols[i].name) {
++        const char *name = libvxhs_symbols[i].name;
++        if (!g_module_symbol(handle, name, libvxhs_symbols[i].addr)) {
++            error_setg(errp, "%s could not be loaded from libvxhs: %s",
++                       name, g_module_error());
++            return;
++        }
++        ++i;
++    }
++}
++
++static void bdrv_vxhs_load_libs(Error **errp)
++{
++    Error *local_err = NULL;
++    int32_t ver;
++
++    if (libvxhs_loaded) {
++        return;
++    }
++
++    if (!g_module_supported()) {
++        error_setg(errp, "modules are not supported on this platform: %s",
++                     g_module_error());
++        return;
++    }
++
++    libvxhs_handle = g_module_open(LIBVXHS_FULL_PATHNAME,
++                                   G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
++    if (!libvxhs_handle) {
++        error_setg(errp, "error loading libvxhs: %s", g_module_error());
++        return;
++    }
++
++    g_module_make_resident(libvxhs_handle);
++
++    bdrv_vxhs_set_funcs(libvxhs_handle, &local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        return;
++    }
++
++    /* Now check to see if the libvxhs we are using here is supported
++     * by the loaded version */
++
++    ver = (*libvxhs.iio_min_version)();
++    if (ver > QNIO_VERSION) {
++        error_setg(errp, "Trying to use libvxhs version %"PRId32" API, but "
++                         "only %"PRId32" or newer is supported by %s",
++                          QNIO_VERSION, ver, LIBVXHS_FULL_PATHNAME);
++        return;
++    }
++
++    ver = (*libvxhs.iio_max_version)();
++    if (ver < QNIO_VERSION) {
++        error_setg(errp, "Trying to use libvxhs version %"PRId32" API, but "
++                         "only %"PRId32" or earlier is supported by %s",
++                          QNIO_VERSION, ver, LIBVXHS_FULL_PATHNAME);
++        return;
++    }
++
++    libvxhs_loaded = true;
++}
++
+ static void vxhs_complete_aio_bh(void *opaque)
+ {
+     VXHSAIOCB *acb = opaque;
+@@ -219,7 +310,7 @@ static void vxhs_parse_filename(const char *filename, QDict *options,
+ static int vxhs_init_and_ref(void)
+ {
+     if (vxhs_ref++ == 0) {
+-        if (iio_init(QNIO_VERSION, vxhs_iio_callback)) {
++        if ((*libvxhs.iio_init)(QNIO_VERSION, vxhs_iio_callback)) {
+             return -ENODEV;
+         }
+     }
+@@ -229,7 +320,7 @@ static int vxhs_init_and_ref(void)
+ static void vxhs_unref(void)
+ {
+     if (--vxhs_ref == 0) {
+-        iio_fini();
++        (*libvxhs.iio_fini)();
+     }
+ }
+ 
+@@ -299,8 +390,17 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
+     char *client_key = NULL;
+     char *client_cert = NULL;
+ 
++    bdrv_vxhs_load_libs(&local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        /* on error, cannot cleanup because the iio_fini() function
++         * is not loaded */
++        return -EINVAL;
++    }
++
+     ret = vxhs_init_and_ref();
+     if (ret < 0) {
++        error_setg(&local_err, "libvxhs iio_init() failed");
+         ret = -EINVAL;
+         goto out;
+     }
+@@ -385,8 +485,8 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
+     /*
+      * Open qnio channel to storage agent if not opened before
+      */
+-    dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
+-                           cacert, client_key, client_cert);
++    dev_handlep = (*libvxhs.iio_open)(of_vsa_addr, s->vdisk_guid, 0,
++                                      cacert, client_key, client_cert);
+     if (dev_handlep == NULL) {
+         trace_vxhs_open_iio_open(of_vsa_addr);
+         ret = -ENODEV;
+@@ -450,12 +550,12 @@ static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
+ 
+     switch (iodir) {
+     case VDISK_AIO_WRITE:
+-            ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
+-                             offset, (uint64_t)size, iio_flags);
++            ret = (*libvxhs.iio_writev)(dev_handle, acb, qiov->iov, qiov->niov,
++                                        offset, (uint64_t)size, iio_flags);
+             break;
+     case VDISK_AIO_READ:
+-            ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
+-                            offset, (uint64_t)size, iio_flags);
++            ret = (*libvxhs.iio_readv)(dev_handle, acb, qiov->iov, qiov->niov,
++                                       offset, (uint64_t)size, iio_flags);
+             break;
+     default:
+             trace_vxhs_aio_rw_invalid(iodir);
+@@ -505,7 +605,7 @@ static void vxhs_close(BlockDriverState *bs)
+      * Close vDisk device
+      */
+     if (s->vdisk_hostinfo.dev_handle) {
+-        iio_close(s->vdisk_hostinfo.dev_handle);
++        (*libvxhs.iio_close)(s->vdisk_hostinfo.dev_handle);
+         s->vdisk_hostinfo.dev_handle = NULL;
+     }
+ 
+@@ -527,7 +627,7 @@ static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
+     int ret = 0;
+     void *dev_handle = s->vdisk_hostinfo.dev_handle;
+ 
+-    ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
++    ret = (*libvxhs.iio_ioctl)(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
+     if (ret < 0) {
+         trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
+         return -EIO;
+diff --git a/configure b/configure
+index dd73cce..355c364 100755
+--- a/configure
++++ b/configure
+@@ -400,11 +400,13 @@ virglrenderer=""
+ tpm="yes"
+ libssh2=""
+ live_block_migration="yes"
++live_block_ops="yes"
+ numa=""
+ tcmalloc="no"
+ jemalloc="no"
+ replication="yes"
+ vxhs=""
++vtd="yes"
+ 
+ supported_cpu="no"
+ supported_os="no"
+@@ -1279,6 +1281,10 @@ for opt do
+   ;;
+   --enable-replication) replication="yes"
+   ;;
++  --disable-live-block-ops) live_block_ops="no"
++  ;;
++  --enable-live-block-ops) live_block_ops="yes"
++  ;;
+   --disable-vxhs) vxhs="no"
+   ;;
+   --enable-vxhs) vxhs="yes"
+@@ -1291,6 +1297,10 @@ for opt do
+           error_exit "vhost-user isn't available on win32"
+       fi
+   ;;
++  --disable-vtd) vtd="no"
++  ;;
++  --enable-vtd) vtd="yes"
++  ;;
+   *)
+       echo "ERROR: unknown option $opt"
+       echo "Try '$0 --help' for more information"
+@@ -1523,6 +1533,8 @@ disabled with --disable-FEATURE, default is enabled if available:
+   glusterfs       GlusterFS backend
+   tpm             TPM support
+   libssh2         ssh block device support
++  live-block-migration live block migration support
++  live-block-ops  live block operations support
+   numa            libnuma support
+   tcmalloc        tcmalloc support
+   jemalloc        jemalloc support
+@@ -1534,6 +1546,7 @@ disabled with --disable-FEATURE, default is enabled if available:
+   qom-cast-debug  cast debugging support
+   tools           build qemu-io, qemu-nbd and qemu-image tools
+   vxhs            Veritas HyperScale vDisk backend support
++  vtd             Emulated VT-d support (only affects x86 targets)
+   crypto-afalg    Linux AF_ALG crypto backend driver
+   vhost-user      vhost-user support
+ 
+@@ -3217,7 +3230,7 @@ else
+     glib_req_ver=2.22
+ fi
+ glib_modules=gthread-2.0
+-if test "$modules" = yes; then
++if test "$modules" = yes -o "$vxhs" = yes; then
+     glib_modules="$glib_modules gmodule-2.0"
+ fi
+ 
+@@ -4940,33 +4953,6 @@ if compile_prog "" "" ; then
+ fi
+ 
+ ##########################################
+-# Veritas HyperScale block driver VxHS
+-# Check if libvxhs is installed
+-
+-if test "$vxhs" != "no" ; then
+-  cat > $TMPC <<EOF
+-#include <stdint.h>
+-#include <qnio/qnio_api.h>
+-
+-void *vxhs_callback;
+-
+-int main(void) {
+-    iio_init(QNIO_VERSION, vxhs_callback);
+-    return 0;
+-}
+-EOF
+-  vxhs_libs="-lvxhs -lssl"
+-  if compile_prog "" "$vxhs_libs" ; then
+-    vxhs=yes
+-  else
+-    if test "$vxhs" = "yes" ; then
+-      feature_not_found "vxhs block device" "Install libvxhs See github"
+-    fi
+-    vxhs=no
+-  fi
+-fi
+-
+-##########################################
+ # check for _Static_assert()
+ 
+ have_static_assert=no
+@@ -5398,6 +5384,7 @@ echo "libssh2 support   $libssh2"
+ echo "TPM passthrough   $tpm_passthrough"
+ echo "QOM debugging     $qom_cast_debug"
+ echo "Live block migration $live_block_migration"
++echo "Live block ops    $live_block_ops"
+ echo "lzo support       $lzo"
+ echo "snappy support    $snappy"
+ echo "bzip2 support     $bzip2"
+@@ -5407,6 +5394,7 @@ echo "jemalloc support  $jemalloc"
+ echo "avx2 optimization $avx2_opt"
+ echo "replication support $replication"
+ echo "VxHS block device $vxhs"
++echo "VT-d emulation    $vtd"
+ 
+ if test "$sdl_too_old" = "yes"; then
+ echo "-> Your SDL version is too old - please upgrade to have SDL support"
+@@ -5976,6 +5964,10 @@ if test "$live_block_migration" = "yes" ; then
+   echo "CONFIG_LIVE_BLOCK_MIGRATION=y" >> $config_host_mak
+ fi
+ 
++if test "$live_block_ops" = "yes" ; then
++  echo "CONFIG_LIVE_BLOCK_OPS=y" >> $config_host_mak
++fi
++
+ # USB host support
+ if test "$libusb" = "yes"; then
+   echo "HOST_USB=libusb legacy" >> $config_host_mak
+@@ -6071,8 +6063,12 @@ if test "$pthread_setname_np" = "yes" ; then
+ fi
+ 
+ if test "$vxhs" = "yes" ; then
+-  echo "CONFIG_VXHS=y" >> $config_host_mak
+-  echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
++  echo "CONFIG_VXHS=m" >> $config_host_mak
++  echo "VXHS_LIBS= -lssl" >> $config_host_mak
++fi
++
++if test "$vtd" = "yes" ; then
++  echo "CONFIG_VTD=y" >> $config_host_mak
+ fi
+ 
+ if test "$tcg_interpreter" = "yes"; then
+diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
+index d9df238..0967e41 100644
+--- a/hmp-commands-info.hx
++++ b/hmp-commands-info.hx
+@@ -84,6 +84,8 @@ STEXI
+ Show block device statistics.
+ ETEXI
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+     {
+         .name       = "block-jobs",
+         .args_type  = "",
+@@ -98,6 +100,8 @@ STEXI
+ Show progress of ongoing block device operations.
+ ETEXI
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+     {
+         .name       = "registers",
+         .args_type  = "cpustate_all:-a",
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 1941e19..2d137a1 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -73,6 +73,8 @@ but should be used with extreme caution.  Note that this command only
+ resizes image files, it can not resize block devices like LVM volumes.
+ ETEXI
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+     {
+         .name       = "block_stream",
+         .args_type  = "device:B,speed:o?,base:s?",
+@@ -159,6 +161,8 @@ STEXI
+ Resume a paused block streaming operation.
+ ETEXI
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+     {
+         .name       = "eject",
+         .args_type  = "force:-f,device:B",
+@@ -1169,6 +1173,8 @@ STEXI
+ Enables or disables migration mode.
+ ETEXI
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+     {
+         .name       = "snapshot_blkdev",
+         .args_type  = "reuse:-n,device:B,snapshot-file:s?,format:s?",
+@@ -1190,6 +1196,8 @@ STEXI
+ Snapshot device, using snapshot file as target if provided
+ ETEXI
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+     {
+         .name       = "snapshot_blkdev_internal",
+         .args_type  = "device:B,name:s",
+@@ -1224,6 +1232,8 @@ STEXI
+ Delete an internal snapshot on device if it support
+ ETEXI
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+     {
+         .name       = "drive_mirror",
+         .args_type  = "reuse:-n,full:-f,device:B,target:s,format:s?",
+@@ -1267,6 +1277,8 @@ STEXI
+ Start a point-in-time copy of a block device to a specificed target.
+ ETEXI
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+     {
+         .name       = "drive_add",
+         .args_type  = "node:-n,pci_addr:s,opts:s",
+diff --git a/hmp.c b/hmp.c
+index fd80dce..ab985c6 100644
+--- a/hmp.c
++++ b/hmp.c
+@@ -951,6 +951,8 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict)
+     qapi_free_PciInfoList(info_list);
+ }
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
+ {
+     BlockJobInfoList *list;
+@@ -989,6 +991,8 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
+     qapi_free_BlockJobInfoList(list);
+ }
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
+ {
+     TPMInfoList *info_list, *info;
+@@ -1197,6 +1201,8 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, &err);
+ }
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
+ {
+     const char *filename = qdict_get_str(qdict, "target");
+@@ -1280,6 +1286,8 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, &err);
+ }
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+ void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
+ {
+     const char *device = qdict_get_str(qdict, "device");
+@@ -1776,6 +1784,8 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, &err);
+ }
+ 
++#ifdef CONFIG_LIVE_BLOCK_OPS
++
+ void hmp_block_stream(Monitor *mon, const QDict *qdict)
+ {
+     Error *error = NULL;
+@@ -1842,6 +1852,8 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, &error);
+ }
+ 
++#endif /* CONFIG_LIVE_BLOCK_OPS */
++
+ typedef struct HMPMigrationStatus
+ {
+     QEMUTimer *timer;
+diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
+index 909ead6..c14559b 100644
+--- a/hw/i386/Makefile.objs
++++ b/hw/i386/Makefile.objs
+@@ -2,7 +2,8 @@ obj-$(CONFIG_KVM) += kvm/
+ obj-y += multiboot.o
+ obj-y += pc.o pc_piix.o pc_q35.o
+ obj-y += pc_sysfw.o
+-obj-y += x86-iommu.o intel_iommu.o
++obj-y += x86-iommu.o
++obj-$(CONFIG_VTD) += intel_iommu.o
+ obj-y += amd_iommu.o
+ obj-$(CONFIG_XEN) += ../xenpv/ xen/
+ 
+diff --git a/include/block/vxhs_shim.h b/include/block/vxhs_shim.h
+new file mode 100644
+index 0000000..42519ae
+--- /dev/null
++++ b/include/block/vxhs_shim.h
+@@ -0,0 +1,143 @@
++/*
++ * Network IO library for VxHS QEMU block driver (Veritas Technologies)
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2.  See
++ * the COPYING file in the top-level directory.
++ *
++ * Contributions after 2014-08-15 are licensed under the terms of the
++ * GNU GPL, version 2 or (at your option) any later version.
++ */
++
++#ifndef QNIO_API_H
++#define QNIO_API_H
++
++#include <sys/uio.h>
++
++/*
++ * Bump up the version everytime this file is modified
++ */
++#define QNIO_VERSION    34
++
++/*
++ * These are the opcodes referenced by callback routine.
++ */
++#define IRP_READ_REQUEST                    0x1FFF
++#define IRP_WRITE_REQUEST                   0x2FFF
++#define IRP_VDISK_CHECK_IO_FAILOVER_READY   2020
++
++/*
++ * opcodes for iio_ioctl.
++ */
++#define IOR_VDISK_STAT                      1005
++
++/*
++ * Error values for iio_cb_t callback function.
++ */
++#define QNIOERROR_HUP                       901 /* Retriable error */
++#define QNIOERROR_NOCONN                    902 /* Non-retriable error */
++
++
++/* Operation Flags */
++#define IIO_FLAG_ASYNC        0x0001   /* Do an async send */
++
++/*
++ * INPUT:
++ *     ctx - opaque context
++ *     opcode - Operation
++ *     error - 0 for sucess, non-zero for failure.
++ * RETURNS:
++ *     void
++ * DESCRIPTION:
++ *     This callback is called, after Async request completes.
++ *
++ * CONTEXT:
++ *     The callback should be wait-free.
++ */
++typedef void (*iio_cb_t) (void *ctx, uint32_t opcode, uint32_t error);
++
++typedef struct LibVXHSFuncs {
++/*
++ * RETURNS:
++ *     0 for sucess, non-zero for failure.
++ * DESCRIPTION:
++ *     Intilize the library state. This should be called at the
++ *     begining before issuing any library call.
++ */
++    int     (*iio_init)(int32_t version, iio_cb_t cb);
++/*
++ * RETURNS:
++ *     void
++ * DESCRIPTION:
++ *     Relinquish library resources. This should be called on the
++ *     close of last open device.
++ */
++    void    (*iio_fini)(void);
++/*
++ * DESCRIPTION:
++ *     Returns minimum QNIO API version supported by library.
++ */
++    int32_t (*iio_min_version)(void);
++/*
++ * DESCRIPTION:
++ *     Returns maximum QNIO API version supported by library.
++ */
++    int32_t (*iio_max_version)(void);
++/*
++ * INPUT:
++ *    uri - const string of the format of://<hostname|ip>:port
++ *    devid - Device ID.
++ *    flags - currently unused, this must be set to 0
++ *    cacert - CA certificates file in PEM format
++ *    client_key - Client private key file in PEM format
++ *    client_cert - Client certificate file in PEM format
++ * RETURNS:
++ *    opeque device handle on success, NULL on failure.
++ * DESCRIPTION:
++ *    This call returns device handle on success. Returns NULL on
++ *    failure with errno set
++ *    errno can be one of:
++ *        ENODEV - remote device not found
++ *        EBADF  - Unable to open communication channel.
++ *        EBUSY  - The call cannot be completed right now
++ */
++    void   *(*iio_open)(const char *uri, const char *devid, uint32_t flags,
++                        const char *cacert, const char *client_key,
++                        const char *client_cert);
++/*
++ * Close the device.
++ *    For every matching iio_open() there should be a matching iio_close()
++ *    The last close free all data structures associated with the device.
++ */
++    int32_t (*iio_close)(void *dev_handle);
++/*
++ * INPUT:
++ *    dev_handle - device descriptor on which read/write needs to be performed
++ *    ctx - an opaque context that is not interpreted This is set for
++ *          async calls only. It can be NULL.
++ *    iov    - an array of iovecs (This is a scatter gather operation)
++ *    iovcnt  - the number of iovecs
++ *    offset - an offset to perform the write
++ *    size   - I/O size
++ *    flags  - can be one of
++ *        IIO_FLAG_ASYNC - indicating this is a aio call.
++ * RETURNS:
++ *        -1 on error, sets errno
++ *        EBADF  - the remote fd is bad
++ *        EBUSY  - The call cannot be completed right now
++ *        EPIPE  - the channel got disconnected, call back would be called in
++ *                 addition to this.
++ */
++    int32_t (*iio_writev)(void *dev_handle, void *ctx, struct iovec *iov,
++                          int iovcnt, uint64_t offset, uint64_t size,
++                          uint32_t flags);
++
++    int32_t (*iio_readv)(void *dev_handle, void *ctx, struct iovec *iov,
++                         int iovcnt, uint64_t offset, uint64_t size,
++                         uint32_t flags);
++
++    int32_t (*iio_ioctl)(void *dev_handle, uint32_t opcode, void *opaque,
++                         uint32_t flags);
++
++} LibVXHSFuncs;
++
++#endif
+diff --git a/monitor.c b/monitor.c
+index e0f8801..de0a70e 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -998,6 +998,22 @@ static void qmp_unregister_commands_hack(void)
+     && !defined(TARGET_S390X)
+     qmp_unregister_command(&qmp_commands, "query-cpu-definitions");
+ #endif
++#ifndef CONFIG_LIVE_BLOCK_OPS
++    qmp_unregister_command(&qmp_commands, "block-stream");
++    qmp_unregister_command(&qmp_commands, "block-commit");
++    qmp_unregister_command(&qmp_commands, "drive-mirror");
++    qmp_unregister_command(&qmp_commands, "blockdev-mirror");
++    qmp_unregister_command(&qmp_commands, "drive-backup");
++    qmp_unregister_command(&qmp_commands, "blockdev-backup");
++    qmp_unregister_command(&qmp_commands, "blockdev-snapshot");
++    qmp_unregister_command(&qmp_commands, "blockdev-snapshot-sync");
++    qmp_unregister_command(&qmp_commands, "block-job-set-speed");
++    qmp_unregister_command(&qmp_commands, "block-job-cancel");
++    qmp_unregister_command(&qmp_commands, "block-job-pause");
++    qmp_unregister_command(&qmp_commands, "block-job-resume");
++    qmp_unregister_command(&qmp_commands, "block-job-complete");
++    qmp_unregister_command(&qmp_commands, "query-block-jobs");
++#endif
+ }
+ 
+ void monitor_init_qmp_commands(void)
+diff --git a/os-posix.c b/os-posix.c
+index 92e9d85..9625679 100644
+--- a/os-posix.c
++++ b/os-posix.c
+@@ -76,7 +76,7 @@ void os_setup_signal_handling(void)
+ /* Find a likely location for support files using the location of the binary.
+    For installed binaries this will be "$bindir/../share/qemu".  When
+    running from the build tree this will be "$bindir/../pc-bios".  */
+-#define SHARE_SUFFIX "/share/qemu"
++#define SHARE_SUFFIX "/share/qemu-kvm"
+ #define BUILD_SUFFIX "/pc-bios"
+ char *os_find_datadir(void)
+ {
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 651cbb8..5b1e264 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -3945,7 +3945,7 @@ void vnc_display_open(const char *id, Error **errp)
+     }
+ 
+ #ifdef CONFIG_VNC_SASL
+-    if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
++    if ((saslErr = sasl_server_init(NULL, "qemu-kvm")) != SASL_OK) {
+         error_setg(errp, "Failed to initialize SASL auth: %s",
+                    sasl_errstring(saslErr, NULL, NULL));
+         goto fail;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0003-Add-RHEL-7-machine-types.patch b/SOURCES/0003-Add-RHEL-7-machine-types.patch
new file mode 100644
index 0000000..b15c41d
--- /dev/null
+++ b/SOURCES/0003-Add-RHEL-7-machine-types.patch
@@ -0,0 +1,3026 @@
+From 44f7e7595c416686a00015e317e74183037a8136 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Sun, 14 Dec 2014 18:32:18 +0100
+Subject: Add RHEL 7 machine types
+
+This commit adds all changes related to machine types applied in
+qemu-kvm-rhev-2.1.2-16.el7.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts (on 2.3 rebase):
+	default-configs/ppc64-softmmu.mak
+	hw/arm/Makefile.objs
+	hw/i386/pc_piix.c
+	hw/i386/pc_q35.c
+	hw/ppc/spapr.c
+	savevm.c - has to change shadow_bios tail to rcu list handling
+	target-i386/machine.c - use xmm instead of ymmh register
+
+--
+Rebase notes (2.10.0):
+- Commented out new unused functions in hw/arm/virt.c
+- savevm_skip_section_footers changed to COMPAT variable (upstream)
+- global_state_set_optional changed to COMPAT variable (upstream)
+- savevm_skip_configuration changed to COMPAT variable (upstream)
+- move shadow_bios() to separate module with stub version available
+- set possible_cpu_arch_ids and cpu_index_to_instance_props fields for arm machine type
+- Re-enable older machine types for ppc64
+- Commented 7.2 rebase error for compat qemu-extended-regs
+
+Rebase notes (2.9.0):
+- new header file for arm (upstream)
+- query_hotpluggable_cpus renamed to has_hotpluggable_cpus (upstream)
+- replace MAX_CPUMASK_BITS with max_cpus
+- Adding rhel6-e1000.rom moved to Initial redhat commit
+- Fixed conflict on cirrus_vga.c
+
+Rebase notes (2.8.0):
+- new "m->max_cpus = 288" in pc_q35_machine_options hw/i386/pc_q35.c
+
+Rebase notes (2.7.0):
+- Additional fsl-imx6.o sabrelito.o files in arm hw dir
+
+Rebase notes (2.6.0):
+- Changes in handling of some compat properties
+- Fixes in x86_64 copmat models
+- Added required devices for aarch64
+- Fixes for ppc machine types
+
+Rebase notes (2.5.0):
+- changed cpu defaults structure
+- chnaged cpu compat properties handling
+- added fix for arm machine type
+
+Rebase notes (2.4.0)
+- Moved needed attribute (due to 5cd8cadae8db905afcbf877cae568c27d1d55a8a)
+- Fixes to machine types changes
+
+Merged patches (2.10.0)
+- 5090ba1 Fix qemu-kvm does not quit when booting guest w/ 241 vcpus and "-no-kvm"
+- 3c52050 x86: bump maximum vcpu count of pc-q35-rhel7.4.0 to 288
+- 0ed92ca x86: Work around SMI breakages
+- f7b5a7f spapr: update SPAPR_COMPAT_RHEL7_3
+- 04faf4d migration: update HW_COMPAT_RHEL7_3
+- 9982768 x86: bump maximum vcpu count of pc-q35-rhel7.4.0 to 384
+- f5095ba re-enable DMA for 7.3 machine type
+- d6ec65d x86 machine compat: 2.9 stragglers
+- eda659a disable linuxboot_dma.bin option rom for 7.3 machine types
+- 8c122a5 Revert "hw/pci: disable pci-bridge's shpc by default" (partial)
+- 627adfa virtio_net: Bypass backends for MTU feature negotiation (partial)
+- b430787 pc: Use "min[x]level" on compat_props on RHEL machine-types
+- 8c3f45a AArch64: remove mach-virt-7.3 machine type
+- d5df1ef Downstream: Update pseries machine types for RHEL-ALT-7.4
+
+Merged patches (2.9.0)
+- 8475d69 hw/arm/virt: Disable virtio-net-pci option ROM file loading
+- 73fe1f6 Workaround rhel6 ctrl_guest_offloads machine type mismatch
+- 21d32ca pc_piix: fix compat props typo for RHEL6 machine types
+- 55a5002 compat: define HW_COMPAT_RHEL7_3
+- 1b8e927 spapr: define pseries-rhel7.4.0 machine type
+- cdb76ec hw/arm/virt: remove aarch64 rhel machine type
+- 7dfa88b hw/arm/virt: create virt-rhel7.3.0 machine type
+- 6894f91 hw/arm/virt: create virt-rhel7.4.0 machine type
+- a9d2d39 x86: Split out options for the head rhel7 machine types
+- fdafbdc x86: Create PC_RHEL7_3_COMPAT definition
+- 3427c72 x86: Define pc-i440fx-rhel7.4.0
+- aea20ab x86: Define pc-q35-rhel7.4.0
+- 0185c0f x86: Remove downstream opteron rdtscp override
+- 6b51073 fix abort in acpi_setup() since 2.8 with rhel6 machine types
+- 954fc0d intel-hda: fix rhel6 compat property
+- 1b57274 kvmclock: reduce kvmclock difference on migration (rhel only part)
+
+Merged patches (2.8.0)
+- a1da2f0 virtio-pci: reduce modern_mem_bar size (rhel only part)
+
+Merged patches (2.7.0):
+- fe9d1cf pc: Use right HW_COMPAT_* macros at PC_RHEL7* compat macros
+- 3938189 compat: Add missing "any_layout" in HW_COMPAT_RHEL7_1
+- 6dffc9d spapr: update RHEL-7.2 machine type
+- c5d5910 migration: fix HW_COMPAT_RHEL7_2
+- 2da9bb8 pc: New (default) pc-i440fx-rhel7.3.0 machine-type
+- 0520d7e 7.3 mismerge fix: Fix ich9-intel-hda compatibility
+- 89528b3 PC migration compat: Section footers/global state
+- 2231e35 fw_cfg for 7.2 compatibility
+- b8a3ade pc: Create new pc-q35-rhel7.3.0 machine-type
+- 340929b q35: Remove 7.0, 7.1, 7.2 machine types
+- bb7fc95 machine types: fix pc_machine_*_options chain
+- d9fa9aa Fix rhel6 rom file
+- dc39363 fix vga type for older machines
+- 255a2d1 7.2 machine type compatibility
+- 16c3d25 target-i386: Remove SSE4a from qemu64 CPU model (rhel only part)
+- 76a1796 target-i386: Remove ABM from qemu64 CPU model (rhel only part)
+- a9f8773 pc: Recover PC_RHEL7_1_COMPAT from RHEL-7.2 code
+- 7a6ed67 pc: Include missing PC_COMPAT_2_3 entries in PC_RHEL7_2_COMPAT
+- 07428f6 Revert "static checker: e1000-82540em got aliased to e1000"
+- 446cf1f Revert "e1000: use alias for default model"
+- 615096e 7.x compat: e1000-82540em
+- 0855905 hw/arm/virt: kill 7.2 machine type
+- 18bbea2 usbredir: turn off streams for rhel7.2 & older
+- 910cf4a target-i386: Fill high bits of mtrr mask (rhel only part)
+- 0e8ab1b target-i386: Enable host-phys-bits on RHEL
+- 8c5f8a5 pc: Fix rhel6.3.0 compat_props setting
+- 8f869f1 pc: use new CPU hotplug interface since 2.7 machine type (rhel only part)
+- d9d646f machine: add properties to compat_props incrementaly (rhel only part)
+- acb18fd apic: Use apic_id as apic's migration instance_id (rhel only part)
+- c7e37d4 apic: fix broken migration for kvm-apic (rhel only part)
+- eca64aee hw/virtio-pci: fix virtio behaviour
+- c56b8F6e pc-rhel-7.2: pcie: fix link active status bit migration
+- 5522aa3 q35-rhel: allow dynamic sysbus
+
+Merged patches (2.6.0):
+- f915d7f arm: virt: Add an abstract RHEL ARM virt machine type
+- deffcc0 arm: virt: Add RHEL 7.3.0 virt machine type
+- 04ca07d arm: virt: Consolidate the naming of RHEL virt machine types
+- 2856ce2 Define HW_COMPAT_RHEL7_2
+- 1869242 spapr: move pseries-2.5 machine to RHEL disabled machine zone
+- cc59ce7 spapr: add RHEL-7.3 machine type
+- 98549c5 pc: Fix property names on CPU compat code
+- caa47bb Fix ich9-intel-hda compatibility
+
+Merged patches (2.3.0):
+- bb4e53c2 pc: add rhel6.6.0 machine type
+- 129a2b3 Downstream-only: Restore "pseries" machine alias
+
+Merged patches (2.4.0):
+- 8e8107c numa: Don't allow memdev= on RHEL-6 machine-types
+- 8b220c0 pc_sysfw: prevent pflash and/or mis-sized firmware for rhel6.x.0 machtypes
+- 9dba3a5 Add pc-i440fx-rhel7.2.0 machine type
+- 1c88ffa Add pc-q35-rhel7.2.0 machine type
+- 6f74d0c Downstream-only: Add rhel7.2.0 machine type
+- a7d6105 Add flag for pre-2.2 migration compatibility
+- 17f9a18 Serial: Migration compatibility pre 2.2/7.2
+- 3799a57 Migration compat for mc146818rtc/irq_reinject_on_ack_count subsection
+- 5668cc1 Fix reported machine type
+- 2417534 386: drop FDC in pc-q35-rhel7.2.0 if neither it nor fl. drives are anted
+- f42eee5 global_state: Make section optional
+- 8640f84 migration: Add configuration section
+- 48c857b pc: memhotplug: fix incorrectly set reserved-memory-end
+- f33f0b6 pc: memhotplug: keep reserved-memory-end broken on rhel71 and earlier machines
+
+(cherry picked from commit d682dec685d0a342b990068b20dbef5aebc30a23)
+---
+ default-configs/aarch64-softmmu.mak |   2 +
+ default-configs/arm-softmmu.mak     |   1 -
+ hw/acpi/piix4.c                     |   6 +-
+ hw/arm/Makefile.objs                |  19 +-
+ hw/arm/virt.c                       | 120 +++++-
+ hw/char/serial.c                    |  28 ++
+ hw/display/cirrus_vga.c             |   4 +-
+ hw/display/vga-isa.c                |   2 +-
+ hw/i386/Makefile.objs               |   1 +
+ hw/i386/pc.c                        |   3 +-
+ hw/i386/pc_piix.c                   | 772 +++++++++++++++++++++++++++++++++++-
+ hw/i386/pc_q35.c                    |  55 ++-
+ hw/i386/pc_sysfw.c                  |  16 +
+ hw/i386/shadow-bios.c               |  64 +++
+ hw/net/e1000.c                      |  20 +-
+ hw/net/ne2000.c                     |   2 +-
+ hw/net/pcnet-pci.c                  |   2 +-
+ hw/net/rtl8139.c                    |   2 +-
+ hw/ppc/Makefile.objs                |   2 +-
+ hw/ppc/spapr.c                      | 124 ++++++
+ hw/smbios/smbios.c                  |   1 +
+ hw/timer/i8254_common.c             |   2 +-
+ hw/timer/mc146818rtc.c              |   6 +
+ hw/usb/hcd-uhci.c                   |  15 +-
+ hw/usb/hcd-xhci.c                   |  18 +
+ hw/usb/hcd-xhci.h                   |   2 +
+ hw/virtio/virtio-pci.c              |   2 +-
+ hw/virtio/virtio.c                  |  22 +-
+ include/hw/arm/virt.h               |  22 +
+ include/hw/compat.h                 | 180 +++++++++
+ include/hw/i386/pc.h                | 442 +++++++++++++++++++++
+ include/hw/usb.h                    |   7 +
+ include/hw/virtio/virtio.h          |   1 +
+ include/sysemu/sysemu.h             |   2 +
+ migration/migration.c               |   2 +
+ migration/migration.h               |   6 +
+ migration/savevm.c                  |   9 +
+ numa.c                              |  13 +
+ qdev-monitor.c                      |   1 -
+ redhat/qemu-kvm.spec.template       |  11 +-
+ scripts/vmstate-static-checker.py   |   1 -
+ stubs/Makefile.objs                 |   1 +
+ stubs/shadow-bios.c                 |   7 +
+ target/i386/cpu.c                   |  51 ++-
+ target/i386/machine.c               |  21 +
+ 45 files changed, 2030 insertions(+), 60 deletions(-)
+ create mode 100644 hw/i386/shadow-bios.c
+ create mode 100644 stubs/shadow-bios.c
+
+diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
+index 2449483..abd18c2 100644
+--- a/default-configs/aarch64-softmmu.mak
++++ b/default-configs/aarch64-softmmu.mak
+@@ -7,3 +7,5 @@ CONFIG_AUX=y
+ CONFIG_DDC=y
+ CONFIG_DPCD=y
+ CONFIG_XLNX_ZYNQMP=y
++CONFIG_PL061=y
++CONFIG_GPIO_KEY=y
+diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
+index bbdd3c1..05aaf8f 100644
+--- a/default-configs/arm-softmmu.mak
++++ b/default-configs/arm-softmmu.mak
+@@ -76,7 +76,6 @@ CONFIG_ARM11SCU=y
+ CONFIG_A9SCU=y
+ CONFIG_DIGIC=y
+ CONFIG_MARVELL_88W8618=y
+-CONFIG_OMAP=y
+ CONFIG_TSC210X=y
+ CONFIG_BLIZZARD=y
+ CONFIG_ONENAND=y
+diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
+index f276967..efd80d1 100644
+--- a/hw/acpi/piix4.c
++++ b/hw/acpi/piix4.c
+@@ -311,7 +311,7 @@ static const VMStateDescription vmstate_cpuhp_state = {
+ static const VMStateDescription vmstate_acpi = {
+     .name = "piix4_pm",
+     .version_id = 3,
+-    .minimum_version_id = 3,
++    .minimum_version_id = 2,
+     .minimum_version_id_old = 1,
+     .load_state_old = acpi_load_old,
+     .post_load = vmstate_acpi_post_load,
+@@ -675,8 +675,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
+ 
+ static Property piix4_pm_properties[] = {
+     DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
+-    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
+-    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
++    DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1),
++    DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1),
+     DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
+     DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
+                      use_acpi_pci_hotplug, true),
+diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
+index a2e56ec..906367c 100644
+--- a/hw/arm/Makefile.objs
++++ b/hw/arm/Makefile.objs
+@@ -1,21 +1,4 @@
+-obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
+-obj-$(CONFIG_DIGIC) += digic_boards.o
+-obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
+-obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
+-obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
+ obj-$(CONFIG_ACPI) += virt-acpi-build.o
+-obj-y += netduino2.o
+ obj-y += sysbus-fdt.o
+ 
+-obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
+-obj-$(CONFIG_DIGIC) += digic.o
+-obj-y += omap1.o omap2.o strongarm.o
+-obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
+-obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
+-obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
+-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
+-obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
+-obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+-obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
+-obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
+-obj-$(CONFIG_MPS2) += mps2.o
++obj-y += boot.o virt.o
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index 6b7a0fe..b14e16d 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -57,6 +57,7 @@
+ #include "qapi/visitor.h"
+ #include "standard-headers/linux/input.h"
+ 
++#if 0 /* disabled Red Hat Enterprise Linux */
+ #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
+     static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
+                                                     void *data) \
+@@ -84,7 +85,36 @@
+     DEFINE_VIRT_MACHINE_LATEST(major, minor, true)
+ #define DEFINE_VIRT_MACHINE(major, minor) \
+     DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
+-
++#endif /* disabled for RHEL */
++
++#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest)                     \
++    static void rhel##m##n##s##_virt_class_init(ObjectClass *oc,        \
++                                                void *data)             \
++    {                                                                   \
++        MachineClass *mc = MACHINE_CLASS(oc);                           \
++        rhel##m##n##s##_virt_options(mc);                               \
++        mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine";  \
++        if (latest) {                                                   \
++            mc->alias = "virt";                                         \
++            mc->is_default = 1;                                         \
++        }                                                               \
++    }                                                                   \
++    static const TypeInfo rhel##m##n##s##_machvirt_info = {             \
++        .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s),     \
++        .parent = TYPE_RHEL_MACHINE,                                    \
++        .instance_init = rhel##m##n##s##_virt_instance_init,            \
++        .class_init = rhel##m##n##s##_virt_class_init,                  \
++    };                                                                  \
++    static void rhel##m##n##s##_machvirt_init(void)                     \
++    {                                                                   \
++        type_register_static(&rhel##m##n##s##_machvirt_info);           \
++    }                                                                   \
++    type_init(rhel##m##n##s##_machvirt_init);
++
++#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor)   \
++    DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true)
++#define DEFINE_RHEL_MACHINE(major, minor, subminor)             \
++    DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false)
+ 
+ /* Number of external interrupt lines to configure the GIC with */
+ #define NUM_IRQS 256
+@@ -1484,6 +1514,7 @@ static void machvirt_init(MachineState *machine)
+     create_platform_bus(vms, pic);
+ }
+ 
++#if 0 /* disabled for RHEL */
+ static bool virt_get_secure(Object *obj, Error **errp)
+ {
+     VirtMachineState *vms = VIRT_MACHINE(obj);
+@@ -1512,6 +1543,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
+     vms->virt = value;
+ }
+ 
++#endif /* disabled for RHEL */
+ static bool virt_get_highmem(Object *obj, Error **errp)
+ {
+     VirtMachineState *vms = VIRT_MACHINE(obj);
+@@ -1604,6 +1636,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
+     return ms->possible_cpus;
+ }
+ 
++#if 0 /* disabled for RHEL */
+ static void virt_machine_class_init(ObjectClass *oc, void *data)
+ {
+     MachineClass *mc = MACHINE_CLASS(oc);
+@@ -1780,3 +1813,88 @@ static void virt_machine_2_6_options(MachineClass *mc)
+     vmc->no_pmu = true;
+ }
+ DEFINE_VIRT_MACHINE(2, 6)
++#endif /* disabled for RHEL */
++
++static void rhel_machine_class_init(ObjectClass *oc, void *data)
++{
++    MachineClass *mc = MACHINE_CLASS(oc);
++
++    mc->family = "virt-rhel-Z";
++    mc->init = machvirt_init;
++    /* Start max_cpus at the maximum QEMU supports. We'll further restrict
++     * it later in machvirt_init, where we have more information about the
++     * configuration of the particular instance.
++     */
++    mc->max_cpus = 255;
++    mc->has_dynamic_sysbus = false;
++    mc->block_default_type = IF_VIRTIO;
++    mc->no_cdrom = 1;
++    mc->pci_allow_0_address = true;
++    /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
++    mc->minimum_page_bits = 12;
++    mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
++    mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
++}
++
++static const TypeInfo rhel_machine_info = {
++    .name          = TYPE_RHEL_MACHINE,
++    .parent        = TYPE_MACHINE,
++    .abstract      = true,
++    .instance_size = sizeof(VirtMachineState),
++    .class_size    = sizeof(VirtMachineClass),
++    .class_init    = rhel_machine_class_init,
++};
++
++static void rhel_machine_init(void)
++{
++    type_register_static(&rhel_machine_info);
++}
++type_init(rhel_machine_init);
++
++static void rhel740_virt_instance_init(Object *obj)
++{
++    VirtMachineState *vms = VIRT_MACHINE(obj);
++    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
++
++    /* EL3 is disabled by default and non-configurable for RHEL */
++    vms->secure = false;
++    /* EL2 is disabled by default and non-configurable for RHEL */
++    vms->virt = false;
++    /* High memory is enabled by default for RHEL */
++    vms->highmem = true;
++    object_property_add_bool(obj, "highmem", virt_get_highmem,
++                             virt_set_highmem, NULL);
++    object_property_set_description(obj, "highmem",
++                                    "Set on/off to enable/disable using "
++                                    "physical address space above 32 bits",
++                                    NULL);
++    /* Default GIC type is still v2, but became configurable for RHEL */
++    vms->gic_version = 2;
++    object_property_add_str(obj, "gic-version", virt_get_gic_version,
++                        virt_set_gic_version, NULL);
++    object_property_set_description(obj, "gic-version",
++                                    "Set GIC version. "
++                                    "Valid values are 2, 3 and host", NULL);
++
++    if (vmc->no_its) {
++        vms->its = false;
++    } else {
++        /* Default allows ITS instantiation */
++        vms->its = true;
++        object_property_add_bool(obj, "its", virt_get_its,
++                                 virt_set_its, NULL);
++        object_property_set_description(obj, "its",
++                                        "Set on/off to enable/disable "
++                                        "ITS instantiation",
++                                        NULL);
++    }
++
++    vms->memmap=a15memmap;
++    vms->irqmap=a15irqmap;
++}
++
++static void rhel740_virt_options(MachineClass *mc)
++{
++    SET_MACHINE_COMPAT(mc, ARM_RHEL_COMPAT);
++}
++DEFINE_RHEL_MACHINE_AS_LATEST(7, 4, 0)
+diff --git a/hw/char/serial.c b/hw/char/serial.c
+index 9aec6c6..fe4f41d 100644
+--- a/hw/char/serial.c
++++ b/hw/char/serial.c
+@@ -30,6 +30,7 @@
+ #include "qemu/timer.h"
+ #include "exec/address-spaces.h"
+ #include "qemu/error-report.h"
++#include "migration/migration.h"
+ 
+ //#define DEBUG_SERIAL
+ 
+@@ -689,6 +690,9 @@ static int serial_post_load(void *opaque, int version_id)
+ static bool serial_thr_ipending_needed(void *opaque)
+ {
+     SerialState *s = opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
+ 
+     if (s->ier & UART_IER_THRI) {
+         bool expected_value = ((s->iir & UART_IIR_ID) == UART_IIR_THRI);
+@@ -716,6 +720,10 @@ static const VMStateDescription vmstate_serial_thr_ipending = {
+ static bool serial_tsr_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return s->tsr_retry != 0;
+ }
+ 
+@@ -735,6 +743,10 @@ static const VMStateDescription vmstate_serial_tsr = {
+ static bool serial_recv_fifo_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return !fifo8_is_empty(&s->recv_fifo);
+ 
+ }
+@@ -753,6 +765,10 @@ static const VMStateDescription vmstate_serial_recv_fifo = {
+ static bool serial_xmit_fifo_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return !fifo8_is_empty(&s->xmit_fifo);
+ }
+ 
+@@ -770,6 +786,10 @@ static const VMStateDescription vmstate_serial_xmit_fifo = {
+ static bool serial_fifo_timeout_timer_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return timer_pending(s->fifo_timeout_timer);
+ }
+ 
+@@ -787,6 +807,10 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = {
+ static bool serial_timeout_ipending_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return s->timeout_ipending != 0;
+ }
+ 
+@@ -804,6 +828,10 @@ static const VMStateDescription vmstate_serial_timeout_ipending = {
+ static bool serial_poll_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return s->poll_msl >= 0;
+ }
+ 
+diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
+index afc290a..14008aa 100644
+--- a/hw/display/cirrus_vga.c
++++ b/hw/display/cirrus_vga.c
+@@ -3063,7 +3063,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)
+ 
+ static Property isa_cirrus_vga_properties[] = {
+     DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState,
+-                       cirrus_vga.vga.vram_size_mb, 4),
++                       cirrus_vga.vga.vram_size_mb, 16),
+     DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState,
+                        cirrus_vga.enable_blitter, true),
+     DEFINE_PROP_END_OF_LIST(),
+@@ -3134,7 +3134,7 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
+ 
+ static Property pci_vga_cirrus_properties[] = {
+     DEFINE_PROP_UINT32("vgamem_mb", struct PCICirrusVGAState,
+-                       cirrus_vga.vga.vram_size_mb, 4),
++                       cirrus_vga.vga.vram_size_mb, 16),
+     DEFINE_PROP_BOOL("blitter", struct PCICirrusVGAState,
+                      cirrus_vga.enable_blitter, true),
+     DEFINE_PROP_END_OF_LIST(),
+diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
+index 1af9556..91a675d 100644
+--- a/hw/display/vga-isa.c
++++ b/hw/display/vga-isa.c
+@@ -80,7 +80,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
+ }
+ 
+ static Property vga_isa_properties[] = {
+-    DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8),
++    DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 16),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
+index c14559b..9b5686b 100644
+--- a/hw/i386/Makefile.objs
++++ b/hw/i386/Makefile.objs
+@@ -10,3 +10,4 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/
+ obj-y += kvmvapic.o
+ obj-y += acpi-build.o
+ obj-y += pci-assign-load-rom.o
++obj-y += shadow-bios.o
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index 2108104..64929ea 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -2353,7 +2353,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
+     mc->default_boot_order = "cad";
+     mc->hot_add_cpu = pc_hot_add_cpu;
+     mc->block_default_type = IF_IDE;
+-    mc->max_cpus = 255;
++    /* 240: max CPU count for RHEL */
++    mc->max_cpus = 240;
+     mc->reset = pc_machine_reset;
+     hc->pre_plug = pc_machine_device_pre_plug_cb;
+     hc->plug = pc_machine_device_plug_cb;
+diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
+index 46dfd2c..7f12ce3 100644
+--- a/hw/i386/pc_piix.c
++++ b/hw/i386/pc_piix.c
+@@ -48,6 +48,7 @@
+ #include "hw/acpi/acpi.h"
+ #include "cpu.h"
+ #include "qemu/error-report.h"
++#include "migration/migration.h"
+ #ifdef CONFIG_XEN
+ #include <xen/hvm/hvm_info_table.h>
+ #include "hw/xen/xen_pt.h"
+@@ -168,8 +169,8 @@ static void pc_init1(MachineState *machine,
+     if (pcmc->smbios_defaults) {
+         MachineClass *mc = MACHINE_GET_CLASS(machine);
+         /* These values are guest ABI, do not change */
+-        smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)",
+-                            mc->name, pcmc->smbios_legacy_mode,
++        smbios_set_defaults("Red Hat", "KVM",
++                            mc->desc, pcmc->smbios_legacy_mode,
+                             pcmc->smbios_uuid_encoded,
+                             SMBIOS_ENTRY_POINT_21);
+     }
+@@ -311,6 +312,7 @@ static void pc_init1(MachineState *machine,
+  * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options().
+  */
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+ static void pc_compat_2_3(MachineState *machine)
+ {
+     PCMachineState *pcms = PC_MACHINE(machine);
+@@ -1122,3 +1124,769 @@ static void xenfv_machine_options(MachineClass *m)
+ DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init,
+                   xenfv_machine_options);
+ #endif
++machine_init(pc_machine_init);
++
++#endif  /* Disabled for Red Hat Enterprise Linux */
++
++/* Red Hat Enterprise Linux machine types */
++
++/* Options for the latest rhel7 machine type */
++static void pc_machine_rhel7_options(MachineClass *m)
++{
++    m->family = "pc_piix_Y";
++    m->default_machine_opts = "firmware=bios-256k.bin";
++    m->default_display = "std";
++    SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT);
++    m->alias = "pc";
++    m->is_default = 1;
++}
++
++static void pc_init_rhel740(MachineState *machine)
++{
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);
++}
++
++static void pc_machine_rhel740_options(MachineClass *m)
++{
++    pc_machine_rhel7_options(m);
++    m->desc = "RHEL 7.4.0 PC (i440FX + PIIX, 1996)";
++}
++
++DEFINE_PC_MACHINE(rhel740, "pc-i440fx-rhel7.4.0", pc_init_rhel740,
++                  pc_machine_rhel740_options);
++
++static void pc_init_rhel730(MachineState *machine)
++{
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);
++}
++
++static void pc_machine_rhel730_options(MachineClass *m)
++{
++    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
++    pc_machine_rhel740_options(m);
++    m->alias = NULL;
++    m->is_default = 0;
++    m->desc = "RHEL 7.3.0 PC (i440FX + PIIX, 1996)";
++    pcmc->linuxboot_dma_enabled = false;
++    SET_MACHINE_COMPAT(m, PC_RHEL7_3_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel730, "pc-i440fx-rhel7.3.0", pc_init_rhel730,
++                  pc_machine_rhel730_options);
++
++
++static void pc_init_rhel720(MachineState *machine)
++{
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);
++}
++
++static void pc_machine_rhel720_options(MachineClass *m)
++{
++    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
++    pc_machine_rhel730_options(m);
++    m->desc = "RHEL 7.2.0 PC (i440FX + PIIX, 1996)";
++    /* From pc_i440fx_2_5_machine_options */
++    pcmc->save_tsc_khz = false;
++    m->legacy_fw_cfg_order = 1;
++    /* Note: broken_reserved_end was already in 7.2 */
++    /* From pc_i440fx_2_6_machine_options */
++    pcmc->legacy_cpu_hotplug = true;
++    SET_MACHINE_COMPAT(m, PC_RHEL7_2_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel720, "pc-i440fx-rhel7.2.0", pc_init_rhel720,
++                  pc_machine_rhel720_options);
++
++static void pc_compat_rhel710(MachineState *machine)
++{
++    PCMachineState *pcms = PC_MACHINE(machine);
++    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
++
++    /* From pc_compat_2_2 */
++    pcmc->rsdp_in_ram = false;
++    machine->suppress_vmdesc = true;
++
++    /* From pc_compat_2_1 */
++    pcmc->smbios_uuid_encoded = false;
++    x86_cpu_change_kvm_default("svm", NULL);
++    pcmc->enforce_aligned_dimm = false;
++
++    /* Disable all the extra subsections that were added in 2.2 */
++    migrate_pre_2_2 = true;
++
++    /* From pc_i440fx_2_4_machine_options */
++    pcmc->broken_reserved_end = true;
++}
++
++static void pc_init_rhel710(MachineState *machine)
++{
++    pc_compat_rhel710(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);
++}
++
++static void pc_machine_rhel710_options(MachineClass *m)
++{
++    pc_machine_rhel720_options(m);
++    m->family = "pc_piix_Y";
++    m->desc = "RHEL 7.1.0 PC (i440FX + PIIX, 1996)";
++    m->default_display = "cirrus";
++    SET_MACHINE_COMPAT(m, PC_RHEL7_1_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel710, "pc-i440fx-rhel7.1.0", pc_init_rhel710,
++                  pc_machine_rhel710_options);
++
++static void pc_compat_rhel700(MachineState *machine)
++{
++    PCMachineState *pcms = PC_MACHINE(machine);
++    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
++
++    pc_compat_rhel710(machine);
++
++    /* Upstream enables it for everyone, we're a little more selective */
++    x86_cpu_change_kvm_default("x2apic", NULL);
++    x86_cpu_change_kvm_default("svm", NULL);
++    pcmc->legacy_acpi_table_size = 6418; /* see pc_compat_2_0() */
++    pcmc->smbios_legacy_mode = true;
++    pcmc->has_reserved_memory = false;
++    migrate_cve_2014_5263_xhci_fields = true;
++}
++
++static void pc_init_rhel700(MachineState *machine)
++{
++    pc_compat_rhel700(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);
++}
++
++static void pc_machine_rhel700_options(MachineClass *m)
++{
++    pc_machine_rhel710_options(m);
++    m->family = "pc_piix_Y";
++    m->desc = "RHEL 7.0.0 PC (i440FX + PIIX, 1996)";
++    SET_MACHINE_COMPAT(m, PC_RHEL7_0_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel700, "pc-i440fx-rhel7.0.0", pc_init_rhel700,
++                  pc_machine_rhel700_options);
++
++#define PC_RHEL6_6_COMPAT \
++        {\
++            .driver   = "scsi-hd",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "scsi-cd",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "scsi-disk",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "ide-hd",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "ide-cd",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "ide-drive",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "virtio-blk-pci",\
++            .property = "discard_granularity",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "virtio-serial-pci",\
++            .property = "vectors",\
++            /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
++            .value    = stringify(0xFFFFFFFF),\
++        },{\
++            .driver   = "486-" TYPE_X86_CPU,\
++            .property = "model",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "usb-tablet",\
++            .property = "usb_version",\
++            .value    = stringify(1),\
++        },{\
++            .driver   = "virtio-net-pci",\
++            .property = "mq",\
++            .value    = "off",\
++        },{\
++            .driver   = "VGA",\
++            .property = "mmio",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-blk-pci",\
++            .property = "config-wce",\
++            .value    = "off",\
++        },{\
++            .driver   = TYPE_ISA_FDC,\
++            .property = "check_media_rate",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-balloon-pci",\
++            .property = "class",\
++            .value    = stringify(PCI_CLASS_MEMORY_RAM),\
++        },{\
++            .driver   = TYPE_PCI_DEVICE,\
++            .property = "command_serr_enable",\
++            .value    = "off",\
++        },{\
++            .driver   = "AC97",\
++            .property = "use_broken_id",\
++            .value    = stringify(1),\
++        },{\
++            .driver   = "intel-hda",\
++            .property = "msi",\
++            .value    = "off",\
++        },{\
++            .driver = "qemu32-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value = stringify(0),\
++        },{\
++            .driver = "486-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value = stringify(0),\
++        },{\
++            .driver   = "qemu32-" TYPE_X86_CPU,\
++            .property = "model",\
++            .value    = stringify(3),\
++        },{\
++            .driver   = "usb-ccid",\
++            .property = "serial",\
++            .value    = "1",\
++        },{\
++            .driver   = "ne2k_pci",\
++            .property = "romfile",\
++            .value    = "rhel6-ne2k_pci.rom",\
++        },{\
++            .driver   = "pcnet",\
++            .property = "romfile",\
++            .value    = "rhel6-pcnet.rom",\
++        },{\
++            .driver   = "rtl8139",\
++            .property = "romfile",\
++            .value    = "rhel6-rtl8139.rom",\
++        },{\
++            .driver   = "e1000",\
++            .property = "romfile",\
++            .value    = "rhel6-e1000.rom",\
++        },{\
++            .driver   = "virtio-net-pci",\
++            .property = "romfile",\
++            .value    = "rhel6-virtio.rom",\
++        },{\
++            .driver   = "virtio-net-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },\
++        {\
++            .driver = "pentium" "-" TYPE_X86_CPU,\
++            .property = "apic",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "pentium2" "-" TYPE_X86_CPU,\
++            .property = "apic",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "pentium3" "-" TYPE_X86_CPU,\
++            .property = "apic",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "Conroe" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Penryn" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Nehalem" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "pclmulqdq",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "fxsr",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "mmx",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "pat",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "cmov",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "pge",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "cx8",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "mce",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "pae",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "msr",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "tsc",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "pse",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "de",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "fpu",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Broadwell" "-" TYPE_X86_CPU,\
++            .property = "rdtscp",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "Broadwell" "-" TYPE_X86_CPU,\
++            .property = "smap",\
++            .value = "off",\
++        },\
++        {\
++            .driver = TYPE_X86_CPU,\
++            .property = "rdtscp",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "Opteron_G1" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Opteron_G2" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Opteron_G3" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
++        {\
++            .driver = "Opteron_G4" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "Opteron_G5" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "off",\
++        },\
++        {\
++            .driver = TYPE_X86_CPU,\
++            .property = "3dnow",\
++            .value = "off",\
++        },\
++        {\
++            .driver = TYPE_X86_CPU,\
++            .property = "3dnowext",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "virtio-net-pci",\
++            .property = "__com.redhat_rhel6_ctrl_guest_workaround", \
++            .value = "on",\
++        },
++
++static void pc_compat_rhel660(MachineState *machine)
++{
++    PCMachineState *pcms = PC_MACHINE(machine);
++    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
++
++    pc_compat_rhel700(machine);
++    if (!machine->cpu_model) {
++        machine->cpu_model = "cpu64-rhel6";
++    }
++
++    x86_cpu_change_kvm_default("kvm-pv-unhalt", NULL);
++
++    pcmc->gigabyte_align = false;
++    shadow_bios_after_incoming = true;
++    ich9_uhci123_irqpin_override = true;
++}
++
++static void pc_init_rhel660(MachineState *machine)
++{
++    pc_compat_rhel660(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel660_options(MachineClass *m)
++{
++    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
++    pc_machine_rhel700_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.6.0 PC";
++    m->rom_file_has_mr = false;
++    m->default_machine_opts = "firmware=bios.bin";
++    pcmc->has_acpi_build = false;
++    SET_MACHINE_COMPAT(m, PC_RHEL6_6_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel660, "rhel6.6.0", pc_init_rhel660,
++                  pc_machine_rhel660_options);
++
++#define PC_RHEL6_5_COMPAT \
++        {\
++            .driver   = TYPE_USB_DEVICE,\
++            .property = "msos-desc",\
++            .value    = "no",\
++        },
++
++static void pc_compat_rhel650(MachineState *machine)
++{
++    pc_compat_rhel660(machine);
++}
++
++static void pc_init_rhel650(MachineState *machine)
++{
++    pc_compat_rhel650(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel650_options(MachineClass *m)
++{
++    pc_machine_rhel660_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.5.0 PC";
++    SET_MACHINE_COMPAT(m, PC_RHEL6_5_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel650, "rhel6.5.0", pc_init_rhel650,
++                  pc_machine_rhel650_options);
++
++#define PC_RHEL6_4_COMPAT \
++        {\
++            .driver   = "virtio-scsi-pci",\
++            .property = "vectors",\
++            .value    = stringify(2),\
++        },{\
++            .driver   = "hda-micro",\
++            .property = "mixer",\
++            .value    = "off",\
++        },{\
++            .driver   = "hda-duplex",\
++            .property = "mixer",\
++            .value    = "off",\
++        },{\
++            .driver   = "hda-output",\
++            .property = "mixer",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-net-pci",\
++            .property = "ctrl_mac_addr",\
++            .value    = "off",\
++        },\
++        {\
++            .driver = TYPE_X86_CPU,\
++            .property = "sep",\
++            .value = "off",\
++        },\
++        {\
++            .driver = "virtio-net-pci",\
++            .property = "__com.redhat_rhel6_ctrl_guest_workaround", \
++            .value = "off",\
++        },
++
++static void pc_compat_rhel640(MachineState *machine)
++{
++    pc_compat_rhel650(machine);
++}
++
++static void pc_init_rhel640(MachineState *machine)
++{
++    pc_compat_rhel640(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel640_options(MachineClass *m)
++{
++    pc_machine_rhel650_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.4.0 PC";
++    SET_MACHINE_COMPAT(m, PC_RHEL6_4_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel640, "rhel6.4.0", pc_init_rhel640,
++                  pc_machine_rhel640_options);
++
++#define PC_RHEL6_3_COMPAT \
++        {\
++            .driver   = "Conroe-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(2),\
++        },{\
++            .driver   = "Penryn-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(2),\
++        },{\
++            .driver   = "Nehalem-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(2),\
++        },{\
++            .driver   = "e1000",\
++            .property = "autonegotiation",\
++            .value    = "off",\
++        },{\
++            .driver   = "qxl",\
++            .property = "revision",\
++            .value    = stringify(3),\
++        },{\
++            .driver   = "qxl-vga",\
++            .property = "revision",\
++            .value    = stringify(3),\
++        },{\
++            .driver   = "virtio-scsi-pci",\
++            .property = "hotplug",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-scsi-pci",\
++            .property = "param_change",\
++            .value    = "off",\
++        },{\
++            .driver = TYPE_X86_CPU,\
++            .property = "pmu",\
++            .value = "on",\
++        },{\
++            .driver   = "usb-hub",\
++            .property = "serial",\
++            .value    = "314159",\
++        },{\
++            .driver   = "usb-storage",\
++            .property = "serial",\
++            .value    = "1",\
++        },\
++        {\
++            .driver = "SandyBridge" "-" TYPE_X86_CPU,\
++            .property = "tsc-deadline",\
++            .value = "off",\
++        },
++
++static void pc_compat_rhel630(MachineState *machine)
++{
++    pc_compat_rhel640(machine);
++    x86_cpu_change_kvm_default("kvm-pv-eoi",NULL);
++    enable_compat_apic_id_mode();
++}
++
++static void pc_init_rhel630(MachineState *machine)
++{
++    pc_compat_rhel630(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel630_options(MachineClass *m)
++{
++    pc_machine_rhel640_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.3.0 PC";
++    SET_MACHINE_COMPAT(m, PC_RHEL6_3_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel630, "rhel6.3.0", pc_init_rhel630,
++                  pc_machine_rhel630_options);
++
++
++#define PC_RHEL6_2_COMPAT \
++        {\
++            .driver = TYPE_X86_CPU,\
++            .property = "pmu",\
++            .value = "off",\
++        },
++
++static void pc_compat_rhel620(MachineState *machine)
++{
++    pc_compat_rhel630(machine);
++}
++
++static void pc_init_rhel620(MachineState *machine)
++{
++    pc_compat_rhel620(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel620_options(MachineClass *m)
++{
++    pc_machine_rhel630_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.2.0 PC";
++    SET_MACHINE_COMPAT(m, PC_RHEL6_2_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel620, "rhel6.2.0", pc_init_rhel620,
++                  pc_machine_rhel620_options);
++
++/*
++ * NOTE: We don't have the event_idx compat entry for the
++ * virtio-balloon-pci driver because RHEL6 doesn't disable
++ * it either due to a bug (see RHBZ 1029539 fo more info)
++ */
++#define PC_RHEL6_1_COMPAT \
++        {\
++            .driver   = "PIIX4_PM",\
++            .property = "disable_s3",\
++            .value    = "0",\
++        },{\
++            .driver   = "PIIX4_PM",\
++            .property = "disable_s4",\
++            .value    = "0",\
++        },{\
++            .driver   = "qxl",\
++            .property = "revision",\
++            .value    = stringify(2),\
++        },{\
++            .driver   = "qxl-vga",\
++            .property = "revision",\
++            .value    = stringify(2),\
++        },{\
++            .driver   = "virtio-blk-pci",\
++            .property = "event_idx",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-serial-pci",\
++            .property = "event_idx",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-net-pci",\
++            .property = "event_idx",\
++            .value    = "off",\
++        },{\
++            .driver   = "usb-kbd",\
++            .property = "serial",\
++            .value    = "1",\
++        },{\
++            .driver   = "usb-mouse",\
++            .property = "serial",\
++            .value    = "1",\
++        },{\
++            .driver   = "usb-tablet",\
++            .property = "serial",\
++            .value    = "1",\
++        },
++
++static void pc_compat_rhel610(MachineState *machine)
++{
++    pc_compat_rhel620(machine);
++}
++
++static void pc_init_rhel610(MachineState *machine)
++{
++    pc_compat_rhel610(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel610_options(MachineClass *m)
++{
++    pc_machine_rhel620_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.1.0 PC";
++    SET_MACHINE_COMPAT(m, PC_RHEL6_1_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel610, "rhel6.1.0", pc_init_rhel610,
++                  pc_machine_rhel610_options);
++
++#define PC_RHEL6_0_COMPAT \
++        {\
++            .driver   = "qxl",\
++            .property = "revision",\
++            .value    = stringify(1),\
++        },{\
++            .driver   = "qxl-vga",\
++            .property = "revision",\
++            .value    = stringify(1),\
++        },{\
++            .driver   = "VGA",\
++            .property = "rombar",\
++            .value    = stringify(0),\
++        },
++
++static void pc_compat_rhel600(MachineState *machine)
++{
++    pc_compat_rhel610(machine);
++}
++
++static void pc_init_rhel600(MachineState *machine)
++{
++    pc_compat_rhel600(machine);
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);}
++
++static void pc_machine_rhel600_options(MachineClass *m)
++{
++    pc_machine_rhel610_options(m);
++    m->family = "pc_piix_Z";
++    m->desc = "RHEL 6.0.0 PC";
++    SET_MACHINE_COMPAT(m, PC_RHEL6_0_COMPAT);
++}
++
++DEFINE_PC_MACHINE(rhel600, "rhel6.0.0", pc_init_rhel600,
++                  pc_machine_rhel600_options);
++
+diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
+index 169a214..575d407 100644
+--- a/hw/i386/pc_q35.c
++++ b/hw/i386/pc_q35.c
+@@ -137,8 +137,8 @@ static void pc_q35_init(MachineState *machine)
+ 
+     if (pcmc->smbios_defaults) {
+         /* These values are guest ABI, do not change */
+-        smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",
+-                            mc->name, pcmc->smbios_legacy_mode,
++        smbios_set_defaults("Red Hat", "KVM",
++                            mc->desc, pcmc->smbios_legacy_mode,
+                             pcmc->smbios_uuid_encoded,
+                             SMBIOS_ENTRY_POINT_21);
+     }
+@@ -289,6 +289,7 @@ static void pc_q35_init(MachineState *machine)
+     DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
+ 
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+ static void pc_q35_machine_options(MachineClass *m)
+ {
+     m->family = "pc_q35";
+@@ -300,6 +301,7 @@ static void pc_q35_machine_options(MachineClass *m)
+     m->no_floppy = 1;
+     m->has_dynamic_sysbus = true;
+     m->max_cpus = 288;
++    SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT);
+ }
+ 
+ static void pc_q35_2_10_machine_options(MachineClass *m)
+@@ -376,3 +378,52 @@ static void pc_q35_2_4_machine_options(MachineClass *m)
+ 
+ DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL,
+                    pc_q35_2_4_machine_options);
++#endif  /* Disabled for Red Hat Enterprise Linux */
++
++/* Red Hat Enterprise Linux machine types */
++
++/* Options for the latest rhel7 q35 machine type */
++static void pc_q35_machine_rhel7_options(MachineClass *m)
++{
++    m->family = "pc_q35_Z";
++    m->default_machine_opts = "firmware=bios-256k.bin";
++    m->default_display = "std";
++    m->no_floppy = 1;
++    m->has_dynamic_sysbus = true;
++    m->alias = "q35";
++    m->max_cpus = 384;
++    SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT);
++}
++
++static void pc_q35_init_rhel740(MachineState *machine)
++{
++    pc_q35_init(machine);
++}
++
++static void pc_q35_machine_rhel740_options(MachineClass *m)
++{
++    pc_q35_machine_rhel7_options(m);
++    m->desc = "RHEL-7.4.0 PC (Q35 + ICH9, 2009)";
++}
++
++DEFINE_PC_MACHINE(q35_rhel740, "pc-q35-rhel7.4.0", pc_q35_init_rhel740,
++                  pc_q35_machine_rhel740_options);
++
++static void pc_q35_init_rhel730(MachineState *machine)
++{
++    pc_q35_init(machine);
++}
++
++static void pc_q35_machine_rhel730_options(MachineClass *m)
++{
++    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
++    pc_q35_machine_rhel740_options(m);
++    m->alias = NULL;
++    m->desc = "RHEL-7.3.0 PC (Q35 + ICH9, 2009)";
++    m->max_cpus = 255;
++    pcmc->linuxboot_dma_enabled = false;
++    SET_MACHINE_COMPAT(m, PC_RHEL7_3_COMPAT);
++}
++
++DEFINE_PC_MACHINE(q35_rhel730, "pc-q35-rhel7.3.0", pc_q35_init_rhel730,
++                  pc_q35_machine_rhel730_options);
+diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
+index 6b18374..04db39a 100644
+--- a/hw/i386/pc_sysfw.c
++++ b/hw/i386/pc_sysfw.c
+@@ -193,6 +193,13 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+         (bios_size % 65536) != 0) {
+         goto bios_error;
+     }
++    if (shadow_bios_after_incoming && bios_size != 128 * 1024) {
++        MachineClass *mc;
++
++        mc = MACHINE_GET_CLASS(current_machine);
++        error_report("machine %s only supports a 128KB BIOS image", mc->name);
++        exit(1);
++    }
+     bios = g_malloc(sizeof(*bios));
+     memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
+     if (!isapc_ram_fw) {
+@@ -240,6 +247,15 @@ void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+         return;
+     }
+ 
++    if (shadow_bios_after_incoming) {
++        MachineClass *mc;
++
++        mc = MACHINE_GET_CLASS(current_machine);
++        error_report("flash-based firmware is not supported by machine %s",
++                     mc->name);
++        exit(1);
++    }
++
+     if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
+         /* Older KVM cannot execute from device memory. So, flash memory
+          * cannot be used unless the readonly memory kvm capability is present. */
+diff --git a/hw/i386/shadow-bios.c b/hw/i386/shadow-bios.c
+new file mode 100644
+index 0000000..65a4cb8
+--- /dev/null
++++ b/hw/i386/shadow-bios.c
+@@ -0,0 +1,64 @@
++#include "qemu/osdep.h"
++#include "sysemu/sysemu.h"
++#include "target/i386/cpu.h"
++#include "exec/ram_addr.h"
++#include "qemu/cutils.h"
++
++void shadow_bios(void)
++{
++    RAMBlock *block, *ram, *oprom, *bios;
++    size_t one_meg, oprom_size, bios_size;
++    uint8_t *cd_seg_host, *ef_seg_host;
++
++    ram = NULL;
++    oprom = NULL;
++    bios = NULL;
++    rcu_read_lock();
++    QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
++        if (strcmp("pc.ram", block->idstr) == 0) {
++            assert(ram == NULL);
++            ram = block;
++        } else if (strcmp("pc.rom", block->idstr) == 0) {
++            assert(oprom == NULL);
++            oprom = block;
++        } else if (strcmp("pc.bios", block->idstr) == 0) {
++            assert(bios == NULL);
++            bios = block;
++        }
++    }
++    assert(ram != NULL);
++    assert(oprom != NULL);
++    assert(bios != NULL);
++    assert(memory_region_is_ram(ram->mr));
++    assert(memory_region_is_ram(oprom->mr));
++    assert(memory_region_is_ram(bios->mr));
++    assert(int128_eq(ram->mr->size, int128_make64(ram->used_length)));
++    assert(int128_eq(oprom->mr->size, int128_make64(oprom->used_length)));
++    assert(int128_eq(bios->mr->size, int128_make64(bios->used_length)));
++
++    one_meg = 1024 * 1024;
++    oprom_size = 128 * 1024;
++    bios_size = 128 * 1024;
++    assert(ram->used_length >= one_meg);
++    assert(oprom->used_length == oprom_size);
++    assert(bios->used_length == bios_size);
++
++    ef_seg_host = memory_region_get_ram_ptr(ram->mr) + (one_meg - bios_size);
++    cd_seg_host = ef_seg_host - oprom_size;
++
++    /* This is a crude hack, but we must distinguish a rhel6.x.0 machtype guest
++     * coming in from a RHEL-6 emulator (where shadowing has had no effect on
++     * "pc.ram") from a similar guest coming in from a RHEL-7 emulator (where
++     * shadowing has worked). In the latter case we must not trample the live
++     * SeaBIOS variables in "pc.ram".
++     */
++    if (buffer_is_zero(ef_seg_host, bios_size)) {
++        fprintf(stderr, "copying E and F segments from pc.bios to pc.ram\n");
++        memcpy(ef_seg_host, memory_region_get_ram_ptr(bios->mr), bios_size);
++    }
++    if (buffer_is_zero(cd_seg_host, oprom_size)) {
++        fprintf(stderr, "copying C and D segments from pc.rom to pc.ram\n");
++        memcpy(cd_seg_host, memory_region_get_ram_ptr(oprom->mr), oprom_size);
++    }
++    rcu_read_unlock();
++}
+diff --git a/hw/net/e1000.c b/hw/net/e1000.c
+index f2e5072..3d86146 100644
+--- a/hw/net/e1000.c
++++ b/hw/net/e1000.c
+@@ -1595,6 +1595,16 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
+ 
+     pci_conf = pci_dev->config;
+ 
++    if (!(d->compat_flags & E1000_FLAG_AUTONEG)) {
++        /*
++         * We have no capabilities, so capability list bit should normally be 0.
++         * Keep it on for compat machine types to avoid breaking migration.
++         * HACK: abuse E1000_FLAG_AUTONEG, which is off exactly for
++         * the machine types that need this.
++         */
++        pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST);
++    }
++
+     /* TODO: RST# value should be 0, PCI spec 6.2.4 */
+     pci_conf[PCI_CACHE_LINE_SIZE] = 0x10;
+ 
+@@ -1657,7 +1667,7 @@ static void e1000_class_init(ObjectClass *klass, void *data)
+ 
+     k->realize = pci_e1000_realize;
+     k->exit = pci_e1000_uninit;
+-    k->romfile = "efi-e1000.rom";
++    k->romfile = "pxe-e1000.rom";
+     k->vendor_id = PCI_VENDOR_ID_INTEL;
+     k->device_id = info->device_id;
+     k->revision = info->revision;
+@@ -1689,7 +1699,7 @@ static const TypeInfo e1000_base_info = {
+ 
+ static const E1000Info e1000_devices[] = {
+     {
+-        .name      = "e1000",
++        .name      = "e1000-82540em",
+         .device_id = E1000_DEV_ID_82540EM,
+         .revision  = 0x03,
+         .phy_id2   = E1000_PHY_ID2_8254xx_DEFAULT,
+@@ -1708,6 +1718,11 @@ static const E1000Info e1000_devices[] = {
+     },
+ };
+ 
++static const TypeInfo e1000_default_info = {
++    .name          = "e1000",
++    .parent        = "e1000-82540em",
++};
++
+ static void e1000_register_types(void)
+ {
+     int i;
+@@ -1725,6 +1740,7 @@ static void e1000_register_types(void)
+ 
+         type_register(&type_info);
+     }
++    type_register_static(&e1000_default_info);
+ }
+ 
+ type_init(e1000_register_types)
+diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
+index 798d681..8660955 100644
+--- a/hw/net/ne2000.c
++++ b/hw/net/ne2000.c
+@@ -771,7 +771,7 @@ static void ne2000_class_init(ObjectClass *klass, void *data)
+ 
+     k->realize = pci_ne2000_realize;
+     k->exit = pci_ne2000_exit;
+-    k->romfile = "efi-ne2k_pci.rom",
++    k->romfile = "pxe-ne2k_pci.rom",
+     k->vendor_id = PCI_VENDOR_ID_REALTEK;
+     k->device_id = PCI_DEVICE_ID_REALTEK_8029;
+     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
+index 0acf8a4..eeab4ca 100644
+--- a/hw/net/pcnet-pci.c
++++ b/hw/net/pcnet-pci.c
+@@ -348,7 +348,7 @@ static void pcnet_class_init(ObjectClass *klass, void *data)
+ 
+     k->realize = pci_pcnet_realize;
+     k->exit = pci_pcnet_uninit;
+-    k->romfile = "efi-pcnet.rom",
++    k->romfile = "pxe-pcnet.rom",
+     k->vendor_id = PCI_VENDOR_ID_AMD;
+     k->device_id = PCI_DEVICE_ID_AMD_LANCE;
+     k->revision = 0x10;
+diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
+index 671c7e4..450658c 100644
+--- a/hw/net/rtl8139.c
++++ b/hw/net/rtl8139.c
+@@ -3472,7 +3472,7 @@ static void rtl8139_class_init(ObjectClass *klass, void *data)
+ 
+     k->realize = pci_rtl8139_realize;
+     k->exit = pci_rtl8139_uninit;
+-    k->romfile = "efi-rtl8139.rom";
++    k->romfile = "pxe-rtl8139.rom";
+     k->vendor_id = PCI_VENDOR_ID_REALTEK;
+     k->device_id = PCI_DEVICE_ID_REALTEK_8139;
+     k->revision = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
+diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
+index 7efc686..645ffdf 100644
+--- a/hw/ppc/Makefile.objs
++++ b/hw/ppc/Makefile.objs
+@@ -12,7 +12,7 @@ obj-y += spapr_pci_vfio.o
+ endif
+ obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o
+ # PowerPC 4xx boards
+-obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
++obj-y += ppc4xx_devs.o ppc405_uc.o
+ obj-y += ppc4xx_pci.o
+ # PReP
+ obj-$(CONFIG_PREP) += prep.o
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index cec441c..268fd44 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3537,6 +3537,7 @@ static const TypeInfo spapr_machine_info = {
+     }                                                                \
+     type_init(spapr_machine_register_##suffix)
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+ /*
+  * pseries-2.10
+  */
+@@ -3630,6 +3631,7 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false);
+         .property = "pre-2.8-migration",            \
+         .value    = "on",                           \
+     },
++#endif
+ 
+ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
+                               uint64_t *buid, hwaddr *pio,
+@@ -3680,6 +3682,7 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
+      */
+ }
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+ static void spapr_machine_2_7_instance_options(MachineState *machine)
+ {
+     sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
+@@ -3839,6 +3842,127 @@ static void spapr_machine_2_1_class_options(MachineClass *mc)
+     SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1);
+ }
+ DEFINE_SPAPR_MACHINE(2_1, "2.1", false);
++#endif
++
++/*
++ * pseries-rhel7.4.0alt
++ */
++static void spapr_machine_rhel740alt_instance_options(MachineState *machine)
++{
++}
++
++static void spapr_machine_rhel740alt_class_options(MachineClass *mc)
++{
++    /* Defaults for the latest behaviour inherited from the base class */
++}
++
++DEFINE_SPAPR_MACHINE(rhel740alt, "rhel7.4.0alt", true);
++
++
++/*
++ * pseries-rhel7.4.0
++ */
++
++static void spapr_machine_rhel740_instance_options(MachineState *machine)
++{
++    spapr_machine_rhel740alt_instance_options(machine);
++}
++
++static void spapr_machine_rhel740_class_options(MachineClass *mc)
++{
++    spapr_machine_rhel740alt_class_options(mc);
++}
++
++DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false);
++
++/*
++ * pseries-rhel7.3.0
++ * like SPAPR_COMPAT_2_6/_2_7/_2_8 but "ddw" has been backported to RHEL7_3
++ */
++#define SPAPR_COMPAT_RHEL7_3 \
++    HW_COMPAT_RHEL7_3                               \
++    {                                               \
++        .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,     \
++        .property = "mem_win_size",                 \
++        .value    = stringify(SPAPR_PCI_2_7_MMIO_WIN_SIZE),\
++    },                                              \
++    {                                               \
++        .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,     \
++        .property = "mem64_win_size",               \
++        .value    = "0",                            \
++    },                                              \
++    {                                               \
++        .driver = TYPE_POWERPC_CPU,                 \
++        .property = "pre-2.8-migration",            \
++        .value    = "on",                           \
++    },                                              \
++    {                                               \
++        .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,       \
++        .property = "pre-2.8-migration",            \
++        .value    = "on",                           \
++    },                                              \
++    {                                               \
++        .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,     \
++        .property = "pcie-extended-configuration-space",\
++        .value    = "off",                          \
++    },
++
++static void spapr_machine_rhel730_instance_options(MachineState *machine)
++{
++    sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
++
++    spapr_machine_rhel740_instance_options(machine);
++    spapr->use_hotplug_event_source = false;
++}
++
++static void spapr_machine_rhel730_class_options(MachineClass *mc)
++{
++    sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
++
++    spapr_machine_rhel740_class_options(mc);
++    smc->tcg_default_cpu = "POWER7";
++    SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_3);
++    smc->phb_placement = phb_placement_2_7;
++}
++
++DEFINE_SPAPR_MACHINE(rhel730, "rhel7.3.0", false);
++
++/*
++ * pseries-rhel7.2.0
++ */
++/* Should be like SPAPR_COMPAT_2_5 + 2_4 + 2_3, but "dynamic-reconfiguration"
++ * has been backported to RHEL7_2 so we don't need it here.
++ */
++
++#define SPAPR_COMPAT_RHEL7_2 \
++    HW_COMPAT_RHEL7_2 \
++    { \
++        .driver   = "spapr-vlan", \
++        .property = "use-rx-buffer-pools", \
++        .value    = "off", \
++    },{ \
++        .driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,\
++        .property = "ddw",\
++        .value    = stringify(off),\
++    },
++
++
++static void spapr_machine_rhel720_instance_options(MachineState *machine)
++{
++    spapr_machine_rhel730_instance_options(machine);
++}
++
++static void spapr_machine_rhel720_class_options(MachineClass *mc)
++{
++    sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
++
++    spapr_machine_rhel730_class_options(mc);
++    smc->use_ohci_by_default = true;
++    mc->has_hotpluggable_cpus = NULL;
++    SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_2);
++}
++
++DEFINE_SPAPR_MACHINE(rhel720, "rhel7.2.0", false);
+ 
+ static void spapr_machine_register_types(void)
+ {
+diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
+index 1a5437a..cd9cdfa 100644
+--- a/hw/smbios/smbios.c
++++ b/hw/smbios/smbios.c
+@@ -743,6 +743,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
+     SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
+     SMBIOS_SET_DEFAULT(type1.product, product);
+     SMBIOS_SET_DEFAULT(type1.version, version);
++    SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux");
+     SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
+     SMBIOS_SET_DEFAULT(type2.product, product);
+     SMBIOS_SET_DEFAULT(type2.version, version);
+diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
+index 976d520..339f336 100644
+--- a/hw/timer/i8254_common.c
++++ b/hw/timer/i8254_common.c
+@@ -267,7 +267,7 @@ static const VMStateDescription vmstate_pit_common = {
+     .pre_save = pit_dispatch_pre_save,
+     .post_load = pit_dispatch_post_load,
+     .fields = (VMStateField[]) {
+-        VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
++        VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */
+         VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
+                              vmstate_pit_channel, PITChannelState),
+         VMSTATE_INT64(channels[0].next_transition_time,
+diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
+index 82843ed..f2ed447 100644
+--- a/hw/timer/mc146818rtc.c
++++ b/hw/timer/mc146818rtc.c
+@@ -32,6 +32,7 @@
+ #include "qapi/visitor.h"
+ #include "qapi-event.h"
+ #include "qmp-commands.h"
++#include "migration/migration.h"
+ 
+ #ifdef TARGET_I386
+ #include "hw/i386/apic.h"
+@@ -835,6 +836,11 @@ static int rtc_post_load(void *opaque, int version_id)
+ static bool rtc_irq_reinject_on_ack_count_needed(void *opaque)
+ {
+     RTCState *s = (RTCState *)opaque;
++
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return s->irq_reinject_on_ack_count != 0;
+ }
+ 
+diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
+index e3562a4..465ed42 100644
+--- a/hw/usb/hcd-uhci.c
++++ b/hw/usb/hcd-uhci.c
+@@ -152,6 +152,8 @@ typedef struct UHCI_QH {
+     uint32_t el_link;
+ } UHCI_QH;
+ 
++bool ich9_uhci123_irqpin_override;
++
+ static void uhci_async_cancel(UHCIAsync *async);
+ static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td);
+ static void uhci_resume(void *opaque);
+@@ -1214,12 +1216,23 @@ static void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
+     UHCIState *s = UHCI(dev);
+     uint8_t *pci_conf = s->dev.config;
+     int i;
++    int irq_pin;
+ 
+     pci_conf[PCI_CLASS_PROG] = 0x00;
+     /* TODO: reset value should be 0. */
+     pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
+ 
+-    pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
++    if (ich9_uhci123_irqpin_override &&
++        u->info.vendor_id == PCI_VENDOR_ID_INTEL &&
++        (u->info.device_id == PCI_DEVICE_ID_INTEL_82801I_UHCI1 ||
++         u->info.device_id == PCI_DEVICE_ID_INTEL_82801I_UHCI2 ||
++         u->info.device_id == PCI_DEVICE_ID_INTEL_82801I_UHCI3)) {
++        fprintf(stderr, "RHEL-6 compat: %s: irq_pin = 3\n", u->info.name);
++        irq_pin = 3;
++    } else {
++        irq_pin = u->info.irq_pin;
++    }
++    pci_config_set_interrupt_pin(pci_conf, irq_pin + 1);
+ 
+     if (s->masterbus) {
+         USBPort *ports[NB_PORTS];
+diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
+index 204ea69..10848db 100644
+--- a/hw/usb/hcd-xhci.c
++++ b/hw/usb/hcd-xhci.c
+@@ -3555,9 +3555,25 @@ static const VMStateDescription vmstate_xhci_slot = {
+     }
+ };
+ 
++static void xhci_event_pre_save(void *opaque)
++{
++    XHCIEvent *s = opaque;
++
++    s->cve_2014_5263_a = ((uint8_t *)&s->type)[0];
++    s->cve_2014_5263_b = ((uint8_t *)&s->type)[1];
++}
++
++bool migrate_cve_2014_5263_xhci_fields;
++
++static bool xhci_event_cve_2014_5263(void *opaque, int version_id)
++{
++    return migrate_cve_2014_5263_xhci_fields;
++}
++
+ static const VMStateDescription vmstate_xhci_event = {
+     .name = "xhci-event",
+     .version_id = 1,
++    .pre_save = xhci_event_pre_save,
+     .fields = (VMStateField[]) {
+         VMSTATE_UINT32(type,   XHCIEvent),
+         VMSTATE_UINT32(ccode,  XHCIEvent),
+@@ -3566,6 +3582,8 @@ static const VMStateDescription vmstate_xhci_event = {
+         VMSTATE_UINT32(flags,  XHCIEvent),
+         VMSTATE_UINT8(slotid,  XHCIEvent),
+         VMSTATE_UINT8(epid,    XHCIEvent),
++        VMSTATE_UINT8_TEST(cve_2014_5263_a, XHCIEvent, xhci_event_cve_2014_5263),
++        VMSTATE_UINT8_TEST(cve_2014_5263_b, XHCIEvent, xhci_event_cve_2014_5263),
+         VMSTATE_END_OF_LIST()
+     }
+ };
+diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
+index fc36a4c..89d4cf7 100644
+--- a/hw/usb/hcd-xhci.h
++++ b/hw/usb/hcd-xhci.h
+@@ -153,6 +153,8 @@ typedef struct XHCIEvent {
+     uint32_t flags;
+     uint8_t slotid;
+     uint8_t epid;
++    uint8_t cve_2014_5263_a;
++    uint8_t cve_2014_5263_b;
+ } XHCIEvent;
+ 
+ typedef struct XHCIInterrupter {
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index 8b0d6b6..eccf809 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -2394,7 +2394,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
+     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+     VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);
+ 
+-    k->romfile = "efi-virtio.rom";
++    k->romfile = "pxe-virtio.rom";
+     k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+     k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
+     k->revision = VIRTIO_PCI_ABI_VERSION;
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 464947f..e7a2bc2 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -24,6 +24,7 @@
+ #include "hw/virtio/virtio-access.h"
+ #include "sysemu/dma.h"
+ 
++#include "standard-headers/linux/virtio_net.h"
+ /*
+  * The alignment to use between consumer and producer parts of vring.
+  * x86 pagesize again. This is the default, used by transports like PCI
+@@ -1984,7 +1985,24 @@ const VMStateInfo  virtio_vmstate_info = {
+ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val)
+ {
+     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+-    bool bad = (val & ~(vdev->host_features)) != 0;
++    bool bad;
++    uint64_t ctrl_guest_mask = 1ull << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS;
++
++    if (vdev->rhel6_ctrl_guest_workaround && (val & ctrl_guest_mask) &&
++          !(vdev->host_features & ctrl_guest_mask)) {
++        /*
++         * This works around a mistake in the definition of the rhel6.[56].0
++         * machinetypes, ctrl-guest-offload was not set in qemu-kvm-rhev for
++         * those machine types, but is set on the rhel6 qemu-kvm-rhev build.
++         * If an incoming rhel6 guest uses it then we need to allow it.
++         * Note: There's a small race where a guest read the flag but didn't
++         * declare it's useage yet.
++         */
++        fprintf(stderr, "RHEL6 ctrl_guest_offload workaround\n");
++        vdev->host_features |= ctrl_guest_mask;
++    }
++
++    bad = (val & ~(vdev->host_features)) != 0;
+ 
+     val &= vdev->host_features;
+     if (k->set_features) {
+@@ -2548,6 +2566,8 @@ static void virtio_device_instance_finalize(Object *obj)
+ 
+ static Property virtio_properties[] = {
+     DEFINE_VIRTIO_COMMON_FEATURES(VirtIODevice, host_features),
++    DEFINE_PROP_BOOL("__com.redhat_rhel6_ctrl_guest_workaround", VirtIODevice,
++                     rhel6_ctrl_guest_workaround, false),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
+index 33b0ff3..a1f533d 100644
+--- a/include/hw/arm/virt.h
++++ b/include/hw/arm/virt.h
+@@ -108,6 +108,7 @@ typedef struct {
+     int psci_conduit;
+ } VirtMachineState;
+ 
++#if 0 /* disabled for Red Hat Enterprise Linux */
+ #define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
+ #define VIRT_MACHINE(obj) \
+     OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
+@@ -116,6 +117,27 @@ typedef struct {
+ #define VIRT_MACHINE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
+ 
++#else
++#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel")
++#define VIRT_MACHINE(obj) \
++    OBJECT_CHECK(VirtMachineState, (obj), TYPE_RHEL_MACHINE)
++#define VIRT_MACHINE_GET_CLASS(obj) \
++    OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_RHEL_MACHINE)
++#define VIRT_MACHINE_CLASS(klass) \
++    OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_RHEL_MACHINE)
++#endif
++
++/* This macro is for changes to properties that are RHEL specific,
++ * different to the current upstream and to be applied to the latest
++ * machine type.
++ */
++#define ARM_RHEL_COMPAT \
++    {\
++        .driver   = "virtio-net-pci",\
++        .property = "romfile",\
++        .value    = "",\
++    },
++
+ void virt_acpi_setup(VirtMachineState *vms);
+ 
+ #endif /* QEMU_ARM_VIRT_H */
+diff --git a/include/hw/compat.h b/include/hw/compat.h
+index 08f3600..bb138cd 100644
+--- a/include/hw/compat.h
++++ b/include/hw/compat.h
+@@ -227,6 +227,186 @@
+         .driver   = "virtio-pci",\
+         .property = "virtio-pci-bus-master-bug-migration",\
+         .value    = "on",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-net-device",\
++        .property = "x-mtu-bypass-backend",\
++        .value    = "off",\
++    },
++
++/* Mostly like HW_COMPAT_2_1 but:
++ *    we don't need virtio-scsi-pci since 7.0 already had that on
++ *
++ * RH: Note, qemu-extended-regs should have been enabled in the 7.1 
++ * machine type, but was accidentally turned off in 7.2 onwards.
++ *
++ */
++#define HW_COMPAT_RHEL7_1 \
++        { /* COMPAT_RHEL7.1 */ \
++            .driver   = "intel-hda-generic",\
++            .property = "old_msi_addr",\
++            .value    = "on",\
++        },{\
++            .driver   = "VGA",\
++            .property = "qemu-extended-regs",\
++            .value    = "off",\
++        },{\
++            .driver   = "secondary-vga",\
++            .property = "qemu-extended-regs",\
++            .value    = "off",\
++        },{\
++            .driver   = "usb-mouse",\
++            .property = "usb_version",\
++            .value    = stringify(1),\
++        },{\
++            .driver   = "usb-kbd",\
++            .property = "usb_version",\
++            .value    = stringify(1),\
++        },{\
++            .driver   = "virtio-pci",\
++            .property = "virtio-pci-bus-master-bug-migration",\
++            .value    = "on",\
++        },{\
++            .driver   = "virtio-blk-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-balloon-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-serial-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-9p-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-rng-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_1 - introduced with 2.10.0 */ \
++            .driver   = "migration",\
++            .property = "send-configuration",\
++            .value    = "off",\
++        },
++
++/* Mostly like HW_COMPAT_2_4 + 2_3 but:
++ *  we don't need "any_layout" as it has been backported to 7.2
++ */
++
++#define HW_COMPAT_RHEL7_2 \
++        {\
++            .driver   = "virtio-blk-device",\
++            .property = "scsi",\
++            .value    = "true",\
++        },{\
++            .driver   = "e1000-82540em",\
++            .property = "extra_mac_registers",\
++            .value    = "off",\
++        },{\
++            .driver   = "virtio-pci",\
++            .property = "x-disable-pcie",\
++            .value    = "on",\
++        },{\
++            .driver   = "virtio-pci",\
++            .property = "migrate-extra",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = "fw_cfg_mem",\
++            .property = "dma_enabled",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = "fw_cfg_io",\
++            .property = "dma_enabled",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = "isa-fdc",\
++            .property = "fallback",\
++            .value    = "144",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = "virtio-pci",\
++            .property = "disable-modern",\
++            .value    = "on",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = "virtio-pci",\
++            .property = "disable-legacy",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = TYPE_PCI_DEVICE,\
++            .property = "x-pcie-lnksta-dllla",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 */ \
++            .driver   = "virtio-pci",\
++            .property = "page-per-vq",\
++            .value    = "on",\
++        },{ /* HW_COMPAT_RHEL7_2 from HW_COMPAT_2_4 added in 2.9 */ \
++            .driver   = "vmgenid",\
++            .property = "x-write-pointer-available",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 - introduced with 2.10.0 */ \
++            .driver   = "migration",\
++            .property = "send-section-footer",\
++            .value    = "off",\
++        },{ /* HW_COMPAT_RHEL7_2 - introduced with 2.10.0 */ \
++            .driver   = "migration",\
++            .property = "store-global-state",\
++            .value    = "off",\
++        },
++
++/* Mostly like HW_COMPAT_2_6 + HW_COMPAT_2_7 + HW_COMPAT_2_8 except
++ * disable-modern, disable-legacy, page-per-vq have already been
++ * backported to RHEL7.3
++ */
++#define HW_COMPAT_RHEL7_3 \
++    { /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-mmio",\
++        .property = "format_transport_address",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-serial-device",\
++        .property = "emergency-write",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "ioapic",\
++        .property = "version",\
++        .value    = "0x11",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "intel-iommu",\
++        .property = "x-buggy-eim",\
++        .value    = "true",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-pci",\
++        .property = "x-ignore-backend-features",\
++        .value    = "on",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "fw_cfg_mem",\
++        .property = "x-file-slots",\
++        .value    = stringify(0x10),\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "fw_cfg_io",\
++        .property = "x-file-slots",\
++        .value    = stringify(0x10),\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "pflash_cfi01",\
++        .property = "old-multiple-chip-handling",\
++        .value    = "on",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = TYPE_PCI_DEVICE,\
++        .property = "x-pcie-extcap-init",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-pci",\
++        .property = "x-pcie-deverr-init",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-pci",\
++        .property = "x-pcie-lnkctl-init",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-pci",\
++        .property = "x-pcie-pm-init",\
++        .value    = "off",\
+     },
+ 
+ #endif /* HW_COMPAT_H */
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index d80859b..b808a9b 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -987,4 +987,446 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
+     type_init(pc_machine_init_##suffix)
+ 
+ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
++
++/* See include/hw/compat.h for shared compatibility lists */
++
++/* This macro is for changes to properties that are RHEL specific,
++ * different to the current upstream and to be applied to the latest
++ * machine type.
++ */
++#define PC_RHEL_COMPAT \
++        { /* PC_RHEL_COMPAT */ \
++            .driver = TYPE_X86_CPU,\
++            .property = "host-phys-bits",\
++            .value = "on",\
++        },
++
++#define PC_RHEL7_3_COMPAT \
++        HW_COMPAT_RHEL7_3 \
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \
++             .driver   = "kvmclock",\
++             .property = "x-mach-use-reliable-get-clock",\
++             .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \
++            .driver   = TYPE_X86_CPU,\
++            .property = "l3-cache",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \
++            .driver   = TYPE_X86_CPU,\
++            .property = "full-cpuid-auto-level",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \
++            .driver   = "Opteron_G3" "-" TYPE_X86_CPU,\
++            .property = "family",\
++            .value    = "15",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \
++            .driver   = "Opteron_G3" "-" TYPE_X86_CPU,\
++            .property = "model",\
++            .value    = "6",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \
++            .driver   = "Opteron_G3" "-" TYPE_X86_CPU,\
++            .property = "stepping",\
++            .value    = "1",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \
++            .driver   = "isa-pcspk",\
++            .property = "migrate",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_6 */ \
++            .driver   = TYPE_X86_CPU,\
++            .property = "cpuid-0xb",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \
++            .driver   = "ICH9-LPC",\
++            .property = "x-smi-broadcast",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \
++            .driver   = TYPE_X86_CPU,\
++            .property = "vmware-cpuid-freq",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \
++            .driver   = "Haswell-" TYPE_X86_CPU,\
++            .property = "stepping",\
++            .value    = "1",\
++        },\
++        { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_3 added in 2.9 */ \
++            .driver = TYPE_X86_CPU,\
++            .property = "kvm-no-smi-migration",\
++            .value    = "on",\
++        },
++
++#define PC_RHEL7_2_COMPAT \
++        HW_COMPAT_RHEL7_2 \
++	{\
++		.driver = "phenom" "-" TYPE_X86_CPU,\
++		.property = "rdtscp",\
++		.value = "off",\
++	},\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "qemu64" "-" TYPE_X86_CPU,\
++            .property = "sse4a",\
++            .value    = "on",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "qemu64" "-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "on",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "Haswell-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "Haswell-noTSX-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "Broadwell-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "Broadwell-noTSX-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "host" "-" TYPE_X86_CPU,\
++            .property = "host-cache-info",\
++            .value    = "on",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = TYPE_X86_CPU,\
++            .property = "check",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "qemu32" "-" TYPE_X86_CPU,\
++            .property = "popcnt",\
++            .value    = "on",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = TYPE_X86_CPU,\
++            .property = "arat",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "usb-redir",\
++            .property = "streams",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver = TYPE_X86_CPU,\
++            .property = "fill-mtrr-mask",\
++            .value = "off",\
++        },\
++        { /* PC_RHEL7_2_COMPAT */ \
++            .driver   = "apic-common",\
++            .property = "legacy-instance-id",\
++            .value    = "on",\
++        },
++
++
++
++#define PC_RHEL7_1_COMPAT \
++        HW_COMPAT_RHEL7_1 \
++	{\
++		.driver = "kvm64" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "kvm32" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Conroe" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Penryn" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Nehalem" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Westmere" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "SandyBridge" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Haswell" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Broadwell" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Opteron_G1" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Opteron_G2" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Opteron_G3" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Opteron_G4" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Opteron_G5" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Haswell" "-" TYPE_X86_CPU,\
++		.property = "f16c",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Haswell" "-" TYPE_X86_CPU,\
++		.property = "rdrand",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Broadwell" "-" TYPE_X86_CPU,\
++		.property = "f16c",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "Broadwell" "-" TYPE_X86_CPU,\
++		.property = "rdrand",\
++		.value = "off",\
++	},\
++	{\
++		.driver = "coreduo" "-" TYPE_X86_CPU,\
++		.property = "vmx",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "core2duo" "-" TYPE_X86_CPU,\
++		.property = "vmx",\
++		.value = "on",\
++	},\
++        { /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "qemu64" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(4),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "kvm64" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(5),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "pentium3" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(2),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "n270" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(5),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Conroe" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(4),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Penryn" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(4),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Nehalem" "-" TYPE_X86_CPU,\
++            .property = "min-level",\
++            .value    = stringify(4),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "n270" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Penryn" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Conroe" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Nehalem" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Westmere" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "SandyBridge" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "IvyBridge" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Haswell" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Haswell-noTSX" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Broadwell" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },{ /* PC_RHEL7_1_COMPAT */ \
++            .driver   = "Broadwell-noTSX" "-" TYPE_X86_CPU,\
++            .property = "min-xlevel",\
++            .value    = stringify(0x8000000a),\
++        },
++
++/*
++ * The PC_RHEL_*_COMPAT serve the same purpose for RHEL-7 machine
++ * types as the PC_COMPAT_* do for upstream types.
++ * PC_RHEL_7_*_COMPAT apply both to i440fx and q35 types.
++ * PC_RHEL6_*_COMPAT apply to i440fx types only, and therefore live
++ * in pc_piix.c.
++ */
++
++/*
++ * RHEL-7 is based on QEMU 1.5.3, so this needs the PC_COMPAT_*
++ * between our base and 1.5, less stuff backported to RHEL-7.0
++ * (usb-device.msos-desc), less stuff for devices we changed
++ * (qemu64-x86_64-cpu) or don't support (hpet, pci-serial-2x,
++ * pci-serial-4x) in 7.0.
++ */
++#define PC_RHEL7_0_COMPAT \
++        {\
++            .driver   = "virtio-scsi-pci",\
++            .property = "any_layout",\
++            .value    = "off",\
++        },{\
++            .driver   = "PIIX4_PM",\
++            .property = "memory-hotplug-support",\
++            .value    = "off",\
++        },{\
++            .driver   = "apic",\
++            .property = "version",\
++            .value    = stringify(0x11),\
++        },{\
++            .driver   = "nec-usb-xhci",\
++            .property = "superspeed-ports-first",\
++            .value    = "off",\
++        },{\
++            .driver   = "nec-usb-xhci",\
++            .property = "force-pcie-endcap",\
++            .value    = "on",\
++        },{\
++            .driver   = "pci-serial",\
++            .property = "prog_if",\
++            .value    = stringify(0),\
++        },{\
++            .driver   = "virtio-net-pci",\
++            .property = "guest_announce",\
++            .value    = "off",\
++        },{\
++            .driver   = "ICH9-LPC",\
++            .property = "memory-hotplug-support",\
++            .value    = "off",\
++        },{\
++            .driver   = "xio3130-downstream",\
++            .property = COMPAT_PROP_PCP,\
++            .value    = "off",\
++        },{\
++            .driver   = "ioh3420",\
++            .property = COMPAT_PROP_PCP,\
++            .value    = "off",\
++        },{\
++            .driver   = "PIIX4_PM",\
++            .property = "acpi-pci-hotplug-with-bridge-support",\
++            .value    = "off",\
++        },{\
++            .driver   = "e1000",\
++            .property = "mitigation",\
++            .value    = "off",\
++        },{ \
++            .driver   = "virtio-net-pci", \
++            .property = "ctrl_guest_offloads", \
++            .value    = "off", \
++        },\
++	{\
++		.driver = "Conroe" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Penryn" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Nehalem" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Westmere" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Opteron_G1" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Opteron_G2" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Opteron_G3" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Opteron_G4" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
++	{\
++		.driver = "Opteron_G5" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},
+ #endif
+diff --git a/include/hw/usb.h b/include/hw/usb.h
+index eb28655..e2d3d77 100644
+--- a/include/hw/usb.h
++++ b/include/hw/usb.h
+@@ -608,4 +608,11 @@ int usb_get_quirks(uint16_t vendor_id, uint16_t product_id,
+                    uint8_t interface_class, uint8_t interface_subclass,
+                    uint8_t interface_protocol);
+ 
++
++/* hcd-uhci.c -- RHEL-6 machine type compatibility */
++extern bool ich9_uhci123_irqpin_override;
++
++/* hcd-xhci.c -- rhel7.0.0 machine type compatibility */
++extern bool migrate_cve_2014_5263_xhci_fields;
++
+ #endif
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index 80c45c3..5faa359 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -95,6 +95,7 @@ struct VirtIODevice
+     uint8_t device_endian;
+     bool use_guest_notifier_mask;
+     AddressSpace *dma_as;
++    bool rhel6_ctrl_guest_workaround;
+     QLIST_HEAD(, VirtQueue) *vector_queues;
+ };
+ 
+diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
+index b213696..9caaacf 100644
+--- a/include/sysemu/sysemu.h
++++ b/include/sysemu/sysemu.h
+@@ -92,6 +92,8 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);
+ void qemu_remove_machine_init_done_notifier(Notifier *notify);
+ 
+ void qemu_announce_self(void);
++extern bool shadow_bios_after_incoming;
++void shadow_bios(void);
+ 
+ extern int autostart;
+ 
+diff --git a/migration/migration.c b/migration/migration.c
+index c3fe0ed..c7b4d3d 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -96,6 +96,8 @@ enum mig_rp_message_type {
+     MIG_RP_MSG_MAX
+ };
+ 
++bool migrate_pre_2_2;
++
+ /* When we add fault tolerance, we could have several
+    migrations at once.  For now we don't need to add
+    dynamic creation of migration */
+diff --git a/migration/migration.h b/migration/migration.h
+index 148c9fa..8771ab0 100644
+--- a/migration/migration.h
++++ b/migration/migration.h
+@@ -193,4 +193,10 @@ void migrate_send_rp_pong(MigrationIncomingState *mis,
+ void migrate_send_rp_req_pages(MigrationIncomingState *mis, const char* rbname,
+                               ram_addr_t start, size_t len);
+ 
++/*
++ * Disables a load of subsections that were added in 2.2/rh7.2 for backwards
++ * migration compatibility.
++ */
++extern bool migrate_pre_2_2;
++
+ #endif
+diff --git a/migration/savevm.c b/migration/savevm.c
+index fdd15fa..5eb3504 100644
+--- a/migration/savevm.c
++++ b/migration/savevm.c
+@@ -42,6 +42,7 @@
+ #include "postcopy-ram.h"
+ #include "qapi/qmp/qerror.h"
+ #include "qemu/error-report.h"
++#include "qemu/rcu_queue.h"
+ #include "sysemu/cpus.h"
+ #include "exec/memory.h"
+ #include "exec/target_page.h"
+@@ -80,6 +81,7 @@ enum qemu_vm_cmd {
+     MIG_CMD_PACKAGED,          /* Send a wrapped stream within this stream */
+     MIG_CMD_MAX
+ };
++bool shadow_bios_after_incoming;
+ 
+ #define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24)
+ static struct mig_cmd_args {
+@@ -2079,6 +2081,13 @@ int qemu_loadvm_state(QEMUFile *f)
+     }
+ 
+     qemu_loadvm_state_cleanup();
++    /* Supplement SeaBIOS's shadowing now, because it was useless when the
++     * incoming VM started on the RHEL-6 emulator.
++     */
++    if (shadow_bios_after_incoming) {
++        shadow_bios();
++    }
++
+     cpu_synchronize_all_post_init();
+ 
+     return ret;
+diff --git a/numa.c b/numa.c
+index e32af04..be78167 100644
+--- a/numa.c
++++ b/numa.c
+@@ -566,6 +566,19 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+         return;
+     }
+ 
++    /* The shadow_bios_after_incoming hack at savevm.c:shadow_bios() is not
++     * able to handle the multiple memory blocks added when using NUMA
++     * memdevs. We can disallow -numa memdev= when using rhel6.* machine-types
++     * because RHEL-6 didn't support the NUMA memdev option.
++     */
++    if (shadow_bios_after_incoming) {
++        MachineClass *mc;
++        mc = MACHINE_GET_CLASS(current_machine);
++        error_report("-numa memdev is not supported by machine %s",
++                     mc->name);
++        exit(1);
++    }
++
+     memory_region_init(mr, owner, name, ram_size);
+     for (i = 0; i < MAX_NODES; i++) {
+         uint64_t size = numa_info[i].node_mem;
+diff --git a/qdev-monitor.c b/qdev-monitor.c
+index 8fd6df9..b05ae6d 100644
+--- a/qdev-monitor.c
++++ b/qdev-monitor.c
+@@ -44,7 +44,6 @@ typedef struct QDevAlias
+ 
+ /* Please keep this table sorted by typename. */
+ static const QDevAlias qdev_alias_table[] = {
+-    { "e1000", "e1000-82540em" },
+     { "ich9-ahci", "ahci" },
+     { "kvm-pci-assign", "pci-assign" },
+     { "lsi53c895a", "lsi" },
+diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py
+index bcef7ee..ffb13d1 100755
+--- a/scripts/vmstate-static-checker.py
++++ b/scripts/vmstate-static-checker.py
+@@ -104,7 +104,6 @@ def get_changed_sec_name(sec):
+     # Section names can change -- see commit 292b1634 for an example.
+     changes = {
+         "ICH9 LPC": "ICH9-LPC",
+-        "e1000-82540em": "e1000",
+     }
+ 
+     for item in changes:
+diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
+index e69c217..b24da3b 100644
+--- a/stubs/Makefile.objs
++++ b/stubs/Makefile.objs
+@@ -40,3 +40,4 @@ stub-obj-y += pc_madt_cpu_entry.o
+ stub-obj-y += vmgenid.o
+ stub-obj-y += xen-common.o
+ stub-obj-y += xen-hvm.o
++stub-obj-y += shadow-bios.o
+diff --git a/stubs/shadow-bios.c b/stubs/shadow-bios.c
+new file mode 100644
+index 0000000..c77cd7a
+--- /dev/null
++++ b/stubs/shadow-bios.c
+@@ -0,0 +1,7 @@
++#include "qemu/osdep.h"
++#include "sysemu/sysemu.h"
++
++void shadow_bios(void)
++{
++  abort();
++}
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index ddc45ab..7f52680 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -754,20 +754,29 @@ struct X86CPUDefinition {
+ 
+ static X86CPUDefinition builtin_x86_defs[] = {
+     {
++        /* qemu64 is the default CPU model for all *-rhel7.* machine-types.
++         * The default on RHEL-6 was cpu64-rhel6.
++         * libvirt assumes that qemu64 is the default for _all_ machine-types,
++         * so we should try to keep qemu64 and cpu64-rhel6 as similar as
++         * possible.
++         */
+         .name = "qemu64",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_AMD,
+         .family = 6,
+-        .model = 6,
++        .model = 13,
+         .stepping = 3,
+-        .features[FEAT_1_EDX] =
+-            PPRO_FEATURES |
+-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+-            CPUID_PSE36,
+-        .features[FEAT_1_ECX] =
+-            CPUID_EXT_SSE3 | CPUID_EXT_CX16,
+-        .features[FEAT_8000_0001_EDX] =
+-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
++        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
++            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV |
++            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
++            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
++            CPUID_PSE | CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR |
++            CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PAT | CPUID_EXT2_CMOV |
++            CPUID_EXT2_PGE | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
++            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC |
++            CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
+         .xlevel = 0x8000000A,
+@@ -993,6 +1002,29 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
+     },
+     {
++        .name = "cpu64-rhel6",
++        .level = 4,
++        .vendor = CPUID_VENDOR_AMD,
++        .family = 6,
++        .model = 13,
++        .stepping = 3,
++        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
++             CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV |
++             CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
++             CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
++             CPUID_PSE | CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR |
++             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PAT | CPUID_EXT2_CMOV |
++             CPUID_EXT2_PGE | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
++             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC |
++             CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
++        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
++             CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
++        .xlevel = 0x8000000A,
++        .model_id = "QEMU Virtual CPU version (cpu64-rhel6)",
++    },
++    {
+         .name = "Conroe",
+         .level = 10,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1542,6 +1574,7 @@ static PropValue kvm_default_props[] = {
+     { "acpi", "off" },
+     { "monitor", "off" },
+     { "svm", "off" },
++    { "kvm-pv-unhalt", "on" },
+     { NULL, NULL },
+ };
+ 
+diff --git a/target/i386/machine.c b/target/i386/machine.c
+index eab3372..6156626 100644
+--- a/target/i386/machine.c
++++ b/target/i386/machine.c
+@@ -818,6 +818,26 @@ static const VMStateDescription vmstate_mcg_ext_ctl = {
+     }
+ };
+ 
++static bool vmstate_xsave_needed(void *opaque)
++{
++    /* The xsave state is already on the main "cpu" section */
++    return false;
++}
++
++static const VMStateDescription vmstate_xsave ={
++    .name = "cpu/xsave",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .minimum_version_id_old = 1,
++    .needed = vmstate_xsave_needed,
++    .fields      = (VMStateField []) {
++    VMSTATE_UINT64_V(env.xcr0, X86CPU, 1),
++    VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 1),
++    VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, CPU_NB_REGS, 1),
++    VMSTATE_END_OF_LIST()
++    }
++};
++
+ VMStateDescription vmstate_x86_cpu = {
+     .name = "cpu",
+     .version_id = 12,
+@@ -937,6 +957,7 @@ VMStateDescription vmstate_x86_cpu = {
+         &vmstate_pkru,
+ #endif
+         &vmstate_mcg_ext_ctl,
++        &vmstate_xsave,
+         NULL
+     }
+ };
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0004-Enable-disable-devices-for-RHEL-7.patch b/SOURCES/0004-Enable-disable-devices-for-RHEL-7.patch
new file mode 100644
index 0000000..94953da
--- /dev/null
+++ b/SOURCES/0004-Enable-disable-devices-for-RHEL-7.patch
@@ -0,0 +1,1912 @@
+From 0e72e616b2d80e47c0eb6c5976276e9f8d920e92 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Mon, 11 Jan 2016 11:53:33 +0100
+Subject: Enable/disable devices for RHEL 7
+
+This commit adds all changes related to changes in supported devices
+up to qemu-kvm-rhev-2.1.2-16.el7.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Rebase notes (2.10.0):
+- replace cannot_instantiate_with_device_add_yet with user_creatable (upstream e90f2a)
+- Comment out default configs instead of removing the options
+- Reenable test_unaligned_write_same
+- Remove default-configs changes for 32bit architectures
+- Removed unnecessary usage of user_creatable
+- Documented arm cpu changes
+
+Rebase notes (2.9.0):
+- enabled CONFIG_ARM_V7M for aarch64
+- need to fix cpu mask
+- disabled some irrelevant ppc64 tests
+- Adding pxe-e1000e.rom to Inital redhat commit
+- Context changed in vfio_probe_igd_bar4_quirk (rc3)
+- Remove fdc test
+- Enabled null-co driver
+- Disabled megasas and bios-tables test
+- Disabled netfilter tests for ppc64
+- Disabled ivshmem test for ppc64
+- Disabled numa test for aarhc64
+- Add CONFIG_USB_XHCI_NEC option for ppc64
+- Enable vhost-user-scsi for ppc64 and aarch64
+- Disable ipmi_bt, ipmi_local, impi_extern for ppc64
+
+Rebase notes (2.8.0):
+- Removed CONFIG_PIIX_PCI (upstream)
+- Disabled POWERNV
+- Disabled additional occurencies of prom-env-test
+- Disabled additional occurencies of usb-hcd-ohci-test and usb-hcd-uhci-test
+- Disabled unsupported machine types in boot-serieal-test
+- Disabled 2.7 machine type compatibility test in test-x86-cpuid-compat
+- Disabled pnv-xscom-test
+- Disabled RHEl 6 machine types for qom-test (failing acpi setting)
+- Added diffutils BuildRequires and diff usage for make check
+
+Rebase notes (2.6.0):
+- disabled prom-env-test
+
+Rebase notes (2.4.0):
+- fixed types
+- include CONFIG_PLATFORM_BUS for aarch64
+- disable failing virtio-scsi-test
+
+Rebase notes (2.3.0):
+- Added USB=y in 2.3-rc2 (used instead of downstream version fora aarch64)
+
+Merged patches (2.10.0):
+- e9b413e Add PCIe bridge devices for AArch64
+- a522114 s390x/virtio-ccw: Disable crypto device in downstream RHEL builds
+- 15dbf98 Disable unimplemented device
+- 5c0ea49 Disable serial-isa for ppc64
+- 728e7e8 Disable rs6000-mc device
+- 2a11896 ppc64le: Remove isabus-bridge device
+- 5c4df94 Reenable Educational device
+- a936463 aarch64: Enable usb-xhci
+- 984f5cd Enable USB_CONFIG for aarch64
+- f13b783 AArch64: Add pci-testdev
+- 81867af Disable virtio-pci for s390x builds
+- bf5f636 target/ppc: Show POWER9 in -cpu help
+
+Merged patches (2.9.0):
+- 9320fc1 Fix unuseds/Fedora build
+- cb16934 config: Remove EHCI from ppc64 builds
+- 626fe4d Disable qemu,register device
+- 783a0b2 Disable vfio-pci-igd-lpc-bridge device
+- bf7c127 Disable new virtio crypto devices
+- a4d3c4e Disable amd iommu devices
+- 5396ebc Disable loader device
+- 1957779 Disable or-irq device
+- 25ee621 Hide new floppy device
+- 2bd29ed Disable devices for for AArch64 QEMU
+
+Merged patches (2.7.0):
+- e2944a5 RHEL: Disable unsupported PowerPC CPU models
+ - have to add additional "if 0" sections to hw/ppc/spapr_cpu_core.c
+- 81b2836 Remove unsupported VFIO devices from QEMU
+- 1248029 Disable spapr-rng
+- 351e1fb Disable Windows enlightnementas
+- 5760290 Disable mptsas1068 device
+- 0b74460 Disable sd-card
+- 2eaf71c Disable rocker device
+- e0ed699 Disable new ipmi devices
+ - disable ipmi tests in bios-tables-test
+- 30e3bee Disable hyperv-testdev
+- 8a9aadf Disable allwiner_ahci device
+- a41119d Disable igd-passthrough-i440FX
+- e305bb4 Disable vfio-platform device
+- a127042 rhel: Revert unwanted inconsequential changes to ivshmem
+- ce1419c rhel: Disable ivshmem-plain migration, ivshmem-doorbell, ivshmem
+- 3f9349b q35: disable s3/s4 by default
+- 2158ca1 i8257: Set no-user flag
+- b2a3bb9 e1000e: add boot rom
+- have to add pxe-e1000e.rom to source files
+
+Merged patches (2.6.0):
+- ce3206a qemu-iotests: Fix broken test cases
+ - Reduced to disabling test 071 only
+- bb34585 qemu-iotests: Disable 099 (requires blkverify)
+- 81be408 build: reenable local builds to pass --enable-debug (downstream only)
+
+Merged patches (2.4.0):
+- fa4fd10 AArch64: Enable ACPI
+- 1219d52 ivshmem: RHEL-only: remove unsupported code
+- 5f6d954 ivshmem: RHEL-only: explicitly remove dead code
+- b88bbf0 Revert "rhel: Drop "ivshmem" device"
+- 8f0aadf Split serial-isa into its own config option
+- 01bff0f rhel: Disable "info irq" and "info pic" for Power
+- b915077 RHEL: Disable remaining unsupported devices for ppc
+- 64cbdc5 Mark onboard devices as cannot_instantiate_with_device_add_yet
+- 4792566 Disable sdhci device
+- bda8169 Disable Educational device
+- a17a8fb rhel: Revert unwanted cannot_instantiate_with_device_add_yet changes
+- 91c76c5 Remove intel-iommu device
+- ec1615d Disable additional e1000 models
+
+(cherry picked from commit a36a3ad800b282cef9d72e6d8026470035f8f21c)
+---
+ default-configs/aarch64-softmmu.mak |  33 ++++++++---
+ default-configs/pci.mak             |  36 ++++++------
+ default-configs/ppc64-softmmu.mak   | 108 ++++++++++++++++++++----------------
+ default-configs/ppcemb-softmmu.mak  |  13 +++++
+ default-configs/s390x-softmmu.mak   |   2 +-
+ default-configs/sound.mak           |   8 +--
+ default-configs/usb.mak             |  14 ++---
+ default-configs/x86_64-softmmu.mak  |  26 +++++----
+ hw/acpi/ich9.c                      |   4 +-
+ hw/block/fdc.c                      |   1 +
+ hw/block/pflash_cfi01.c             |   1 +
+ hw/char/serial-pci.c                |   4 ++
+ hw/core/Makefile.objs               |   7 ++-
+ hw/display/cirrus_vga.c             |   2 +
+ hw/display/sm501.c                  |   2 +-
+ hw/dma/i8257.c                      |   2 +
+ hw/i386/Makefile.objs               |   3 +-
+ hw/i386/kvm/clock.c                 |   1 +
+ hw/i386/pc.c                        |   3 +-
+ hw/ide/ahci.c                       |   5 ++
+ hw/ide/piix.c                       |   5 +-
+ hw/ide/via.c                        |   2 +
+ hw/input/pckbd.c                    |   2 +
+ hw/isa/isa-bus.c                    |   1 +
+ hw/misc/Makefile.objs               |   2 +-
+ hw/misc/ivshmem.c                   |  11 ++++
+ hw/net/e1000.c                      |   2 +
+ hw/net/e1000e.c                     |   2 +-
+ hw/pci-host/piix.c                  |   4 ++
+ hw/pci-host/q35.c                   |   1 +
+ hw/ppc/Makefile.objs                |   3 +-
+ hw/ppc/spapr.c                      |   3 +-
+ hw/ppc/spapr_cpu_core.c             |   4 +-
+ hw/s390x/virtio-ccw.c               |  10 ++++
+ hw/usb/ccid-card-emulated.c         |   2 +
+ hw/vfio/Makefile.objs               |   3 -
+ hw/vfio/pci-quirks.c                |   5 ++
+ hw/virtio/Makefile.objs             |   5 +-
+ hw/virtio/virtio-mmio.c             |   1 +
+ qemu-options.hx                     |   5 --
+ redhat/build_configure.sh           |   2 +-
+ redhat/qemu-kvm.spec.template       |   5 +-
+ stubs/Makefile.objs                 |   1 +
+ stubs/ide-isa.c                     |  13 +++++
+ target/arm/cpu.c                    |   4 +-
+ target/i386/cpu.c                   |  15 ++---
+ target/ppc/cpu-models.c             |  17 +++++-
+ tests/Makefile.include              |  72 +++++++-----------------
+ tests/bios-tables-test.c            |   4 ++
+ tests/boot-order-test.c             |   7 +++
+ tests/boot-serial-test.c            |   8 +--
+ tests/e1000-test.c                  |   2 +
+ tests/endianness-test.c             |   2 +
+ tests/ivshmem-test.c                |  10 +++-
+ tests/qemu-iotests/051              |  20 +++----
+ tests/qemu-iotests/group            |   4 +-
+ tests/qom-test.c                    |   4 +-
+ tests/test-x86-cpuid-compat.c       |   2 +
+ tests/usb-hcd-xhci-test.c           |   5 +-
+ vl.c                                |   2 +-
+ 60 files changed, 338 insertions(+), 209 deletions(-)
+ create mode 100644 stubs/ide-isa.c
+
+diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
+index abd18c2..5d57303 100644
+--- a/default-configs/aarch64-softmmu.mak
++++ b/default-configs/aarch64-softmmu.mak
+@@ -1,11 +1,30 @@
+ # Default configuration for aarch64-softmmu
+ 
+-# We support all the 32 bit boards so need all their config
+-include arm-softmmu.mak
+-
+-CONFIG_AUX=y
+-CONFIG_DDC=y
+-CONFIG_DPCD=y
+-CONFIG_XLNX_ZYNQMP=y
++# Disabled in Red Hat Enterprise Linux
++# CONFIG_AUX=y
++# CONFIG_DDC=y
++# CONFIG_DPCD=y
++# CONFIG_XLNX_ZYNQMP=y
++CONFIG_PCI=y
++CONFIG_PCI_TESTDEV=y
++CONFIG_VIRTIO_PCI=y
++CONFIG_VIRTIO=y
++CONFIG_STELLARIS=y
++CONFIG_ARM_GIC=y
++CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
++CONFIG_PL011=y
++CONFIG_PL031=y
++CONFIG_PFLASH_CFI01=y
++CONFIG_PCI_GENERIC=y
++CONFIG_ACPI=y
++CONFIG_PLATFORM_BUS=y
++CONFIG_SMBIOS=y
+ CONFIG_PL061=y
+ CONFIG_GPIO_KEY=y
++CONFIG_ARM_V7M=y
++CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
++CONFIG_PCIE_PORT=y
++CONFIG_XIO3130=y
++CONFIG_IOH3420=y
++CONFIG_USB_XHCI=y
++CONFIG_USB=y
+diff --git a/default-configs/pci.mak b/default-configs/pci.mak
+index a758630..9bd8452 100644
+--- a/default-configs/pci.mak
++++ b/default-configs/pci.mak
+@@ -4,43 +4,43 @@ CONFIG_ISA_BUS=y
+ CONFIG_VIRTIO_PCI=y
+ CONFIG_VIRTIO=y
+ CONFIG_USB_UHCI=y
+-CONFIG_USB_OHCI=y
++#CONFIG_USB_OHCI=y
+ CONFIG_USB_EHCI=y
+ CONFIG_USB_XHCI=y
+ CONFIG_USB_XHCI_NEC=y
+-CONFIG_NE2000_PCI=y
+-CONFIG_EEPRO100_PCI=y
+-CONFIG_PCNET_PCI=y
+-CONFIG_PCNET_COMMON=y
++#CONFIG_NE2000_PCI=y
++#CONFIG_EEPRO100_PCI=y
++#CONFIG_PCNET_PCI=y
++#CONFIG_PCNET_COMMON=y
+ CONFIG_AC97=y
+ CONFIG_HDA=y
+-CONFIG_ES1370=y
+-CONFIG_LSI_SCSI_PCI=y
+-CONFIG_VMW_PVSCSI_SCSI_PCI=y
+-CONFIG_MEGASAS_SCSI_PCI=y
+-CONFIG_MPTSAS_SCSI_PCI=y
++#CONFIG_ES1370=y
++#CONFIG_LSI_SCSI_PCI=y
++#CONFIG_VMW_PVSCSI_SCSI_PCI=y
++#CONFIG_MEGASAS_SCSI_PCI=y
++#CONFIG_MPTSAS_SCSI_PCI=y
+ CONFIG_RTL8139_PCI=y
+ CONFIG_E1000_PCI=y
+ CONFIG_E1000E_PCI=y
+-CONFIG_VMXNET3_PCI=y
++#CONFIG_VMXNET3_PCI=y
+ CONFIG_IDE_CORE=y
+ CONFIG_IDE_QDEV=y
+ CONFIG_IDE_PCI=y
+ CONFIG_AHCI=y
+-CONFIG_ESP=y
+-CONFIG_ESP_PCI=y
++#CONFIG_ESP=y
++#CONFIG_ESP_PCI=y
+ CONFIG_SERIAL=y
+ CONFIG_SERIAL_ISA=y
+ CONFIG_SERIAL_PCI=y
+-CONFIG_IPACK=y
++#CONFIG_IPACK=y
+ CONFIG_WDT_IB6300ESB=y
+ CONFIG_PCI_TESTDEV=y
+-CONFIG_NVME_PCI=y
+-CONFIG_SD=y
+-CONFIG_SDHCI=y
++#CONFIG_NVME_PCI=y
++#CONFIG_SD=y
++#CONFIG_SDHCI=y
+ CONFIG_EDU=y
+ CONFIG_VGA=y
+ CONFIG_VGA_PCI=y
+ CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM)
+-CONFIG_ROCKER=y
++#CONFIG_ROCKER=y
+ CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
+index 46c9599..31ef40c 100644
+--- a/default-configs/ppc64-softmmu.mak
++++ b/default-configs/ppc64-softmmu.mak
+@@ -1,64 +1,76 @@
+ # Default configuration for ppc64-softmmu
+ 
+-include pci.mak
++# PCI configuration - cut down from the defaults in pci.mak
++CONFIG_PCI=y
++CONFIG_VIRTIO_PCI=y
++CONFIG_VIRTIO=y
++CONFIG_USB_XHCI=y
++CONFIG_USB_XHCI_NEC=y
++CONFIG_WDT_IB6300ESB=y
++CONFIG_PCI_TESTDEV=y
++CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
++
+ include sound.mak
+ include usb.mak
+ CONFIG_VIRTIO_VGA=y
+-CONFIG_ESCC=y
+-CONFIG_M48T59=y
++#CONFIG_ESCC=y
++#CONFIG_M48T59=y
+ CONFIG_IPMI=y
+-CONFIG_IPMI_LOCAL=y
+-CONFIG_IPMI_EXTERN=y
+-CONFIG_ISA_IPMI_BT=y
++#CONFIG_IPMI_LOCAL=y
++#CONFIG_IPMI_EXTERN=y
++#CONFIG_ISA_IPMI_BT=y
++CONFIG_VGA=y
++CONFIG_VGA_PCI=y
+ CONFIG_SERIAL=y
+-CONFIG_PARALLEL=y
+-CONFIG_I8254=y
+-CONFIG_PCKBD=y
+-CONFIG_FDC=y
+-CONFIG_I8257=y
+-CONFIG_I82374=y
+-CONFIG_OPENPIC=y
+-CONFIG_PREP_PCI=y
+-CONFIG_I82378=y
+-CONFIG_PC87312=y
+-CONFIG_MACIO=y
+-CONFIG_PCSPK=y
+-CONFIG_CUDA=y
+-CONFIG_ADB=y
+-CONFIG_MAC_NVRAM=y
+-CONFIG_MAC_DBDMA=y
+-CONFIG_HEATHROW_PIC=y
+-CONFIG_GRACKLE_PCI=y
+-CONFIG_UNIN_PCI=y
+-CONFIG_DEC_PCI=y
+-CONFIG_PPCE500_PCI=y
+-CONFIG_IDE_ISA=y
+-CONFIG_IDE_CMD646=y
+-CONFIG_IDE_MACIO=y
+-CONFIG_NE2000_ISA=y
+-CONFIG_PFLASH_CFI01=y
+-CONFIG_PFLASH_CFI02=y
+-CONFIG_PTIMER=y
+-CONFIG_I8259=y
+-CONFIG_XILINX=y
+-CONFIG_XILINX_ETHLITE=y
++#CONFIG_PARALLEL=y
++#CONFIG_I8254=y
++#CONFIG_PCKBD=y
++#CONFIG_FDC=y
++#CONFIG_I8257=y
++#CONFIG_I82374=y
++#CONFIG_OPENPIC=y
++#CONFIG_PREP_PCI=y
++#CONFIG_I82378=y
++#CONFIG_PC87312=y
++#CONFIG_MACIO=y
++#CONFIG_PCSPK=y
++#CONFIG_CUDA=y
++#CONFIG_ADB=y
++#CONFIG_MAC_NVRAM=y
++#CONFIG_MAC_DBDMA=y
++#CONFIG_HEATHROW_PIC=y
++#CONFIG_GRACKLE_PCI=y
++#CONFIG_UNIN_PCI=y
++#CONFIG_DEC_PCI=y
++#CONFIG_PPCE500_PCI=y
++#CONFIG_IDE_ISA=y
++#CONFIG_IDE_CMD646=y
++#CONFIG_IDE_MACIO=y
++#CONFIG_NE2000_ISA=y
++#CONFIG_PFLASH_CFI01=y
++#CONFIG_PFLASH_CFI02=y
++#CONFIG_PTIMER=y
++#CONFIG_I8259=y
++#CONFIG_XILINX=y
++#CONFIG_XILINX_ETHLITE=y
+ CONFIG_PSERIES=y
+-CONFIG_POWERNV=y
+-CONFIG_PREP=y
+-CONFIG_MAC=y
+-CONFIG_E500=y
+-CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
+-CONFIG_PLATFORM_BUS=y
+-CONFIG_ETSEC=y
++#CONFIG_POWERNV=y
++#CONFIG_PREP=y
++#CONFIG_MAC=y
++#CONFIG_E500=y
++#CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
++#CONFIG_PLATFORM_BUS=y
++#CONFIG_ETSEC=y
+ CONFIG_LIBDECNUMBER=y
+ CONFIG_SM501=y
++CONFIG_USB_OHCI=y
+ # For pSeries
+ CONFIG_XICS=$(CONFIG_PSERIES)
+ CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
+ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
+ # For PReP
+-CONFIG_SERIAL_ISA=y
+-CONFIG_MC146818RTC=y
+-CONFIG_ISA_TESTDEV=y
++#CONFIG_SERIAL_ISA=y
++#CONFIG_MC146818RTC=y
++#CONFIG_ISA_TESTDEV=y
+ CONFIG_MEM_HOTPLUG=y
+-CONFIG_RS6000_MC=y
++#CONFIG_RS6000_MC=y
+diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
+index 94340de..cd9d51a 100644
+--- a/default-configs/ppcemb-softmmu.mak
++++ b/default-configs/ppcemb-softmmu.mak
+@@ -8,6 +8,19 @@ CONFIG_SERIAL=y
+ CONFIG_SERIAL_ISA=y
+ CONFIG_I8257=y
+ CONFIG_OPENPIC=y
++CONFIG_MACIO=y
++CONFIG_CUDA=y
++CONFIG_ADB=y
++CONFIG_MAC_NVRAM=y
++CONFIG_MAC_DBDMA=y
++CONFIG_HEATHROW_PIC=y
++CONFIG_GRACKLE_PCI=y
++CONFIG_UNIN_PCI=y
++CONFIG_DEC_PCI=y
++CONFIG_PPCE500_PCI=y
++CONFIG_IDE_ISA=y
++CONFIG_IDE_CMD646=y
++CONFIG_IDE_MACIO=y
+ CONFIG_PFLASH_CFI01=y
+ CONFIG_PFLASH_CFI02=y
+ CONFIG_PTIMER=y
+diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
+index 51191b7..43dbf34 100644
+--- a/default-configs/s390x-softmmu.mak
++++ b/default-configs/s390x-softmmu.mak
+@@ -1,5 +1,5 @@
+ CONFIG_PCI=y
+-CONFIG_VIRTIO_PCI=y
++#CONFIG_VIRTIO_PCI=y
+ CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+ CONFIG_VIRTIO=y
+ CONFIG_SCLPCONSOLE=y
+diff --git a/default-configs/sound.mak b/default-configs/sound.mak
+index 4f22c34..1bead9b 100644
+--- a/default-configs/sound.mak
++++ b/default-configs/sound.mak
+@@ -1,4 +1,4 @@
+-CONFIG_SB16=y
+-CONFIG_ADLIB=y
+-CONFIG_GUS=y
+-CONFIG_CS4231A=y
++#CONFIG_SB16=y
++#CONFIG_ADLIB=y
++#CONFIG_GUS=y
++#CONFIG_CS4231A=y
+diff --git a/default-configs/usb.mak b/default-configs/usb.mak
+index f4b8568..a256f84 100644
+--- a/default-configs/usb.mak
++++ b/default-configs/usb.mak
+@@ -1,10 +1,10 @@
+ CONFIG_USB=y
+-CONFIG_USB_TABLET_WACOM=y
++#CONFIG_USB_TABLET_WACOM=y
+ CONFIG_USB_STORAGE_BOT=y
+-CONFIG_USB_STORAGE_UAS=y
+-CONFIG_USB_STORAGE_MTP=y
++#CONFIG_USB_STORAGE_UAS=y
++#CONFIG_USB_STORAGE_MTP=y
+ CONFIG_USB_SMARTCARD=y
+-CONFIG_USB_AUDIO=y
+-CONFIG_USB_SERIAL=y
+-CONFIG_USB_NETWORK=y
+-CONFIG_USB_BLUETOOTH=y
++#CONFIG_USB_AUDIO=y
++#CONFIG_USB_SERIAL=y
++#CONFIG_USB_NETWORK=y
++#CONFIG_USB_BLUETOOTH=y
+diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
+index 9bde2f1..d6d10aa 100644
+--- a/default-configs/x86_64-softmmu.mak
++++ b/default-configs/x86_64-softmmu.mak
+@@ -4,19 +4,20 @@ include pci.mak
+ include sound.mak
+ include usb.mak
+ CONFIG_QXL=$(CONFIG_SPICE)
+-CONFIG_VGA_ISA=y
++#CONFIG_VGA_ISA=y
++CONFIG_VGA_PCI=y
+ CONFIG_VGA_CIRRUS=y
+-CONFIG_VMWARE_VGA=y
++#CONFIG_VMWARE_VGA=y
+ CONFIG_VIRTIO_VGA=y
+ CONFIG_VMMOUSE=y
+ CONFIG_IPMI=y
+-CONFIG_IPMI_LOCAL=y
+-CONFIG_IPMI_EXTERN=y
+-CONFIG_ISA_IPMI_KCS=y
+-CONFIG_ISA_IPMI_BT=y
++#CONFIG_IPMI_LOCAL=y
++#CONFIG_IPMI_EXTERN=y
++#CONFIG_ISA_IPMI_KCS=y
++#CONFIG_ISA_IPMI_BT=y
+ CONFIG_SERIAL=y
+ CONFIG_SERIAL_ISA=y
+-CONFIG_PARALLEL=y
++#CONFIG_PARALLEL=y
+ CONFIG_I8254=y
+ CONFIG_PCSPK=y
+ CONFIG_PCKBD=y
+@@ -28,17 +29,18 @@ CONFIG_ACPI_MEMORY_HOTPLUG=y
+ CONFIG_ACPI_CPU_HOTPLUG=y
+ CONFIG_APM=y
+ CONFIG_I8257=y
+-CONFIG_IDE_ISA=y
++#CONFIG_IDE_ISA=y
+ CONFIG_IDE_PIIX=y
+-CONFIG_NE2000_ISA=y
+-CONFIG_HPET=y
+-CONFIG_APPLESMC=y
++#CONFIG_NE2000_ISA=y
++#CONFIG_HPET=y
++#CONFIG_APPLESMC=y
+ CONFIG_I8259=y
+ CONFIG_PFLASH_CFI01=y
+ CONFIG_TPM_TIS=$(CONFIG_TPM)
+ CONFIG_MC146818RTC=y
+ CONFIG_PCI_PIIX=y
+ CONFIG_WDT_IB700=y
++CONFIG_ISA_BUS=y
+ CONFIG_ISA_DEBUG=y
+ CONFIG_ISA_TESTDEV=y
+ CONFIG_VMPORT=y
+@@ -56,6 +58,6 @@ CONFIG_XIO3130=y
+ CONFIG_IOH3420=y
+ CONFIG_I82801B11=y
+ CONFIG_SMBIOS=y
+-CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
++#CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
+ CONFIG_PXB=y
+ CONFIG_ACPI_VMGENID=y
+diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
+index c5d8646..a4e87b8 100644
+--- a/hw/acpi/ich9.c
++++ b/hw/acpi/ich9.c
+@@ -446,8 +446,8 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
+     static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
+     pm->acpi_memory_hotplug.is_enabled = true;
+     pm->cpu_hotplug_legacy = true;
+-    pm->disable_s3 = 0;
+-    pm->disable_s4 = 0;
++    pm->disable_s3 = 1;
++    pm->disable_s4 = 1;
+     pm->s4_val = 2;
+ 
+     object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
+diff --git a/hw/block/fdc.c b/hw/block/fdc.c
+index 4011290..90cd9a0 100644
+--- a/hw/block/fdc.c
++++ b/hw/block/fdc.c
+@@ -611,6 +611,7 @@ static void floppy_drive_class_init(ObjectClass *klass, void *data)
+     k->bus_type = TYPE_FLOPPY_BUS;
+     k->props = floppy_drive_properties;
+     k->desc = "virtual floppy drive";
++    k->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static const TypeInfo floppy_drive_info = {
+diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
+index 1113ab1..afe6230 100644
+--- a/hw/block/pflash_cfi01.c
++++ b/hw/block/pflash_cfi01.c
+@@ -925,6 +925,7 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
+     dc->realize = pflash_cfi01_realize;
+     dc->props = pflash_cfi01_properties;
+     dc->vmsd = &vmstate_pflash;
++    dc->user_creatable = false; /* RH state preserve */
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ }
+ 
+diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
+index 303104d..24ce17b 100644
+--- a/hw/char/serial-pci.c
++++ b/hw/char/serial-pci.c
+@@ -228,6 +228,8 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+     dc->vmsd = &vmstate_pci_multi_serial;
+     dc->props = multi_2x_serial_pci_properties;
+     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+@@ -243,6 +245,8 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
+     dc->vmsd = &vmstate_pci_multi_serial;
+     dc->props = multi_4x_serial_pci_properties;
+     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo serial_pci_info = {
+diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
+index f8d7a4a..060d594 100644
+--- a/hw/core/Makefile.objs
++++ b/hw/core/Makefile.objs
+@@ -15,9 +15,10 @@ common-obj-$(CONFIG_SOFTMMU) += machine.o
+ common-obj-$(CONFIG_SOFTMMU) += loader.o
+ common-obj-$(CONFIG_FITLOADER) += loader-fit.o
+ common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
+-common-obj-$(CONFIG_SOFTMMU) += register.o
+-common-obj-$(CONFIG_SOFTMMU) += or-irq.o
+ common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
++# Disabled in Red Hat Enterprise Linux
++# common-obj-$(CONFIG_SOFTMMU) += register.o
++# obj-$(CONFIG_SOFTMMU) += generic-loader.o
++# common-obj-$(CONFIG_SOFTMMU) += or-irq.o
+ 
+-obj-$(CONFIG_SOFTMMU) += generic-loader.o
+ obj-$(CONFIG_SOFTMMU) += null-machine.o
+diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
+index 14008aa..15322b5 100644
+--- a/hw/display/cirrus_vga.c
++++ b/hw/display/cirrus_vga.c
+@@ -3077,6 +3077,8 @@ static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
+     dc->realize = isa_cirrus_vga_realizefn;
+     dc->props = isa_cirrus_vga_properties;
+     set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo isa_cirrus_vga_info = {
+diff --git a/hw/display/sm501.c b/hw/display/sm501.c
+index 9aa515b..6f3dfe0 100644
+--- a/hw/display/sm501.c
++++ b/hw/display/sm501.c
+@@ -1758,7 +1758,7 @@ static void sm501_sysbus_class_init(ObjectClass *klass, void *data)
+     dc->reset = sm501_reset_sysbus;
+     dc->vmsd = &vmstate_sm501_sysbus;
+     /* Note: pointer property "chr-state" may remain null, thus
+-     * no need for dc->cannot_instantiate_with_device_add_yet = true;
++     * no need for dc->user_creatable = false;
+      */
+ }
+ 
+diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
+index bd23e89..e52a679 100644
+--- a/hw/dma/i8257.c
++++ b/hw/dma/i8257.c
+@@ -591,6 +591,8 @@ static void i8257_class_init(ObjectClass *klass, void *data)
+     dc->reset = i8257_reset;
+     dc->vmsd = &vmstate_i8257;
+     dc->props = i8257_properties;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ 
+     idc->get_transfer_mode = i8257_dma_get_transfer_mode;
+     idc->has_autoinitialization = i8257_dma_has_autoinitialization;
+diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
+index 9b5686b..1874b03 100644
+--- a/hw/i386/Makefile.objs
++++ b/hw/i386/Makefile.objs
+@@ -4,7 +4,8 @@ obj-y += pc.o pc_piix.o pc_q35.o
+ obj-y += pc_sysfw.o
+ obj-y += x86-iommu.o
+ obj-$(CONFIG_VTD) += intel_iommu.o
+-obj-y += amd_iommu.o
++# Disabled in Red Hat Enterprise Linux
++# obj-y += amd_iommu.o
+ obj-$(CONFIG_XEN) += ../xenpv/ xen/
+ 
+ obj-y += kvmvapic.o
+diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
+index 363d1b5..fc7212f 100644
+--- a/hw/i386/kvm/clock.c
++++ b/hw/i386/kvm/clock.c
+@@ -289,6 +289,7 @@ static void kvmclock_class_init(ObjectClass *klass, void *data)
+     dc->realize = kvmclock_realize;
+     dc->vmsd = &kvmclock_vmsd;
+     dc->props = kvmclock_properties;
++    dc->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static const TypeInfo kvmclock_info = {
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index 64929ea..c568777 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -1593,8 +1593,9 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
+     }
+ 
+     serial_hds_isa_init(isa_bus, 0, MAX_SERIAL_PORTS);
++#if 0 /* Disabled for Red Hat Enterprise Linux 7 */
+     parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS);
+-
++#endif
+     a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
+     i8042 = isa_create_simple(isa_bus, "i8042");
+     i8042_setup_a20_line(i8042, a20_line[0]);
+diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
+index 406a1b5..2cb41fc 100644
+--- a/hw/ide/ahci.c
++++ b/hw/ide/ahci.c
+@@ -1720,6 +1720,7 @@ static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
+     dc->vmsd = &vmstate_sysbus_ahci;
+     dc->props = sysbus_ahci_properties;
+     dc->reset = sysbus_ahci_reset;
++    dc->user_creatable = false; /* RH state preserve */
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ }
+ 
+@@ -1731,6 +1732,7 @@ static const TypeInfo sysbus_ahci_info = {
+     .class_init    = sysbus_ahci_class_init,
+ };
+ 
++#if 0  /* Disabled in Red Hat Enterprise Linux */
+ #define ALLWINNER_AHCI_BISTAFR    ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
+ #define ALLWINNER_AHCI_BISTCR     ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
+ #define ALLWINNER_AHCI_BISTFCTR   ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
+@@ -1824,11 +1826,14 @@ static const TypeInfo allwinner_ahci_info = {
+     .instance_init = allwinner_ahci_init,
+     .class_init    = allwinner_ahci_class_init,
+ };
++#endif
+ 
+ static void sysbus_ahci_register_types(void)
+ {
+     type_register_static(&sysbus_ahci_info);
++#if 0  /* Disabled in Red Hat Enterprise Linux */
+     type_register_static(&allwinner_ahci_info);
++#endif
+ }
+ 
+ type_init(sysbus_ahci_register_types)
+diff --git a/hw/ide/piix.c b/hw/ide/piix.c
+index 7e2d767..3184377 100644
+--- a/hw/ide/piix.c
++++ b/hw/ide/piix.c
+@@ -254,7 +254,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
+     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
+     k->class_id = PCI_CLASS_STORAGE_IDE;
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+-    dc->hotpluggable = false;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo piix3_ide_info = {
+@@ -281,6 +282,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
+     k->class_id = PCI_CLASS_STORAGE_IDE;
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+     dc->hotpluggable = false;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo piix4_ide_info = {
+diff --git a/hw/ide/via.c b/hw/ide/via.c
+index 5b32ecb..c0ab568 100644
+--- a/hw/ide/via.c
++++ b/hw/ide/via.c
+@@ -220,6 +220,8 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
+     k->revision = 0x06;
+     k->class_id = PCI_CLASS_STORAGE_IDE;
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo via_ide_info = {
+diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
+index c479f82..62678f3 100644
+--- a/hw/input/pckbd.c
++++ b/hw/input/pckbd.c
+@@ -570,6 +570,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
+ 
+     dc->realize = i8042_realizefn;
+     dc->vmsd = &vmstate_kbd_isa;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo i8042_info = {
+diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
+index 348e0ea..467042f 100644
+--- a/hw/isa/isa-bus.c
++++ b/hw/isa/isa-bus.c
+@@ -221,6 +221,7 @@ static void isabus_bridge_class_init(ObjectClass *klass, void *data)
+ 
+     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+     dc->fw_name = "isa";
++    dc->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static const TypeInfo isabus_bridge_info = {
+diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
+index 29fb922..a1007ae 100644
+--- a/hw/misc/Makefile.objs
++++ b/hw/misc/Makefile.objs
+@@ -8,7 +8,7 @@ common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
+ common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
+ common-obj-$(CONFIG_EDU) += edu.o
+ 
+-common-obj-y += unimp.o
++#common-obj-y += unimp.o
+ 
+ obj-$(CONFIG_VMPORT) += vmport.o
+ 
+diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
+index 47a015f..33ef10b 100644
+--- a/hw/misc/ivshmem.c
++++ b/hw/misc/ivshmem.c
+@@ -850,6 +850,13 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
+         return;
+     }
+ 
++    /* Migration disabled for Red Hat Enterprise Linux: */
++    if (s->master == ON_OFF_AUTO_ON) {
++        error_setg(errp, "master=on is not supported");
++        return;
++    }
++    s->master = ON_OFF_AUTO_OFF;
++
+     pci_conf = dev->config;
+     pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ 
+@@ -1137,6 +1144,8 @@ static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data)
+     k->realize = ivshmem_doorbell_realize;
+     dc->props = ivshmem_doorbell_properties;
+     dc->vmsd = &ivshmem_doorbell_vmsd;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo ivshmem_doorbell_info = {
+@@ -1306,6 +1315,8 @@ static void ivshmem_class_init(ObjectClass *klass, void *data)
+     dc->desc = "Inter-VM shared memory (legacy)";
+     dc->props = ivshmem_properties;
+     dc->vmsd = &ivshmem_vmsd;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo ivshmem_info = {
+diff --git a/hw/net/e1000.c b/hw/net/e1000.c
+index 3d86146..d29e9ee 100644
+--- a/hw/net/e1000.c
++++ b/hw/net/e1000.c
+@@ -1704,6 +1704,7 @@ static const E1000Info e1000_devices[] = {
+         .revision  = 0x03,
+         .phy_id2   = E1000_PHY_ID2_8254xx_DEFAULT,
+     },
++#if 0 /* Disabled for Red Hat Enterprise Linux 7 */
+     {
+         .name      = "e1000-82544gc",
+         .device_id = E1000_DEV_ID_82544GC_COPPER,
+@@ -1716,6 +1717,7 @@ static const E1000Info e1000_devices[] = {
+         .revision  = 0x03,
+         .phy_id2   = E1000_PHY_ID2_8254xx_DEFAULT,
+     },
++#endif
+ };
+ 
+ static const TypeInfo e1000_default_info = {
+diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
+index 6c42b44..2c91d07 100644
+--- a/hw/net/e1000e.c
++++ b/hw/net/e1000e.c
+@@ -671,7 +671,7 @@ static void e1000e_class_init(ObjectClass *class, void *data)
+     c->vendor_id = PCI_VENDOR_ID_INTEL;
+     c->device_id = E1000_DEV_ID_82574L;
+     c->revision = 0;
+-    c->romfile = "efi-e1000e.rom";
++    c->romfile = "pxe-e1000e.rom";
+     c->class_id = PCI_CLASS_NETWORK_ETHERNET;
+     c->is_express = 1;
+ 
+diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
+index 072a04e..90c50b0 100644
+--- a/hw/pci-host/piix.c
++++ b/hw/pci-host/piix.c
+@@ -750,6 +750,7 @@ static const TypeInfo i440fx_info = {
+     .class_init    = i440fx_class_init,
+ };
+ 
++#if 0 /*  Disabled in Red Hat Enterprise Linux */
+ /* IGD Passthrough Host Bridge. */
+ typedef struct {
+     uint8_t offset;
+@@ -838,6 +839,7 @@ static const TypeInfo igd_passthrough_i440fx_info = {
+     .instance_size = sizeof(PCII440FXState),
+     .class_init    = igd_passthrough_i440fx_class_init,
+ };
++#endif
+ 
+ static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
+                                                 PCIBus *rootbus)
+@@ -882,7 +884,9 @@ static const TypeInfo i440fx_pcihost_info = {
+ static void i440fx_register_types(void)
+ {
+     type_register_static(&i440fx_info);
++#if 0 /*  Disabled in Red Hat Enterprise Linux */
+     type_register_static(&igd_passthrough_i440fx_info);
++#endif
+     type_register_static(&piix3_pci_type_info);
+     type_register_static(&piix3_info);
+     type_register_static(&piix3_xen_info);
+diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
+index 0e472f2..a91418c 100644
+--- a/hw/pci-host/q35.c
++++ b/hw/pci-host/q35.c
+@@ -158,6 +158,7 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
+     dc->user_creatable = false;
+     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+     dc->fw_name = "pci";
++    dc->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static void q35_host_initfn(Object *obj)
+diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
+index 645ffdf..856cef5 100644
+--- a/hw/ppc/Makefile.objs
++++ b/hw/ppc/Makefile.objs
+@@ -3,7 +3,7 @@ obj-y += ppc.o ppc_booke.o fdt.o
+ # IBM pSeries (sPAPR)
+ obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
+ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
+-obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
++obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o
+ obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
+ # IBM PowerNV
+ obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o pnv_bmc.o
+@@ -13,7 +13,6 @@ endif
+ obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o
+ # PowerPC 4xx boards
+ obj-y += ppc4xx_devs.o ppc405_uc.o
+-obj-y += ppc4xx_pci.o
+ # PReP
+ obj-$(CONFIG_PREP) += prep.o
+ obj-$(CONFIG_PREP) += prep_systemio.o
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 268fd44..8d1cfcf 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1084,6 +1084,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
+     /* /vdevice */
+     spapr_dt_vdevice(spapr->vio_bus, fdt);
+ 
++#if 0 /* Disabled in Red Hat Enterprise Linux */
+     if (object_resolve_path_type("", TYPE_SPAPR_RNG, NULL)) {
+         ret = spapr_rng_populate_dt(fdt);
+         if (ret < 0) {
+@@ -1091,7 +1092,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
+             exit(1);
+         }
+     }
+-
++#endif
+     QLIST_FOREACH(phb, &spapr->phbs, list) {
+         ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt);
+         if (ret < 0) {
+diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
+index ea278ce..3e731e4 100644
+--- a/hw/ppc/spapr_cpu_core.c
++++ b/hw/ppc/spapr_cpu_core.c
+@@ -264,6 +264,7 @@ err:
+ }
+ 
+ static const char *spapr_core_models[] = {
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+     /* 970 */
+     "970_v2.2",
+ 
+@@ -276,6 +277,8 @@ static const char *spapr_core_models[] = {
+     /* POWER5+ */
+     "POWER5+_v2.1",
+ 
++    { .name = "POWER5+_v2.1", .initfn = spapr_cpu_core_POWER5plus_initfn },
++#endif
+     /* POWER7 */
+     "POWER7_v2.3",
+ 
+@@ -290,7 +293,6 @@ static const char *spapr_core_models[] = {
+ 
+     /* POWER8NVL */
+     "POWER8NVL_v1.0",
+-
+     /* POWER9 */
+     "POWER9_v1.0",
+ };
+diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
+index b1976fd..d85ff1d 100644
+--- a/hw/s390x/virtio-ccw.c
++++ b/hw/s390x/virtio-ccw.c
+@@ -989,6 +989,8 @@ static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp)
+                              NULL);
+ }
+ 
++#if 0  /* Disabled in Red Hat Enterprise Linux */
++
+ static void virtio_ccw_crypto_realize(VirtioCcwDevice *ccw_dev, Error **errp)
+ {
+     VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(ccw_dev);
+@@ -1007,6 +1009,8 @@ static void virtio_ccw_crypto_realize(VirtioCcwDevice *ccw_dev, Error **errp)
+                              NULL);
+ }
+ 
++#endif
++
+ /* DeviceState to VirtioCcwDevice. Note: used on datapath,
+  * be careful and test performance if you change this.
+  */
+@@ -1578,6 +1582,8 @@ static const TypeInfo virtio_ccw_rng = {
+     .class_init    = virtio_ccw_rng_class_init,
+ };
+ 
++#if 0  /* Disabled in Red Hat Enterprise Linux */
++
+ static Property virtio_ccw_crypto_properties[] = {
+     DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
+                     VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
+@@ -1616,6 +1622,8 @@ static const TypeInfo virtio_ccw_crypto = {
+     .class_init    = virtio_ccw_crypto_class_init,
+ };
+ 
++#endif
++
+ static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp)
+ {
+     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
+@@ -1814,7 +1822,9 @@ static void virtio_ccw_register(void)
+ #ifdef CONFIG_VHOST_VSOCK
+     type_register_static(&vhost_vsock_ccw_info);
+ #endif
++#if 0  /* Disabled in Red Hat Enterprise Linux */
+     type_register_static(&virtio_ccw_crypto);
++#endif
+ }
+ 
+ type_init(virtio_ccw_register)
+diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
+index e646eb2..8d7205c 100644
+--- a/hw/usb/ccid-card-emulated.c
++++ b/hw/usb/ccid-card-emulated.c
+@@ -588,6 +588,8 @@ static void emulated_class_initfn(ObjectClass *klass, void *data)
+     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+     dc->desc = "emulated smartcard";
+     dc->props = emulated_card_properties;
++    /* Disabled for Red Hat Enterprise Linux: */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo emulated_card_info = {
+diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
+index c3ab909..4029072 100644
+--- a/hw/vfio/Makefile.objs
++++ b/hw/vfio/Makefile.objs
+@@ -2,8 +2,5 @@ ifeq ($(CONFIG_LINUX), y)
+ obj-$(CONFIG_SOFTMMU) += common.o
+ obj-$(CONFIG_PCI) += pci.o pci-quirks.o
+ obj-$(CONFIG_VFIO_CCW) += ccw.o
+-obj-$(CONFIG_SOFTMMU) += platform.o
+-obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
+-obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o
+ obj-$(CONFIG_SOFTMMU) += spapr.o
+ endif
+diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
+index 349085e..58046e6 100644
+--- a/hw/vfio/pci-quirks.c
++++ b/hw/vfio/pci-quirks.c
+@@ -1189,6 +1189,8 @@ static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, void *data)
+     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+     dc->desc = "VFIO dummy ISA/LPC bridge for IGD assignment";
+     dc->hotpluggable = false;
++    /* Disabled in Red Hat Enterprise Linux */
++    dc->user_creatable = false;
+     k->realize = vfio_pci_igd_lpc_bridge_realize;
+     k->class_id = PCI_CLASS_BRIDGE_ISA;
+ }
+@@ -1378,6 +1380,9 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
+                                        0, PCI_DEVFN(0x2, 0))) {
+         return;
+     }
++    
++    /* Disabled in Red Hat Enterprise Linux */
++    return;
+ 
+     /*
+      * We need to create an LPC/ISA bridge at PCI bus address 00:1f.0 that we
+diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
+index 765d363..a5a0936 100644
+--- a/hw/virtio/Makefile.objs
++++ b/hw/virtio/Makefile.objs
+@@ -7,8 +7,9 @@ common-obj-y += virtio-mmio.o
+ obj-y += virtio.o virtio-balloon.o 
+ obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
+ obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
+-obj-y += virtio-crypto.o
+-obj-$(CONFIG_VIRTIO_PCI) += virtio-crypto-pci.o
++# Disabled in Red Hat Enterprise Linux
++#obj-y += virtio-crypto.o
++#obj-$(CONFIG_VIRTIO_PCI) += virtio-crypto-pci.o
+ endif
+ 
+ common-obj-$(call lnot,$(CONFIG_LINUX)) += vhost-stub.o
+diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
+index 5807aa8..62df6c2 100644
+--- a/hw/virtio/virtio-mmio.c
++++ b/hw/virtio/virtio-mmio.c
+@@ -448,6 +448,7 @@ static void virtio_mmio_class_init(ObjectClass *klass, void *data)
+ 
+     dc->realize = virtio_mmio_realizefn;
+     dc->reset = virtio_mmio_reset;
++    dc->user_creatable = false; /* RH state preserve */
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     dc->props = virtio_mmio_properties;
+ }
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 9f6e2ad..568fc7c 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -1820,11 +1820,6 @@ ETEXI
+ 
+ DEF("no-hpet", 0, QEMU_OPTION_no_hpet,
+     "-no-hpet        disable HPET\n", QEMU_ARCH_I386)
+-STEXI
+-@item -no-hpet
+-@findex -no-hpet
+-Disable HPET support.
+-ETEXI
+ 
+ DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
+     "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
+diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
+index b24da3b..7e9f94d 100644
+--- a/stubs/Makefile.objs
++++ b/stubs/Makefile.objs
+@@ -41,3 +41,4 @@ stub-obj-y += vmgenid.o
+ stub-obj-y += xen-common.o
+ stub-obj-y += xen-hvm.o
+ stub-obj-y += shadow-bios.o
++stub-obj-y += ide-isa.o
+diff --git a/stubs/ide-isa.c b/stubs/ide-isa.c
+new file mode 100644
+index 0000000..5dacaa5
+--- /dev/null
++++ b/stubs/ide-isa.c
+@@ -0,0 +1,13 @@
++#include <qemu/osdep.h>
++#include <hw/ide.h>
++#include <stdlib.h>
++
++ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
++                        DriveInfo *hd0, DriveInfo *hd1)
++{
++    /*
++     * In theory the real isa_ide_init() function can return NULL, but no
++     * caller actually checks for that. Make sure we go out with a clear bang.
++     */
++    abort();
++}
+diff --git a/target/arm/cpu.c b/target/arm/cpu.c
+index 05c038b..3f90b7e 100644
+--- a/target/arm/cpu.c
++++ b/target/arm/cpu.c
+@@ -1724,7 +1724,9 @@ static void arm_cpu_register_types(void)
+     type_register_static(&arm_cpu_type_info);
+ 
+     while (info->name) {
+-        cpu_register(info);
++        /* RHEL specific: Filter out unsupported cpu models */
++        if (!strcmp(info->name, "cortex-a15"))
++            cpu_register(info);
+         info++;
+     }
+ }
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 7f52680..670d121 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -772,11 +772,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
+             CPUID_PSE | CPUID_DE | CPUID_FP87,
+         .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
+-        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR |
+-            CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PAT | CPUID_EXT2_CMOV |
+-            CPUID_EXT2_PGE | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
+-            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC |
+-            CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
++        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
+         .xlevel = 0x8000000A,
+@@ -1014,11 +1011,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
+              CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
+              CPUID_PSE | CPUID_DE | CPUID_FP87,
+         .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
+-        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR |
+-             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PAT | CPUID_EXT2_CMOV |
+-             CPUID_EXT2_PGE | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
+-             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC |
+-             CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
++        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+         .features[FEAT_8000_0001_ECX] = CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
+              CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+         .xlevel = 0x8000000A,
+@@ -4113,11 +4106,13 @@ static Property x86_cpu_properties[] = {
+     DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
+     DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
+     DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+     DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
+     DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
+     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),
++#endif
+     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/ppc/cpu-models.c b/target/ppc/cpu-models.c
+index 4d3e635..08a1f59 100644
+--- a/target/ppc/cpu-models.c
++++ b/target/ppc/cpu-models.c
+@@ -70,6 +70,7 @@
+ #define POWERPC_DEF(_name, _pvr, _type, _desc)                              \
+     POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type)
+ 
++#if 0  /* Embedded and 32-bit CPUs disabled for Red Hat Enterprise Linux */
+     /* Embedded PowerPC                                                      */
+     /* PowerPC 401 family                                                    */
+     POWERPC_DEF("401",           CPU_POWERPC_401,                    401,
+@@ -1101,8 +1102,10 @@
+                 "PowerPC 7447A v1.2 (G4)")
+     POWERPC_DEF("7457A_v1.2",    CPU_POWERPC_74x7A_v12,              7455,
+                 "PowerPC 7457A v1.2 (G4)")
++#endif
+     /* 64 bits PowerPC                                                       */
+ #if defined (TARGET_PPC64)
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+ #if defined(TODO)
+     POWERPC_DEF("620",           CPU_POWERPC_620,                    620,
+                 "PowerPC 620")
+@@ -1131,6 +1134,7 @@
+     POWERPC_DEF("POWER6",        CPU_POWERPC_POWER6,                 POWER6,
+                 "POWER6")
+ #endif
++#endif
+     POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7,
+                 "POWER7 v2.3")
+     POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,            POWER7,
+@@ -1141,12 +1145,15 @@
+                 "POWER8 v2.0")
+     POWERPC_DEF("POWER8NVL_v1.0",CPU_POWERPC_POWER8NVL_v10,          POWER8,
+                 "POWER8NVL v1.0")
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+     POWERPC_DEF("970_v2.2",      CPU_POWERPC_970_v22,                970,
+                 "PowerPC 970 v2.2")
++#endif
+ 
+     POWERPC_DEF("POWER9_v1.0",   CPU_POWERPC_POWER9_BASE,            POWER9,
+                 "POWER9 v1.0")
+ 
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+     POWERPC_DEF("970fx_v1.0",    CPU_POWERPC_970FX_v10,              970,
+                 "PowerPC 970FX v1.0 (G5)")
+     POWERPC_DEF("970fx_v2.0",    CPU_POWERPC_970FX_v20,              970,
+@@ -1161,6 +1168,7 @@
+                 "PowerPC 970MP v1.0")
+     POWERPC_DEF("970mp_v1.1",    CPU_POWERPC_970MP_v11,              970,
+                 "PowerPC 970MP v1.1")
++#endif
+ #if defined(TODO)
+     POWERPC_DEF("Cell",          CPU_POWERPC_CELL,                   970,
+                 "PowerPC Cell")
+@@ -1226,6 +1234,7 @@
+ /* PowerPC CPU aliases                                                     */
+ 
+ PowerPCCPUAlias ppc_cpu_aliases[] = {
++#if 0  /* Embedded and 32-bit CPUs disabled for Red Hat Enterprise Linux */
+     { "403", "403GC" },
+     { "405", "405D4" },
+     { "405CR", "405CRc" },
+@@ -1381,22 +1390,27 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
+     { "7447A", "7447A_v1.2" },
+     { "7457A", "7457A_v1.2" },
+     { "Apollo7PM", "7457A_v1.0" },
++#endif
+ #if defined(TARGET_PPC64)
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+     { "POWER3", "630" },
+     { "POWER3+", "631" },
+     { "POWER5+", "POWER5+_v2.1" },
+     { "POWER5gs", "POWER5+_v2.1" },
++#endif
+     { "POWER7", "POWER7_v2.3" },
+     { "POWER7+", "POWER7+_v2.1" },
+     { "POWER8E", "POWER8E_v2.1" },
+     { "POWER8", "POWER8_v2.0" },
+     { "POWER8NVL", "POWER8NVL_v1.0" },
+     { "POWER9", "POWER9_v1.0" },
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+     { "970", "970_v2.2" },
+     { "970fx", "970fx_v3.1" },
+     { "970mp", "970mp_v1.1" },
+ #endif
+-
++#endif
++#if 0  /* Disabled for Red Hat Enterprise Linux */
+     /* Generic PowerPCs */
+ #if defined(TARGET_PPC64)
+     { "ppc64", "970fx" },
+@@ -1404,5 +1418,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
+     { "ppc32", "604" },
+     { "ppc", "ppc32" },
+     { "default", "ppc" },
++#endif
+     { NULL, NULL }
+ };
+diff --git a/tests/Makefile.include b/tests/Makefile.include
+index 37c1bed..327ffd9 100644
+--- a/tests/Makefile.include
++++ b/tests/Makefile.include
+@@ -166,8 +166,6 @@ check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
+ gcov-files-generic-y = qdev-monitor.c qmp.c
+ 
+ gcov-files-ipack-y += hw/ipack/ipack.c
+-check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
+-gcov-files-ipack-y += hw/char/ipoctal232.c
+ 
+ check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF)
+ gcov-files-virtioserial-y += hw/char/virtio-console.c
+@@ -199,23 +197,10 @@ check-qtest-pci-y += tests/e1000e-test$(EXESUF)
+ gcov-files-pci-y += hw/net/e1000e.c hw/net/e1000e_core.c
+ check-qtest-pci-y += tests/rtl8139-test$(EXESUF)
+ gcov-files-pci-y += hw/net/rtl8139.c
+-check-qtest-pci-y += tests/pcnet-test$(EXESUF)
+-gcov-files-pci-y += hw/net/pcnet.c
+-gcov-files-pci-y += hw/net/pcnet-pci.c
+-check-qtest-pci-y += tests/eepro100-test$(EXESUF)
+-gcov-files-pci-y += hw/net/eepro100.c
+-check-qtest-pci-y += tests/ne2000-test$(EXESUF)
+-gcov-files-pci-y += hw/net/ne2000.c
+-check-qtest-pci-y += tests/nvme-test$(EXESUF)
+-gcov-files-pci-y += hw/block/nvme.c
+ check-qtest-pci-y += tests/ac97-test$(EXESUF)
+ gcov-files-pci-y += hw/audio/ac97.c
+-check-qtest-pci-y += tests/es1370-test$(EXESUF)
+-gcov-files-pci-y += hw/audio/es1370.c
+ check-qtest-pci-y += $(check-qtest-virtio-y)
+ gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c
+-check-qtest-pci-y += tests/tpci200-test$(EXESUF)
+-gcov-files-pci-y += hw/ipack/tpci200.c
+ check-qtest-pci-y += $(check-qtest-ipack-y)
+ gcov-files-pci-y += $(gcov-files-ipack-y)
+ check-qtest-pci-y += tests/display-vga-test$(EXESUF)
+@@ -229,23 +214,21 @@ check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
+ gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
+ check-qtest-pci-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF)
+ gcov-files-pci-y += hw/misc/ivshmem.c
+-check-qtest-pci-y += tests/megasas-test$(EXESUF)
+-gcov-files-pci-y += hw/scsi/megasas.c
++#check-qtest-pci-y += tests/megasas-test$(EXESUF)
++#gcov-files-pci-y += hw/scsi/megasas.c
+ 
+ check-qtest-i386-y = tests/endianness-test$(EXESUF)
+-check-qtest-i386-y += tests/fdc-test$(EXESUF)
+-gcov-files-i386-y = hw/block/fdc.c
++#check-qtest-i386-y += tests/fdc-test$(EXESUF)
++#gcov-files-i386-y = hw/block/fdc.c
+ check-qtest-i386-y += tests/ide-test$(EXESUF)
+ check-qtest-i386-y += tests/ahci-test$(EXESUF)
+ check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
+ gcov-files-i386-y += hw/block/hd-geometry.c
+ check-qtest-i386-y += tests/boot-order-test$(EXESUF)
+-check-qtest-i386-y += tests/bios-tables-test$(EXESUF)
++#check-qtest-i386-y += tests/bios-tables-test$(EXESUF)
+ check-qtest-i386-y += tests/boot-serial-test$(EXESUF)
+ check-qtest-i386-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF)
+ check-qtest-i386-y += tests/rtc-test$(EXESUF)
+-check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF)
+-check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF)
+ check-qtest-i386-y += tests/i440fx-test$(EXESUF)
+ check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
+ check-qtest-i386-y += tests/drive_del-test$(EXESUF)
+@@ -254,8 +237,6 @@ check-qtest-i386-y += tests/tco-test$(EXESUF)
+ gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c
+ check-qtest-i386-y += $(check-qtest-pci-y)
+ gcov-files-i386-y += $(gcov-files-pci-y)
+-check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
+-gcov-files-i386-y += hw/net/vmxnet3.c
+ gcov-files-i386-y += hw/net/net_rx_pkt.c
+ gcov-files-i386-y += hw/net/net_tx_pkt.c
+ check-qtest-i386-y += tests/pvpanic-test$(EXESUF)
+@@ -264,8 +245,6 @@ check-qtest-i386-y += tests/i82801b11-test$(EXESUF)
+ gcov-files-i386-y += hw/pci-bridge/i82801b11.c
+ check-qtest-i386-y += tests/ioh3420-test$(EXESUF)
+ gcov-files-i386-y += hw/pci-bridge/ioh3420.c
+-check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF)
+-gcov-files-i386-y += hw/usb/hcd-ohci.c
+ check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF)
+ gcov-files-i386-y += hw/usb/hcd-uhci.c
+ check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
+@@ -302,7 +281,7 @@ check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
+ 
+ check-qtest-ppc-y = tests/endianness-test$(EXESUF)
+ check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
+-check-qtest-ppc-y += tests/prom-env-test$(EXESUF)
++#check-qtest-ppc-y += tests/prom-env-test$(EXESUF)
+ check-qtest-ppc-y += tests/drive_del-test$(EXESUF)
+ check-qtest-ppc-y += tests/boot-serial-test$(EXESUF)
+ 
+@@ -310,32 +289,32 @@ check-qtest-ppc64-y = tests/spapr-phb-test$(EXESUF)
+ gcov-files-ppc64-y = ppc64-softmmu/hw/ppc/spapr_pci.c
+ check-qtest-ppc64-y += tests/endianness-test$(EXESUF)
+ check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
+-check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
+-check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF)
++#check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
++#check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF)
+ check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
+ check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
+ check-qtest-ppc64-y += tests/boot-serial-test$(EXESUF)
+ check-qtest-ppc64-y += tests/rtas-test$(EXESUF)
+ check-qtest-ppc64-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF)
+-check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF)
++#check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF)
+ gcov-files-ppc64-y += hw/usb/hcd-ohci.c
+-check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF)
++#check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF)
+ gcov-files-ppc64-y += hw/usb/hcd-uhci.c
+ check-qtest-ppc64-y += tests/usb-hcd-xhci-test$(EXESUF)
+ gcov-files-ppc64-y += hw/usb/hcd-xhci.c
+ check-qtest-ppc64-y += $(check-qtest-virtio-y)
+-check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
+-check-qtest-ppc64-y += tests/test-filter-mirror$(EXESUF)
+-check-qtest-ppc64-y += tests/test-filter-redirector$(EXESUF)
++#check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
++#check-qtest-ppc64-y += tests/test-filter-mirror$(EXESUF)
++#check-qtest-ppc64-y += tests/test-filter-redirector$(EXESUF)
+ check-qtest-ppc64-y += tests/display-vga-test$(EXESUF)
+ check-qtest-ppc64-y += tests/numa-test$(EXESUF)
+-check-qtest-ppc64-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF)
++#check-qtest-ppc64-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF)
+ 
+ check-qtest-sh4-y = tests/endianness-test$(EXESUF)
+ 
+ check-qtest-sh4eb-y = tests/endianness-test$(EXESUF)
+ 
+-check-qtest-sparc-y = tests/prom-env-test$(EXESUF)
++#check-qtest-sparc-y = tests/prom-env-test$(EXESUF)
+ #check-qtest-sparc-y += tests/m48t59-test$(EXESUF)
+ #gcov-files-sparc-y = hw/timer/m48t59.c
+ 
+@@ -353,7 +332,7 @@ gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
+ check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
+ gcov-files-arm-y += hw/timer/arm_mptimer.c
+ 
+-check-qtest-aarch64-y = tests/numa-test$(EXESUF)
++#check-qtest-aarch64-y = tests/numa-test$(EXESUF)
+ 
+ check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
+ 
+@@ -716,17 +695,15 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o
+ tests/m48t59-test$(EXESUF): tests/m48t59-test.o
+ tests/endianness-test$(EXESUF): tests/endianness-test.o
+ tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
+-tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
++#tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
+ tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
+-tests/fdc-test$(EXESUF): tests/fdc-test.o
++#tests/fdc-test$(EXESUF): tests/fdc-test.o
+ tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
+ tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
+-tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
+-tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
+ tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
+ tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
+ tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y)
+-tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
++#tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
+ 	tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y)
+ tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
+ tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
+@@ -738,11 +715,8 @@ tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
+ tests/e1000-test$(EXESUF): tests/e1000-test.o
+ tests/e1000e-test$(EXESUF): tests/e1000e-test.o $(libqos-pc-obj-y)
+ tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y)
+-tests/pcnet-test$(EXESUF): tests/pcnet-test.o
+-tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o
++#tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o
+ tests/eepro100-test$(EXESUF): tests/eepro100-test.o
+-tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
+-tests/ne2000-test$(EXESUF): tests/ne2000-test.o
+ tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o
+ tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y)
+ tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o
+@@ -753,21 +727,17 @@ tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y)
+ tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y)
+ tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
+ tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
+-tests/tpci200-test$(EXESUF): tests/tpci200-test.o
+ tests/display-vga-test$(EXESUF): tests/display-vga-test.o
+ tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
+ tests/qom-test$(EXESUF): tests/qom-test.o
+ tests/test-hmp$(EXESUF): tests/test-hmp.o
+ tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-pc-obj-y)
+ tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
+-tests/nvme-test$(EXESUF): tests/nvme-test.o
+ tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
+ tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o
+ tests/ac97-test$(EXESUF): tests/ac97-test.o
+-tests/es1370-test$(EXESUF): tests/es1370-test.o
+ tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
+ tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
+-tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y)
+ tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y)
+ tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y)
+ tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
+@@ -785,7 +755,7 @@ tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
+ tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y)
+ tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y)
+ tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
+-tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y)
++#tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y)
+ tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o contrib/libvhost-user/libvhost-user.o $(test-util-obj-y)
+ tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y)
+ tests/test-arm-mptimer$(EXESUF): tests/test-arm-mptimer.o
+diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
+index 564da45..ede777a 100644
+--- a/tests/bios-tables-test.c
++++ b/tests/bios-tables-test.c
+@@ -743,6 +743,7 @@ static void test_acpi_q35_tcg_cphp(void)
+     free_test_data(&data);
+ }
+ 
++#if 0 /* Disabled in Red Hat Enterprise Linux */
+ static uint8_t ipmi_required_struct_types[] = {
+     0, 1, 3, 4, 16, 17, 19, 32, 38, 127
+ };
+@@ -779,6 +780,7 @@ static void test_acpi_piix4_tcg_ipmi(void)
+                   &data);
+     free_test_data(&data);
+ }
++#endif
+ 
+ static void test_acpi_q35_tcg_memhp(void)
+ {
+@@ -824,8 +826,10 @@ int main(int argc, char *argv[])
+         qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge);
+         qtest_add_func("acpi/q35", test_acpi_q35_tcg);
+         qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
++#if 0 /* Disabled in Red Hat Enterprise Linux */
+         qtest_add_func("acpi/piix4/ipmi", test_acpi_piix4_tcg_ipmi);
+         qtest_add_func("acpi/q35/ipmi", test_acpi_q35_tcg_ipmi);
++#endif
+         qtest_add_func("acpi/piix4/cpuhp", test_acpi_piix4_tcg_cphp);
+         qtest_add_func("acpi/q35/cpuhp", test_acpi_q35_tcg_cphp);
+         qtest_add_func("acpi/piix4/memhp", test_acpi_piix4_tcg_memhp);
+diff --git a/tests/boot-order-test.c b/tests/boot-order-test.c
+index fc1e794..e29c528 100644
+--- a/tests/boot-order-test.c
++++ b/tests/boot-order-test.c
+@@ -109,6 +109,7 @@ static void test_pc_boot_order(void)
+     test_boot_orders(NULL, read_boot_order_pc, test_cases_pc);
+ }
+ 
++#if 0 /* Disabled for RHEL, since CONFIG_MAC and CONFIG_PREP are not enabled */
+ static uint8_t read_m48t59(uint64_t addr, uint16_t reg)
+ {
+     writeb(addr, reg & 0xff);
+@@ -139,6 +140,7 @@ static uint64_t read_boot_order_pmac(void)
+ 
+     return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE);
+ }
++#endif /* Disabled for RHEL, since CONFIG_MAC and CONFIG_PREP are not enabled */
+ 
+ static const boot_order_test test_cases_fw_cfg[] = {
+     { "", 'c', 'c' },
+@@ -148,6 +150,7 @@ static const boot_order_test test_cases_fw_cfg[] = {
+     {}
+ };
+ 
++#if 0 /* Disabled for RHEL, since CONFIG_MAC and CONFIG_PREP are not enabled */
+ static void test_pmac_oldworld_boot_order(void)
+ {
+     test_boot_orders("g3beige", read_boot_order_pmac, test_cases_fw_cfg);
+@@ -156,7 +159,9 @@ static void test_pmac_oldworld_boot_order(void)
+ static void test_pmac_newworld_boot_order(void)
+ {
+     test_boot_orders("mac99", read_boot_order_pmac, test_cases_fw_cfg);
++
+ }
++#endif /* Disabled for RHEL, since CONFIG_MAC and CONFIG_PREP are not enabled */
+ 
+ static uint64_t read_boot_order_sun4m(void)
+ {
+@@ -191,11 +196,13 @@ int main(int argc, char *argv[])
+     if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+         qtest_add_func("boot-order/pc", test_pc_boot_order);
+     } else if (strcmp(arch, "ppc") == 0 || strcmp(arch, "ppc64") == 0) {
++#if 0 /* Disabled for RHEL, since CONFIG_MAC and CONFIG_PREP are not enabled */
+         qtest_add_func("boot-order/prep", test_prep_boot_order);
+         qtest_add_func("boot-order/pmac_oldworld",
+                        test_pmac_oldworld_boot_order);
+         qtest_add_func("boot-order/pmac_newworld",
+                        test_pmac_newworld_boot_order);
++#endif /* Disabled for RHEL, since CONFIG_MAC and CONFIG_PREP are not enabled */
+     } else if (strcmp(arch, "sparc") == 0) {
+         qtest_add_func("boot-order/sun4m", test_sun4m_boot_order);
+     } else if (strcmp(arch, "sparc64") == 0) {
+diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
+index b95c5e7..e58c518 100644
+--- a/tests/boot-serial-test.c
++++ b/tests/boot-serial-test.c
+@@ -26,14 +26,14 @@ static testdef_t tests[] = {
+     { "alpha", "clipper", "", "PCI:" },
+     { "ppc", "ppce500", "", "U-Boot" },
+     { "ppc", "prep", "", "Open Hack'Ware BIOS" },
+-    { "ppc64", "ppce500", "", "U-Boot" },
+-    { "ppc64", "prep", "", "Open Hack'Ware BIOS" },
++/*    { "ppc64", "ppce500", "", "U-Boot" },
++    { "ppc64", "prep", "", "Open Hack'Ware BIOS" }, */
+     { "ppc64", "pseries", "", "Open Firmware" },
+-    { "ppc64", "powernv", "-cpu POWER8", "SkiBoot" },
++/*    { "ppc64", "powernv", "-cpu POWER8", "SkiBoot" }, */
+     { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
+     { "i386", "pc", "-device sga", "SGABIOS" },
+     { "i386", "q35", "-device sga", "SGABIOS" },
+-    { "x86_64", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
++    { "x86_64", "pc", "-cpu qemu32 -device sga", "SGABIOS" },
+     { "x86_64", "q35", "-device sga", "SGABIOS" },
+     { "s390x", "s390-ccw-virtio",
+       "-nodefaults -device sclpconsole,chardev=serial0", "virtio device" },
+diff --git a/tests/e1000-test.c b/tests/e1000-test.c
+index 0c5fcdc..0504d33 100644
+--- a/tests/e1000-test.c
++++ b/tests/e1000-test.c
+@@ -29,8 +29,10 @@ static void test_device(gconstpointer data)
+ static const char *models[] = {
+     "e1000",
+     "e1000-82540em",
++#if 0 /* Disabled in Red Hat Enterprise Linux 7 */
+     "e1000-82544gc",
+     "e1000-82545em",
++#endif
+ };
+ 
+ int main(int argc, char **argv)
+diff --git a/tests/endianness-test.c b/tests/endianness-test.c
+index ed0bf52..58af690 100644
+--- a/tests/endianness-test.c
++++ b/tests/endianness-test.c
+@@ -34,6 +34,7 @@ static const TestCase test_cases[] = {
+     { "mips64", "mips", 0x14000000, .bswap = true },
+     { "mips64", "malta", 0x10000000, .bswap = true },
+     { "mips64el", "fulong2e", 0x1fd00000 },
++#if 0 /* Disabled for RHEL, since ISA is not enabled */
+     { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" },
+     { "ppc", "prep", 0x80000000, .bswap = true },
+     { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" },
+@@ -41,6 +42,7 @@ static const TestCase test_cases[] = {
+     { "ppc64", "pseries", (1ULL << 45), .bswap = true, .superio = "i82378" },
+     { "ppc64", "pseries-2.7", 0x10080000000ULL,
+       .bswap = true, .superio = "i82378" },
++#endif /* Disabled for RHEL, since ISA is not enabled */
+     { "sh4", "r2d", 0xfe240000, .superio = "i82378" },
+     { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },
+     { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true },
+diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
+index 3776342..6aae100 100644
+--- a/tests/ivshmem-test.c
++++ b/tests/ivshmem-test.c
+@@ -256,6 +256,7 @@ static void test_ivshmem_pair(void)
+     g_free(data);
+ }
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux: */
+ typedef struct ServerThread {
+     GThread *thread;
+     IvshmemServer *server;
+@@ -413,9 +414,11 @@ static void test_ivshmem_server_irq(void)
+ {
+     test_ivshmem_server(false);
+ }
++#endif
+ 
+ #define PCI_SLOT_HP             0x06
+ 
++#if 0 /* Test uses legacy ivshmem, which is disabled for Red Hat Enterprise Linux: */
+ static void test_ivshmem_hotplug(void)
+ {
+     const char *arch = qtest_get_arch();
+@@ -433,6 +436,7 @@ static void test_ivshmem_hotplug(void)
+     qtest_end();
+     g_free(opts);
+ }
++#endif
+ 
+ static void test_ivshmem_memdev(void)
+ {
+@@ -500,7 +504,7 @@ static gchar *mktempshm(int size, int *fd)
+ int main(int argc, char **argv)
+ {
+     int ret, fd;
+-    const char *arch = qtest_get_arch();
++/*    const char *arch = qtest_get_arch(); */
+     gchar dir[] = "/tmp/ivshmem-test.XXXXXX";
+ 
+ #if !GLIB_CHECK_VERSION(2, 31, 0)
+@@ -527,14 +531,18 @@ int main(int argc, char **argv)
+     tmpserver = g_strconcat(tmpdir, "/server", NULL);
+ 
+     qtest_add_func("/ivshmem/single", test_ivshmem_single);
++#if 0 /* Test uses legacy ivshmem, which is disabled for Red Hat Enterprise Linux: */
+     qtest_add_func("/ivshmem/hotplug", test_ivshmem_hotplug);
++#endif
+     qtest_add_func("/ivshmem/memdev", test_ivshmem_memdev);
+     if (g_test_slow()) {
+         qtest_add_func("/ivshmem/pair", test_ivshmem_pair);
++#if 0 /* Disabled for Red Hat Enterprise Linux: */
+         if (strcmp(arch, "ppc64") != 0) {
+             qtest_add_func("/ivshmem/server-msi", test_ivshmem_server_msi);
+             qtest_add_func("/ivshmem/server-irq", test_ivshmem_server_irq);
+         }
++#endif
+     }
+ 
+     ret = g_test_run();
+diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
+index c8cfc76..e6275f6 100755
+--- a/tests/qemu-iotests/051
++++ b/tests/qemu-iotests/051
+@@ -145,9 +145,9 @@ case "$QEMU_DEFAULT_MACHINE" in
+     pc)
+         run_qemu -drive if=floppy
+         run_qemu -drive if=ide,media=cdrom
+-        run_qemu -drive if=scsi,media=cdrom
++#        run_qemu -drive if=scsi,media=cdrom
+         run_qemu -drive if=ide
+-        run_qemu -drive if=scsi
++#        run_qemu -drive if=scsi
+         ;;
+      *)
+         ;;
+@@ -158,11 +158,11 @@ run_qemu -drive if=virtio
+ case "$QEMU_DEFAULT_MACHINE" in
+     pc)
+         run_qemu -drive if=none,id=disk -device ide-cd,drive=disk
+-        run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
++#        run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
+         run_qemu -drive if=none,id=disk -device ide-drive,drive=disk
+         run_qemu -drive if=none,id=disk -device ide-hd,drive=disk
+-        run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
+-        run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
++#        run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
++#        run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
+         ;;
+      *)
+         ;;
+@@ -176,9 +176,9 @@ case "$QEMU_DEFAULT_MACHINE" in
+     pc)
+         run_qemu -drive file="$TEST_IMG",if=floppy,readonly=on
+         run_qemu -drive file="$TEST_IMG",if=ide,media=cdrom,readonly=on
+-        run_qemu -drive file="$TEST_IMG",if=scsi,media=cdrom,readonly=on
++#        run_qemu -drive file="$TEST_IMG",if=scsi,media=cdrom,readonly=on
+         run_qemu -drive file="$TEST_IMG",if=ide,readonly=on
+-        run_qemu -drive file="$TEST_IMG",if=scsi,readonly=on
++#        run_qemu -drive file="$TEST_IMG",if=scsi,readonly=on
+         ;;
+      *)
+         ;;
+@@ -189,11 +189,11 @@ run_qemu -drive file="$TEST_IMG",if=virtio,readonly=on
+ case "$QEMU_DEFAULT_MACHINE" in
+     pc)
+         run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-cd,drive=disk
+-        run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
++#        run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
+         run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-drive,drive=disk
+         run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-hd,drive=disk
+-        run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
+-        run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
++#        run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
++#        run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
+         ;;
+      *)
+         ;;
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 4bd5017..0c2bda3 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -77,7 +77,7 @@
+ 068 rw auto quick
+ 069 rw auto quick
+ 070 rw auto quick
+-071 rw auto quick
++# 071 rw auto quick -- requires whitelisted blkverify
+ 072 rw auto quick
+ 073 rw auto quick
+ 074 rw auto quick
+@@ -105,7 +105,7 @@
+ 096 rw auto quick
+ 097 rw auto backing
+ 098 rw auto backing quick
+-099 rw auto quick
++# 099 rw auto quick  -- requires whitelisted blkverify
+ # 100 was removed, do not reuse
+ 101 rw auto quick
+ 102 rw auto quick
+diff --git a/tests/qom-test.c b/tests/qom-test.c
+index ab0595d..44347d2 100644
+--- a/tests/qom-test.c
++++ b/tests/qom-test.c
+@@ -15,7 +15,9 @@
+ #include "qapi/qmp/types.h"
+ 
+ static const char *blacklist_x86[] = {
+-    "xenfv", "xenpv", NULL
++    "xenfv", "xenpv",
++    "rhel6.6.0", "rhel6.5.0", "rhel6.4.0", "rhel6.3.0",
++    "rhel6.2.0", "rhel6.1.0", "rhel6.0.0", NULL
+ };
+ 
+ static const struct {
+diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
+index 58a2dd9..47c21f7 100644
+--- a/tests/test-x86-cpuid-compat.c
++++ b/tests/test-x86-cpuid-compat.c
+@@ -305,6 +305,7 @@ int main(int argc, char **argv)
+                    "-cpu 486,xlevel2=0xC0000002,+xstore",
+                    "xlevel2", 0xC0000002);
+ 
++#if 0 /* Disabled in Red Hat Enterprise Linux */
+     /* Check compatibility of old machine-types that didn't
+      * auto-increase level/xlevel/xlevel2: */
+ 
+@@ -355,6 +356,7 @@ int main(int argc, char **argv)
+     add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on",
+                    "-machine pc-i440fx-2.4 -cpu SandyBridge,+npt",
+                    "xlevel", 0x80000008);
++#endif
+ 
+     /* Test feature parsing */
+     add_feature_test("x86/cpuid/features/plus",
+diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c
+index 031764d..80666d4 100644
+--- a/tests/usb-hcd-xhci-test.c
++++ b/tests/usb-hcd-xhci-test.c
+@@ -21,6 +21,7 @@ static void test_xhci_hotplug(void)
+     usb_test_hotplug("xhci", 1, NULL);
+ }
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux 7 */
+ static void test_usb_uas_hotplug(void)
+ {
+     QDict *response;
+@@ -77,6 +78,7 @@ static void test_usb_uas_hotplug(void)
+     g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
+     QDECREF(response);
+ }
++#endif
+ 
+ int main(int argc, char **argv)
+ {
+@@ -86,8 +88,9 @@ int main(int argc, char **argv)
+ 
+     qtest_add_func("/xhci/pci/init", test_xhci_init);
+     qtest_add_func("/xhci/pci/hotplug", test_xhci_hotplug);
++#if 0 /* Disabled for Red Hat Enterprise Linux 7 */
+     qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug);
+-
++#endif
+     qtest_start("-device nec-usb-xhci,id=xhci"
+                 " -drive id=drive0,if=none,file=null-co://,format=raw");
+     ret = g_test_run();
+diff --git a/vl.c b/vl.c
+index 8e247cc..a64b349 100644
+--- a/vl.c
++++ b/vl.c
+@@ -168,7 +168,7 @@ int max_cpus = 1;
+ int smp_cores = 1;
+ int smp_threads = 1;
+ int acpi_enabled = 1;
+-int no_hpet = 0;
++int no_hpet = 1; /* Always disabled for Red Hat Enterprise Linux */
+ int fd_bootchk = 1;
+ static int no_reboot;
+ int no_shutdown = 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0005-Use-kvm-by-default.patch b/SOURCES/0005-Use-kvm-by-default.patch
new file mode 100644
index 0000000..7145f04
--- /dev/null
+++ b/SOURCES/0005-Use-kvm-by-default.patch
@@ -0,0 +1,40 @@
+From eca6d5766d956c37e3f7f28d70903d357308c846 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Thu, 18 Dec 2014 06:27:49 +0100
+Subject: Use kvm by default
+
+Bugzilla: 906185
+
+RHEL uses kvm accelerator by default, if available.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Rebase notes (2.10.0)
+- variable rename (upstream)
+
+Rebase notes (2.2.0):
+- Move code from vl.c to accel.c
+
+(cherry picked from commit abcd662eb8e516ebe4a6b401e83a62f749491a15)
+---
+ accel/accel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/accel/accel.c b/accel/accel.c
+index 8ae40e1..9e757ff 100644
+--- a/accel/accel.c
++++ b/accel/accel.c
+@@ -79,8 +79,8 @@ void configure_accelerator(MachineState *ms)
+ 
+     accel = qemu_opt_get(qemu_get_machine_opts(), "accel");
+     if (accel == NULL) {
+-        /* Use the default "accelerator", tcg */
+-        accel = "tcg";
++        /* RHEL uses kvm as the default accelerator, fallback to tcg */
++        accel = "kvm:tcg";
+     }
+ 
+     p = accel;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0006-add-qxl_screendump-monitor-command.patch b/SOURCES/0006-add-qxl_screendump-monitor-command.patch
new file mode 100644
index 0000000..e723e30
--- /dev/null
+++ b/SOURCES/0006-add-qxl_screendump-monitor-command.patch
@@ -0,0 +1,188 @@
+From fd2ce5e462ee97f4538981f50e9bebc222fbe157 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 14 Mar 2017 13:21:06 +0100
+Subject: add qxl_screendump monitor command
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <1375866764-17766-2-git-send-email-kraxel@redhat.com>
+Patchwork-id: 53033
+O-Subject: [RHEL-7 qemu-kvm PATCH 1/1] add qxl_screendump monitor command
+Bugzilla: 903910
+RH-Acked-by: Hans de Goede <hdegoede@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michal Novotny <minovotn@redhat.com>
+
+This patch ports the rhel-6 specific qxl_screendump command to rhel-7.
+qxl_screendump takes the device id as additional argument and thus can
+be used to take screenshots from non-primary displays.
+
+The plan to get that functionality upstream in time failed, so we go for
+plan b and carry forward the rhel-6 specific qxl_screendump command.
+Thanks to the major console subsystem cleanups which made it upstream
+the implementation is (a) alot less hackier than the rhel-6 one and (b)
+not qxl-specific any more.  Given that qxl is the only graphic device
+which can work as secondary vga card the later is only a theoretical
+benefit though ;)
+
+RHEL-6 commit: 1c6074d107dff93c7c7b0edfb5da871504802946
+
+bugzilla: #903910 - RHEL7 does not have equivalent functionality for
+__com.redhat_qxl_screendump
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 211321c693f46d283205830c6c49b54d7250e98c)
+
+Rebase notes (2.9.0):
+- documentation moved to qapi schema
+
+Rebase notes (2.8.0):
+- qmp-commands.hx replaced by docs/qmp-commands.txt (commit bd6092e)
+- mhandler.cmd attribute renamed to cmd (commit 2b9e357)
+
+Rebase notes (2.4.0):
+- replace QERR_DEVICE_NOT_FOUND with ERROR_CLASS_DEVICE_NOT_FOUND
+
+Merged patches (2.9.0):
+- a3b59c0 HMP: Fix user manual typo of __com.redhat_qxl_screendump
+
+Merged patches (2.6.0):
+- f12846f __com.redhat_qxl_screendump: add docs
+
+(cherry picked from commit 9ff701a5129653d6bd27c0b3cc249691cb6ce6a7)
+---
+ hmp-commands.hx  | 14 ++++++++++++++
+ hmp.c            | 10 ++++++++++
+ hmp.h            |  1 +
+ qapi-schema.json | 22 ++++++++++++++++++++++
+ ui/console.c     | 24 ++++++++++++++++++++++++
+ 5 files changed, 71 insertions(+)
+
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 2d137a1..cb00a3e 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -270,6 +270,20 @@ Save screen into PPM image @var{filename}.
+ ETEXI
+ 
+     {
++        .name       = "__com.redhat_qxl_screendump",
++        .args_type  = "id:s,filename:F",
++        .params     = "id filename",
++        .help       = "save screen from qxl device 'id' into PPM image 'filename'",
++        .cmd = hmp___com_redhat_qxl_screen_dump,
++    },
++
++STEXI
++@item __com.redhat_qxl_screendump @var{id} @var{filename}
++@findex __com.redhat_qxl_screendump
++Save screen from qxl device @var{id} into PPM image @var{filename}.
++ETEXI
++
++    {
+         .name       = "logfile",
+         .args_type  = "filename:F",
+         .params     = "filename",
+diff --git a/hmp.c b/hmp.c
+index ab985c6..5b6eeba 100644
+--- a/hmp.c
++++ b/hmp.c
+@@ -2145,6 +2145,16 @@ void hmp_screendump(Monitor *mon, const QDict *qdict)
+     hmp_handle_error(mon, &err);
+ }
+ 
++void hmp___com_redhat_qxl_screen_dump(Monitor *mon, const QDict *qdict)
++{
++    const char *id = qdict_get_str(qdict, "id");
++    const char *filename = qdict_get_str(qdict, "filename");
++    Error *err = NULL;
++
++    qmp___com_redhat_qxl_screendump(id, filename, &err);
++    hmp_handle_error(mon, &err);
++}
++
+ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
+ {
+     const char *uri = qdict_get_str(qdict, "uri");
+diff --git a/hmp.h b/hmp.h
+index 1ff4552..8d9cb29 100644
+--- a/hmp.h
++++ b/hmp.h
+@@ -98,6 +98,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
+ void hmp_closefd(Monitor *mon, const QDict *qdict);
+ void hmp_sendkey(Monitor *mon, const QDict *qdict);
+ void hmp_screendump(Monitor *mon, const QDict *qdict);
++void hmp___com_redhat_qxl_screen_dump(Monitor *mon, const QDict *qdict);
+ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
+ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
+ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
+diff --git a/qapi-schema.json b/qapi-schema.json
+index 802ea53..0591d9d 100644
+--- a/qapi-schema.json
++++ b/qapi-schema.json
+@@ -4968,6 +4968,28 @@
+                                        '*logappend': 'bool' } }
+ 
+ ##
++# @__com.redhat_qxl_screendump:
++#
++# Write a PPM of secondary qxl devices to a file.
++#
++# @id: qxl device id
++# @filename: the path of a new PPM file to store the image
++#
++# Returns: Nothing on success
++#
++# Since: never (rhel-only, not upstream)
++#
++# Example:
++#
++# -> { "execute": "__com.redhat_qxl_screendump",
++#      "arguments": { "id": video1", "filename": "v1.ppm" } }
++# <- { "return": {} }
++#
++##
++{ 'command': '__com.redhat_qxl_screendump', 'data': { 'id' : 'str',
++                                                      'filename': 'str' } }
++
++##
+ # @ChardevFile:
+ #
+ # Configuration info for file chardevs.
+diff --git a/ui/console.c b/ui/console.c
+index d2d3534..2616f9c 100644
+--- a/ui/console.c
++++ b/ui/console.c
+@@ -357,6 +357,30 @@ void qmp_screendump(const char *filename, Error **errp)
+     ppm_save(filename, surface, errp);
+ }
+ 
++void qmp___com_redhat_qxl_screendump(const char *id, const char *filename, Error **errp)
++{
++    DeviceState *dev;
++    QemuConsole *con;
++    DisplaySurface *surface;
++
++    dev = qdev_find_recursive(sysbus_get_default(), id);
++    if (NULL == dev) {
++        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
++                  "Device '%s' not found", id);
++        return;
++    }
++
++    con = qemu_console_lookup_by_device(dev, 0);
++    if (con == NULL) {
++        error_setg(errp, "Device %s has no QemuConsole attached to it.", id);
++        return;
++    }
++
++    graphic_hw_update(con);
++    surface = qemu_console_surface(con);
++    ppm_save(filename, surface, errp);
++}
++
+ void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
+ {
+     if (!con) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0007-seabios-paravirt-allow-more-than-1TB-in-x86-guest.patch b/SOURCES/0007-seabios-paravirt-allow-more-than-1TB-in-x86-guest.patch
new file mode 100644
index 0000000..7cbce1d
--- /dev/null
+++ b/SOURCES/0007-seabios-paravirt-allow-more-than-1TB-in-x86-guest.patch
@@ -0,0 +1,39 @@
+From 5bbfbb1394759b58edd32134cd5c43871938dac8 Mon Sep 17 00:00:00 2001
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Tue, 8 Oct 2013 17:05:45 +0200
+Subject: seabios paravirt: allow more than 1TB in x86 guest
+
+RH-Author: Andrea Arcangeli <aarcange@redhat.com>
+Message-id: <1381251945-13402-2-git-send-email-aarcange@redhat.com>
+Patchwork-id: 54784
+O-Subject: [RHEL-7.0 qemu-kvm PATCH] seabios paravirt: allow more than 1TB in x86 guest
+Bugzilla: 989677
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Gleb Natapov <gleb@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+This patch should be applied to the qemu-kvm rpm package at the same
+time of the other one for seabios, so qemu will forward the ram_size
+bits over 40 to seabios without losing them.
+
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+(cherry picked from commit 85123a6939a536f81470ad2e8afa5a7c72584dc0)
+---
+ hw/i386/pc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index c568777..ae23fc4 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -474,6 +474,7 @@ void pc_cmos_init(PCMachineState *pcms,
+     rtc_set_memory(s, 0x5b, val);
+     rtc_set_memory(s, 0x5c, val >> 8);
+     rtc_set_memory(s, 0x5d, val >> 16);
++    rtc_set_memory(s, 0x5e, val >> 24);
+ 
+     object_property_add_link(OBJECT(pcms), "rtc_state",
+                              TYPE_ISA_DEVICE,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0008-monitor-Remove-usb_add-del-commands-for-Red-Hat-Ente.patch b/SOURCES/0008-monitor-Remove-usb_add-del-commands-for-Red-Hat-Ente.patch
new file mode 100644
index 0000000..233bde0
--- /dev/null
+++ b/SOURCES/0008-monitor-Remove-usb_add-del-commands-for-Red-Hat-Ente.patch
@@ -0,0 +1,55 @@
+From d0bc2e633e1ec0b84e437605e974bd511241a130 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Wed, 6 Nov 2013 12:36:03 +0100
+Subject: monitor: Remove usb_add/del commands for Red Hat Enterprise Linux
+
+RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
+Message-id: <daf2ca0042519cd01a6a68d30eb76bdd8b88c9f2.1383741033.git.mrezanin@redhat.com>
+Patchwork-id: 55520
+O-Subject: [RHEL7 qemu-kvm PATCH v2 3/4] monitor: Remove usb_add/del commands for Red Hat Enterprise Linux
+Bugzilla: 1010858
+RH-Acked-by: Michal Novotny <minovotn@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+
+From: Miroslav Rezanina <mrezanin@redhat.com>
+
+This is forwardport of RHEL-6 commit 754e6292b4ab41c8848171555af830ab7284f4d3:
+
+    monitor: Remove usb_add/del commands for Red Hat Enterprise Linux
+
+    The usb_add/del commands have been obsoleted by the device_add/del
+    commands.
+
+    Signed-off-by: Amit Shah <amit.shah@redhat.com>
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 23698561a70052b5d3cd376d66ec5889605e0559)
+---
+ hmp-commands.hx | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index cb00a3e..91477c5 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -683,6 +683,7 @@ STEXI
+ Compute the checksum of a memory region.
+ ETEXI
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+     {
+         .name       = "usb_add",
+         .args_type  = "devname:s",
+@@ -715,6 +716,7 @@ hub. @var{devname} has the syntax @code{bus.addr}. Use the monitor
+ command @code{info usb} to see the devices you can remove. This
+ command is deprecated, please use @code{device_del} instead.
+ ETEXI
++#endif
+ 
+     {
+         .name       = "device_add",
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0009-monitor-Remove-host_net_add-remove-for-Red-Hat-Enter.patch b/SOURCES/0009-monitor-Remove-host_net_add-remove-for-Red-Hat-Enter.patch
new file mode 100644
index 0000000..82e4c89
--- /dev/null
+++ b/SOURCES/0009-monitor-Remove-host_net_add-remove-for-Red-Hat-Enter.patch
@@ -0,0 +1,55 @@
+From ce335250360779414304856efa3488cb30393109 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Wed, 6 Nov 2013 12:36:04 +0100
+Subject: monitor: Remove host_net_add/remove for Red Hat Enterprise Linux
+
+RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
+Message-id: <b28f4458b4470c9a6fcbf5085c3a1bb4d7a0a5eb.1383741033.git.mrezanin@redhat.com>
+Patchwork-id: 55519
+O-Subject: [RHEL7 qemu-kvm PATCH v2 4/4] monitor: Remove host_net_add/remove for Red Hat Enterprise Linux
+Bugzilla: 1010858
+RH-Acked-by: Michal Novotny <minovotn@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+
+From: Miroslav Rezanina <mrezanin@redhat.com>
+
+This is forwardport of RHEL-6 commit dd94505bd1b826db0c7e155ccee5c24f77987f16:
+
+    monitor: Remove host_net_add/remove for Red Hat Enterprise Linux
+
+    The host_net_add/remove commands are replaced by netdev_add/del. Remove
+    them.
+
+    Signed-off-by: Amit Shah <amit.shah@redhat.com>
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit c9963b7cbcc5a0148ce8c29dfa4c473b27f2fd71)
+---
+ hmp-commands.hx | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 91477c5..3cd63be 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -1338,6 +1338,7 @@ STEXI
+ Inject PCIe AER error
+ ETEXI
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+     {
+         .name       = "host_net_add",
+         .args_type  = "device:s,opts:s?",
+@@ -1367,6 +1368,7 @@ STEXI
+ @findex host_net_remove
+ Remove host VLAN client. Deprecated, please use @code{netdev_del} instead.
+ ETEXI
++#endif
+ 
+     {
+         .name       = "netdev_add",
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0010-vfio-cap-number-of-devices-that-can-be-assigned.patch b/SOURCES/0010-vfio-cap-number-of-devices-that-can-be-assigned.patch
new file mode 100644
index 0000000..53fc2c2
--- /dev/null
+++ b/SOURCES/0010-vfio-cap-number-of-devices-that-can-be-assigned.patch
@@ -0,0 +1,73 @@
+From 3cb35556dc7d994f203d732fe952f95fcdb03c0a Mon Sep 17 00:00:00 2001
+From: Bandan Das <bsd@redhat.com>
+Date: Tue, 3 Dec 2013 20:05:13 +0100
+Subject: vfio: cap number of devices that can be assigned
+
+RH-Author: Bandan Das <bsd@redhat.com>
+Message-id: <1386101113-31560-3-git-send-email-bsd@redhat.com>
+Patchwork-id: 55984
+O-Subject: [PATCH RHEL7 qemu-kvm v2 2/2] vfio: cap number of devices that can be assigned
+Bugzilla: 678368
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+Go through all groups to get count of total number of devices
+active to enforce limit
+
+Reasoning from Alex for the limit(32) - Assuming 3 slots per
+device, with 125 slots (number of memory slots for RHEL 7),
+we can support almost 40 devices and still have few slots left
+for other uses. Stepping down a bit, the number 32 arbitrarily
+matches the number of slots on a PCI bus and is also a nice power
+of two.
+
+Signed-off-by: Bandan Das <bsd@redhat.com>
+
+Rebase notes (2.8.0):
+- removed return value for vfio_realize (commit 1a22aca)
+
+Merged patches (2.9.0):
+- 17eb774 vfio: Use error_setg when reporting max assigned device overshoot
+
+(cherry picked from commit 9fa3c9fc6dfcde76d80db1aa601b2d577f72ceec)
+---
+ hw/vfio/pci.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
+index 31e1edf..f3f1ce6 100644
+--- a/hw/vfio/pci.c
++++ b/hw/vfio/pci.c
+@@ -34,6 +34,7 @@
+ #include "qapi/error.h"
+ 
+ #define MSIX_CAP_LENGTH 12
++#define MAX_DEV_ASSIGN_CMDLINE 32
+ 
+ static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
+ static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
+@@ -2639,7 +2640,19 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
+     ssize_t len;
+     struct stat st;
+     int groupid;
+-    int i, ret;
++    int ret, i = 0;
++
++    QLIST_FOREACH(group, &vfio_group_list, next) {
++        QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
++            i++;
++        }
++    }
++
++    if (i >= MAX_DEV_ASSIGN_CMDLINE) {
++        error_setg(errp, "Maximum supported vfio devices (%d) "
++                     "already attached", MAX_DEV_ASSIGN_CMDLINE);
++        return;
++    }
+ 
+     if (!vdev->vbasedev.sysfsdev) {
+         if (!(~vdev->host.domain || ~vdev->host.bus ||
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0011-QMP-Forward-port-__com.redhat_drive_del-from-RHEL-6.patch b/SOURCES/0011-QMP-Forward-port-__com.redhat_drive_del-from-RHEL-6.patch
new file mode 100644
index 0000000..be47b67
--- /dev/null
+++ b/SOURCES/0011-QMP-Forward-port-__com.redhat_drive_del-from-RHEL-6.patch
@@ -0,0 +1,164 @@
+From 60b62c9d02e5e19e4cfa6eaeb6652339d4c4ede5 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Tue, 14 Mar 2017 14:03:39 +0100
+Subject: QMP: Forward-port __com.redhat_drive_del from RHEL-6
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <1387262799-10350-3-git-send-email-armbru@redhat.com>
+Patchwork-id: 56292
+O-Subject: [PATCH v2 2/6] QMP: Forward-port __com.redhat_drive_del from RHEL-6
+Bugzilla: 889051
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
+
+From: Markus Armbruster <armbru@redhat.com>
+
+Upstream has drive_del, but only in HMP.  The backport to RHEL-6 added
+it to QMP as well.  Since the QMP command is a downstream extension,
+it needs the __com.redhat_ prefix.  Since RHEL-6 doesn't have separate
+definition of QMP and HMP commands, both the QMP and the HMP command
+got the prefix.
+
+RHEL-7 inherits HMP command drive_del from upstream.  Add QMP command
+__com.redhat_drive_del for RHEL-6 compatibility.
+
+If we needed similar compatibility for the HMP command, we'd have to
+add __com.redhat_drive_del as alias for drive_del.  But we don't.
+
+Code copied from RHEL-6's qemu-monitor.hx as of
+qemu-kvm-0.12.1.2-2.418.el6.  It has a "drive_del" without the prefix
+in the documentation.  Fixed here.  Hardly worth fixing in RHEL-6 now.
+
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+
+Rebase notes (2.9.0):
+- documentation moved from docs/qmp-commands.txt to qapi/block.json
+- replace qmp_x_blockdev_del with qmp_blockdev_del (due to 79b7a77)
+
+Rebase notes (2.8.0):
+- qmp-commands.hx replaced by docs/qmp-commands.txt (commit bd6092e)
+- Changed qmp_x_blockdev_del arguments (upstream)
+
+Rebase notes (2.4.0):
+- use traditional cmd for qmp
+- remove user_print
+
+Merged patches (2.9.0):
+- 4831182 QMP: Fix forward port of __com.redhat_drive_del
+
+Merged patches (2.7.0):
+- 85786e0 Fix crash with __com.redhat_drive_del
+
+(cherry picked from commit b7a0cafd6494cd3855fe10934314b6b1d2df5d2d)
+---
+ blockdev.c      | 28 ++++++++++++++++------------
+ qapi/block.json | 23 +++++++++++++++++++++++
+ 2 files changed, 39 insertions(+), 12 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 02cd69b..d5e8ee3 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -2854,32 +2854,27 @@ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
+     return ret;
+ }
+ 
+-void hmp_drive_del(Monitor *mon, const QDict *qdict)
++void qmp___com_redhat_drive_del(const char *id, Error **errp)
+ {
+-    const char *id = qdict_get_str(qdict, "id");
+     BlockBackend *blk;
+     BlockDriverState *bs;
+     AioContext *aio_context;
+-    Error *local_err = NULL;
+ 
+     bs = bdrv_find_node(id);
+     if (bs) {
+-        qmp_blockdev_del(id, &local_err);
+-        if (local_err) {
+-            error_report_err(local_err);
+-        }
++        qmp_blockdev_del(id, errp);
+         return;
+     }
+ 
+     blk = blk_by_name(id);
+     if (!blk) {
+-        error_report("Device '%s' not found", id);
++        error_setg(errp, "Device '%s' not found", id);
+         return;
+     }
+ 
+     if (!blk_legacy_dinfo(blk)) {
+-        error_report("Deleting device added with blockdev-add"
+-                     " is not supported");
++        error_setg(errp, "Deleting device added with blockdev-add"
++                         " is not supported");
+         return;
+     }
+ 
+@@ -2888,8 +2883,7 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
+ 
+     bs = blk_bs(blk);
+     if (bs) {
+-        if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
+-            error_report_err(local_err);
++        if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, errp)) {
+             aio_context_release(aio_context);
+             return;
+         }
+@@ -2914,6 +2908,16 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
+     aio_context_release(aio_context);
+ }
+ 
++void hmp_drive_del(Monitor *mon, const QDict *qdict)
++{
++    Error *local_err = NULL;
++
++    qmp___com_redhat_drive_del(qdict_get_str(qdict, "id"), &local_err);
++    if (local_err) {
++        error_report_err(local_err);
++    }
++}
++
+ void qmp_block_resize(bool has_device, const char *device,
+                       bool has_node_name, const char *node_name,
+                       int64_t size, Error **errp)
+diff --git a/qapi/block.json b/qapi/block.json
+index 414b61b..03115d3 100644
+--- a/qapi/block.json
++++ b/qapi/block.json
+@@ -189,6 +189,29 @@
+             '*force': 'bool' } }
+ 
+ ##
++# @__com.redhat_drive_del:
++#
++# Remove host block device.
++#
++# Remove host block device.  The result is that guest generated IO is no longer
++# submitted against the host device underlying the disk.  Once a drive has
++# been deleted, the QEMU Block layer returns -EIO which results in IO
++# errors in the guest for applications that are reading/writing to the device.
++# These errors are always reported to the guest, regardless of the drive's error
++# actions (drive options rerror, werror).
++# 
++# @id: the device's ID
++#
++# Example:
++#
++# -> { "execute": "__com.redhat_drive_del", "arguments": { "id": "block1" } }
++# <- { "return": {} }
++#
++##
++{ 'command': '__com.redhat_drive_del',
++  'data': { 'id': 'str' } }
++
++##
+ # @nbd-server-start:
+ #
+ # Start an NBD server listening on the given host and port.  Block
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0012-QMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch b/SOURCES/0012-QMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch
new file mode 100644
index 0000000..aafbb94
--- /dev/null
+++ b/SOURCES/0012-QMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch
@@ -0,0 +1,227 @@
+From 5d293a214ca093a133011d0edc9039b1e71b4219 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Tue, 14 Mar 2017 14:16:45 +0100
+Subject: QMP: Forward-port __com.redhat_drive_add from RHEL-6
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <1387262799-10350-4-git-send-email-armbru@redhat.com>
+Patchwork-id: 56294
+O-Subject: [PATCH v2 3/6] QMP: Forward-port __com.redhat_drive_add from RHEL-6
+Bugzilla: 889051
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
+
+From: Markus Armbruster <armbru@redhat.com>
+
+Code taken from RHEL-6 as of qemu-kvm-0.12.1.2-2.418.el6, backported
+and fixed up as follows:
+
+* Update simple_drive_add() for commit 4e89978 "qemu-option:
+  qemu_opts_from_qdict(): use error_set()".
+
+* Update simple_drive_add() for commit 2d0d283 "Support default block
+  interfaces per QEMUMachine".
+
+* Add comment explaining drive_init() error reporting hacks to
+  simple_drive_add().
+
+* qemu-monitor.hx has been split into qmp-commands.hx and
+  hmp-commands.hx.  Copy the QMP parts to qmp-commands.hx.  Clean up
+  second example slightly.
+
+* Trailing whitespace cleaned up.
+
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+
+Rebase notes (2.9.0):
+- documentation moved from docs/qmp-commands.txt to qapi/block.json
+- added argument to qmp_register_command
+- explicit argument listing for correct documentation checking
+
+Rebase notes (2.8.0):
+- qmp-commands.hx replaced by docs/qmp-commands.txt (commit bd6092e)
+
+Rebase notes (2.6.0):
+- Added qapi/error.h to device-hotplug.c
+
+Rebase notes (2.4.0):
+- removed qerror_report
+- removed user_print
+
+Merged patches (2.9.0):
+- 599ec5f QMP: Fix forward port of __com.redhat_drive_add
+
+Merged patches (2.7.0):
+- 20af75a QMP: Relax __com.redhat_drive_add parameter checking
+
+(cherry picked from commit 6b8c0495aa317dfc5caa6d204373140811880d1a)
+---
+ device-hotplug.c          | 64 +++++++++++++++++++++++++++++++++++++++++++++++
+ include/sysemu/blockdev.h |  2 ++
+ monitor.c                 |  2 ++
+ qapi/block.json           | 45 +++++++++++++++++++++++++++++++++
+ 4 files changed, 113 insertions(+)
+
+diff --git a/device-hotplug.c b/device-hotplug.c
+index 126f73c..12c17e5 100644
+--- a/device-hotplug.c
++++ b/device-hotplug.c
+@@ -31,6 +31,10 @@
+ #include "sysemu/sysemu.h"
+ #include "monitor/monitor.h"
+ #include "block/block_int.h"
++#include "qemu/error-report.h"
++#include "qapi/qmp/qerror.h"
++#include "qapi/error.h"
++
+ 
+ static DriveInfo *add_init_drive(const char *optstr)
+ {
+@@ -89,3 +93,63 @@ err:
+         blk_unref(blk);
+     }
+ }
++
++static void check_parm(const char *key, QObject *obj, void *opaque)
++{
++    static const char *unwanted_keys[] = {
++        "bus", "unit", "index", "if", "boot", "addr",
++        NULL
++
++    };
++    int *stopped = opaque;
++    const char **p;
++
++    if (*stopped) {
++        return;
++    }
++
++    for (p = unwanted_keys; *p; p++) {
++        if (!strcmp(key, *p)) {
++            error_report(QERR_INVALID_PARAMETER, key);
++            *stopped = 1;
++            return;
++        }
++    }
++}
++
++void simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp)
++{
++    int stopped;
++    Error *local_err = NULL;
++    QemuOpts *opts;
++    DriveInfo *dinfo;
++    MachineClass *mc;
++
++    if (!qdict_haskey(qdict, "id")) {
++        error_setg(errp, QERR_MISSING_PARAMETER, "id");
++        return;
++    }
++
++    stopped = 0;
++    qdict_iter(qdict, check_parm, &stopped);
++    if (stopped) {
++        return;
++    }
++
++    opts = qemu_opts_from_qdict(&qemu_drive_opts, qdict, &local_err);
++    if (!opts) {
++        error_propagate(errp, local_err);
++        return;
++    }
++    qemu_opt_set(opts, "if", "none", &error_abort);
++    mc = MACHINE_GET_CLASS(current_machine);
++    dinfo = drive_new(opts, mc->block_default_type);
++    if (!dinfo) {
++        error_report(QERR_DEVICE_INIT_FAILED,
++                      qemu_opts_id(opts));
++        qemu_opts_del(opts);
++        return;
++    }
++
++    return;
++}
+diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
+index ac22f2a..3bda14c 100644
+--- a/include/sysemu/blockdev.h
++++ b/include/sysemu/blockdev.h
+@@ -63,4 +63,6 @@ DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
+ 
+ void hmp_commit(Monitor *mon, const QDict *qdict);
+ void hmp_drive_del(Monitor *mon, const QDict *qdict);
++
++void simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp);
+ #endif
+diff --git a/monitor.c b/monitor.c
+index de0a70e..76b8605 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -1034,6 +1034,8 @@ void monitor_init_qmp_commands(void)
+                          QCO_NO_OPTIONS);
+     qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
+                          QCO_NO_OPTIONS);
++    qmp_register_command(&qmp_commands, "__com.redhat_drive_add", simple_drive_add,
++                         QCO_NO_OPTIONS);
+ 
+     qmp_unregister_commands_hack();
+ 
+diff --git a/qapi/block.json b/qapi/block.json
+index 03115d3..2083bc7 100644
+--- a/qapi/block.json
++++ b/qapi/block.json
+@@ -212,6 +212,51 @@
+   'data': { 'id': 'str' } }
+ 
+ ##
++# @__com.redhat_drive_add:
++#
++# Create a drive similar to -drive if=none.
++#
++# @id: Drive ID, must be unique
++# @file: Disk image
++# @format: Disk format
++# @aio: How to perform asynchronous disk I/O
++# @cache: Host cache use policy
++# @cyls, "heads", "secs": Disk geometry
++# @trans: BIOS translation mode
++# @media: Media type
++# @readonly: Open image read-only
++# @rerror: What to do on read error
++# @werror: What to do on write error
++# @serial: Drive serial number
++# @snapshot: Enable snapshot mode
++# @copy-on-read: Enable copy-on-read mode
++#
++# Example:
++#
++# 1. Add a drive without medium:
++#
++# -> { "execute": "__com.redhat_drive_add", "arguments": { "id": "foo" } }
++# <- {"return": {}}
++#
++# 2. Add a drive with medium:
++#
++# -> { "execute": "__com.redhat_drive_add",
++#      "arguments": { "id": "bar", "file": "tmp.qcow2", "format": "qcow2" } }
++# <- {"return": {}}
++#
++##
++{ 'command': '__com.redhat_drive_add',
++  'data': { 'id': 'str', '*file': 'str', '*format': 'str',
++            '*aio': 'BlockdevAioOptions',
++            '*cache': 'BlockdevCacheOptions',
++            '*cyls': 'int', '*heads': 'int', '*secs': 'int',
++            '*trans': 'str', '*media': 'str',
++            '*readonly': 'bool', '*snapshot': 'bool',
++            '*rerror': 'str', '*werror': 'str',
++            '*copy-on-read': 'bool', '*serial': 'str' },
++  'gen': false }                # just to minimize porting churn
++
++##
+ # @nbd-server-start:
+ #
+ # Start an NBD server listening on the given host and port.  Block
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0013-HMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch b/SOURCES/0013-HMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch
new file mode 100644
index 0000000..4ad3e70
--- /dev/null
+++ b/SOURCES/0013-HMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch
@@ -0,0 +1,171 @@
+From 365e9ae133897df34817774c93b40ecee0821cf1 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Tue, 14 Mar 2017 14:25:44 +0100
+Subject: HMP: Forward-port __com.redhat_drive_add from RHEL-6
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <1387262799-10350-5-git-send-email-armbru@redhat.com>
+Patchwork-id: 56295
+O-Subject: [PATCH v2 4/6] HMP: Forward-port __com.redhat_drive_add from RHEL-6
+Bugzilla: 889051
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
+
+From: Markus Armbruster <armbru@redhat.com>
+
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+
+Rebase notes (2.8.0):
+- qmp-commands.hx replaced by docs/qmp-commands.txt (commit bd6092e)
+- mhandler.cmd attribute renamed to cmd (commit 2b9e357)
+
+Rebase notes (2.4.0):
+- removed user_print
+
+Merged patches (2.9.0):
+- 854d5bf Drop macro RFQDN_REDHAT (partially)
+- 4804631 HMP: Clean up botched conflict resolution in user manual
+- bb06f4 HMP: Fix documentation of __com.redhat.drive_add
+
+Merged patches (2.7.0):
+- a28dcc5 Fix crash bug in rebase of__com.redhat_drive_add
+
+(cherry picked from commit 913177df4933b58f50ba55ad2e1205b03b61fc54)
+---
+ blockdev.c                | 14 ++++++++++++++
+ device-hotplug.c          | 12 +++++++++++-
+ hmp-commands.hx           | 14 ++++++++++++++
+ include/sysemu/blockdev.h |  4 +++-
+ include/sysemu/sysemu.h   |  1 +
+ monitor.c                 |  2 +-
+ vl.c                      |  1 +
+ 7 files changed, 45 insertions(+), 3 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index d5e8ee3..e525ebf 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -4132,3 +4132,17 @@ QemuOptsList qemu_drive_opts = {
+         { /* end of list */ }
+     },
+ };
++
++QemuOptsList qemu_simple_drive_opts = {
++    .name = "simple-drive",
++    .implied_opt_name = "format",
++    .head = QTAILQ_HEAD_INITIALIZER(qemu_simple_drive_opts.head),
++    .desc = {
++        /*
++         * no elements => accept any
++         * sanity checking will happen later
++         * when setting device properties
++         */
++        { /* end if list */ }
++    }
++};
+diff --git a/device-hotplug.c b/device-hotplug.c
+index 12c17e5..218f7b3 100644
+--- a/device-hotplug.c
++++ b/device-hotplug.c
+@@ -117,7 +117,7 @@ static void check_parm(const char *key, QObject *obj, void *opaque)
+     }
+ }
+ 
+-void simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp)
++void qmp_simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp)
+ {
+     int stopped;
+     Error *local_err = NULL;
+@@ -153,3 +153,13 @@ void simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp)
+ 
+     return;
+ }
++
++void hmp_simple_drive_add(Monitor *mon, const QDict *qdict)
++{
++    Error *err = NULL;
++
++    qmp_simple_drive_add((QDict *)qdict, NULL, &err);
++    if (err) {
++        error_report_err(err);
++    }
++}
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 3cd63be..5b4cf6b 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -1315,6 +1315,20 @@ Add drive to PCI storage controller.
+ ETEXI
+ 
+     {
++        .name       = "__com.redhat_drive_add",
++        .args_type  = "simple-drive:O",
++        .params     = "id=name,[file=file][,format=f][,media=d]...",
++        .help       = "Create a drive similar to -drive if=none.",
++        .cmd = hmp_simple_drive_add,
++    },
++
++STEXI
++@item __com.redhat_drive_add
++@findex __com.redhat_drive_add
++Create a drive similar to -drive if=none.
++ETEXI
++
++    {
+         .name       = "pcie_aer_inject_error",
+         .args_type  = "advisory_non_fatal:-a,correctable:-c,"
+ 	              "id:s,error_status:s,"
+diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
+index 3bda14c..c19c36a 100644
+--- a/include/sysemu/blockdev.h
++++ b/include/sysemu/blockdev.h
+@@ -64,5 +64,7 @@ DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
+ void hmp_commit(Monitor *mon, const QDict *qdict);
+ void hmp_drive_del(Monitor *mon, const QDict *qdict);
+ 
+-void simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp);
++void hmp_simple_drive_add(Monitor *mon, const QDict *qdict);
++void qmp_simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp);
++
+ #endif
+diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
+index 9caaacf..54fdc4f 100644
+--- a/include/sysemu/sysemu.h
++++ b/include/sysemu/sysemu.h
+@@ -199,6 +199,7 @@ extern QemuOptsList qemu_legacy_drive_opts;
+ extern QemuOptsList qemu_common_drive_opts;
+ extern QemuOptsList qemu_drive_opts;
+ extern QemuOptsList bdrv_runtime_opts;
++extern QemuOptsList qemu_simple_drive_opts;
+ extern QemuOptsList qemu_chardev_opts;
+ extern QemuOptsList qemu_device_opts;
+ extern QemuOptsList qemu_netdev_opts;
+diff --git a/monitor.c b/monitor.c
+index 76b8605..bade261 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -1034,7 +1034,7 @@ void monitor_init_qmp_commands(void)
+                          QCO_NO_OPTIONS);
+     qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
+                          QCO_NO_OPTIONS);
+-    qmp_register_command(&qmp_commands, "__com.redhat_drive_add", simple_drive_add,
++    qmp_register_command(&qmp_commands, "__com.redhat_drive_add", qmp_simple_drive_add,
+                          QCO_NO_OPTIONS);
+ 
+     qmp_unregister_commands_hack();
+diff --git a/vl.c b/vl.c
+index a64b349..253da17 100644
+--- a/vl.c
++++ b/vl.c
+@@ -3054,6 +3054,7 @@ int main(int argc, char **argv, char **envp)
+     qemu_add_drive_opts(&qemu_common_drive_opts);
+     qemu_add_drive_opts(&qemu_drive_opts);
+     qemu_add_drive_opts(&bdrv_runtime_opts);
++    qemu_add_opts(&qemu_simple_drive_opts);
+     qemu_add_opts(&qemu_chardev_opts);
+     qemu_add_opts(&qemu_device_opts);
+     qemu_add_opts(&qemu_netdev_opts);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0014-Add-support-statement-to-help-output.patch b/SOURCES/0014-Add-support-statement-to-help-output.patch
new file mode 100644
index 0000000..fa43fdc
--- /dev/null
+++ b/SOURCES/0014-Add-support-statement-to-help-output.patch
@@ -0,0 +1,56 @@
+From 5dd2f4706e2fef945771949e59a8fcc1b5452de9 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Wed, 4 Dec 2013 18:53:17 +0100
+Subject: Add support statement to -help output
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <1386183197-27761-1-git-send-email-ehabkost@redhat.com>
+Patchwork-id: 55994
+O-Subject: [qemu-kvm RHEL7 PATCH] Add support statement to -help output
+Bugzilla: 972773
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: knoel@redhat.com
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Add support statement to -help output, reporting direct qemu-kvm usage
+as unsupported by Red Hat, and advising users to use libvirt instead.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 2a07700936e39856cc9f149c6a6517f0715536a6)
+---
+ vl.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/vl.c b/vl.c
+index 253da17..ff4e7f7 100644
+--- a/vl.c
++++ b/vl.c
+@@ -1927,9 +1927,17 @@ static void version(void)
+            QEMU_COPYRIGHT "\n");
+ }
+ 
++static void print_rh_warning(void)
++{
++    printf("\nWARNING: Direct use of qemu-kvm from the command line is not supported by Red Hat.\n"
++             "WARNING: Use libvirt as the stable management interface.\n"
++             "WARNING: Some command line options listed here may not be available in future releases.\n\n");
++}
++
+ static void help(int exitcode)
+ {
+     version();
++    print_rh_warning();
+     printf("usage: %s [options] [disk_image]\n\n"
+            "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
+             error_get_progname());
+@@ -1946,6 +1954,7 @@ static void help(int exitcode)
+            "\n"
+            QEMU_HELP_BOTTOM "\n");
+ 
++    print_rh_warning();
+     exit(exitcode);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0015-vl-Round-memory-sizes-below-2MiB-up-to-2MiB.patch b/SOURCES/0015-vl-Round-memory-sizes-below-2MiB-up-to-2MiB.patch
new file mode 100644
index 0000000..0b4caaf
--- /dev/null
+++ b/SOURCES/0015-vl-Round-memory-sizes-below-2MiB-up-to-2MiB.patch
@@ -0,0 +1,46 @@
+From 29e44e4e1f10ac7d2f9ac824b928518f3a2ccc10 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Mon, 7 Jul 2014 10:28:38 +0200
+Subject: vl: Round memory sizes below 2MiB up to 2MiB
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <1387459965-19517-2-git-send-email-armbru@redhat.com>
+Patchwork-id: 56389
+O-Subject: [PATCH 7.0 qemu-kvm 1/1] vl: Round memory sizes below 2MiB up to 2MiB
+Bugzilla: 999836
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Markus Armbruster <armbru@redhat.com>
+
+SeaBIOS requires at least 1MiB of RAM, but doesn't doesn't check for
+it.  It simply assumes it's there, and crashes when it isn't, often
+without any indication what's wrong.  No upstream SeaBIOS fix
+expected.
+
+In RHEL-6, we round memory sizes below 2MiB up to 2MiB to protect
+SeaBIOS (commit 551c098 and commit b9d6c40).  Do the same for RHEL-7.
+Not wanted upstream.
+
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+(cherry picked from commit 5c401c750c8e52fe5c67b4e60143a862a0d584c1)
+---
+ vl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/vl.c b/vl.c
+index ff4e7f7..59f515c 100644
+--- a/vl.c
++++ b/vl.c
+@@ -2906,6 +2906,7 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
+     }
+ 
+     sz = QEMU_ALIGN_UP(sz, 8192);
++    sz = MAX(sz, 2 * 1024 * 1024);
+     ram_size = sz;
+     if (ram_size != sz) {
+         error_report("ram size too large");
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0016-use-recommended-max-vcpu-count.patch b/SOURCES/0016-use-recommended-max-vcpu-count.patch
new file mode 100644
index 0000000..308b729
--- /dev/null
+++ b/SOURCES/0016-use-recommended-max-vcpu-count.patch
@@ -0,0 +1,42 @@
+From a1f26d85171b4d554225150053700e93ba6eba10 Mon Sep 17 00:00:00 2001
+From: Andrew Jones <drjones@redhat.com>
+Date: Tue, 21 Jan 2014 10:46:52 +0100
+Subject: use recommended max vcpu count
+
+RH-Author: Andrew Jones <drjones@redhat.com>
+Message-id: <1390301212-15344-1-git-send-email-drjones@redhat.com>
+Patchwork-id: 56862
+O-Subject: [RHEL7.0 qemu-kvm PATCH v6] use recommended max vcpu count
+Bugzilla: 998708
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
+
+The recommended vcpu max limit (KVM_CAP_NR_VCPUS) should be used instead
+of the actual max vcpu limit (KVM_CAP_MAX_VCPUS) to give an error.
+
+This matches the limit tested by QE on RHEL6: 160.
+
+Signed-off-by: Andrew Jones <drjones@redhat.com>
+(cherry picked from commit a4ceb63bdc5cbac19f5f633ec761b9de0dedb55e)
+---
+ accel/kvm/kvm-all.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
+index 46ce479..b42c56a 100644
+--- a/accel/kvm/kvm-all.c
++++ b/accel/kvm/kvm-all.c
+@@ -1627,6 +1627,9 @@ static int kvm_init(MachineState *ms)
+     soft_vcpus_limit = kvm_recommended_vcpus(s);
+     hard_vcpus_limit = kvm_max_vcpus(s);
+ 
++    /* RHEL doesn't support nr_vcpus > soft_vcpus_limit */
++    hard_vcpus_limit = soft_vcpus_limit;
++
+     while (nc->name) {
+         if (nc->num > soft_vcpus_limit) {
+             fprintf(stderr,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0017-Add-support-for-simpletrace.patch b/SOURCES/0017-Add-support-for-simpletrace.patch
new file mode 100644
index 0000000..0f76550
--- /dev/null
+++ b/SOURCES/0017-Add-support-for-simpletrace.patch
@@ -0,0 +1,118 @@
+From 2fcb1e48dc05cd801a85b70972b0a0e7182fb522 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Thu, 8 Oct 2015 09:50:17 +0200
+Subject: Add support for simpletrace
+
+As simpletrace is upstream, we just need to properly handle it during rpmbuild.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Rebase notes (2.9.0):
+- Added group argument for tracetool.py (upstream)
+
+Rebase notes (2.8.0):
+- Changed tracetool.py parameters
+
+Merged patches (2.3.0):
+- db959d6 redhat/qemu-kvm.spec.template: Install qemu-kvm-simpletrace.stp
+- 5292fc3 trace: add SystemTap init scripts for simpletrace bridge
+- eda9e5e simpletrace: install simpletrace.py
+- 85c4c8f trace: add systemtap-initscript README file to RPM
+
+(cherry picked from commit bfc1d7f3628f2ffbabbae71d57a506cea6663ddf)
+---
+ .gitignore                              |  2 ++
+ Makefile                                |  4 +++
+ README.systemtap                        | 43 +++++++++++++++++++++++++++++++++
+ redhat/qemu-kvm.spec.template           | 27 +++++++++++++++++++--
+ scripts/systemtap/conf.d/qemu_kvm.conf  |  4 +++
+ scripts/systemtap/script.d/qemu_kvm.stp |  1 +
+ 6 files changed, 79 insertions(+), 2 deletions(-)
+ create mode 100644 README.systemtap
+ create mode 100644 scripts/systemtap/conf.d/qemu_kvm.conf
+ create mode 100644 scripts/systemtap/script.d/qemu_kvm.stp
+
+diff --git a/Makefile b/Makefile
+index 2cb2442..ba31124 100644
+--- a/Makefile
++++ b/Makefile
+@@ -629,6 +629,10 @@ endif
+ 		$(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(qemu_datadir)/keymaps"; \
+ 	done
+ 	$(INSTALL_DATA) $(BUILD_DIR)/trace-events-all "$(DESTDIR)$(qemu_datadir)/trace-events-all"
++	$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/systemtap/script.d"
++	$(INSTALL_DATA) $(SRC_PATH)/scripts/systemtap/script.d/qemu_kvm.stp "$(DESTDIR)$(qemu_datadir)/systemtap/script.d/"
++	$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/systemtap/conf.d"
++	$(INSTALL_DATA) $(SRC_PATH)/scripts/systemtap/conf.d/qemu_kvm.conf "$(DESTDIR)$(qemu_datadir)/systemtap/conf.d/"
+ 	for d in $(TARGET_DIRS); do \
+ 	$(MAKE) $(SUBDIR_MAKEFLAGS) TARGET_DIR=$$d/ -C $$d $@ || exit 1 ; \
+         done
+diff --git a/README.systemtap b/README.systemtap
+new file mode 100644
+index 0000000..ad913fc
+--- /dev/null
++++ b/README.systemtap
+@@ -0,0 +1,43 @@
++QEMU tracing using systemtap-initscript
++---------------------------------------
++
++You can capture QEMU trace data all the time using systemtap-initscript.  This
++uses SystemTap's flight recorder mode to trace all running guests to a
++fixed-size buffer on the host.  Old trace entries are overwritten by new
++entries when the buffer size wraps.
++
++1. Install the systemtap-initscript package:
++  # yum install systemtap-initscript
++
++2. Install the systemtap scripts and the conf file:
++  # cp /usr/share/qemu-kvm/systemtap/script.d/qemu_kvm.stp /etc/systemtap/script.d/
++  # cp /usr/share/qemu-kvm/systemtap/conf.d/qemu_kvm.conf /etc/systemtap/conf.d/
++
++The set of trace events to enable is given in qemu_kvm.stp.  This SystemTap
++script can be customized to add or remove trace events provided in
++/usr/share/systemtap/tapset/qemu-kvm-simpletrace.stp.
++
++SystemTap customizations can be made to qemu_kvm.conf to control the flight
++recorder buffer size and whether to store traces in memory only or disk too.
++See stap(1) for option documentation.
++
++3. Start the systemtap service.
++ # service systemtap start qemu_kvm
++
++4. Make the service start at boot time.
++ # chkconfig systemtap on
++
++5. Confirm that the service works.
++  # service systemtap status qemu_kvm
++  qemu_kvm is running...
++
++When you want to inspect the trace buffer, perform the following steps:
++
++1. Dump the trace buffer.
++  # staprun -A qemu_kvm >/tmp/trace.log
++
++2. Start the systemtap service because the preceding step stops the service.
++  # service systemtap start qemu_kvm
++
++3. Translate the trace record to readable format.
++  # /usr/share/qemu-kvm/simpletrace.py --no-header /usr/share/qemu-kvm/trace-events /tmp/trace.log
+diff --git a/scripts/systemtap/conf.d/qemu_kvm.conf b/scripts/systemtap/conf.d/qemu_kvm.conf
+new file mode 100644
+index 0000000..372d816
+--- /dev/null
++++ b/scripts/systemtap/conf.d/qemu_kvm.conf
+@@ -0,0 +1,4 @@
++# Force load uprobes (see BZ#1118352)
++stap -e 'probe process("/usr/libexec/qemu-kvm").function("main") { printf("") }' -c true
++
++qemu_kvm_OPT="-s4" # per-CPU buffer size, in megabytes
+diff --git a/scripts/systemtap/script.d/qemu_kvm.stp b/scripts/systemtap/script.d/qemu_kvm.stp
+new file mode 100644
+index 0000000..c04abf9
+--- /dev/null
++++ b/scripts/systemtap/script.d/qemu_kvm.stp
+@@ -0,0 +1 @@
++probe qemu.kvm.simpletrace.handle_qmp_command,qemu.kvm.simpletrace.monitor_protocol_*,qemu.kvm.simpletrace.migrate_set_state {}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch b/SOURCES/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch
new file mode 100644
index 0000000..e3a55d6
--- /dev/null
+++ b/SOURCES/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch
@@ -0,0 +1,923 @@
+From dfa2037d390047a7d7c7b13f779443bfc6c3709d Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Fri, 14 Nov 2014 08:51:50 +0100
+Subject: Use qemu-kvm in documentation instead of qemu-system-<arch>
+
+Patchwork-id: 62380
+O-Subject: [RHEV-7.1 qemu-kvm-rhev PATCHv4] Use qemu-kvm in documentation instead of qemu-system-i386
+Bugzilla: 1140620
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Miroslav Rezanina <mrezanin@redhat.com>
+
+We change the name and location of qemu-kvm binaries. Update documentation
+to reflect this change. Only architectures available in RHEL are updated.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Rebase Notes (2.10.0):
+- Changed patch name and updated commit message.
+
+Rebase Notes (2.9.0):
+- fixed chunks missed on 2.8 rebase
+
+(cherry picked from commit 1c2dac56d5e710faebe25b7aa9cac594ec0f9d4b)
+---
+ qemu-doc.texi   | 110 ++++++++++++++++++++---------------------
+ qemu-options.hx | 148 ++++++++++++++++++++++++++++----------------------------
+ 2 files changed, 129 insertions(+), 129 deletions(-)
+
+diff --git a/qemu-doc.texi b/qemu-doc.texi
+index 9811476..da0e513 100644
+--- a/qemu-doc.texi
++++ b/qemu-doc.texi
+@@ -202,12 +202,12 @@ Note that, by default, GUS shares IRQ(7) with parallel ports and so
+ QEMU must be told to not have parallel ports to have working GUS.
+ 
+ @example
+-qemu-system-i386 dos.img -soundhw gus -parallel none
++qemu-kvm dos.img -soundhw gus -parallel none
+ @end example
+ 
+ Alternatively:
+ @example
+-qemu-system-i386 dos.img -device gus,irq=5
++qemu-kvm dos.img -device gus,irq=5
+ @end example
+ 
+ Or some other unclaimed IRQ.
+@@ -223,7 +223,7 @@ CS4231A is the chip used in Windows Sound System and GUSMAX products
+ Download and uncompress the linux image (@file{linux.img}) and type:
+ 
+ @example
+-qemu-system-i386 linux.img
++qemu-kvm linux.img
+ @end example
+ 
+ Linux should boot and give you a prompt.
+@@ -233,7 +233,7 @@ Linux should boot and give you a prompt.
+ 
+ @example
+ @c man begin SYNOPSIS
+-@command{qemu-system-i386} [@var{options}] [@var{disk_image}]
++@command{qemu-kvm} [@var{options}] [@var{disk_image}]
+ @c man end
+ @end example
+ 
+@@ -891,7 +891,7 @@ QEMU can automatically create a virtual FAT disk image from a
+ directory tree. In order to use it, just type:
+ 
+ @example
+-qemu-system-i386 linux.img -hdb fat:/my_directory
++qemu-kvm linux.img -hdb fat:/my_directory
+ @end example
+ 
+ Then you access access to all the files in the @file{/my_directory}
+@@ -901,14 +901,14 @@ them via SAMBA or NFS. The default access is @emph{read-only}.
+ Floppies can be emulated with the @code{:floppy:} option:
+ 
+ @example
+-qemu-system-i386 linux.img -fda fat:floppy:/my_directory
++qemu-kvm linux.img -fda fat:floppy:/my_directory
+ @end example
+ 
+ A read/write support is available for testing (beta stage) with the
+ @code{:rw:} option:
+ 
+ @example
+-qemu-system-i386 linux.img -fda fat:floppy:rw:/my_directory
++qemu-kvm linux.img -fda fat:floppy:rw:/my_directory
+ @end example
+ 
+ What you should @emph{never} do:
+@@ -926,14 +926,14 @@ QEMU can access directly to block device exported using the Network Block Device
+ protocol.
+ 
+ @example
+-qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
++qemu-kvm linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
+ @end example
+ 
+ If the NBD server is located on the same host, you can use an unix socket instead
+ of an inet socket:
+ 
+ @example
+-qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket
++qemu-kvm linux.img -hdb nbd+unix://?socket=/tmp/my_socket
+ @end example
+ 
+ In this case, the block device must be exported using qemu-nbd:
+@@ -950,23 +950,23 @@ qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
+ @noindent
+ and then you can use it with two guests:
+ @example
+-qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
+-qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
++qemu-kvm linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
++qemu-kvm linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
+ @end example
+ 
+ If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
+ own embedded NBD server), you must specify an export name in the URI:
+ @example
+-qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst
+-qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
++qemu-kvm -cdrom nbd://localhost/debian-500-ppc-netinst
++qemu-kvm -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
+ @end example
+ 
+ The URI syntax for NBD is supported since QEMU 1.3.  An alternative syntax is
+ also available.  Here are some example of the older syntax:
+ @example
+-qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
+-qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket
+-qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
++qemu-kvm linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
++qemu-kvm linux2.img -hdb nbd:unix:/tmp/my_socket
++qemu-kvm -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
+ @end example
+ 
+ @node disk_images_sheepdog
+@@ -991,7 +991,7 @@ qemu-img convert @var{filename} sheepdog:///@var{image}
+ 
+ You can boot from the Sheepdog disk image with the command:
+ @example
+-qemu-system-i386 sheepdog:///@var{image}
++qemu-kvm sheepdog:///@var{image}
+ @end example
+ 
+ You can also create a snapshot of the Sheepdog image like qcow2.
+@@ -1003,7 +1003,7 @@ where @var{tag} is a tag name of the newly created snapshot.
+ To boot from the Sheepdog snapshot, specify the tag name of the
+ snapshot.
+ @example
+-qemu-system-i386 sheepdog:///@var{image}#@var{tag}
++qemu-kvm sheepdog:///@var{image}#@var{tag}
+ @end example
+ 
+ You can create a cloned image from the existing snapshot.
+@@ -1016,14 +1016,14 @@ is its tag name.
+ You can use an unix socket instead of an inet socket:
+ 
+ @example
+-qemu-system-i386 sheepdog+unix:///@var{image}?socket=@var{path}
++qemu-kvm sheepdog+unix:///@var{image}?socket=@var{path}
+ @end example
+ 
+ If the Sheepdog daemon doesn't run on the local host, you need to
+ specify one of the Sheepdog servers to connect to.
+ @example
+ qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
+-qemu-system-i386 sheepdog://@var{hostname}:@var{port}/@var{image}
++qemu-kvm sheepdog://@var{hostname}:@var{port}/@var{image}
+ @end example
+ 
+ @node disk_images_iscsi
+@@ -1065,7 +1065,7 @@ Various session related parameters can be set via special options, either
+ in a configuration file provided via '-readconfig' or directly on the
+ command line.
+ 
+-If the initiator-name is not specified qemu will use a default name
++If the initiator-name is not specified qemu-kvm will use a default name
+ of 'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
+ virtual machine.
+ 
+@@ -1112,7 +1112,7 @@ cat >iscsi.conf <<EOF
+   header-digest = "CRC32C"
+ EOF
+ 
+-qemu-system-i386 -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
++qemu-kvm -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
+     -readconfig iscsi.conf
+ @end example
+ 
+@@ -1131,7 +1131,7 @@ tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
+     -b /IMAGES/cd.iso --device-type=cd
+ tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
+ 
+-qemu-system-i386 -iscsi initiator-name=iqn.qemu.test:my-initiator \
++qemu-kvm -iscsi initiator-name=iqn.qemu.test:my-initiator \
+     -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
+     -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
+ @end example
+@@ -1144,11 +1144,11 @@ GlusterFS is a user space distributed file system.
+ You can boot from the GlusterFS disk image with the command:
+ @example
+ URI:
+-qemu-system-x86_64 -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
++qemu-kvm -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
+                                [?socket=...][,file.debug=9][,file.logfile=...]
+ 
+ JSON:
+-qemu-system-x86_64 'json:@{"driver":"qcow2",
++qemu-kvm 'json:@{"driver":"qcow2",
+                            "file":@{"driver":"gluster",
+                                     "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
+                                     "server":[@{"type":"tcp","host":"...","port":"..."@},
+@@ -1196,22 +1196,22 @@ qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
+ 
+ Examples
+ @example
+-qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img
+-qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4/testvol/a.img
+-qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
+-qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
+-qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
+-qemu-system-x86_64 -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
+-qemu-system-x86_64 -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
+-qemu-system-x86_64 -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
+-qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
+-qemu-system-x86_64 'json:@{"driver":"qcow2",
++qemu-kvm -drive file=gluster://1.2.3.4/testvol/a.img
++qemu-kvm -drive file=gluster+tcp://1.2.3.4/testvol/a.img
++qemu-kvm -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
++qemu-kvm -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
++qemu-kvm -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
++qemu-kvm -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
++qemu-kvm -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
++qemu-kvm -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
++qemu-kvm -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
++qemu-kvm 'json:@{"driver":"qcow2",
+                            "file":@{"driver":"gluster",
+                                     "volume":"testvol","path":"a.img",
+                                     "debug":9,"logfile":"/var/log/qemu-gluster.log",
+                                     "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
+                                               @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
+-qemu-system-x86_64 -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
++qemu-kvm -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
+                                        file.debug=9,file.logfile=/var/log/qemu-gluster.log,
+                                        file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
+                                        file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
+@@ -1224,13 +1224,13 @@ You can access disk images located on a remote ssh server
+ by using the ssh protocol:
+ 
+ @example
+-qemu-system-x86_64 -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
++qemu-kvm -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
+ @end example
+ 
+ Alternative syntax using properties:
+ 
+ @example
+-qemu-system-x86_64 -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
++qemu-kvm -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
+ @end example
+ 
+ @var{ssh} is the protocol.
+@@ -1372,7 +1372,7 @@ On Linux hosts, a shared memory device is available.  The basic syntax
+ is:
+ 
+ @example
+-qemu-system-x86_64 -device ivshmem-plain,memdev=@var{hostmem}
++qemu-kvm -device ivshmem-plain,memdev=@var{hostmem}
+ @end example
+ 
+ where @var{hostmem} names a host memory backend.  For a POSIX shared
+@@ -1393,7 +1393,7 @@ memory server is:
+ ivshmem-server -p @var{pidfile} -S @var{path} -m @var{shm-name} -l @var{shm-size} -n @var{vectors}
+ 
+ # Then start your qemu instances with matching arguments
+-qemu-system-x86_64 -device ivshmem-doorbell,vectors=@var{vectors},chardev=@var{id}
++qemu-kvm -device ivshmem-doorbell,vectors=@var{vectors},chardev=@var{id}
+                  -chardev socket,path=@var{path},id=@var{id}
+ @end example
+ 
+@@ -1418,7 +1418,7 @@ Instead of specifying the <shm size> using POSIX shm, you may specify
+ a memory backend that has hugepage support:
+ 
+ @example
+-qemu-system-x86_64 -object memory-backend-file,size=1G,mem-path=/dev/hugepages/my-shmem-file,share,id=mb1
++qemu-kvm -object memory-backend-file,size=1G,mem-path=/dev/hugepages/my-shmem-file,share,id=mb1
+                  -device ivshmem-plain,memdev=mb1
+ @end example
+ 
+@@ -1434,7 +1434,7 @@ kernel testing.
+ 
+ The syntax is:
+ @example
+-qemu-system-i386 -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda"
++qemu-kvm -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda"
+ @end example
+ 
+ Use @option{-kernel} to provide the Linux kernel image and
+@@ -1449,7 +1449,7 @@ If you do not need graphical output, you can disable it and redirect
+ the virtual serial port and the QEMU monitor to the console with the
+ @option{-nographic} option. The typical command line is:
+ @example
+-qemu-system-i386 -kernel arch/i386/boot/bzImage -hda root-2.4.20.img \
++qemu-kvm -kernel arch/i386/boot/bzImage -hda root-2.4.20.img \
+                  -append "root=/dev/hda console=ttyS0" -nographic
+ @end example
+ 
+@@ -1515,7 +1515,7 @@ Network adapter that supports CDC ethernet and RNDIS protocols.  @var{id}
+ specifies a netdev defined with @code{-netdev @dots{},id=@var{id}}.
+ For instance, user-mode networking can be used with
+ @example
+-qemu-system-i386 [...] -netdev user,id=net0 -device usb-net,netdev=net0
++qemu-kvm [...] -netdev user,id=net0 -device usb-net,netdev=net0
+ @end example
+ @item usb-ccid
+ Smartcard reader device
+@@ -1534,7 +1534,7 @@ no type is given, the HCI logic corresponds to @code{-bt hci,vlan=0}.
+ This USB device implements the USB Transport Layer of HCI.  Example
+ usage:
+ @example
+-@command{qemu-system-i386} [...@var{OPTIONS}...] @option{-usbdevice} bt:hci,vlan=3 @option{-bt} device:keyboard,vlan=3
++@command{qemu-kvm} [...@var{OPTIONS}...] @option{-usbdevice} bt:hci,vlan=3 @option{-bt} device:keyboard,vlan=3
+ @end example
+ @end table
+ 
+@@ -1612,7 +1612,7 @@ For this setup it is recommended to restrict it to listen on a UNIX domain
+ socket only. For example
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc unix:/home/joebloggs/.qemu-myvm-vnc
++qemu-kvm [...OPTIONS...] -vnc unix:/home/joebloggs/.qemu-myvm-vnc
+ @end example
+ 
+ This ensures that only users on local box with read/write access to that
+@@ -1635,7 +1635,7 @@ is running the password is set with the monitor. Until the monitor is used to
+ set the password all clients will be rejected.
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc :1,password -monitor stdio
++qemu-kvm [...OPTIONS...] -vnc :1,password -monitor stdio
+ (qemu) change vnc password
+ Password: ********
+ (qemu)
+@@ -1652,7 +1652,7 @@ support provides a secure session, but no authentication. This allows any
+ client to connect, and provides an encrypted session.
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509=/etc/pki/qemu -monitor stdio
++qemu-kvm [...OPTIONS...] -vnc :1,tls,x509=/etc/pki/qemu -monitor stdio
+ @end example
+ 
+ In the above example @code{/etc/pki/qemu} should contain at least three files,
+@@ -1670,7 +1670,7 @@ then validate against the CA certificate. This is a good choice if deploying
+ in an environment with a private internal certificate authority.
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509verify=/etc/pki/qemu -monitor stdio
++qemu-kvm [...OPTIONS...] -vnc :1,tls,x509verify=/etc/pki/qemu -monitor stdio
+ @end example
+ 
+ 
+@@ -1681,7 +1681,7 @@ Finally, the previous method can be combined with VNC password authentication
+ to provide two layers of authentication for clients.
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc :1,password,tls,x509verify=/etc/pki/qemu -monitor stdio
++qemu-kvm [...OPTIONS...] -vnc :1,password,tls,x509verify=/etc/pki/qemu -monitor stdio
+ (qemu) change vnc password
+ Password: ********
+ (qemu)
+@@ -1704,7 +1704,7 @@ used for authentication, but assuming use of one supporting SSF,
+ then QEMU can be launched with:
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc :1,sasl -monitor stdio
++qemu-kvm [...OPTIONS...] -vnc :1,sasl -monitor stdio
+ @end example
+ 
+ @node vnc_sec_certificate_sasl
+@@ -1718,7 +1718,7 @@ credentials. This can be enabled, by combining the 'sasl' option
+ with the aforementioned TLS + x509 options:
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
++qemu-kvm [...OPTIONS...] -vnc :1,tls,x509,sasl -monitor stdio
+ @end example
+ 
+ 
+@@ -1894,7 +1894,7 @@ QEMU has a primitive support to work with gdb, so that you can do
+ In order to use gdb, launch QEMU with the '-s' option. It will wait for a
+ gdb connection:
+ @example
+-qemu-system-i386 -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img \
++qemu-kvm -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img \
+                     -append "root=/dev/hda"
+ Connected to host network interface: tun0
+ Waiting gdb connection on port 1234
+@@ -2076,7 +2076,7 @@ differences are mentioned in the following sections.
+ @section PowerPC System emulator
+ @cindex system emulation (PowerPC)
+ 
+-Use the executable @file{qemu-system-ppc} to simulate a complete PREP
++Use the executable @file{qemu-kvm} to simulate a complete PREP
+ or PowerMac PowerPC system.
+ 
+ QEMU emulates the following PowerMac peripherals:
+@@ -2140,7 +2140,7 @@ Set the initial VGA graphic mode. The default is 800x600x32.
+ Set OpenBIOS variables in NVRAM, for example:
+ 
+ @example
+-qemu-system-ppc -prom-env 'auto-boot?=false' \
++qemu-kvm -prom-env 'auto-boot?=false' \
+  -prom-env 'boot-device=hd:2,\yaboot' \
+  -prom-env 'boot-args=conf=hd:2,\yaboot.conf'
+ @end example
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 568fc7c..5220120 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -252,7 +252,7 @@ This option defines a free-form string that can be used to describe @var{fd}.
+ 
+ You can open an image using pre-opened file descriptors from an fd set:
+ @example
+-qemu-system-i386
++qemu-kvm
+ -add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
+ -add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
+ -drive file=/dev/fdset/2,index=0,media=disk
+@@ -281,7 +281,7 @@ STEXI
+ Set default value of @var{driver}'s property @var{prop} to @var{value}, e.g.:
+ 
+ @example
+-qemu-system-i386 -global ide-hd.physical_block_size=4096 disk-image.img
++qemu-kvm -global ide-hd.physical_block_size=4096 disk-image.img
+ @end example
+ 
+ In particular, you can use this to set driver properties for devices which are 
+@@ -326,7 +326,7 @@ the recommended is 320x240, 640x480, 800x640.
+ 
+ A timeout could be passed to bios, guest will pause for @var{rb_timeout} ms
+ when boot failed, then reboot. If @var{rb_timeout} is '-1', guest will not
+-reboot, qemu passes '-1' to bios by default. Currently Seabios for X86
++reboot, qemu-kvm passes '-1' to bios by default. Currently Seabios for X86
+ system support it.
+ 
+ Do strict boot via @option{strict=on} as far as firmware/BIOS
+@@ -335,11 +335,11 @@ bootindex options. The default is non-strict boot.
+ 
+ @example
+ # try to boot from network first, then from hard disk
+-qemu-system-i386 -boot order=nc
++qemu-kvm -boot order=nc
+ # boot from CD-ROM first, switch back to default order after reboot
+-qemu-system-i386 -boot once=d
++qemu-kvm -boot once=d
+ # boot with a splash picture for 5 seconds.
+-qemu-system-i386 -boot menu=on,splash=/root/boot.bmp,splash-time=5000
++qemu-kvm -boot menu=on,splash=/root/boot.bmp,splash-time=5000
+ @end example
+ 
+ Note: The legacy format '-boot @var{drives}' is still supported but its
+@@ -368,7 +368,7 @@ For example, the following command-line sets the guest startup RAM size to
+ memory the guest can reach to 4GB:
+ 
+ @example
+-qemu-system-x86_64 -m 1G,slots=3,maxmem=4G
++qemu-kvm -m 1G,slots=3,maxmem=4G
+ @end example
+ 
+ If @var{slots} and @var{maxmem} are not specified, memory hotplug won't
+@@ -437,12 +437,12 @@ Enable audio and selected sound hardware. Use 'help' to print all
+ available sound hardware.
+ 
+ @example
+-qemu-system-i386 -soundhw sb16,adlib disk.img
+-qemu-system-i386 -soundhw es1370 disk.img
+-qemu-system-i386 -soundhw ac97 disk.img
+-qemu-system-i386 -soundhw hda disk.img
+-qemu-system-i386 -soundhw all disk.img
+-qemu-system-i386 -soundhw help
++qemu-kvm -soundhw sb16,adlib disk.img
++qemu-kvm -soundhw es1370 disk.img
++qemu-kvm -soundhw ac97 disk.img
++qemu-kvm -soundhw hda disk.img
++qemu-kvm -soundhw all disk.img
++qemu-kvm -soundhw help
+ @end example
+ 
+ Note that Linux's i810_audio OSS kernel (for AC97) module might
+@@ -934,21 +934,21 @@ is off.
+ 
+ Instead of @option{-cdrom} you can use:
+ @example
+-qemu-system-i386 -drive file=file,index=2,media=cdrom
++qemu-kvm -drive file=file,index=2,media=cdrom
+ @end example
+ 
+ Instead of @option{-hda}, @option{-hdb}, @option{-hdc}, @option{-hdd}, you can
+ use:
+ @example
+-qemu-system-i386 -drive file=file,index=0,media=disk
+-qemu-system-i386 -drive file=file,index=1,media=disk
+-qemu-system-i386 -drive file=file,index=2,media=disk
+-qemu-system-i386 -drive file=file,index=3,media=disk
++qemu-kvm -drive file=file,index=0,media=disk
++qemu-kvm -drive file=file,index=1,media=disk
++qemu-kvm -drive file=file,index=2,media=disk
++qemu-kvm -drive file=file,index=3,media=disk
+ @end example
+ 
+ You can open an image using pre-opened file descriptors from an fd set:
+ @example
+-qemu-system-i386
++qemu-kvm
+ -add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
+ -add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
+ -drive file=/dev/fdset/2,index=0,media=disk
+@@ -956,28 +956,28 @@ qemu-system-i386
+ 
+ You can connect a CDROM to the slave of ide0:
+ @example
+-qemu-system-i386 -drive file=file,if=ide,index=1,media=cdrom
++qemu-kvm -drive file=file,if=ide,index=1,media=cdrom
+ @end example
+ 
+ If you don't specify the "file=" argument, you define an empty drive:
+ @example
+-qemu-system-i386 -drive if=ide,index=1,media=cdrom
++qemu-kvm -drive if=ide,index=1,media=cdrom
+ @end example
+ 
+ Instead of @option{-fda}, @option{-fdb}, you can use:
+ @example
+-qemu-system-i386 -drive file=file,index=0,if=floppy
+-qemu-system-i386 -drive file=file,index=1,if=floppy
++qemu-kvm -drive file=file,index=0,if=floppy
++qemu-kvm -drive file=file,index=1,if=floppy
+ @end example
+ 
+ By default, @var{interface} is "ide" and @var{index} is automatically
+ incremented:
+ @example
+-qemu-system-i386 -drive file=a -drive file=b"
++qemu-kvm -drive file=a -drive file=b"
+ @end example
+ is interpreted like:
+ @example
+-qemu-system-i386 -hda a -hdb b
++qemu-kvm -hda a -hdb b
+ @end example
+ ETEXI
+ 
+@@ -2115,7 +2115,7 @@ can not be resolved.
+ 
+ Example:
+ @example
+-qemu -net user,dnssearch=mgmt.example.org,dnssearch=example.org [...]
++qemu-kvm -net user,dnssearch=mgmt.example.org,dnssearch=example.org [...]
+ @end example
+ 
+ @item tftp=@var{dir}
+@@ -2131,7 +2131,7 @@ a guest from a local directory.
+ 
+ Example (using pxelinux):
+ @example
+-qemu-system-i386 -hda linux.img -boot n -net user,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
++qemu-kvm -hda linux.img -boot n -net user,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
+ @end example
+ 
+ @item smb=@var{dir}[,smbserver=@var{addr}]
+@@ -2166,7 +2166,7 @@ screen 0, use the following:
+ 
+ @example
+ # on the host
+-qemu-system-i386 -net user,hostfwd=tcp:127.0.0.1:6001-:6000 [...]
++qemu-kvm -net user,hostfwd=tcp:127.0.0.1:6001-:6000 [...]
+ # this host xterm should open in the guest X11 server
+ xterm -display :1
+ @end example
+@@ -2176,7 +2176,7 @@ the guest, use the following:
+ 
+ @example
+ # on the host
+-qemu-system-i386 -net user,hostfwd=tcp::5555-:23 [...]
++qemu-kvm -net user,hostfwd=tcp::5555-:23 [...]
+ telnet localhost 5555
+ @end example
+ 
+@@ -2195,7 +2195,7 @@ lifetime, like in the following example:
+ @example
+ # open 10.10.1.1:4321 on bootup, connect 10.0.2.100:1234 to it whenever
+ # the guest accesses it
+-qemu -net user,guestfwd=tcp:10.0.2.100:1234-tcp:10.10.1.1:4321 [...]
++qemu-kvm -net user,guestfwd=tcp:10.0.2.100:1234-tcp:10.10.1.1:4321 [...]
+ @end example
+ 
+ Or you can execute a command on every TCP connection established by the guest,
+@@ -2204,7 +2204,7 @@ so that QEMU behaves similar to an inetd process for that virtual server:
+ @example
+ # call "netcat 10.10.1.1 4321" on every TCP connection to 10.0.2.100:1234
+ # and connect the TCP stream to its stdin/stdout
+-qemu -net 'user,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10.1.1 4321'
++qemu-kvm -net 'user,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10.1.1 4321'
+ @end example
+ 
+ @end table
+@@ -2237,13 +2237,13 @@ Examples:
+ 
+ @example
+ #launch a QEMU instance with the default network script
+-qemu-system-i386 linux.img -net nic -net tap
++qemu-kvm linux.img -net nic -net tap
+ @end example
+ 
+ @example
+ #launch a QEMU instance with two NICs, each one connected
+ #to a TAP device
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
+                  -net nic,vlan=1 -net tap,vlan=1,ifname=tap1
+ @end example
+@@ -2251,7 +2251,7 @@ qemu-system-i386 linux.img \
+ @example
+ #launch a QEMU instance with the default network helper to
+ #connect a TAP device to bridge br0
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic -net tap,"helper=/path/to/qemu-bridge-helper"
+ @end example
+ 
+@@ -2269,13 +2269,13 @@ Examples:
+ @example
+ #launch a QEMU instance with the default network helper to
+ #connect a TAP device to bridge br0
+-qemu-system-i386 linux.img -net bridge -net nic,model=virtio
++qemu-kvm linux.img -net bridge -net nic,model=virtio
+ @end example
+ 
+ @example
+ #launch a QEMU instance with the default network helper to
+ #connect a TAP device to bridge qemubr0
+-qemu-system-i386 linux.img -net bridge,br=qemubr0 -net nic,model=virtio
++qemu-kvm linux.img -net bridge,br=qemubr0 -net nic,model=virtio
+ @end example
+ 
+ @item -netdev socket,id=@var{id}[,fd=@var{h}][,listen=[@var{host}]:@var{port}][,connect=@var{host}:@var{port}]
+@@ -2291,12 +2291,12 @@ specifies an already opened TCP socket.
+ Example:
+ @example
+ # launch a first QEMU instance
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:56 \
+                  -net socket,listen=:1234
+ # connect the VLAN 0 of this instance to the VLAN 0
+ # of the first instance
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:57 \
+                  -net socket,connect=127.0.0.1:1234
+ @end example
+@@ -2322,15 +2322,15 @@ Use @option{fd=h} to specify an already opened UDP multicast socket.
+ Example:
+ @example
+ # launch one QEMU instance
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:56 \
+                  -net socket,mcast=230.0.0.1:1234
+ # launch another QEMU instance on same "bus"
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:57 \
+                  -net socket,mcast=230.0.0.1:1234
+ # launch yet another QEMU instance on same "bus"
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:58 \
+                  -net socket,mcast=230.0.0.1:1234
+ @end example
+@@ -2339,7 +2339,7 @@ Example (User Mode Linux compat.):
+ @example
+ # launch QEMU instance (note mcast address selected
+ # is UML's default)
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:56 \
+                  -net socket,mcast=239.192.168.1:1102
+ # launch UML
+@@ -2348,7 +2348,7 @@ qemu-system-i386 linux.img \
+ 
+ Example (send packets from host's 1.2.3.4):
+ @example
+-qemu-system-i386 linux.img \
++qemu-kvm linux.img \
+                  -net nic,macaddr=52:54:00:12:34:56 \
+                  -net socket,mcast=239.192.168.1:1102,localaddr=1.2.3.4
+ @end example
+@@ -2407,7 +2407,7 @@ brctl addif br-lan vmtunnel0
+ # on 4.3.2.1
+ # launch QEMU instance - if your network has reorder or is very lossy add ,pincounter
+ 
+-qemu-system-i386 linux.img -net nic -net l2tpv3,src=4.2.3.1,dst=1.2.3.4,udp,srcport=16384,dstport=16384,rxsession=0xffffffff,txsession=0xffffffff,counter
++qemu-kvm linux.img -net nic -net l2tpv3,src=4.2.3.1,dst=1.2.3.4,udp,srcport=16384,dstport=16384,rxsession=0xffffffff,txsession=0xffffffff,counter
+ 
+ 
+ @end example
+@@ -2425,7 +2425,7 @@ Example:
+ # launch vde switch
+ vde_switch -F -sock /tmp/myswitch
+ # launch QEMU instance
+-qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
++qemu-kvm linux.img -net nic -net vde,sock=/tmp/myswitch
+ @end example
+ 
+ @item -netdev hubport,id=@var{id},hubid=@var{hubid}
+@@ -2447,11 +2447,11 @@ be created for multiqueue vhost-user.
+ 
+ Example:
+ @example
+-qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
+-     -numa node,memdev=mem \
+-     -chardev socket,id=chr0,path=/path/to/socket \
+-     -netdev type=vhost-user,id=net0,chardev=chr0 \
+-     -device virtio-net-pci,netdev=net0
++qemu-kvm -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
++         -numa node,memdev=mem \
++         -chardev socket,id=chr0,path=/path/to/socket \
++         -netdev type=vhost-user,id=net0,chardev=chr0 \
++         -device virtio-net-pci,netdev=net0
+ @end example
+ 
+ @item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
+@@ -2819,7 +2819,7 @@ images for the guest storage. Both disk and cdrom images are supported.
+ Syntax for specifying iSCSI LUNs is
+ ``iscsi://<target-ip>[:<port>]/<target-iqn>/<lun>''
+ 
+-By default qemu will use the iSCSI initiator-name
++By default qemu-kvm will use the iSCSI initiator-name
+ 'iqn.2008-11.org.linux-kvm[:<name>]' but this can also be set from the command
+ line or a configuration file.
+ 
+@@ -2830,21 +2830,21 @@ is specified in seconds. The default is 0 which means no timeout. Libiscsi
+ 
+ Example (without authentication):
+ @example
+-qemu-system-i386 -iscsi initiator-name=iqn.2001-04.com.example:my-initiator \
++qemu-kvm -iscsi initiator-name=iqn.2001-04.com.example:my-initiator \
+                  -cdrom iscsi://192.0.2.1/iqn.2001-04.com.example/2 \
+                  -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
+ @end example
+ 
+ Example (CHAP username/password via URL):
+ @example
+-qemu-system-i386 -drive file=iscsi://user%password@@192.0.2.1/iqn.2001-04.com.example/1
++qemu-kvm -drive file=iscsi://user%password@@192.0.2.1/iqn.2001-04.com.example/1
+ @end example
+ 
+ Example (CHAP username/password via environment variables):
+ @example
+ LIBISCSI_CHAP_USERNAME="user" \
+ LIBISCSI_CHAP_PASSWORD="password" \
+-qemu-system-i386 -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
++qemu-kvm -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
+ @end example
+ 
+ iSCSI support is an optional feature of QEMU and only available when
+@@ -2874,12 +2874,12 @@ Syntax for specifying a NBD device using Unix Domain Sockets
+ 
+ Example for TCP
+ @example
+-qemu-system-i386 --drive file=nbd:192.0.2.1:30000
++qemu-kvm --drive file=nbd:192.0.2.1:30000
+ @end example
+ 
+ Example for Unix Domain Sockets
+ @example
+-qemu-system-i386 --drive file=nbd:unix:/tmp/nbd-socket
++qemu-kvm --drive file=nbd:unix:/tmp/nbd-socket
+ @end example
+ 
+ @item SSH
+@@ -2887,8 +2887,8 @@ QEMU supports SSH (Secure Shell) access to remote disks.
+ 
+ Examples:
+ @example
+-qemu-system-i386 -drive file=ssh://user@@host/path/to/disk.img
+-qemu-system-i386 -drive file.driver=ssh,file.user=user,file.host=host,file.port=22,file.path=/path/to/disk.img
++qemu-kvm -drive file=ssh://user@@host/path/to/disk.img
++qemu-kvm -drive file.driver=ssh,file.user=user,file.host=host,file.port=22,file.path=/path/to/disk.img
+ @end example
+ 
+ Currently authentication must be done using ssh-agent.  Other
+@@ -2906,7 +2906,7 @@ sheepdog[+tcp|+unix]://[host:port]/vdiname[?socket=path][#snapid|#tag]
+ 
+ Example
+ @example
+-qemu-system-i386 --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
++qemu-kvm --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
+ @end example
+ 
+ See also @url{https://sheepdog.github.io/sheepdog/}.
+@@ -2932,17 +2932,17 @@ JSON:
+ Example
+ @example
+ URI:
+-qemu-system-x86_64 --drive file=gluster://192.0.2.1/testvol/a.img,
++qemu-kvm --drive file=gluster://192.0.2.1/testvol/a.img,
+ @                               file.debug=9,file.logfile=/var/log/qemu-gluster.log
+ 
+ JSON:
+-qemu-system-x86_64 'json:@{"driver":"qcow2",
++qemu-kvm 'json:@{"driver":"qcow2",
+ @                          "file":@{"driver":"gluster",
+ @                                   "volume":"testvol","path":"a.img",
+ @                                   "debug":9,"logfile":"/var/log/qemu-gluster.log",
+ @                                   "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
+ @                                             @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
+-qemu-system-x86_64 -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
++qemu-kvm -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
+ @                                      file.debug=9,file.logfile=/var/log/qemu-gluster.log,
+ @                                      file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
+ @                                      file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
+@@ -3002,14 +3002,14 @@ that CURL waits for a response from the remote server to get the size of the
+ image to be downloaded. If not set, the default timeout of 5 seconds is used.
+ @end table
+ 
+-Note that when passing options to qemu explicitly, @option{driver} is the value
++Note that when passing options to qemu-kvm explicitly, @option{driver} is the value
+ of <protocol>.
+ 
+ Example: boot from a remote Fedora 20 live ISO image
+ @example
+-qemu-system-x86_64 --drive media=cdrom,file=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
++qemu-kvm --drive media=cdrom,file=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
+ 
+-qemu-system-x86_64 --drive media=cdrom,file.driver=http,file.url=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
++qemu-kvm --drive media=cdrom,file.driver=http,file.url=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
+ @end example
+ 
+ Example: boot from a remote Fedora 20 cloud image using a local overlay for
+@@ -3017,7 +3017,7 @@ writes, copy-on-read, and a readahead of 64k
+ @example
+ qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"http",, "file.url":"https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2",, "file.readahead":"64k"@}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
+ 
+-qemu-system-x86_64 -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-on-read=on
++qemu-kvm -drive file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-on-read=on
+ @end example
+ 
+ Example: boot from an image stored on a VMware vSphere server with a self-signed
+@@ -3026,7 +3026,7 @@ of 10 seconds.
+ @example
+ qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"https",, "file.url":"https://user:password@@vsphere.example.com/folder/test/test-flat.vmdk?dcPath=Datacenter&dsName=datastore1",, "file.sslverify":"off",, "file.readahead":"64k",, "file.timeout":10@}' /tmp/test.qcow2
+ 
+-qemu-system-x86_64 -drive file=/tmp/test.qcow2
++qemu-kvm -drive file=/tmp/test.qcow2
+ @end example
+ ETEXI
+ 
+@@ -3090,7 +3090,7 @@ and communicate.  Requires the Linux @code{vhci} driver installed.  Can
+ be used as following:
+ 
+ @example
+-qemu-system-i386 [...OPTIONS...] -bt hci,vlan=5 -bt vhci,vlan=5
++qemu-kvm [...OPTIONS...] -bt hci,vlan=5 -bt vhci,vlan=5
+ @end example
+ 
+ @item -bt device:@var{dev}[,vlan=@var{n}]
+@@ -3136,7 +3136,7 @@ Options to each backend are described below.
+ 
+ Use 'help' to print all available TPM backend types.
+ @example
+-qemu -tpmdev help
++qemu-kvm -tpmdev help
+ @end example
+ 
+ @item -tpmdev passthrough, id=@var{id}, path=@var{path}, cancel-path=@var{cancel-path}
+@@ -3504,14 +3504,14 @@ ETEXI
+ 
+ DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
+     "-realtime [mlock=on|off]\n"
+-    "                run qemu with realtime features\n"
++    "                run qemu-kvm with realtime features\n"
+     "                mlock=on|off controls mlock support (default: on)\n",
+     QEMU_ARCH_ALL)
+ STEXI
+ @item -realtime mlock=on|off
+ @findex -realtime
+-Run qemu with realtime features.
+-mlocking qemu and guest memory can be enabled via @option{mlock=on}
++Run qemu-kvm with realtime features.
++mlocking qemu-kvm and guest memory can be enabled via @option{mlock=on}
+ (enabled by default).
+ ETEXI
+ 
+@@ -3525,7 +3525,7 @@ connections will likely be TCP-based, but also UDP, pseudo TTY, or even
+ stdio are reasonable use case. The latter is allowing to start QEMU from
+ within gdb and establish the connection via a pipe:
+ @example
+-(gdb) target remote | exec qemu-system-i386 -gdb stdio ...
++(gdb) target remote | exec qemu-kvm -gdb stdio ...
+ @end example
+ ETEXI
+ 
+@@ -4340,7 +4340,7 @@ which specify the queue number of cryptodev backend, the default of
+ 
+ @example
+ 
+- # qemu-system-x86_64 \
++ # qemu-kvm \
+    [...] \
+        -object cryptodev-backend-builtin,id=cryptodev0 \
+        -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0019-qmp-add-__com.redhat_reason-to-the-BLOCK_IO_ERROR-ev.patch b/SOURCES/0019-qmp-add-__com.redhat_reason-to-the-BLOCK_IO_ERROR-ev.patch
new file mode 100644
index 0000000..891eeec
--- /dev/null
+++ b/SOURCES/0019-qmp-add-__com.redhat_reason-to-the-BLOCK_IO_ERROR-ev.patch
@@ -0,0 +1,162 @@
+From e2bf476c86cf5697ef3ea6aab2249aa85b8be2cd Mon Sep 17 00:00:00 2001
+From: Luiz Capitulino <lcapitulino@redhat.com>
+Date: Wed, 15 Mar 2017 13:25:17 +0100
+Subject: qmp: add __com.redhat_reason to the BLOCK_IO_ERROR event
+
+Patchwork-id: 64969
+O-Subject: [RHEL7.2 qemu-kvm-rhev PATCH 1/2] qmp: add error reason to the BLOCK_IO_ERROR event
+Bugzilla: 1199174
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+
+This commit forward ports the following RHEL-7.0 commit to RHEL-7.2:
+
+  commit 771a3a333eb0c9299a69a78ddb9c4181850b827d
+  Author: Laszlo Ersek <lersek@redhat.com>
+  Date:   Thu Nov 21 16:27:18 2013 +0100
+
+  error reason in BLOCK_IO_ERROR / BLOCK_JOB_ERROR events (RHEL 6->7 fwd)
+
+I had to redo the work because now events use the QAPI, but it
+was straightforward.
+
+There's one significant difference though: this commit does not
+extend the BLOCK_JOB_ERROR event as did the RHEL-7.0 commit. The
+reason is that this extension was supposed to be used only by vdsm
+and I don't think there's a requirement to have the extension
+in BLOCK_JOB_ERROR too. Let's not spread it.
+
+Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Rebase notes (2.10.0):
+- Properly updated example
+
+Rebase notes (2.9.0):
+- moved documentation to schema
+
+(cherry picked from commit 2f9487b60f700de33551208c543f5d3b4fa89236)
+---
+ block/block-backend.c | 27 +++++++++++++++++++++++----
+ qapi/block-core.json  | 20 ++++++++++++++++++--
+ 2 files changed, 41 insertions(+), 6 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 1031742..0819b3a 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -1510,9 +1510,25 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
+     }
+ }
+ 
++/* https://bugzilla.redhat.com/show_bug.cgi?id=1199174 */
++static RHEL7BlockErrorReason get_rhel7_error_reason(int error)
++{
++	switch (error) {
++	case ENOSPC:
++        return RHEL7_BLOCK_ERROR_REASON_ENOSPC;
++	case EPERM:
++        return RHEL7_BLOCK_ERROR_REASON_EPERM;
++	case EIO:
++        return RHEL7_BLOCK_ERROR_REASON_EIO;
++	default:
++        return RHEL7_BLOCK_ERROR_REASON_EOTHER;
++    }
++}
++
+ static void send_qmp_error_event(BlockBackend *blk,
+                                  BlockErrorAction action,
+-                                 bool is_read, int error)
++                                 bool is_read, int error,
++                                 RHEL7BlockErrorReason res)
+ {
+     IoOperationType optype;
+ 
+@@ -1521,7 +1537,7 @@ static void send_qmp_error_event(BlockBackend *blk,
+                                    bdrv_get_node_name(blk_bs(blk)), optype,
+                                    action, blk_iostatus_is_enabled(blk),
+                                    error == ENOSPC, strerror(error),
+-                                   &error_abort);
++                                   res, &error_abort);
+ }
+ 
+ /* This is done by device models because, while the block layer knows
+@@ -1531,7 +1547,10 @@ static void send_qmp_error_event(BlockBackend *blk,
+ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
+                       bool is_read, int error)
+ {
++    RHEL7BlockErrorReason res;
++
+     assert(error >= 0);
++    res = get_rhel7_error_reason(error);
+ 
+     if (action == BLOCK_ERROR_ACTION_STOP) {
+         /* First set the iostatus, so that "info block" returns an iostatus
+@@ -1549,10 +1568,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
+          * also ensures that the STOP/RESUME pair of events is emitted.
+          */
+         qemu_system_vmstop_request_prepare();
+-        send_qmp_error_event(blk, action, is_read, error);
++        send_qmp_error_event(blk, action, is_read, error, res);
+         qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
+     } else {
+-        send_qmp_error_event(blk, action, is_read, error);
++        send_qmp_error_event(blk, action, is_read, error, res);
+     }
+ }
+ 
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index 833c602..8f5f105 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -3552,6 +3552,19 @@
+             'fatal'      : 'bool' } }
+ 
+ ##
++# @RHEL7BlockErrorReason:
++#
++# Block I/O error reason
++#
++# @eio:  errno EIO
++# @eperm: errno EPERM
++# @enospc: errno ENOSPC
++# @eother: any errno other than EIO, EPERM, ENOSPC
++##
++{ 'enum': 'RHEL7BlockErrorReason',
++  'data': [ 'enospc', 'eperm', 'eio', 'eother' ] }
++
++##
+ # @BLOCK_IO_ERROR:
+ #
+ # Emitted when a disk I/O error occurs
+@@ -3577,6 +3590,8 @@
+ #          (This field is a debugging aid for humans, it should not
+ #           be parsed by applications) (since: 2.2)
+ #
++# @__com.redhat_reason: error reason
++#
+ # Note: If action is "stop", a STOP event will eventually follow the
+ # BLOCK_IO_ERROR event
+ #
+@@ -3588,14 +3603,15 @@
+ #      "data": { "device": "ide0-hd1",
+ #                "node-name": "#block212",
+ #                "operation": "write",
+-#                "action": "stop" },
++#                "action": "stop",
++#                "__com.redhat_reason": "enospc" },
+ #      "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+ #
+ ##
+ { 'event': 'BLOCK_IO_ERROR',
+   'data': { 'device': 'str', 'node-name': 'str', 'operation': 'IoOperationType',
+             'action': 'BlockErrorAction', '*nospace': 'bool',
+-            'reason': 'str' } }
++            'reason': 'str', '__com.redhat_reason': 'RHEL7BlockErrorReason' } }
+ 
+ ##
+ # @BLOCK_JOB_COMPLETED:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0020-Migration-compat-for-pckbd.patch b/SOURCES/0020-Migration-compat-for-pckbd.patch
new file mode 100644
index 0000000..daaee47
--- /dev/null
+++ b/SOURCES/0020-Migration-compat-for-pckbd.patch
@@ -0,0 +1,60 @@
+From 583b819622f77c9e62bf3cd4f44b08de8aa46dcd Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Thu, 25 Jun 2015 16:34:25 +0200
+Subject: Migration compat for pckbd
+
+Patchwork-id: 66497
+O-Subject: [RHEL-7.2 qemu-kvm-rhev PATCH 1/1] Migration compat for pckbd
+Bugzilla: 1215092
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+2.2 added a new subsection to the pc keyboard model to preserve
+the value of 'outport' across migration; to maintain migration
+backwards compatibility this patch disables it on older machine types.
+This leaves us no-worse-off than in older versions.
+
+Even with the new code, the value migrated in 'outport' isn't used
+anywhere in the pckbd model; for example the value migrated doesn't
+change the state of the A20 line or potentially do a reset.
+
+The only effect, as far as I can tell is if the guest were to
+explicitly read the outport value it might get a more sensible reply.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit d2aba8a17b40c081f2ce29bc12b3945b7fb91d53)
+---
+ hw/input/pckbd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
+index 62678f3..7d43237 100644
+--- a/hw/input/pckbd.c
++++ b/hw/input/pckbd.c
+@@ -26,6 +26,7 @@
+ #include "hw/isa/isa.h"
+ #include "hw/i386/pc.h"
+ #include "hw/input/ps2.h"
++#include "migration/migration.h"
+ #include "sysemu/sysemu.h"
+ 
+ /* debug PC keyboard */
+@@ -389,6 +390,11 @@ static int kbd_outport_post_load(void *opaque, int version_id)
+ static bool kbd_outport_needed(void *opaque)
+ {
+     KBDState *s = opaque;
++
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return s->outport != kbd_outport_default(s);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0021-Migration-compat-for-fdc.patch b/SOURCES/0021-Migration-compat-for-fdc.patch
new file mode 100644
index 0000000..f852ee3
--- /dev/null
+++ b/SOURCES/0021-Migration-compat-for-fdc.patch
@@ -0,0 +1,126 @@
+From 50613448205a2e85e90a488be1c83d0f2b5f2d52 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Fri, 26 Jun 2015 16:19:47 +0200
+Subject: Migration compat for fdc
+
+Patchwork-id: 66534
+O-Subject: [RHEL-7.2 qemu-kvm-rhev PATCH 1/1] Migration compat for fdc
+Bugzilla: 1215091
+RH-Acked-by: Amit Shah <amit.shah@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+2.2 added some sections into the fdc and floppy drive, this patch
+disables those new sections for reverse migration compatibility.
+
+There are three pieces of data added to the migration:
+   1) 'perpendicular mode' on the drive - i.e. 2.88MB mode, that
+      was rare as hens teeth and the flag isn't actually used anywhere.
+
+   2) fdc_reset_sensei
+      This relates to the state of the fdc just after a reset command;
+      the fdc produces four 'sense' states internally (corresponding to
+      one external interrupt) that is there for backwards compatibility
+      to an older fdc (and to 8" drives!!).  This compatibility code
+      was added to qemu to fix SCO Openserver floppy problems, ~2009.
+      Migration just after an fdc-reset would get the initial interrupt
+      but lose the extra 3 sense states.  Print a log message since
+      that's guest visible, but it's not knowingly caused us a problem
+      so don't fail migration.
+
+   3) result-timer
+      The emulation models a delay after the 'read id' command which
+      is handled by a timer; if we migrate before the timer goes off
+      we probably wont complete the command.
+      I'm worried that the most likely time that a 'read id' would be
+      used would be in a background probe to see if there's a floppy
+      present, so again, don't fail the migrate, but do print a log
+      message.  With any luck any sane floppy driver will have a
+      timeout; if we hit problems then a work around would be to
+      make the pre-save mark the command as finished with error.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit b18d89c56aa26e86fb6194f77a15a72244d5ff88)
+---
+ hw/block/fdc.c | 39 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/hw/block/fdc.c b/hw/block/fdc.c
+index 90cd9a0..d3213cb 100644
+--- a/hw/block/fdc.c
++++ b/hw/block/fdc.c
+@@ -36,6 +36,7 @@
+ #include "hw/isa/isa.h"
+ #include "hw/sysbus.h"
+ #include "hw/block/block.h"
++#include "migration/migration.h"
+ #include "sysemu/block-backend.h"
+ #include "sysemu/blockdev.h"
+ #include "sysemu/sysemu.h"
+@@ -1042,6 +1043,10 @@ static bool fdrive_perpendicular_needed(void *opaque)
+ {
+     FDrive *drive = opaque;
+ 
++    if (migrate_pre_2_2) {
++        return false;
++    }
++
+     return drive->perpendicular != 0;
+ }
+ 
+@@ -1134,8 +1139,20 @@ static int fdc_post_load(void *opaque, int version_id)
+ static bool fdc_reset_sensei_needed(void *opaque)
+ {
+     FDCtrl *s = opaque;
++    bool needed = s->reset_sensei != 0;
++
++    if (migrate_pre_2_2) {
++        /*
++         * This probably wont matter for most OSs, but it's good to log
++         * it just incase we find it causes problems.
++         */
++        if (needed) {
++            error_report("INFO: fdc migration just after reset (sensei!=0)");
++        }
++        return false;
++    }
+ 
+-    return s->reset_sensei != 0;
++    return needed;
+ }
+ 
+ static const VMStateDescription vmstate_fdc_reset_sensei = {
+@@ -1152,8 +1169,26 @@ static const VMStateDescription vmstate_fdc_reset_sensei = {
+ static bool fdc_result_timer_needed(void *opaque)
+ {
+     FDCtrl *s = opaque;
++    bool needed = timer_pending(s->result_timer);
++
++    if (migrate_pre_2_2) {
++        /*
++         * This could upset some OSs if their read-id command doesn't
++         * complete, so lets log something.
++         */
++        if (needed) {
++            error_report("INFO: fdc migration just after read-id (timer!=0)");
++        }
++        /*
++         * However, since it's not apparently caused us problems for many
++         * years, don't fail the migration, especially as this could
++         * happen as part of a background drive-probe which if it fails
++         * won't be a problem.
++         */
++        return false;
++    }
+ 
+-    return timer_pending(s->result_timer);
++    return needed;
+ }
+ 
+ static const VMStateDescription vmstate_fdc_result_timer = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0022-RHEL-Set-vcpus-hard-limit-to-240-for-Power.patch b/SOURCES/0022-RHEL-Set-vcpus-hard-limit-to-240-for-Power.patch
new file mode 100644
index 0000000..a58629a
--- /dev/null
+++ b/SOURCES/0022-RHEL-Set-vcpus-hard-limit-to-240-for-Power.patch
@@ -0,0 +1,62 @@
+From fdeef3c1c7926a5c8a5b732135ea0a80b177c103 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 3 Sep 2015 04:09:04 +0200
+Subject: RHEL: Set vcpus hard limit to 240 for Power
+
+Patchwork-id: 67655
+O-Subject: [RHEL7.2 qemu-kvm-rhev PATCH] RHEL: Set vcpus hard limit to 240 for Power
+Bugzilla: 1257781
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+On POWER, the kernel advertises a soft limit based on the number of CPU
+threads on the host.  We want to allow exceeding this for testing purposes,
+so we don't want to set hard limit to soft limit as on x86.
+
+However the POWER hard limit advertised by the kernel is 2048 (== NR_CPUS)
+but we only want to allow up to the number of vCPUs we actually test, so
+we force the hard limit to 240.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 815a8be86930089767730c30cfb6b5373c138cf7)
+---
+ accel/kvm/kvm-all.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
+index b42c56a..80ab1c7 100644
+--- a/accel/kvm/kvm-all.c
++++ b/accel/kvm/kvm-all.c
+@@ -1627,8 +1627,27 @@ static int kvm_init(MachineState *ms)
+     soft_vcpus_limit = kvm_recommended_vcpus(s);
+     hard_vcpus_limit = kvm_max_vcpus(s);
+ 
++#ifdef HOST_PPC64
++    /*
++     * RHEL hack:
++     *
++     * On POWER, the kernel advertises a soft limit based on the
++     * number of CPU threads on the host.  We want to allow exceeding
++     * this for testing purposes, so we don't want to set hard limit
++     * to soft limit as on x86.
++     *
++     * However the POWER hard limit advertised by the kernel is 2048
++     * (== NR_CPUS) but we only want to allow up to the number of
++     * vCPUs we actually test, so we force the hard limit to 240
++     */
++    hard_vcpus_limit = 240;
++    if (soft_vcpus_limit > hard_vcpus_limit) {
++        soft_vcpus_limit = hard_vcpus_limit;
++    }
++#else
+     /* RHEL doesn't support nr_vcpus > soft_vcpus_limit */
+     hard_vcpus_limit = soft_vcpus_limit;
++#endif
+ 
+     while (nc->name) {
+         if (nc->num > soft_vcpus_limit) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0023-spapr-Reduce-advertised-max-LUNs-for-spapr_vscsi.patch b/SOURCES/0023-spapr-Reduce-advertised-max-LUNs-for-spapr_vscsi.patch
new file mode 100644
index 0000000..29d10b0
--- /dev/null
+++ b/SOURCES/0023-spapr-Reduce-advertised-max-LUNs-for-spapr_vscsi.patch
@@ -0,0 +1,48 @@
+From 9eadef5817e22891efc509ff1af6f0d14545b2b0 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Wed, 9 Sep 2015 02:03:04 +0200
+Subject: spapr: Reduce advertised max LUNs for spapr_vscsi
+
+Patchwork-id: 67711
+O-Subject: [RHEL7.2 qemu-kvm-rhev PATCH] spapr: Reduce advertised max LUNs for spapr_vscsi
+Bugzilla: 1260464
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+The implementation of the PAPR paravirtual SCSI adapter currently
+allows up to 32 LUNs (max_lun == 31).  However the adapter isn't really
+designed to support lots of devices - the PowerVM implementation only
+ever puts one disk per vSCSI controller.
+
+More specifically, the Linux guest side vscsi driver (the only one we
+really care about) is hardcoded to allow a maximum of 8 LUNs.
+
+So, reduce the number of LUNs on the qemu side to 8, so we don't
+falsely advertise that more LUNs can work.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 6c166e382c232ba4e527b4fc5ca9fdea151498d9)
+---
+ hw/scsi/spapr_vscsi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
+index 55ee48c..92a3de3 100644
+--- a/hw/scsi/spapr_vscsi.c
++++ b/hw/scsi/spapr_vscsi.c
+@@ -1178,7 +1178,7 @@ static const struct SCSIBusInfo vscsi_scsi_info = {
+     .tcq = true,
+     .max_channel = 7, /* logical unit addressing format */
+     .max_target = 63,
+-    .max_lun = 31,
++    .max_lun = 7,
+ 
+     .transfer_data = vscsi_transfer_data,
+     .complete = vscsi_command_complete,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0024-qmp-Report-__com.redhat_drive_add-error-to-monitor.patch b/SOURCES/0024-qmp-Report-__com.redhat_drive_add-error-to-monitor.patch
new file mode 100644
index 0000000..78a5095
--- /dev/null
+++ b/SOURCES/0024-qmp-Report-__com.redhat_drive_add-error-to-monitor.patch
@@ -0,0 +1,52 @@
+From d6db718295b53f11017aaba1dd8a0507c77d7a1e Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Thu, 19 May 2016 06:39:44 +0200
+Subject: qmp: Report __com.redhat_drive_add error to monitor
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <1463639984-1165-1-git-send-email-famz@redhat.com>
+Patchwork-id: 70412
+O-Subject: [RHEL-7.3 qemu-kvm-rhev PATCH] qmp: Report drive_add error to monitor
+Bugzilla: 1337100
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+In other error cases of this function we use error_setg, the same should
+be done with drive_new() failures. This is useful for libvirt to
+correctly detect the failure and report proper error message when a
+specified image is not available.
+
+This bug cames from the forward porting from qemu-kvm, at which point we
+overlooked the difference in QMP reporting between qerror_report and
+error_report.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit c5736179da1a310ddb384836fc025b2582f9e90d)
+
+Rebase notes (2.8.0):
+- Changed patch name
+
+(cherry picked from commit 8a1f601ec13449e736c05789c4f5ae52ab34f3a7)
+---
+ device-hotplug.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/device-hotplug.c b/device-hotplug.c
+index 218f7b3..29f9a64 100644
+--- a/device-hotplug.c
++++ b/device-hotplug.c
+@@ -145,8 +145,7 @@ void qmp_simple_drive_add(QDict *qdict, QObject **ret_data, Error **errp)
+     mc = MACHINE_GET_CLASS(current_machine);
+     dinfo = drive_new(opts, mc->block_default_type);
+     if (!dinfo) {
+-        error_report(QERR_DEVICE_INIT_FAILED,
+-                      qemu_opts_id(opts));
++        error_setg(errp, QERR_DEVICE_INIT_FAILED, qemu_opts_id(opts));
+         qemu_opts_del(opts);
+         return;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0025-RHEL-only-hw-char-pl011-fix-SBSA-reset.patch b/SOURCES/0025-RHEL-only-hw-char-pl011-fix-SBSA-reset.patch
new file mode 100644
index 0000000..ab6d21b
--- /dev/null
+++ b/SOURCES/0025-RHEL-only-hw-char-pl011-fix-SBSA-reset.patch
@@ -0,0 +1,57 @@
+From 49be481336c227fdad2f7edc02fa088f3d88c9a2 Mon Sep 17 00:00:00 2001
+From: Andrew Jones <drjones@redhat.com>
+Date: Mon, 1 Aug 2016 14:27:09 +0200
+Subject: RHEL-only: hw/char/pl011: fix SBSA reset
+
+RH-Author: Andrew Jones <drjones@redhat.com>
+Message-id: <1470061629-6395-1-git-send-email-drjones@redhat.com>
+Patchwork-id: 71697
+O-Subject: [AArch64 RHEL-7.3 qemu-kvm-rhev PATCH] RHEL-only: hw/char/pl011: fix SBSA reset
+Bugzilla: 1266048
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+When booting Linux with an SBSA UART, e.g. when booting mach-virt
+with ACPI, if the user types on the console during boot, then when
+the login prompt appears she won't be able to log in. This is
+because during boot the SBSA UART needs to be reset, but the SBSA
+specification doesn't provide registers to enable/disable the FIFOs.
+This patch observes a couple registers the SBSA UART does write to
+in order to attempt to guess when a reset is needed, and then do it.
+We risk losing some characters from the FIFO if the guess is wrong,
+but the risk of that should be quite low.
+
+Signed-off-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 15ee295534f654d6b6ba9499cdd380aa9c954920)
+---
+ hw/char/pl011.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/hw/char/pl011.c b/hw/char/pl011.c
+index 2aa277f..23fe047 100644
+--- a/hw/char/pl011.c
++++ b/hw/char/pl011.c
+@@ -209,6 +209,18 @@ static void pl011_write(void *opaque, hwaddr offset,
+         pl011_update(s);
+         break;
+     case 17: /* UARTICR */
++        /*
++         * RHEL-only, fixes BZ1266048
++         *
++         * Look for the "signature" of a driver init or shutdown in
++         * order to know that we need to reset the SBSA UART. Yes,
++         * this is hacky, but as SBSA drivers aren't required to write
++         * UARTLCR_H or UARTCR, then we don't have much choice...
++         */
++        if (s->int_enabled == 0 && value == 0xffff) {
++            s->read_count = 0;
++            s->read_pos = 0;
++        }
+         s->int_level &= ~value;
+         pl011_update(s);
+         break;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0026-blockdev-ignore-cache-options-for-empty-CDROM-drives.patch b/SOURCES/0026-blockdev-ignore-cache-options-for-empty-CDROM-drives.patch
new file mode 100644
index 0000000..c824be1
--- /dev/null
+++ b/SOURCES/0026-blockdev-ignore-cache-options-for-empty-CDROM-drives.patch
@@ -0,0 +1,90 @@
+From 454f60447bfea904d561ef282fc0446229484c02 Mon Sep 17 00:00:00 2001
+From: John Snow <jsnow@redhat.com>
+Date: Fri, 16 Sep 2016 22:06:28 +0200
+Subject: blockdev: ignore cache options for empty CDROM drives
+
+RH-Author: John Snow <jsnow@redhat.com>
+Message-id: <1474063588-6370-2-git-send-email-jsnow@redhat.com>
+Patchwork-id: 72377
+O-Subject: [RHEV-7.3 qemu-kvm-rhev PATCH 1/1] blockdev: ignore cache options for empty CDROM drives
+Bugzilla: 1342999
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+In qemu-kvm-rhev-2.3.0, QEMU will accept cache options for empty CDROM
+devices, but silently ignore them as they will be overwritten when the
+next CDROM is inserted.
+
+Libvirt and VMM are capable of generating XML configurations which
+attempt to specify these cache options to QEMU, though they don't have
+any effect.
+
+Upstream, a refactoring of cache option mechanisms means that we have
+started rejecting invalid configurations where cache options are supplied
+without any target to actually apply them to.
+
+This means that there are combinations of QEMU and libvirt that will fail
+to start a VM if a user selects a cache option.
+
+This patch is a downstream-only workaround until libvirt can stop
+supplying cache settings for empty CDROMs and/or until libvirt can take
+advantage of the new QMP tray/medium manipulation mechanisms that will
+allow proper cache specification for removable media.
+
+Signed-off-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 89b162019bfd202bbbd00563d03a030c2f7c1395)
+---
+ blockdev.c | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index e525ebf..6d4cb70 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -450,6 +450,32 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
+     }
+ }
+ 
++/**
++ * libvirt expects to be able to pass cache options for CDROM drives without
++ * inserted media. Historically, QEMU eventually ignores these cache options as
++ * they are lost when media is inserted. Recently, QEMU started rejecting these
++ * configurations. Libvirt however still generates such configurations.
++ *
++ * To prevent QEMU from being unable to start, pretend there are no options
++ * present if the only options present are cache options for the BDS.
++ */
++static bool __redhat_com_has_bs_opts(QDict *bs_opts)
++{
++    size_t n, s;
++    s = qdict_size(bs_opts);
++
++    if (s == 0) {
++        return false;
++    } else if (s > 2) {
++        return true;
++    }
++
++    n = qdict_haskey(bs_opts, BDRV_OPT_CACHE_DIRECT);
++    n += qdict_haskey(bs_opts, BDRV_OPT_CACHE_NO_FLUSH);
++
++    return s != n;
++}
++
+ /* Takes the ownership of bs_opts */
+ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
+                                    Error **errp)
+@@ -557,7 +583,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
+     read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false);
+ 
+     /* init */
+-    if ((!file || !*file) && !qdict_size(bs_opts)) {
++    if ((!file || !*file) && !__redhat_com_has_bs_opts(bs_opts)) {
+         BlockBackendRootState *blk_rs;
+ 
+         blk = blk_new(0, BLK_PERM_ALL);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0027-Revert-kvm_stat-Remove.patch b/SOURCES/0027-Revert-kvm_stat-Remove.patch
new file mode 100644
index 0000000..39bcf2f
--- /dev/null
+++ b/SOURCES/0027-Revert-kvm_stat-Remove.patch
@@ -0,0 +1,1262 @@
+From e0425f69f136a05a59ee5cb7022409ed2be94a0b Mon Sep 17 00:00:00 2001
+From: "Danilo C. L. de Paula" <ddepaula@redhat.com>
+Date: Mon, 16 Jan 2017 11:52:49 +0100
+Subject: Revert "kvm_stat: Remove"
+
+RH-Author: ddepaula <ddepaula@redhat.com>
+Message-id: <1479302806-10135-2-git-send-email-ddepaula@redhat.com>
+Patchwork-id: 72851
+O-Subject: [RHEV-7.4 qemu-kvm-rhev PATCH v3 1/3] Revert "kvm_stat: Remove"
+Bugzilla: 1389238
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+kvm_stat script was removed in QEMU 2.7.0 as it become part of kernel
+tree. However kvm_stat is shipped in qemu-kvm-tools package in RHEL.
+
+This reverts commit 60b412dd18362bd4ddc44ba7022aacb6af074b5d.
+
+Signed-off-by: Danilo Cesar Lemes de Paula <ddepaula@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Merged patches (2.9.0):
+- 1e69b1b Include kvm_stat in qemu-kvm.spec
+- 7fcfc94 tools: kvm_stat: Powerpc related fixes
+- 7f89136 tools: kvm_stat: Introduce pid monitoring
+- c728a6b tools: kvm_stat: Add comments
+- 27fb856 Package man page of "kvm_stat" tool
+
+(cherry picked from commit d4a8e35b84072816c79e23f5d0a69a2145217004)
+---
+ Makefile                      |    8 +
+ redhat/qemu-kvm.spec.template |    7 +-
+ scripts/kvm/kvm_stat          | 1127 +++++++++++++++++++++++++++++++++++++++++
+ scripts/kvm/kvm_stat.texi     |   55 ++
+ 4 files changed, 1196 insertions(+), 1 deletion(-)
+ create mode 100755 scripts/kvm/kvm_stat
+ create mode 100644 scripts/kvm/kvm_stat.texi
+
+diff --git a/Makefile b/Makefile
+index ba31124..312ed5e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -209,6 +209,9 @@ ifdef BUILD_DOCS
+ DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
+ DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
+ DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
++ifdef CONFIG_LINUX
++DOCS+=kvm_stat.1
++endif
+ ifdef CONFIG_VIRTFS
+ DOCS+=fsdev/virtfs-proxy-helper.1
+ endif
+@@ -727,6 +730,11 @@ html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
+ info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
+ pdf: qemu-doc.pdf docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
+ txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
++kvm_stat.1: scripts/kvm/kvm_stat.texi
++	$(call quiet-command, \
++	  perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< kvm_stat.pod && \
++	  $(POD2MAN) --section=1 --center=" " --release=" " kvm_stat.pod > $@, \
++	  "  GEN   $@")
+ 
+ qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
+ 	qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-option-trace.texi \
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+new file mode 100755
+index 0000000..581278c
+--- /dev/null
++++ b/scripts/kvm/kvm_stat
+@@ -0,0 +1,1127 @@
++#!/usr/bin/python
++#
++# top-like utility for displaying kvm statistics
++#
++# Copyright 2006-2008 Qumranet Technologies
++# Copyright 2008-2011 Red Hat, Inc.
++#
++# Authors:
++#  Avi Kivity <avi@redhat.com>
++#
++# This work is licensed under the terms of the GNU GPL, version 2.  See
++# the COPYING file in the top-level directory.
++"""The kvm_stat module outputs statistics about running KVM VMs
++
++Three different ways of output formatting are available:
++- as a top-like text ui
++- in a key -> value format
++- in an all keys, all values format
++
++The data is sampled from the KVM's debugfs entries and its perf events.
++"""
++
++import curses
++import sys
++import os
++import time
++import optparse
++import ctypes
++import fcntl
++import resource
++import struct
++import re
++from collections import defaultdict
++from time import sleep
++
++VMX_EXIT_REASONS = {
++    'EXCEPTION_NMI':        0,
++    'EXTERNAL_INTERRUPT':   1,
++    'TRIPLE_FAULT':         2,
++    'PENDING_INTERRUPT':    7,
++    'NMI_WINDOW':           8,
++    'TASK_SWITCH':          9,
++    'CPUID':                10,
++    'HLT':                  12,
++    'INVLPG':               14,
++    'RDPMC':                15,
++    'RDTSC':                16,
++    'VMCALL':               18,
++    'VMCLEAR':              19,
++    'VMLAUNCH':             20,
++    'VMPTRLD':              21,
++    'VMPTRST':              22,
++    'VMREAD':               23,
++    'VMRESUME':             24,
++    'VMWRITE':              25,
++    'VMOFF':                26,
++    'VMON':                 27,
++    'CR_ACCESS':            28,
++    'DR_ACCESS':            29,
++    'IO_INSTRUCTION':       30,
++    'MSR_READ':             31,
++    'MSR_WRITE':            32,
++    'INVALID_STATE':        33,
++    'MWAIT_INSTRUCTION':    36,
++    'MONITOR_INSTRUCTION':  39,
++    'PAUSE_INSTRUCTION':    40,
++    'MCE_DURING_VMENTRY':   41,
++    'TPR_BELOW_THRESHOLD':  43,
++    'APIC_ACCESS':          44,
++    'EPT_VIOLATION':        48,
++    'EPT_MISCONFIG':        49,
++    'WBINVD':               54,
++    'XSETBV':               55,
++    'APIC_WRITE':           56,
++    'INVPCID':              58,
++}
++
++SVM_EXIT_REASONS = {
++    'READ_CR0':       0x000,
++    'READ_CR3':       0x003,
++    'READ_CR4':       0x004,
++    'READ_CR8':       0x008,
++    'WRITE_CR0':      0x010,
++    'WRITE_CR3':      0x013,
++    'WRITE_CR4':      0x014,
++    'WRITE_CR8':      0x018,
++    'READ_DR0':       0x020,
++    'READ_DR1':       0x021,
++    'READ_DR2':       0x022,
++    'READ_DR3':       0x023,
++    'READ_DR4':       0x024,
++    'READ_DR5':       0x025,
++    'READ_DR6':       0x026,
++    'READ_DR7':       0x027,
++    'WRITE_DR0':      0x030,
++    'WRITE_DR1':      0x031,
++    'WRITE_DR2':      0x032,
++    'WRITE_DR3':      0x033,
++    'WRITE_DR4':      0x034,
++    'WRITE_DR5':      0x035,
++    'WRITE_DR6':      0x036,
++    'WRITE_DR7':      0x037,
++    'EXCP_BASE':      0x040,
++    'INTR':           0x060,
++    'NMI':            0x061,
++    'SMI':            0x062,
++    'INIT':           0x063,
++    'VINTR':          0x064,
++    'CR0_SEL_WRITE':  0x065,
++    'IDTR_READ':      0x066,
++    'GDTR_READ':      0x067,
++    'LDTR_READ':      0x068,
++    'TR_READ':        0x069,
++    'IDTR_WRITE':     0x06a,
++    'GDTR_WRITE':     0x06b,
++    'LDTR_WRITE':     0x06c,
++    'TR_WRITE':       0x06d,
++    'RDTSC':          0x06e,
++    'RDPMC':          0x06f,
++    'PUSHF':          0x070,
++    'POPF':           0x071,
++    'CPUID':          0x072,
++    'RSM':            0x073,
++    'IRET':           0x074,
++    'SWINT':          0x075,
++    'INVD':           0x076,
++    'PAUSE':          0x077,
++    'HLT':            0x078,
++    'INVLPG':         0x079,
++    'INVLPGA':        0x07a,
++    'IOIO':           0x07b,
++    'MSR':            0x07c,
++    'TASK_SWITCH':    0x07d,
++    'FERR_FREEZE':    0x07e,
++    'SHUTDOWN':       0x07f,
++    'VMRUN':          0x080,
++    'VMMCALL':        0x081,
++    'VMLOAD':         0x082,
++    'VMSAVE':         0x083,
++    'STGI':           0x084,
++    'CLGI':           0x085,
++    'SKINIT':         0x086,
++    'RDTSCP':         0x087,
++    'ICEBP':          0x088,
++    'WBINVD':         0x089,
++    'MONITOR':        0x08a,
++    'MWAIT':          0x08b,
++    'MWAIT_COND':     0x08c,
++    'XSETBV':         0x08d,
++    'NPF':            0x400,
++}
++
++# EC definition of HSR (from arch/arm64/include/asm/kvm_arm.h)
++AARCH64_EXIT_REASONS = {
++    'UNKNOWN':      0x00,
++    'WFI':          0x01,
++    'CP15_32':      0x03,
++    'CP15_64':      0x04,
++    'CP14_MR':      0x05,
++    'CP14_LS':      0x06,
++    'FP_ASIMD':     0x07,
++    'CP10_ID':      0x08,
++    'CP14_64':      0x0C,
++    'ILL_ISS':      0x0E,
++    'SVC32':        0x11,
++    'HVC32':        0x12,
++    'SMC32':        0x13,
++    'SVC64':        0x15,
++    'HVC64':        0x16,
++    'SMC64':        0x17,
++    'SYS64':        0x18,
++    'IABT':         0x20,
++    'IABT_HYP':     0x21,
++    'PC_ALIGN':     0x22,
++    'DABT':         0x24,
++    'DABT_HYP':     0x25,
++    'SP_ALIGN':     0x26,
++    'FP_EXC32':     0x28,
++    'FP_EXC64':     0x2C,
++    'SERROR':       0x2F,
++    'BREAKPT':      0x30,
++    'BREAKPT_HYP':  0x31,
++    'SOFTSTP':      0x32,
++    'SOFTSTP_HYP':  0x33,
++    'WATCHPT':      0x34,
++    'WATCHPT_HYP':  0x35,
++    'BKPT32':       0x38,
++    'VECTOR32':     0x3A,
++    'BRK64':        0x3C,
++}
++
++# From include/uapi/linux/kvm.h, KVM_EXIT_xxx
++USERSPACE_EXIT_REASONS = {
++    'UNKNOWN':          0,
++    'EXCEPTION':        1,
++    'IO':               2,
++    'HYPERCALL':        3,
++    'DEBUG':            4,
++    'HLT':              5,
++    'MMIO':             6,
++    'IRQ_WINDOW_OPEN':  7,
++    'SHUTDOWN':         8,
++    'FAIL_ENTRY':       9,
++    'INTR':             10,
++    'SET_TPR':          11,
++    'TPR_ACCESS':       12,
++    'S390_SIEIC':       13,
++    'S390_RESET':       14,
++    'DCR':              15,
++    'NMI':              16,
++    'INTERNAL_ERROR':   17,
++    'OSI':              18,
++    'PAPR_HCALL':       19,
++    'S390_UCONTROL':    20,
++    'WATCHDOG':         21,
++    'S390_TSCH':        22,
++    'EPR':              23,
++    'SYSTEM_EVENT':     24,
++}
++
++IOCTL_NUMBERS = {
++    'SET_FILTER':  0x40082406,
++    'ENABLE':      0x00002400,
++    'DISABLE':     0x00002401,
++    'RESET':       0x00002403,
++}
++
++class Arch(object):
++    """Encapsulates global architecture specific data.
++
++    Contains the performance event open syscall and ioctl numbers, as
++    well as the VM exit reasons for the architecture it runs on.
++
++    """
++    @staticmethod
++    def get_arch():
++        machine = os.uname()[4]
++
++        if machine.startswith('ppc'):
++            return ArchPPC()
++        elif machine.startswith('aarch64'):
++            return ArchA64()
++        elif machine.startswith('s390'):
++            return ArchS390()
++        else:
++            # X86_64
++            for line in open('/proc/cpuinfo'):
++                if not line.startswith('flags'):
++                    continue
++
++                flags = line.split()
++                if 'vmx' in flags:
++                    return ArchX86(VMX_EXIT_REASONS)
++                if 'svm' in flags:
++                    return ArchX86(SVM_EXIT_REASONS)
++                return
++
++class ArchX86(Arch):
++    def __init__(self, exit_reasons):
++        self.sc_perf_evt_open = 298
++        self.ioctl_numbers = IOCTL_NUMBERS
++        self.exit_reasons = exit_reasons
++
++class ArchPPC(Arch):
++    def __init__(self):
++        self.sc_perf_evt_open = 319
++        self.ioctl_numbers = IOCTL_NUMBERS
++        self.ioctl_numbers['ENABLE'] = 0x20002400
++        self.ioctl_numbers['DISABLE'] = 0x20002401
++        self.ioctl_numbers['RESET'] = 0x20002403
++
++        # PPC comes in 32 and 64 bit and some generated ioctl
++        # numbers depend on the wordsize.
++        char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
++        self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
++        self.exit_reasons = {}
++
++class ArchA64(Arch):
++    def __init__(self):
++        self.sc_perf_evt_open = 241
++        self.ioctl_numbers = IOCTL_NUMBERS
++        self.exit_reasons = AARCH64_EXIT_REASONS
++
++class ArchS390(Arch):
++    def __init__(self):
++        self.sc_perf_evt_open = 331
++        self.ioctl_numbers = IOCTL_NUMBERS
++        self.exit_reasons = None
++
++ARCH = Arch.get_arch()
++
++
++def walkdir(path):
++    """Returns os.walk() data for specified directory.
++
++    As it is only a wrapper it returns the same 3-tuple of (dirpath,
++    dirnames, filenames).
++    """
++    return next(os.walk(path))
++
++
++def parse_int_list(list_string):
++    """Returns an int list from a string of comma separated integers and
++    integer ranges."""
++    integers = []
++    members = list_string.split(',')
++
++    for member in members:
++        if '-' not in member:
++            integers.append(int(member))
++        else:
++            int_range = member.split('-')
++            integers.extend(range(int(int_range[0]),
++                                  int(int_range[1]) + 1))
++
++    return integers
++
++
++def get_online_cpus():
++    """Returns a list of cpu id integers."""
++    with open('/sys/devices/system/cpu/online') as cpu_list:
++        cpu_string = cpu_list.readline()
++        return parse_int_list(cpu_string)
++
++
++def get_filters():
++    """Returns a dict of trace events, their filter ids and
++    the values that can be filtered.
++
++    Trace events can be filtered for special values by setting a
++    filter string via an ioctl. The string normally has the format
++    identifier==value. For each filter a new event will be created, to
++    be able to distinguish the events.
++
++    """
++    filters = {}
++    filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
++    if ARCH.exit_reasons:
++        filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
++    return filters
++
++libc = ctypes.CDLL('libc.so.6', use_errno=True)
++syscall = libc.syscall
++
++class perf_event_attr(ctypes.Structure):
++    """Struct that holds the necessary data to set up a trace event.
++
++    For an extensive explanation see perf_event_open(2) and
++    include/uapi/linux/perf_event.h, struct perf_event_attr
++
++    All fields that are not initialized in the constructor are 0.
++
++    """
++    _fields_ = [('type', ctypes.c_uint32),
++                ('size', ctypes.c_uint32),
++                ('config', ctypes.c_uint64),
++                ('sample_freq', ctypes.c_uint64),
++                ('sample_type', ctypes.c_uint64),
++                ('read_format', ctypes.c_uint64),
++                ('flags', ctypes.c_uint64),
++                ('wakeup_events', ctypes.c_uint32),
++                ('bp_type', ctypes.c_uint32),
++                ('bp_addr', ctypes.c_uint64),
++                ('bp_len', ctypes.c_uint64),
++                ]
++
++    def __init__(self):
++        super(self.__class__, self).__init__()
++        self.type = PERF_TYPE_TRACEPOINT
++        self.size = ctypes.sizeof(self)
++        self.read_format = PERF_FORMAT_GROUP
++
++def perf_event_open(attr, pid, cpu, group_fd, flags):
++    """Wrapper for the sys_perf_evt_open() syscall.
++
++    Used to set up performance events, returns a file descriptor or -1
++    on error.
++
++    Attributes are:
++    - syscall number
++    - struct perf_event_attr *
++    - pid or -1 to monitor all pids
++    - cpu number or -1 to monitor all cpus
++    - The file descriptor of the group leader or -1 to create a group.
++    - flags
++
++    """
++    return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
++                   ctypes.c_int(pid), ctypes.c_int(cpu),
++                   ctypes.c_int(group_fd), ctypes.c_long(flags))
++
++PERF_TYPE_TRACEPOINT = 2
++PERF_FORMAT_GROUP = 1 << 3
++
++PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
++PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'
++
++class Group(object):
++    """Represents a perf event group."""
++
++    def __init__(self):
++        self.events = []
++
++    def add_event(self, event):
++        self.events.append(event)
++
++    def read(self):
++        """Returns a dict with 'event name: value' for all events in the
++        group.
++
++        Values are read by reading from the file descriptor of the
++        event that is the group leader. See perf_event_open(2) for
++        details.
++
++        Read format for the used event configuration is:
++        struct read_format {
++            u64 nr; /* The number of events */
++            struct {
++                u64 value; /* The value of the event */
++            } values[nr];
++        };
++
++        """
++        length = 8 * (1 + len(self.events))
++        read_format = 'xxxxxxxx' + 'Q' * len(self.events)
++        return dict(zip([event.name for event in self.events],
++                        struct.unpack(read_format,
++                                      os.read(self.events[0].fd, length))))
++
++class Event(object):
++    """Represents a performance event and manages its life cycle."""
++    def __init__(self, name, group, trace_cpu, trace_pid, trace_point,
++                 trace_filter, trace_set='kvm'):
++        self.name = name
++        self.fd = None
++        self.setup_event(group, trace_cpu, trace_pid, trace_point,
++                         trace_filter, trace_set)
++
++    def __del__(self):
++        """Closes the event's file descriptor.
++
++        As no python file object was created for the file descriptor,
++        python will not reference count the descriptor and will not
++        close it itself automatically, so we do it.
++
++        """
++        if self.fd:
++            os.close(self.fd)
++
++    def setup_event_attribute(self, trace_set, trace_point):
++        """Returns an initialized ctype perf_event_attr struct."""
++
++        id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
++                               trace_point, 'id')
++
++        event_attr = perf_event_attr()
++        event_attr.config = int(open(id_path).read())
++        return event_attr
++
++    def setup_event(self, group, trace_cpu, trace_pid, trace_point,
++                    trace_filter, trace_set):
++        """Sets up the perf event in Linux.
++
++        Issues the syscall to register the event in the kernel and
++        then sets the optional filter.
++
++        """
++
++        event_attr = self.setup_event_attribute(trace_set, trace_point)
++
++        # First event will be group leader.
++        group_leader = -1
++
++        # All others have to pass the leader's descriptor instead.
++        if group.events:
++            group_leader = group.events[0].fd
++
++        fd = perf_event_open(event_attr, trace_pid,
++                             trace_cpu, group_leader, 0)
++        if fd == -1:
++            err = ctypes.get_errno()
++            raise OSError(err, os.strerror(err),
++                          'while calling sys_perf_event_open().')
++
++        if trace_filter:
++            fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
++                        trace_filter)
++
++        self.fd = fd
++
++    def enable(self):
++        """Enables the trace event in the kernel.
++
++        Enabling the group leader makes reading counters from it and the
++        events under it possible.
++
++        """
++        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)
++
++    def disable(self):
++        """Disables the trace event in the kernel.
++
++        Disabling the group leader makes reading all counters under it
++        impossible.
++
++        """
++        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)
++
++    def reset(self):
++        """Resets the count of the trace event in the kernel."""
++        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
++
++class TracepointProvider(object):
++    """Data provider for the stats class.
++
++    Manages the events/groups from which it acquires its data.
++
++    """
++    def __init__(self):
++        self.group_leaders = []
++        self.filters = get_filters()
++        self._fields = self.get_available_fields()
++        self._pid = 0
++
++    def get_available_fields(self):
++        """Returns a list of available event's of format 'event name(filter
++        name)'.
++
++        All available events have directories under
++        /sys/kernel/debug/tracing/events/ which export information
++        about the specific event. Therefore, listing the dirs gives us
++        a list of all available events.
++
++        Some events like the vm exit reasons can be filtered for
++        specific values. To take account for that, the routine below
++        creates special fields with the following format:
++        event name(filter name)
++
++        """
++        path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
++        fields = walkdir(path)[1]
++        extra = []
++        for field in fields:
++            if field in self.filters:
++                filter_name_, filter_dicts = self.filters[field]
++                for name in filter_dicts:
++                    extra.append(field + '(' + name + ')')
++        fields += extra
++        return fields
++
++    def setup_traces(self):
++        """Creates all event and group objects needed to be able to retrieve
++        data."""
++        if self._pid > 0:
++            # Fetch list of all threads of the monitored pid, as qemu
++            # starts a thread for each vcpu.
++            path = os.path.join('/proc', str(self._pid), 'task')
++            groupids = walkdir(path)[1]
++        else:
++            groupids = get_online_cpus()
++
++        # The constant is needed as a buffer for python libs, std
++        # streams and other files that the script opens.
++        newlim = len(groupids) * len(self._fields) + 50
++        try:
++            softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)
++
++            if hardlim < newlim:
++                # Now we need CAP_SYS_RESOURCE, to increase the hard limit.
++                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, newlim))
++            else:
++                # Raising the soft limit is sufficient.
++                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, hardlim))
++
++        except ValueError:
++            sys.exit("NOFILE rlimit could not be raised to {0}".format(newlim))
++
++        for groupid in groupids:
++            group = Group()
++            for name in self._fields:
++                tracepoint = name
++                tracefilter = None
++                match = re.match(r'(.*)\((.*)\)', name)
++                if match:
++                    tracepoint, sub = match.groups()
++                    tracefilter = ('%s==%d\0' %
++                                   (self.filters[tracepoint][0],
++                                    self.filters[tracepoint][1][sub]))
++
++                # From perf_event_open(2):
++                # pid > 0 and cpu == -1
++                # This measures the specified process/thread on any CPU.
++                #
++                # pid == -1 and cpu >= 0
++                # This measures all processes/threads on the specified CPU.
++                trace_cpu = groupid if self._pid == 0 else -1
++                trace_pid = int(groupid) if self._pid != 0 else -1
++
++                group.add_event(Event(name=name,
++                                      group=group,
++                                      trace_cpu=trace_cpu,
++                                      trace_pid=trace_pid,
++                                      trace_point=tracepoint,
++                                      trace_filter=tracefilter))
++
++            self.group_leaders.append(group)
++
++    def available_fields(self):
++        return self.get_available_fields()
++
++    @property
++    def fields(self):
++        return self._fields
++
++    @fields.setter
++    def fields(self, fields):
++        """Enables/disables the (un)wanted events"""
++        self._fields = fields
++        for group in self.group_leaders:
++            for index, event in enumerate(group.events):
++                if event.name in fields:
++                    event.reset()
++                    event.enable()
++                else:
++                    # Do not disable the group leader.
++                    # It would disable all of its events.
++                    if index != 0:
++                        event.disable()
++
++    @property
++    def pid(self):
++        return self._pid
++
++    @pid.setter
++    def pid(self, pid):
++        """Changes the monitored pid by setting new traces."""
++        self._pid = pid
++        # The garbage collector will get rid of all Event/Group
++        # objects and open files after removing the references.
++        self.group_leaders = []
++        self.setup_traces()
++        self.fields = self._fields
++
++    def read(self):
++        """Returns 'event name: current value' for all enabled events."""
++        ret = defaultdict(int)
++        for group in self.group_leaders:
++            for name, val in group.read().iteritems():
++                if name in self._fields:
++                    ret[name] += val
++        return ret
++
++class DebugfsProvider(object):
++    """Provides data from the files that KVM creates in the kvm debugfs
++    folder."""
++    def __init__(self):
++        self._fields = self.get_available_fields()
++        self._pid = 0
++        self.do_read = True
++
++    def get_available_fields(self):
++        """"Returns a list of available fields.
++
++        The fields are all available KVM debugfs files
++
++        """
++        return walkdir(PATH_DEBUGFS_KVM)[2]
++
++    @property
++    def fields(self):
++        return self._fields
++
++    @fields.setter
++    def fields(self, fields):
++        self._fields = fields
++
++    @property
++    def pid(self):
++        return self._pid
++
++    @pid.setter
++    def pid(self, pid):
++        if pid != 0:
++            self._pid = pid
++
++            vms = walkdir(PATH_DEBUGFS_KVM)[1]
++            if len(vms) == 0:
++                self.do_read = False
++
++            self.paths = filter(lambda x: "{}-".format(pid) in x, vms)
++
++        else:
++            self.paths = ['']
++            self.do_read = True
++
++    def read(self):
++        """Returns a dict with format:'file name / field -> current value'."""
++        results = {}
++
++        # If no debugfs filtering support is available, then don't read.
++        if not self.do_read:
++            return results
++
++        for path in self.paths:
++            for field in self._fields:
++                results[field] = results.get(field, 0) \
++                                 + self.read_field(field, path)
++
++        return results
++
++    def read_field(self, field, path):
++        """Returns the value of a single field from a specific VM."""
++        try:
++            return int(open(os.path.join(PATH_DEBUGFS_KVM,
++                                         path,
++                                         field))
++                       .read())
++        except IOError:
++            return 0
++
++class Stats(object):
++    """Manages the data providers and the data they provide.
++
++    It is used to set filters on the provider's data and collect all
++    provider data.
++
++    """
++    def __init__(self, providers, pid, fields=None):
++        self.providers = providers
++        self._pid_filter = pid
++        self._fields_filter = fields
++        self.values = {}
++        self.update_provider_pid()
++        self.update_provider_filters()
++
++    def update_provider_filters(self):
++        """Propagates fields filters to providers."""
++        def wanted(key):
++            if not self._fields_filter:
++                return True
++            return re.match(self._fields_filter, key) is not None
++
++        # As we reset the counters when updating the fields we can
++        # also clear the cache of old values.
++        self.values = {}
++        for provider in self.providers:
++            provider_fields = [key for key in provider.get_available_fields()
++                               if wanted(key)]
++            provider.fields = provider_fields
++
++    def update_provider_pid(self):
++        """Propagates pid filters to providers."""
++        for provider in self.providers:
++            provider.pid = self._pid_filter
++
++    @property
++    def fields_filter(self):
++        return self._fields_filter
++
++    @fields_filter.setter
++    def fields_filter(self, fields_filter):
++        self._fields_filter = fields_filter
++        self.update_provider_filters()
++
++    @property
++    def pid_filter(self):
++        return self._pid_filter
++
++    @pid_filter.setter
++    def pid_filter(self, pid):
++        self._pid_filter = pid
++        self.values = {}
++        self.update_provider_pid()
++
++    def get(self):
++        """Returns a dict with field -> (value, delta to last value) of all
++        provider data."""
++        for provider in self.providers:
++            new = provider.read()
++            for key in provider.fields:
++                oldval = self.values.get(key, (0, 0))
++                newval = new.get(key, 0)
++                newdelta = None
++                if oldval is not None:
++                    newdelta = newval - oldval[0]
++                self.values[key] = (newval, newdelta)
++        return self.values
++
++LABEL_WIDTH = 40
++NUMBER_WIDTH = 10
++
++class Tui(object):
++    """Instruments curses to draw a nice text ui."""
++    def __init__(self, stats):
++        self.stats = stats
++        self.screen = None
++        self.drilldown = False
++        self.update_drilldown()
++
++    def __enter__(self):
++        """Initialises curses for later use.  Based on curses.wrapper
++           implementation from the Python standard library."""
++        self.screen = curses.initscr()
++        curses.noecho()
++        curses.cbreak()
++
++        # The try/catch works around a minor bit of
++        # over-conscientiousness in the curses module, the error
++        # return from C start_color() is ignorable.
++        try:
++            curses.start_color()
++        except:
++            pass
++
++        curses.use_default_colors()
++        return self
++
++    def __exit__(self, *exception):
++        """Resets the terminal to its normal state.  Based on curses.wrappre
++           implementation from the Python standard library."""
++        if self.screen:
++            self.screen.keypad(0)
++            curses.echo()
++            curses.nocbreak()
++            curses.endwin()
++
++    def update_drilldown(self):
++        """Sets or removes a filter that only allows fields without braces."""
++        if not self.stats.fields_filter:
++            self.stats.fields_filter = r'^[^\(]*$'
++
++        elif self.stats.fields_filter == r'^[^\(]*$':
++            self.stats.fields_filter = None
++
++    def update_pid(self, pid):
++        """Propagates pid selection to stats object."""
++        self.stats.pid_filter = pid
++
++    def refresh(self, sleeptime):
++        """Refreshes on-screen data."""
++        self.screen.erase()
++        if self.stats.pid_filter > 0:
++            self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
++                               .format(self.stats.pid_filter),
++                               curses.A_BOLD)
++        else:
++            self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
++        self.screen.addstr(2, 1, 'Event')
++        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
++                           len('Total'), 'Total')
++        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
++                           len('Current'), 'Current')
++        row = 3
++        stats = self.stats.get()
++        def sortkey(x):
++            if stats[x][1]:
++                return (-stats[x][1], -stats[x][0])
++            else:
++                return (0, -stats[x][0])
++        for key in sorted(stats.keys(), key=sortkey):
++
++            if row >= self.screen.getmaxyx()[0]:
++                break
++            values = stats[key]
++            if not values[0] and not values[1]:
++                break
++            col = 1
++            self.screen.addstr(row, col, key)
++            col += LABEL_WIDTH
++            self.screen.addstr(row, col, '%10d' % (values[0],))
++            col += NUMBER_WIDTH
++            if values[1] is not None:
++                self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
++            row += 1
++        self.screen.refresh()
++
++    def show_filter_selection(self):
++        """Draws filter selection mask.
++
++        Asks for a valid regex and sets the fields filter accordingly.
++
++        """
++        while True:
++            self.screen.erase()
++            self.screen.addstr(0, 0,
++                               "Show statistics for events matching a regex.",
++                               curses.A_BOLD)
++            self.screen.addstr(2, 0,
++                               "Current regex: {0}"
++                               .format(self.stats.fields_filter))
++            self.screen.addstr(3, 0, "New regex: ")
++            curses.echo()
++            regex = self.screen.getstr()
++            curses.noecho()
++            if len(regex) == 0:
++                return
++            try:
++                re.compile(regex)
++                self.stats.fields_filter = regex
++                return
++            except re.error:
++                continue
++
++    def show_vm_selection(self):
++        """Draws PID selection mask.
++
++        Asks for a pid until a valid pid or 0 has been entered.
++
++        """
++        while True:
++            self.screen.erase()
++            self.screen.addstr(0, 0,
++                               'Show statistics for specific pid.',
++                               curses.A_BOLD)
++            self.screen.addstr(1, 0,
++                               'This might limit the shown data to the trace '
++                               'statistics.')
++
++            curses.echo()
++            self.screen.addstr(3, 0, "Pid [0 or pid]: ")
++            pid = self.screen.getstr()
++            curses.noecho()
++
++            try:
++                pid = int(pid)
++
++                if pid == 0:
++                    self.update_pid(pid)
++                    break
++                else:
++                    if not os.path.isdir(os.path.join('/proc/', str(pid))):
++                        continue
++                    else:
++                        self.update_pid(pid)
++                        break
++
++            except ValueError:
++                continue
++
++    def show_stats(self):
++        """Refreshes the screen and processes user input."""
++        sleeptime = 0.25
++        while True:
++            self.refresh(sleeptime)
++            curses.halfdelay(int(sleeptime * 10))
++            sleeptime = 3
++            try:
++                char = self.screen.getkey()
++                if char == 'x':
++                    self.drilldown = not self.drilldown
++                    self.update_drilldown()
++                if char == 'q':
++                    break
++                if char == 'f':
++                    self.show_filter_selection()
++                if char == 'p':
++                    self.show_vm_selection()
++            except KeyboardInterrupt:
++                break
++            except curses.error:
++                continue
++
++def batch(stats):
++    """Prints statistics in a key, value format."""
++    s = stats.get()
++    time.sleep(1)
++    s = stats.get()
++    for key in sorted(s.keys()):
++        values = s[key]
++        print '%-42s%10d%10d' % (key, values[0], values[1])
++
++def log(stats):
++    """Prints statistics as reiterating key block, multiple value blocks."""
++    keys = sorted(stats.get().iterkeys())
++    def banner():
++        for k in keys:
++            print '%s' % k,
++        print
++    def statline():
++        s = stats.get()
++        for k in keys:
++            print ' %9d' % s[k][1],
++        print
++    line = 0
++    banner_repeat = 20
++    while True:
++        time.sleep(1)
++        if line % banner_repeat == 0:
++            banner()
++        statline()
++        line += 1
++
++def get_options():
++    """Returns processed program arguments."""
++    description_text = """
++This script displays various statistics about VMs running under KVM.
++The statistics are gathered from the KVM debugfs entries and / or the
++currently available perf traces.
++
++The monitoring takes additional cpu cycles and might affect the VM's
++performance.
++
++Requirements:
++- Access to:
++    /sys/kernel/debug/kvm
++    /sys/kernel/debug/trace/events/*
++    /proc/pid/task
++- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
++  CAP_SYS_ADMIN and perf events are used.
++- CAP_SYS_RESOURCE if the hard limit is not high enough to allow
++  the large number of files that are possibly opened.
++"""
++
++    class PlainHelpFormatter(optparse.IndentedHelpFormatter):
++        def format_description(self, description):
++            if description:
++                return description + "\n"
++            else:
++                return ""
++
++    optparser = optparse.OptionParser(description=description_text,
++                                      formatter=PlainHelpFormatter())
++    optparser.add_option('-1', '--once', '--batch',
++                         action='store_true',
++                         default=False,
++                         dest='once',
++                         help='run in batch mode for one second',
++                         )
++    optparser.add_option('-l', '--log',
++                         action='store_true',
++                         default=False,
++                         dest='log',
++                         help='run in logging mode (like vmstat)',
++                         )
++    optparser.add_option('-t', '--tracepoints',
++                         action='store_true',
++                         default=False,
++                         dest='tracepoints',
++                         help='retrieve statistics from tracepoints',
++                         )
++    optparser.add_option('-d', '--debugfs',
++                         action='store_true',
++                         default=False,
++                         dest='debugfs',
++                         help='retrieve statistics from debugfs',
++                         )
++    optparser.add_option('-f', '--fields',
++                         action='store',
++                         default=None,
++                         dest='fields',
++                         help='fields to display (regex)',
++                         )
++    optparser.add_option('-p', '--pid',
++                        action='store',
++                        default=0,
++                        type=int,
++                        dest='pid',
++                        help='restrict statistics to pid',
++                        )
++    (options, _) = optparser.parse_args(sys.argv)
++    return options
++
++def get_providers(options):
++    """Returns a list of data providers depending on the passed options."""
++    providers = []
++
++    if options.tracepoints:
++        providers.append(TracepointProvider())
++    if options.debugfs:
++        providers.append(DebugfsProvider())
++    if len(providers) == 0:
++        providers.append(TracepointProvider())
++
++    return providers
++
++def check_access(options):
++    """Exits if the current user can't access all needed directories."""
++    if not os.path.exists('/sys/kernel/debug'):
++        sys.stderr.write('Please enable CONFIG_DEBUG_FS in your kernel.')
++        sys.exit(1)
++
++    if not os.path.exists(PATH_DEBUGFS_KVM):
++        sys.stderr.write("Please make sure, that debugfs is mounted and "
++                         "readable by the current user:\n"
++                         "('mount -t debugfs debugfs /sys/kernel/debug')\n"
++                         "Also ensure, that the kvm modules are loaded.\n")
++        sys.exit(1)
++
++    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints
++                                                     or not options.debugfs):
++        sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
++                         "when using the option -t (default).\n"
++                         "If it is enabled, make {0} readable by the "
++                         "current user.\n"
++                         .format(PATH_DEBUGFS_TRACING))
++        if options.tracepoints:
++            sys.exit(1)
++
++        sys.stderr.write("Falling back to debugfs statistics!\n")
++        options.debugfs = True
++        sleep(5)
++
++    return options
++
++def main():
++    options = get_options()
++    options = check_access(options)
++
++    if (options.pid > 0 and
++        not os.path.isdir(os.path.join('/proc/',
++                                       str(options.pid)))):
++        sys.stderr.write('Did you use a (unsupported) tid instead of a pid?\n')
++        sys.exit('Specified pid does not exist.')
++
++    providers = get_providers(options)
++    stats = Stats(providers, options.pid, fields=options.fields)
++
++    if options.log:
++        log(stats)
++    elif not options.once:
++        with Tui(stats) as tui:
++            tui.show_stats()
++    else:
++        batch(stats)
++
++if __name__ == "__main__":
++    main()
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+new file mode 100644
+index 0000000..4faf1a6
+--- /dev/null
++++ b/scripts/kvm/kvm_stat.texi
+@@ -0,0 +1,55 @@
++@example
++@c man begin SYNOPSIS
++usage: kvm_stat [OPTION]...
++@c man end
++@end example
++
++@c man begin DESCRIPTION
++
++kvm_stat prints counts of KVM kernel module trace events.  These events signify
++state transitions such as guest mode entry and exit.
++
++This tool is useful for observing guest behavior from the host perspective.
++Often conclusions about performance or buggy behavior can be drawn from the
++output.
++
++The set of KVM kernel module trace events may be specific to the kernel version
++or architecture.  It is best to check the KVM kernel module source code for the
++meaning of events.
++
++@c man end
++
++@c man begin OPTIONS
++@table @option
++@item -1, --once, --batch
++  run in batch mode for one second
++@item -l, --log
++  run in logging mode (like vmstat)
++@item -t, --tracepoints
++  retrieve statistics from tracepoints
++@item -d, --debugfs
++  retrieve statistics from debugfs
++@item -p, --pid=@var{pid}
++  limit statistics to one virtual machine (pid)
++@item -f, --fields=@var{fields}
++  fields to display (regex)
++@item -h, --help
++  show help message
++@end table
++
++@c man end
++
++@ignore
++
++@setfilename kvm_stat
++@settitle Report KVM kernel module event counters.
++
++@c man begin AUTHOR
++Stefan Hajnoczi <stefanha@redhat.com>
++@c man end
++
++@c man begin SEEALSO
++perf(1), trace-cmd(1)
++@c man end
++
++@end ignore
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0028-migcompat-e1000e-Work-around-7.3-msi-intr_state-fiel.patch b/SOURCES/0028-migcompat-e1000e-Work-around-7.3-msi-intr_state-fiel.patch
new file mode 100644
index 0000000..638b502
--- /dev/null
+++ b/SOURCES/0028-migcompat-e1000e-Work-around-7.3-msi-intr_state-fiel.patch
@@ -0,0 +1,135 @@
+From cc306393d79691b82c1f5f660a01bf00fe0775e9 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Thu, 9 Feb 2017 13:06:18 +0100
+Subject: migcompat/e1000e: Work around 7.3 msi/intr_state field
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20170209130618.20328-1-dgilbert@redhat.com>
+Patchwork-id: 73730
+O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH 1/1] migcompat/e1000e: Work around 7.3 msi/intr_state field
+Bugzilla: 1420216
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Xiao Wang <jasowang@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+bz: https://bugzilla.redhat.com/show_bug.cgi?id=1420216
+brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=12518741
+upstream: No, fixing downstream inconsistency
+
+Our 7.3 e1000e model has an 'intr_state' field that's used
+only in the cleanup of msi & msix.
+
+e1000e was introducing in 2.7 but was backported to the 2.6 based
+qemu-kvm-rhev 7.3 by backporting 6f3fbe4 and 103916.
+
+During the 2.7rc's the migration structure was changed by
+e0af5a0e8 and 66bf7d but we never pulled those into 7.3 which
+removed the 'intr_state' field.
+
+For compatibility add the field back (guarded by a property on 7.3)
+and populate the values based on the source MSI state.
+Since the flags were only used for cleanup I don't think
+we need to pay attention to the value we receive.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 7b3c2e676cd62e947e9b020bba9309a171e94c9e)
+---
+ hw/net/e1000e.c     | 21 +++++++++++++++++++++
+ include/hw/compat.h |  4 ++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
+index 2c91d07..d6ca464 100644
+--- a/hw/net/e1000e.c
++++ b/hw/net/e1000e.c
+@@ -74,6 +74,11 @@ typedef struct E1000EState {
+ 
+     E1000ECore core;
+ 
++    /* 7.3 had the intr_state field that was in the original e1000e code
++     * but that was removed prior to 2.7's release
++     */
++    bool redhat_7_3_intr_state_enable;
++    uint32_t redhat_7_3_intr_state;
+ } E1000EState;
+ 
+ #define E1000E_MMIO_IDX     0
+@@ -89,6 +94,10 @@ typedef struct E1000EState {
+ #define E1000E_MSIX_TABLE   (0x0000)
+ #define E1000E_MSIX_PBA     (0x2000)
+ 
++/* Values as in RHEL 7.3 build and original upstream */
++#define RH_E1000E_USE_MSI     BIT(0)
++#define RH_E1000E_USE_MSIX    BIT(1)
++
+ static uint64_t
+ e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size)
+ {
+@@ -300,6 +309,8 @@ e1000e_init_msix(E1000EState *s)
+     } else {
+         if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
+             msix_uninit(d, &s->msix, &s->msix);
++        } else {
++            s->redhat_7_3_intr_state |= RH_E1000E_USE_MSIX;
+         }
+     }
+ }
+@@ -471,6 +482,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp)
+     ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL);
+     if (ret) {
+         trace_e1000e_msi_init_fail(ret);
++    } else {
++        s->redhat_7_3_intr_state |= RH_E1000E_USE_MSI;
+     }
+ 
+     if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset,
+@@ -592,6 +605,11 @@ static const VMStateDescription e1000e_vmstate_intr_timer = {
+     VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0,                           \
+                          e1000e_vmstate_intr_timer, E1000IntrDelayTimer)
+ 
++static bool rhel_7_3_check(void *opaque, int version_id)
++{
++    return ((E1000EState *)opaque)->redhat_7_3_intr_state_enable;
++}
++
+ static const VMStateDescription e1000e_vmstate = {
+     .name = "e1000e",
+     .version_id = 1,
+@@ -603,6 +621,7 @@ static const VMStateDescription e1000e_vmstate = {
+         VMSTATE_MSIX(parent_obj, E1000EState),
+ 
+         VMSTATE_UINT32(ioaddr, E1000EState),
++        VMSTATE_UINT32_TEST(redhat_7_3_intr_state, E1000EState, rhel_7_3_check),
+         VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState),
+         VMSTATE_UINT8(core.rx_desc_len, E1000EState),
+         VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState,
+@@ -651,6 +670,8 @@ static PropertyInfo e1000e_prop_disable_vnet,
+ 
+ static Property e1000e_properties[] = {
+     DEFINE_NIC_PROPERTIES(E1000EState, conf),
++    DEFINE_PROP_BOOL("__redhat_e1000e_7_3_intr_state", E1000EState,
++                        redhat_7_3_intr_state_enable, false),
+     DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, false,
+                         e1000e_prop_disable_vnet, bool),
+     DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven,
+diff --git a/include/hw/compat.h b/include/hw/compat.h
+index bb138cd..56cefc9 100644
+--- a/include/hw/compat.h
++++ b/include/hw/compat.h
+@@ -407,6 +407,10 @@
+         .driver   = "virtio-pci",\
+         .property = "x-pcie-pm-init",\
+         .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "e1000e",\
++        .property = "__redhat_e1000e_7_3_intr_state",\
++        .value    = "on",\
+     },
+ 
+ #endif /* HW_COMPAT_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0029-migcompat-rtl8139-Work-around-version-bump.patch b/SOURCES/0029-migcompat-rtl8139-Work-around-version-bump.patch
new file mode 100644
index 0000000..b794755
--- /dev/null
+++ b/SOURCES/0029-migcompat-rtl8139-Work-around-version-bump.patch
@@ -0,0 +1,62 @@
+From c4753f76a30a3e96c573d8e863587ba3e686348e Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 29 Mar 2017 10:57:23 +0200
+Subject: migcompat/rtl8139: Work around version bump
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20170329105723.7789-2-dgilbert@redhat.com>
+Patchwork-id: 74581
+O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH v2 1/1] migcompat/rtl8139: Work around version bump
+Bugzilla: 1420195
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+commit 46fe8bef in 2.7 bumped the version number of the rtl8139
+vmstate, and added back a field that had been lost ~7 years ago
+by 9d29cde in v0.11.
+
+To keep backwards compatibility we can't bump the version, so push
+the version number back down and remove the field that was added.
+The field doesn't seem to be that significant, especially since we've
+survived for 7 years with out it.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Rebase notes (2.9.0):
+- Patch rewritten
+
+(cherry picked from commit 45ca263288bcbc98f36fae68c55e1a1b55e09221)
+---
+ hw/net/rtl8139.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
+index 450658c..80c62dc 100644
+--- a/hw/net/rtl8139.c
++++ b/hw/net/rtl8139.c
+@@ -3206,7 +3206,7 @@ static void rtl8139_pre_save(void *opaque)
+ 
+ static const VMStateDescription vmstate_rtl8139 = {
+     .name = "rtl8139",
+-    .version_id = 5,
++    .version_id = 4,
+     .minimum_version_id = 3,
+     .post_load = rtl8139_post_load,
+     .pre_save  = rtl8139_pre_save,
+@@ -3287,7 +3287,9 @@ static const VMStateDescription vmstate_rtl8139 = {
+         VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
+         VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
+         VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
++#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */
+         VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5),
++#endif
+         VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State),
+         VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0030-usb-xhci-Fix-PCI-capability-order.patch b/SOURCES/0030-usb-xhci-Fix-PCI-capability-order.patch
new file mode 100644
index 0000000..e722504
--- /dev/null
+++ b/SOURCES/0030-usb-xhci-Fix-PCI-capability-order.patch
@@ -0,0 +1,88 @@
+From 2dd7402227e77d748a7375233ac9e7feab244bda Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Fri, 5 May 2017 19:06:14 +0200
+Subject: usb-xhci: Fix PCI capability order
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20170505190614.15987-2-dgilbert@redhat.com>
+Patchwork-id: 75038
+O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH 1/1] usb-xhci: Fix PCI capability order
+Bugzilla: 1447874
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Upstream commit 1108b2f8a9 in 2.7.0 changed the order
+of the PCI capability chain in the XHCI pci device in the case
+where the device has the PCIe endpoint capability (i.e. only
+older machine types, pc-i440fx-2.0 upstream, pc-i440fx-rhel7.0.0
+apparently for us).
+
+Changing the order breaks migration compatibility; fixing this
+upstream would mean breaking the same case going from 2.7.0->current
+that currently works 2.7.0->2.9.0 - so upstream it's a choice
+of two breakages.
+
+Since we never released 2.7.0/2.8.0 we can fix this downstream.
+
+This reverts the order so that we create the capabilities in the
+order:
+   PCIe
+   MSI
+   MSI-X
+
+The symptom is:
+qemu-kvm: get_pci_config_device: Bad config data: i=0x71 read: a0 device: 0 cmask: ff wmask: 0 w1cmask:0
+qemu-kvm: Failed to load PCIDevice:config
+qemu-kvm: Failed to load xhci:parent_obj
+qemu-kvm: error while loading state for instance 0x0 of device '0000:00:0d.0/xhci'
+qemu-kvm: load of migration failed: Invalid argument
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+--
+Rebase notes (2.9.0):
+- Change in assert condition (upstream)
+
+(cherry picked from commit aad727a5ecde1ad4935eb8427604d4df5a1f1f35)
+---
+ hw/usb/hcd-xhci.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
+index 10848db..53de805 100644
+--- a/hw/usb/hcd-xhci.c
++++ b/hw/usb/hcd-xhci.c
+@@ -3368,6 +3368,12 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
+         xhci->max_pstreams_mask = 0;
+     }
+ 
++    if (pci_bus_is_express(dev->bus) ||
++        xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
++        ret = pcie_endpoint_cap_init(dev, 0xa0);
++        assert(ret > 0);
++    }
++
+     if (xhci->msi != ON_OFF_AUTO_OFF) {
+         ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err);
+         /* Any error other than -ENOTSUP(board's MSI support is broken)
+@@ -3416,12 +3422,6 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
+                      PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
+                      &xhci->mem);
+ 
+-    if (pci_bus_is_express(dev->bus) ||
+-        xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
+-        ret = pcie_endpoint_cap_init(dev, 0xa0);
+-        assert(ret > 0);
+-    }
+-
+     if (xhci->msix != ON_OFF_AUTO_OFF) {
+         /* TODO check for errors, and should fail when msix=on */
+         msix_init(dev, xhci->numintrs,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0031-blockdev-ignore-aio-native-for-empty-drives.patch b/SOURCES/0031-blockdev-ignore-aio-native-for-empty-drives.patch
new file mode 100644
index 0000000..000fea4
--- /dev/null
+++ b/SOURCES/0031-blockdev-ignore-aio-native-for-empty-drives.patch
@@ -0,0 +1,74 @@
+From a72f1c0f7b02ea571ec2ce35dfbe8c17c4dfa6d9 Mon Sep 17 00:00:00 2001
+From: John Snow <jsnow@redhat.com>
+Date: Thu, 11 May 2017 20:53:51 +0200
+Subject: blockdev: ignore aio=native for empty drives
+
+RH-Author: John Snow <jsnow@redhat.com>
+Message-id: <20170511205351.6337-2-jsnow@redhat.com>
+Patchwork-id: 75070
+O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH 1/1] blockdev: ignore aio=native for empty drives
+Bugzilla: 1402645
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+This is a bit of a gross one; Upstream QEMU changed the way it handles
+cache options with regards to removable media, associating options more
+with the medium instead of the device. As part of that, it became
+impossible to specify cache options on empty drives.
+
+In the future, one would use blockdev-add instead to choose cache options
+per-medium instead of per-device, but we're not there yet in libvirt so
+we added a workaround downstream to simply ignore cache options on empty
+CDROMs under the premise of "It actually never worked anyway."
+
+As fallout from this decision, it is now no longer possible to specify
+aio=native on empty CDROM devices either, as that requires the use of a
+cache option that you can no longer specify. As a bad, gross, disgusting
+workaround, simply ignore aio=native on empty drives until such time that
+libvirt stops providing such configurations.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit cda174ad842c9a61bc275315bf3155139ba19bc0)
+---
+ blockdev.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 6d4cb70..d54ea6f 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -476,6 +476,21 @@ static bool __redhat_com_has_bs_opts(QDict *bs_opts)
+     return s != n;
+ }
+ 
++/**
++ * libvirt expects to be able to pass io driver options (aio=native) for CDROM
++ * drives without inserted media. While this has worked historically, given the
++ * above workaround and lack of a supported alternative in current versions of
++ * libvirt, certain options such as aio=native cannot be supported as it
++ * requires the use of an accompanying cache option, which we also ignore.
++ * Until libvirt learns how to supply cache options to inserted media, ignore
++ * the aio= preference on empty CDROMs with the understanding that un-tuned
++ * performance is preferable to being unable to use the CDROM at all.
++ */
++static int __redhat_com_filter_flags(int flags)
++{
++    return flags & ~BDRV_O_NATIVE_AIO;
++}
++
+ /* Takes the ownership of bs_opts */
+ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
+                                    Error **errp)
+@@ -588,7 +603,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
+ 
+         blk = blk_new(0, BLK_PERM_ALL);
+         blk_rs = blk_get_root_state(blk);
+-        blk_rs->open_flags    = bdrv_flags;
++        blk_rs->open_flags    = __redhat_com_filter_flags(bdrv_flags);
+         blk_rs->read_only     = read_only;
+         blk_rs->detect_zeroes = detect_zeroes;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0032-scsi-Disable-deprecated-implicit-SCSI-HBA-creation-m.patch b/SOURCES/0032-scsi-Disable-deprecated-implicit-SCSI-HBA-creation-m.patch
new file mode 100644
index 0000000..485f34d
--- /dev/null
+++ b/SOURCES/0032-scsi-Disable-deprecated-implicit-SCSI-HBA-creation-m.patch
@@ -0,0 +1,122 @@
+From 4c43abf1394c3711f93a4e0175ff5c10769f6480 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Fri, 28 Apr 2017 12:22:27 +0200
+Subject: scsi: Disable deprecated implicit SCSI HBA creation more cleanly
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <1493382147-23057-2-git-send-email-armbru@redhat.com>
+Patchwork-id: 74946
+O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH] scsi: Disable deprecated implicit SCSI HBA creation more cleanly
+Bugzilla: 971799
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+The PC machines (pc-q35-* pc-i440fx-* pc-* isapc xenfv) automatically
+create lsi53c895a SCSI HBAs and SCSI devices to honor -drive if=scsi.
+Deprecated upstream since commit f778a82, v2.9.0, not supported at all
+in RHEL.  The way it fails is rather ugly, though:
+
+    $ qemu-kvm -nodefaults -S -drive if=scsi,media=cdrom
+    qemu-kvm: Unknown device 'lsi53c895a' for bus 'PCI'
+    Aborted (core dumped)
+
+Recent upstream work permit us to make this fail cleanly by commenting
+out the code that tries to create lsi53c895a SCSI HBAs in
+pc_pci_device_init():
+
+    qemu-kvm: -drive if=scsi,media=cdrom: machine type does not support if=scsi,bus=0,unit=0
+
+However, by itself this would make another deprecated feature
+available in RHEL: drives defined with if=scsi get picked up by SCSI
+HBAs added with -device, unlike other interface types.  Deprecated
+upstream since commit a64aa57, v2.9.0.  Comment out that code, too.
+Bonus: that code can be rather slow with a large number of drives, so
+good riddance.
+
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit 7977e603169c92da4b0ecd656c3346500a93897b)
+---
+ hw/i386/pc.c       | 2 ++
+ hw/scsi/scsi-bus.c | 7 +++++++
+ vl.c               | 2 ++
+ 3 files changed, 11 insertions(+)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index ae23fc4..ccaa832 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -1645,6 +1645,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
+ 
+ void pc_pci_device_init(PCIBus *pci_bus)
+ {
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+     int max_bus;
+     int bus;
+ 
+@@ -1658,6 +1659,7 @@ void pc_pci_device_init(PCIBus *pci_bus)
+          * this usage is deprecated.
+          */
+     }
++#endif
+ }
+ 
+ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index e364410..309daaa 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -265,6 +265,8 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
+ 
+ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
+ {
++#if 0 /* Disabled for Red Hat Enterprise Linux */
++
+     Location loc;
+     DriveInfo *dinfo;
+     int unit;
+@@ -291,8 +293,11 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
+                                   unit, false, -1, NULL, &error_fatal);
+     }
+     loc_pop(&loc);
++#endif
+ }
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
++
+ static bool is_scsi_hba_with_legacy_magic(Object *obj)
+ {
+     static const char *magic[] = {
+@@ -329,6 +334,8 @@ void scsi_legacy_handle_cmdline(void)
+                                    scsi_legacy_handle_cmdline_cb, NULL);
+ }
+ 
++#endif
++
+ static int32_t scsi_invalid_field(SCSIRequest *req, uint8_t *buf)
+ {
+     scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD));
+diff --git a/vl.c b/vl.c
+index 59f515c..183b7f7 100644
+--- a/vl.c
++++ b/vl.c
+@@ -4676,6 +4676,7 @@ int main(int argc, char **argv, char **envp)
+ 
+     rom_reset_order_override();
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+     /*
+      * Create frontends for -drive if=scsi leftovers.
+      * Normally, frontends for -drive get created by machine
+@@ -4684,6 +4685,7 @@ int main(int argc, char **argv, char **envp)
+      * implementation accident, and deprecated.
+      */
+     scsi_legacy_handle_cmdline();
++#endif
+ 
+     /* Did we create any drives that we failed to create a device for? */
+     drive_check_orphaned();
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0033-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch b/SOURCES/0033-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch
new file mode 100644
index 0000000..8b62881
--- /dev/null
+++ b/SOURCES/0033-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch
@@ -0,0 +1,66 @@
+From c9c4f117d8b507c2f86035c282d537c0a327364f Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Wed, 14 Jun 2017 15:37:01 +0200
+Subject: virtio-scsi: Reject scsi-cd if data plane enabled [RHEL only]
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20170614153701.14757-1-famz@redhat.com>
+Patchwork-id: 75613
+O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH v3] virtio-scsi: Reject scsi-cd if data plane enabled [RHEL only]
+Bugzilla: 1378816
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+We need a fix for RHEL 7.4 and 7.3.z, but unfortunately upstream isn't
+ready. If it were, the changes will be too invasive. To have an idea:
+
+https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg05400.html
+
+is an incomplete attempt to fix part of the issue, and the remaining
+work unfortunately involve even more complex changes.
+
+As a band-aid, this partially reverts the effect of ef8875b
+(virtio-scsi: Remove op blocker for dataplane, since v2.7). We cannot
+simply revert that commit as a whole because we already shipped it in
+qemu-kvm-rhev 7.3, since when, block jobs has been possible.  We should
+only block what has been broken.  Also, faithfully reverting the above
+commit means adding back the removed op blocker, but that is not enough,
+because it still crashes when inserting media into an initially empty
+scsi-cd.
+
+All in all, scsi-cd on virtio-scsi-dataplane has basically been unusable
+unless the scsi-cd never enters an empty state, so, disable it
+altogether.  Otherwise it would be much more difficult to avoid
+crashing.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+(cherry picked from commit b0caf00bbc35c7d89e02999bdce86e1f867728e8)
+---
+ hw/scsi/virtio-scsi.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
+index eb63944..2635c38 100644
+--- a/hw/scsi/virtio-scsi.c
++++ b/hw/scsi/virtio-scsi.c
+@@ -790,6 +790,15 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
+     VirtIOSCSI *s = VIRTIO_SCSI(vdev);
+     SCSIDevice *sd = SCSI_DEVICE(dev);
+ 
++    /* XXX: Remove this check once block backend is capable of handling
++     * AioContext change upon eject/insert.
++     * s->ctx is NULL if ioeventfd is off, s->ctx is qemu_get_aio_context() if
++     * data plane is not used, both cases are safe for scsi-cd. */
++    if (s->ctx && s->ctx != qemu_get_aio_context() &&
++        object_dynamic_cast(OBJECT(dev), "scsi-cd")) {
++        error_setg(errp, "scsi-cd is not supported by data plane");
++        return;
++    }
+     if (s->ctx && !s->dataplane_fenced) {
+         if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
+             return;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0034-hmp-fix-dump-quest-memory-segfault-ppc.patch b/SOURCES/0034-hmp-fix-dump-quest-memory-segfault-ppc.patch
new file mode 100644
index 0000000..d5431ac
--- /dev/null
+++ b/SOURCES/0034-hmp-fix-dump-quest-memory-segfault-ppc.patch
@@ -0,0 +1,53 @@
+From 647e9ff9107bb3c1536b995281e8db905bcb4164 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 13 Sep 2017 16:20:33 +0200
+Subject: hmp: fix "dump-quest-memory" segfault (ppc)
+
+Running QEMU with
+    qemu-system-ppc64 -M none -nographic -m 256
+and executing
+    dump-guest-memory /dev/null 0 8192
+results in segfault
+
+Fix by checking if we have CPU, and exit with
+error if there is no CPU:
+
+    (qemu) dump-guest-memory /dev/null
+    this feature or command is not currently supported
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <20170913142036.2469-2-lvivier@redhat.com>
+Acked-by: David Gibson <david@gibson.dropbear.id.au>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit b1fde1ef5106c92dd12f1f0cfcb8c76e57d7f681)
+---
+ target/ppc/arch_dump.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
+index 8e9397a..95b9ab6 100644
+--- a/target/ppc/arch_dump.c
++++ b/target/ppc/arch_dump.c
+@@ -224,8 +224,15 @@ typedef struct NoteFuncDescStruct NoteFuncDesc;
+ int cpu_get_dump_info(ArchDumpInfo *info,
+                       const struct GuestPhysBlockList *guest_phys_blocks)
+ {
+-    PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
++    PowerPCCPU *cpu;
++    PowerPCCPUClass *pcc;
++
++    if (first_cpu == NULL) {
++        return -1;
++    }
++
++    cpu = POWERPC_CPU(first_cpu);
++    pcc = POWERPC_CPU_GET_CLASS(cpu);
+ 
+     info->d_machine = PPC_ELF_MACHINE;
+     info->d_class = ELFCLASS;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0035-hmp-fix-dump-quest-memory-segfault-arm.patch b/SOURCES/0035-hmp-fix-dump-quest-memory-segfault-arm.patch
new file mode 100644
index 0000000..3b4403b
--- /dev/null
+++ b/SOURCES/0035-hmp-fix-dump-quest-memory-segfault-arm.patch
@@ -0,0 +1,57 @@
+From 14dc40db1b710c64fbb2eeccde1afefa0a37cd1e Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 13 Sep 2017 16:20:34 +0200
+Subject: hmp: fix "dump-quest-memory" segfault (arm)
+
+Running QEMU with
+    qemu-system-aarch64 -M none -nographic -m 256
+and executing
+    dump-guest-memory /dev/null 0 8192
+results in segfault
+
+Fix by checking if we have CPU, and exit with
+error if there is no CPU:
+
+    (qemu) dump-guest-memory /dev/null
+    this feature or command is not currently supported
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Message-Id: <20170913142036.2469-3-lvivier@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 6dba634097d54db60017f10c160a052e46bdf60d)
+---
+ target/arm/arch_dump.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
+index 1a9861f..9e5b2fb 100644
+--- a/target/arm/arch_dump.c
++++ b/target/arm/arch_dump.c
+@@ -273,11 +273,18 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+ int cpu_get_dump_info(ArchDumpInfo *info,
+                       const GuestPhysBlockList *guest_phys_blocks)
+ {
+-    ARMCPU *cpu = ARM_CPU(first_cpu);
+-    CPUARMState *env = &cpu->env;
++    ARMCPU *cpu;
++    CPUARMState *env;
+     GuestPhysBlock *block;
+     hwaddr lowest_addr = ULLONG_MAX;
+ 
++    if (first_cpu == NULL) {
++        return -1;
++    }
++
++    cpu = ARM_CPU(first_cpu);
++    env = &cpu->env;
++
+     /* Take a best guess at the phys_base. If we get it wrong then crash
+      * will need '--machdep phys_offset=<phys-offset>' added to its command
+      * line, which isn't any worse than assuming we can use zero, but being
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0036-dump-do-not-dump-non-existent-guest-memory.patch b/SOURCES/0036-dump-do-not-dump-non-existent-guest-memory.patch
new file mode 100644
index 0000000..da3d2c3
--- /dev/null
+++ b/SOURCES/0036-dump-do-not-dump-non-existent-guest-memory.patch
@@ -0,0 +1,50 @@
+From 4fd31afb27446d33e659cb279691aa94270e6bfb Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Wed, 13 Sep 2017 16:20:35 +0200
+Subject: dump: do not dump non-existent guest memory
+
+It does not really make sense to dump memory that is not there.
+
+Moreover, that fixes a segmentation fault when calling dump-guest-memory
+with no filter for a machine with no memory defined.
+
+New behaviour is:
+
+(qemu) dump-guest-memory /dev/null
+dump: no guest memory to dump
+(qemu) dump-guest-memory /dev/null 0 4096
+dump: no guest memory to dump
+
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Tested-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Message-Id: <20170913142036.2469-4-lvivier@redhat.com>
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit d1e6994abcd12c7f54aa73ff848fb6215c783898)
+---
+ dump.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/dump.c b/dump.c
+index d9090a2..99117ba 100644
+--- a/dump.c
++++ b/dump.c
+@@ -1536,6 +1536,12 @@ static void dump_init(DumpState *s, int fd, bool has_format,
+     fprintf(stderr, "DUMP: total memory to dump: %lu\n", s->total_size);
+ #endif
+ 
++    /* it does not make sense to dump non-existent memory */
++    if (!s->total_size) {
++        error_setg(errp, "dump: no guest memory to dump");
++        goto cleanup;
++    }
++
+     s->start = get_start_block(s);
+     if (s->start == -1) {
+         error_setg(errp, QERR_INVALID_PARAMETER, "begin");
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0037-tests-hmp-test-none-machine-with-memory.patch b/SOURCES/0037-tests-hmp-test-none-machine-with-memory.patch
new file mode 100644
index 0000000..13c2127
--- /dev/null
+++ b/SOURCES/0037-tests-hmp-test-none-machine-with-memory.patch
@@ -0,0 +1,42 @@
+From f4217185263cd9a3e2da574648b9bf72e65d9ad6 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 13 Sep 2017 16:20:36 +0200
+Subject: tests/hmp: test "none" machine with memory
+
+and add a test case of dump-guest-memory without
+"[begin length]" parameters.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20170913142036.2469-5-lvivier@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 4e5c3a3742adcf7514b73f4da1c005ee7b35e41b)
+---
+ tests/test-hmp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/test-hmp.c b/tests/test-hmp.c
+index 729c033..d124e81 100644
+--- a/tests/test-hmp.c
++++ b/tests/test-hmp.c
+@@ -35,6 +35,7 @@ static const char *hmp_cmds[] = {
+     "mouse_button 0",
+     "device_del mouse1",
+     "dump-guest-memory /dev/null 0 4096",
++    "dump-guest-memory /dev/null",
+     "gdbserver",
+     "host_net_add user id=net0",
+     "hostfwd_add tcp::43210-:43210",
+@@ -159,5 +160,8 @@ int main(int argc, char **argv)
+ 
+     qtest_cb_for_every_machine(add_machine_test_case);
+ 
++    /* as none machine has no memory by default, add a test case with memory */
++    qtest_add_data_func("hmp/none+2MB", g_strdup("none -m 2"), test_machine);
++
+     return g_test_run();
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0038-vfio-spapr-Fix-levels-calculation.patch b/SOURCES/0038-vfio-spapr-Fix-levels-calculation.patch
new file mode 100644
index 0000000..7b7331b
--- /dev/null
+++ b/SOURCES/0038-vfio-spapr-Fix-levels-calculation.patch
@@ -0,0 +1,51 @@
+From 6ef9f439f68181319e04b5fd6bfb1a2e36d4bbee Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Mon, 18 Sep 2017 00:20:08 +0100
+Subject: vfio, spapr: Fix levels calculation
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20170918002008.24430-1-dgibson@redhat.com>
+Patchwork-id: 76404
+O-Subject: [Pegas-1.0 qemu-kvm PATCH] vfio, spapr: Fix levels calculation
+Bugzilla: 1491749
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Suraj Jitindar Singh <sursingh@redhat.com>
+RH-Acked-by: Sam Bobroff <sbobroff@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+The existing tries to round up the number of pages but @pages is always
+calculated as the rounded up value minus one  which makes ctz64() always
+return 0 and have create.levels always set 1.
+
+This removes wrong "-1" and allows having more than 1 levels. This becomes
+handy for >128GB guests with standard 64K pages as this requires blocks
+with zone order 9 and the popular limit of CONFIG_FORCE_MAX_ZONEORDER=9
+means that only blocks up to order 8 are allowed.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit e100161b69f8cf56dae866912dfffe7dcd7140af)
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+(cherry picked from commit b83a6ae1492fa004c6e0e34cfb3ac8efe21e7bd2)
+---
+ hw/vfio/spapr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
+index 32fd6a9..259397c 100644
+--- a/hw/vfio/spapr.c
++++ b/hw/vfio/spapr.c
+@@ -163,7 +163,7 @@ int vfio_spapr_create_window(VFIOContainer *container,
+      */
+     entries = create.window_size >> create.page_shift;
+     pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);
+-    pages = MAX(pow2ceil(pages) - 1, 1); /* Round up */
++    pages = MAX(pow2ceil(pages), 1); /* Round up */
+     create.levels = ctz64(pages) / 6 + 1;
+ 
+     ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/80-kvm.rules b/SOURCES/80-kvm.rules
new file mode 100644
index 0000000..4ad7d43
--- /dev/null
+++ b/SOURCES/80-kvm.rules
@@ -0,0 +1 @@
+KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"
diff --git a/SOURCES/85-kvm.preset b/SOURCES/85-kvm.preset
new file mode 100644
index 0000000..8024052
--- /dev/null
+++ b/SOURCES/85-kvm.preset
@@ -0,0 +1,5 @@
+# Enable kvm-setup by default.  This can have odd side effects on
+# PowerNV systems that aren't intended as KVM hosts, but at present we
+# only support RHEL on PowerNV for the purpose of being a RHEV host.
+
+enable kvm-setup.service
diff --git a/SOURCES/95-kvm-memlock.conf b/SOURCES/95-kvm-memlock.conf
new file mode 100644
index 0000000..fc59dbe
--- /dev/null
+++ b/SOURCES/95-kvm-memlock.conf
@@ -0,0 +1,10 @@
+# The KVM HV implementation on Power can require a significant amount
+# of unswappable memory (about half of which also needs to be host
+# physically contiguous) to hold the guest's Hash Page Table (HPT) -
+# roughly 1/64th of the guest's RAM size, minimum 16MiB.
+#
+# These limits allow unprivileged users to start smallish VMs, such as
+# those used by libguestfs.
+#
+*	hard	memlock		65536
+*	soft	memlock		65536
diff --git a/SOURCES/99-qemu-guest-agent.rules b/SOURCES/99-qemu-guest-agent.rules
new file mode 100644
index 0000000..8a290ab
--- /dev/null
+++ b/SOURCES/99-qemu-guest-agent.rules
@@ -0,0 +1,2 @@
+SUBSYSTEM=="virtio-ports", ATTR{name}=="org.qemu.guest_agent.0", \
+  TAG+="systemd" ENV{SYSTEMD_WANTS}="qemu-guest-agent.service"
diff --git a/SOURCES/README.rhel6-gpxe-source b/SOURCES/README.rhel6-gpxe-source
new file mode 100644
index 0000000..959ac38
--- /dev/null
+++ b/SOURCES/README.rhel6-gpxe-source
@@ -0,0 +1,9 @@
+The ROM images on /usr/share/qemu-kvm/rhel6-*.rom come from the
+Red Hat Enterprise Linux 6.4 package gpxe-roms-qemu-0.9.7-6.16.el6.noarch.rpm.
+
+The source code for those images can be downloaded from:
+http://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/gpxe-0.9.7-6.16.el6.src.rpm
+
+For more information on how to obtain source code for Red Hat Enterprise Linux
+software, you can refer to Chapter 1. Obtaining Red Hat Enterprise Linux of the
+Red Hat Enterprise Linux Installation Guide.
diff --git a/SOURCES/bridge.conf b/SOURCES/bridge.conf
new file mode 100644
index 0000000..a573665
--- /dev/null
+++ b/SOURCES/bridge.conf
@@ -0,0 +1 @@
+allow virbr0
diff --git a/SOURCES/build_configure.sh b/SOURCES/build_configure.sh
new file mode 100755
index 0000000..97f1c1f
--- /dev/null
+++ b/SOURCES/build_configure.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+
+_prefix=$1
+shift
+_libdir=$1
+shift
+_sysconfdir=$1
+shift
+_localstatedir=$1
+shift
+_libexecdir=$1
+shift
+qemudocdir=$1
+shift
+pkgname=$1
+shift
+arch=$1
+shift
+nvr=$1
+shift
+optflags=$1
+shift
+have_fdt=$1
+shift
+have_gluster=$1
+shift
+have_guest_agent=$1
+shift
+have_numa=$1
+shift
+have_rbd=$1
+shift
+have_rdma=$1
+shift
+have_seccomp=$1
+shift
+have_spice=$1
+shift
+have_usbredir=$1
+shift
+have_tcmalloc=$1
+shift
+have_vxhs=$1
+shift
+have_vtd=$1
+shift
+have_live_block_ops=$1
+shift
+have_vhost_user=$1
+shift
+is_rhv=$1
+shift
+
+if [ "$have_rbd" == "enable" ]; then
+  rbd_driver=rbd,
+fi
+
+if [ "$have_gluster" == "enable" ]; then
+  gluster_driver=gluster,
+fi
+
+if [ "$have_vxhs" == "enable" ]; then
+  vxhs_driver=vxhs,
+fi
+
+if [ "$is_rhv" == "enable" ]; then
+  rhel_target=rhv
+else
+  rhel_target=rhel
+fi
+
+./configure \
+    --prefix=${_prefix} \
+    --libdir=${_libdir} \
+    --sysconfdir=${_sysconfdir} \
+    --interp-prefix=${_prefix}/qemu-%M \
+    --localstatedir=${_localstatedir} \
+    --docdir=${qemudocdir} \
+    --libexecdir=${_libexecdir} \
+    --extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \
+    --extra-cflags="${optflags} -fPIE -DPIE" \
+    --with-pkgversion=${nvr} \
+    --with-confsuffix=/${pkgname} \
+    --with-coroutine=ucontext \
+    --with-system-pixman \
+    --tls-priority=NORMAL \
+    --disable-bluez \
+    --disable-brlapi \
+    --disable-cap-ng \
+    --enable-coroutine-pool \
+    --enable-curl \
+    --disable-curses \
+    --disable-debug-tcg \
+    --enable-docs \
+    --disable-gtk \
+    --enable-kvm \
+    --enable-libiscsi \
+    --disable-libnfs \
+    --enable-libssh2 \
+    --enable-libusb \
+    --disable-bzip2 \
+    --enable-linux-aio \
+    --disable-live-block-migration \
+    --enable-lzo \
+    --disable-opengl \
+    --enable-pie \
+    --disable-qom-cast-debug \
+    --disable-sdl \
+    --enable-snappy \
+    --disable-sparse \
+    --disable-strip \
+    --disable-tpm \
+    --enable-trace-backend=dtrace \
+    --disable-vde \
+    --disable-vhost-scsi \
+    --disable-virtfs \
+    --disable-vnc-jpeg \
+    --disable-vte \
+    --enable-vnc-png \
+    --enable-vnc-sasl \
+    --enable-werror \
+    --disable-xen \
+    --disable-xfsctl \
+    --enable-gnutls \
+    --disable-gcrypt \
+    --enable-nettle \
+    --enable-attr \
+    --disable-bsd-user \
+    --disable-cocoa \
+    --enable-debug-info \
+    --disable-guest-agent-msi \
+    --disable-hax \
+    --disable-jemalloc \
+    --disable-linux-user \
+    --disable-modules \
+    --disable-netmap \
+    --disable-replication \
+    --enable-system \
+    --enable-tools \
+    --disable-user \
+    --enable-vhost-net \
+    --enable-vhost-vsock \
+    --enable-vnc \
+    --enable-mpath \
+    --disable-virglrenderer \
+    --disable-xen-pci-passthrough \
+    --enable-tcg \
+    --disable-crypto-afalg \
+    --${have_fdt}-fdt \
+    --${have_gluster}-glusterfs \
+    --${have_guest_agent}-guest-agent \
+    --${have_numa}-numa \
+    --${have_rbd}-rbd \
+    --${have_rdma}-rdma \
+    --${have_seccomp}-seccomp \
+    --${have_spice}-spice \
+    --${have_spice}-smartcard \
+    --${have_usbredir}-usb-redir \
+    --${have_tcmalloc}-tcmalloc \
+    --${have_vxhs}-vxhs \
+    --${have_vtd}-vtd \
+    --${have_live_block_ops}-live-block-ops \
+    --${have_vhost_user}-vhost-user \
+    --audio-drv-list= \
+    --block-drv-rw-whitelist=qcow2,raw,file,host_device,nbd,iscsi,${gluster_driver}${rbd_driver}${vxhs_driver}blkdebug,luks,null-co \
+    --block-drv-ro-whitelist=vmdk,vhdx,vpc,https,ssh \
+    --rhel-target=${rhel_target} \
+    "$@"
diff --git a/SOURCES/ksm.service b/SOURCES/ksm.service
new file mode 100644
index 0000000..35c6f1d
--- /dev/null
+++ b/SOURCES/ksm.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Kernel Samepage Merging
+ConditionPathExists=/sys/kernel/mm/ksm
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+EnvironmentFile=-/etc/sysconfig/ksm
+ExecStart=/usr/libexec/ksmctl start
+ExecStop=/usr/libexec/ksmctl stop
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/ksm.sysconfig b/SOURCES/ksm.sysconfig
new file mode 100644
index 0000000..d99656d
--- /dev/null
+++ b/SOURCES/ksm.sysconfig
@@ -0,0 +1,4 @@
+# The maximum number of unswappable kernel pages
+# which may be allocated by ksm (0 for unlimited)
+# If unset, defaults to half of total memory
+# KSM_MAX_KERNEL_PAGES=
diff --git a/SOURCES/ksmctl.c b/SOURCES/ksmctl.c
new file mode 100644
index 0000000..af39591
--- /dev/null
+++ b/SOURCES/ksmctl.c
@@ -0,0 +1,77 @@
+/* Start/stop KSM, for systemd.
+ * Copyright (C) 2009, 2011 Red Hat, Inc.
+ * Written by Paolo Bonzini <pbonzini@redhat.com>.
+ * Based on the original sysvinit script by Dan Kenigsberg <danken@redhat.com>
+ * This file is distributed under the GNU General Public License, version 2
+ * or later.  */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define KSM_MAX_KERNEL_PAGES_FILE "/sys/kernel/mm/ksm/max_kernel_pages"
+#define KSM_RUN_FILE		  "/sys/kernel/mm/ksm/run"
+
+char *program_name;
+
+int usage(void)
+{
+	fprintf(stderr, "Usage: %s {start|stop}\n", program_name);
+	return 1;
+}
+
+int write_value(uint64_t value, char *filename)
+{
+	FILE *fp;
+	if (!(fp = fopen(filename, "w")) ||
+	    fprintf(fp, "%llu\n", (unsigned long long) value) == EOF ||
+	    fflush(fp) == EOF ||
+	    fclose(fp) == EOF)
+		return 1;
+
+	return 0;
+}
+
+uint64_t ksm_max_kernel_pages()
+{
+	char *var = getenv("KSM_MAX_KERNEL_PAGES");
+	char *endptr;
+	uint64_t value;
+	if (var && *var) {
+		value = strtoll(var, &endptr, 0);
+		if (value < LLONG_MAX && !*endptr)
+			return value;
+	}
+	/* Unless KSM_MAX_KERNEL_PAGES is set, let KSM munch up to half of
+	 * total memory.  */
+	return sysconf(_SC_PHYS_PAGES) / 2;
+}
+
+int start(void)
+{
+	if (access(KSM_MAX_KERNEL_PAGES_FILE, R_OK) >= 0)
+		write_value(ksm_max_kernel_pages(), KSM_MAX_KERNEL_PAGES_FILE);
+	return write_value(1, KSM_RUN_FILE);
+}
+
+int stop(void)
+{
+	return write_value(0, KSM_RUN_FILE);
+}
+
+int main(int argc, char **argv)
+{
+	program_name = argv[0];
+	if (argc < 2) {
+		return usage();
+	} else if (!strcmp(argv[1], "start")) {
+		return start();
+	} else if (!strcmp(argv[1], "stop")) {
+		return stop();
+	} else {
+		return usage();
+	}
+}
diff --git a/SOURCES/ksmtuned b/SOURCES/ksmtuned
new file mode 100644
index 0000000..320ce74
--- /dev/null
+++ b/SOURCES/ksmtuned
@@ -0,0 +1,138 @@
+#!/bin/bash
+#
+# Copyright 2009 Red Hat, Inc. and/or its affiliates.
+# Released under the GPL
+#
+# Author:      Dan Kenigsberg <danken@redhat.com>
+#
+# ksmtuned - a simple script that controls whether (and with what vigor) ksm
+# should search for duplicated pages.
+#
+# starts ksm when memory commited to qemu processes exceeds a threshold, and
+# make ksm work harder and harder untill memory load falls below that
+# threshold.
+#
+# send SIGUSR1 to this process right after a new qemu process is started, or
+# following its death, to retune ksm accordingly
+#
+# needs testing and ironing. contact danken@redhat.com if something breaks.
+
+if [ -f /etc/ksmtuned.conf ]; then
+    . /etc/ksmtuned.conf
+fi
+
+debug() {
+    if [ -n "$DEBUG" ]; then
+        s="`/bin/date`: $*"
+        [ -n "$LOGFILE" ] && echo "$s" >> "$LOGFILE" || echo "$s"
+    fi
+}
+
+
+KSM_MONITOR_INTERVAL=${KSM_MONITOR_INTERVAL:-60}
+KSM_NPAGES_BOOST=${KSM_NPAGES_BOOST:-300}
+KSM_NPAGES_DECAY=${KSM_NPAGES_DECAY:--50}
+
+KSM_NPAGES_MIN=${KSM_NPAGES_MIN:-64}
+KSM_NPAGES_MAX=${KSM_NPAGES_MAX:-1250}
+# millisecond sleep between ksm scans for 16Gb server. Smaller servers sleep
+# more, bigger sleep less.
+KSM_SLEEP_MSEC=${KSM_SLEEP_MSEC:-10}
+
+KSM_THRES_COEF=${KSM_THRES_COEF:-20}
+KSM_THRES_CONST=${KSM_THRES_CONST:-2048}
+
+total=`awk '/^MemTotal:/ {print $2}' /proc/meminfo`
+debug total $total
+
+npages=0
+sleep=$[KSM_SLEEP_MSEC * 16 * 1024 * 1024 / total]
+[ $sleep -le 10 ] && sleep=10
+debug sleep $sleep
+thres=$[total * KSM_THRES_COEF / 100]
+if [ $KSM_THRES_CONST -gt $thres ]; then
+    thres=$KSM_THRES_CONST
+fi
+debug thres $thres
+
+KSMCTL () {
+    case x$1 in
+        xstop)
+            echo 0 > /sys/kernel/mm/ksm/run
+            ;;
+        xstart)
+            echo $2 > /sys/kernel/mm/ksm/pages_to_scan
+            echo $3 > /sys/kernel/mm/ksm/sleep_millisecs
+            echo 1 > /sys/kernel/mm/ksm/run
+            ;;
+    esac
+}
+
+committed_memory () {
+    local pidlist
+    pidlist=$(pgrep -d ' ' -- '^qemu(-kvm|:.{1,11})$')
+    if [ -n "$pidlist" ]; then
+        ps -p "$pidlist" -o rsz=
+    fi | awk '{ sum += $1 }; END { print 0+sum }'
+}
+
+free_memory () {
+    awk '/^(MemFree|Buffers|Cached):/ {free += $2}; END {print free}' \
+                /proc/meminfo
+}
+
+increase_npages() {
+    local delta
+    delta=${1:-0}
+    npages=$[npages + delta]
+    if [ $npages -lt $KSM_NPAGES_MIN ]; then
+        npages=$KSM_NPAGES_MIN
+    elif [ $npages -gt $KSM_NPAGES_MAX ]; then
+        npages=$KSM_NPAGES_MAX
+    fi
+    echo $npages
+}
+
+
+adjust () {
+    local free committed
+    free=`free_memory`
+    committed=`committed_memory`
+    debug committed $committed free $free
+    if [ $[committed + thres] -lt $total -a $free -gt $thres ]; then
+        KSMCTL stop
+        debug "$[committed + thres] < $total and free > $thres, stop ksm"
+        return 1
+    fi
+    debug "$[committed + thres] > $total, start ksm"
+    if [ $free -lt $thres ]; then
+        npages=`increase_npages $KSM_NPAGES_BOOST`
+        debug "$free < $thres, boost"
+    else
+        npages=`increase_npages $KSM_NPAGES_DECAY`
+        debug "$free > $thres, decay"
+    fi
+    KSMCTL start $npages $sleep
+    debug "KSMCTL start $npages $sleep"
+    return 0
+}
+
+function nothing () {
+    :
+}
+
+loop () {
+    trap nothing SIGUSR1
+    while true
+    do
+        sleep $KSM_MONITOR_INTERVAL &
+        wait $!
+        adjust
+    done
+}
+
+PIDFILE=${PIDFILE-/var/run/ksmtune.pid}
+if touch "$PIDFILE"; then
+  loop &
+  echo $! > "$PIDFILE"
+fi
diff --git a/SOURCES/ksmtuned.conf b/SOURCES/ksmtuned.conf
new file mode 100644
index 0000000..fc4518c
--- /dev/null
+++ b/SOURCES/ksmtuned.conf
@@ -0,0 +1,21 @@
+# Configuration file for ksmtuned.
+
+# How long ksmtuned should sleep between tuning adjustments
+# KSM_MONITOR_INTERVAL=60
+
+# Millisecond sleep between ksm scans for 16Gb server.
+# Smaller servers sleep more, bigger sleep less.
+# KSM_SLEEP_MSEC=10
+
+# KSM_NPAGES_BOOST=300
+# KSM_NPAGES_DECAY=-50
+# KSM_NPAGES_MIN=64
+# KSM_NPAGES_MAX=1250
+
+# KSM_THRES_COEF=20
+# KSM_THRES_CONST=2048
+
+# uncomment the following if you want ksmtuned debug info
+
+# LOGFILE=/var/log/ksmtuned
+# DEBUG=1
diff --git a/SOURCES/ksmtuned.service b/SOURCES/ksmtuned.service
new file mode 100644
index 0000000..39febcc
--- /dev/null
+++ b/SOURCES/ksmtuned.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Kernel Samepage Merging (KSM) Tuning Daemon
+After=ksm.service
+Requires=ksm.service
+
+[Service]
+ExecStart=/usr/sbin/ksmtuned
+ExecReload=/bin/kill -USR1 $MAINPID
+Type=forking
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/kvm-BZ1513294-spapr-Include-pre-plugged-DIMMS-in-ram-siz.patch b/SOURCES/kvm-BZ1513294-spapr-Include-pre-plugged-DIMMS-in-ram-siz.patch
new file mode 100644
index 0000000..50f4b40
--- /dev/null
+++ b/SOURCES/kvm-BZ1513294-spapr-Include-pre-plugged-DIMMS-in-ram-siz.patch
@@ -0,0 +1,65 @@
+From 35dcc0b1cf6cf7e031f5e4f9bfd3eab9e98044dc Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Tue, 5 Dec 2017 04:18:21 +0100
+Subject: [PATCH 15/21] BZ1513294: spapr: Include "pre-plugged" DIMMS in ram
+ size calculation at reset
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171205041821.28985-1-dgibson@redhat.com>
+Patchwork-id: 78132
+O-Subject: [RHL-7.5 qemu-kvm-rhev PATCH] BZ1513294: spapr: Include "pre-plugged" DIMMS in ram size calculation at reset
+Bugzilla: 1513294
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+At guest reset time, we allocate a hash page table (HPT) for the guest
+based on the guest's RAM size.  If dynamic HPT resizing is not available we
+use the maximum RAM size, if it is we use the current RAM size.
+
+But the "current RAM size" calculation is incorrect - we just use the
+"base" ram_size from the machine structure.  This doesn't include any
+pluggable DIMMs that are already plugged at reset time.
+
+This means that if you try to start a 'pseries' machine with a DIMM
+specified on the command line that's much larger than the "base" RAM size,
+then the guest will get a woefully inadequate HPT.  This can lead to a
+guest freeze during boot as it runs out of HPT space during initial MMU
+setup.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Tested-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 768a20f3a491ed4afce73ebb65347d55251c0ebd)
+
+Slightly modified logic downstream because we don't have the
+get_plugged_memory_size() helper.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index e3dce84..af7a3bb 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1369,7 +1369,11 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
+             && !spapr_ovec_test(spapr->ov5_cas, OV5_HPT_RESIZE))) {
+         hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size);
+     } else {
+-        hpt_shift = spapr_hpt_shift_for_ramsize(MACHINE(spapr)->ram_size);
++        uint64_t current_ram_size;
++
++        current_ram_size = MACHINE(spapr)->ram_size +
++            pc_existing_dimms_capacity(&error_fatal);
++        hpt_shift = spapr_hpt_shift_for_ramsize(current_ram_size);
+     }
+     spapr_reallocate_hpt(spapr, hpt_shift, &error_fatal);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Create-x86-7.5.0-machine-types.patch b/SOURCES/kvm-Create-x86-7.5.0-machine-types.patch
new file mode 100644
index 0000000..6b24cfb
--- /dev/null
+++ b/SOURCES/kvm-Create-x86-7.5.0-machine-types.patch
@@ -0,0 +1,127 @@
+From 9b07271835af176f2f10c0c50b520701e0bfc6e4 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 10 Oct 2017 10:36:01 +0200
+Subject: [PATCH 09/69] Create x86 7.5.0 machine types
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171010103601.7723-2-dgilbert@redhat.com>
+Patchwork-id: 77054
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] Create x86 7.5.0 machine types
+Bugzilla: 1499011
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Not that much change from 2.9.0
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/i386/pc_piix.c    | 21 ++++++++++++++++++++-
+ hw/i386/pc_q35.c     | 19 ++++++++++++++++++-
+ include/hw/i386/pc.h |  9 +++++++++
+ 3 files changed, 47 insertions(+), 2 deletions(-)
+
+diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
+index 7f12ce3..935391f 100644
+--- a/hw/i386/pc_piix.c
++++ b/hw/i386/pc_piix.c
+@@ -1141,6 +1141,21 @@ static void pc_machine_rhel7_options(MachineClass *m)
+     m->is_default = 1;
+ }
+ 
++static void pc_init_rhel750(MachineState *machine)
++{
++    pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
++             TYPE_I440FX_PCI_DEVICE);
++}
++
++static void pc_machine_rhel750_options(MachineClass *m)
++{
++    pc_machine_rhel7_options(m);
++    m->desc = "RHEL 7.5.0 PC (i440FX + PIIX, 1996)";
++}
++
++DEFINE_PC_MACHINE(rhel750, "pc-i440fx-rhel7.5.0", pc_init_rhel750,
++                  pc_machine_rhel750_options);
++
+ static void pc_init_rhel740(MachineState *machine)
+ {
+     pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
+@@ -1149,8 +1164,12 @@ static void pc_init_rhel740(MachineState *machine)
+ 
+ static void pc_machine_rhel740_options(MachineClass *m)
+ {
+-    pc_machine_rhel7_options(m);
++    pc_machine_rhel750_options(m);
++    m->alias = NULL;
++    m->is_default = 0;
+     m->desc = "RHEL 7.4.0 PC (i440FX + PIIX, 1996)";
++    m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
++    SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT);
+ }
+ 
+ DEFINE_PC_MACHINE(rhel740, "pc-i440fx-rhel7.4.0", pc_init_rhel740,
+diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
+index 575d407..e73097b 100644
+--- a/hw/i386/pc_q35.c
++++ b/hw/i386/pc_q35.c
+@@ -395,6 +395,20 @@ static void pc_q35_machine_rhel7_options(MachineClass *m)
+     SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT);
+ }
+ 
++static void pc_q35_init_rhel750(MachineState *machine)
++{
++    pc_q35_init(machine);
++}
++
++static void pc_q35_machine_rhel750_options(MachineClass *m)
++{
++    pc_q35_machine_rhel7_options(m);
++    m->desc = "RHEL-7.5.0 PC (Q35 + ICH9, 2009)";
++}
++
++DEFINE_PC_MACHINE(q35_rhel750, "pc-q35-rhel7.5.0", pc_q35_init_rhel750,
++                  pc_q35_machine_rhel750_options);
++
+ static void pc_q35_init_rhel740(MachineState *machine)
+ {
+     pc_q35_init(machine);
+@@ -402,8 +416,11 @@ static void pc_q35_init_rhel740(MachineState *machine)
+ 
+ static void pc_q35_machine_rhel740_options(MachineClass *m)
+ {
+-    pc_q35_machine_rhel7_options(m);
++    pc_q35_machine_rhel750_options(m);
++    m->alias = NULL;
+     m->desc = "RHEL-7.4.0 PC (Q35 + ICH9, 2009)";
++    m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
++    SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT);
+ }
+ 
+ DEFINE_PC_MACHINE(q35_rhel740, "pc-q35-rhel7.4.0", pc_q35_init_rhel740,
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index b808a9b..89bdaa4 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -1001,6 +1001,15 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+             .value = "on",\
+         },
+ 
++#define PC_RHEL7_4_COMPAT \
++        HW_COMPAT_RHEL7_4 \
++        { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_9 */ \
++            .driver   = "mch",\
++            .property = "extended-tseg-mbytes",\
++            .value    = stringify(0),\
++        },
++
++
+ #define PC_RHEL7_3_COMPAT \
+         HW_COMPAT_RHEL7_3 \
+         { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Disable-GeForce-quirks-in-vfio-pci-for-RHEL-machines.patch b/SOURCES/kvm-Disable-GeForce-quirks-in-vfio-pci-for-RHEL-machines.patch
new file mode 100644
index 0000000..d6e735b
--- /dev/null
+++ b/SOURCES/kvm-Disable-GeForce-quirks-in-vfio-pci-for-RHEL-machines.patch
@@ -0,0 +1,67 @@
+From 332f7a6f8dd4ee6fae95c87e717d4527ca9344a7 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Tue, 13 Feb 2018 19:04:56 +0100
+Subject: [PATCH 15/15] Disable GeForce quirks in vfio-pci for RHEL machines
+
+RH-Author: Alex Williamson <alex.williamson@redhat.com>
+Message-id: <20180213190456.27565.18217.stgit@gimli.home>
+Patchwork-id: 78999
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH v2 2/2] [RHEL] Disable GeForce quirks in vfio-pci for RHEL machines
+Bugzilla: 1508330
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+
+RHEL-ONLY - The GeForce quirks are primarily used to virtualize the
+various ways the driver and VGA BIOS has available to access PCI
+config space using alternate memory regions, ex. MMIO and I/O port.
+Generally these quirks are benign and even where not required, do not
+interfere with operation.  However, NVIDIA has a strange MSI behavior
+where the MSI interrupt will not re-trigger until the driver writes
+back to specifc addresses in config space via the MMIO mirror.  Since
+we virtualize the mirror for GeForce, every MSI interrupt requires an
+exit to QEMU to handle this MSI-ACK behavior.  For very high interrupt
+rate applications, such as NVIDIA's DolphinVS test program, this
+virtualization causes enough overhead to degrade the performance.
+
+RHEL does not support GeForce assignment and supported configurations
+using Quadro, GRID, or Tesla assignment, including NVIDIA vGPU, do not
+require these quirks.  We can therefore disable these quirks by
+default, removing this overhead for supported configurations while
+still allowing unsupported configurations access to re-enable them
+via (equally unsupported) <qemu:args> options.
+
+Upstream development is underway to mitigate this performance overhead
+even for GeForce, but preliminary results show that we can only
+achieve 95% of the performance of disabling the quirk entirely via an
+ioeventfd approach.  Obviously detecting GeForce vs Quadro would also
+be a useful approach, but there's no clear way to do this aside from
+scraping device descriptions from libpci.  Therefore, disabling
+GeForce quirks, with unsupported mechanisms to re-enable unsupported
+configurations, seems like the best approach for RHEL/RHV.
+
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/hw/i386/pc.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index d1b1320..2b35ed8 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -1002,6 +1002,11 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+             .driver = TYPE_X86_CPU,\
+             .property = "host-phys-bits",\
+             .value = "on",\
++        },\
++        { /* PC_RHEL_COMPAT bz 1508330 */ \
++            .driver = "vfio-pci",\
++            .property = "x-no-geforce-quirks",\
++            .value = "on",\
+         },
+ 
+ #define PC_RHEL7_4_COMPAT \
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Disable-sm501-and-sysbus-sm501-devices.patch b/SOURCES/kvm-Disable-sm501-and-sysbus-sm501-devices.patch
new file mode 100644
index 0000000..6bdb2d3
--- /dev/null
+++ b/SOURCES/kvm-Disable-sm501-and-sysbus-sm501-devices.patch
@@ -0,0 +1,39 @@
+From 28f294c02314ceaee4b5c8b4bd568c84b017546d Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Fri, 13 Oct 2017 11:56:49 +0200
+Subject: [PATCH 18/69] Disable sm501 and sysbus-sm501 devices
+
+RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
+Message-id: <20171013115649.20817-3-mrezanin@redhat.com>
+Patchwork-id: 77261
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCHv2 2/2] Disable sm501 and sysbus-sm501 devices
+Bugzilla: 1498496
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Miroslav Rezanina <mrezanin@redhat.com>
+
+We are not goint to support these devices so disable them.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ default-configs/ppc64-softmmu.mak | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
+index 46e356b..8de2149 100644
+--- a/default-configs/ppc64-softmmu.mak
++++ b/default-configs/ppc64-softmmu.mak
+@@ -62,7 +62,7 @@ CONFIG_PSERIES=y
+ #CONFIG_PLATFORM_BUS=y
+ #CONFIG_ETSEC=y
+ CONFIG_LIBDECNUMBER=y
+-CONFIG_SM501=y
++#CONFIG_SM501=y
+ CONFIG_USB_OHCI=y
+ # For pSeries
+ CONFIG_XICS=$(CONFIG_PSERIES)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Disable-vhost-user-scsi-and-vhost-user-scsi-pci.patch b/SOURCES/kvm-Disable-vhost-user-scsi-and-vhost-user-scsi-pci.patch
new file mode 100644
index 0000000..5edd7a8
--- /dev/null
+++ b/SOURCES/kvm-Disable-vhost-user-scsi-and-vhost-user-scsi-pci.patch
@@ -0,0 +1,96 @@
+From b303e792c3084c0b5535ec58fbae84a5fd4b892b Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Fri, 13 Oct 2017 11:56:48 +0200
+Subject: [PATCH 17/69] Disable vhost-user-scsi and vhost-user-scsi-pci
+
+RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
+Message-id: <20171013115649.20817-2-mrezanin@redhat.com>
+Patchwork-id: 77263
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCHv2 1/2] Disable vhost-user-scsi and vhost-user-scsi-pci
+Bugzilla: 1498496
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Miroslav Rezanina <mrezanin@redhat.com>
+
+We are not going to support these new devices. CONFIG_VHOST_USER_SCSI option
+removes only vhost-user-scsi so we have to manually disable
+vhost-user-scsi-pci.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ default-configs/aarch64-softmmu.mak | 2 +-
+ default-configs/pci.mak             | 2 +-
+ default-configs/ppc64-softmmu.mak   | 2 +-
+ default-configs/s390x-softmmu.mak   | 2 +-
+ hw/virtio/virtio-pci.c              | 2 ++
+ 5 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
+index 5d57303..a2d05f4 100644
+--- a/default-configs/aarch64-softmmu.mak
++++ b/default-configs/aarch64-softmmu.mak
+@@ -22,7 +22,7 @@ CONFIG_SMBIOS=y
+ CONFIG_PL061=y
+ CONFIG_GPIO_KEY=y
+ CONFIG_ARM_V7M=y
+-CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
++#CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+ CONFIG_PCIE_PORT=y
+ CONFIG_XIO3130=y
+ CONFIG_IOH3420=y
+diff --git a/default-configs/pci.mak b/default-configs/pci.mak
+index 9bd8452..8cf0b60 100644
+--- a/default-configs/pci.mak
++++ b/default-configs/pci.mak
+@@ -43,4 +43,4 @@ CONFIG_VGA=y
+ CONFIG_VGA_PCI=y
+ CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM)
+ #CONFIG_ROCKER=y
+-CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
++#CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
+index 31ef40c..46e356b 100644
+--- a/default-configs/ppc64-softmmu.mak
++++ b/default-configs/ppc64-softmmu.mak
+@@ -8,7 +8,7 @@ CONFIG_USB_XHCI=y
+ CONFIG_USB_XHCI_NEC=y
+ CONFIG_WDT_IB6300ESB=y
+ CONFIG_PCI_TESTDEV=y
+-CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
++#CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+ 
+ include sound.mak
+ include usb.mak
+diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
+index 2846634..02f62de 100644
+--- a/default-configs/s390x-softmmu.mak
++++ b/default-configs/s390x-softmmu.mak
+@@ -1,6 +1,6 @@
+ CONFIG_PCI=y
+ #CONFIG_VIRTIO_PCI=y
+-CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
++#CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+ CONFIG_VIRTIO=y
+ CONFIG_SCLPCONSOLE=y
+ # Disabled for Red Hat Enterprise Linux:
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index eccf809..8208aa2 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -2665,9 +2665,11 @@ static void virtio_pci_register_types(void)
+ #ifdef CONFIG_VHOST_SCSI
+     type_register_static(&vhost_scsi_pci_info);
+ #endif
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+ #if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
+     type_register_static(&vhost_user_scsi_pci_info);
+ #endif
++#endif
+ #ifdef CONFIG_VHOST_VSOCK
+     type_register_static(&vhost_vsock_pci_info);
+ #endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Drop-105th-key-from-en-us-keymap.patch b/SOURCES/kvm-Drop-105th-key-from-en-us-keymap.patch
new file mode 100644
index 0000000..11d943c
--- /dev/null
+++ b/SOURCES/kvm-Drop-105th-key-from-en-us-keymap.patch
@@ -0,0 +1,58 @@
+From bfd55b42182f0c0c43ad0e251083a941f6af0a45 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 12 Jan 2018 10:45:52 +0100
+Subject: [PATCH 1/8] Drop 105th key from en-us keymap.
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20180112104552.13782-2-kraxel@redhat.com>
+Patchwork-id: 78561
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] Drop 105th key from en-us keymap.
+Bugzilla: 1513870
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+
+Qemu keymap code has problems to deal with the case that multiple
+keyscodes can generate the same keysym.  In this specific case both
+shift+comma and the 105th key map to "<".  qemu picks the 105th key
+instead of comma, the guest sees shift+105th key and interprets that
+as ">".  Oops.
+
+The correct fix for that is to use not only the keysym for the reverse
+keycode lookup, but also the modifier state.  So "<" with shift gets
+mapped to shift+command and "<" without shift to the 105th key.  That
+requires some non-trivial changes in qemu though as right now the
+reverse keymap can hold one entry per keysym only.
+
+Given that we are pretty late in the 7.5 cycle we take the shortcut to
+simply remove the mappings for the 105th key (which isn't present anyway
+on physical 104 key us keyboards, only 105 key intl keyboards running
+with en-us keymap have that), to workaround this issue for the most
+annonying case.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ pc-bios/keymaps/en-us | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/pc-bios/keymaps/en-us b/pc-bios/keymaps/en-us
+index a70e03a..e518a9d 100644
+--- a/pc-bios/keymaps/en-us
++++ b/pc-bios/keymaps/en-us
+@@ -343,12 +343,6 @@ KP_Decimal 0x53 numlock
+ 
+ # evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+ 
+-# evdev 86 (0x56), QKeyCode "less", number 0x56
+-less 0x56
+-greater 0x56 shift
+-bar 0x56 altgr
+-brokenbar 0x56 shift altgr
+-
+ # evdev 87 (0x57), QKeyCode "f11", number 0x57
+ F11 0x57
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Match-POWER-max-cpus-to-x86.patch b/SOURCES/kvm-Match-POWER-max-cpus-to-x86.patch
new file mode 100644
index 0000000..3e92e3f
--- /dev/null
+++ b/SOURCES/kvm-Match-POWER-max-cpus-to-x86.patch
@@ -0,0 +1,68 @@
+From 0584216921b243fac91395aa8975dbc34997381a Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Mon, 4 Dec 2017 06:30:08 +0100
+Subject: [PATCH 28/36] Match POWER max cpus to x86
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171204063008.31826-1-dgibson@redhat.com>
+Patchwork-id: 78091
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] [RHEL only] Match POWER max cpus to x86
+Bugzilla: 1495456
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Serhii Popovych <spopovyc@redhat.com>
+
+On at least some x86 configurations we now support 384 guest vcpus.
+POWER supports more than that in theory, but set the cap to 384 as a
+supported maximum for feature parity.  This includes updating the
+downstream lie about what KVM supports (in fact it supports 2048 vcpus
+as of right now).
+
+As of the current kernel, even with this patch 384 vcpus can only be
+created with threads=2 or greater (in the guest), otherwise the
+spacing of guest vcpu numbers causes us to exhaust the 2048 vcpu ids
+in KVM.  There are a few ways we could address that, which we'll track
+as a different bug.
+
+Testing: Started guest with -smp 384,threads=2 using new qemu
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ accel/kvm/kvm-all.c | 4 ++--
+ hw/ppc/spapr.c      | 3 ++-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
+index 80ab1c7..94c4968 100644
+--- a/accel/kvm/kvm-all.c
++++ b/accel/kvm/kvm-all.c
+@@ -1638,9 +1638,9 @@ static int kvm_init(MachineState *ms)
+      *
+      * However the POWER hard limit advertised by the kernel is 2048
+      * (== NR_CPUS) but we only want to allow up to the number of
+-     * vCPUs we actually test, so we force the hard limit to 240
++     * vCPUs we actually test, so we force the hard limit to 384
+      */
+-    hard_vcpus_limit = 240;
++    hard_vcpus_limit = 384;
+     if (soft_vcpus_limit > hard_vcpus_limit) {
+         soft_vcpus_limit = hard_vcpus_limit;
+     }
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 6c64c55..8623996 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3580,7 +3580,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     mc->init = ppc_spapr_init;
+     mc->reset = ppc_spapr_reset;
+     mc->block_default_type = IF_SCSI;
+-    mc->max_cpus = 1024;
++    /* RHEL: set to max # of supported vcpus */
++    mc->max_cpus = 384;
+     mc->no_parallel = 1;
+     mc->default_boot_order = "";
+     mc->default_ram_size = 512 * M_BYTE;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-PPC-KVM-Support-machine-option-to-set-VSMT-mode.patch b/SOURCES/kvm-PPC-KVM-Support-machine-option-to-set-VSMT-mode.patch
new file mode 100644
index 0000000..3e3ff2d
--- /dev/null
+++ b/SOURCES/kvm-PPC-KVM-Support-machine-option-to-set-VSMT-mode.patch
@@ -0,0 +1,304 @@
+From cdb93019369dff9f8a3ab19df18f24a5ba508698 Mon Sep 17 00:00:00 2001
+From: Sam Bobroff <sbobroff@redhat.com>
+Date: Fri, 6 Oct 2017 06:04:59 +0200
+Subject: [PATCH 13/34] PPC: KVM: Support machine option to set VSMT mode
+
+RH-Author: Sam Bobroff <sbobroff@redhat.com>
+Message-id: <1507269899-22908-1-git-send-email-sbobroff@redhat.com>
+Patchwork-id: 76834
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH] PPC: KVM: Support machine option to set VSMT mode
+Bugzilla: 1479178
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Sam Bobroff <sam.bobroff@au1.ibm.com>
+
+KVM now allows writing to KVM_CAP_PPC_SMT which has previously been
+read only. Doing so causes KVM to act, for that VM, as if the host's
+SMT mode was the given value. This is particularly important on Power
+9 systems because their default value is 1, but they are able to
+support values up to 8.
+
+This patch introduces a way to control this capability via a new
+machine property called VSMT ("Virtual SMT"). If the value is not set
+on the command line a default is chosen that is, when possible,
+compatible with legacy systems.
+
+Note that the intialization of KVM_CAP_PPC_SMT has changed slightly
+because it has changed (in KVM) from a global capability to a
+VM-specific one. This won't cause a problem on older KVMs because VM
+capabilities fall back to global ones.
+
+Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit fa98fbfcdfcb980b4a690b8bc93ab597935087b1)
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1479178
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14187630
+Testing: Start QEMU using "--machine pseries,vsmt=4".
+Signed-off-by: Sam Bobroff <sbobroff@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c              | 75 +++++++++++++++++++++++++++++++++++++++++++++
+ include/hw/ppc/spapr.h      |  1 +
+ target/ppc/kvm.c            | 39 ++++++++++++++++++++++-
+ target/ppc/kvm_ppc.h        | 12 ++++++++
+ target/ppc/translate_init.c | 14 ---------
+ 5 files changed, 126 insertions(+), 15 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index d3db051..30b2c5b 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -26,6 +26,7 @@
+  */
+ #include "qemu/osdep.h"
+ #include "qapi/error.h"
++#include "qapi/visitor.h"
+ #include "sysemu/sysemu.h"
+ #include "sysemu/numa.h"
+ #include "hw/hw.h"
+@@ -2166,6 +2167,61 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
+     g_free(type);
+ }
+ 
++static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
++{
++    Error *local_err = NULL;
++    bool vsmt_user = !!spapr->vsmt;
++    int kvm_smt = kvmppc_smt_threads();
++    int ret;
++
++    if (!kvm_enabled() && (smp_threads > 1)) {
++        error_setg(&local_err, "TCG cannot support more than 1 thread/core "
++                     "on a pseries machine");
++        goto out;
++    }
++    if (!is_power_of_2(smp_threads)) {
++        error_setg(&local_err, "Cannot support %d threads/core on a pseries "
++                     "machine because it must be a power of 2", smp_threads);
++        goto out;
++    }
++
++    /* Detemine the VSMT mode to use: */
++    if (vsmt_user) {
++        if (spapr->vsmt < smp_threads) {
++            error_setg(&local_err, "Cannot support VSMT mode %d"
++                         " because it must be >= threads/core (%d)",
++                         spapr->vsmt, smp_threads);
++            goto out;
++        }
++        /* In this case, spapr->vsmt has been set by the command line */
++    } else {
++        /* Choose a VSMT mode that may be higher than necessary but is
++         * likely to be compatible with hosts that don't have VSMT. */
++        spapr->vsmt = MAX(kvm_smt, smp_threads);
++    }
++
++    /* KVM: If necessary, set the SMT mode: */
++    if (kvm_enabled() && (spapr->vsmt != kvm_smt)) {
++        ret = kvmppc_set_smt_threads(spapr->vsmt);
++        if (ret) {
++            error_setg(&local_err,
++                       "Failed to set KVM's VSMT mode to %d (errno %d)",
++                       spapr->vsmt, ret);
++            if (!vsmt_user) {
++                error_append_hint(&local_err, "On PPC, a VM with %d threads/"
++                             "core on a host with %d threads/core requires "
++                             " the use of VSMT mode %d.\n",
++                             smp_threads, kvm_smt, spapr->vsmt);
++            }
++            kvmppc_hint_smt_possible(&local_err);
++            goto out;
++        }
++    }
++    /* else TCG: nothing to do currently */
++out:
++    error_propagate(errp, local_err);
++}
++
+ /* pSeries LPAR / sPAPR hardware init */
+ static void ppc_spapr_init(MachineState *machine)
+ {
+@@ -2298,6 +2354,8 @@ static void ppc_spapr_init(MachineState *machine)
+ 
+     spapr_cpu_parse_features(spapr);
+ 
++    spapr_set_vsmt_mode(spapr, &error_fatal);
++
+     spapr_init_cpus(spapr);
+ 
+     if (kvm_enabled()) {
+@@ -2682,6 +2740,18 @@ static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp)
+     }
+ }
+ 
++static void spapr_get_vsmt(Object *obj, Visitor *v, const char *name,
++                                   void *opaque, Error **errp)
++{
++    visit_type_uint32(v, name, (uint32_t *)opaque, errp);
++}
++
++static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name,
++                                   void *opaque, Error **errp)
++{
++    visit_type_uint32(v, name, (uint32_t *)opaque, errp);
++}
++
+ static void spapr_machine_initfn(Object *obj)
+ {
+     sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+@@ -2712,6 +2782,11 @@ static void spapr_machine_initfn(Object *obj)
+     object_property_set_description(obj, "resize-hpt",
+                                     "Resizing of the Hash Page Table (enabled, disabled, required)",
+                                     NULL);
++    object_property_add(obj, "vsmt", "uint32", spapr_get_vsmt,
++                        spapr_set_vsmt, NULL, &spapr->vsmt, &error_abort);
++    object_property_set_description(obj, "vsmt",
++                                    "Virtual SMT: KVM behaves as if this were"
++                                    " the host's SMT mode", &error_abort);
+ }
+ 
+ static void spapr_machine_finalizefn(Object *obj)
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 5d161ec..3d0d206 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -99,6 +99,7 @@ struct sPAPRMachineState {
+     uint64_t rtc_offset; /* Now used only during incoming migration */
+     struct PPCTimebase tb;
+     bool has_graphics;
++    uint32_t vsmt;       /* Virtual SMT mode (KVM's "core stride") */
+ 
+     Notifier epow_notifier;
+     QTAILQ_HEAD(, sPAPREventLogEntry) pending_events;
+diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
+index f31c67e..ce7e2ec 100644
+--- a/target/ppc/kvm.c
++++ b/target/ppc/kvm.c
+@@ -74,6 +74,7 @@ static int cap_interrupt_level = false;
+ static int cap_segstate;
+ static int cap_booke_sregs;
+ static int cap_ppc_smt;
++static int cap_ppc_smt_possible;
+ static int cap_ppc_rma;
+ static int cap_spapr_tce;
+ static int cap_spapr_tce_64;
+@@ -130,7 +131,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL);
+     cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
+     cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
+-    cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
++    cap_ppc_smt_possible = kvm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE);
+     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
+     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
+     cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
+@@ -144,6 +145,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+      * only activated after this by kvmppc_set_papr() */
+     cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
+     cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
++    cap_ppc_smt = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT);
+     cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
+     cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
+     cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
+@@ -2134,6 +2136,41 @@ int kvmppc_smt_threads(void)
+     return cap_ppc_smt ? cap_ppc_smt : 1;
+ }
+ 
++int kvmppc_set_smt_threads(int smt)
++{
++    int ret;
++
++    ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SMT, 0, smt, 0);
++    if (!ret) {
++        cap_ppc_smt = smt;
++    }
++    return ret;
++}
++
++void kvmppc_hint_smt_possible(Error **errp)
++{
++    int i;
++    GString *g;
++    char *s;
++
++    assert(kvm_enabled());
++    if (cap_ppc_smt_possible) {
++        g = g_string_new("Available VSMT modes:");
++        for (i = 63; i >= 0; i--) {
++            if ((1UL << i) & cap_ppc_smt_possible) {
++                g_string_append_printf(g, " %lu", (1UL << i));
++            }
++        }
++        s = g_string_free(g, false);
++        error_append_hint(errp, "%s.\n", s);
++        g_free(s);
++    } else {
++        error_append_hint(errp,
++                          "This KVM seems to be too old to support VSMT.\n");
++    }
++}
++
++
+ #ifdef TARGET_PPC64
+ off_t kvmppc_alloc_rma(void **rma)
+ {
+diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
+index 381afe6..e6711fc 100644
+--- a/target/ppc/kvm_ppc.h
++++ b/target/ppc/kvm_ppc.h
+@@ -29,6 +29,8 @@ void kvmppc_set_papr(PowerPCCPU *cpu);
+ int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
+ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
+ int kvmppc_smt_threads(void);
++void kvmppc_hint_smt_possible(Error **errp);
++int kvmppc_set_smt_threads(int smt);
+ int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
+ int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
+ int kvmppc_set_tcr(PowerPCCPU *cpu);
+@@ -148,6 +150,16 @@ static inline int kvmppc_smt_threads(void)
+     return 1;
+ }
+ 
++static inline void kvmppc_hint_smt_possible(Error **errp)
++{
++    return;
++}
++
++static inline int kvmppc_set_smt_threads(int smt)
++{
++    return 0;
++}
++
+ static inline int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
+ {
+     return 0;
+diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
+index 8fb407e..371bbae 100644
+--- a/target/ppc/translate_init.c
++++ b/target/ppc/translate_init.c
+@@ -9817,20 +9817,6 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
+     int max_smt = kvmppc_smt_threads();
+ #endif
+ 
+-#if !defined(CONFIG_USER_ONLY)
+-    if (smp_threads > max_smt) {
+-        error_setg(errp, "Cannot support more than %d threads on PPC with %s",
+-                   max_smt, kvm_enabled() ? "KVM" : "TCG");
+-        return;
+-    }
+-    if (!is_power_of_2(smp_threads)) {
+-        error_setg(errp, "Cannot support %d threads on PPC with %s, "
+-                   "threads count must be a power of 2.",
+-                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
+-        return;
+-    }
+-#endif
+-
+     cpu_exec_realizefn(cs, &local_err);
+     if (local_err != NULL) {
+         error_propagate(errp, local_err);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-RHEL-Add-RHEL7-machine-type-for-qemu-on-s390x.patch b/SOURCES/kvm-RHEL-Add-RHEL7-machine-type-for-qemu-on-s390x.patch
new file mode 100644
index 0000000..89b7ce7
--- /dev/null
+++ b/SOURCES/kvm-RHEL-Add-RHEL7-machine-type-for-qemu-on-s390x.patch
@@ -0,0 +1,72 @@
+From 1ece5bfd00eda071ff19d17035d1af23f4d160e9 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 15:50:34 +0200
+Subject: [PATCH 31/34] RHEL: Add RHEL7 machine type for qemu on s390x
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507564234-19627-3-git-send-email-thuth@redhat.com>
+Patchwork-id: 77037
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 2/2] RHEL: Add RHEL7 machine type for qemu on s390x
+Bugzilla: 1473292
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Upstream-status: downstream only
+
+Since downstream qemu-kvm is an engineered version (with additional
+bug fixes and features on top of the upstream version), we can not
+use the upstream machine types here. Introduce RHEL-specific machine
+types instead.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/s390-virtio-ccw.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index 1aec58c..4e524b0 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -411,7 +411,7 @@ bool css_migration_enabled(void)
+     {                                                                         \
+         MachineClass *mc = MACHINE_CLASS(oc);                                 \
+         ccw_machine_##suffix##_class_options(mc);                             \
+-        mc->desc = "VirtIO-ccw based S390 machine v" verstr;                  \
++        mc->desc = "VirtIO-ccw based S390 machine " verstr;                   \
+         if (latest) {                                                         \
+             mc->alias = "s390-ccw-virtio";                                    \
+             mc->is_default = 1;                                               \
+@@ -435,6 +435,8 @@ bool css_migration_enabled(void)
+     }                                                                         \
+     type_init(ccw_machine_register_##suffix)
+ 
++#if 0 /* Disabled for Red Hat Enterprise Linux */
++
+ #define CCW_COMPAT_2_9 \
+         HW_COMPAT_2_9 \
+         {\
+@@ -605,6 +607,19 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
+ }
+ DEFINE_CCW_MACHINE(2_4, "2.4", false);
+ 
++#else
++
++static void ccw_machine_rhel750_instance_options(MachineState *machine)
++{
++}
++
++static void ccw_machine_rhel750_class_options(MachineClass *mc)
++{
++}
++DEFINE_CCW_MACHINE(rhel750, "rhel7.5.0", true);
++
++#endif
++
+ static void ccw_machine_register_types(void)
+ {
+     type_register_static(&ccw_machine_info);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-RHEL-Disable-vfio-ccw-and-x-terminal3270-devices.patch b/SOURCES/kvm-RHEL-Disable-vfio-ccw-and-x-terminal3270-devices.patch
new file mode 100644
index 0000000..384ee0e
--- /dev/null
+++ b/SOURCES/kvm-RHEL-Disable-vfio-ccw-and-x-terminal3270-devices.patch
@@ -0,0 +1,45 @@
+From 17abc4f5bd7df54a1e09e2f8a1086354ef69aa87 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:48 +0200
+Subject: [PATCH 29/34] RHEL: Disable vfio-ccw and x-terminal3270 devices
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-13-git-send-email-thuth@redhat.com>
+Patchwork-id: 77030
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 12/12] RHEL: Disable vfio-ccw and x-terminal3270 devices
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Upstream-status: downstream only
+
+We don't support them in downstream RHEL, so disable them in
+the config files.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ default-configs/s390x-softmmu.mak | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak
+index 43dbf34..2846634 100644
+--- a/default-configs/s390x-softmmu.mak
++++ b/default-configs/s390x-softmmu.mak
+@@ -3,8 +3,10 @@ CONFIG_PCI=y
+ CONFIG_VHOST_USER_SCSI=$(and $(CONFIG_VHOST_USER),$(CONFIG_LINUX))
+ CONFIG_VIRTIO=y
+ CONFIG_SCLPCONSOLE=y
+-CONFIG_TERMINAL3270=y
++# Disabled for Red Hat Enterprise Linux:
++# CONFIG_TERMINAL3270=y
+ CONFIG_S390_FLIC=y
+ CONFIG_S390_FLIC_KVM=$(CONFIG_KVM)
+-CONFIG_VFIO_CCW=$(CONFIG_LINUX)
++# Disabled for Red Hat Enterprise Linux:
++# CONFIG_VFIO_CCW=$(CONFIG_LINUX)
+ CONFIG_WDT_DIAG288=y
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Revert-qdev-Free-QemuOpts-when-the-QOM-path-goes-awa.patch b/SOURCES/kvm-Revert-qdev-Free-QemuOpts-when-the-QOM-path-goes-awa.patch
new file mode 100644
index 0000000..c2d550b
--- /dev/null
+++ b/SOURCES/kvm-Revert-qdev-Free-QemuOpts-when-the-QOM-path-goes-awa.patch
@@ -0,0 +1,66 @@
+From 8edc99e92cf93764e190e69d3f970bdf6de606e0 Mon Sep 17 00:00:00 2001
+From: Serhii Popovych <spopovyc@redhat.com>
+Date: Thu, 9 Nov 2017 15:30:04 +0100
+Subject: [PATCH 4/7] Revert "qdev: Free QemuOpts when the QOM path goes away"
+
+RH-Author: Serhii Popovych <spopovyc@redhat.com>
+Message-id: <1510241405-20597-3-git-send-email-spopovyc@redhat.com>
+Patchwork-id: 77630
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/3] Revert "qdev: Free QemuOpts when the QOM path goes away"
+Bugzilla: 1445460
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Michael Roth <mdroth@linux.vnet.ibm.com>
+
+This reverts commit abed886ec60cf239a03515cf0b30fb11fa964c44.
+
+This patch originally addressed an issue where a DEVICE_DELETED
+event could be emitted (in device_unparent()) before a Device's
+QemuOpts were cleaned up (in device_finalize()), leading to a
+"duplicate ID" error if management attempted to immediately add
+a device with the same ID in response to the DEVICE_DELETED event.
+
+An alternative will be implemented in a subsequent patch where we
+defer the DEVICE_DELETED event until device_finalize(), which would
+also prevent the race, so we revert the original fix in preparation.
+
+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Message-Id: <20171016222315.407-3-mdroth@linux.vnet.ibm.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 2fc06c4ac65594ad248e9a9150ebdde9ff5a1253)
+Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/core/qdev.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index 0019a49..418cdac 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -1069,6 +1069,7 @@ static void device_finalize(Object *obj)
+     NamedGPIOList *ngl, *next;
+ 
+     DeviceState *dev = DEVICE(obj);
++    qemu_opts_del(dev->opts);
+ 
+     QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
+         QLIST_REMOVE(ngl, node);
+@@ -1118,9 +1119,6 @@ static void device_unparent(Object *obj)
+         g_free(dev->canonical_path);
+         dev->canonical_path = NULL;
+     }
+-
+-    qemu_opts_del(dev->opts);
+-    dev->opts = NULL;
+ }
+ 
+ static void device_class_init(ObjectClass *class, void *data)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-acpi-Force-rev1-FADT-on-old-q35-machine-types.patch b/SOURCES/kvm-acpi-Force-rev1-FADT-on-old-q35-machine-types.patch
new file mode 100644
index 0000000..2e68432
--- /dev/null
+++ b/SOURCES/kvm-acpi-Force-rev1-FADT-on-old-q35-machine-types.patch
@@ -0,0 +1,114 @@
+From e63d707db946519d04590b86e241ac82e328339b Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 11 Oct 2017 17:54:59 +0200
+Subject: [PATCH 14/69] acpi: Force rev1 FADT on old q35 machine types
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171011175500.12390-2-dgilbert@redhat.com>
+Patchwork-id: 77177
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v3 1/2] acpi: Force rev1 FADT on old q35 machine types
+Bugzilla: 1489800
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Upstream lp's 1714331 found that older OVMF
+didn't boot various versions of windows on 2.10+q35
+due to the change to the newer FADT version.  That's
+fixed with a newer OVMF, and it's too late upstream
+to keep compatibility.
+
+Downstream, keep the compatibility on the older rhel-q35
+machine types by forcing rev1 FADT.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/acpi/ich9.c         | 16 ++++++++++++++++
+ hw/i386/acpi-build.c   |  2 ++
+ include/hw/acpi/ich9.h |  3 +++
+ include/hw/i386/pc.h   |  5 +++++
+ 4 files changed, 26 insertions(+)
+
+diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
+index a4e87b8..23a7baa 100644
+--- a/hw/acpi/ich9.c
++++ b/hw/acpi/ich9.c
+@@ -441,6 +441,18 @@ static void ich9_pm_set_enable_tco(Object *obj, bool value, Error **errp)
+     s->pm.enable_tco = value;
+ }
+ 
++static bool ich9_pm_get_force_rev1_fadt(Object *obj, Error **errp)
++{
++    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
++    return s->pm.force_rev1_fadt;
++}
++
++static void ich9_pm_set_force_rev1_fadt(Object *obj, bool value, Error **errp)
++{
++    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
++    s->pm.force_rev1_fadt = value;
++}
++
+ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
+ {
+     static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
+@@ -465,6 +477,10 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
+                              ich9_pm_get_cpu_hotplug_legacy,
+                              ich9_pm_set_cpu_hotplug_legacy,
+                              NULL);
++    object_property_add_bool(obj, "__com.redhat_force-rev1-fadt",
++                             ich9_pm_get_force_rev1_fadt,
++                             ich9_pm_set_force_rev1_fadt,
++                             NULL);
+     object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8",
+                         ich9_pm_get_disable_s3,
+                         ich9_pm_set_disable_s3,
+diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
+index 98dd424..e38fff2 100644
+--- a/hw/i386/acpi-build.c
++++ b/hw/i386/acpi-build.c
+@@ -146,6 +146,8 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
+     }
+     if (lpc) {
+         obj = lpc;
++        pm->force_rev1_fadt = object_property_get_bool(lpc,
++                                  "__com.redhat_force-rev1-fadt", NULL);
+         pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;
+     }
+     assert(obj);
+diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
+index a352c94..e9a8fad 100644
+--- a/include/hw/acpi/ich9.h
++++ b/include/hw/acpi/ich9.h
+@@ -61,6 +61,9 @@ typedef struct ICH9LPCPMRegs {
+     uint8_t smm_enabled;
+     bool enable_tco;
+     TCOIORegs tco_regs;
++
++    /* RH addition, see bz 1489800 */
++    bool force_rev1_fadt;
+ } ICH9LPCPMRegs;
+ 
+ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index 89bdaa4..a8d6857 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -1007,6 +1007,11 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+             .driver   = "mch",\
+             .property = "extended-tseg-mbytes",\
+             .value    = stringify(0),\
++        },\
++        { /* PC_RHEL7_4_COMPAT bz 1489800 */ \
++            .driver   = "ICH9-LPC",\
++            .property = "__com.redhat_force-rev1-fadt",\
++            .value    = "on",\
+         },
+ 
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-aio-fix-assert-when-remove-poll-during-destroy.patch b/SOURCES/kvm-aio-fix-assert-when-remove-poll-during-destroy.patch
new file mode 100644
index 0000000..ad3bb86
--- /dev/null
+++ b/SOURCES/kvm-aio-fix-assert-when-remove-poll-during-destroy.patch
@@ -0,0 +1,66 @@
+From 5ca7635b41a142a709364412fb367c23ac169a21 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:48 +0100
+Subject: [PATCH 30/42] aio: fix assert when remove poll during destroy
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-9-stefanha@redhat.com>
+Patchwork-id: 78491
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 08/20] aio: fix assert when remove poll during destroy
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+After iothread is enabled internally inside QEMU with GMainContext, we
+may encounter this warning when destroying the iothread:
+
+(qemu-system-x86_64:19925): GLib-CRITICAL **: g_source_remove_poll:
+ assertion '!SOURCE_DESTROYED (source)' failed
+
+The problem is that g_source_remove_poll() does not allow to remove one
+source from array if the source is detached from its owner
+context. (peterx: which IMHO does not make much sense)
+
+Fix it on QEMU side by avoid calling g_source_remove_poll() if we know
+the object is during destruction, and we won't leak anything after all
+since the array will be gone soon cleanly even with that fd.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-id: 20170928025958.1420-6-peterx@redhat.com
+[peterx: write the commit message]
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit f708a5e71cba0d784e307334c07ade5f56f827ab)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/aio-posix.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/util/aio-posix.c b/util/aio-posix.c
+index 2d51239..5946ac0 100644
+--- a/util/aio-posix.c
++++ b/util/aio-posix.c
+@@ -223,7 +223,14 @@ void aio_set_fd_handler(AioContext *ctx,
+             return;
+         }
+ 
+-        g_source_remove_poll(&ctx->source, &node->pfd);
++        /* If the GSource is in the process of being destroyed then
++         * g_source_remove_poll() causes an assertion failure.  Skip
++         * removal in that case, because glib cleans up its state during
++         * destruction anyway.
++         */
++        if (!g_source_is_destroyed(&ctx->source)) {
++            g_source_remove_poll(&ctx->source, &node->pfd);
++        }
+ 
+         /* If the lock is held, just mark the node as deleted */
+         if (qemu_lockcnt_count(&ctx->list_lock)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-arm-virt-Add-RHEL-7.5-machine-type.patch b/SOURCES/kvm-arm-virt-Add-RHEL-7.5-machine-type.patch
new file mode 100644
index 0000000..e2c7957
--- /dev/null
+++ b/SOURCES/kvm-arm-virt-Add-RHEL-7.5-machine-type.patch
@@ -0,0 +1,64 @@
+From 082bd3ba3df66c556def600e0a9b4b451e106290 Mon Sep 17 00:00:00 2001
+From: Wei Huang <wei@redhat.com>
+Date: Tue, 17 Oct 2017 16:39:11 +0200
+Subject: [PATCH 21/69] arm/virt: Add RHEL 7.5 machine type
+
+RH-Author: Wei Huang <wei@redhat.com>
+Message-id: <1508258351-22962-1-git-send-email-wei@redhat.com>
+Patchwork-id: 77308
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] arm/virt: Add RHEL 7.5 machine type
+Bugzilla: 1498662
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1498662
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14281054
+Brew-ma: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14280994
+Upstream: No, downstream only
+
+This patch adds a new machine type, virt-rhel7.5.0, for AArch64. Note
+the existing 7.4 machine type, virt-rhel7.4.0, is removed in this patch
+because RHEL 7.4 for ARM was as a development preview. So we decided
+that it is unnecessary to support the 7.4 machine type.
+
+After applying this patch, the machine type list ("-M ?") is shown as
+the following:
+
+virt                 RHEL 7.5.0 ARM Virtual Machine (alias of virt-rhel7.5.0)
+virt-rhel7.5.0       RHEL 7.5.0 ARM Virtual Machine (default)
+none                 empty machine
+
+Signed-off-by: Wei Huang <wei@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/arm/virt.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index b14e16d..f243536 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -1851,7 +1851,7 @@ static void rhel_machine_init(void)
+ }
+ type_init(rhel_machine_init);
+ 
+-static void rhel740_virt_instance_init(Object *obj)
++static void rhel750_virt_instance_init(Object *obj)
+ {
+     VirtMachineState *vms = VIRT_MACHINE(obj);
+     VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+@@ -1893,8 +1893,8 @@ static void rhel740_virt_instance_init(Object *obj)
+     vms->irqmap=a15irqmap;
+ }
+ 
+-static void rhel740_virt_options(MachineClass *mc)
++static void rhel750_virt_options(MachineClass *mc)
+ {
+     SET_MACHINE_COMPAT(mc, ARM_RHEL_COMPAT);
+ }
+-DEFINE_RHEL_MACHINE_AS_LATEST(7, 4, 0)
++DEFINE_RHEL_MACHINE_AS_LATEST(7, 5, 0)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-atomic-update-documentation.patch b/SOURCES/kvm-atomic-update-documentation.patch
new file mode 100644
index 0000000..8965c30
--- /dev/null
+++ b/SOURCES/kvm-atomic-update-documentation.patch
@@ -0,0 +1,57 @@
+From be36671765f098deb41e032b40253967cbd50452 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:12 +0100
+Subject: [PATCH 08/30] atomic: update documentation
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-3-dgibson@redhat.com>
+Patchwork-id: 77692
+O-Subject: [PATCH 02/22] atomic: update documentation
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit db81b9953761cac71906728fb3dfefce661ab903)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ docs/devel/atomics.txt | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/docs/devel/atomics.txt b/docs/devel/atomics.txt
+index 3ef5d85..048e5f2 100644
+--- a/docs/devel/atomics.txt
++++ b/docs/devel/atomics.txt
+@@ -63,11 +63,22 @@ operations:
+     typeof(*ptr) atomic_fetch_sub(ptr, val)
+     typeof(*ptr) atomic_fetch_and(ptr, val)
+     typeof(*ptr) atomic_fetch_or(ptr, val)
++    typeof(*ptr) atomic_fetch_xor(ptr, val)
+     typeof(*ptr) atomic_xchg(ptr, val)
+     typeof(*ptr) atomic_cmpxchg(ptr, old, new)
+ 
+ all of which return the old value of *ptr.  These operations are
+-polymorphic; they operate on any type that is as wide as an int.
++polymorphic; they operate on any type that is as wide as a pointer.
++
++Similar operations return the new value of *ptr:
++
++    typeof(*ptr) atomic_inc_fetch(ptr)
++    typeof(*ptr) atomic_dec_fetch(ptr)
++    typeof(*ptr) atomic_add_fetch(ptr, val)
++    typeof(*ptr) atomic_sub_fetch(ptr, val)
++    typeof(*ptr) atomic_and_fetch(ptr, val)
++    typeof(*ptr) atomic_or_fetch(ptr, val)
++    typeof(*ptr) atomic_xor_fetch(ptr, val)
+ 
+ Sequentially consistent loads and stores can be done using:
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Add-reopen-queue-to-bdrv_check_perm.patch b/SOURCES/kvm-block-Add-reopen-queue-to-bdrv_check_perm.patch
new file mode 100644
index 0000000..11eec90
--- /dev/null
+++ b/SOURCES/kvm-block-Add-reopen-queue-to-bdrv_check_perm.patch
@@ -0,0 +1,156 @@
+From 6c5f6c4a5d6471c620c905ec911b2a0cbb5687c8 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:02 +0100
+Subject: [PATCH 31/36] block: Add reopen queue to bdrv_check_perm()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-4-kwolf@redhat.com>
+Patchwork-id: 78110
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 3/8] block: Add reopen queue to bdrv_check_perm()
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+In the context of bdrv_reopen(), we'll have to look at the state of the
+graph as it will be after the reopen. This interface addition is in
+preparation for the change.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 3121fb45b004ea85fb3589368ea699f32e6ef832)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+diff --git a/block.c b/block.c
+index ab67062..5ce773a 100644
+--- a/block.c
++++ b/block.c
+@@ -1529,7 +1529,8 @@ static int bdrv_fill_options(QDict **options, const char *filename,
+     return 0;
+ }
+ 
+-static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
++static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
++                                 uint64_t perm, uint64_t shared,
+                                  GSList *ignore_children, Error **errp);
+ static void bdrv_child_abort_perm_update(BdrvChild *c);
+ static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
+@@ -1560,7 +1561,8 @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
+  * A call to this function must always be followed by a call to bdrv_set_perm()
+  * or bdrv_abort_perm_update().
+  */
+-static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,
++static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
++                           uint64_t cumulative_perms,
+                            uint64_t cumulative_shared_perms,
+                            GSList *ignore_children, Error **errp)
+ {
+@@ -1595,11 +1597,11 @@ static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,
+     /* Check all children */
+     QLIST_FOREACH(c, &bs->children, next) {
+         uint64_t cur_perm, cur_shared;
+-        bdrv_child_perm(bs, c->bs, c, c->role, NULL,
++        bdrv_child_perm(bs, c->bs, c, c->role, q,
+                         cumulative_perms, cumulative_shared_perms,
+                         &cur_perm, &cur_shared);
+-        ret = bdrv_child_check_perm(c, cur_perm, cur_shared, ignore_children,
+-                                    errp);
++        ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared,
++                                    ignore_children, errp);
+         if (ret < 0) {
+             return ret;
+         }
+@@ -1725,7 +1727,8 @@ char *bdrv_perm_names(uint64_t perm)
+  *
+  * Needs to be followed by a call to either bdrv_set_perm() or
+  * bdrv_abort_perm_update(). */
+-static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm,
++static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
++                                  uint64_t new_used_perm,
+                                   uint64_t new_shared_perm,
+                                   GSList *ignore_children, Error **errp)
+ {
+@@ -1767,19 +1770,20 @@ static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm,
+         cumulative_shared_perms &= c->shared_perm;
+     }
+ 
+-    return bdrv_check_perm(bs, cumulative_perms, cumulative_shared_perms,
++    return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perms,
+                            ignore_children, errp);
+ }
+ 
+ /* Needs to be followed by a call to either bdrv_child_set_perm() or
+  * bdrv_child_abort_perm_update(). */
+-static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
++static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
++                                 uint64_t perm, uint64_t shared,
+                                  GSList *ignore_children, Error **errp)
+ {
+     int ret;
+ 
+     ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
+-    ret = bdrv_check_update_perm(c->bs, perm, shared, ignore_children, errp);
++    ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children, errp);
+     g_slist_free(ignore_children);
+ 
+     return ret;
+@@ -1807,7 +1811,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
+ {
+     int ret;
+ 
+-    ret = bdrv_child_check_perm(c, perm, shared, NULL, errp);
++    ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, errp);
+     if (ret < 0) {
+         bdrv_child_abort_perm_update(c);
+         return ret;
+@@ -1948,7 +1952,7 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
+          * because we're just taking a parent away, so we're loosening
+          * restrictions. */
+         bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
+-        bdrv_check_perm(old_bs, perm, shared_perm, NULL, &error_abort);
++        bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL, &error_abort);
+         bdrv_set_perm(old_bs, perm, shared_perm);
+     }
+ 
+@@ -1967,7 +1971,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
+     BdrvChild *child;
+     int ret;
+ 
+-    ret = bdrv_check_update_perm(child_bs, perm, shared_perm, NULL, errp);
++    ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
+     if (ret < 0) {
+         bdrv_abort_perm_update(child_bs);
+         return NULL;
+@@ -3183,7 +3187,7 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
+ 
+     /* Check whether the required permissions can be granted on @to, ignoring
+      * all BdrvChild in @list so that they can't block themselves. */
+-    ret = bdrv_check_update_perm(to, perm, shared, list, errp);
++    ret = bdrv_check_update_perm(to, NULL, perm, shared, list, errp);
+     if (ret < 0) {
+         bdrv_abort_perm_update(to);
+         goto out;
+@@ -4040,7 +4044,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
+ 
+     /* Update permissions, they may differ for inactive nodes */
+     bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
+-    ret = bdrv_check_perm(bs, perm, shared_perm, NULL, &local_err);
++    ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &local_err);
+     if (ret < 0) {
+         bs->open_flags |= BDRV_O_INACTIVE;
+         error_propagate(errp, local_err);
+@@ -4107,7 +4111,7 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs,
+ 
+         /* Update permissions, they may differ for inactive nodes */
+         bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
+-        bdrv_check_perm(bs, perm, shared_perm, NULL, &error_abort);
++        bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &error_abort);
+         bdrv_set_perm(bs, perm, shared_perm);
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Add-reopen_queue-to-bdrv_child_perm.patch b/SOURCES/kvm-block-Add-reopen_queue-to-bdrv_child_perm.patch
new file mode 100644
index 0000000..89ac615
--- /dev/null
+++ b/SOURCES/kvm-block-Add-reopen_queue-to-bdrv_child_perm.patch
@@ -0,0 +1,198 @@
+From 4233c105ab4dc42ea8252717a0b68ee387ef8ed8 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:01 +0100
+Subject: [PATCH 30/36] block: Add reopen_queue to bdrv_child_perm()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-3-kwolf@redhat.com>
+Patchwork-id: 78105
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 2/8] block: Add reopen_queue to bdrv_child_perm()
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+In the context of bdrv_reopen(), we'll have to look at the state of the
+graph as it will be after the reopen. This interface addition is in
+preparation for the change.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit e0995dc3da0894d0a8260bddaa200a4cd7809ba4)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c                   | 19 ++++++++++++-------
+ block/commit.c            |  1 +
+ block/mirror.c            |  1 +
+ block/replication.c       |  1 +
+ block/vvfat.c             |  1 +
+ include/block/block_int.h |  7 +++++++
+ 6 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/block.c b/block.c
+index 6fb4e98..ab67062 100644
+--- a/block.c
++++ b/block.c
+@@ -1535,16 +1535,17 @@ static void bdrv_child_abort_perm_update(BdrvChild *c);
+ static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
+ 
+ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
+-                            BdrvChild *c,
+-                            const BdrvChildRole *role,
++                            BdrvChild *c, const BdrvChildRole *role,
++                            BlockReopenQueue *reopen_queue,
+                             uint64_t parent_perm, uint64_t parent_shared,
+                             uint64_t *nperm, uint64_t *nshared)
+ {
+     if (bs->drv && bs->drv->bdrv_child_perm) {
+-        bs->drv->bdrv_child_perm(bs, c, role,
++        bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
+                                  parent_perm, parent_shared,
+                                  nperm, nshared);
+     }
++    /* TODO Take force_share from reopen_queue */
+     if (child_bs && child_bs->force_share) {
+         *nshared = BLK_PERM_ALL;
+     }
+@@ -1594,7 +1595,7 @@ static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,
+     /* Check all children */
+     QLIST_FOREACH(c, &bs->children, next) {
+         uint64_t cur_perm, cur_shared;
+-        bdrv_child_perm(bs, c->bs, c, c->role,
++        bdrv_child_perm(bs, c->bs, c, c->role, NULL,
+                         cumulative_perms, cumulative_shared_perms,
+                         &cur_perm, &cur_shared);
+         ret = bdrv_child_check_perm(c, cur_perm, cur_shared, ignore_children,
+@@ -1656,7 +1657,7 @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
+     /* Update all children */
+     QLIST_FOREACH(c, &bs->children, next) {
+         uint64_t cur_perm, cur_shared;
+-        bdrv_child_perm(bs, c->bs, c, c->role,
++        bdrv_child_perm(bs, c->bs, c, c->role, NULL,
+                         cumulative_perms, cumulative_shared_perms,
+                         &cur_perm, &cur_shared);
+         bdrv_child_set_perm(c, cur_perm, cur_shared);
+@@ -1825,6 +1826,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
+ 
+ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
+                                const BdrvChildRole *role,
++                               BlockReopenQueue *reopen_queue,
+                                uint64_t perm, uint64_t shared,
+                                uint64_t *nperm, uint64_t *nshared)
+ {
+@@ -1842,6 +1844,7 @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
+ 
+ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
+                                const BdrvChildRole *role,
++                               BlockReopenQueue *reopen_queue,
+                                uint64_t perm, uint64_t shared,
+                                uint64_t *nperm, uint64_t *nshared)
+ {
+@@ -1851,9 +1854,11 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
+     if (!backing) {
+         /* Apart from the modifications below, the same permissions are
+          * forwarded and left alone as for filters */
+-        bdrv_filter_default_perms(bs, c, role, perm, shared, &perm, &shared);
++        bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
++                                  &perm, &shared);
+ 
+         /* Format drivers may touch metadata even if the guest doesn't write */
++        /* TODO Take flags from reopen_queue */
+         if (bdrv_is_writable(bs)) {
+             perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
+         }
+@@ -1997,7 +2002,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
+ 
+     assert(parent_bs->drv);
+     assert(bdrv_get_aio_context(parent_bs) == bdrv_get_aio_context(child_bs));
+-    bdrv_child_perm(parent_bs, child_bs, NULL, child_role,
++    bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
+                     perm, shared_perm, &perm, &shared_perm);
+ 
+     child = bdrv_root_attach_child(child_bs, child_name, child_role,
+diff --git a/block/commit.c b/block/commit.c
+index c7857c3..834084b 100644
+--- a/block/commit.c
++++ b/block/commit.c
+@@ -267,6 +267,7 @@ static void bdrv_commit_top_close(BlockDriverState *bs)
+ 
+ static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
+                                        const BdrvChildRole *role,
++                                       BlockReopenQueue *reopen_queue,
+                                        uint64_t perm, uint64_t shared,
+                                        uint64_t *nperm, uint64_t *nshared)
+ {
+diff --git a/block/mirror.c b/block/mirror.c
+index 429751b..17278db 100644
+--- a/block/mirror.c
++++ b/block/mirror.c
+@@ -1094,6 +1094,7 @@ static void bdrv_mirror_top_close(BlockDriverState *bs)
+ 
+ static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
+                                        const BdrvChildRole *role,
++                                       BlockReopenQueue *reopen_queue,
+                                        uint64_t perm, uint64_t shared,
+                                        uint64_t *nperm, uint64_t *nshared)
+ {
+diff --git a/block/replication.c b/block/replication.c
+index bf4462c..3a4e682 100644
+--- a/block/replication.c
++++ b/block/replication.c
+@@ -157,6 +157,7 @@ static void replication_close(BlockDriverState *bs)
+ 
+ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
+                                    const BdrvChildRole *role,
++                                   BlockReopenQueue *reopen_queue,
+                                    uint64_t perm, uint64_t shared,
+                                    uint64_t *nperm, uint64_t *nshared)
+ {
+diff --git a/block/vvfat.c b/block/vvfat.c
+index a9e207f..e9110a9 100644
+--- a/block/vvfat.c
++++ b/block/vvfat.c
+@@ -3210,6 +3210,7 @@ err:
+ 
+ static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
+                              const BdrvChildRole *role,
++                             BlockReopenQueue *reopen_queue,
+                              uint64_t perm, uint64_t shared,
+                              uint64_t *nperm, uint64_t *nshared)
+ {
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index 7571c0a..a6faf1b 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -377,9 +377,14 @@ struct BlockDriver {
+      *
+      * If @c is NULL, return the permissions for attaching a new child for the
+      * given @role.
++     *
++     * If @reopen_queue is non-NULL, don't return the currently needed
++     * permissions, but those that will be needed after applying the
++     * @reopen_queue.
+      */
+      void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
+                              const BdrvChildRole *role,
++                             BlockReopenQueue *reopen_queue,
+                              uint64_t parent_perm, uint64_t parent_shared,
+                              uint64_t *nperm, uint64_t *nshared);
+ 
+@@ -949,6 +954,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
+  * all children */
+ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
+                                const BdrvChildRole *role,
++                               BlockReopenQueue *reopen_queue,
+                                uint64_t perm, uint64_t shared,
+                                uint64_t *nperm, uint64_t *nshared);
+ 
+@@ -958,6 +964,7 @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
+  * CONSISTENT_READ and doesn't share WRITE. */
+ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
+                                const BdrvChildRole *role,
++                               BlockReopenQueue *reopen_queue,
+                                uint64_t perm, uint64_t shared,
+                                uint64_t *nperm, uint64_t *nshared);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Base-permissions-on-rw-state-after-reopen.patch b/SOURCES/kvm-block-Base-permissions-on-rw-state-after-reopen.patch
new file mode 100644
index 0000000..0256810
--- /dev/null
+++ b/SOURCES/kvm-block-Base-permissions-on-rw-state-after-reopen.patch
@@ -0,0 +1,142 @@
+From 35806318c04a6d8450ed745d1921a07915c3cc16 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:03 +0100
+Subject: [PATCH 32/36] block: Base permissions on rw state after reopen
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-5-kwolf@redhat.com>
+Patchwork-id: 78109
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 4/8] block: Base permissions on rw state after reopen
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+When new permissions are calculated during bdrv_reopen(), they need to
+be based on the state of the graph as it will be after the reopen has
+completed, not on the current state of the involved nodes.
+
+This patch makes bdrv_is_writable() optionally accept a BlockReopenQueue
+from which the new flags are taken. This is then used for determining
+the new bs->file permissions of format drivers as soon as we add the
+code to actually pass a non-NULL reopen queue to the .bdrv_child_perm
+callbacks.
+
+While moving bdrv_is_writable(), make it static. It isn't used outside
+block.c.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 148eb13c84cccd0eedd6e59f90e0151bd7bac9fa)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c               | 52 ++++++++++++++++++++++++++++++++++++---------------
+ include/block/block.h |  1 -
+ 2 files changed, 37 insertions(+), 16 deletions(-)
+
+diff --git a/block.c b/block.c
+index 5ce773a..5cce274 100644
+--- a/block.c
++++ b/block.c
+@@ -240,12 +240,6 @@ bool bdrv_is_read_only(BlockDriverState *bs)
+     return bs->read_only;
+ }
+ 
+-/* Returns whether the image file can be written to right now */
+-bool bdrv_is_writable(BlockDriverState *bs)
+-{
+-    return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE);
+-}
+-
+ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
+                            bool ignore_allow_rdw, Error **errp)
+ {
+@@ -1535,6 +1529,41 @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
+ static void bdrv_child_abort_perm_update(BdrvChild *c);
+ static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
+ 
++typedef struct BlockReopenQueueEntry {
++     bool prepared;
++     BDRVReopenState state;
++     QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
++} BlockReopenQueueEntry;
++
++/*
++ * Return the flags that @bs will have after the reopens in @q have
++ * successfully completed. If @q is NULL (or @bs is not contained in @q),
++ * return the current flags.
++ */
++static int bdrv_reopen_get_flags(BlockReopenQueue *q, BlockDriverState *bs)
++{
++    BlockReopenQueueEntry *entry;
++
++    if (q != NULL) {
++        QSIMPLEQ_FOREACH(entry, q, entry) {
++            if (entry->state.bs == bs) {
++                return entry->state.flags;
++            }
++        }
++    }
++
++    return bs->open_flags;
++}
++
++/* Returns whether the image file can be written to after the reopen queue @q
++ * has been successfully applied, or right now if @q is NULL. */
++static bool bdrv_is_writable(BlockDriverState *bs, BlockReopenQueue *q)
++{
++    int flags = bdrv_reopen_get_flags(q, bs);
++
++    return (flags & (BDRV_O_RDWR | BDRV_O_INACTIVE)) == BDRV_O_RDWR;
++}
++
+ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
+                             BdrvChild *c, const BdrvChildRole *role,
+                             BlockReopenQueue *reopen_queue,
+@@ -1572,7 +1601,7 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
+ 
+     /* Write permissions never work with read-only images */
+     if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
+-        !bdrv_is_writable(bs))
++        !bdrv_is_writable(bs, q))
+     {
+         error_setg(errp, "Block node is read-only");
+         return -EPERM;
+@@ -1862,8 +1891,7 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
+                                   &perm, &shared);
+ 
+         /* Format drivers may touch metadata even if the guest doesn't write */
+-        /* TODO Take flags from reopen_queue */
+-        if (bdrv_is_writable(bs)) {
++        if (bdrv_is_writable(bs, reopen_queue)) {
+             perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
+         }
+ 
+@@ -2641,12 +2669,6 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
+                              NULL, errp);
+ }
+ 
+-typedef struct BlockReopenQueueEntry {
+-     bool prepared;
+-     BDRVReopenState state;
+-     QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
+-} BlockReopenQueueEntry;
+-
+ /*
+  * Adds a BlockDriverState to a simple queue for an atomic, transactional
+  * reopen of multiple devices.
+diff --git a/include/block/block.h b/include/block/block.h
+index ab80195..4d0d2da 100644
+--- a/include/block/block.h
++++ b/include/block/block.h
+@@ -435,7 +435,6 @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
+                             int64_t offset, int64_t bytes, int64_t *pnum);
+ 
+ bool bdrv_is_read_only(BlockDriverState *bs);
+-bool bdrv_is_writable(BlockDriverState *bs);
+ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
+                            bool ignore_allow_rdw, Error **errp);
+ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Check-for-inserted-BlockDriverState-in-blk_io_.patch b/SOURCES/kvm-block-Check-for-inserted-BlockDriverState-in-blk_io_.patch
new file mode 100644
index 0000000..766e307
--- /dev/null
+++ b/SOURCES/kvm-block-Check-for-inserted-BlockDriverState-in-blk_io_.patch
@@ -0,0 +1,68 @@
+From 20f05f7cc0ae81aecad40e5c3c69d9c91d6d3687 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:05 +0100
+Subject: [PATCH 06/15] block: Check for inserted BlockDriverState in
+ blk_io_limits_disable()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-7-stefanha@redhat.com>
+Patchwork-id: 77741
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 6/9] block: Check for inserted BlockDriverState in blk_io_limits_disable()
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alberto Garcia <berto@igalia.com>
+
+When you set I/O limits using block_set_io_throttle or the command
+line throttling.* options they are kept in the BlockBackend regardless
+of whether a BlockDriverState is attached to the backend or not.
+
+Therefore when removing the limits using blk_io_limits_disable() we
+need to check if there's a BDS before attempting to drain it, else it
+will crash QEMU. This can be reproduced very easily using HMP:
+
+     (qemu) drive_add 0 if=none,throttling.iops-total=5000
+     (qemu) drive_del none0
+
+Reported-by: sochin jiang <sochin.jiang@huawei.com>
+Signed-off-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-id: 0d3a67ce8d948bb33e08672564714dcfb76a3d8c.1510339534.git.berto@igalia.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 48bf7ea81aa848027bad24f7e7791b503dff727d)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 520f2b2..0bd439e 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -1999,10 +1999,16 @@ void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
+ 
+ void blk_io_limits_disable(BlockBackend *blk)
+ {
+-    assert(blk->public.throttle_group_member.throttle_state);
+-    bdrv_drained_begin(blk_bs(blk));
+-    throttle_group_unregister_tgm(&blk->public.throttle_group_member);
+-    bdrv_drained_end(blk_bs(blk));
++    BlockDriverState *bs = blk_bs(blk);
++    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
++    assert(tgm->throttle_state);
++    if (bs) {
++        bdrv_drained_begin(bs);
++    }
++    throttle_group_unregister_tgm(tgm);
++    if (bs) {
++        bdrv_drained_end(bs);
++    }
+ }
+ 
+ /* should be called before blk_set_io_limits if a limit is set */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Don-t-request-I-O-permission-with-BDRV_O_NO_IO.patch b/SOURCES/kvm-block-Don-t-request-I-O-permission-with-BDRV_O_NO_IO.patch
new file mode 100644
index 0000000..04fd644
--- /dev/null
+++ b/SOURCES/kvm-block-Don-t-request-I-O-permission-with-BDRV_O_NO_IO.patch
@@ -0,0 +1,64 @@
+From 47357547c1040e029aec3e1d9e850d6249bc2bbb Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 15 Jan 2018 11:23:36 +0100
+Subject: [PATCH 11/12] block: Don't request I/O permission with BDRV_O_NO_IO
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20180115112337.20885-3-kwolf@redhat.com>
+Patchwork-id: 78575
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 2/3] block: Don't request I/O permission with BDRV_O_NO_IO
+Bugzilla: 1515604
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+'qemu-img info' makes sense even when BLK_PERM_CONSISTENT_READ cannot be
+granted because of a block job in a running qemu process. It already
+sets BDRV_O_NO_IO to indicate that it doesn't access the guest visible
+data at all.
+
+Check the BDRV_O_NO_IO flags in blk_new_open(), so that I/O related
+permissions are not unnecessarily requested and 'qemu-img info' can work
+even if BLK_PERM_CONSISTENT_READ cannot be granted.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+(cherry picked from commit 1f4ad7d3b8f7162ec0471506d86f57a5d77b8f76)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 083e65f..dce8b96 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -299,7 +299,7 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
+ {
+     BlockBackend *blk;
+     BlockDriverState *bs;
+-    uint64_t perm;
++    uint64_t perm = 0;
+ 
+     /* blk_new_open() is mainly used in .bdrv_create implementations and the
+      * tools where sharing isn't a concern because the BDS stays private, so we
+@@ -309,9 +309,11 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
+      * caller of blk_new_open() doesn't make use of the permissions, but they
+      * shouldn't hurt either. We can still share everything here because the
+      * guest devices will add their own blockers if they can't share. */
+-    perm = BLK_PERM_CONSISTENT_READ;
+-    if (flags & BDRV_O_RDWR) {
+-        perm |= BLK_PERM_WRITE;
++    if ((flags & BDRV_O_NO_IO) == 0) {
++        perm |= BLK_PERM_CONSISTENT_READ;
++        if (flags & BDRV_O_RDWR) {
++            perm |= BLK_PERM_WRITE;
++        }
+     }
+     if (flags & BDRV_O_RESIZE) {
+         perm |= BLK_PERM_RESIZE;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Don-t-use-BLK_PERM_CONSISTENT_READ-for-format-.patch b/SOURCES/kvm-block-Don-t-use-BLK_PERM_CONSISTENT_READ-for-format-.patch
new file mode 100644
index 0000000..b4954f5
--- /dev/null
+++ b/SOURCES/kvm-block-Don-t-use-BLK_PERM_CONSISTENT_READ-for-format-.patch
@@ -0,0 +1,53 @@
+From ab2ef6c7b0c99840a5b530899076998a7bbdf5df Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 15 Jan 2018 11:23:35 +0100
+Subject: [PATCH 10/12] block: Don't use BLK_PERM_CONSISTENT_READ for format
+ probing
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20180115112337.20885-2-kwolf@redhat.com>
+Patchwork-id: 78573
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 1/3] block: Don't use BLK_PERM_CONSISTENT_READ for format probing
+Bugzilla: 1515604
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+For format probing, we don't really care whether all of the image
+content is consistent. The only thing we're looking at is the image
+header, and specifically the magic numbers that are expected to never
+change, no matter how inconsistent the guest visible disk content is.
+
+Therefore, don't request BLK_PERM_CONSISTENT_READ. This allows to use
+format probing, e.g. in the context of 'qemu-img info', even while the
+guest visible data in the image is inconsistent during a running block
+job.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+(cherry picked from commit dacaa16238cc5915a609ddaab4b7f81c4bceb9ae)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/block.c b/block.c
+index 17629ab..90a60bc 100644
+--- a/block.c
++++ b/block.c
+@@ -2540,7 +2540,10 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
+             goto fail;
+         }
+         if (file_bs != NULL) {
+-            file = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
++            /* Not requesting BLK_PERM_CONSISTENT_READ because we're only
++             * looking at the header to guess the image format. This works even
++             * in cases where a guest would not see a consistent state. */
++            file = blk_new(0, BLK_PERM_ALL);
+             blk_insert_bs(file, file_bs, &local_err);
+             bdrv_unref(file_bs);
+             if (local_err) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Expect-graph-changes-in-bdrv_parent_drained_be.patch b/SOURCES/kvm-block-Expect-graph-changes-in-bdrv_parent_drained_be.patch
new file mode 100644
index 0000000..4c97b56
--- /dev/null
+++ b/SOURCES/kvm-block-Expect-graph-changes-in-bdrv_parent_drained_be.patch
@@ -0,0 +1,70 @@
+From 2a9bf55a3db6b1a4a20c07fa030fde5ded02cf92 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:12 +0100
+Subject: [PATCH 08/21] block: Expect graph changes in
+ bdrv_parent_drained_begin/end
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <09d305a1846240448bc742a53a49ea87950e427d.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78047
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 08/11] block: Expect graph changes in bdrv_parent_drained_begin/end
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Kevin Wolf <kwolf@redhat.com>
+
+The .drained_begin/end callbacks can (directly or indirectly via
+aio_poll()) cause block nodes to be removed or the current BdrvChild to
+point to a different child node.
+
+Use QLIST_FOREACH_SAFE() to make sure we don't access invalid
+BlockDriverStates or accidentally continue iterating the parents of the
+new child node instead of the node we actually came from.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Tested-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 02d213009d571bcd7171e3ff9234722a11d30d1b)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/io.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/block/io.c b/block/io.c
+index 3a717bc..4ff2f25 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -39,9 +39,9 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
+ 
+ void bdrv_parent_drained_begin(BlockDriverState *bs)
+ {
+-    BdrvChild *c;
++    BdrvChild *c, *next;
+ 
+-    QLIST_FOREACH(c, &bs->parents, next_parent) {
++    QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
+         if (c->role->drained_begin) {
+             c->role->drained_begin(c);
+         }
+@@ -50,9 +50,9 @@ void bdrv_parent_drained_begin(BlockDriverState *bs)
+ 
+ void bdrv_parent_drained_end(BlockDriverState *bs)
+ {
+-    BdrvChild *c;
++    BdrvChild *c, *next;
+ 
+-    QLIST_FOREACH(c, &bs->parents, next_parent) {
++    QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
+         if (c->role->drained_end) {
+             c->role->drained_end(c);
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Fix-permissions-after-bdrv_reopen.patch b/SOURCES/kvm-block-Fix-permissions-after-bdrv_reopen.patch
new file mode 100644
index 0000000..92e14ec
--- /dev/null
+++ b/SOURCES/kvm-block-Fix-permissions-after-bdrv_reopen.patch
@@ -0,0 +1,152 @@
+From b87d11b7f13dd4725fe801b014d425fa7753b1d0 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:05 +0100
+Subject: [PATCH 34/36] block: Fix permissions after bdrv_reopen()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-7-kwolf@redhat.com>
+Patchwork-id: 78112
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 6/8] block: Fix permissions after bdrv_reopen()
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+If we switch between read-only and read-write, the permissions that
+image format drivers need on bs->file change, too. Make sure to update
+the permissions during bdrv_reopen().
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 3045025991ebeec77ce89c8ec56e83858950bbb3)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c               | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/block/block.h |  1 +
+ 2 files changed, 65 insertions(+)
+
+diff --git a/block.c b/block.c
+index 0a7e2c6..bc8b80b 100644
+--- a/block.c
++++ b/block.c
+@@ -2780,6 +2780,10 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
+     bs_entry->state.explicit_options = explicit_options;
+     bs_entry->state.flags = flags;
+ 
++    /* This needs to be overwritten in bdrv_reopen_prepare() */
++    bs_entry->state.perm = UINT64_MAX;
++    bs_entry->state.shared_perm = 0;
++
+     QLIST_FOREACH(child, &bs->children, next) {
+         QDict *new_child_options;
+         char *child_key_dot;
+@@ -2886,6 +2890,52 @@ int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp)
+     return ret;
+ }
+ 
++static BlockReopenQueueEntry *find_parent_in_reopen_queue(BlockReopenQueue *q,
++                                                          BdrvChild *c)
++{
++    BlockReopenQueueEntry *entry;
++
++    QSIMPLEQ_FOREACH(entry, q, entry) {
++        BlockDriverState *bs = entry->state.bs;
++        BdrvChild *child;
++
++        QLIST_FOREACH(child, &bs->children, next) {
++            if (child == c) {
++                return entry;
++            }
++        }
++    }
++
++    return NULL;
++}
++
++static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
++                             uint64_t *perm, uint64_t *shared)
++{
++    BdrvChild *c;
++    BlockReopenQueueEntry *parent;
++    uint64_t cumulative_perms = 0;
++    uint64_t cumulative_shared_perms = BLK_PERM_ALL;
++
++    QLIST_FOREACH(c, &bs->parents, next_parent) {
++        parent = find_parent_in_reopen_queue(q, c);
++        if (!parent) {
++            cumulative_perms |= c->perm;
++            cumulative_shared_perms &= c->shared_perm;
++        } else {
++            uint64_t nperm, nshared;
++
++            bdrv_child_perm(parent->state.bs, bs, c, c->role, q,
++                            parent->state.perm, parent->state.shared_perm,
++                            &nperm, &nshared);
++
++            cumulative_perms |= nperm;
++            cumulative_shared_perms &= nshared;
++        }
++    }
++    *perm = cumulative_perms;
++    *shared = cumulative_shared_perms;
++}
+ 
+ /*
+  * Prepares a BlockDriverState for reopen. All changes are staged in the
+@@ -2951,6 +3001,9 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
+         goto error;
+     }
+ 
++    /* Calculate required permissions after reopening */
++    bdrv_reopen_perm(queue, reopen_state->bs,
++                     &reopen_state->perm, &reopen_state->shared_perm);
+ 
+     ret = bdrv_flush(reopen_state->bs);
+     if (ret) {
+@@ -3006,6 +3059,12 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
+         } while ((entry = qdict_next(reopen_state->options, entry)));
+     }
+ 
++    ret = bdrv_check_perm(reopen_state->bs, queue, reopen_state->perm,
++                          reopen_state->shared_perm, NULL, errp);
++    if (ret < 0) {
++        goto error;
++    }
++
+     ret = 0;
+ 
+ error:
+@@ -3046,6 +3105,9 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
+ 
+     bdrv_refresh_limits(bs, NULL);
+ 
++    bdrv_set_perm(reopen_state->bs, reopen_state->perm,
++                  reopen_state->shared_perm);
++
+     new_can_write =
+         !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
+     if (!old_can_write && new_can_write && drv->bdrv_reopen_bitmaps_rw) {
+@@ -3079,6 +3141,8 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state)
+     }
+ 
+     QDECREF(reopen_state->explicit_options);
++
++    bdrv_abort_perm_update(reopen_state->bs);
+ }
+ 
+ 
+diff --git a/include/block/block.h b/include/block/block.h
+index 4d0d2da..59a3077 100644
+--- a/include/block/block.h
++++ b/include/block/block.h
+@@ -166,6 +166,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
+ typedef struct BDRVReopenState {
+     BlockDriverState *bs;
+     int flags;
++    uint64_t perm, shared_perm;
+     QDict *options;
+     QDict *explicit_options;
+     void *opaque;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Formats-don-t-need-CONSISTENT_READ-with-NO_IO.patch b/SOURCES/kvm-block-Formats-don-t-need-CONSISTENT_READ-with-NO_IO.patch
new file mode 100644
index 0000000..0db4ba1
--- /dev/null
+++ b/SOURCES/kvm-block-Formats-don-t-need-CONSISTENT_READ-with-NO_IO.patch
@@ -0,0 +1,58 @@
+From a80280654277c361714ec5f3925d2d6b077eca7b Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 15 Jan 2018 11:23:37 +0100
+Subject: [PATCH 12/12] block: Formats don't need CONSISTENT_READ with NO_IO
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20180115112337.20885-4-kwolf@redhat.com>
+Patchwork-id: 78574
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 3/3] block: Formats don't need CONSISTENT_READ with NO_IO
+Bugzilla: 1515604
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Commit 1f4ad7d fixed 'qemu-img info' for raw images that are currently
+in use as a mirror target. It is not enough for image formats, though,
+as these still unconditionally request BLK_PERM_CONSISTENT_READ.
+
+As this permission is geared towards whether the guest-visible data is
+consistent, and has no impact on whether the metadata is sane, and
+'qemu-img info' does not read guest-visible data (except for the raw
+format), it makes sense to not require BLK_PERM_CONSISTENT_READ if there
+is not going to be any guest I/O performed, regardless of image format.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 5fbfabd313b77e1cc7038ae8c4481c4b9f8b650a)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/block.c b/block.c
+index 90a60bc..ca8a46b 100644
+--- a/block.c
++++ b/block.c
+@@ -1885,6 +1885,8 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
+     assert(role == &child_backing || role == &child_file);
+ 
+     if (!backing) {
++        int flags = bdrv_reopen_get_flags(reopen_queue, bs);
++
+         /* Apart from the modifications below, the same permissions are
+          * forwarded and left alone as for filters */
+         bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
+@@ -1897,7 +1899,9 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
+ 
+         /* bs->file always needs to be consistent because of the metadata. We
+          * can never allow other users to resize or write to it. */
+-        perm |= BLK_PERM_CONSISTENT_READ;
++        if (!(flags & BDRV_O_NO_IO)) {
++            perm |= BLK_PERM_CONSISTENT_READ;
++        }
+         shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
+     } else {
+         /* We want consistent read from backing files if the parent needs it.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Leave-valid-throttle-timers-when-removing-a-BD.patch b/SOURCES/kvm-block-Leave-valid-throttle-timers-when-removing-a-BD.patch
new file mode 100644
index 0000000..9143117
--- /dev/null
+++ b/SOURCES/kvm-block-Leave-valid-throttle-timers-when-removing-a-BD.patch
@@ -0,0 +1,110 @@
+From d2461fce36126372a78f020f107389cd72395f15 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:06 +0100
+Subject: [PATCH 07/15] block: Leave valid throttle timers when removing a BDS
+ from a backend
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-8-stefanha@redhat.com>
+Patchwork-id: 77742
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 7/9] block: Leave valid throttle timers when removing a BDS from a backend
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alberto Garcia <berto@igalia.com>
+
+If a BlockBackend has I/O limits set then its ThrottleGroupMember
+structure uses the AioContext from its attached BlockDriverState.
+Those two contexts must be kept in sync manually. This is not
+ideal and will be fixed in the future by removing the throttling
+configuration from the BlockBackend and storing it in an implicit
+filter node instead, but for now we have to live with this.
+
+When you remove the BlockDriverState from the backend then the
+throttle timers are destroyed. If a new BlockDriverState is later
+inserted then they are created again using the new AioContext.
+
+There are a couple of problems with this:
+
+   a) The code manipulates the timers directly, leaving the
+      ThrottleGroupMember.aio_context field in an inconsisent state.
+
+   b) If you remove the I/O limits (e.g by destroying the backend)
+      when the timers are gone then throttle_group_unregister_tgm()
+      will attempt to destroy them again, crashing QEMU.
+
+While b) could be fixed easily by allowing the timers to be freed
+twice, this would result in a situation in which we can no longer
+guarantee that a valid ThrottleState has a valid AioContext and
+timers.
+
+This patch ensures that the timers and AioContext are always valid
+when I/O limits are set, regardless of whether the BlockBackend has a
+BlockDriverState inserted or not.
+
+[Fixed "There'a" typo as suggested by Max Reitz <mreitz@redhat.com>
+--Stefan]
+
+Reported-by: sochin jiang <sochin.jiang@huawei.com>
+Signed-off-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-id: e089c66e7c20289b046d782cea4373b765c5bc1d.1510339534.git.berto@igalia.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit c89bcf3af01e7a8834cca5344e098bf879e99999)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 0bd439e..083e65f 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -655,15 +655,15 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
+  */
+ void blk_remove_bs(BlockBackend *blk)
+ {
++    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
+     BlockDriverState *bs;
+-    ThrottleTimers *tt;
+ 
+     notifier_list_notify(&blk->remove_bs_notifiers, blk);
+-    if (blk->public.throttle_group_member.throttle_state) {
+-        tt = &blk->public.throttle_group_member.throttle_timers;
++    if (tgm->throttle_state) {
+         bs = blk_bs(blk);
+         bdrv_drained_begin(bs);
+-        throttle_timers_detach_aio_context(tt);
++        throttle_group_detach_aio_context(tgm);
++        throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
+         bdrv_drained_end(bs);
+     }
+ 
+@@ -678,6 +678,7 @@ void blk_remove_bs(BlockBackend *blk)
+  */
+ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
+ {
++    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
+     blk->root = bdrv_root_attach_child(bs, "root", &child_root,
+                                        blk->perm, blk->shared_perm, blk, errp);
+     if (blk->root == NULL) {
+@@ -686,10 +687,9 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
+     bdrv_ref(bs);
+ 
+     notifier_list_notify(&blk->insert_bs_notifiers, blk);
+-    if (blk->public.throttle_group_member.throttle_state) {
+-        throttle_timers_attach_aio_context(
+-            &blk->public.throttle_group_member.throttle_timers,
+-            bdrv_get_aio_context(bs));
++    if (tgm->throttle_state) {
++        throttle_group_detach_aio_context(tgm);
++        throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
+     }
+ 
+     return 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Open-backing-image-in-force-share-mode-for-siz.patch b/SOURCES/kvm-block-Open-backing-image-in-force-share-mode-for-siz.patch
new file mode 100644
index 0000000..6461257
--- /dev/null
+++ b/SOURCES/kvm-block-Open-backing-image-in-force-share-mode-for-siz.patch
@@ -0,0 +1,57 @@
+From 20103e6ef28af483bb8aa54b1272fbd480b61aa4 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Mon, 15 Jan 2018 06:15:18 +0100
+Subject: [PATCH 08/12] block: Open backing image in force share mode for size
+ probe
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20180115061518.16303-1-famz@redhat.com>
+Patchwork-id: 78570
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] block: Open backing image in force share mode for size probe
+Bugzilla: 1526212
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Management tools create overlays of running guests with qemu-img:
+
+  $ qemu-img create -b /image/in/use.qcow2 -f qcow2 /overlay/image.qcow2
+
+but this doesn't work anymore due to image locking:
+
+    qemu-img: /overlay/image.qcow2: Failed to get shared "write" lock
+    Is another process using the image?
+    Could not open backing image to determine size.
+Use the force share option to allow this use case again.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit cc954f01e3c004aad081aa36736a17e842b80211)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block.c b/block.c
+index b5736dd..17629ab 100644
+--- a/block.c
++++ b/block.c
+@@ -4515,10 +4515,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
+         back_flags = flags;
+         back_flags &= ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+ 
++        backing_options = qdict_new();
+         if (backing_fmt) {
+-            backing_options = qdict_new();
+             qdict_put_str(backing_options, "driver", backing_fmt);
+         }
++        qdict_put_bool(backing_options, BDRV_OPT_FORCE_SHARE, true);
+ 
+         bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
+                        &local_err);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-add-aio_context-field-in-ThrottleGroupMember.patch b/SOURCES/kvm-block-add-aio_context-field-in-ThrottleGroupMember.patch
new file mode 100644
index 0000000..7d28b03
--- /dev/null
+++ b/SOURCES/kvm-block-add-aio_context-field-in-ThrottleGroupMember.patch
@@ -0,0 +1,376 @@
+From 5531090858f0cb3aabf6e95a948256b4eeb36e5a Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:01 +0100
+Subject: [PATCH 02/15] block: add aio_context field in ThrottleGroupMember
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-3-stefanha@redhat.com>
+Patchwork-id: 77735
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/9] block: add aio_context field in ThrottleGroupMember
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Manos Pitsidianakis <el13635@mail.ntua.gr>
+
+timer_cb() needs to know about the current Aio context of the throttle
+request that is woken up. In order to make ThrottleGroupMember backend
+agnostic, this information is stored in an aio_context field instead of
+accessing it from BlockBackend.
+
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit c61791fc23ecd96e6a1e038c379c4033ffd5f40c)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c           | 15 ++++------
+ block/throttle-groups.c         | 38 ++++++++++++++++---------
+ include/block/throttle-groups.h |  7 ++++-
+ tests/test-throttle.c           | 63 +++++++++++++++++++++--------------------
+ 4 files changed, 69 insertions(+), 54 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index e61f072..515be10 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -1766,18 +1766,14 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
+ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
+ {
+     BlockDriverState *bs = blk_bs(blk);
+-    ThrottleTimers *tt;
++    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
+ 
+     if (bs) {
+-        if (blk->public.throttle_group_member.throttle_state) {
+-            tt = &blk->public.throttle_group_member.throttle_timers;
+-            throttle_timers_detach_aio_context(tt);
++        if (tgm->throttle_state) {
++            throttle_group_detach_aio_context(tgm);
++            throttle_group_attach_aio_context(tgm, new_context);
+         }
+         bdrv_set_aio_context(bs, new_context);
+-        if (blk->public.throttle_group_member.throttle_state) {
+-            tt = &blk->public.throttle_group_member.throttle_timers;
+-            throttle_timers_attach_aio_context(tt, new_context);
+-        }
+     }
+ }
+ 
+@@ -2010,7 +2006,8 @@ void blk_io_limits_disable(BlockBackend *blk)
+ void blk_io_limits_enable(BlockBackend *blk, const char *group)
+ {
+     assert(!blk->public.throttle_group_member.throttle_state);
+-    throttle_group_register_tgm(&blk->public.throttle_group_member, group);
++    throttle_group_register_tgm(&blk->public.throttle_group_member,
++                                group, blk_get_aio_context(blk));
+ }
+ 
+ void blk_io_limits_update_group(BlockBackend *blk, const char *group)
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index c8ed16d..3b07b25 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -391,9 +391,6 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
+ 
+ static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write)
+ {
+-    BlockBackendPublic *blkp = container_of(tgm, BlockBackendPublic,
+-            throttle_group_member);
+-    BlockBackend *blk = blk_by_public(blkp);
+     Coroutine *co;
+     RestartData rd = {
+         .tgm = tgm,
+@@ -401,7 +398,7 @@ static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write
+     };
+ 
+     co = qemu_coroutine_create(throttle_group_restart_queue_entry, &rd);
+-    aio_co_enter(blk_get_aio_context(blk), co);
++    aio_co_enter(tgm->aio_context, co);
+ }
+ 
+ void throttle_group_restart_tgm(ThrottleGroupMember *tgm)
+@@ -449,13 +446,11 @@ void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
+ /* ThrottleTimers callback. This wakes up a request that was waiting
+  * because it had been throttled.
+  *
+- * @blk:       the BlockBackend whose request had been throttled
++ * @tgm:       the ThrottleGroupMember whose request had been throttled
+  * @is_write:  the type of operation (read/write)
+  */
+-static void timer_cb(BlockBackend *blk, bool is_write)
++static void timer_cb(ThrottleGroupMember *tgm, bool is_write)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroupMember *tgm = &blkp->throttle_group_member;
+     ThrottleState *ts = tgm->throttle_state;
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ 
+@@ -484,18 +479,18 @@ static void write_timer_cb(void *opaque)
+  *
+  * @tgm:       the ThrottleGroupMember to insert
+  * @groupname: the name of the group
++ * @ctx:       the AioContext to use
+  */
+ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+-                                 const char *groupname)
++                                 const char *groupname,
++                                 AioContext *ctx)
+ {
+     int i;
+-    BlockBackendPublic *blkp = container_of(tgm, BlockBackendPublic,
+-            throttle_group_member);
+-    BlockBackend *blk = blk_by_public(blkp);
+     ThrottleState *ts = throttle_group_incref(groupname);
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ 
+     tgm->throttle_state = ts;
++    tgm->aio_context = ctx;
+ 
+     qemu_mutex_lock(&tg->lock);
+     /* If the ThrottleGroup is new set this ThrottleGroupMember as the token */
+@@ -508,11 +503,11 @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+     QLIST_INSERT_HEAD(&tg->head, tgm, round_robin);
+ 
+     throttle_timers_init(&tgm->throttle_timers,
+-                         blk_get_aio_context(blk),
++                         tgm->aio_context,
+                          tg->clock_type,
+                          read_timer_cb,
+                          write_timer_cb,
+-                         blk);
++                         tgm);
+ 
+     qemu_mutex_unlock(&tg->lock);
+ }
+@@ -559,6 +554,21 @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
+     tgm->throttle_state = NULL;
+ }
+ 
++void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
++                                       AioContext *new_context)
++{
++    ThrottleTimers *tt = &tgm->throttle_timers;
++    throttle_timers_attach_aio_context(tt, new_context);
++    tgm->aio_context = new_context;
++}
++
++void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
++{
++    ThrottleTimers *tt = &tgm->throttle_timers;
++    throttle_timers_detach_aio_context(tt);
++    tgm->aio_context = NULL;
++}
++
+ static void throttle_groups_init(void)
+ {
+     qemu_mutex_init(&throttle_groups_lock);
+diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
+index 1a6bcda..a0f27ca 100644
+--- a/include/block/throttle-groups.h
++++ b/include/block/throttle-groups.h
+@@ -33,6 +33,7 @@
+  */
+ 
+ typedef struct ThrottleGroupMember {
++    AioContext   *aio_context;
+     /* throttled_reqs_lock protects the CoQueues for throttled requests.  */
+     CoMutex      throttled_reqs_lock;
+     CoQueue      throttled_reqs[2];
+@@ -61,12 +62,16 @@ void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
+ void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
+ 
+ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+-                                const char *groupname);
++                                const char *groupname,
++                                AioContext *ctx);
+ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
+ void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
+ 
+ void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
+                                                         unsigned int bytes,
+                                                         bool is_write);
++void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
++                                       AioContext *new_context);
++void throttle_group_detach_aio_context(ThrottleGroupMember *tgm);
+ 
+ #endif
+diff --git a/tests/test-throttle.c b/tests/test-throttle.c
+index 6e6d926..57cf5ba 100644
+--- a/tests/test-throttle.c
++++ b/tests/test-throttle.c
+@@ -24,8 +24,9 @@
+ static AioContext     *ctx;
+ static LeakyBucket    bkt;
+ static ThrottleConfig cfg;
++static ThrottleGroupMember tgm;
+ static ThrottleState  ts;
+-static ThrottleTimers tt;
++static ThrottleTimers *tt;
+ 
+ /* useful function */
+ static bool double_cmp(double x, double y)
+@@ -153,19 +154,21 @@ static void test_init(void)
+ {
+     int i;
+ 
++    tt = &tgm.throttle_timers;
++
+     /* fill the structures with crap */
+     memset(&ts, 1, sizeof(ts));
+-    memset(&tt, 1, sizeof(tt));
++    memset(tt, 1, sizeof(*tt));
+ 
+     /* init structures */
+     throttle_init(&ts);
+-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
++    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
+                          read_timer_cb, write_timer_cb, &ts);
+ 
+     /* check initialized fields */
+-    g_assert(tt.clock_type == QEMU_CLOCK_VIRTUAL);
+-    g_assert(tt.timers[0]);
+-    g_assert(tt.timers[1]);
++    g_assert(tt->clock_type == QEMU_CLOCK_VIRTUAL);
++    g_assert(tt->timers[0]);
++    g_assert(tt->timers[1]);
+ 
+     /* check other fields where cleared */
+     g_assert(!ts.previous_leak);
+@@ -176,18 +179,18 @@ static void test_init(void)
+         g_assert(!ts.cfg.buckets[i].level);
+     }
+ 
+-    throttle_timers_destroy(&tt);
++    throttle_timers_destroy(tt);
+ }
+ 
+ static void test_destroy(void)
+ {
+     int i;
+     throttle_init(&ts);
+-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
++    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
+                          read_timer_cb, write_timer_cb, &ts);
+-    throttle_timers_destroy(&tt);
++    throttle_timers_destroy(tt);
+     for (i = 0; i < 2; i++) {
+-        g_assert(!tt.timers[i]);
++        g_assert(!tt->timers[i]);
+     }
+ }
+ 
+@@ -224,7 +227,7 @@ static void test_config_functions(void)
+     orig_cfg.op_size = 1;
+ 
+     throttle_init(&ts);
+-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
++    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
+                          read_timer_cb, write_timer_cb, &ts);
+     /* structure reset by throttle_init previous_leak should be null */
+     g_assert(!ts.previous_leak);
+@@ -236,7 +239,7 @@ static void test_config_functions(void)
+     /* get back the fixed configuration */
+     throttle_get_config(&ts, &final_cfg);
+ 
+-    throttle_timers_destroy(&tt);
++    throttle_timers_destroy(tt);
+ 
+     g_assert(final_cfg.buckets[THROTTLE_BPS_TOTAL].avg == 153);
+     g_assert(final_cfg.buckets[THROTTLE_BPS_READ].avg  == 56);
+@@ -417,45 +420,45 @@ static void test_have_timer(void)
+ {
+     /* zero structures */
+     memset(&ts, 0, sizeof(ts));
+-    memset(&tt, 0, sizeof(tt));
++    memset(tt, 0, sizeof(*tt));
+ 
+     /* no timer set should return false */
+-    g_assert(!throttle_timers_are_initialized(&tt));
++    g_assert(!throttle_timers_are_initialized(tt));
+ 
+     /* init structures */
+     throttle_init(&ts);
+-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
++    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
+                          read_timer_cb, write_timer_cb, &ts);
+ 
+     /* timer set by init should return true */
+-    g_assert(throttle_timers_are_initialized(&tt));
++    g_assert(throttle_timers_are_initialized(tt));
+ 
+-    throttle_timers_destroy(&tt);
++    throttle_timers_destroy(tt);
+ }
+ 
+ static void test_detach_attach(void)
+ {
+     /* zero structures */
+     memset(&ts, 0, sizeof(ts));
+-    memset(&tt, 0, sizeof(tt));
++    memset(tt, 0, sizeof(*tt));
+ 
+     /* init the structure */
+     throttle_init(&ts);
+-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
++    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
+                          read_timer_cb, write_timer_cb, &ts);
+ 
+     /* timer set by init should return true */
+-    g_assert(throttle_timers_are_initialized(&tt));
++    g_assert(throttle_timers_are_initialized(tt));
+ 
+     /* timer should no longer exist after detaching */
+-    throttle_timers_detach_aio_context(&tt);
+-    g_assert(!throttle_timers_are_initialized(&tt));
++    throttle_timers_detach_aio_context(tt);
++    g_assert(!throttle_timers_are_initialized(tt));
+ 
+     /* timer should exist again after attaching */
+-    throttle_timers_attach_aio_context(&tt, ctx);
+-    g_assert(throttle_timers_are_initialized(&tt));
++    throttle_timers_attach_aio_context(tt, ctx);
++    g_assert(throttle_timers_are_initialized(tt));
+ 
+-    throttle_timers_destroy(&tt);
++    throttle_timers_destroy(tt);
+ }
+ 
+ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
+@@ -484,7 +487,7 @@ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
+     cfg.op_size = op_size;
+ 
+     throttle_init(&ts);
+-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
++    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
+                          read_timer_cb, write_timer_cb, &ts);
+     throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &cfg);
+ 
+@@ -511,7 +514,7 @@ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
+         return false;
+     }
+ 
+-    throttle_timers_destroy(&tt);
++    throttle_timers_destroy(tt);
+ 
+     return true;
+ }
+@@ -611,9 +614,9 @@ static void test_groups(void)
+     g_assert(tgm2->throttle_state == NULL);
+     g_assert(tgm3->throttle_state == NULL);
+ 
+-    throttle_group_register_tgm(tgm1, "bar");
+-    throttle_group_register_tgm(tgm2, "foo");
+-    throttle_group_register_tgm(tgm3, "bar");
++    throttle_group_register_tgm(tgm1, "bar", blk_get_aio_context(blk1));
++    throttle_group_register_tgm(tgm2, "foo", blk_get_aio_context(blk2));
++    throttle_group_register_tgm(tgm3, "bar", blk_get_aio_context(blk3));
+ 
+     g_assert(tgm1->throttle_state != NULL);
+     g_assert(tgm2->throttle_state != NULL);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-add-bdrv_co_drain_end-callback.patch b/SOURCES/kvm-block-add-bdrv_co_drain_end-callback.patch
new file mode 100644
index 0000000..b7ed7ee
--- /dev/null
+++ b/SOURCES/kvm-block-add-bdrv_co_drain_end-callback.patch
@@ -0,0 +1,209 @@
+From 58a794ea48e1a6c6f5711f07e34024c037e4c4b1 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:05 +0100
+Subject: [PATCH 01/21] block: add bdrv_co_drain_end callback
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <5493cbaa3bab031054077168340f5aff55b6be2e.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78040
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 01/11] block: add bdrv_co_drain_end callback
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Manos Pitsidianakis <el13635@mail.ntua.gr>
+
+BlockDriverState has a bdrv_co_drain() callback but no equivalent for
+the end of the drain. The throttle driver (block/throttle.c) needs a way
+to mark the end of the drain in order to toggle io_limits_disabled
+correctly, thus bdrv_co_drain_end is needed.
+
+Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 481cad48e5e655746893e001af31c161f4587a02)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/io.c                | 48 +++++++++++++++++++++++++++++++++--------------
+ include/block/block_int.h | 11 +++++++++--
+ 2 files changed, 43 insertions(+), 16 deletions(-)
+
+diff --git a/block/io.c b/block/io.c
+index 2600381..93fb802 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -153,6 +153,7 @@ typedef struct {
+     Coroutine *co;
+     BlockDriverState *bs;
+     bool done;
++    bool begin;
+ } BdrvCoDrainData;
+ 
+ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
+@@ -160,18 +161,23 @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
+     BdrvCoDrainData *data = opaque;
+     BlockDriverState *bs = data->bs;
+ 
+-    bs->drv->bdrv_co_drain(bs);
++    if (data->begin) {
++        bs->drv->bdrv_co_drain(bs);
++    } else {
++        bs->drv->bdrv_co_drain_end(bs);
++    }
+ 
+     /* Set data->done before reading bs->wakeup.  */
+     atomic_mb_set(&data->done, true);
+     bdrv_wakeup(bs);
+ }
+ 
+-static void bdrv_drain_invoke(BlockDriverState *bs)
++static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
+ {
+-    BdrvCoDrainData data = { .bs = bs, .done = false };
++    BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
+ 
+-    if (!bs->drv || !bs->drv->bdrv_co_drain) {
++    if (!bs->drv || (begin && !bs->drv->bdrv_co_drain) ||
++            (!begin && !bs->drv->bdrv_co_drain_end)) {
+         return;
+     }
+ 
+@@ -180,15 +186,16 @@ static void bdrv_drain_invoke(BlockDriverState *bs)
+     BDRV_POLL_WHILE(bs, !data.done);
+ }
+ 
+-static bool bdrv_drain_recurse(BlockDriverState *bs)
++static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
+ {
+     BdrvChild *child, *tmp;
+     bool waited;
+ 
+-    waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
+-
+     /* Ensure any pending metadata writes are submitted to bs->file.  */
+-    bdrv_drain_invoke(bs);
++    bdrv_drain_invoke(bs, begin);
++
++    /* Wait for drained requests to finish */
++    waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
+ 
+     QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
+         BlockDriverState *bs = child->bs;
+@@ -205,7 +212,7 @@ static bool bdrv_drain_recurse(BlockDriverState *bs)
+              */
+             bdrv_ref(bs);
+         }
+-        waited |= bdrv_drain_recurse(bs);
++        waited |= bdrv_drain_recurse(bs, begin);
+         if (in_main_loop) {
+             bdrv_unref(bs);
+         }
+@@ -221,12 +228,18 @@ static void bdrv_co_drain_bh_cb(void *opaque)
+     BlockDriverState *bs = data->bs;
+ 
+     bdrv_dec_in_flight(bs);
+-    bdrv_drained_begin(bs);
++    if (data->begin) {
++        bdrv_drained_begin(bs);
++    } else {
++        bdrv_drained_end(bs);
++    }
++
+     data->done = true;
+     aio_co_wake(co);
+ }
+ 
+-static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
++static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
++                                                bool begin)
+ {
+     BdrvCoDrainData data;
+ 
+@@ -239,6 +252,7 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
+         .co = qemu_coroutine_self(),
+         .bs = bs,
+         .done = false,
++        .begin = begin,
+     };
+     bdrv_inc_in_flight(bs);
+     aio_bh_schedule_oneshot(bdrv_get_aio_context(bs),
+@@ -253,7 +267,7 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
+ void bdrv_drained_begin(BlockDriverState *bs)
+ {
+     if (qemu_in_coroutine()) {
+-        bdrv_co_yield_to_drain(bs);
++        bdrv_co_yield_to_drain(bs, true);
+         return;
+     }
+ 
+@@ -262,17 +276,22 @@ void bdrv_drained_begin(BlockDriverState *bs)
+         bdrv_parent_drained_begin(bs);
+     }
+ 
+-    bdrv_drain_recurse(bs);
++    bdrv_drain_recurse(bs, true);
+ }
+ 
+ void bdrv_drained_end(BlockDriverState *bs)
+ {
++    if (qemu_in_coroutine()) {
++        bdrv_co_yield_to_drain(bs, false);
++        return;
++    }
+     assert(bs->quiesce_counter > 0);
+     if (atomic_fetch_dec(&bs->quiesce_counter) > 1) {
+         return;
+     }
+ 
+     bdrv_parent_drained_end(bs);
++    bdrv_drain_recurse(bs, false);
+     aio_enable_external(bdrv_get_aio_context(bs));
+ }
+ 
+@@ -350,7 +369,7 @@ void bdrv_drain_all_begin(void)
+             aio_context_acquire(aio_context);
+             for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+                 if (aio_context == bdrv_get_aio_context(bs)) {
+-                    waited |= bdrv_drain_recurse(bs);
++                    waited |= bdrv_drain_recurse(bs, true);
+                 }
+             }
+             aio_context_release(aio_context);
+@@ -371,6 +390,7 @@ void bdrv_drain_all_end(void)
+         aio_context_acquire(aio_context);
+         aio_enable_external(aio_context);
+         bdrv_parent_drained_end(bs);
++        bdrv_drain_recurse(bs, false);
+         aio_context_release(aio_context);
+     }
+ 
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index a6faf1b..98d02ba 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -320,10 +320,17 @@ struct BlockDriver {
+     int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
+ 
+     /**
+-     * Drain and stop any internal sources of requests in the driver, and
+-     * remain so until next I/O callback (e.g. bdrv_co_writev) is called.
++     * bdrv_co_drain is called if implemented in the beginning of a
++     * drain operation to drain and stop any internal sources of requests in
++     * the driver.
++     * bdrv_co_drain_end is called if implemented at the end of the drain.
++     *
++     * They should be used by the driver to e.g. manage scheduled I/O
++     * requests, or toggle an internal state. After the end of the drain new
++     * requests will continue normally.
+      */
+     void coroutine_fn (*bdrv_co_drain)(BlockDriverState *bs);
++    void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
+ 
+     void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
+                            Error **errp);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-all-I-O-should-be-completed-before-removing-th.patch b/SOURCES/kvm-block-all-I-O-should-be-completed-before-removing-th.patch
new file mode 100644
index 0000000..af7c524
--- /dev/null
+++ b/SOURCES/kvm-block-all-I-O-should-be-completed-before-removing-th.patch
@@ -0,0 +1,63 @@
+From 18d530eed9ea334b2235a1a7ae5801ee23c57290 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:03 +0100
+Subject: [PATCH 04/15] block: all I/O should be completed before removing
+ throttle timers.
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-5-stefanha@redhat.com>
+Patchwork-id: 77738
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 4/9] block: all I/O should be completed before removing throttle timers.
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Zhengui <lizhengui@huawei.com>
+
+In blk_remove_bs, all I/O should be completed before removing throttle
+timers. If there has inflight I/O, removing throttle timers here will
+cause the inflight I/O never return.
+This patch add bdrv_drained_begin before throttle_timers_detach_aio_context
+to let all I/O completed before removing throttle timers.
+
+[Moved declaration of bs as suggested by Alberto Garcia
+<berto@igalia.com>.
+--Stefan]
+
+Signed-off-by: Zhengui <lizhengui@huawei.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Message-id: 1508564040-120700-1-git-send-email-lizhengui@huawei.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 632a77354317df32c7ff2d23424f0559c23fee51)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 6826476..bfb3e84 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -655,12 +655,16 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
+  */
+ void blk_remove_bs(BlockBackend *blk)
+ {
++    BlockDriverState *bs;
+     ThrottleTimers *tt;
+ 
+     notifier_list_notify(&blk->remove_bs_notifiers, blk);
+     if (blk->public.throttle_group_member.throttle_state) {
+         tt = &blk->public.throttle_group_member.throttle_timers;
++        bs = blk_bs(blk);
++        bdrv_drained_begin(bs);
+         throttle_timers_detach_aio_context(tt);
++        bdrv_drained_end(bs);
+     }
+ 
+     blk_update_root_state(blk);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-avoid-recursive-AioContext-acquire-in-bdrv_ina.patch b/SOURCES/kvm-block-avoid-recursive-AioContext-acquire-in-bdrv_ina.patch
new file mode 100644
index 0000000..cb5019d
--- /dev/null
+++ b/SOURCES/kvm-block-avoid-recursive-AioContext-acquire-in-bdrv_ina.patch
@@ -0,0 +1,85 @@
+From 14279ae97888ecd51bcf04771d064fa11a3df7a1 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 20 Dec 2017 12:29:52 +0100
+Subject: [PATCH 02/42] block: avoid recursive AioContext acquire in
+ bdrv_inactivate_all()
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171220122952.9799-2-dgilbert@redhat.com>
+Patchwork-id: 78418
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] block: avoid recursive AioContext acquire in bdrv_inactivate_all()
+Bugzilla: 1520824
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+BDRV_POLL_WHILE() does not support recursive AioContext locking.  It
+only releases the AioContext lock once regardless of how many times the
+caller has acquired it.  This results in a hang since the IOThread does
+not make progress while the AioContext is still locked.
+
+The following steps trigger the hang:
+
+  $ qemu-system-x86_64 -M accel=kvm -m 1G -cpu host \
+                       -object iothread,id=iothread0 \
+                       -device virtio-scsi-pci,iothread=iothread0 \
+                       -drive if=none,id=drive0,file=test.img,format=raw \
+                       -device scsi-hd,drive=drive0 \
+                       -drive if=none,id=drive1,file=test.img,format=raw \
+                       -device scsi-hd,drive=drive1
+  $ qemu-system-x86_64 ...same options... \
+                       -incoming tcp::1234
+  (qemu) migrate tcp:127.0.0.1:1234
+  ...hang...
+
+Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171207201320.19284-2-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit bd6458e410c1e7d2912357aeb399fe7d8ee9f9a3)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/block.c b/block.c
+index bc8b80b..b5736dd 100644
+--- a/block.c
++++ b/block.c
+@@ -4221,9 +4221,15 @@ int bdrv_inactivate_all(void)
+     BdrvNextIterator it;
+     int ret = 0;
+     int pass;
++    GSList *aio_ctxs = NULL, *ctx;
+ 
+     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+-        aio_context_acquire(bdrv_get_aio_context(bs));
++        AioContext *aio_context = bdrv_get_aio_context(bs);
++
++        if (!g_slist_find(aio_ctxs, aio_context)) {
++            aio_ctxs = g_slist_prepend(aio_ctxs, aio_context);
++            aio_context_acquire(aio_context);
++        }
+     }
+ 
+     /* We do two passes of inactivation. The first pass calls to drivers'
+@@ -4240,9 +4246,11 @@ int bdrv_inactivate_all(void)
+     }
+ 
+ out:
+-    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
+-        aio_context_release(bdrv_get_aio_context(bs));
++    for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {
++        AioContext *aio_context = ctx->data;
++        aio_context_release(aio_context);
+     }
++    g_slist_free(aio_ctxs);
+ 
+     return ret;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-don-t-add-driver-to-options-when-referring-to-.patch b/SOURCES/kvm-block-don-t-add-driver-to-options-when-referring-to-.patch
new file mode 100644
index 0000000..6659373
--- /dev/null
+++ b/SOURCES/kvm-block-don-t-add-driver-to-options-when-referring-to-.patch
@@ -0,0 +1,55 @@
+From 9ffa9f42dd630e01a507905b60cc7f45d8326327 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Thu, 30 Nov 2017 16:17:47 +0100
+Subject: [PATCH 08/36] block: don't add 'driver' to options when referring to
+ backing via node name
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171130161747.18388-2-kwolf@redhat.com>
+Patchwork-id: 78023
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 1/1] block: don't add 'driver' to options when referring to backing via node name
+Bugzilla: 1505701
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Peter Krempa <pkrempa@redhat.com>
+
+When referring to a backing file of an image via node name
+bdrv_open_backing_file would add the 'driver' option to the option list
+filling it with the backing format driver. This breaks construction of
+the backing chain via -blockdev, as bdrv_open_inherit reports an error
+if both 'reference' and 'options' are provided.
+
+$ qemu-img create -f raw /tmp/backing.raw 64M
+$ qemu-img create -f qcow2 -F raw -b /tmp/backing.raw /tmp/test.qcow2
+$ qemu-system-x86_64 \
+  -blockdev driver=file,filename=/tmp/backing.raw,node-name=backing \
+  -blockdev driver=qcow2,file.driver=file,file.filename=/tmp/test.qcow2,node-name=root,backing=backing
+qemu-system-x86_64: -blockdev driver=qcow2,file.driver=file,file.filename=/tmp/test.qcow2,node-name=root,backing=backing: Could not open backing file: Cannot reference an existing block device with additional options or a new filename
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 6bff597bf6580ecc691258e849f652911dbdda7c)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block.c b/block.c
+index 3308814..6fb4e98 100644
+--- a/block.c
++++ b/block.c
+@@ -2178,7 +2178,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
+         goto free_exit;
+     }
+ 
+-    if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
++    if (!reference &&
++        bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
+         qdict_put_str(options, "driver", bs->backing_format);
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-blockdev_.patch b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-blockdev_.patch
new file mode 100644
index 0000000..327312d
--- /dev/null
+++ b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-blockdev_.patch
@@ -0,0 +1,132 @@
+From 0caba353a8208065904c8a1c80da8f0a8163bc76 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:52 +0100
+Subject: [PATCH 34/42] block: don't keep AioContext acquired after
+ blockdev_backup_prepare()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-13-stefanha@redhat.com>
+Patchwork-id: 78497
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 12/20] block: don't keep AioContext acquired after blockdev_backup_prepare()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-5-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit edd5adeecddf665e7954bc146ff458bb30f178ae)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c | 44 ++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index c962b8a..6efae53 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1979,7 +1979,6 @@ typedef struct BlockdevBackupState {
+     BlkActionState common;
+     BlockDriverState *bs;
+     BlockJob *job;
+-    AioContext *aio_context;
+ } BlockdevBackupState;
+ 
+ static BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
+@@ -1990,6 +1989,7 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
+     BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
+     BlockdevBackup *backup;
+     BlockDriverState *bs, *target;
++    AioContext *aio_context;
+     Error *local_err = NULL;
+ 
+     assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
+@@ -2005,29 +2005,39 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
+         return;
+     }
+ 
+-    /* AioContext is released in .clean() */
+-    state->aio_context = bdrv_get_aio_context(bs);
+-    if (state->aio_context != bdrv_get_aio_context(target)) {
+-        state->aio_context = NULL;
++    aio_context = bdrv_get_aio_context(bs);
++    if (aio_context != bdrv_get_aio_context(target)) {
+         error_setg(errp, "Backup between two IO threads is not implemented");
+         return;
+     }
+-    aio_context_acquire(state->aio_context);
++    aio_context_acquire(aio_context);
+     state->bs = bs;
++
++    /* Paired with .clean() */
+     bdrv_drained_begin(state->bs);
+ 
+     state->job = do_blockdev_backup(backup, common->block_job_txn, &local_err);
+     if (local_err) {
+         error_propagate(errp, local_err);
+-        return;
++        goto out;
+     }
++
++out:
++    aio_context_release(aio_context);
+ }
+ 
+ static void blockdev_backup_commit(BlkActionState *common)
+ {
+     BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
++    AioContext *aio_context;
++
++    aio_context = bdrv_get_aio_context(state->bs);
++    aio_context_acquire(aio_context);
++
+     assert(state->job);
+     block_job_start(state->job);
++
++    aio_context_release(aio_context);
+ }
+ 
+ static void blockdev_backup_abort(BlkActionState *common)
+@@ -2035,18 +2045,32 @@ static void blockdev_backup_abort(BlkActionState *common)
+     BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
+ 
+     if (state->job) {
++        AioContext *aio_context;
++
++        aio_context = bdrv_get_aio_context(state->bs);
++        aio_context_acquire(aio_context);
++
+         block_job_cancel_sync(state->job);
++
++        aio_context_release(aio_context);
+     }
+ }
+ 
+ static void blockdev_backup_clean(BlkActionState *common)
+ {
+     BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
++    AioContext *aio_context;
+ 
+-    if (state->aio_context) {
+-        bdrv_drained_end(state->bs);
+-        aio_context_release(state->aio_context);
++    if (!state->bs) {
++        return;
+     }
++
++    aio_context = bdrv_get_aio_context(state->bs);
++    aio_context_acquire(aio_context);
++
++    bdrv_drained_end(state->bs);
++
++    aio_context_release(aio_context);
+ }
+ 
+ typedef struct BlockDirtyBitmapState {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-drive_bac.patch b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-drive_bac.patch
new file mode 100644
index 0000000..2359fed
--- /dev/null
+++ b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-drive_bac.patch
@@ -0,0 +1,127 @@
+From 73e2dea7d9da65e53aa05247324e069de75e0c71 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:51 +0100
+Subject: [PATCH 33/42] block: don't keep AioContext acquired after
+ drive_backup_prepare()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-12-stefanha@redhat.com>
+Patchwork-id: 78493
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 11/20] block: don't keep AioContext acquired after drive_backup_prepare()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-4-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 66d56054bca3c1c45861d18ea97f147f7d376d21)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c | 42 ++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 8 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 8bb23e9..c962b8a 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1888,7 +1888,6 @@ static void external_snapshot_clean(BlkActionState *common)
+ typedef struct DriveBackupState {
+     BlkActionState common;
+     BlockDriverState *bs;
+-    AioContext *aio_context;
+     BlockJob *job;
+ } DriveBackupState;
+ 
+@@ -1900,6 +1899,7 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
+     DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
+     BlockDriverState *bs;
+     DriveBackup *backup;
++    AioContext *aio_context;
+     Error *local_err = NULL;
+ 
+     assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
+@@ -1910,24 +1910,36 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
+         return;
+     }
+ 
+-    /* AioContext is released in .clean() */
+-    state->aio_context = bdrv_get_aio_context(bs);
+-    aio_context_acquire(state->aio_context);
++    aio_context = bdrv_get_aio_context(bs);
++    aio_context_acquire(aio_context);
++
++    /* Paired with .clean() */
+     bdrv_drained_begin(bs);
++
+     state->bs = bs;
+ 
+     state->job = do_drive_backup(backup, common->block_job_txn, &local_err);
+     if (local_err) {
+         error_propagate(errp, local_err);
+-        return;
++        goto out;
+     }
++
++out:
++    aio_context_release(aio_context);
+ }
+ 
+ static void drive_backup_commit(BlkActionState *common)
+ {
+     DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
++    AioContext *aio_context;
++
++    aio_context = bdrv_get_aio_context(state->bs);
++    aio_context_acquire(aio_context);
++
+     assert(state->job);
+     block_job_start(state->job);
++
++    aio_context_release(aio_context);
+ }
+ 
+ static void drive_backup_abort(BlkActionState *common)
+@@ -1935,18 +1947,32 @@ static void drive_backup_abort(BlkActionState *common)
+     DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
+ 
+     if (state->job) {
++        AioContext *aio_context;
++
++        aio_context = bdrv_get_aio_context(state->bs);
++        aio_context_acquire(aio_context);
++
+         block_job_cancel_sync(state->job);
++
++        aio_context_release(aio_context);
+     }
+ }
+ 
+ static void drive_backup_clean(BlkActionState *common)
+ {
+     DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
++    AioContext *aio_context;
+ 
+-    if (state->aio_context) {
+-        bdrv_drained_end(state->bs);
+-        aio_context_release(state->aio_context);
++    if (!state->bs) {
++        return;
+     }
++
++    aio_context = bdrv_get_aio_context(state->bs);
++    aio_context_acquire(aio_context);
++
++    bdrv_drained_end(state->bs);
++
++    aio_context_release(aio_context);
+ }
+ 
+ typedef struct BlockdevBackupState {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-external_.patch b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-external_.patch
new file mode 100644
index 0000000..4c6aab8
--- /dev/null
+++ b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-external_.patch
@@ -0,0 +1,246 @@
+From 618ad78b4afa654623057234db339c8cbcfb7392 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:50 +0100
+Subject: [PATCH 32/42] block: don't keep AioContext acquired after
+ external_snapshot_prepare()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-11-stefanha@redhat.com>
+Patchwork-id: 78492
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 10/20] block: don't keep AioContext acquired after external_snapshot_prepare()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+It is not necessary to hold AioContext across transactions anymore since
+bdrv_drained_begin/end() is used to keep the nodes quiesced.  In fact,
+using the AioContext lock for this purpose was always buggy.
+
+This patch reduces the scope of AioContext locked regions.  This is not
+just a cleanup but also fixes hangs that occur in BDRV_POLL_WHILE()
+because it is unware of recursive locking and does not release the
+AioContext the necessary number of times to allow progress to be made.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-3-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 2d24b60b7747f7bf40fd00b0375b6bd988d4f0d9)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c | 71 ++++++++++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 48 insertions(+), 23 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index c6978a5..8bb23e9 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1649,7 +1649,6 @@ typedef struct ExternalSnapshotState {
+     BlkActionState common;
+     BlockDriverState *old_bs;
+     BlockDriverState *new_bs;
+-    AioContext *aio_context;
+     bool overlay_appended;
+ } ExternalSnapshotState;
+ 
+@@ -1669,6 +1668,7 @@ static void external_snapshot_prepare(BlkActionState *common,
+     ExternalSnapshotState *state =
+                              DO_UPCAST(ExternalSnapshotState, common, common);
+     TransactionAction *action = common->action;
++    AioContext *aio_context;
+ 
+     /* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
+      * purpose but a different set of parameters */
+@@ -1705,31 +1705,32 @@ static void external_snapshot_prepare(BlkActionState *common,
+         return;
+     }
+ 
+-    /* Acquire AioContext now so any threads operating on old_bs stop */
+-    state->aio_context = bdrv_get_aio_context(state->old_bs);
+-    aio_context_acquire(state->aio_context);
++    aio_context = bdrv_get_aio_context(state->old_bs);
++    aio_context_acquire(aio_context);
++
++    /* Paired with .clean() */
+     bdrv_drained_begin(state->old_bs);
+ 
+     if (!bdrv_is_inserted(state->old_bs)) {
+         error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+-        return;
++        goto out;
+     }
+ 
+     if (bdrv_op_is_blocked(state->old_bs,
+                            BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, errp)) {
+-        return;
++        goto out;
+     }
+ 
+     if (!bdrv_is_read_only(state->old_bs)) {
+         if (bdrv_flush(state->old_bs)) {
+             error_setg(errp, QERR_IO_ERROR);
+-            return;
++            goto out;
+         }
+     }
+ 
+     if (!bdrv_is_first_non_filter(state->old_bs)) {
+         error_setg(errp, QERR_FEATURE_DISABLED, "snapshot");
+-        return;
++        goto out;
+     }
+ 
+     if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) {
+@@ -1741,13 +1742,13 @@ static void external_snapshot_prepare(BlkActionState *common,
+ 
+         if (node_name && !snapshot_node_name) {
+             error_setg(errp, "New snapshot node name missing");
+-            return;
++            goto out;
+         }
+ 
+         if (snapshot_node_name &&
+             bdrv_lookup_bs(snapshot_node_name, snapshot_node_name, NULL)) {
+             error_setg(errp, "New snapshot node name already in use");
+-            return;
++            goto out;
+         }
+ 
+         flags = state->old_bs->open_flags;
+@@ -1760,7 +1761,7 @@ static void external_snapshot_prepare(BlkActionState *common,
+             int64_t size = bdrv_getlength(state->old_bs);
+             if (size < 0) {
+                 error_setg_errno(errp, -size, "bdrv_getlength failed");
+-                return;
++                goto out;
+             }
+             bdrv_img_create(new_image_file, format,
+                             state->old_bs->filename,
+@@ -1768,7 +1769,7 @@ static void external_snapshot_prepare(BlkActionState *common,
+                             NULL, size, flags, false, &local_err);
+             if (local_err) {
+                 error_propagate(errp, local_err);
+-                return;
++                goto out;
+             }
+         }
+ 
+@@ -1783,30 +1784,30 @@ static void external_snapshot_prepare(BlkActionState *common,
+                               errp);
+     /* We will manually add the backing_hd field to the bs later */
+     if (!state->new_bs) {
+-        return;
++        goto out;
+     }
+ 
+     if (bdrv_has_blk(state->new_bs)) {
+         error_setg(errp, "The snapshot is already in use");
+-        return;
++        goto out;
+     }
+ 
+     if (bdrv_op_is_blocked(state->new_bs, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
+                            errp)) {
+-        return;
++        goto out;
+     }
+ 
+     if (state->new_bs->backing != NULL) {
+         error_setg(errp, "The snapshot already has a backing image");
+-        return;
++        goto out;
+     }
+ 
+     if (!state->new_bs->drv->supports_backing) {
+         error_setg(errp, "The snapshot does not support backing images");
+-        return;
++        goto out;
+     }
+ 
+-    bdrv_set_aio_context(state->new_bs, state->aio_context);
++    bdrv_set_aio_context(state->new_bs, aio_context);
+ 
+     /* This removes our old bs and adds the new bs. This is an operation that
+      * can fail, so we need to do it in .prepare; undoing it for abort is
+@@ -1815,15 +1816,22 @@ static void external_snapshot_prepare(BlkActionState *common,
+     bdrv_append(state->new_bs, state->old_bs, &local_err);
+     if (local_err) {
+         error_propagate(errp, local_err);
+-        return;
++        goto out;
+     }
+     state->overlay_appended = true;
++
++out:
++    aio_context_release(aio_context);
+ }
+ 
+ static void external_snapshot_commit(BlkActionState *common)
+ {
+     ExternalSnapshotState *state =
+                              DO_UPCAST(ExternalSnapshotState, common, common);
++    AioContext *aio_context;
++
++    aio_context = bdrv_get_aio_context(state->old_bs);
++    aio_context_acquire(aio_context);
+ 
+     /* We don't need (or want) to use the transactional
+      * bdrv_reopen_multiple() across all the entries at once, because we
+@@ -1832,6 +1840,8 @@ static void external_snapshot_commit(BlkActionState *common)
+         bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR,
+                     NULL);
+     }
++
++    aio_context_release(aio_context);
+ }
+ 
+ static void external_snapshot_abort(BlkActionState *common)
+@@ -1840,11 +1850,18 @@ static void external_snapshot_abort(BlkActionState *common)
+                              DO_UPCAST(ExternalSnapshotState, common, common);
+     if (state->new_bs) {
+         if (state->overlay_appended) {
++            AioContext *aio_context;
++
++            aio_context = bdrv_get_aio_context(state->old_bs);
++            aio_context_acquire(aio_context);
++
+             bdrv_ref(state->old_bs);   /* we can't let bdrv_set_backind_hd()
+                                           close state->old_bs; we need it */
+             bdrv_set_backing_hd(state->new_bs, NULL, &error_abort);
+             bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
+             bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
++
++            aio_context_release(aio_context);
+         }
+     }
+ }
+@@ -1853,11 +1870,19 @@ static void external_snapshot_clean(BlkActionState *common)
+ {
+     ExternalSnapshotState *state =
+                              DO_UPCAST(ExternalSnapshotState, common, common);
+-    if (state->aio_context) {
+-        bdrv_drained_end(state->old_bs);
+-        bdrv_unref(state->new_bs);
+-        aio_context_release(state->aio_context);
++    AioContext *aio_context;
++
++    if (!state->old_bs) {
++        return;
+     }
++
++    aio_context = bdrv_get_aio_context(state->old_bs);
++    aio_context_acquire(aio_context);
++
++    bdrv_drained_end(state->old_bs);
++    bdrv_unref(state->new_bs);
++
++    aio_context_release(aio_context);
+ }
+ 
+ typedef struct DriveBackupState {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-internal_.patch b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-internal_.patch
new file mode 100644
index 0000000..fe426a5
--- /dev/null
+++ b/SOURCES/kvm-block-don-t-keep-AioContext-acquired-after-internal_.patch
@@ -0,0 +1,171 @@
+From a9ef5c84766a00677204474b0f8d8e845b9d4d3f Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:53 +0100
+Subject: [PATCH 35/42] block: don't keep AioContext acquired after
+ internal_snapshot_prepare()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-14-stefanha@redhat.com>
+Patchwork-id: 78499
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 13/20] block: don't keep AioContext acquired after internal_snapshot_prepare()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-6-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit a36e458cdda0196911c1cbe7cfe6f9530f2280e3)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c | 47 +++++++++++++++++++++++++++++++----------------
+ 1 file changed, 31 insertions(+), 16 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 6efae53..f118444 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1497,7 +1497,6 @@ struct BlkActionState {
+ typedef struct InternalSnapshotState {
+     BlkActionState common;
+     BlockDriverState *bs;
+-    AioContext *aio_context;
+     QEMUSnapshotInfo sn;
+     bool created;
+ } InternalSnapshotState;
+@@ -1528,6 +1527,7 @@ static void internal_snapshot_prepare(BlkActionState *common,
+     qemu_timeval tv;
+     BlockdevSnapshotInternal *internal;
+     InternalSnapshotState *state;
++    AioContext *aio_context;
+     int ret1;
+ 
+     g_assert(common->action->type ==
+@@ -1549,32 +1549,33 @@ static void internal_snapshot_prepare(BlkActionState *common,
+         return;
+     }
+ 
+-    /* AioContext is released in .clean() */
+-    state->aio_context = bdrv_get_aio_context(bs);
+-    aio_context_acquire(state->aio_context);
++    aio_context = bdrv_get_aio_context(bs);
++    aio_context_acquire(aio_context);
+ 
+     state->bs = bs;
++
++    /* Paired with .clean() */
+     bdrv_drained_begin(bs);
+ 
+     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
+-        return;
++        goto out;
+     }
+ 
+     if (bdrv_is_read_only(bs)) {
+         error_setg(errp, "Device '%s' is read only", device);
+-        return;
++        goto out;
+     }
+ 
+     if (!bdrv_can_snapshot(bs)) {
+         error_setg(errp, "Block format '%s' used by device '%s' "
+                    "does not support internal snapshots",
+                    bs->drv->format_name, device);
+-        return;
++        goto out;
+     }
+ 
+     if (!strlen(name)) {
+         error_setg(errp, "Name is empty");
+-        return;
++        goto out;
+     }
+ 
+     /* check whether a snapshot with name exist */
+@@ -1582,12 +1583,12 @@ static void internal_snapshot_prepare(BlkActionState *common,
+                                             &local_err);
+     if (local_err) {
+         error_propagate(errp, local_err);
+-        return;
++        goto out;
+     } else if (ret) {
+         error_setg(errp,
+                    "Snapshot with name '%s' already exists on device '%s'",
+                    name, device);
+-        return;
++        goto out;
+     }
+ 
+     /* 3. take the snapshot */
+@@ -1603,11 +1604,14 @@ static void internal_snapshot_prepare(BlkActionState *common,
+         error_setg_errno(errp, -ret1,
+                          "Failed to create snapshot '%s' on device '%s'",
+                          name, device);
+-        return;
++        goto out;
+     }
+ 
+     /* 4. succeed, mark a snapshot is created */
+     state->created = true;
++
++out:
++    aio_context_release(aio_context);
+ }
+ 
+ static void internal_snapshot_abort(BlkActionState *common)
+@@ -1616,12 +1620,16 @@ static void internal_snapshot_abort(BlkActionState *common)
+                              DO_UPCAST(InternalSnapshotState, common, common);
+     BlockDriverState *bs = state->bs;
+     QEMUSnapshotInfo *sn = &state->sn;
++    AioContext *aio_context;
+     Error *local_error = NULL;
+ 
+     if (!state->created) {
+         return;
+     }
+ 
++    aio_context = bdrv_get_aio_context(state->bs);
++    aio_context_acquire(aio_context);
++
+     if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) {
+         error_reportf_err(local_error,
+                           "Failed to delete snapshot with id '%s' and "
+@@ -1629,19 +1637,26 @@ static void internal_snapshot_abort(BlkActionState *common)
+                           sn->id_str, sn->name,
+                           bdrv_get_device_name(bs));
+     }
++
++    aio_context_release(aio_context);
+ }
+ 
+ static void internal_snapshot_clean(BlkActionState *common)
+ {
+     InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState,
+                                              common, common);
++    AioContext *aio_context;
+ 
+-    if (state->aio_context) {
+-        if (state->bs) {
+-            bdrv_drained_end(state->bs);
+-        }
+-        aio_context_release(state->aio_context);
++    if (!state->bs) {
++        return;
+     }
++
++    aio_context = bdrv_get_aio_context(state->bs);
++    aio_context_acquire(aio_context);
++
++    bdrv_drained_end(state->bs);
++
++    aio_context_release(aio_context);
+ }
+ 
+ /* external snapshot private data */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-move-ThrottleGroup-membership-to-ThrottleGroup.patch b/SOURCES/kvm-block-move-ThrottleGroup-membership-to-ThrottleGroup.patch
new file mode 100644
index 0000000..f9ac543
--- /dev/null
+++ b/SOURCES/kvm-block-move-ThrottleGroup-membership-to-ThrottleGroup.patch
@@ -0,0 +1,1023 @@
+From 6b39617d8b6ec2930c61e8965452317afbdf8030 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:00 +0100
+Subject: [PATCH 01/15] block: move ThrottleGroup membership to
+ ThrottleGroupMember
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-2-stefanha@redhat.com>
+Patchwork-id: 77737
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/9] block: move ThrottleGroup membership to ThrottleGroupMember
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Manos Pitsidianakis <el13635@mail.ntua.gr>
+
+This commit eliminates the 1:1 relationship between BlockBackend and
+throttle group state.  Users will be able to create multiple throttle
+nodes, each with its own throttle group state, in the future.  The
+throttle group state cannot be per-BlockBackend anymore, it must be
+per-throttle node. This is done by gathering ThrottleGroup membership
+details from BlockBackendPublic into ThrottleGroupMember and refactoring
+existing code to use the structure.
+
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 022cdc9f407434ad6eb7ace80362a1218a009bcc)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c           |  66 +++++----
+ block/qapi.c                    |   8 +-
+ block/throttle-groups.c         | 288 ++++++++++++++++++++--------------------
+ blockdev.c                      |   4 +-
+ include/block/throttle-groups.h |  39 +++++-
+ include/sysemu/block-backend.h  |  20 +--
+ tests/test-throttle.c           |  53 ++++----
+ 7 files changed, 252 insertions(+), 226 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 0819b3a..e61f072 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -273,9 +273,9 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
+     blk->shared_perm = shared_perm;
+     blk_set_enable_write_cache(blk, true);
+ 
+-    qemu_co_mutex_init(&blk->public.throttled_reqs_lock);
+-    qemu_co_queue_init(&blk->public.throttled_reqs[0]);
+-    qemu_co_queue_init(&blk->public.throttled_reqs[1]);
++    qemu_co_mutex_init(&blk->public.throttle_group_member.throttled_reqs_lock);
++    qemu_co_queue_init(&blk->public.throttle_group_member.throttled_reqs[0]);
++    qemu_co_queue_init(&blk->public.throttle_group_member.throttled_reqs[1]);
+     block_acct_init(&blk->stats);
+ 
+     notifier_list_init(&blk->remove_bs_notifiers);
+@@ -343,7 +343,7 @@ static void blk_delete(BlockBackend *blk)
+     assert(!blk->refcnt);
+     assert(!blk->name);
+     assert(!blk->dev);
+-    if (blk->public.throttle_state) {
++    if (blk->public.throttle_group_member.throttle_state) {
+         blk_io_limits_disable(blk);
+     }
+     if (blk->root) {
+@@ -658,9 +658,12 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
+  */
+ void blk_remove_bs(BlockBackend *blk)
+ {
++    ThrottleTimers *tt;
++
+     notifier_list_notify(&blk->remove_bs_notifiers, blk);
+-    if (blk->public.throttle_state) {
+-        throttle_timers_detach_aio_context(&blk->public.throttle_timers);
++    if (blk->public.throttle_group_member.throttle_state) {
++        tt = &blk->public.throttle_group_member.throttle_timers;
++        throttle_timers_detach_aio_context(tt);
+     }
+ 
+     blk_update_root_state(blk);
+@@ -682,9 +685,10 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
+     bdrv_ref(bs);
+ 
+     notifier_list_notify(&blk->insert_bs_notifiers, blk);
+-    if (blk->public.throttle_state) {
++    if (blk->public.throttle_group_member.throttle_state) {
+         throttle_timers_attach_aio_context(
+-            &blk->public.throttle_timers, bdrv_get_aio_context(bs));
++            &blk->public.throttle_group_member.throttle_timers,
++            bdrv_get_aio_context(bs));
+     }
+ 
+     return 0;
+@@ -1046,8 +1050,9 @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
+     bdrv_inc_in_flight(bs);
+ 
+     /* throttling disk I/O */
+-    if (blk->public.throttle_state) {
+-        throttle_group_co_io_limits_intercept(blk, bytes, false);
++    if (blk->public.throttle_group_member.throttle_state) {
++        throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
++                bytes, false);
+     }
+ 
+     ret = bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
+@@ -1070,10 +1075,10 @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
+     }
+ 
+     bdrv_inc_in_flight(bs);
+-
+     /* throttling disk I/O */
+-    if (blk->public.throttle_state) {
+-        throttle_group_co_io_limits_intercept(blk, bytes, true);
++    if (blk->public.throttle_group_member.throttle_state) {
++        throttle_group_co_io_limits_intercept(&blk->public.throttle_group_member,
++                bytes, true);
+     }
+ 
+     if (!blk->enable_write_cache) {
+@@ -1761,15 +1766,17 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
+ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
+ {
+     BlockDriverState *bs = blk_bs(blk);
++    ThrottleTimers *tt;
+ 
+     if (bs) {
+-        if (blk->public.throttle_state) {
+-            throttle_timers_detach_aio_context(&blk->public.throttle_timers);
++        if (blk->public.throttle_group_member.throttle_state) {
++            tt = &blk->public.throttle_group_member.throttle_timers;
++            throttle_timers_detach_aio_context(tt);
+         }
+         bdrv_set_aio_context(bs, new_context);
+-        if (blk->public.throttle_state) {
+-            throttle_timers_attach_aio_context(&blk->public.throttle_timers,
+-                                               new_context);
++        if (blk->public.throttle_group_member.throttle_state) {
++            tt = &blk->public.throttle_group_member.throttle_timers;
++            throttle_timers_attach_aio_context(tt, new_context);
+         }
+     }
+ }
+@@ -1988,33 +1995,34 @@ int blk_commit_all(void)
+ /* throttling disk I/O limits */
+ void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
+ {
+-    throttle_group_config(blk, cfg);
++    throttle_group_config(&blk->public.throttle_group_member, cfg);
+ }
+ 
+ void blk_io_limits_disable(BlockBackend *blk)
+ {
+-    assert(blk->public.throttle_state);
++    assert(blk->public.throttle_group_member.throttle_state);
+     bdrv_drained_begin(blk_bs(blk));
+-    throttle_group_unregister_blk(blk);
++    throttle_group_unregister_tgm(&blk->public.throttle_group_member);
+     bdrv_drained_end(blk_bs(blk));
+ }
+ 
+ /* should be called before blk_set_io_limits if a limit is set */
+ void blk_io_limits_enable(BlockBackend *blk, const char *group)
+ {
+-    assert(!blk->public.throttle_state);
+-    throttle_group_register_blk(blk, group);
++    assert(!blk->public.throttle_group_member.throttle_state);
++    throttle_group_register_tgm(&blk->public.throttle_group_member, group);
+ }
+ 
+ void blk_io_limits_update_group(BlockBackend *blk, const char *group)
+ {
+     /* this BB is not part of any group */
+-    if (!blk->public.throttle_state) {
++    if (!blk->public.throttle_group_member.throttle_state) {
+         return;
+     }
+ 
+     /* this BB is a part of the same group than the one we want */
+-    if (!g_strcmp0(throttle_group_get_name(blk), group)) {
++    if (!g_strcmp0(throttle_group_get_name(&blk->public.throttle_group_member),
++                group)) {
+         return;
+     }
+ 
+@@ -2036,8 +2044,8 @@ static void blk_root_drained_begin(BdrvChild *child)
+     /* Note that blk->root may not be accessible here yet if we are just
+      * attaching to a BlockDriverState that is drained. Use child instead. */
+ 
+-    if (atomic_fetch_inc(&blk->public.io_limits_disabled) == 0) {
+-        throttle_group_restart_blk(blk);
++    if (atomic_fetch_inc(&blk->public.throttle_group_member.io_limits_disabled) == 0) {
++        throttle_group_restart_tgm(&blk->public.throttle_group_member);
+     }
+ }
+ 
+@@ -2046,8 +2054,8 @@ static void blk_root_drained_end(BdrvChild *child)
+     BlockBackend *blk = child->opaque;
+     assert(blk->quiesce_counter);
+ 
+-    assert(blk->public.io_limits_disabled);
+-    atomic_dec(&blk->public.io_limits_disabled);
++    assert(blk->public.throttle_group_member.io_limits_disabled);
++    atomic_dec(&blk->public.throttle_group_member.io_limits_disabled);
+ 
+     if (--blk->quiesce_counter == 0) {
+         if (blk->dev_ops && blk->dev_ops->drained_end) {
+diff --git a/block/qapi.c b/block/qapi.c
+index 5f1a71f..7fa2437 100644
+--- a/block/qapi.c
++++ b/block/qapi.c
+@@ -66,10 +66,11 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
+ 
+     info->detect_zeroes = bs->detect_zeroes;
+ 
+-    if (blk && blk_get_public(blk)->throttle_state) {
++    if (blk && blk_get_public(blk)->throttle_group_member.throttle_state) {
+         ThrottleConfig cfg;
++        BlockBackendPublic *blkp = blk_get_public(blk);
+ 
+-        throttle_group_get_config(blk, &cfg);
++        throttle_group_get_config(&blkp->throttle_group_member, &cfg);
+ 
+         info->bps     = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
+         info->bps_rd  = cfg.buckets[THROTTLE_BPS_READ].avg;
+@@ -117,7 +118,8 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
+         info->iops_size = cfg.op_size;
+ 
+         info->has_group = true;
+-        info->group = g_strdup(throttle_group_get_name(blk));
++        info->group =
++            g_strdup(throttle_group_get_name(&blkp->throttle_group_member));
+     }
+ 
+     info->write_threshold = bdrv_write_threshold_get(bs);
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index 890bfde..c8ed16d 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -30,7 +30,7 @@
+ #include "sysemu/qtest.h"
+ 
+ /* The ThrottleGroup structure (with its ThrottleState) is shared
+- * among different BlockBackends and it's independent from
++ * among different ThrottleGroupMembers and it's independent from
+  * AioContext, so in order to use it from different threads it needs
+  * its own locking.
+  *
+@@ -40,26 +40,26 @@
+  * The whole ThrottleGroup structure is private and invisible to
+  * outside users, that only use it through its ThrottleState.
+  *
+- * In addition to the ThrottleGroup structure, BlockBackendPublic has
++ * In addition to the ThrottleGroup structure, ThrottleGroupMember has
+  * fields that need to be accessed by other members of the group and
+  * therefore also need to be protected by this lock. Once a
+- * BlockBackend is registered in a group those fields can be accessed
++ * ThrottleGroupMember is registered in a group those fields can be accessed
+  * by other threads any time.
+  *
+  * Again, all this is handled internally and is mostly transparent to
+  * the outside. The 'throttle_timers' field however has an additional
+  * constraint because it may be temporarily invalid (see for example
+  * blk_set_aio_context()). Therefore in this file a thread will
+- * access some other BlockBackend's timers only after verifying that
+- * that BlockBackend has throttled requests in the queue.
++ * access some other ThrottleGroupMember's timers only after verifying that
++ * that ThrottleGroupMember has throttled requests in the queue.
+  */
+ typedef struct ThrottleGroup {
+     char *name; /* This is constant during the lifetime of the group */
+ 
+     QemuMutex lock; /* This lock protects the following four fields */
+     ThrottleState ts;
+-    QLIST_HEAD(, BlockBackendPublic) head;
+-    BlockBackend *tokens[2];
++    QLIST_HEAD(, ThrottleGroupMember) head;
++    ThrottleGroupMember *tokens[2];
+     bool any_timer_armed[2];
+     QEMUClockType clock_type;
+ 
+@@ -140,114 +140,112 @@ void throttle_group_unref(ThrottleState *ts)
+     qemu_mutex_unlock(&throttle_groups_lock);
+ }
+ 
+-/* Get the name from a BlockBackend's ThrottleGroup. The name (and the pointer)
++/* Get the name from a ThrottleGroupMember's group. The name (and the pointer)
+  * is guaranteed to remain constant during the lifetime of the group.
+  *
+- * @blk:  a BlockBackend that is member of a throttling group
++ * @tgm:  a ThrottleGroupMember
+  * @ret:  the name of the group.
+  */
+-const char *throttle_group_get_name(BlockBackend *blk)
++const char *throttle_group_get_name(ThrottleGroupMember *tgm)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
++    ThrottleGroup *tg = container_of(tgm->throttle_state, ThrottleGroup, ts);
+     return tg->name;
+ }
+ 
+-/* Return the next BlockBackend in the round-robin sequence, simulating a
+- * circular list.
++/* Return the next ThrottleGroupMember in the round-robin sequence, simulating
++ * a circular list.
+  *
+  * This assumes that tg->lock is held.
+  *
+- * @blk: the current BlockBackend
+- * @ret: the next BlockBackend in the sequence
++ * @tgm: the current ThrottleGroupMember
++ * @ret: the next ThrottleGroupMember in the sequence
+  */
+-static BlockBackend *throttle_group_next_blk(BlockBackend *blk)
++static ThrottleGroupMember *throttle_group_next_tgm(ThrottleGroupMember *tgm)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleState *ts = blkp->throttle_state;
++    ThrottleState *ts = tgm->throttle_state;
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+-    BlockBackendPublic *next = QLIST_NEXT(blkp, round_robin);
++    ThrottleGroupMember *next = QLIST_NEXT(tgm, round_robin);
+ 
+     if (!next) {
+         next = QLIST_FIRST(&tg->head);
+     }
+ 
+-    return blk_by_public(next);
++    return next;
+ }
+ 
+ /*
+- * Return whether a BlockBackend has pending requests.
++ * Return whether a ThrottleGroupMember has pending requests.
+  *
+  * This assumes that tg->lock is held.
+  *
+- * @blk: the BlockBackend
+- * @is_write:  the type of operation (read/write)
+- * @ret:       whether the BlockBackend has pending requests.
++ * @tgm:        the ThrottleGroupMember
++ * @is_write:   the type of operation (read/write)
++ * @ret:        whether the ThrottleGroupMember has pending requests.
+  */
+-static inline bool blk_has_pending_reqs(BlockBackend *blk,
++static inline bool tgm_has_pending_reqs(ThrottleGroupMember *tgm,
+                                         bool is_write)
+ {
+-    const BlockBackendPublic *blkp = blk_get_public(blk);
+-    return blkp->pending_reqs[is_write];
++    return tgm->pending_reqs[is_write];
+ }
+ 
+-/* Return the next BlockBackend in the round-robin sequence with pending I/O
+- * requests.
++/* Return the next ThrottleGroupMember in the round-robin sequence with pending
++ * I/O requests.
+  *
+  * This assumes that tg->lock is held.
+  *
+- * @blk:       the current BlockBackend
++ * @tgm:       the current ThrottleGroupMember
+  * @is_write:  the type of operation (read/write)
+- * @ret:       the next BlockBackend with pending requests, or blk if there is
+- *             none.
++ * @ret:       the next ThrottleGroupMember with pending requests, or tgm if
++ *             there is none.
+  */
+-static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
++static ThrottleGroupMember *next_throttle_token(ThrottleGroupMember *tgm,
++                                                bool is_write)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+-    BlockBackend *token, *start;
++    ThrottleState *ts = tgm->throttle_state;
++    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
++    ThrottleGroupMember *token, *start;
+ 
+     start = token = tg->tokens[is_write];
+ 
+     /* get next bs round in round robin style */
+-    token = throttle_group_next_blk(token);
+-    while (token != start && !blk_has_pending_reqs(token, is_write)) {
+-        token = throttle_group_next_blk(token);
++    token = throttle_group_next_tgm(token);
++    while (token != start && !tgm_has_pending_reqs(token, is_write)) {
++        token = throttle_group_next_tgm(token);
+     }
+ 
+     /* If no IO are queued for scheduling on the next round robin token
+-     * then decide the token is the current bs because chances are
+-     * the current bs get the current request queued.
++     * then decide the token is the current tgm because chances are
++     * the current tgm got the current request queued.
+      */
+-    if (token == start && !blk_has_pending_reqs(token, is_write)) {
+-        token = blk;
++    if (token == start && !tgm_has_pending_reqs(token, is_write)) {
++        token = tgm;
+     }
+ 
+-    /* Either we return the original BB, or one with pending requests */
+-    assert(token == blk || blk_has_pending_reqs(token, is_write));
++    /* Either we return the original TGM, or one with pending requests */
++    assert(token == tgm || tgm_has_pending_reqs(token, is_write));
+ 
+     return token;
+ }
+ 
+-/* Check if the next I/O request for a BlockBackend needs to be throttled or
+- * not. If there's no timer set in this group, set one and update the token
+- * accordingly.
++/* Check if the next I/O request for a ThrottleGroupMember needs to be
++ * throttled or not. If there's no timer set in this group, set one and update
++ * the token accordingly.
+  *
+  * This assumes that tg->lock is held.
+  *
+- * @blk:        the current BlockBackend
++ * @tgm:        the current ThrottleGroupMember
+  * @is_write:   the type of operation (read/write)
+  * @ret:        whether the I/O request needs to be throttled or not
+  */
+-static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
++static bool throttle_group_schedule_timer(ThrottleGroupMember *tgm,
++                                          bool is_write)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleState *ts = blkp->throttle_state;
+-    ThrottleTimers *tt = &blkp->throttle_timers;
++    ThrottleState *ts = tgm->throttle_state;
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
++    ThrottleTimers *tt = &tgm->throttle_timers;
+     bool must_wait;
+ 
+-    if (atomic_read(&blkp->io_limits_disabled)) {
++    if (atomic_read(&tgm->io_limits_disabled)) {
+         return false;
+     }
+ 
+@@ -258,30 +256,29 @@ static bool throttle_group_schedule_timer(BlockBackend *blk, bool is_write)
+ 
+     must_wait = throttle_schedule_timer(ts, tt, is_write);
+ 
+-    /* If a timer just got armed, set blk as the current token */
++    /* If a timer just got armed, set tgm as the current token */
+     if (must_wait) {
+-        tg->tokens[is_write] = blk;
++        tg->tokens[is_write] = tgm;
+         tg->any_timer_armed[is_write] = true;
+     }
+ 
+     return must_wait;
+ }
+ 
+-/* Start the next pending I/O request for a BlockBackend.  Return whether
++/* Start the next pending I/O request for a ThrottleGroupMember. Return whether
+  * any request was actually pending.
+  *
+- * @blk:       the current BlockBackend
++ * @tgm:       the current ThrottleGroupMember
+  * @is_write:  the type of operation (read/write)
+  */
+-static bool coroutine_fn throttle_group_co_restart_queue(BlockBackend *blk,
++static bool coroutine_fn throttle_group_co_restart_queue(ThrottleGroupMember *tgm,
+                                                          bool is_write)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+     bool ret;
+ 
+-    qemu_co_mutex_lock(&blkp->throttled_reqs_lock);
+-    ret = qemu_co_queue_next(&blkp->throttled_reqs[is_write]);
+-    qemu_co_mutex_unlock(&blkp->throttled_reqs_lock);
++    qemu_co_mutex_lock(&tgm->throttled_reqs_lock);
++    ret = qemu_co_queue_next(&tgm->throttled_reqs[is_write]);
++    qemu_co_mutex_unlock(&tgm->throttled_reqs_lock);
+ 
+     return ret;
+ }
+@@ -290,19 +287,19 @@ static bool coroutine_fn throttle_group_co_restart_queue(BlockBackend *blk,
+  *
+  * This assumes that tg->lock is held.
+  *
+- * @blk:       the current BlockBackend
++ * @tgm:       the current ThrottleGroupMember
+  * @is_write:  the type of operation (read/write)
+  */
+-static void schedule_next_request(BlockBackend *blk, bool is_write)
++static void schedule_next_request(ThrottleGroupMember *tgm, bool is_write)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
++    ThrottleState *ts = tgm->throttle_state;
++    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+     bool must_wait;
+-    BlockBackend *token;
++    ThrottleGroupMember *token;
+ 
+     /* Check if there's any pending request to schedule next */
+-    token = next_throttle_token(blk, is_write);
+-    if (!blk_has_pending_reqs(token, is_write)) {
++    token = next_throttle_token(tgm, is_write);
++    if (!tgm_has_pending_reqs(token, is_write)) {
+         return;
+     }
+ 
+@@ -311,12 +308,12 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
+ 
+     /* If it doesn't have to wait, queue it for immediate execution */
+     if (!must_wait) {
+-        /* Give preference to requests from the current blk */
++        /* Give preference to requests from the current tgm */
+         if (qemu_in_coroutine() &&
+-            throttle_group_co_restart_queue(blk, is_write)) {
+-            token = blk;
++            throttle_group_co_restart_queue(tgm, is_write)) {
++            token = tgm;
+         } else {
+-            ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
++            ThrottleTimers *tt = &token->throttle_timers;
+             int64_t now = qemu_clock_get_ns(tg->clock_type);
+             timer_mod(tt->timers[is_write], now);
+             tg->any_timer_armed[is_write] = true;
+@@ -329,76 +326,77 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
+  * if necessary, and schedule the next request using a round robin
+  * algorithm.
+  *
+- * @blk:       the current BlockBackend
++ * @tgm:       the current ThrottleGroupMember
+  * @bytes:     the number of bytes for this I/O
+  * @is_write:  the type of operation (read/write)
+  */
+-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
++void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
+                                                         unsigned int bytes,
+                                                         bool is_write)
+ {
+     bool must_wait;
+-    BlockBackend *token;
+-
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
++    ThrottleGroupMember *token;
++    ThrottleGroup *tg = container_of(tgm->throttle_state, ThrottleGroup, ts);
+     qemu_mutex_lock(&tg->lock);
+ 
+     /* First we check if this I/O has to be throttled. */
+-    token = next_throttle_token(blk, is_write);
++    token = next_throttle_token(tgm, is_write);
+     must_wait = throttle_group_schedule_timer(token, is_write);
+ 
+     /* Wait if there's a timer set or queued requests of this type */
+-    if (must_wait || blkp->pending_reqs[is_write]) {
+-        blkp->pending_reqs[is_write]++;
++    if (must_wait || tgm->pending_reqs[is_write]) {
++        tgm->pending_reqs[is_write]++;
+         qemu_mutex_unlock(&tg->lock);
+-        qemu_co_mutex_lock(&blkp->throttled_reqs_lock);
+-        qemu_co_queue_wait(&blkp->throttled_reqs[is_write],
+-                           &blkp->throttled_reqs_lock);
+-        qemu_co_mutex_unlock(&blkp->throttled_reqs_lock);
++        qemu_co_mutex_lock(&tgm->throttled_reqs_lock);
++        qemu_co_queue_wait(&tgm->throttled_reqs[is_write],
++                           &tgm->throttled_reqs_lock);
++        qemu_co_mutex_unlock(&tgm->throttled_reqs_lock);
+         qemu_mutex_lock(&tg->lock);
+-        blkp->pending_reqs[is_write]--;
++        tgm->pending_reqs[is_write]--;
+     }
+ 
+     /* The I/O will be executed, so do the accounting */
+-    throttle_account(blkp->throttle_state, is_write, bytes);
++    throttle_account(tgm->throttle_state, is_write, bytes);
+ 
+     /* Schedule the next request */
+-    schedule_next_request(blk, is_write);
++    schedule_next_request(tgm, is_write);
+ 
+     qemu_mutex_unlock(&tg->lock);
+ }
+ 
+ typedef struct {
+-    BlockBackend *blk;
++    ThrottleGroupMember *tgm;
+     bool is_write;
+ } RestartData;
+ 
+ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
+ {
+     RestartData *data = opaque;
+-    BlockBackend *blk = data->blk;
++    ThrottleGroupMember *tgm = data->tgm;
++    ThrottleState *ts = tgm->throttle_state;
++    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+     bool is_write = data->is_write;
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
+     bool empty_queue;
+ 
+-    empty_queue = !throttle_group_co_restart_queue(blk, is_write);
++    empty_queue = !throttle_group_co_restart_queue(tgm, is_write);
+ 
+     /* If the request queue was empty then we have to take care of
+      * scheduling the next one */
+     if (empty_queue) {
+         qemu_mutex_lock(&tg->lock);
+-        schedule_next_request(blk, is_write);
++        schedule_next_request(tgm, is_write);
+         qemu_mutex_unlock(&tg->lock);
+     }
+ }
+ 
+-static void throttle_group_restart_queue(BlockBackend *blk, bool is_write)
++static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write)
+ {
++    BlockBackendPublic *blkp = container_of(tgm, BlockBackendPublic,
++            throttle_group_member);
++    BlockBackend *blk = blk_by_public(blkp);
+     Coroutine *co;
+     RestartData rd = {
+-        .blk = blk,
++        .tgm = tgm,
+         .is_write = is_write
+     };
+ 
+@@ -406,13 +404,11 @@ static void throttle_group_restart_queue(BlockBackend *blk, bool is_write)
+     aio_co_enter(blk_get_aio_context(blk), co);
+ }
+ 
+-void throttle_group_restart_blk(BlockBackend *blk)
++void throttle_group_restart_tgm(ThrottleGroupMember *tgm)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-
+-    if (blkp->throttle_state) {
+-        throttle_group_restart_queue(blk, 0);
+-        throttle_group_restart_queue(blk, 1);
++    if (tgm->throttle_state) {
++        throttle_group_restart_queue(tgm, 0);
++        throttle_group_restart_queue(tgm, 1);
+     }
+ }
+ 
+@@ -420,32 +416,30 @@ void throttle_group_restart_blk(BlockBackend *blk)
+  * to throttle_config(), but guarantees atomicity within the
+  * throttling group.
+  *
+- * @blk: a BlockBackend that is a member of the group
++ * @tgm:    a ThrottleGroupMember that is a member of the group
+  * @cfg: the configuration to set
+  */
+-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
++void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleState *ts = blkp->throttle_state;
++    ThrottleState *ts = tgm->throttle_state;
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+     qemu_mutex_lock(&tg->lock);
+     throttle_config(ts, tg->clock_type, cfg);
+     qemu_mutex_unlock(&tg->lock);
+ 
+-    throttle_group_restart_blk(blk);
++    throttle_group_restart_tgm(tgm);
+ }
+ 
+ /* Get the throttle configuration from a particular group. Similar to
+  * throttle_get_config(), but guarantees atomicity within the
+  * throttling group.
+  *
+- * @blk: a BlockBackend that is a member of the group
++ * @tgm:    a ThrottleGroupMember that is a member of the group
+  * @cfg: the configuration will be written here
+  */
+-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg)
++void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleState *ts = blkp->throttle_state;
++    ThrottleState *ts = tgm->throttle_state;
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+     qemu_mutex_lock(&tg->lock);
+     throttle_get_config(ts, cfg);
+@@ -461,7 +455,8 @@ void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg)
+ static void timer_cb(BlockBackend *blk, bool is_write)
+ {
+     BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleState *ts = blkp->throttle_state;
++    ThrottleGroupMember *tgm = &blkp->throttle_group_member;
++    ThrottleState *ts = tgm->throttle_state;
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+ 
+     /* The timer has just been fired, so we can update the flag */
+@@ -470,7 +465,7 @@ static void timer_cb(BlockBackend *blk, bool is_write)
+     qemu_mutex_unlock(&tg->lock);
+ 
+     /* Run the request that was waiting for this timer */
+-    throttle_group_restart_queue(blk, is_write);
++    throttle_group_restart_queue(tgm, is_write);
+ }
+ 
+ static void read_timer_cb(void *opaque)
+@@ -483,32 +478,36 @@ static void write_timer_cb(void *opaque)
+     timer_cb(opaque, true);
+ }
+ 
+-/* Register a BlockBackend in the throttling group, also initializing its
+- * timers and updating its throttle_state pointer to point to it. If a
++/* Register a ThrottleGroupMember from the throttling group, also initializing
++ * its timers and updating its throttle_state pointer to point to it. If a
+  * throttling group with that name does not exist yet, it will be created.
+  *
+- * @blk:       the BlockBackend to insert
++ * @tgm:       the ThrottleGroupMember to insert
+  * @groupname: the name of the group
+  */
+-void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
++void throttle_group_register_tgm(ThrottleGroupMember *tgm,
++                                 const char *groupname)
+ {
+     int i;
+-    BlockBackendPublic *blkp = blk_get_public(blk);
++    BlockBackendPublic *blkp = container_of(tgm, BlockBackendPublic,
++            throttle_group_member);
++    BlockBackend *blk = blk_by_public(blkp);
+     ThrottleState *ts = throttle_group_incref(groupname);
+     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
+-    blkp->throttle_state = ts;
++
++    tgm->throttle_state = ts;
+ 
+     qemu_mutex_lock(&tg->lock);
+-    /* If the ThrottleGroup is new set this BlockBackend as the token */
++    /* If the ThrottleGroup is new set this ThrottleGroupMember as the token */
+     for (i = 0; i < 2; i++) {
+         if (!tg->tokens[i]) {
+-            tg->tokens[i] = blk;
++            tg->tokens[i] = tgm;
+         }
+     }
+ 
+-    QLIST_INSERT_HEAD(&tg->head, blkp, round_robin);
++    QLIST_INSERT_HEAD(&tg->head, tgm, round_robin);
+ 
+-    throttle_timers_init(&blkp->throttle_timers,
++    throttle_timers_init(&tgm->throttle_timers,
+                          blk_get_aio_context(blk),
+                          tg->clock_type,
+                          read_timer_cb,
+@@ -518,45 +517,46 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
+     qemu_mutex_unlock(&tg->lock);
+ }
+ 
+-/* Unregister a BlockBackend from its group, removing it from the list,
++/* Unregister a ThrottleGroupMember from its group, removing it from the list,
+  * destroying the timers and setting the throttle_state pointer to NULL.
+  *
+- * The BlockBackend must not have pending throttled requests, so the caller has
+- * to drain them first.
++ * The ThrottleGroupMember must not have pending throttled requests, so the
++ * caller has to drain them first.
+  *
+  * The group will be destroyed if it's empty after this operation.
+  *
+- * @blk: the BlockBackend to remove
++ * @tgm the ThrottleGroupMember to remove
+  */
+-void throttle_group_unregister_blk(BlockBackend *blk)
++void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
+ {
+-    BlockBackendPublic *blkp = blk_get_public(blk);
+-    ThrottleGroup *tg = container_of(blkp->throttle_state, ThrottleGroup, ts);
++    ThrottleState *ts = tgm->throttle_state;
++    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
++    ThrottleGroupMember *token;
+     int i;
+ 
+-    assert(blkp->pending_reqs[0] == 0 && blkp->pending_reqs[1] == 0);
+-    assert(qemu_co_queue_empty(&blkp->throttled_reqs[0]));
+-    assert(qemu_co_queue_empty(&blkp->throttled_reqs[1]));
++    assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
++    assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
++    assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
+ 
+     qemu_mutex_lock(&tg->lock);
+     for (i = 0; i < 2; i++) {
+-        if (tg->tokens[i] == blk) {
+-            BlockBackend *token = throttle_group_next_blk(blk);
+-            /* Take care of the case where this is the last blk in the group */
+-            if (token == blk) {
++        if (tg->tokens[i] == tgm) {
++            token = throttle_group_next_tgm(tgm);
++            /* Take care of the case where this is the last tgm in the group */
++            if (token == tgm) {
+                 token = NULL;
+             }
+             tg->tokens[i] = token;
+         }
+     }
+ 
+-    /* remove the current blk from the list */
+-    QLIST_REMOVE(blkp, round_robin);
+-    throttle_timers_destroy(&blkp->throttle_timers);
++    /* remove the current tgm from the list */
++    QLIST_REMOVE(tgm, round_robin);
++    throttle_timers_destroy(&tgm->throttle_timers);
+     qemu_mutex_unlock(&tg->lock);
+ 
+     throttle_group_unref(&tg->ts);
+-    blkp->throttle_state = NULL;
++    tgm->throttle_state = NULL;
+ }
+ 
+ static void throttle_groups_init(void)
+diff --git a/blockdev.c b/blockdev.c
+index d54ea6f..0f063ec 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -2729,7 +2729,7 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
+     if (throttle_enabled(&cfg)) {
+         /* Enable I/O limits if they're not enabled yet, otherwise
+          * just update the throttling group. */
+-        if (!blk_get_public(blk)->throttle_state) {
++        if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
+             blk_io_limits_enable(blk,
+                                  arg->has_group ? arg->group :
+                                  arg->has_device ? arg->device :
+@@ -2739,7 +2739,7 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
+         }
+         /* Set the new throttling configuration */
+         blk_set_io_limits(blk, &cfg);
+-    } else if (blk_get_public(blk)->throttle_state) {
++    } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
+         /* If all throttling settings are set to 0, disable I/O limits */
+         blk_io_limits_disable(blk);
+     }
+diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
+index d983d34..1a6bcda 100644
+--- a/include/block/throttle-groups.h
++++ b/include/block/throttle-groups.h
+@@ -28,19 +28,44 @@
+ #include "qemu/throttle.h"
+ #include "block/block_int.h"
+ 
+-const char *throttle_group_get_name(BlockBackend *blk);
++/* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
++ * and holds related data.
++ */
++
++typedef struct ThrottleGroupMember {
++    /* throttled_reqs_lock protects the CoQueues for throttled requests.  */
++    CoMutex      throttled_reqs_lock;
++    CoQueue      throttled_reqs[2];
++
++    /* Nonzero if the I/O limits are currently being ignored; generally
++     * it is zero.  Accessed with atomic operations.
++     */
++    unsigned int io_limits_disabled;
++
++    /* The following fields are protected by the ThrottleGroup lock.
++     * See the ThrottleGroup documentation for details.
++     * throttle_state tells us if I/O limits are configured. */
++    ThrottleState *throttle_state;
++    ThrottleTimers throttle_timers;
++    unsigned       pending_reqs[2];
++    QLIST_ENTRY(ThrottleGroupMember) round_robin;
++
++} ThrottleGroupMember;
++
++const char *throttle_group_get_name(ThrottleGroupMember *tgm);
+ 
+ ThrottleState *throttle_group_incref(const char *name);
+ void throttle_group_unref(ThrottleState *ts);
+ 
+-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg);
+-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg);
++void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
++void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
+ 
+-void throttle_group_register_blk(BlockBackend *blk, const char *groupname);
+-void throttle_group_unregister_blk(BlockBackend *blk);
+-void throttle_group_restart_blk(BlockBackend *blk);
++void throttle_group_register_tgm(ThrottleGroupMember *tgm,
++                                const char *groupname);
++void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
++void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
+ 
+-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
++void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
+                                                         unsigned int bytes,
+                                                         bool is_write);
+ 
+diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
+index aadc733..c4e52a5 100644
+--- a/include/sysemu/block-backend.h
++++ b/include/sysemu/block-backend.h
+@@ -70,24 +70,10 @@ typedef struct BlockDevOps {
+ 
+ /* This struct is embedded in (the private) BlockBackend struct and contains
+  * fields that must be public. This is in particular for QLIST_ENTRY() and
+- * friends so that BlockBackends can be kept in lists outside block-backend.c */
++ * friends so that BlockBackends can be kept in lists outside block-backend.c
++ * */
+ typedef struct BlockBackendPublic {
+-    /* throttled_reqs_lock protects the CoQueues for throttled requests.  */
+-    CoMutex      throttled_reqs_lock;
+-    CoQueue      throttled_reqs[2];
+-
+-    /* Nonzero if the I/O limits are currently being ignored; generally
+-     * it is zero.  Accessed with atomic operations.
+-     */
+-    unsigned int io_limits_disabled;
+-
+-    /* The following fields are protected by the ThrottleGroup lock.
+-     * See the ThrottleGroup documentation for details.
+-     * throttle_state tells us if I/O limits are configured. */
+-    ThrottleState *throttle_state;
+-    ThrottleTimers throttle_timers;
+-    unsigned       pending_reqs[2];
+-    QLIST_ENTRY(BlockBackendPublic) round_robin;
++    ThrottleGroupMember throttle_group_member;
+ } BlockBackendPublic;
+ 
+ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm);
+diff --git a/tests/test-throttle.c b/tests/test-throttle.c
+index 768f11d..6e6d926 100644
+--- a/tests/test-throttle.c
++++ b/tests/test-throttle.c
+@@ -592,6 +592,7 @@ static void test_groups(void)
+     ThrottleConfig cfg1, cfg2;
+     BlockBackend *blk1, *blk2, *blk3;
+     BlockBackendPublic *blkp1, *blkp2, *blkp3;
++    ThrottleGroupMember *tgm1, *tgm2, *tgm3;
+ 
+     /* No actual I/O is performed on these devices */
+     blk1 = blk_new(0, BLK_PERM_ALL);
+@@ -602,21 +603,25 @@ static void test_groups(void)
+     blkp2 = blk_get_public(blk2);
+     blkp3 = blk_get_public(blk3);
+ 
+-    g_assert(blkp1->throttle_state == NULL);
+-    g_assert(blkp2->throttle_state == NULL);
+-    g_assert(blkp3->throttle_state == NULL);
++    tgm1 = &blkp1->throttle_group_member;
++    tgm2 = &blkp2->throttle_group_member;
++    tgm3 = &blkp3->throttle_group_member;
+ 
+-    throttle_group_register_blk(blk1, "bar");
+-    throttle_group_register_blk(blk2, "foo");
+-    throttle_group_register_blk(blk3, "bar");
++    g_assert(tgm1->throttle_state == NULL);
++    g_assert(tgm2->throttle_state == NULL);
++    g_assert(tgm3->throttle_state == NULL);
+ 
+-    g_assert(blkp1->throttle_state != NULL);
+-    g_assert(blkp2->throttle_state != NULL);
+-    g_assert(blkp3->throttle_state != NULL);
++    throttle_group_register_tgm(tgm1, "bar");
++    throttle_group_register_tgm(tgm2, "foo");
++    throttle_group_register_tgm(tgm3, "bar");
+ 
+-    g_assert(!strcmp(throttle_group_get_name(blk1), "bar"));
+-    g_assert(!strcmp(throttle_group_get_name(blk2), "foo"));
+-    g_assert(blkp1->throttle_state == blkp3->throttle_state);
++    g_assert(tgm1->throttle_state != NULL);
++    g_assert(tgm2->throttle_state != NULL);
++    g_assert(tgm3->throttle_state != NULL);
++
++    g_assert(!strcmp(throttle_group_get_name(tgm1), "bar"));
++    g_assert(!strcmp(throttle_group_get_name(tgm2), "foo"));
++    g_assert(tgm1->throttle_state == tgm3->throttle_state);
+ 
+     /* Setting the config of a group member affects the whole group */
+     throttle_config_init(&cfg1);
+@@ -624,29 +629,29 @@ static void test_groups(void)
+     cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000;
+     cfg1.buckets[THROTTLE_OPS_READ].avg  = 20000;
+     cfg1.buckets[THROTTLE_OPS_WRITE].avg = 12000;
+-    throttle_group_config(blk1, &cfg1);
++    throttle_group_config(tgm1, &cfg1);
+ 
+-    throttle_group_get_config(blk1, &cfg1);
+-    throttle_group_get_config(blk3, &cfg2);
++    throttle_group_get_config(tgm1, &cfg1);
++    throttle_group_get_config(tgm3, &cfg2);
+     g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
+ 
+     cfg2.buckets[THROTTLE_BPS_READ].avg  = 4547;
+     cfg2.buckets[THROTTLE_BPS_WRITE].avg = 1349;
+     cfg2.buckets[THROTTLE_OPS_READ].avg  = 123;
+     cfg2.buckets[THROTTLE_OPS_WRITE].avg = 86;
+-    throttle_group_config(blk3, &cfg1);
++    throttle_group_config(tgm3, &cfg1);
+ 
+-    throttle_group_get_config(blk1, &cfg1);
+-    throttle_group_get_config(blk3, &cfg2);
++    throttle_group_get_config(tgm1, &cfg1);
++    throttle_group_get_config(tgm3, &cfg2);
+     g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
+ 
+-    throttle_group_unregister_blk(blk1);
+-    throttle_group_unregister_blk(blk2);
+-    throttle_group_unregister_blk(blk3);
++    throttle_group_unregister_tgm(tgm1);
++    throttle_group_unregister_tgm(tgm2);
++    throttle_group_unregister_tgm(tgm3);
+ 
+-    g_assert(blkp1->throttle_state == NULL);
+-    g_assert(blkp2->throttle_state == NULL);
+-    g_assert(blkp3->throttle_state == NULL);
++    g_assert(tgm1->throttle_state == NULL);
++    g_assert(tgm2->throttle_state == NULL);
++    g_assert(tgm3->throttle_state == NULL);
+ }
+ 
+ int main(int argc, char **argv)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-nbd-client-nbd_co_send_request-fix-return-code.patch b/SOURCES/kvm-block-nbd-client-nbd_co_send_request-fix-return-code.patch
new file mode 100644
index 0000000..43c3192
--- /dev/null
+++ b/SOURCES/kvm-block-nbd-client-nbd_co_send_request-fix-return-code.patch
@@ -0,0 +1,45 @@
+From 3f5ffd9dc9075dff3ab8052d5cfb0cdd2bfd1d7d Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Fri, 6 Oct 2017 19:24:09 +0200
+Subject: [PATCH 17/34] block/nbd-client: nbd_co_send_request: fix return code
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171006192409.29915-5-eblake@redhat.com>
+Patchwork-id: 76912
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 4/4] block/nbd-client: nbd_co_send_request: fix return code
+Bugzilla: 1482478
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+
+It's incorrect to return success rc >= 0 if we skip qio_channel_writev_all()
+call due to s->quit.
+
+Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20170920124507.18841-4-vsementsov@virtuozzo.com>
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit a693437037328a95d815ad5aec37ac2f8e130e58)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/nbd-client.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/block/nbd-client.c b/block/nbd-client.c
+index ea728ff..ed48fcf 100644
+--- a/block/nbd-client.c
++++ b/block/nbd-client.c
+@@ -161,6 +161,8 @@ static int nbd_co_send_request(BlockDriverState *bs,
+             if (ret != request->len) {
+                 rc = -EIO;
+             }
++        } else if (rc >= 0) {
++            rc = -EIO;
+         }
+         qio_channel_set_cork(s->ioc, false);
+     } else {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-rename-bdrv_co_drain-to-bdrv_co_drain_begin.patch b/SOURCES/kvm-block-rename-bdrv_co_drain-to-bdrv_co_drain_begin.patch
new file mode 100644
index 0000000..3c18713
--- /dev/null
+++ b/SOURCES/kvm-block-rename-bdrv_co_drain-to-bdrv_co_drain_begin.patch
@@ -0,0 +1,108 @@
+From 5185df6533f3e1f3c428e6d7b11a1fe372d0357b Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:06 +0100
+Subject: [PATCH 02/21] block: rename bdrv_co_drain to bdrv_co_drain_begin
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <ec3f5f7be56c7d67bb8e8230d5ef27824ea2bf1f.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78039
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 02/11] block: rename bdrv_co_drain to bdrv_co_drain_begin
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Manos Pitsidianakis <el13635@mail.ntua.gr>
+
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit f8ea8dacf0de636e2c0f13b90c0d75db97dc9b44)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/io.c                | 4 ++--
+ block/qed.c               | 6 +++---
+ include/block/block_int.h | 4 ++--
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/block/io.c b/block/io.c
+index 93fb802..3a717bc 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -162,7 +162,7 @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
+     BlockDriverState *bs = data->bs;
+ 
+     if (data->begin) {
+-        bs->drv->bdrv_co_drain(bs);
++        bs->drv->bdrv_co_drain_begin(bs);
+     } else {
+         bs->drv->bdrv_co_drain_end(bs);
+     }
+@@ -176,7 +176,7 @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
+ {
+     BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
+ 
+-    if (!bs->drv || (begin && !bs->drv->bdrv_co_drain) ||
++    if (!bs->drv || (begin && !bs->drv->bdrv_co_drain_begin) ||
+             (!begin && !bs->drv->bdrv_co_drain_end)) {
+         return;
+     }
+diff --git a/block/qed.c b/block/qed.c
+index dc54bf4..62d12db 100644
+--- a/block/qed.c
++++ b/block/qed.c
+@@ -265,7 +265,7 @@ static bool qed_plug_allocating_write_reqs(BDRVQEDState *s)
+     assert(!s->allocating_write_reqs_plugged);
+     if (s->allocating_acb != NULL) {
+         /* Another allocating write came concurrently.  This cannot happen
+-         * from bdrv_qed_co_drain, but it can happen when the timer runs.
++         * from bdrv_qed_co_drain_begin, but it can happen when the timer runs.
+          */
+         qemu_co_mutex_unlock(&s->table_lock);
+         return false;
+@@ -358,7 +358,7 @@ static void bdrv_qed_attach_aio_context(BlockDriverState *bs,
+     }
+ }
+ 
+-static void coroutine_fn bdrv_qed_co_drain(BlockDriverState *bs)
++static void coroutine_fn bdrv_qed_co_drain_begin(BlockDriverState *bs)
+ {
+     BDRVQEDState *s = bs->opaque;
+ 
+@@ -1608,7 +1608,7 @@ static BlockDriver bdrv_qed = {
+     .bdrv_check               = bdrv_qed_check,
+     .bdrv_detach_aio_context  = bdrv_qed_detach_aio_context,
+     .bdrv_attach_aio_context  = bdrv_qed_attach_aio_context,
+-    .bdrv_co_drain            = bdrv_qed_co_drain,
++    .bdrv_co_drain_begin      = bdrv_qed_co_drain_begin,
+ };
+ 
+ static void bdrv_qed_init(void)
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index 98d02ba..e02d540 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -320,7 +320,7 @@ struct BlockDriver {
+     int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
+ 
+     /**
+-     * bdrv_co_drain is called if implemented in the beginning of a
++     * bdrv_co_drain_begin is called if implemented in the beginning of a
+      * drain operation to drain and stop any internal sources of requests in
+      * the driver.
+      * bdrv_co_drain_end is called if implemented at the end of the drain.
+@@ -329,7 +329,7 @@ struct BlockDriver {
+      * requests, or toggle an internal state. After the end of the drain new
+      * requests will continue normally.
+      */
+-    void coroutine_fn (*bdrv_co_drain)(BlockDriverState *bs);
++    void coroutine_fn (*bdrv_co_drain_begin)(BlockDriverState *bs);
+     void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
+ 
+     void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-reopen-Queue-children-after-their-parents.patch b/SOURCES/kvm-block-reopen-Queue-children-after-their-parents.patch
new file mode 100644
index 0000000..2aecc46
--- /dev/null
+++ b/SOURCES/kvm-block-reopen-Queue-children-after-their-parents.patch
@@ -0,0 +1,76 @@
+From 32f7f67152cf7ffe36917a2c436eb89871dcee92 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:04 +0100
+Subject: [PATCH 33/36] block: reopen: Queue children after their parents
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-6-kwolf@redhat.com>
+Patchwork-id: 78107
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 5/8] block: reopen: Queue children after their parents
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+We will calculate the required new permissions in the prepare stage of a
+reopen. Required permissions of children can be influenced by the
+changes made to their parents, but parents are independent from their
+children. This means that permissions need to be calculated top-down. In
+order to achieve this, queue parents before their children rather than
+queuing the children first.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 1857c97b76af02537b954c86dab066503950a4fd)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/block.c b/block.c
+index 5cce274..0a7e2c6 100644
+--- a/block.c
++++ b/block.c
+@@ -2767,6 +2767,19 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
+         flags |= BDRV_O_ALLOW_RDWR;
+     }
+ 
++    if (!bs_entry) {
++        bs_entry = g_new0(BlockReopenQueueEntry, 1);
++        QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
++    } else {
++        QDECREF(bs_entry->state.options);
++        QDECREF(bs_entry->state.explicit_options);
++    }
++
++    bs_entry->state.bs = bs;
++    bs_entry->state.options = options;
++    bs_entry->state.explicit_options = explicit_options;
++    bs_entry->state.flags = flags;
++
+     QLIST_FOREACH(child, &bs->children, next) {
+         QDict *new_child_options;
+         char *child_key_dot;
+@@ -2786,19 +2799,6 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
+                                 child->role, options, flags);
+     }
+ 
+-    if (!bs_entry) {
+-        bs_entry = g_new0(BlockReopenQueueEntry, 1);
+-        QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
+-    } else {
+-        QDECREF(bs_entry->state.options);
+-        QDECREF(bs_entry->state.explicit_options);
+-    }
+-
+-    bs_entry->state.bs = bs;
+-    bs_entry->state.options = options;
+-    bs_entry->state.explicit_options = explicit_options;
+-    bs_entry->state.flags = flags;
+-
+     return bs_queue;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-throttle-groups.c-allocate-RestartData-on-the-.patch b/SOURCES/kvm-block-throttle-groups.c-allocate-RestartData-on-the-.patch
new file mode 100644
index 0000000..42bde0b
--- /dev/null
+++ b/SOURCES/kvm-block-throttle-groups.c-allocate-RestartData-on-the-.patch
@@ -0,0 +1,65 @@
+From 6ce7177922a538b653910bde85d4f03fe2a299d7 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Wed, 3 Jan 2018 11:30:21 +0100
+Subject: [PATCH 8/9] block/throttle-groups.c: allocate RestartData on the heap
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20180103113021.6954-2-stefanha@redhat.com>
+Patchwork-id: 78510
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] block/throttle-groups.c: allocate RestartData on the heap
+Bugzilla: 1525868
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+From: Manos Pitsidianakis <el13635@mail.ntua.gr>
+
+RestartData is the opaque data of the throttle_group_restart_queue_entry
+coroutine. By being stack allocated, it isn't available anymore if
+aio_co_enter schedules the coroutine with a bottom half and runs after
+throttle_group_restart_queue returns.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 43a5dc02fd6070827d5c4ff652b885219fa8cbe1)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/throttle-groups.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index 35c22ac..e6ba336 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -387,17 +387,19 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
+         schedule_next_request(tgm, is_write);
+         qemu_mutex_unlock(&tg->lock);
+     }
++
++    g_free(data);
+ }
+ 
+ static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write)
+ {
+     Coroutine *co;
+-    RestartData rd = {
+-        .tgm = tgm,
+-        .is_write = is_write
+-    };
++    RestartData *rd = g_new0(RestartData, 1);
++
++    rd->tgm = tgm;
++    rd->is_write = is_write;
+ 
+-    co = qemu_coroutine_create(throttle_group_restart_queue_entry, &rd);
++    co = qemu_coroutine_create(throttle_group_restart_queue_entry, rd);
+     aio_co_enter(tgm->aio_context, co);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-tidy-ThrottleGroupMember-initializations.patch b/SOURCES/kvm-block-tidy-ThrottleGroupMember-initializations.patch
new file mode 100644
index 0000000..2ac2588
--- /dev/null
+++ b/SOURCES/kvm-block-tidy-ThrottleGroupMember-initializations.patch
@@ -0,0 +1,63 @@
+From 339d01accebcd27e23600e709ef426cdb794cf2e Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:02 +0100
+Subject: [PATCH 03/15] block: tidy ThrottleGroupMember initializations
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-4-stefanha@redhat.com>
+Patchwork-id: 77739
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/9] block: tidy ThrottleGroupMember initializations
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Manos Pitsidianakis <el13635@mail.ntua.gr>
+
+Move the CoMutex and CoQueue inits inside throttle_group_register_tgm()
+which is called whenever a ThrottleGroupMember is initialized. There's
+no need for them to be separate.
+
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit f738cfc843055238ad969782db69156929873832)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c   | 3 ---
+ block/throttle-groups.c | 3 +++
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 515be10..6826476 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -273,9 +273,6 @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
+     blk->shared_perm = shared_perm;
+     blk_set_enable_write_cache(blk, true);
+ 
+-    qemu_co_mutex_init(&blk->public.throttle_group_member.throttled_reqs_lock);
+-    qemu_co_queue_init(&blk->public.throttle_group_member.throttled_reqs[0]);
+-    qemu_co_queue_init(&blk->public.throttle_group_member.throttled_reqs[1]);
+     block_acct_init(&blk->stats);
+ 
+     notifier_list_init(&blk->remove_bs_notifiers);
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index 3b07b25..7749cf0 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -508,6 +508,9 @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+                          read_timer_cb,
+                          write_timer_cb,
+                          tgm);
++    qemu_co_mutex_init(&tgm->throttled_reqs_lock);
++    qemu_co_queue_init(&tgm->throttled_reqs[0]);
++    qemu_co_queue_init(&tgm->throttled_reqs[1]);
+ 
+     qemu_mutex_unlock(&tg->lock);
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-use-1-MB-bounce-buffers-for-crypto-instead-of-.patch b/SOURCES/kvm-block-use-1-MB-bounce-buffers-for-crypto-instead-of-.patch
new file mode 100644
index 0000000..81de0ac
--- /dev/null
+++ b/SOURCES/kvm-block-use-1-MB-bounce-buffers-for-crypto-instead-of-.patch
@@ -0,0 +1,113 @@
+From 16e6d181f5e881082a42dbae18c8f002fbbe689a Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Fri, 1 Dec 2017 10:44:46 +0100
+Subject: [PATCH 10/36] block: use 1 MB bounce buffers for crypto instead of
+ 16KB
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171201104446.7973-1-berrange@redhat.com>
+Patchwork-id: 78063
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH] block: use 1 MB bounce buffers for crypto instead of 16KB
+Bugzilla: 1500334
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+Using 16KB bounce buffers creates a significant performance
+penalty for I/O to encrypted volumes on storage which high
+I/O latency (rotating rust & network drives), because it
+triggers lots of fairly small I/O operations.
+
+On tests with rotating rust, and cache=none|directsync,
+write speed increased from 2MiB/s to 32MiB/s, on a par
+with that achieved by the in-kernel luks driver. With
+other cache modes the in-kernel driver is still notably
+faster because it is able to report completion of the
+I/O request before any encryption is done, while the
+in-QEMU driver must encrypt the data before completion.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Message-id: 20170927125340.12360-2-berrange@redhat.com
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 161253e2d0a83a1b33bca019c6e926013e1a03db)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/crypto.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/block/crypto.c b/block/crypto.c
+index 58ef6f2..684cabe 100644
+--- a/block/crypto.c
++++ b/block/crypto.c
+@@ -379,7 +379,11 @@ static void block_crypto_close(BlockDriverState *bs)
+ }
+ 
+ 
+-#define BLOCK_CRYPTO_MAX_SECTORS 32
++/*
++ * 1 MB bounce buffer gives good performance / memory tradeoff
++ * when using cache=none|directsync.
++ */
++#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
+ 
+ static coroutine_fn int
+ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
+@@ -396,12 +400,11 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
+ 
+     qemu_iovec_init(&hd_qiov, qiov->niov);
+ 
+-    /* Bounce buffer so we have a linear mem region for
+-     * entire sector. XXX optimize so we avoid bounce
+-     * buffer in case that qiov->niov == 1
++    /* Bounce buffer because we don't wish to expose cipher text
++     * in qiov which points to guest memory.
+      */
+     cipher_data =
+-        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 512,
++        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
+                                               qiov->size));
+     if (cipher_data == NULL) {
+         ret = -ENOMEM;
+@@ -411,8 +414,8 @@ block_crypto_co_readv(BlockDriverState *bs, int64_t sector_num,
+     while (remaining_sectors) {
+         cur_nr_sectors = remaining_sectors;
+ 
+-        if (cur_nr_sectors > BLOCK_CRYPTO_MAX_SECTORS) {
+-            cur_nr_sectors = BLOCK_CRYPTO_MAX_SECTORS;
++        if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
++            cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
+         }
+ 
+         qemu_iovec_reset(&hd_qiov);
+@@ -464,12 +467,11 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
+ 
+     qemu_iovec_init(&hd_qiov, qiov->niov);
+ 
+-    /* Bounce buffer so we have a linear mem region for
+-     * entire sector. XXX optimize so we avoid bounce
+-     * buffer in case that qiov->niov == 1
++    /* Bounce buffer because we're not permitted to touch
++     * contents of qiov - it points to guest memory.
+      */
+     cipher_data =
+-        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_SECTORS * 512,
++        qemu_try_blockalign(bs->file->bs, MIN(BLOCK_CRYPTO_MAX_IO_SIZE,
+                                               qiov->size));
+     if (cipher_data == NULL) {
+         ret = -ENOMEM;
+@@ -479,8 +481,8 @@ block_crypto_co_writev(BlockDriverState *bs, int64_t sector_num,
+     while (remaining_sectors) {
+         cur_nr_sectors = remaining_sectors;
+ 
+-        if (cur_nr_sectors > BLOCK_CRYPTO_MAX_SECTORS) {
+-            cur_nr_sectors = BLOCK_CRYPTO_MAX_SECTORS;
++        if (cur_nr_sectors > (BLOCK_CRYPTO_MAX_IO_SIZE / 512)) {
++            cur_nr_sectors = (BLOCK_CRYPTO_MAX_IO_SIZE / 512);
+         }
+ 
+         qemu_iovec_to_buf(qiov, bytes_done,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-vxhs-improve-error-message-for-missing-bad-vxh.patch b/SOURCES/kvm-block-vxhs-improve-error-message-for-missing-bad-vxh.patch
new file mode 100644
index 0000000..d7e2e1a
--- /dev/null
+++ b/SOURCES/kvm-block-vxhs-improve-error-message-for-missing-bad-vxh.patch
@@ -0,0 +1,63 @@
+From 23c1a34ecd6ca7f986ffff7a04deeb3eab0948c9 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Mon, 11 Dec 2017 22:38:12 +0100
+Subject: [PATCH 2/6] block/vxhs: improve error message for missing / bad vxhs
+ module
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <59af10d83125fff42beacd30dbca83d50409bbed.1513031708.git.jcody@redhat.com>
+Patchwork-id: 78305
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] block/vxhs: improve error message for missing / bad vxhs module
+Bugzilla: 1505654
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+[Downstream only, as the module load of libvxhs is downstream only]
+
+In the case of missing libvxhs libraries, the original error message,
+while technically accurate, may lead a user to think there is a QEMU bug
+if trying to using the VXHS protocol.  Update the message so that it is
+clear that the likely issue is that the Veritas QEMU libvxhs RPM is not
+installed (or not installed correctly, if there are permission or file
+corruption issues, etc.).
+
+An example error message before this change:
+
+> qemu-img info vxhs://localhost/test
+qemu-img: Could not open 'vxhs://localhost/test': \
+        error loading libvxhs: /usr/lib64/qemu/libvxhs.so.1: \
+        cannot open shared object file: No such file or directory
+
+An example error message after this change:
+
+> qemu-img info vxhs://localhost/test
+qemu-img: Could not open 'vxhs://localhost/test': \
+        The VXHS library from Veritas might not be installed correctly \
+        (/usr/lib64/qemu/libvxhs.so.1: \
+         cannot open shared object file: No such file or directory)
+
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/vxhs.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block/vxhs.c b/block/vxhs.c
+index a18154c..68edb51 100644
+--- a/block/vxhs.c
++++ b/block/vxhs.c
+@@ -115,7 +115,8 @@ static void bdrv_vxhs_load_libs(Error **errp)
+     libvxhs_handle = g_module_open(LIBVXHS_FULL_PATHNAME,
+                                    G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+     if (!libvxhs_handle) {
+-        error_setg(errp, "error loading libvxhs: %s", g_module_error());
++        error_setg(errp, "The VXHS library from Veritas might not be installed "
++                   "correctly (%s)", g_module_error());
+         return;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockdev-Report-proper-error-class-in-__com.redhat.d.patch b/SOURCES/kvm-blockdev-Report-proper-error-class-in-__com.redhat.d.patch
new file mode 100644
index 0000000..02b5b83
--- /dev/null
+++ b/SOURCES/kvm-blockdev-Report-proper-error-class-in-__com.redhat.d.patch
@@ -0,0 +1,50 @@
+From bacc2236309db4099bbbfe7125efaa7ad83739d8 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Fri, 1 Dec 2017 03:12:21 +0100
+Subject: [PATCH 09/36] blockdev: Report proper error class in
+ __com.redhat.drive_del
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171201031221.26738-1-eblake@redhat.com>
+Patchwork-id: 78060
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH] blockdev: Report proper error class in __com.redhat.drive_del
+Bugzilla: 1487515
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+From: Eric Blake <eblake@redhat.com
+
+Libvirt expects 'DeviceNotFound' to suppress the error message rather
+than the generic error.  If the wrong error class is used, the libvirt
+spams /var/log/messages with a spurious message during hot-unplug:
+
+  Aug 30 20:03:32 rhosp8-test libvirtd: 2017-08-30 11:03:32.354+0000: 2562: error : qemuMonitorJSONCheckError:389 : internal error: unable to execute QEMU command '__com.redhat_drive_del': Device 'drive-virtio-disk1' not found
+
+Fixes: 60b62c9d
+
+Diagnosis of the issue performed by Peter Krempa.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 0f063ec..6a37934 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -2909,7 +2909,8 @@ void qmp___com_redhat_drive_del(const char *id, Error **errp)
+ 
+     blk = blk_by_name(id);
+     if (!blk) {
+-        error_setg(errp, "Device '%s' not found", id);
++        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
++                  "Device '%s' not found", id);
+         return;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockdev-add-x-blockdev-set-iothread-force-boolean.patch b/SOURCES/kvm-blockdev-add-x-blockdev-set-iothread-force-boolean.patch
new file mode 100644
index 0000000..4d6ba25
--- /dev/null
+++ b/SOURCES/kvm-blockdev-add-x-blockdev-set-iothread-force-boolean.patch
@@ -0,0 +1,87 @@
+From 322e74b00634817abd82f66d8c98effc07d532a8 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:57 +0100
+Subject: [PATCH 39/42] blockdev: add x-blockdev-set-iothread force boolean
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-18-stefanha@redhat.com>
+Patchwork-id: 78495
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 17/20] blockdev: add x-blockdev-set-iothread force boolean
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+When a node is already associated with a BlockBackend the
+x-blockdev-set-iothread command refuses to set the IOThread.  This is to
+prevent accidentally changing the IOThread when the nodes are in use.
+
+When the nodes are created with -drive they automatically get a
+BlockBackend.  In that case we know nothing is using them yet and it's
+safe to set the IOThread.  Add a force boolean to override the check.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171207201320.19284-4-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 882e9b89af7c1086d97cee11b2437337e756fa00)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c           | 11 ++++++-----
+ qapi/block-core.json |  6 +++++-
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 6cbe627..17e2cf1 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -4192,7 +4192,7 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
+ }
+ 
+ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
+-                                 Error **errp)
++                                 bool has_force, bool force, Error **errp)
+ {
+     AioContext *old_context;
+     AioContext *new_context;
+@@ -4204,10 +4204,11 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
+         return;
+     }
+ 
+-    /* If we want to allow more extreme test scenarios this guard could be
+-     * removed.  For now it protects against accidents. */
+-    if (bdrv_has_blk(bs)) {
+-        error_setg(errp, "Node %s is in use", node_name);
++    /* Protects against accidents. */
++    if (!(has_force && force) && bdrv_has_blk(bs)) {
++        error_setg(errp, "Node %s is associated with a BlockBackend and could "
++                         "be in use (use force=true to override this check)",
++                         node_name);
+         return;
+     }
+ 
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index d579c99..305f7ff 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -3895,6 +3895,9 @@
+ #
+ # @iothread: the name of the IOThread object or null for the main loop
+ #
++# @force: true if the node and its children should be moved when a BlockBackend
++#         is already attached
++#
+ # Note: this command is experimental and intended for test cases that need
+ # control over IOThreads only.
+ #
+@@ -3917,4 +3920,5 @@
+ ##
+ { 'command': 'x-blockdev-set-iothread',
+   'data' : { 'node-name': 'str',
+-             'iothread': 'StrOrNull' } }
++             'iothread': 'StrOrNull',
++             '*force': 'bool' } }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockdev-add-x-blockdev-set-iothread-testing-command.patch b/SOURCES/kvm-blockdev-add-x-blockdev-set-iothread-testing-command.patch
new file mode 100644
index 0000000..ab65da4
--- /dev/null
+++ b/SOURCES/kvm-blockdev-add-x-blockdev-set-iothread-testing-command.patch
@@ -0,0 +1,143 @@
+From 0ee9b6146fd9b451c21f3428fb363d5e659693b7 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:55 +0100
+Subject: [PATCH 37/42] blockdev: add x-blockdev-set-iothread testing command
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-16-stefanha@redhat.com>
+Patchwork-id: 78494
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 15/20] blockdev: add x-blockdev-set-iothread testing command
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Currently there is no easy way for iotests to ensure that a BDS is bound
+to a particular IOThread.  Normally the virtio-blk device calls
+blk_set_aio_context() when dataplane is enabled during guest driver
+initialization.  This never happens in iotests since -machine
+accel=qtest means there is no guest activity (including device driver
+initialization).
+
+This patch adds a QMP command to explicitly assign IOThreads in test
+cases.  See qapi/block-core.json for a description of the command.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-9-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit ca00bbb153d03c5338d8c8136812163f463f841e)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c           | 41 +++++++++++++++++++++++++++++++++++++++++
+ qapi/block-core.json | 36 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 77 insertions(+)
+
+diff --git a/blockdev.c b/blockdev.c
+index f118444..6cbe627 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -46,6 +46,7 @@
+ #include "qapi/qobject-output-visitor.h"
+ #include "qapi/util.h"
+ #include "sysemu/sysemu.h"
++#include "sysemu/iothread.h"
+ #include "block/block_int.h"
+ #include "qmp-commands.h"
+ #include "block/trace.h"
+@@ -4190,6 +4191,46 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
+     return head;
+ }
+ 
++void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
++                                 Error **errp)
++{
++    AioContext *old_context;
++    AioContext *new_context;
++    BlockDriverState *bs;
++
++    bs = bdrv_find_node(node_name);
++    if (!bs) {
++        error_setg(errp, "Cannot find node %s", node_name);
++        return;
++    }
++
++    /* If we want to allow more extreme test scenarios this guard could be
++     * removed.  For now it protects against accidents. */
++    if (bdrv_has_blk(bs)) {
++        error_setg(errp, "Node %s is in use", node_name);
++        return;
++    }
++
++    if (iothread->type == QTYPE_QSTRING) {
++        IOThread *obj = iothread_by_id(iothread->u.s);
++        if (!obj) {
++            error_setg(errp, "Cannot find iothread %s", iothread->u.s);
++            return;
++        }
++
++        new_context = iothread_get_aio_context(obj);
++    } else {
++        new_context = qemu_get_aio_context();
++    }
++
++    old_context = bdrv_get_aio_context(bs);
++    aio_context_acquire(old_context);
++
++    bdrv_set_aio_context(bs, new_context);
++
++    aio_context_release(old_context);
++}
++
+ QemuOptsList qemu_common_drive_opts = {
+     .name = "drive",
+     .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index 15fc08f..d579c99 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -3882,3 +3882,39 @@
+   'data' : { 'parent': 'str',
+              '*child': 'str',
+              '*node': 'str' } }
++
++##
++# @x-blockdev-set-iothread:
++#
++# Move @node and its children into the @iothread.  If @iothread is null then
++# move @node and its children into the main loop.
++#
++# The node must not be attached to a BlockBackend.
++#
++# @node-name: the name of the block driver node
++#
++# @iothread: the name of the IOThread object or null for the main loop
++#
++# Note: this command is experimental and intended for test cases that need
++# control over IOThreads only.
++#
++# Since: 2.12
++#
++# Example:
++#
++# 1. Move a node into an IOThread
++# -> { "execute": "x-blockdev-set-iothread",
++#      "arguments": { "node-name": "disk1",
++#                     "iothread": "iothread0" } }
++# <- { "return": {} }
++#
++# 2. Move a node into the main loop
++# -> { "execute": "x-blockdev-set-iothread",
++#      "arguments": { "node-name": "disk1",
++#                     "iothread": null } }
++# <- { "return": {} }
++#
++##
++{ 'command': 'x-blockdev-set-iothread',
++  'data' : { 'node-name': 'str',
++             'iothread': 'StrOrNull' } }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockdev-hold-AioContext-for-bdrv_unref-in-external_.patch b/SOURCES/kvm-blockdev-hold-AioContext-for-bdrv_unref-in-external_.patch
new file mode 100644
index 0000000..9f8b68b
--- /dev/null
+++ b/SOURCES/kvm-blockdev-hold-AioContext-for-bdrv_unref-in-external_.patch
@@ -0,0 +1,63 @@
+From 96ba2c5dcbe1bed81311a8a150712a3bb25b9296 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:49 +0100
+Subject: [PATCH 31/42] blockdev: hold AioContext for bdrv_unref() in
+ external_snapshot_clean()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-10-stefanha@redhat.com>
+Patchwork-id: 78490
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 09/20] blockdev: hold AioContext for bdrv_unref() in external_snapshot_clean()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+bdrv_unref() requires the AioContext lock because bdrv_flush() uses
+BDRV_POLL_WHILE(), which assumes the AioContext is currently held.  If
+BDRV_POLL_WHILE() runs without AioContext held the
+pthread_mutex_unlock() call in aio_context_release() fails.
+
+This patch moves bdrv_unref() into the AioContext locked region to solve
+the following pthread_mutex_unlock() failure:
+
+  #0  0x00007f566181969b in raise () at /lib64/libc.so.6
+  #1  0x00007f566181b3b1 in abort () at /lib64/libc.so.6
+  #2  0x00005592cd590458 in error_exit (err=<optimized out>, msg=msg@entry=0x5592cdaf6d60 <__func__.23977> "qemu_mutex_unlock") at util/qemu-thread-posix.c:36
+  #3  0x00005592cd96e738 in qemu_mutex_unlock (mutex=mutex@entry=0x5592ce9505e0) at util/qemu-thread-posix.c:96
+  #4  0x00005592cd969b69 in aio_context_release (ctx=ctx@entry=0x5592ce950580) at util/async.c:507
+  #5  0x00005592cd8ead78 in bdrv_flush (bs=bs@entry=0x5592cfa87210) at block/io.c:2478
+  #6  0x00005592cd89df30 in bdrv_close (bs=0x5592cfa87210) at block.c:3207
+  #7  0x00005592cd89df30 in bdrv_delete (bs=0x5592cfa87210) at block.c:3395
+  #8  0x00005592cd89df30 in bdrv_unref (bs=0x5592cfa87210) at block.c:4418
+  #9  0x00005592cd6b7f86 in qmp_transaction (dev_list=<optimized out>, has_props=<optimized out>, props=<optimized out>, errp=errp@entry=0x7ffe4a1fc9d8) at blockdev.c:2308
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-2-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit b9464ba19f821ea6b29969104dc48dcdb26243dd)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockdev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 6a37934..c6978a5 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1855,8 +1855,8 @@ static void external_snapshot_clean(BlkActionState *common)
+                              DO_UPCAST(ExternalSnapshotState, common, common);
+     if (state->aio_context) {
+         bdrv_drained_end(state->old_bs);
+-        aio_context_release(state->aio_context);
+         bdrv_unref(state->new_bs);
++        aio_context_release(state->aio_context);
+     }
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockjob-Make-block_job_pause_all-keep-a-reference-t.patch b/SOURCES/kvm-blockjob-Make-block_job_pause_all-keep-a-reference-t.patch
new file mode 100644
index 0000000..a3c9055
--- /dev/null
+++ b/SOURCES/kvm-blockjob-Make-block_job_pause_all-keep-a-reference-t.patch
@@ -0,0 +1,90 @@
+From 03560a7d6e57ca2ba3198d5051acfdd1e345f9a4 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Tue, 5 Dec 2017 16:03:17 +0100
+Subject: [PATCH 12/21] blockjob: Make block_job_pause_all() keep a reference
+ to the jobs
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <e6cd1cf608e4720141f9e3b0d62a5a9721203325.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78161
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 12/11] blockjob: Make block_job_pause_all() keep a reference to the jobs
+Bugzilla: 1506531
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Alberto Garcia <berto@igalia.com>
+
+Starting from commit 40840e419be31e6a32e6ea24511c74b389d5e0e4 we are
+pausing all block jobs during bdrv_reopen_multiple() to prevent any of
+them from finishing and removing nodes from the graph while they are
+being reopened.
+
+It turns out that pausing a block job doesn't necessarily prevent it
+from finishing: a paused block job can still run its exit function
+from the main loop and call block_job_completed(). The mirror block
+job in particular always goes to the main loop while it is paused (by
+virtue of the bdrv_drained_begin() call in mirror_run()).
+
+Destroying a paused block job during bdrv_reopen_multiple() has two
+consequences:
+
+   1) The references to the nodes involved in the job are released,
+      possibly destroying some of them. If those nodes were in the
+      reopen queue this would trigger the problem originally described
+      in commit 40840e419be, crashing QEMU.
+
+   2) At the end of bdrv_reopen_multiple(), bdrv_drain_all_end() would
+      not be doing all necessary bdrv_parent_drained_end() calls.
+
+I can reproduce problem 1) easily with iotest 030 by increasing
+STREAM_BUFFER_SIZE from 512KB to 8MB in block/stream.c, or by tweaking
+the iotest like in this example:
+
+   https://lists.gnu.org/archive/html/qemu-block/2017-11/msg00934.html
+
+This patch keeps an additional reference to all block jobs between
+block_job_pause_all() and block_job_resume_all(), guaranteeing that
+they are kept alive.
+
+Signed-off-by: Alberto Garcia <berto@igalia.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 3d5d319e1221082974711af1d09d82f0755c1698)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockjob.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/blockjob.c b/blockjob.c
+index 84f526a..63aecce 100644
+--- a/blockjob.c
++++ b/blockjob.c
+@@ -730,6 +730,7 @@ void block_job_pause_all(void)
+         AioContext *aio_context = blk_get_aio_context(job->blk);
+ 
+         aio_context_acquire(aio_context);
++        block_job_ref(job);
+         block_job_pause(job);
+         aio_context_release(aio_context);
+     }
+@@ -808,12 +809,14 @@ void coroutine_fn block_job_pause_point(BlockJob *job)
+ 
+ void block_job_resume_all(void)
+ {
+-    BlockJob *job = NULL;
+-    while ((job = block_job_next(job))) {
++    BlockJob *job, *next;
++
++    QLIST_FOREACH_SAFE(job, &block_jobs, job_list, next) {
+         AioContext *aio_context = blk_get_aio_context(job->blk);
+ 
+         aio_context_acquire(aio_context);
+         block_job_resume(job);
++        block_job_unref(job);
+         aio_context_release(aio_context);
+     }
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockjob-Remove-the-job-from-the-list-earlier-in-blo.patch b/SOURCES/kvm-blockjob-Remove-the-job-from-the-list-earlier-in-blo.patch
new file mode 100644
index 0000000..52181fe
--- /dev/null
+++ b/SOURCES/kvm-blockjob-Remove-the-job-from-the-list-earlier-in-blo.patch
@@ -0,0 +1,57 @@
+From f64ca42ce16a0df89d4abba838d00ea7bc7e4da9 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:11 +0100
+Subject: [PATCH 07/21] blockjob: Remove the job from the list earlier in
+ block_job_unref()
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <8fc0c61d51c41fdde7d809502e5025371f89c4c7.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78045
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 07/11] blockjob: Remove the job from the list earlier in block_job_unref()
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Alberto Garcia <berto@igalia.com>
+
+When destroying a block job in block_job_unref() we should remove it
+from the job list before calling block_job_remove_all_bdrv().
+
+This is because removing the BDSs can trigger an aio_poll() and wake
+up other jobs that might attempt to use the block job list. If that
+happens the job we're currently destroying should not be in that list
+anymore.
+
+Signed-off-by: Alberto Garcia <berto@igalia.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 0a3e155f3f5ec9b6f12d00894c7701b3cbb66590)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockjob.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/blockjob.c b/blockjob.c
+index c3cf9a2..2509bba 100644
+--- a/blockjob.c
++++ b/blockjob.c
+@@ -152,6 +152,7 @@ void block_job_unref(BlockJob *job)
+ {
+     if (--job->refcnt == 0) {
+         BlockDriverState *bs = blk_bs(job->blk);
++        QLIST_REMOVE(job, job_list);
+         bs->job = NULL;
+         block_job_remove_all_bdrv(job);
+         blk_remove_aio_context_notifier(job->blk,
+@@ -160,7 +161,6 @@ void block_job_unref(BlockJob *job)
+         blk_unref(job->blk);
+         error_free(job->blocker);
+         g_free(job->id);
+-        QLIST_REMOVE(job, job_list);
+         g_free(job);
+     }
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockjob-do-not-allow-coroutine-double-entry-or-entr.patch b/SOURCES/kvm-blockjob-do-not-allow-coroutine-double-entry-or-entr.patch
new file mode 100644
index 0000000..dc9b7c8
--- /dev/null
+++ b/SOURCES/kvm-blockjob-do-not-allow-coroutine-double-entry-or-entr.patch
@@ -0,0 +1,81 @@
+From 01dd04dfd1421d041da935e7a22987d0883b4353 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:07 +0100
+Subject: [PATCH 03/21] blockjob: do not allow coroutine double entry or
+ entry-after-completion
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <36a71db70d56ebdb223c760e682a146ad91d97ad.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78041
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 03/11] blockjob: do not allow coroutine double entry or entry-after-completion
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+When block_job_sleep_ns() is called, the co-routine is scheduled for
+future execution.  If we allow the job to be re-entered prior to the
+scheduled time, we present a race condition in which a coroutine can be
+entered recursively, or even entered after the coroutine is deleted.
+
+The job->busy flag is used by blockjobs when a coroutine is busy
+executing. The function 'block_job_enter()' obeys the busy flag,
+and will not enter a coroutine if set.  If we sleep a job, we need to
+leave the busy flag set, so that subsequent calls to block_job_enter()
+are prevented.
+
+This changes the prior behavior of block_job_cancel() being able to
+immediately wake up and cancel a job; in practice, this should not be an
+issue, as the coroutine sleep times are generally very small, and the
+cancel will occur the next time the coroutine wakes up.
+
+This fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1508708
+
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 4afeffc8572f40d8844b946a30c00b10da4442b1)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockjob.c                   | 7 +++++--
+ include/block/blockjob_int.h | 3 ++-
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/blockjob.c b/blockjob.c
+index 70a7818..c3cf9a2 100644
+--- a/blockjob.c
++++ b/blockjob.c
+@@ -797,11 +797,14 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
+         return;
+     }
+ 
+-    job->busy = false;
++    /* We need to leave job->busy set here, because when we have
++     * put a coroutine to 'sleep', we have scheduled it to run in
++     * the future.  We cannot enter that same coroutine again before
++     * it wakes and runs, otherwise we risk double-entry or entry after
++     * completion. */
+     if (!block_job_should_pause(job)) {
+         co_aio_sleep_ns(blk_get_aio_context(job->blk), type, ns);
+     }
+-    job->busy = true;
+ 
+     block_job_pause_point(job);
+ }
+diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
+index f13ad05..43f3be2 100644
+--- a/include/block/blockjob_int.h
++++ b/include/block/blockjob_int.h
+@@ -143,7 +143,8 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+  * @ns: How many nanoseconds to stop for.
+  *
+  * Put the job to sleep (assuming that it wasn't canceled) for @ns
+- * nanoseconds.  Canceling the job will interrupt the wait immediately.
++ * nanoseconds.  Canceling the job will not interrupt the wait, so the
++ * cancel will not process until the coroutine wakes up.
+  */
+ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockjob-introduce-block_job_do_yield.patch b/SOURCES/kvm-blockjob-introduce-block_job_do_yield.patch
new file mode 100644
index 0000000..f9b7b1e
--- /dev/null
+++ b/SOURCES/kvm-blockjob-introduce-block_job_do_yield.patch
@@ -0,0 +1,95 @@
+From dace2b99ec7489bdabb4beeb429ec44427805d90 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:14 +0100
+Subject: [PATCH 10/21] blockjob: introduce block_job_do_yield
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <331a28f9c09b1ce40dd95f7b21ded200ab46713d.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78046
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 10/11] blockjob: introduce block_job_do_yield
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+Hide the clearing of job->busy in a single function, and set it
+in block_job_enter.  This lets block_job_do_yield verify that
+qemu_coroutine_enter is not used while job->busy = false.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Tested-By: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 356f59b8757f47c0aca3e2e4e51d6010f64cade1)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockjob.c | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/blockjob.c b/blockjob.c
+index 4d78046..e960b3e 100644
+--- a/blockjob.c
++++ b/blockjob.c
+@@ -729,6 +729,15 @@ static bool block_job_should_pause(BlockJob *job)
+     return job->pause_count > 0;
+ }
+ 
++static void block_job_do_yield(BlockJob *job)
++{
++    job->busy = false;
++    qemu_coroutine_yield();
++
++    /* Set by block_job_enter before re-entering the coroutine.  */
++    assert(job->busy);
++}
++
+ void coroutine_fn block_job_pause_point(BlockJob *job)
+ {
+     assert(job && block_job_started(job));
+@@ -746,9 +755,7 @@ void coroutine_fn block_job_pause_point(BlockJob *job)
+ 
+     if (block_job_should_pause(job) && !block_job_is_cancelled(job)) {
+         job->paused = true;
+-        job->busy = false;
+-        qemu_coroutine_yield(); /* wait for block_job_resume() */
+-        job->busy = true;
++        block_job_do_yield(job);
+         job->paused = false;
+     }
+ 
+@@ -778,9 +785,12 @@ void block_job_enter(BlockJob *job)
+         return;
+     }
+ 
+-    if (!job->busy) {
+-        bdrv_coroutine_enter(blk_bs(job->blk), job->co);
++    if (job->busy) {
++        return;
+     }
++
++    job->busy = true;
++    aio_co_wake(job->co);
+ }
+ 
+ bool block_job_is_cancelled(BlockJob *job)
+@@ -819,11 +829,9 @@ void block_job_yield(BlockJob *job)
+         return;
+     }
+ 
+-    job->busy = false;
+     if (!block_job_should_pause(job)) {
+-        qemu_coroutine_yield();
++        block_job_do_yield(job);
+     }
+-    job->busy = true;
+ 
+     block_job_pause_point(job);
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockjob-reimplement-block_job_sleep_ns-to-allow-can.patch b/SOURCES/kvm-blockjob-reimplement-block_job_sleep_ns-to-allow-can.patch
new file mode 100644
index 0000000..acddfff
--- /dev/null
+++ b/SOURCES/kvm-blockjob-reimplement-block_job_sleep_ns-to-allow-can.patch
@@ -0,0 +1,230 @@
+From b3526a8557aac40fa4f4520518a1193cc92598e6 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:15 +0100
+Subject: [PATCH 11/21] blockjob: reimplement block_job_sleep_ns to allow
+ cancellation
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <51b0c9ece9db7a164c4e7ccc90a7d51f786ceaa2.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78049
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 11/11] blockjob: reimplement block_job_sleep_ns to allow cancellation
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+This reverts the effects of commit 4afeffc857 ("blockjob: do not allow
+coroutine double entry or entry-after-completion", 2017-11-21)
+
+This fixed the symptom of a bug rather than the root cause. Canceling the
+wait on a sleeping blockjob coroutine is generally fine, we just need to
+make it work correctly across AioContexts.  To do so, use a QEMUTimer
+that calls block_job_enter.  Use a mutex to ensure that block_job_enter
+synchronizes correctly with block_job_sleep_ns.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Tested-By: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit fc24908e7d232b79c2a6f0363f52bda18dedb57b)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ blockjob.c                   | 63 ++++++++++++++++++++++++++++++++++++--------
+ include/block/blockjob.h     |  8 +++++-
+ include/block/blockjob_int.h |  4 +--
+ 3 files changed, 61 insertions(+), 14 deletions(-)
+
+diff --git a/blockjob.c b/blockjob.c
+index e960b3e..84f526a 100644
+--- a/blockjob.c
++++ b/blockjob.c
+@@ -37,6 +37,26 @@
+ #include "qemu/timer.h"
+ #include "qapi-event.h"
+ 
++/* Right now, this mutex is only needed to synchronize accesses to job->busy
++ * and job->sleep_timer, such as concurrent calls to block_job_do_yield and
++ * block_job_enter. */
++static QemuMutex block_job_mutex;
++
++static void block_job_lock(void)
++{
++    qemu_mutex_lock(&block_job_mutex);
++}
++
++static void block_job_unlock(void)
++{
++    qemu_mutex_unlock(&block_job_mutex);
++}
++
++static void __attribute__((__constructor__)) block_job_init(void)
++{
++    qemu_mutex_init(&block_job_mutex);
++}
++
+ static void block_job_event_cancelled(BlockJob *job);
+ static void block_job_event_completed(BlockJob *job, const char *msg);
+ 
+@@ -161,6 +181,7 @@ void block_job_unref(BlockJob *job)
+         blk_unref(job->blk);
+         error_free(job->blocker);
+         g_free(job->id);
++        assert(!timer_pending(&job->sleep_timer));
+         g_free(job);
+     }
+ }
+@@ -287,6 +308,13 @@ static void coroutine_fn block_job_co_entry(void *opaque)
+     job->driver->start(job);
+ }
+ 
++static void block_job_sleep_timer_cb(void *opaque)
++{
++    BlockJob *job = opaque;
++
++    block_job_enter(job);
++}
++
+ void block_job_start(BlockJob *job)
+ {
+     assert(job && !block_job_started(job) && job->paused &&
+@@ -556,7 +584,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
+     info->type      = g_strdup(BlockJobType_lookup[job->driver->job_type]);
+     info->device    = g_strdup(job->id);
+     info->len       = job->len;
+-    info->busy      = job->busy;
++    info->busy      = atomic_read(&job->busy);
+     info->paused    = job->pause_count > 0;
+     info->offset    = job->offset;
+     info->speed     = job->speed;
+@@ -664,6 +692,9 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+     job->paused        = true;
+     job->pause_count   = 1;
+     job->refcnt        = 1;
++    aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
++                   QEMU_CLOCK_REALTIME, SCALE_NS,
++                   block_job_sleep_timer_cb, job);
+ 
+     error_setg(&job->blocker, "block device is in use by block job: %s",
+                BlockJobType_lookup[driver->job_type]);
+@@ -729,9 +760,20 @@ static bool block_job_should_pause(BlockJob *job)
+     return job->pause_count > 0;
+ }
+ 
+-static void block_job_do_yield(BlockJob *job)
++/* Yield, and schedule a timer to reenter the coroutine after @ns nanoseconds.
++ * Reentering the job coroutine with block_job_enter() before the timer has
++ * expired is allowed and cancels the timer.
++ *
++ * If @ns is (uint64_t) -1, no timer is scheduled and block_job_enter() must be
++ * called explicitly. */
++static void block_job_do_yield(BlockJob *job, uint64_t ns)
+ {
++    block_job_lock();
++    if (ns != -1) {
++        timer_mod(&job->sleep_timer, ns);
++    }
+     job->busy = false;
++    block_job_unlock();
+     qemu_coroutine_yield();
+ 
+     /* Set by block_job_enter before re-entering the coroutine.  */
+@@ -755,7 +797,7 @@ void coroutine_fn block_job_pause_point(BlockJob *job)
+ 
+     if (block_job_should_pause(job) && !block_job_is_cancelled(job)) {
+         job->paused = true;
+-        block_job_do_yield(job);
++        block_job_do_yield(job, -1);
+         job->paused = false;
+     }
+ 
+@@ -785,11 +827,16 @@ void block_job_enter(BlockJob *job)
+         return;
+     }
+ 
++    block_job_lock();
+     if (job->busy) {
++        block_job_unlock();
+         return;
+     }
+ 
++    assert(!job->deferred_to_main_loop);
++    timer_del(&job->sleep_timer);
+     job->busy = true;
++    block_job_unlock();
+     aio_co_wake(job->co);
+ }
+ 
+@@ -807,14 +854,8 @@ void block_job_sleep_ns(BlockJob *job, int64_t ns)
+         return;
+     }
+ 
+-    /* We need to leave job->busy set here, because when we have
+-     * put a coroutine to 'sleep', we have scheduled it to run in
+-     * the future.  We cannot enter that same coroutine again before
+-     * it wakes and runs, otherwise we risk double-entry or entry after
+-     * completion. */
+     if (!block_job_should_pause(job)) {
+-        co_aio_sleep_ns(blk_get_aio_context(job->blk),
+-                        QEMU_CLOCK_REALTIME, ns);
++        block_job_do_yield(job, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns);
+     }
+ 
+     block_job_pause_point(job);
+@@ -830,7 +871,7 @@ void block_job_yield(BlockJob *job)
+     }
+ 
+     if (!block_job_should_pause(job)) {
+-        block_job_do_yield(job);
++        block_job_do_yield(job, -1);
+     }
+ 
+     block_job_pause_point(job);
+diff --git a/include/block/blockjob.h b/include/block/blockjob.h
+index 67c0968..00403d9 100644
+--- a/include/block/blockjob.h
++++ b/include/block/blockjob.h
+@@ -77,7 +77,7 @@ typedef struct BlockJob {
+     /**
+      * Set to false by the job while the coroutine has yielded and may be
+      * re-entered by block_job_enter().  There may still be I/O or event loop
+-     * activity pending.
++     * activity pending.  Accessed under block_job_mutex (in blockjob.c).
+      */
+     bool busy;
+ 
+@@ -135,6 +135,12 @@ typedef struct BlockJob {
+      */
+     int ret;
+ 
++    /**
++     * Timer that is used by @block_job_sleep_ns. Accessed under
++     * block_job_mutex (in blockjob.c).
++     */
++    QEMUTimer sleep_timer;
++
+     /** Non-NULL if this job is part of a transaction */
+     BlockJobTxn *txn;
+     QLIST_ENTRY(BlockJob) txn_list;
+diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
+index f7ab183..c9b23b0 100644
+--- a/include/block/blockjob_int.h
++++ b/include/block/blockjob_int.h
+@@ -142,8 +142,8 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+  * @ns: How many nanoseconds to stop for.
+  *
+  * Put the job to sleep (assuming that it wasn't canceled) for @ns
+- * %QEMU_CLOCK_REALTIME nanoseconds.  Canceling the job will not interrupt
+- * the wait, so the cancel will not process until the coroutine wakes up.
++ * %QEMU_CLOCK_REALTIME nanoseconds.  Canceling the job will immediately
++ * interrupt the wait.
+  */
+ void block_job_sleep_ns(BlockJob *job, int64_t ns);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockjob-remove-clock-argument-from-block_job_sleep_.patch b/SOURCES/kvm-blockjob-remove-clock-argument-from-block_job_sleep_.patch
new file mode 100644
index 0000000..3685bfc
--- /dev/null
+++ b/SOURCES/kvm-blockjob-remove-clock-argument-from-block_job_sleep_.patch
@@ -0,0 +1,172 @@
+From e514856415406ee30a9199843895057faa7e7152 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:13 +0100
+Subject: [PATCH 09/21] blockjob: remove clock argument from block_job_sleep_ns
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <2f57c3ce7143bdde2d8c485e3b1eda19898547dd.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78048
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 09/11] blockjob: remove clock argument from block_job_sleep_ns
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+All callers are using QEMU_CLOCK_REALTIME, and it will not be possible to
+support more than one clock when block_job_sleep_ns switches to a single
+timer stored in the BlockJob struct.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Tested-By: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 5bf1d5a73a4a6d0e2d692bd02b6d7f3eedeed3b7)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/backup.c               | 4 ++--
+ block/commit.c               | 2 +-
+ block/mirror.c               | 6 +++---
+ block/stream.c               | 2 +-
+ blockjob.c                   | 5 +++--
+ include/block/blockjob_int.h | 7 +++----
+ tests/test-blockjob-txn.c    | 2 +-
+ 7 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/block/backup.c b/block/backup.c
+index 504a089..ac6dc89 100644
+--- a/block/backup.c
++++ b/block/backup.c
+@@ -346,9 +346,9 @@ static bool coroutine_fn yield_and_check(BackupBlockJob *job)
+         uint64_t delay_ns = ratelimit_calculate_delay(&job->limit,
+                                                       job->bytes_read);
+         job->bytes_read = 0;
+-        block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
++        block_job_sleep_ns(&job->common, delay_ns);
+     } else {
+-        block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
++        block_job_sleep_ns(&job->common, 0);
+     }
+ 
+     if (block_job_is_cancelled(&job->common)) {
+diff --git a/block/commit.c b/block/commit.c
+index 834084b..9dbad9c 100644
+--- a/block/commit.c
++++ b/block/commit.c
+@@ -179,7 +179,7 @@ static void coroutine_fn commit_run(void *opaque)
+         /* Note that even when no rate limit is applied we need to yield
+          * with no pending I/O here so that bdrv_drain_all() returns.
+          */
+-        block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
++        block_job_sleep_ns(&s->common, delay_ns);
+         if (block_job_is_cancelled(&s->common)) {
+             break;
+         }
+diff --git a/block/mirror.c b/block/mirror.c
+index 17278db..b88014e 100644
+--- a/block/mirror.c
++++ b/block/mirror.c
+@@ -608,7 +608,7 @@ static void mirror_throttle(MirrorBlockJob *s)
+ 
+     if (now - s->last_pause_ns > SLICE_TIME) {
+         s->last_pause_ns = now;
+-        block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0);
++        block_job_sleep_ns(&s->common, 0);
+     } else {
+         block_job_pause_point(&s->common);
+     }
+@@ -891,13 +891,13 @@ static void coroutine_fn mirror_run(void *opaque)
+         trace_mirror_before_sleep(s, cnt * BDRV_SECTOR_SIZE,
+                                   s->synced, delay_ns);
+         if (!s->synced) {
+-            block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
++            block_job_sleep_ns(&s->common, delay_ns);
+             if (block_job_is_cancelled(&s->common)) {
+                 break;
+             }
+         } else if (!should_complete) {
+             delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0);
+-            block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
++            block_job_sleep_ns(&s->common, delay_ns);
+         }
+         s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+     }
+diff --git a/block/stream.c b/block/stream.c
+index e6f7234..499cdac 100644
+--- a/block/stream.c
++++ b/block/stream.c
+@@ -141,7 +141,7 @@ static void coroutine_fn stream_run(void *opaque)
+         /* Note that even when no rate limit is applied we need to yield
+          * with no pending I/O here so that bdrv_drain_all() returns.
+          */
+-        block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
++        block_job_sleep_ns(&s->common, delay_ns);
+         if (block_job_is_cancelled(&s->common)) {
+             break;
+         }
+diff --git a/blockjob.c b/blockjob.c
+index 2509bba..4d78046 100644
+--- a/blockjob.c
++++ b/blockjob.c
+@@ -788,7 +788,7 @@ bool block_job_is_cancelled(BlockJob *job)
+     return job->cancelled;
+ }
+ 
+-void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
++void block_job_sleep_ns(BlockJob *job, int64_t ns)
+ {
+     assert(job->busy);
+ 
+@@ -803,7 +803,8 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
+      * it wakes and runs, otherwise we risk double-entry or entry after
+      * completion. */
+     if (!block_job_should_pause(job)) {
+-        co_aio_sleep_ns(blk_get_aio_context(job->blk), type, ns);
++        co_aio_sleep_ns(blk_get_aio_context(job->blk),
++                        QEMU_CLOCK_REALTIME, ns);
+     }
+ 
+     block_job_pause_point(job);
+diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
+index 43f3be2..f7ab183 100644
+--- a/include/block/blockjob_int.h
++++ b/include/block/blockjob_int.h
+@@ -139,14 +139,13 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+ /**
+  * block_job_sleep_ns:
+  * @job: The job that calls the function.
+- * @clock: The clock to sleep on.
+  * @ns: How many nanoseconds to stop for.
+  *
+  * Put the job to sleep (assuming that it wasn't canceled) for @ns
+- * nanoseconds.  Canceling the job will not interrupt the wait, so the
+- * cancel will not process until the coroutine wakes up.
++ * %QEMU_CLOCK_REALTIME nanoseconds.  Canceling the job will not interrupt
++ * the wait, so the cancel will not process until the coroutine wakes up.
+  */
+-void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns);
++void block_job_sleep_ns(BlockJob *job, int64_t ns);
+ 
+ /**
+  * block_job_yield:
+diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
+index c77343f..3591c96 100644
+--- a/tests/test-blockjob-txn.c
++++ b/tests/test-blockjob-txn.c
+@@ -44,7 +44,7 @@ static void coroutine_fn test_block_job_run(void *opaque)
+ 
+     while (s->iterations--) {
+         if (s->use_timer) {
+-            block_job_sleep_ns(job, QEMU_CLOCK_REALTIME, 0);
++            block_job_sleep_ns(job, 0);
+         } else {
+             block_job_yield(job);
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-build-sys-restrict-vmcoreinfo-to-fw_cfg-dma-capable-.patch b/SOURCES/kvm-build-sys-restrict-vmcoreinfo-to-fw_cfg-dma-capable-.patch
new file mode 100644
index 0000000..f1b0df3
--- /dev/null
+++ b/SOURCES/kvm-build-sys-restrict-vmcoreinfo-to-fw_cfg-dma-capable-.patch
@@ -0,0 +1,84 @@
+From bc725b358214c32163d60898e26b24b3ba84a3ca Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:11 +0100
+Subject: [PATCH 13/21] build-sys: restrict vmcoreinfo to fw_cfg+dma capable
+ targets
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-10-marcandre.lureau@redhat.com>
+Patchwork-id: 77926
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 9/9] build-sys: restrict vmcoreinfo to fw_cfg+dma capable targets
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+vmcoreinfo is built for all targets. However, it requires fw_cfg with
+DMA operations support (write operation). Restrict vmcoreinfo exposure
+to architectures that are supporting FW_CFG_DMA, that is arm-virt and
+x86 only atm.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Tested-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit f865da7c369fa00b2ccaf6bce158ad2701b2a27c)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ default-configs/arm-softmmu.mak    | 2 ++
+ default-configs/i386-softmmu.mak   | 1 +
+ default-configs/x86_64-softmmu.mak | 1 +
+ hw/misc/Makefile.objs              | 2 +-
+ 4 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
+index 05aaf8f..bbdcc81 100644
+--- a/default-configs/arm-softmmu.mak
++++ b/default-configs/arm-softmmu.mak
+@@ -128,3 +128,5 @@ CONFIG_ACPI=y
+ CONFIG_SMBIOS=y
+ CONFIG_ASPEED_SOC=y
+ CONFIG_GPIO_KEY=y
++
++CONFIG_FW_CFG_DMA=y
+diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
+index d2ab2f6..f7c0b33 100644
+--- a/default-configs/i386-softmmu.mak
++++ b/default-configs/i386-softmmu.mak
+@@ -59,3 +59,4 @@ CONFIG_SMBIOS=y
+ CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
+ CONFIG_PXB=y
+ CONFIG_ACPI_VMGENID=y
++CONFIG_FW_CFG_DMA=y
+diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
+index d6d10aa..611fa6f 100644
+--- a/default-configs/x86_64-softmmu.mak
++++ b/default-configs/x86_64-softmmu.mak
+@@ -61,3 +61,4 @@ CONFIG_SMBIOS=y
+ #CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
+ CONFIG_PXB=y
+ CONFIG_ACPI_VMGENID=y
++CONFIG_FW_CFG_DMA=y
+diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
+index b4cbebf..255a35a 100644
+--- a/hw/misc/Makefile.objs
++++ b/hw/misc/Makefile.objs
+@@ -9,7 +9,7 @@ common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
+ common-obj-$(CONFIG_EDU) += edu.o
+ 
+ #common-obj-y += unimp.o
+-common-obj-y += vmcoreinfo.o
++common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
+ 
+ obj-$(CONFIG_VMPORT) += vmport.o
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch b/SOURCES/kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch
new file mode 100644
index 0000000..96add77
--- /dev/null
+++ b/SOURCES/kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch
@@ -0,0 +1,69 @@
+From 63d5677cbe031c52b37af8d123c27fdcb0f73af3 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 20 Oct 2017 07:19:25 +0200
+Subject: [PATCH 03/19] cirrus: fix oob access in mode4and5 write functions
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171020071925.9483-5-kraxel@redhat.com>
+Patchwork-id: 77392
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 4/4] cirrus: fix oob access in mode4and5 write functions
+Bugzilla: 1501301
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Move dst calculation into the loop, so we apply the mask on each
+interation and will not overflow vga memory.
+
+Cc: Prasad J Pandit <pjp@fedoraproject.org>
+Reported-by: Niu Guoxiang <niuguoxiang@huawei.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20171011084314.21752-1-kraxel@redhat.com
+(cherry picked from commit eb38e1bc3740725ca29a535351de94107ec58d51)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/cirrus_vga.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
+index 15322b5..e53c6f2 100644
+--- a/hw/display/cirrus_vga.c
++++ b/hw/display/cirrus_vga.c
+@@ -2038,15 +2038,14 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
+     unsigned val = mem_value;
+     uint8_t *dst;
+ 
+-    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
+     for (x = 0; x < 8; x++) {
++        dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask);
+ 	if (val & 0x80) {
+ 	    *dst = s->cirrus_shadow_gr1;
+ 	} else if (mode == 5) {
+ 	    *dst = s->cirrus_shadow_gr0;
+ 	}
+ 	val <<= 1;
+-	dst++;
+     }
+     memory_region_set_dirty(&s->vga.vram, offset, 8);
+ }
+@@ -2060,8 +2059,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
+     unsigned val = mem_value;
+     uint8_t *dst;
+ 
+-    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
+     for (x = 0; x < 8; x++) {
++        dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1);
+ 	if (val & 0x80) {
+ 	    *dst = s->cirrus_shadow_gr1;
+ 	    *(dst + 1) = s->vga.gr[0x11];
+@@ -2070,7 +2069,6 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
+ 	    *(dst + 1) = s->vga.gr[0x10];
+ 	}
+ 	val <<= 1;
+-	dst += 2;
+     }
+     memory_region_set_dirty(&s->vga.vram, offset, 16);
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-configure-Allow-enable-seccomp-on-s390x-too.patch b/SOURCES/kvm-configure-Allow-enable-seccomp-on-s390x-too.patch
new file mode 100644
index 0000000..ec26e33
--- /dev/null
+++ b/SOURCES/kvm-configure-Allow-enable-seccomp-on-s390x-too.patch
@@ -0,0 +1,46 @@
+From eb80abd49652e09d10b44da5a75c753e76ef5beb Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 2 Oct 2017 07:04:17 +0200
+Subject: [PATCH 02/34] configure: Allow --enable-seccomp on s390x, too
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1506927858-5400-2-git-send-email-thuth@redhat.com>
+Patchwork-id: 76788
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 1/2] configure: Allow --enable-seccomp on s390x, too
+Bugzilla: 1491647
+RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+libseccomp supports s390x since version 2.3.0, and I was able to start
+a VM with "-sandbox on" without any obvious problems by using this patch,
+so it should be safe to allow --enable-seccomp on s390x nowadays, too.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1505385363-27717-1-git-send-email-thuth@redhat.com>
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Acked-by: Eduardo Otubo <otubo@redhat.com>
+Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 3aa35fcffcf0fe22ac48d4277ed6057ae3e57ce0)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ configure | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index 355c364..5cb65d0 100755
+--- a/configure
++++ b/configure
+@@ -2050,7 +2050,7 @@ if test "$seccomp" != "no" ; then
+     arm|aarch64)
+         libseccomp_minver="2.2.3"
+         ;;
+-    ppc|ppc64)
++    ppc|ppc64|s390x)
+         libseccomp_minver="2.3.0"
+         ;;
+     *)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-configure-enable-s390-pgste-linker-option.patch b/SOURCES/kvm-configure-enable-s390-pgste-linker-option.patch
new file mode 100644
index 0000000..ee67ad0
--- /dev/null
+++ b/SOURCES/kvm-configure-enable-s390-pgste-linker-option.patch
@@ -0,0 +1,98 @@
+From 487aafe7bfede37118f4664b473b9a3960a5b89d Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Fri, 13 Oct 2017 14:13:00 +0200
+Subject: [PATCH 19/69] configure: enable --s390-pgste linker option
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20171013141301.23131-2-cohuck@redhat.com>
+Patchwork-id: 77285
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH v3 1/2] configure: enable --s390-pgste linker option
+Bugzilla: 1485399
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+KVM guests on s390 need a different page table layout than normal
+processes (2kb page table + 2kb page status extensions vs 2kb page table
+only). As of today this has to be enabled via the vm.allocate_pgste
+sysctl.
+
+Newer kernels (>= 4.12) on s390 check for an S390_PGSTE program header
+and enable the pgste page table extensions in that case. This makes the
+vm.allocate_pgste sysctl unnecessary. We enable this program header for
+the s390 system emulation (qemu-system-s390x) if we build on s390
+- for s390 system emulation
+- the linker supports --s390-pgste (binutils >= 2.29)
+- KVM is enabled
+
+This will allow distributions to disable the global vm.allocate_pgste
+sysctl, which will improve the page table allocation for non KVM
+processes as only 2kb chunks are necessary.
+
+Cc: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Cc: Alexander Graf <agraf@suse.de>
+Cc: Dan Horak <dhorak@redhat.com>
+Cc: David Hildenbrand <david@redhat.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Acked-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1503483383-199649-1-git-send-email-borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit e9a3591fa09f273592451f8b9f83692bcbedb60c)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ configure | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index 0da6821..644e52d 100755
+--- a/configure
++++ b/configure
+@@ -240,6 +240,11 @@ supported_target() {
+     return 1
+ }
+ 
++
++ld_has() {
++    $ld --help 2>/dev/null | grep ".$1" >/dev/null 2>&1
++}
++
+ # default parameters
+ source_path=$(dirname "$0")
+ cpu=""
+@@ -5033,7 +5038,7 @@ fi
+ # Use ASLR, no-SEH and DEP if available
+ if test "$mingw32" = "yes" ; then
+     for flag in --dynamicbase --no-seh --nxcompat; do
+-        if $ld --help 2>/dev/null | grep ".$flag" >/dev/null 2>/dev/null ; then
++        if ld_has $flag ; then
+             LDFLAGS="-Wl,$flag $LDFLAGS"
+         fi
+     done
+@@ -6520,6 +6525,20 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
+   ldflags="$ldflags $textseg_ldflags"
+ fi
+ 
++# Newer kernels on s390 check for an S390_PGSTE program header and
++# enable the pgste page table extensions in that case. This makes
++# the vm.allocate_pgste sysctl unnecessary. We enable this program
++# header if
++#  - we build on s390x
++#  - we build the system emulation for s390x (qemu-system-s390x)
++#  - KVM is enabled
++#  - the linker supports --s390-pgste
++if test "$TARGET_ARCH" = "s390x" -a "$target_softmmu" = "yes"  -a "$ARCH" = "s390x" -a "$kvm" = "yes"; then
++    if ld_has --s390-pgste ; then
++        ldflags="-Wl,--s390-pgste $ldflags"
++    fi
++fi
++
+ echo "LDFLAGS+=$ldflags" >> $config_target_mak
+ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-console-fix-dpy_gfx_replace_surface-assert.patch b/SOURCES/kvm-console-fix-dpy_gfx_replace_surface-assert.patch
new file mode 100644
index 0000000..1f57eb3
--- /dev/null
+++ b/SOURCES/kvm-console-fix-dpy_gfx_replace_surface-assert.patch
@@ -0,0 +1,47 @@
+From d8e09c7193591639d22c197bf265080cb22c2404 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 12 Jan 2018 11:30:11 +0100
+Subject: [PATCH 01/20] console: fix dpy_gfx_replace_surface assert
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20180112113011.21952-2-kraxel@redhat.com>
+Patchwork-id: 78565
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] console: fix dpy_gfx_replace_surface assert
+Bugzilla: 1505696
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+virtio-gpu can trigger the assert added by commit "6905b93447 console:
+add same surface replace pre-condition" in multihead setups (where
+surface can be NULL for secondary displays).  Allow surface being NULL.
+
+Fixes: 6905b93447a42e606dfd126b90f75f4cd3c6fe94
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20170906142109.2685-1-kraxel@redhat.com
+(cherry picked from commit 1540008629bbb6a9c0826582d94ecf7a559f784c)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/console.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui/console.c b/ui/console.c
+index 6967fd4..e92e9e0 100644
+--- a/ui/console.c
++++ b/ui/console.c
+@@ -1565,7 +1565,7 @@ void dpy_gfx_replace_surface(QemuConsole *con,
+     DisplaySurface *old_surface = con->surface;
+     DisplayChangeListener *dcl;
+ 
+-    assert(old_surface != surface);
++    assert(old_surface != surface || surface == NULL);
+ 
+     con->surface = surface;
+     QLIST_FOREACH(dcl, &s->listeners, next) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-coroutine-abort-if-we-try-to-schedule-or-enter-a-pen.patch b/SOURCES/kvm-coroutine-abort-if-we-try-to-schedule-or-enter-a-pen.patch
new file mode 100644
index 0000000..c319edc
--- /dev/null
+++ b/SOURCES/kvm-coroutine-abort-if-we-try-to-schedule-or-enter-a-pen.patch
@@ -0,0 +1,175 @@
+From ab88ad152dbdf6e906da07e2c165f01985edfe13 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:08 +0100
+Subject: [PATCH 04/21] coroutine: abort if we try to schedule or enter a
+ pending coroutine
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <27811c58f7dd73e9d8b6f51aff42a7de9bae37fc.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78044
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 04/11] coroutine: abort if we try to schedule or enter a pending coroutine
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+The previous patch fixed a race condition, in which there were
+coroutines being executing doubly, or after coroutine deletion.
+
+We can detect common scenarios when this happens, and print an error
+message and abort before we corrupt memory / data, or segfault.
+
+This patch will abort if an attempt to enter a coroutine is made while
+it is currently pending execution, either in a specific AioContext bh,
+or pending execution via a timer.  It will also abort if a coroutine
+is scheduled, before a prior scheduled run has occurred.
+
+We cannot rely on the existing co->caller check for recursive re-entry
+to catch this, as the coroutine may run and exit with
+COROUTINE_TERMINATE before the scheduled coroutine executes.
+
+(This is the scenario that was occurring and fixed in the previous
+patch).
+
+This patch also re-orders the Coroutine struct elements in an attempt to
+optimize caching.
+
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 6133b39f3c36623425a6ede9e89d93175fde15cd)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/qemu/coroutine_int.h | 13 ++++++++++---
+ util/async.c                 | 13 +++++++++++++
+ util/qemu-coroutine-sleep.c  | 12 ++++++++++++
+ util/qemu-coroutine.c        | 14 ++++++++++++++
+ 4 files changed, 49 insertions(+), 3 deletions(-)
+
+diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h
+index cb98892..59e8406 100644
+--- a/include/qemu/coroutine_int.h
++++ b/include/qemu/coroutine_int.h
+@@ -46,14 +46,21 @@ struct Coroutine {
+ 
+     size_t locks_held;
+ 
++    /* Only used when the coroutine has yielded.  */
++    AioContext *ctx;
++
++    /* Used to catch and abort on illegal co-routine entry.
++     * Will contain the name of the function that had first
++     * scheduled the coroutine. */
++    const char *scheduled;
++
++    QSIMPLEQ_ENTRY(Coroutine) co_queue_next;
++
+     /* Coroutines that should be woken up when we yield or terminate.
+      * Only used when the coroutine is running.
+      */
+     QSIMPLEQ_HEAD(, Coroutine) co_queue_wakeup;
+ 
+-    /* Only used when the coroutine has yielded.  */
+-    AioContext *ctx;
+-    QSIMPLEQ_ENTRY(Coroutine) co_queue_next;
+     QSLIST_ENTRY(Coroutine) co_scheduled_next;
+ };
+ 
+diff --git a/util/async.c b/util/async.c
+index 0e1bd87..4dd9d95 100644
+--- a/util/async.c
++++ b/util/async.c
+@@ -388,6 +388,9 @@ static void co_schedule_bh_cb(void *opaque)
+         QSLIST_REMOVE_HEAD(&straight, co_scheduled_next);
+         trace_aio_co_schedule_bh_cb(ctx, co);
+         aio_context_acquire(ctx);
++
++        /* Protected by write barrier in qemu_aio_coroutine_enter */
++        atomic_set(&co->scheduled, NULL);
+         qemu_coroutine_enter(co);
+         aio_context_release(ctx);
+     }
+@@ -438,6 +441,16 @@ fail:
+ void aio_co_schedule(AioContext *ctx, Coroutine *co)
+ {
+     trace_aio_co_schedule(ctx, co);
++    const char *scheduled = atomic_cmpxchg(&co->scheduled, NULL,
++                                           __func__);
++
++    if (scheduled) {
++        fprintf(stderr,
++                "%s: Co-routine was already scheduled in '%s'\n",
++                __func__, scheduled);
++        abort();
++    }
++
+     QSLIST_INSERT_HEAD_ATOMIC(&ctx->scheduled_coroutines,
+                               co, co_scheduled_next);
+     qemu_bh_schedule(ctx->co_schedule_bh);
+diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
+index 9c56550..254349c 100644
+--- a/util/qemu-coroutine-sleep.c
++++ b/util/qemu-coroutine-sleep.c
+@@ -13,6 +13,7 @@
+ 
+ #include "qemu/osdep.h"
+ #include "qemu/coroutine.h"
++#include "qemu/coroutine_int.h"
+ #include "qemu/timer.h"
+ #include "block/aio.h"
+ 
+@@ -25,6 +26,8 @@ static void co_sleep_cb(void *opaque)
+ {
+     CoSleepCB *sleep_cb = opaque;
+ 
++    /* Write of schedule protected by barrier write in aio_co_schedule */
++    atomic_set(&sleep_cb->co->scheduled, NULL);
+     aio_co_wake(sleep_cb->co);
+ }
+ 
+@@ -34,6 +37,15 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
+     CoSleepCB sleep_cb = {
+         .co = qemu_coroutine_self(),
+     };
++
++    const char *scheduled = atomic_cmpxchg(&sleep_cb.co->scheduled, NULL,
++                                           __func__);
++    if (scheduled) {
++        fprintf(stderr,
++                "%s: Co-routine was already scheduled in '%s'\n",
++                __func__, scheduled);
++        abort();
++    }
+     sleep_cb.ts = aio_timer_new(ctx, type, SCALE_NS, co_sleep_cb, &sleep_cb);
+     timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns);
+     qemu_coroutine_yield();
+diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
+index d6095c1..9eff7fd 100644
+--- a/util/qemu-coroutine.c
++++ b/util/qemu-coroutine.c
+@@ -107,8 +107,22 @@ void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co)
+     Coroutine *self = qemu_coroutine_self();
+     CoroutineAction ret;
+ 
++    /* Cannot rely on the read barrier for co in aio_co_wake(), as there are
++     * callers outside of aio_co_wake() */
++    const char *scheduled = atomic_mb_read(&co->scheduled);
++
+     trace_qemu_aio_coroutine_enter(ctx, self, co, co->entry_arg);
+ 
++    /* if the Coroutine has already been scheduled, entering it again will
++     * cause us to enter it twice, potentially even after the coroutine has
++     * been deleted */
++    if (scheduled) {
++        fprintf(stderr,
++                "%s: Co-routine was already scheduled in '%s'\n",
++                __func__, scheduled);
++        abort();
++    }
++
+     if (co->caller) {
+         fprintf(stderr, "Co-routine re-entered recursively\n");
+         abort();
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-docs-Add-image-locking-subsection.patch b/SOURCES/kvm-docs-Add-image-locking-subsection.patch
new file mode 100644
index 0000000..d3bca6e
--- /dev/null
+++ b/SOURCES/kvm-docs-Add-image-locking-subsection.patch
@@ -0,0 +1,89 @@
+From c83bac681bd10d576c3af9a45b49065aa6b7330e Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Thu, 30 Nov 2017 09:25:42 +0100
+Subject: [PATCH 05/36] docs: Add image locking subsection
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20171130092544.19231-4-famz@redhat.com>
+Patchwork-id: 78016
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 3/5] docs: Add image locking subsection
+Bugzilla: 1494210
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+This documents the image locking feature and explains when and how
+related options can be used.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit b1d1cb272882dd6868740155120f6aeb260a204c)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ docs/qemu-block-drivers.texi | 36 ++++++++++++++++++++++++++++++++++++
+ qemu-doc.texi                |  1 +
+ 2 files changed, 37 insertions(+)
+
+diff --git a/docs/qemu-block-drivers.texi b/docs/qemu-block-drivers.texi
+index d3b8f3b..aa64e60 100644
+--- a/docs/qemu-block-drivers.texi
++++ b/docs/qemu-block-drivers.texi
+@@ -785,6 +785,42 @@ warning: ssh server @code{ssh.example.com:22} does not support fsync
+ With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
+ supported.
+ 
++@node disk_image_locking
++@subsection Disk image file locking
++
++By default, QEMU tries to protect image files from unexpected concurrent
++access, as long as it's supported by the block protocol driver and host
++operating system. If multiple QEMU processes (including QEMU emulators and
++utilities) try to open the same image with conflicting accessing modes, all but
++the first one will get an error.
++
++This feature is currently supported by the file protocol on Linux with the Open
++File Descriptor (OFD) locking API, and can be configured to fall back to POSIX
++locking if the POSIX host doesn't support Linux OFD locking.
++
++To explicitly enable image locking, specify "locking=on" in the file protocol
++driver options. If OFD locking is not possible, a warning will be printed and
++the POSIX locking API will be used. In this case there is a risk that the lock
++will get silently lost when doing hot plugging and block jobs, due to the
++shortcomings of the POSIX locking API.
++
++QEMU transparently handles lock handover during shared storage migration.  For
++shared virtual disk images between multiple VMs, the "share-rw" device option
++should be used.
++
++Alternatively, locking can be fully disabled by "locking=off" block device
++option. In the command line, the option is usually in the form of
++"file.locking=off" as the protocol driver is normally placed as a "file" child
++under a format driver. For example:
++
++@code{-blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file}
++
++To check if image locking is active, check the output of the "lslocks" command
++on host and see if there are locks held by the QEMU process on the image file.
++More than one byte could be locked by the QEMU instance, each byte of which
++reflects a particular permission that is acquired or protected by the running
++block driver.
++
+ @c man end
+ 
+ @ignore
+diff --git a/qemu-doc.texi b/qemu-doc.texi
+index b0db386..6af38de 100644
+--- a/qemu-doc.texi
++++ b/qemu-doc.texi
+@@ -405,6 +405,7 @@ encrypted disk images.
+ * disk_images_iscsi::         iSCSI LUNs
+ * disk_images_gluster::       GlusterFS disk images
+ * disk_images_ssh::           Secure Shell (ssh) disk images
++* disk_image_locking::        Disk image file locking
+ @end menu
+ 
+ @node disk_images_quickstart
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-docs-add-qemu-block-drivers-7-man-page.patch b/SOURCES/kvm-docs-add-qemu-block-drivers-7-man-page.patch
new file mode 100644
index 0000000..f38bd83
--- /dev/null
+++ b/SOURCES/kvm-docs-add-qemu-block-drivers-7-man-page.patch
@@ -0,0 +1,1693 @@
+From 8a61770b2643a2af889205cc643d62d0ea3121f5 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Thu, 30 Nov 2017 09:25:41 +0100
+Subject: [PATCH 04/36] docs: add qemu-block-drivers(7) man page
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20171130092544.19231-3-famz@redhat.com>
+Patchwork-id: 78014
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 2/5] docs: add qemu-block-drivers(7) man page
+Bugzilla: 1494210
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+Block driver documentation is available in qemu-doc.html.  It would be
+convenient to have documentation for formats, protocols, and filter
+drivers in a man page.
+
+Extract the relevant part of qemu-doc.html into a new file called
+docs/qemu-block-drivers.texi.  This file can also be built as a
+stand-alone document (man, html, etc).
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 78aa8aa019b999ec07b62b322c1280a8250e44ac)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	Makefile
+Context different because we have reverted 60b412dd18362bd in downstream
+(as e0425f69f13).
+	qemu-doc.texi
+We do s/qemu-system-i386/qemu-kvm/ everywhere in downstream docs.
+---
+ Makefile                     |   6 +-
+ docs/qemu-block-drivers.texi | 804 +++++++++++++++++++++++++++++++++++++++++++
+ qemu-doc.texi                | 781 +----------------------------------------
+ 3 files changed, 810 insertions(+), 781 deletions(-)
+ create mode 100644 docs/qemu-block-drivers.texi
+
+diff --git a/Makefile b/Makefile
+index 312ed5e..1a773a8 100644
+--- a/Makefile
++++ b/Makefile
+@@ -209,6 +209,7 @@ ifdef BUILD_DOCS
+ DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
+ DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
+ DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
++DOCS+=docs/qemu-block-drivers.7
+ ifdef CONFIG_LINUX
+ DOCS+=kvm_stat.1
+ endif
+@@ -531,6 +532,7 @@ distclean: clean
+ 	rm -f docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
+ 	rm -f docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
+ 	rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
++	rm -f docs/qemu-block-drivers.7
+ 	for d in $(TARGET_DIRS); do \
+ 	rm -rf $$d || exit 1 ; \
+         done
+@@ -576,6 +578,7 @@ ifdef CONFIG_POSIX
+ 	$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1/qemu-kvm.1"
+ 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man7"
+ 	$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
++	$(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
+ ifneq ($(TOOLS),)
+ 	$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
+ 	$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
+@@ -725,6 +728,7 @@ qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
+ fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
+ qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
+ qemu-ga.8: qemu-ga.texi
++docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
+ 
+ html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
+ info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
+@@ -739,7 +743,7 @@ kvm_stat.1: scripts/kvm/kvm_stat.texi
+ qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
+ 	qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-option-trace.texi \
+ 	qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
+-	qemu-monitor-info.texi
++	qemu-monitor-info.texi docs/qemu-block-drivers.texi
+ 
+ docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
+     docs/interop/qemu-ga-ref.info docs/interop/qemu-ga-ref.pdf \
+diff --git a/docs/qemu-block-drivers.texi b/docs/qemu-block-drivers.texi
+new file mode 100644
+index 0000000..d3b8f3b
+--- /dev/null
++++ b/docs/qemu-block-drivers.texi
+@@ -0,0 +1,804 @@
++@c man begin SYNOPSIS
++QEMU block driver reference manual
++@c man end
++
++@c man begin DESCRIPTION
++
++@node disk_images_formats
++@subsection Disk image file formats
++
++QEMU supports many image file formats that can be used with VMs as well as with
++any of the tools (like @code{qemu-img}). This includes the preferred formats
++raw and qcow2 as well as formats that are supported for compatibility with
++older QEMU versions or other hypervisors.
++
++Depending on the image format, different options can be passed to
++@code{qemu-img create} and @code{qemu-img convert} using the @code{-o} option.
++This section describes each format and the options that are supported for it.
++
++@table @option
++@item raw
++
++Raw disk image format. This format has the advantage of
++being simple and easily exportable to all other emulators. If your
++file system supports @emph{holes} (for example in ext2 or ext3 on
++Linux or NTFS on Windows), then only the written sectors will reserve
++space. Use @code{qemu-img info} to know the real size used by the
++image or @code{ls -ls} on Unix/Linux.
++
++Supported options:
++@table @code
++@item preallocation
++Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
++@code{falloc} mode preallocates space for image by calling posix_fallocate().
++@code{full} mode preallocates space for image by writing zeros to underlying
++storage.
++@end table
++
++@item qcow2
++QEMU image format, the most versatile format. Use it to have smaller
++images (useful if your filesystem does not supports holes, for example
++on Windows), zlib based compression and support of multiple VM
++snapshots.
++
++Supported options:
++@table @code
++@item compat
++Determines the qcow2 version to use. @code{compat=0.10} uses the
++traditional image format that can be read by any QEMU since 0.10.
++@code{compat=1.1} enables image format extensions that only QEMU 1.1 and
++newer understand (this is the default). Amongst others, this includes
++zero clusters, which allow efficient copy-on-read for sparse images.
++
++@item backing_file
++File name of a base image (see @option{create} subcommand)
++@item backing_fmt
++Image format of the base image
++@item encryption
++This option is deprecated and equivalent to @code{encrypt.format=aes}
++
++@item encrypt.format
++
++If this is set to @code{luks}, it requests that the qcow2 payload (not
++qcow2 header) be encrypted using the LUKS format. The passphrase to
++use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
++parameter. LUKS encryption parameters can be tuned with the other
++@code{encrypt.*} parameters.
++
++If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
++The encryption key is given by the @code{encrypt.key-secret} parameter.
++This encryption format is considered to be flawed by modern cryptography
++standards, suffering from a number of design problems:
++
++@itemize @minus
++@item The AES-CBC cipher is used with predictable initialization vectors based
++on the sector number. This makes it vulnerable to chosen plaintext attacks
++which can reveal the existence of encrypted data.
++@item The user passphrase is directly used as the encryption key. A poorly
++chosen or short passphrase will compromise the security of the encryption.
++@item In the event of the passphrase being compromised there is no way to
++change the passphrase to protect data in any qcow images. The files must
++be cloned, using a different encryption passphrase in the new file. The
++original file must then be securely erased using a program like shred,
++though even this is ineffective with many modern storage technologies.
++@end itemize
++
++The use of this is no longer supported in system emulators. Support only
++remains in the command line utilities, for the purposes of data liberation
++and interoperability with old versions of QEMU. The @code{luks} format
++should be used instead.
++
++@item encrypt.key-secret
++
++Provides the ID of a @code{secret} object that contains the passphrase
++(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
++
++@item encrypt.cipher-alg
++
++Name of the cipher algorithm and key length. Currently defaults
++to @code{aes-256}. Only used when @code{encrypt.format=luks}.
++
++@item encrypt.cipher-mode
++
++Name of the encryption mode to use. Currently defaults to @code{xts}.
++Only used when @code{encrypt.format=luks}.
++
++@item encrypt.ivgen-alg
++
++Name of the initialization vector generator algorithm. Currently defaults
++to @code{plain64}. Only used when @code{encrypt.format=luks}.
++
++@item encrypt.ivgen-hash-alg
++
++Name of the hash algorithm to use with the initialization vector generator
++(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
++
++@item encrypt.hash-alg
++
++Name of the hash algorithm to use for PBKDF algorithm
++Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
++
++@item encrypt.iter-time
++
++Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
++Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
++
++@item cluster_size
++Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
++sizes can improve the image file size whereas larger cluster sizes generally
++provide better performance.
++
++@item preallocation
++Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
++@code{full}). An image with preallocated metadata is initially larger but can
++improve performance when the image needs to grow. @code{falloc} and @code{full}
++preallocations are like the same options of @code{raw} format, but sets up
++metadata also.
++
++@item lazy_refcounts
++If this option is set to @code{on}, reference count updates are postponed with
++the goal of avoiding metadata I/O and improving performance. This is
++particularly interesting with @option{cache=writethrough} which doesn't batch
++metadata updates. The tradeoff is that after a host crash, the reference count
++tables must be rebuilt, i.e. on the next open an (automatic) @code{qemu-img
++check -r all} is required, which may take some time.
++
++This option can only be enabled if @code{compat=1.1} is specified.
++
++@item nocow
++If this option is set to @code{on}, it will turn off COW of the file. It's only
++valid on btrfs, no effect on other file systems.
++
++Btrfs has low performance when hosting a VM image file, even more when the guest
++on the VM also using btrfs as file system. Turning off COW is a way to mitigate
++this bad performance. Generally there are two ways to turn off COW on btrfs:
++a) Disable it by mounting with nodatacow, then all newly created files will be
++NOCOW. b) For an empty file, add the NOCOW file attribute. That's what this option
++does.
++
++Note: this option is only valid to new or empty files. If there is an existing
++file which is COW and has data blocks already, it couldn't be changed to NOCOW
++by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
++the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
++
++@end table
++
++@item qed
++Old QEMU image format with support for backing files and compact image files
++(when your filesystem or transport medium does not support holes).
++
++When converting QED images to qcow2, you might want to consider using the
++@code{lazy_refcounts=on} option to get a more QED-like behaviour.
++
++Supported options:
++@table @code
++@item backing_file
++File name of a base image (see @option{create} subcommand).
++@item backing_fmt
++Image file format of backing file (optional).  Useful if the format cannot be
++autodetected because it has no header, like some vhd/vpc files.
++@item cluster_size
++Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
++cluster sizes can improve the image file size whereas larger cluster sizes
++generally provide better performance.
++@item table_size
++Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
++and 16).  There is normally no need to change this value but this option can be
++used for performance benchmarking.
++@end table
++
++@item qcow
++Old QEMU image format with support for backing files, compact image files,
++encryption and compression.
++
++Supported options:
++@table @code
++@item backing_file
++File name of a base image (see @option{create} subcommand)
++@item encryption
++This option is deprecated and equivalent to @code{encrypt.format=aes}
++
++@item encrypt.format
++If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
++The encryption key is given by the @code{encrypt.key-secret} parameter.
++This encryption format is considered to be flawed by modern cryptography
++standards, suffering from a number of design problems enumerated previously
++against the @code{qcow2} image format.
++
++The use of this is no longer supported in system emulators. Support only
++remains in the command line utilities, for the purposes of data liberation
++and interoperability with old versions of QEMU.
++
++Users requiring native encryption should use the @code{qcow2} format
++instead with @code{encrypt.format=luks}.
++
++@item encrypt.key-secret
++
++Provides the ID of a @code{secret} object that contains the encryption
++key (@code{encrypt.format=aes}).
++
++@end table
++
++@item luks
++
++LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
++
++Supported options:
++@table @code
++
++@item key-secret
++
++Provides the ID of a @code{secret} object that contains the passphrase.
++
++@item cipher-alg
++
++Name of the cipher algorithm and key length. Currently defaults
++to @code{aes-256}.
++
++@item cipher-mode
++
++Name of the encryption mode to use. Currently defaults to @code{xts}.
++
++@item ivgen-alg
++
++Name of the initialization vector generator algorithm. Currently defaults
++to @code{plain64}.
++
++@item ivgen-hash-alg
++
++Name of the hash algorithm to use with the initialization vector generator
++(if required). Defaults to @code{sha256}.
++
++@item hash-alg
++
++Name of the hash algorithm to use for PBKDF algorithm
++Defaults to @code{sha256}.
++
++@item iter-time
++
++Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
++Defaults to @code{2000}.
++
++@end table
++
++@item vdi
++VirtualBox 1.1 compatible image format.
++Supported options:
++@table @code
++@item static
++If this option is set to @code{on}, the image is created with metadata
++preallocation.
++@end table
++
++@item vmdk
++VMware 3 and 4 compatible image format.
++
++Supported options:
++@table @code
++@item backing_file
++File name of a base image (see @option{create} subcommand).
++@item compat6
++Create a VMDK version 6 image (instead of version 4)
++@item hwversion
++Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
++if hwversion is specified.
++@item subformat
++Specifies which VMDK subformat to use. Valid options are
++@code{monolithicSparse} (default),
++@code{monolithicFlat},
++@code{twoGbMaxExtentSparse},
++@code{twoGbMaxExtentFlat} and
++@code{streamOptimized}.
++@end table
++
++@item vpc
++VirtualPC compatible image format (VHD).
++Supported options:
++@table @code
++@item subformat
++Specifies which VHD subformat to use. Valid options are
++@code{dynamic} (default) and @code{fixed}.
++@end table
++
++@item VHDX
++Hyper-V compatible image format (VHDX).
++Supported options:
++@table @code
++@item subformat
++Specifies which VHDX subformat to use. Valid options are
++@code{dynamic} (default) and @code{fixed}.
++@item block_state_zero
++Force use of payload blocks of type 'ZERO'.  Can be set to @code{on} (default)
++or @code{off}.  When set to @code{off}, new blocks will be created as
++@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
++arbitrary data for those blocks.  Do not set to @code{off} when using
++@code{qemu-img convert} with @code{subformat=dynamic}.
++@item block_size
++Block size; min 1 MB, max 256 MB.  0 means auto-calculate based on image size.
++@item log_size
++Log size; min 1 MB.
++@end table
++@end table
++
++@subsubsection Read-only formats
++More disk image file formats are supported in a read-only mode.
++@table @option
++@item bochs
++Bochs images of @code{growing} type.
++@item cloop
++Linux Compressed Loop image, useful only to reuse directly compressed
++CD-ROM images present for example in the Knoppix CD-ROMs.
++@item dmg
++Apple disk image.
++@item parallels
++Parallels disk image format.
++@end table
++
++
++@node host_drives
++@subsection Using host drives
++
++In addition to disk image files, QEMU can directly access host
++devices. We describe here the usage for QEMU version >= 0.8.3.
++
++@subsubsection Linux
++
++On Linux, you can directly use the host device filename instead of a
++disk image filename provided you have enough privileges to access
++it. For example, use @file{/dev/cdrom} to access to the CDROM.
++
++@table @code
++@item CD
++You can specify a CDROM device even if no CDROM is loaded. QEMU has
++specific code to detect CDROM insertion or removal. CDROM ejection by
++the guest OS is supported. Currently only data CDs are supported.
++@item Floppy
++You can specify a floppy device even if no floppy is loaded. Floppy
++removal is currently not detected accurately (if you change floppy
++without doing floppy access while the floppy is not loaded, the guest
++OS will think that the same floppy is loaded).
++Use of the host's floppy device is deprecated, and support for it will
++be removed in a future release.
++@item Hard disks
++Hard disks can be used. Normally you must specify the whole disk
++(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
++see it as a partitioned disk. WARNING: unless you know what you do, it
++is better to only make READ-ONLY accesses to the hard disk otherwise
++you may corrupt your host data (use the @option{-snapshot} command
++line option or modify the device permissions accordingly).
++@end table
++
++@subsubsection Windows
++
++@table @code
++@item CD
++The preferred syntax is the drive letter (e.g. @file{d:}). The
++alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
++supported as an alias to the first CDROM drive.
++
++Currently there is no specific code to handle removable media, so it
++is better to use the @code{change} or @code{eject} monitor commands to
++change or eject media.
++@item Hard disks
++Hard disks can be used with the syntax: @file{\\.\PhysicalDrive@var{N}}
++where @var{N} is the drive number (0 is the first hard disk).
++
++WARNING: unless you know what you do, it is better to only make
++READ-ONLY accesses to the hard disk otherwise you may corrupt your
++host data (use the @option{-snapshot} command line so that the
++modifications are written in a temporary file).
++@end table
++
++
++@subsubsection Mac OS X
++
++@file{/dev/cdrom} is an alias to the first CDROM.
++
++Currently there is no specific code to handle removable media, so it
++is better to use the @code{change} or @code{eject} monitor commands to
++change or eject media.
++
++@node disk_images_fat_images
++@subsection Virtual FAT disk images
++
++QEMU can automatically create a virtual FAT disk image from a
++directory tree. In order to use it, just type:
++
++@example
++qemu-kvm linux.img -hdb fat:/my_directory
++@end example
++
++Then you access access to all the files in the @file{/my_directory}
++directory without having to copy them in a disk image or to export
++them via SAMBA or NFS. The default access is @emph{read-only}.
++
++Floppies can be emulated with the @code{:floppy:} option:
++
++@example
++qemu-kvm linux.img -fda fat:floppy:/my_directory
++@end example
++
++A read/write support is available for testing (beta stage) with the
++@code{:rw:} option:
++
++@example
++qemu-kvm linux.img -fda fat:floppy:rw:/my_directory
++@end example
++
++What you should @emph{never} do:
++@itemize
++@item use non-ASCII filenames ;
++@item use "-snapshot" together with ":rw:" ;
++@item expect it to work when loadvm'ing ;
++@item write to the FAT directory on the host system while accessing it with the guest system.
++@end itemize
++
++@node disk_images_nbd
++@subsection NBD access
++
++QEMU can access directly to block device exported using the Network Block Device
++protocol.
++
++@example
++qemu-kvm linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
++@end example
++
++If the NBD server is located on the same host, you can use an unix socket instead
++of an inet socket:
++
++@example
++qemu-kvm linux.img -hdb nbd+unix://?socket=/tmp/my_socket
++@end example
++
++In this case, the block device must be exported using qemu-nbd:
++
++@example
++qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
++@end example
++
++The use of qemu-nbd allows sharing of a disk between several guests:
++@example
++qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
++@end example
++
++@noindent
++and then you can use it with two guests:
++@example
++qemu-kvm linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
++qemu-kvm linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
++@end example
++
++If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
++own embedded NBD server), you must specify an export name in the URI:
++@example
++qemu-kvm -cdrom nbd://localhost/debian-500-ppc-netinst
++qemu-kvm -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
++@end example
++
++The URI syntax for NBD is supported since QEMU 1.3.  An alternative syntax is
++also available.  Here are some example of the older syntax:
++@example
++qemu-kvm linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
++qemu-kvm linux2.img -hdb nbd:unix:/tmp/my_socket
++qemu-kvm -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
++@end example
++
++@node disk_images_sheepdog
++@subsection Sheepdog disk images
++
++Sheepdog is a distributed storage system for QEMU.  It provides highly
++available block level storage volumes that can be attached to
++QEMU-based virtual machines.
++
++You can create a Sheepdog disk image with the command:
++@example
++qemu-img create sheepdog:///@var{image} @var{size}
++@end example
++where @var{image} is the Sheepdog image name and @var{size} is its
++size.
++
++To import the existing @var{filename} to Sheepdog, you can use a
++convert command.
++@example
++qemu-img convert @var{filename} sheepdog:///@var{image}
++@end example
++
++You can boot from the Sheepdog disk image with the command:
++@example
++qemu-kvm sheepdog:///@var{image}
++@end example
++
++You can also create a snapshot of the Sheepdog image like qcow2.
++@example
++qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
++@end example
++where @var{tag} is a tag name of the newly created snapshot.
++
++To boot from the Sheepdog snapshot, specify the tag name of the
++snapshot.
++@example
++qemu-kvm sheepdog:///@var{image}#@var{tag}
++@end example
++
++You can create a cloned image from the existing snapshot.
++@example
++qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
++@end example
++where @var{base} is a image name of the source snapshot and @var{tag}
++is its tag name.
++
++You can use an unix socket instead of an inet socket:
++
++@example
++qemu-kvm sheepdog+unix:///@var{image}?socket=@var{path}
++@end example
++
++If the Sheepdog daemon doesn't run on the local host, you need to
++specify one of the Sheepdog servers to connect to.
++@example
++qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
++qemu-kvm sheepdog://@var{hostname}:@var{port}/@var{image}
++@end example
++
++@node disk_images_iscsi
++@subsection iSCSI LUNs
++
++iSCSI is a popular protocol used to access SCSI devices across a computer
++network.
++
++There are two different ways iSCSI devices can be used by QEMU.
++
++The first method is to mount the iSCSI LUN on the host, and make it appear as
++any other ordinary SCSI device on the host and then to access this device as a
++/dev/sd device from QEMU. How to do this differs between host OSes.
++
++The second method involves using the iSCSI initiator that is built into
++QEMU. This provides a mechanism that works the same way regardless of which
++host OS you are running QEMU on. This section will describe this second method
++of using iSCSI together with QEMU.
++
++In QEMU, iSCSI devices are described using special iSCSI URLs
++
++@example
++URL syntax:
++iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
++@end example
++
++Username and password are optional and only used if your target is set up
++using CHAP authentication for access control.
++Alternatively the username and password can also be set via environment
++variables to have these not show up in the process list
++
++@example
++export LIBISCSI_CHAP_USERNAME=<username>
++export LIBISCSI_CHAP_PASSWORD=<password>
++iscsi://<host>/<target-iqn-name>/<lun>
++@end example
++
++Various session related parameters can be set via special options, either
++in a configuration file provided via '-readconfig' or directly on the
++command line.
++
++If the initiator-name is not specified qemu will use a default name
++of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
++virtual machine. If the UUID is not specified qemu will use
++'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
++virtual machine.
++
++@example
++Setting a specific initiator name to use when logging in to the target
++-iscsi initiator-name=iqn.qemu.test:my-initiator
++@end example
++
++@example
++Controlling which type of header digest to negotiate with the target
++-iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
++@end example
++
++These can also be set via a configuration file
++@example
++[iscsi]
++  user = "CHAP username"
++  password = "CHAP password"
++  initiator-name = "iqn.qemu.test:my-initiator"
++  # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
++  header-digest = "CRC32C"
++@end example
++
++
++Setting the target name allows different options for different targets
++@example
++[iscsi "iqn.target.name"]
++  user = "CHAP username"
++  password = "CHAP password"
++  initiator-name = "iqn.qemu.test:my-initiator"
++  # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
++  header-digest = "CRC32C"
++@end example
++
++
++Howto use a configuration file to set iSCSI configuration options:
++@example
++cat >iscsi.conf <<EOF
++[iscsi]
++  user = "me"
++  password = "my password"
++  initiator-name = "iqn.qemu.test:my-initiator"
++  header-digest = "CRC32C"
++EOF
++
++qemu-kvm -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
++    -readconfig iscsi.conf
++@end example
++
++
++Howto set up a simple iSCSI target on loopback and accessing it via QEMU:
++@example
++This example shows how to set up an iSCSI target with one CDROM and one DISK
++using the Linux STGT software target. This target is available on Red Hat based
++systems as the package 'scsi-target-utils'.
++
++tgtd --iscsi portal=127.0.0.1:3260
++tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
++tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
++    -b /IMAGES/disk.img --device-type=disk
++tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
++    -b /IMAGES/cd.iso --device-type=cd
++tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
++
++qemu-kvm -iscsi initiator-name=iqn.qemu.test:my-initiator \
++    -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
++    -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
++@end example
++
++@node disk_images_gluster
++@subsection GlusterFS disk images
++
++GlusterFS is a user space distributed file system.
++
++You can boot from the GlusterFS disk image with the command:
++@example
++URI:
++qemu-system-x86_64 -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
++                               [?socket=...][,file.debug=9][,file.logfile=...]
++
++JSON:
++qemu-system-x86_64 'json:@{"driver":"qcow2",
++                           "file":@{"driver":"gluster",
++                                    "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
++                                    "server":[@{"type":"tcp","host":"...","port":"..."@},
++                                              @{"type":"unix","socket":"..."@}]@}@}'
++@end example
++
++@var{gluster} is the protocol.
++
++@var{type} specifies the transport type used to connect to gluster
++management daemon (glusterd). Valid transport types are
++tcp and unix. In the URI form, if a transport type isn't specified,
++then tcp type is assumed.
++
++@var{host} specifies the server where the volume file specification for
++the given volume resides. This can be either a hostname or an ipv4 address.
++If transport type is unix, then @var{host} field should not be specified.
++Instead @var{socket} field needs to be populated with the path to unix domain
++socket.
++
++@var{port} is the port number on which glusterd is listening. This is optional
++and if not specified, it defaults to port 24007. If the transport type is unix,
++then @var{port} should not be specified.
++
++@var{volume} is the name of the gluster volume which contains the disk image.
++
++@var{path} is the path to the actual disk image that resides on gluster volume.
++
++@var{debug} is the logging level of the gluster protocol driver. Debug levels
++are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
++The default level is 4. The current logging levels defined in the gluster source
++are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
++6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
++
++@var{logfile} is a commandline option to mention log file path which helps in
++logging to the specified file and also help in persisting the gfapi logs. The
++default is stderr.
++
++
++
++
++You can create a GlusterFS disk image with the command:
++@example
++qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
++@end example
++
++Examples
++@example
++qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img
++qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4/testvol/a.img
++qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
++qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
++qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
++qemu-system-x86_64 -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
++qemu-system-x86_64 -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
++qemu-system-x86_64 -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
++qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
++qemu-system-x86_64 'json:@{"driver":"qcow2",
++                           "file":@{"driver":"gluster",
++                                    "volume":"testvol","path":"a.img",
++                                    "debug":9,"logfile":"/var/log/qemu-gluster.log",
++                                    "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
++                                              @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
++qemu-system-x86_64 -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
++                                       file.debug=9,file.logfile=/var/log/qemu-gluster.log,
++                                       file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
++                                       file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
++@end example
++
++@node disk_images_ssh
++@subsection Secure Shell (ssh) disk images
++
++You can access disk images located on a remote ssh server
++by using the ssh protocol:
++
++@example
++qemu-system-x86_64 -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
++@end example
++
++Alternative syntax using properties:
++
++@example
++qemu-system-x86_64 -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
++@end example
++
++@var{ssh} is the protocol.
++
++@var{user} is the remote user.  If not specified, then the local
++username is tried.
++
++@var{server} specifies the remote ssh server.  Any ssh server can be
++used, but it must implement the sftp-server protocol.  Most Unix/Linux
++systems should work without requiring any extra configuration.
++
++@var{port} is the port number on which sshd is listening.  By default
++the standard ssh port (22) is used.
++
++@var{path} is the path to the disk image.
++
++The optional @var{host_key_check} parameter controls how the remote
++host's key is checked.  The default is @code{yes} which means to use
++the local @file{.ssh/known_hosts} file.  Setting this to @code{no}
++turns off known-hosts checking.  Or you can check that the host key
++matches a specific fingerprint:
++@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
++(@code{sha1:} can also be used as a prefix, but note that OpenSSH
++tools only use MD5 to print fingerprints).
++
++Currently authentication must be done using ssh-agent.  Other
++authentication methods may be supported in future.
++
++Note: Many ssh servers do not support an @code{fsync}-style operation.
++The ssh driver cannot guarantee that disk flush requests are
++obeyed, and this causes a risk of disk corruption if the remote
++server or network goes down during writes.  The driver will
++print a warning when @code{fsync} is not supported:
++
++warning: ssh server @code{ssh.example.com:22} does not support fsync
++
++With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
++supported.
++
++@c man end
++
++@ignore
++
++@setfilename qemu-block-drivers
++@settitle QEMU block drivers reference
++
++@c man begin SEEALSO
++The HTML documentation of QEMU for more precise information and Linux
++user mode emulator invocation.
++@c man end
++
++@c man begin AUTHOR
++Fabrice Bellard and the QEMU Project developers
++@c man end
++
++@end ignore
+diff --git a/qemu-doc.texi b/qemu-doc.texi
+index db09b7e..b0db386 100644
+--- a/qemu-doc.texi
++++ b/qemu-doc.texi
+@@ -490,786 +490,7 @@ state is not saved or restored properly (in particular USB).
+ 
+ @include qemu-nbd.texi
+ 
+-@node disk_images_formats
+-@subsection Disk image file formats
+-
+-QEMU supports many image file formats that can be used with VMs as well as with
+-any of the tools (like @code{qemu-img}). This includes the preferred formats
+-raw and qcow2 as well as formats that are supported for compatibility with
+-older QEMU versions or other hypervisors.
+-
+-Depending on the image format, different options can be passed to
+-@code{qemu-img create} and @code{qemu-img convert} using the @code{-o} option.
+-This section describes each format and the options that are supported for it.
+-
+-@table @option
+-@item raw
+-
+-Raw disk image format. This format has the advantage of
+-being simple and easily exportable to all other emulators. If your
+-file system supports @emph{holes} (for example in ext2 or ext3 on
+-Linux or NTFS on Windows), then only the written sectors will reserve
+-space. Use @code{qemu-img info} to know the real size used by the
+-image or @code{ls -ls} on Unix/Linux.
+-
+-Supported options:
+-@table @code
+-@item preallocation
+-Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
+-@code{falloc} mode preallocates space for image by calling posix_fallocate().
+-@code{full} mode preallocates space for image by writing zeros to underlying
+-storage.
+-@end table
+-
+-@item qcow2
+-QEMU image format, the most versatile format. Use it to have smaller
+-images (useful if your filesystem does not supports holes, for example
+-on Windows), zlib based compression and support of multiple VM
+-snapshots.
+-
+-Supported options:
+-@table @code
+-@item compat
+-Determines the qcow2 version to use. @code{compat=0.10} uses the
+-traditional image format that can be read by any QEMU since 0.10.
+-@code{compat=1.1} enables image format extensions that only QEMU 1.1 and
+-newer understand (this is the default). Amongst others, this includes
+-zero clusters, which allow efficient copy-on-read for sparse images.
+-
+-@item backing_file
+-File name of a base image (see @option{create} subcommand)
+-@item backing_fmt
+-Image format of the base image
+-@item encryption
+-This option is deprecated and equivalent to @code{encrypt.format=aes}
+-
+-@item encrypt.format
+-
+-If this is set to @code{luks}, it requests that the qcow2 payload (not
+-qcow2 header) be encrypted using the LUKS format. The passphrase to
+-use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
+-parameter. LUKS encryption parameters can be tuned with the other
+-@code{encrypt.*} parameters.
+-
+-If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
+-The encryption key is given by the @code{encrypt.key-secret} parameter.
+-This encryption format is considered to be flawed by modern cryptography
+-standards, suffering from a number of design problems:
+-
+-@itemize @minus
+-@item The AES-CBC cipher is used with predictable initialization vectors based
+-on the sector number. This makes it vulnerable to chosen plaintext attacks
+-which can reveal the existence of encrypted data.
+-@item The user passphrase is directly used as the encryption key. A poorly
+-chosen or short passphrase will compromise the security of the encryption.
+-@item In the event of the passphrase being compromised there is no way to
+-change the passphrase to protect data in any qcow images. The files must
+-be cloned, using a different encryption passphrase in the new file. The
+-original file must then be securely erased using a program like shred,
+-though even this is ineffective with many modern storage technologies.
+-@end itemize
+-
+-The use of this is no longer supported in system emulators. Support only
+-remains in the command line utilities, for the purposes of data liberation
+-and interoperability with old versions of QEMU. The @code{luks} format
+-should be used instead.
+-
+-@item encrypt.key-secret
+-
+-Provides the ID of a @code{secret} object that contains the passphrase
+-(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
+-
+-@item encrypt.cipher-alg
+-
+-Name of the cipher algorithm and key length. Currently defaults
+-to @code{aes-256}. Only used when @code{encrypt.format=luks}.
+-
+-@item encrypt.cipher-mode
+-
+-Name of the encryption mode to use. Currently defaults to @code{xts}.
+-Only used when @code{encrypt.format=luks}.
+-
+-@item encrypt.ivgen-alg
+-
+-Name of the initialization vector generator algorithm. Currently defaults
+-to @code{plain64}. Only used when @code{encrypt.format=luks}.
+-
+-@item encrypt.ivgen-hash-alg
+-
+-Name of the hash algorithm to use with the initialization vector generator
+-(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
+-
+-@item encrypt.hash-alg
+-
+-Name of the hash algorithm to use for PBKDF algorithm
+-Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
+-
+-@item encrypt.iter-time
+-
+-Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
+-Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
+-
+-@item cluster_size
+-Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
+-sizes can improve the image file size whereas larger cluster sizes generally
+-provide better performance.
+-
+-@item preallocation
+-Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
+-@code{full}). An image with preallocated metadata is initially larger but can
+-improve performance when the image needs to grow. @code{falloc} and @code{full}
+-preallocations are like the same options of @code{raw} format, but sets up
+-metadata also.
+-
+-@item lazy_refcounts
+-If this option is set to @code{on}, reference count updates are postponed with
+-the goal of avoiding metadata I/O and improving performance. This is
+-particularly interesting with @option{cache=writethrough} which doesn't batch
+-metadata updates. The tradeoff is that after a host crash, the reference count
+-tables must be rebuilt, i.e. on the next open an (automatic) @code{qemu-img
+-check -r all} is required, which may take some time.
+-
+-This option can only be enabled if @code{compat=1.1} is specified.
+-
+-@item nocow
+-If this option is set to @code{on}, it will turn off COW of the file. It's only
+-valid on btrfs, no effect on other file systems.
+-
+-Btrfs has low performance when hosting a VM image file, even more when the guest
+-on the VM also using btrfs as file system. Turning off COW is a way to mitigate
+-this bad performance. Generally there are two ways to turn off COW on btrfs:
+-a) Disable it by mounting with nodatacow, then all newly created files will be
+-NOCOW. b) For an empty file, add the NOCOW file attribute. That's what this option
+-does.
+-
+-Note: this option is only valid to new or empty files. If there is an existing
+-file which is COW and has data blocks already, it couldn't be changed to NOCOW
+-by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
+-the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
+-
+-@end table
+-
+-@item qed
+-Old QEMU image format with support for backing files and compact image files
+-(when your filesystem or transport medium does not support holes).
+-
+-When converting QED images to qcow2, you might want to consider using the
+-@code{lazy_refcounts=on} option to get a more QED-like behaviour.
+-
+-Supported options:
+-@table @code
+-@item backing_file
+-File name of a base image (see @option{create} subcommand).
+-@item backing_fmt
+-Image file format of backing file (optional).  Useful if the format cannot be
+-autodetected because it has no header, like some vhd/vpc files.
+-@item cluster_size
+-Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
+-cluster sizes can improve the image file size whereas larger cluster sizes
+-generally provide better performance.
+-@item table_size
+-Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
+-and 16).  There is normally no need to change this value but this option can be
+-used for performance benchmarking.
+-@end table
+-
+-@item qcow
+-Old QEMU image format with support for backing files, compact image files,
+-encryption and compression.
+-
+-Supported options:
+-@table @code
+-@item backing_file
+-File name of a base image (see @option{create} subcommand)
+-@item encryption
+-This option is deprecated and equivalent to @code{encrypt.format=aes}
+-
+-@item encrypt.format
+-If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
+-The encryption key is given by the @code{encrypt.key-secret} parameter.
+-This encryption format is considered to be flawed by modern cryptography
+-standards, suffering from a number of design problems enumerated previously
+-against the @code{qcow2} image format.
+-
+-The use of this is no longer supported in system emulators. Support only
+-remains in the command line utilities, for the purposes of data liberation
+-and interoperability with old versions of QEMU.
+-
+-Users requiring native encryption should use the @code{qcow2} format
+-instead with @code{encrypt.format=luks}.
+-
+-@item encrypt.key-secret
+-
+-Provides the ID of a @code{secret} object that contains the encryption
+-key (@code{encrypt.format=aes}).
+-
+-@end table
+-
+-@item luks
+-
+-LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
+-
+-Supported options:
+-@table @code
+-
+-@item key-secret
+-
+-Provides the ID of a @code{secret} object that contains the passphrase.
+-
+-@item cipher-alg
+-
+-Name of the cipher algorithm and key length. Currently defaults
+-to @code{aes-256}.
+-
+-@item cipher-mode
+-
+-Name of the encryption mode to use. Currently defaults to @code{xts}.
+-
+-@item ivgen-alg
+-
+-Name of the initialization vector generator algorithm. Currently defaults
+-to @code{plain64}.
+-
+-@item ivgen-hash-alg
+-
+-Name of the hash algorithm to use with the initialization vector generator
+-(if required). Defaults to @code{sha256}.
+-
+-@item hash-alg
+-
+-Name of the hash algorithm to use for PBKDF algorithm
+-Defaults to @code{sha256}.
+-
+-@item iter-time
+-
+-Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
+-Defaults to @code{2000}.
+-
+-@end table
+-
+-@item vdi
+-VirtualBox 1.1 compatible image format.
+-Supported options:
+-@table @code
+-@item static
+-If this option is set to @code{on}, the image is created with metadata
+-preallocation.
+-@end table
+-
+-@item vmdk
+-VMware 3 and 4 compatible image format.
+-
+-Supported options:
+-@table @code
+-@item backing_file
+-File name of a base image (see @option{create} subcommand).
+-@item compat6
+-Create a VMDK version 6 image (instead of version 4)
+-@item hwversion
+-Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
+-if hwversion is specified.
+-@item subformat
+-Specifies which VMDK subformat to use. Valid options are
+-@code{monolithicSparse} (default),
+-@code{monolithicFlat},
+-@code{twoGbMaxExtentSparse},
+-@code{twoGbMaxExtentFlat} and
+-@code{streamOptimized}.
+-@end table
+-
+-@item vpc
+-VirtualPC compatible image format (VHD).
+-Supported options:
+-@table @code
+-@item subformat
+-Specifies which VHD subformat to use. Valid options are
+-@code{dynamic} (default) and @code{fixed}.
+-@end table
+-
+-@item VHDX
+-Hyper-V compatible image format (VHDX).
+-Supported options:
+-@table @code
+-@item subformat
+-Specifies which VHDX subformat to use. Valid options are
+-@code{dynamic} (default) and @code{fixed}.
+-@item block_state_zero
+-Force use of payload blocks of type 'ZERO'.  Can be set to @code{on} (default)
+-or @code{off}.  When set to @code{off}, new blocks will be created as
+-@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
+-arbitrary data for those blocks.  Do not set to @code{off} when using
+-@code{qemu-img convert} with @code{subformat=dynamic}.
+-@item block_size
+-Block size; min 1 MB, max 256 MB.  0 means auto-calculate based on image size.
+-@item log_size
+-Log size; min 1 MB.
+-@end table
+-@end table
+-
+-@subsubsection Read-only formats
+-More disk image file formats are supported in a read-only mode.
+-@table @option
+-@item bochs
+-Bochs images of @code{growing} type.
+-@item cloop
+-Linux Compressed Loop image, useful only to reuse directly compressed
+-CD-ROM images present for example in the Knoppix CD-ROMs.
+-@item dmg
+-Apple disk image.
+-@item parallels
+-Parallels disk image format.
+-@end table
+-
+-
+-@node host_drives
+-@subsection Using host drives
+-
+-In addition to disk image files, QEMU can directly access host
+-devices. We describe here the usage for QEMU version >= 0.8.3.
+-
+-@subsubsection Linux
+-
+-On Linux, you can directly use the host device filename instead of a
+-disk image filename provided you have enough privileges to access
+-it. For example, use @file{/dev/cdrom} to access to the CDROM.
+-
+-@table @code
+-@item CD
+-You can specify a CDROM device even if no CDROM is loaded. QEMU has
+-specific code to detect CDROM insertion or removal. CDROM ejection by
+-the guest OS is supported. Currently only data CDs are supported.
+-@item Floppy
+-You can specify a floppy device even if no floppy is loaded. Floppy
+-removal is currently not detected accurately (if you change floppy
+-without doing floppy access while the floppy is not loaded, the guest
+-OS will think that the same floppy is loaded).
+-Use of the host's floppy device is deprecated, and support for it will
+-be removed in a future release.
+-@item Hard disks
+-Hard disks can be used. Normally you must specify the whole disk
+-(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
+-see it as a partitioned disk. WARNING: unless you know what you do, it
+-is better to only make READ-ONLY accesses to the hard disk otherwise
+-you may corrupt your host data (use the @option{-snapshot} command
+-line option or modify the device permissions accordingly).
+-@end table
+-
+-@subsubsection Windows
+-
+-@table @code
+-@item CD
+-The preferred syntax is the drive letter (e.g. @file{d:}). The
+-alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
+-supported as an alias to the first CDROM drive.
+-
+-Currently there is no specific code to handle removable media, so it
+-is better to use the @code{change} or @code{eject} monitor commands to
+-change or eject media.
+-@item Hard disks
+-Hard disks can be used with the syntax: @file{\\.\PhysicalDrive@var{N}}
+-where @var{N} is the drive number (0 is the first hard disk).
+-
+-WARNING: unless you know what you do, it is better to only make
+-READ-ONLY accesses to the hard disk otherwise you may corrupt your
+-host data (use the @option{-snapshot} command line so that the
+-modifications are written in a temporary file).
+-@end table
+-
+-
+-@subsubsection Mac OS X
+-
+-@file{/dev/cdrom} is an alias to the first CDROM.
+-
+-Currently there is no specific code to handle removable media, so it
+-is better to use the @code{change} or @code{eject} monitor commands to
+-change or eject media.
+-
+-@node disk_images_fat_images
+-@subsection Virtual FAT disk images
+-
+-QEMU can automatically create a virtual FAT disk image from a
+-directory tree. In order to use it, just type:
+-
+-@example
+-qemu-kvm linux.img -hdb fat:/my_directory
+-@end example
+-
+-Then you access access to all the files in the @file{/my_directory}
+-directory without having to copy them in a disk image or to export
+-them via SAMBA or NFS. The default access is @emph{read-only}.
+-
+-Floppies can be emulated with the @code{:floppy:} option:
+-
+-@example
+-qemu-kvm linux.img -fda fat:floppy:/my_directory
+-@end example
+-
+-A read/write support is available for testing (beta stage) with the
+-@code{:rw:} option:
+-
+-@example
+-qemu-kvm linux.img -fda fat:floppy:rw:/my_directory
+-@end example
+-
+-What you should @emph{never} do:
+-@itemize
+-@item use non-ASCII filenames ;
+-@item use "-snapshot" together with ":rw:" ;
+-@item expect it to work when loadvm'ing ;
+-@item write to the FAT directory on the host system while accessing it with the guest system.
+-@end itemize
+-
+-@node disk_images_nbd
+-@subsection NBD access
+-
+-QEMU can access directly to block device exported using the Network Block Device
+-protocol.
+-
+-@example
+-qemu-kvm linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
+-@end example
+-
+-If the NBD server is located on the same host, you can use an unix socket instead
+-of an inet socket:
+-
+-@example
+-qemu-kvm linux.img -hdb nbd+unix://?socket=/tmp/my_socket
+-@end example
+-
+-In this case, the block device must be exported using qemu-nbd:
+-
+-@example
+-qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
+-@end example
+-
+-The use of qemu-nbd allows sharing of a disk between several guests:
+-@example
+-qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
+-@end example
+-
+-@noindent
+-and then you can use it with two guests:
+-@example
+-qemu-kvm linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
+-qemu-kvm linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
+-@end example
+-
+-If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
+-own embedded NBD server), you must specify an export name in the URI:
+-@example
+-qemu-kvm -cdrom nbd://localhost/debian-500-ppc-netinst
+-qemu-kvm -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
+-@end example
+-
+-The URI syntax for NBD is supported since QEMU 1.3.  An alternative syntax is
+-also available.  Here are some example of the older syntax:
+-@example
+-qemu-kvm linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
+-qemu-kvm linux2.img -hdb nbd:unix:/tmp/my_socket
+-qemu-kvm -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
+-@end example
+-
+-@node disk_images_sheepdog
+-@subsection Sheepdog disk images
+-
+-Sheepdog is a distributed storage system for QEMU.  It provides highly
+-available block level storage volumes that can be attached to
+-QEMU-based virtual machines.
+-
+-You can create a Sheepdog disk image with the command:
+-@example
+-qemu-img create sheepdog:///@var{image} @var{size}
+-@end example
+-where @var{image} is the Sheepdog image name and @var{size} is its
+-size.
+-
+-To import the existing @var{filename} to Sheepdog, you can use a
+-convert command.
+-@example
+-qemu-img convert @var{filename} sheepdog:///@var{image}
+-@end example
+-
+-You can boot from the Sheepdog disk image with the command:
+-@example
+-qemu-kvm sheepdog:///@var{image}
+-@end example
+-
+-You can also create a snapshot of the Sheepdog image like qcow2.
+-@example
+-qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
+-@end example
+-where @var{tag} is a tag name of the newly created snapshot.
+-
+-To boot from the Sheepdog snapshot, specify the tag name of the
+-snapshot.
+-@example
+-qemu-kvm sheepdog:///@var{image}#@var{tag}
+-@end example
+-
+-You can create a cloned image from the existing snapshot.
+-@example
+-qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
+-@end example
+-where @var{base} is a image name of the source snapshot and @var{tag}
+-is its tag name.
+-
+-You can use an unix socket instead of an inet socket:
+-
+-@example
+-qemu-kvm sheepdog+unix:///@var{image}?socket=@var{path}
+-@end example
+-
+-If the Sheepdog daemon doesn't run on the local host, you need to
+-specify one of the Sheepdog servers to connect to.
+-@example
+-qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
+-qemu-kvm sheepdog://@var{hostname}:@var{port}/@var{image}
+-@end example
+-
+-@node disk_images_iscsi
+-@subsection iSCSI LUNs
+-
+-iSCSI is a popular protocol used to access SCSI devices across a computer
+-network.
+-
+-There are two different ways iSCSI devices can be used by QEMU.
+-
+-The first method is to mount the iSCSI LUN on the host, and make it appear as
+-any other ordinary SCSI device on the host and then to access this device as a
+-/dev/sd device from QEMU. How to do this differs between host OSes.
+-
+-The second method involves using the iSCSI initiator that is built into
+-QEMU. This provides a mechanism that works the same way regardless of which
+-host OS you are running QEMU on. This section will describe this second method
+-of using iSCSI together with QEMU.
+-
+-In QEMU, iSCSI devices are described using special iSCSI URLs
+-
+-@example
+-URL syntax:
+-iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
+-@end example
+-
+-Username and password are optional and only used if your target is set up
+-using CHAP authentication for access control.
+-Alternatively the username and password can also be set via environment
+-variables to have these not show up in the process list
+-
+-@example
+-export LIBISCSI_CHAP_USERNAME=<username>
+-export LIBISCSI_CHAP_PASSWORD=<password>
+-iscsi://<host>/<target-iqn-name>/<lun>
+-@end example
+-
+-Various session related parameters can be set via special options, either
+-in a configuration file provided via '-readconfig' or directly on the
+-command line.
+-
+-If the initiator-name is not specified qemu-kvm will use a default name
+-of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
+-virtual machine. If the UUID is not specified qemu will use
+-'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
+-virtual machine.
+-
+-@example
+-Setting a specific initiator name to use when logging in to the target
+--iscsi initiator-name=iqn.qemu.test:my-initiator
+-@end example
+-
+-@example
+-Controlling which type of header digest to negotiate with the target
+--iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
+-@end example
+-
+-These can also be set via a configuration file
+-@example
+-[iscsi]
+-  user = "CHAP username"
+-  password = "CHAP password"
+-  initiator-name = "iqn.qemu.test:my-initiator"
+-  # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
+-  header-digest = "CRC32C"
+-@end example
+-
+-
+-Setting the target name allows different options for different targets
+-@example
+-[iscsi "iqn.target.name"]
+-  user = "CHAP username"
+-  password = "CHAP password"
+-  initiator-name = "iqn.qemu.test:my-initiator"
+-  # header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
+-  header-digest = "CRC32C"
+-@end example
+-
+-
+-Howto use a configuration file to set iSCSI configuration options:
+-@example
+-cat >iscsi.conf <<EOF
+-[iscsi]
+-  user = "me"
+-  password = "my password"
+-  initiator-name = "iqn.qemu.test:my-initiator"
+-  header-digest = "CRC32C"
+-EOF
+-
+-qemu-kvm -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
+-    -readconfig iscsi.conf
+-@end example
+-
+-
+-Howto set up a simple iSCSI target on loopback and accessing it via QEMU:
+-@example
+-This example shows how to set up an iSCSI target with one CDROM and one DISK
+-using the Linux STGT software target. This target is available on Red Hat based
+-systems as the package 'scsi-target-utils'.
+-
+-tgtd --iscsi portal=127.0.0.1:3260
+-tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
+-tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
+-    -b /IMAGES/disk.img --device-type=disk
+-tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
+-    -b /IMAGES/cd.iso --device-type=cd
+-tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
+-
+-qemu-kvm -iscsi initiator-name=iqn.qemu.test:my-initiator \
+-    -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
+-    -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
+-@end example
+-
+-@node disk_images_gluster
+-@subsection GlusterFS disk images
+-
+-GlusterFS is a user space distributed file system.
+-
+-You can boot from the GlusterFS disk image with the command:
+-@example
+-URI:
+-qemu-kvm -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
+-                               [?socket=...][,file.debug=9][,file.logfile=...]
+-
+-JSON:
+-qemu-kvm 'json:@{"driver":"qcow2",
+-                           "file":@{"driver":"gluster",
+-                                    "volume":"testvol","path":"a.img","debug":9,"logfile":"...",
+-                                    "server":[@{"type":"tcp","host":"...","port":"..."@},
+-                                              @{"type":"unix","socket":"..."@}]@}@}'
+-@end example
+-
+-@var{gluster} is the protocol.
+-
+-@var{type} specifies the transport type used to connect to gluster
+-management daemon (glusterd). Valid transport types are
+-tcp and unix. In the URI form, if a transport type isn't specified,
+-then tcp type is assumed.
+-
+-@var{host} specifies the server where the volume file specification for
+-the given volume resides. This can be either a hostname or an ipv4 address.
+-If transport type is unix, then @var{host} field should not be specified.
+-Instead @var{socket} field needs to be populated with the path to unix domain
+-socket.
+-
+-@var{port} is the port number on which glusterd is listening. This is optional
+-and if not specified, it defaults to port 24007. If the transport type is unix,
+-then @var{port} should not be specified.
+-
+-@var{volume} is the name of the gluster volume which contains the disk image.
+-
+-@var{path} is the path to the actual disk image that resides on gluster volume.
+-
+-@var{debug} is the logging level of the gluster protocol driver. Debug levels
+-are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
+-The default level is 4. The current logging levels defined in the gluster source
+-are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
+-6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
+-
+-@var{logfile} is a commandline option to mention log file path which helps in
+-logging to the specified file and also help in persisting the gfapi logs. The
+-default is stderr.
+-
+-
+-
+-
+-You can create a GlusterFS disk image with the command:
+-@example
+-qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
+-@end example
+-
+-Examples
+-@example
+-qemu-kvm -drive file=gluster://1.2.3.4/testvol/a.img
+-qemu-kvm -drive file=gluster+tcp://1.2.3.4/testvol/a.img
+-qemu-kvm -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
+-qemu-kvm -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
+-qemu-kvm -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
+-qemu-kvm -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
+-qemu-kvm -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
+-qemu-kvm -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
+-qemu-kvm -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
+-qemu-kvm 'json:@{"driver":"qcow2",
+-                           "file":@{"driver":"gluster",
+-                                    "volume":"testvol","path":"a.img",
+-                                    "debug":9,"logfile":"/var/log/qemu-gluster.log",
+-                                    "server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
+-                                              @{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
+-qemu-kvm -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
+-                                       file.debug=9,file.logfile=/var/log/qemu-gluster.log,
+-                                       file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
+-                                       file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
+-@end example
+-
+-@node disk_images_ssh
+-@subsection Secure Shell (ssh) disk images
+-
+-You can access disk images located on a remote ssh server
+-by using the ssh protocol:
+-
+-@example
+-qemu-kvm -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
+-@end example
+-
+-Alternative syntax using properties:
+-
+-@example
+-qemu-kvm -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
+-@end example
+-
+-@var{ssh} is the protocol.
+-
+-@var{user} is the remote user.  If not specified, then the local
+-username is tried.
+-
+-@var{server} specifies the remote ssh server.  Any ssh server can be
+-used, but it must implement the sftp-server protocol.  Most Unix/Linux
+-systems should work without requiring any extra configuration.
+-
+-@var{port} is the port number on which sshd is listening.  By default
+-the standard ssh port (22) is used.
+-
+-@var{path} is the path to the disk image.
+-
+-The optional @var{host_key_check} parameter controls how the remote
+-host's key is checked.  The default is @code{yes} which means to use
+-the local @file{.ssh/known_hosts} file.  Setting this to @code{no}
+-turns off known-hosts checking.  Or you can check that the host key
+-matches a specific fingerprint:
+-@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
+-(@code{sha1:} can also be used as a prefix, but note that OpenSSH
+-tools only use MD5 to print fingerprints).
+-
+-Currently authentication must be done using ssh-agent.  Other
+-authentication methods may be supported in future.
+-
+-Note: Many ssh servers do not support an @code{fsync}-style operation.
+-The ssh driver cannot guarantee that disk flush requests are
+-obeyed, and this causes a risk of disk corruption if the remote
+-server or network goes down during writes.  The driver will
+-print a warning when @code{fsync} is not supported:
+-
+-warning: ssh server @code{ssh.example.com:22} does not support fsync
+-
+-With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
+-supported.
++@include docs/qemu-block-drivers.texi
+ 
+ @node pcsys_network
+ @section Network emulation
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-dump-add-guest-ELF-note.patch b/SOURCES/kvm-dump-add-guest-ELF-note.patch
new file mode 100644
index 0000000..514604a
--- /dev/null
+++ b/SOURCES/kvm-dump-add-guest-ELF-note.patch
@@ -0,0 +1,223 @@
+From 93d31dbfbf412b8a80d364aac0ff6f5f319e831c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:06 +0100
+Subject: [PATCH 08/21] dump: add guest ELF note
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-5-marcandre.lureau@redhat.com>
+Patchwork-id: 77925
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 4/9] dump: add guest ELF note
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Read the guest ELF PT_NOTE from guest memory when fw_cfg
+etc/vmcoreinfo entry provides the location, and write it as an
+additional note in the dump.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit 903ef7349699dcd932b5981b85c1f1ebe4a4bf2a)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ dump.c                | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/sysemu/dump.h |   2 +
+ 2 files changed, 109 insertions(+)
+
+diff --git a/dump.c b/dump.c
+index 99117ba..a4f175d 100644
+--- a/dump.c
++++ b/dump.c
+@@ -26,6 +26,8 @@
+ #include "qapi/qmp/qerror.h"
+ #include "qmp-commands.h"
+ #include "qapi-event.h"
++#include "qemu/error-report.h"
++#include "hw/misc/vmcoreinfo.h"
+ 
+ #include <zlib.h>
+ #ifdef CONFIG_LZO
+@@ -38,6 +40,13 @@
+ #define ELF_MACHINE_UNAME "Unknown"
+ #endif
+ 
++#define MAX_GUEST_NOTE_SIZE (1 << 20) /* 1MB should be enough */
++
++#define ELF_NOTE_SIZE(hdr_size, name_size, desc_size)   \
++    ((DIV_ROUND_UP((hdr_size), 4) +                     \
++      DIV_ROUND_UP((name_size), 4) +                    \
++      DIV_ROUND_UP((desc_size), 4)) * 4)
++
+ uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
+ {
+     if (s->dump_info.d_endian == ELFDATA2LSB) {
+@@ -76,6 +85,8 @@ static int dump_cleanup(DumpState *s)
+     guest_phys_blocks_free(&s->guest_phys_blocks);
+     memory_mapping_list_free(&s->list);
+     close(s->fd);
++    g_free(s->guest_note);
++    s->guest_note = NULL;
+     if (s->resume) {
+         if (s->detached) {
+             qemu_mutex_lock_iothread();
+@@ -235,6 +246,19 @@ static inline int cpu_index(CPUState *cpu)
+     return cpu->cpu_index + 1;
+ }
+ 
++static void write_guest_note(WriteCoreDumpFunction f, DumpState *s,
++                             Error **errp)
++{
++    int ret;
++
++    if (s->guest_note) {
++        ret = f(s->guest_note, s->guest_note_size, s);
++        if (ret < 0) {
++            error_setg(errp, "dump: failed to write guest note");
++        }
++    }
++}
++
+ static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
+                               Error **errp)
+ {
+@@ -258,6 +282,8 @@ static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
+             return;
+         }
+     }
++
++    write_guest_note(f, s, errp);
+ }
+ 
+ static void write_elf32_note(DumpState *s, Error **errp)
+@@ -303,6 +329,8 @@ static void write_elf32_notes(WriteCoreDumpFunction f, DumpState *s,
+             return;
+         }
+     }
++
++    write_guest_note(f, s, errp);
+ }
+ 
+ static void write_elf_section(DumpState *s, int type, Error **errp)
+@@ -714,6 +742,44 @@ static int buf_write_note(const void *buf, size_t size, void *opaque)
+     return 0;
+ }
+ 
++/*
++ * This function retrieves various sizes from an elf header.
++ *
++ * @note has to be a valid ELF note. The return sizes are unmodified
++ * (not padded or rounded up to be multiple of 4).
++ */
++static void get_note_sizes(DumpState *s, const void *note,
++                           uint64_t *note_head_size,
++                           uint64_t *name_size,
++                           uint64_t *desc_size)
++{
++    uint64_t note_head_sz;
++    uint64_t name_sz;
++    uint64_t desc_sz;
++
++    if (s->dump_info.d_class == ELFCLASS64) {
++        const Elf64_Nhdr *hdr = note;
++        note_head_sz = sizeof(Elf64_Nhdr);
++        name_sz = tswap64(hdr->n_namesz);
++        desc_sz = tswap64(hdr->n_descsz);
++    } else {
++        const Elf32_Nhdr *hdr = note;
++        note_head_sz = sizeof(Elf32_Nhdr);
++        name_sz = tswap32(hdr->n_namesz);
++        desc_sz = tswap32(hdr->n_descsz);
++    }
++
++    if (note_head_size) {
++        *note_head_size = note_head_sz;
++    }
++    if (name_size) {
++        *name_size = name_sz;
++    }
++    if (desc_size) {
++        *desc_size = desc_sz;
++    }
++}
++
+ /* write common header, sub header and elf note to vmcore */
+ static void create_header32(DumpState *s, Error **errp)
+ {
+@@ -1492,6 +1558,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
+                       DumpGuestMemoryFormat format, bool paging, bool has_filter,
+                       int64_t begin, int64_t length, Error **errp)
+ {
++    VMCoreInfoState *vmci = vmcoreinfo_find();
+     CPUState *cpu;
+     int nr_cpus;
+     Error *err = NULL;
+@@ -1569,6 +1636,46 @@ static void dump_init(DumpState *s, int fd, bool has_format,
+         goto cleanup;
+     }
+ 
++    /*
++     * The goal of this block is to copy the guest note out of
++     * the guest.  Failure to do so is not fatal for dumping.
++     */
++    if (vmci) {
++        uint64_t addr, note_head_size, name_size, desc_size;
++        uint32_t size;
++        uint16_t format;
++
++        note_head_size = s->dump_info.d_class == ELFCLASS32 ?
++            sizeof(Elf32_Nhdr) : sizeof(Elf64_Nhdr);
++
++        format = le16_to_cpu(vmci->vmcoreinfo.guest_format);
++        size = le32_to_cpu(vmci->vmcoreinfo.size);
++        addr = le64_to_cpu(vmci->vmcoreinfo.paddr);
++        if (!vmci->has_vmcoreinfo) {
++            warn_report("guest note is not present");
++        } else if (size < note_head_size || size > MAX_GUEST_NOTE_SIZE) {
++            warn_report("guest note size is invalid: %" PRIu32, size);
++        } else if (format != VMCOREINFO_FORMAT_ELF) {
++            warn_report("guest note format is unsupported: %" PRIu16, format);
++        } else {
++            s->guest_note = g_malloc(size + 1); /* +1 for adding \0 */
++            cpu_physical_memory_read(addr, s->guest_note, size);
++
++            get_note_sizes(s, s->guest_note, NULL, &name_size, &desc_size);
++            s->guest_note_size = ELF_NOTE_SIZE(note_head_size, name_size,
++                                               desc_size);
++            if (name_size > MAX_GUEST_NOTE_SIZE ||
++                desc_size > MAX_GUEST_NOTE_SIZE ||
++                s->guest_note_size > size) {
++                warn_report("Invalid guest note header");
++                g_free(s->guest_note);
++                s->guest_note = NULL;
++            } else {
++                s->note_size += s->guest_note_size;
++            }
++        }
++    }
++
+     /* get memory mapping */
+     if (paging) {
+         qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);
+diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
+index 2672a15..df43bd0 100644
+--- a/include/sysemu/dump.h
++++ b/include/sysemu/dump.h
+@@ -192,6 +192,8 @@ typedef struct DumpState {
+                                   * this could be used to calculate
+                                   * how much work we have
+                                   * finished. */
++    uint8_t *guest_note;         /* ELF note content */
++    size_t guest_note_size;
+ } DumpState;
+ 
+ uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-dump-guest-memory.py-fix-No-symbol-vmcoreinfo_find.patch b/SOURCES/kvm-dump-guest-memory.py-fix-No-symbol-vmcoreinfo_find.patch
new file mode 100644
index 0000000..4e2986e
--- /dev/null
+++ b/SOURCES/kvm-dump-guest-memory.py-fix-No-symbol-vmcoreinfo_find.patch
@@ -0,0 +1,65 @@
+From af7952afccf368763122322931a603bfd4443471 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Tue, 5 Dec 2017 14:29:30 +0100
+Subject: [PATCH 18/21] dump-guest-memory.py: fix No symbol "vmcoreinfo_find"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171205142930.5499-1-marcandre.lureau@redhat.com>
+Patchwork-id: 78143
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] dump-guest-memory.py: fix No symbol "vmcoreinfo_find"
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+When qemu is compiled without debug, the dump gdb python script can fail with:
+
+Error occurred in Python command: No symbol "vmcoreinfo_find" in current context.
+
+Because vmcoreinfo_find() is inlined and not exported.
+
+Use the underlying object_resolve_path_type() to get the instance instead.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit d36d0a9d152316a41e02c2613a71f5859f407da1)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/dump-guest-memory.py | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
+index 69dd5ef..1af26c1 100644
+--- a/scripts/dump-guest-memory.py
++++ b/scripts/dump-guest-memory.py
+@@ -546,13 +546,15 @@ shape and this command should mostly work."""
+         return None
+ 
+     def add_vmcoreinfo(self):
+-        if not gdb.parse_and_eval("vmcoreinfo_find()") \
+-           or not gdb.parse_and_eval("vmcoreinfo_find()->has_vmcoreinfo"):
++        vmci = '(VMCoreInfoState *)' + \
++               'object_resolve_path_type("", "vmcoreinfo", 0)'
++        if not gdb.parse_and_eval("%s" % vmci) \
++           or not gdb.parse_and_eval("(%s)->has_vmcoreinfo" % vmci):
+             return
+ 
+-        fmt = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.guest_format")
+-        addr = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.paddr")
+-        size = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.size")
++        fmt = gdb.parse_and_eval("(%s)->vmcoreinfo.guest_format" % vmci)
++        addr = gdb.parse_and_eval("(%s)->vmcoreinfo.paddr" % vmci)
++        size = gdb.parse_and_eval("(%s)->vmcoreinfo.size" % vmci)
+ 
+         fmt = le16_to_cpu(fmt)
+         addr = le64_to_cpu(addr)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-dump-guest-memory.py-fix-You-can-t-do-that-without-a.patch b/SOURCES/kvm-dump-guest-memory.py-fix-You-can-t-do-that-without-a.patch
new file mode 100644
index 0000000..6a5dbab
--- /dev/null
+++ b/SOURCES/kvm-dump-guest-memory.py-fix-You-can-t-do-that-without-a.patch
@@ -0,0 +1,92 @@
+From 6a2b7d555d46c05b0ca334f8fd6511e134e3220c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Tue, 9 Jan 2018 12:52:04 +0100
+Subject: [PATCH 04/12] dump-guest-memory.py: fix "You can't do that without a
+ process to debug"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20180109125204.4313-1-marcandre.lureau@redhat.com>
+Patchwork-id: 78534
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] dump-guest-memory.py: fix "You can't do that without a process to debug"
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+If the script is run with a core (no running process), it produces an
+error:
+
+(gdb)  dump-guest-memory /tmp/vmcore X86_64
+guest RAM blocks:
+target_start     target_end       host_addr        message count
+---------------- ---------------- ---------------- ------- -----
+0000000000000000 00000000000a0000 00007f7935800000 added       1
+00000000000a0000 00000000000b0000 00007f7934200000 added       2
+00000000000c0000 00000000000ca000 00007f79358c0000 added       3
+00000000000ca000 00000000000cd000 00007f79358ca000 joined      3
+00000000000cd000 00000000000e8000 00007f79358cd000 joined      3
+00000000000e8000 00000000000f0000 00007f79358e8000 joined      3
+00000000000f0000 0000000000100000 00007f79358f0000 joined      3
+0000000000100000 0000000080000000 00007f7935900000 joined      3
+00000000fd000000 00000000fe000000 00007f7934200000 added       4
+00000000fffc0000 0000000100000000 00007f7935600000 added       5
+Python Exception <class 'gdb.error'> You can't do that without a process to debug.:
+Error occurred in Python command: You can't do that without a process
+to debug.
+
+Replace the object_resolve_path_type() function call with a local
+volatile variable.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+
+(cherry picked from commit c3b1642b9b6b3ba4314d6be3be509d396372cfd5)
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/misc/vmcoreinfo.c         | 3 +++
+ scripts/dump-guest-memory.py | 3 +--
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c
+index 31db57a..a280552 100644
+--- a/hw/misc/vmcoreinfo.c
++++ b/hw/misc/vmcoreinfo.c
+@@ -35,6 +35,8 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
+ {
+     VMCoreInfoState *s = VMCOREINFO(dev);
+     FWCfgState *fw_cfg = fw_cfg_find();
++    /* for gdb script dump-guest-memory.py */
++    static VMCoreInfoState * volatile vmcoreinfo_state G_GNUC_UNUSED;
+ 
+     /* Given that this function is executing, there is at least one VMCOREINFO
+      * device. Check if there are several.
+@@ -56,6 +58,7 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
+                              &s->vmcoreinfo, sizeof(s->vmcoreinfo), false);
+ 
+     qemu_register_reset(vmcoreinfo_reset, dev);
++    vmcoreinfo_state = s;
+ }
+ 
+ static const VMStateDescription vmstate_vmcoreinfo = {
+diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
+index 1af26c1..09bec92 100644
+--- a/scripts/dump-guest-memory.py
++++ b/scripts/dump-guest-memory.py
+@@ -546,8 +546,7 @@ shape and this command should mostly work."""
+         return None
+ 
+     def add_vmcoreinfo(self):
+-        vmci = '(VMCoreInfoState *)' + \
+-               'object_resolve_path_type("", "vmcoreinfo", 0)'
++        vmci = 'vmcoreinfo_realize::vmcoreinfo_state'
+         if not gdb.parse_and_eval("%s" % vmci) \
+            or not gdb.parse_and_eval("(%s)->has_vmcoreinfo" % vmci):
+             return
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-dump-guest-memory.py-fix-python-2-support.patch b/SOURCES/kvm-dump-guest-memory.py-fix-python-2-support.patch
new file mode 100644
index 0000000..b764e55
--- /dev/null
+++ b/SOURCES/kvm-dump-guest-memory.py-fix-python-2-support.patch
@@ -0,0 +1,58 @@
+From f342adbebaff74bae55e4ebb681683d951ba61a2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 22 Jan 2018 13:51:41 +0100
+Subject: [PATCH 20/21] dump-guest-memory.py: fix python 2 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20180122135141.11068-1-marcandre.lureau@redhat.com>
+Patchwork-id: 78691
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] dump-guest-memory.py: fix python 2 support
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Python GDB support may use Python 2 or 3.
+
+Inferior.read_memory() may return a 'buffer' with Python 2 or a
+'memoryview' with Python 3 (see also
+https://sourceware.org/gdb/onlinedocs/gdb/Inferiors-In-Python.html)
+
+The elf.add_vmcoreinfo_note() method expects a "bytes" object. Wrap
+the returned memory with bytes(), which works with both 'memoryview'
+and 'buffer'.
+
+Fixes a regression introduced with commit
+d23bfa91b7789534d16ede6cb7d925bfac3f3c4c ("add vmcoreinfo").
+
+Suggested-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Acked-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+
+(cherry picked from commit 6f49ec4034e55dfb675a56a62c9579384f7fb8cc)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/dump-guest-memory.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
+index 09bec92..03fbf69 100644
+--- a/scripts/dump-guest-memory.py
++++ b/scripts/dump-guest-memory.py
+@@ -564,7 +564,7 @@ shape and this command should mostly work."""
+ 
+         vmcoreinfo = self.phys_memory_read(addr, size)
+         if vmcoreinfo:
+-            self.elf.add_vmcoreinfo_note(vmcoreinfo.tobytes())
++            self.elf.add_vmcoreinfo_note(bytes(vmcoreinfo))
+ 
+     def invoke(self, args, from_tty):
+         """Handles command invocation from gdb."""
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-dump-guest-memory.py-skip-vmcoreinfo-section-if-not-.patch b/SOURCES/kvm-dump-guest-memory.py-skip-vmcoreinfo-section-if-not-.patch
new file mode 100644
index 0000000..fda8f30
--- /dev/null
+++ b/SOURCES/kvm-dump-guest-memory.py-skip-vmcoreinfo-section-if-not-.patch
@@ -0,0 +1,60 @@
+From cfa9ef75d5a2e814368940c0b6e70981bd082169 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 5 Feb 2018 16:38:47 +0100
+Subject: [PATCH 19/20] dump-guest-memory.py: skip vmcoreinfo section if not
+ available
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20180205163847.12004-1-marcandre.lureau@redhat.com>
+Patchwork-id: 78897
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] dump-guest-memory.py: skip vmcoreinfo section if not available
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+On some architectures, qemu doesn't support vmcoreinfo device,
+and dump-guest-memory fails:
+
+(gdb) dump-guest-memory /tmp/vmcore  ppc64-le
+guest RAM blocks:
+target_start     target_end       host_addr        message count
+---------------- ---------------- ---------------- ------- -----
+0000000000000000 0000000200000000 00003ffd86980000 added       1
+0000200080000000 0000200080800000 00003ffd86170000 added       2
+Python Exception <class 'gdb.error'> No symbol "vmcoreinfo_realize" in current context.:
+Error occurred in Python command: No symbol "vmcoreinfo_realize" in current context.
+
+Check that vmcoreinfo_realize symbol exists before evaluating an
+expression with it.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+
+(cherry picked from commit ce6b9e421a9ab45d7e6c97af092a07c049954444)
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/dump-guest-memory.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
+index 03fbf69..51acfcd 100644
+--- a/scripts/dump-guest-memory.py
++++ b/scripts/dump-guest-memory.py
+@@ -546,6 +546,8 @@ shape and this command should mostly work."""
+         return None
+ 
+     def add_vmcoreinfo(self):
++        if gdb.lookup_symbol("vmcoreinfo_realize")[0] is None:
++            return
+         vmci = 'vmcoreinfo_realize::vmcoreinfo_state'
+         if not gdb.parse_and_eval("%s" % vmci) \
+            or not gdb.parse_and_eval("(%s)->has_vmcoreinfo" % vmci):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-dump-update-phys_base-header-field-based-on-VMCOREIN.patch b/SOURCES/kvm-dump-update-phys_base-header-field-based-on-VMCOREIN.patch
new file mode 100644
index 0000000..62c2a6e
--- /dev/null
+++ b/SOURCES/kvm-dump-update-phys_base-header-field-based-on-VMCOREIN.patch
@@ -0,0 +1,139 @@
+From a1b9c54811a4fc6797259dae98548229dba53d76 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:07 +0100
+Subject: [PATCH 09/21] dump: update phys_base header field based on VMCOREINFO
+ content
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-6-marcandre.lureau@redhat.com>
+Patchwork-id: 77928
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 5/9] dump: update phys_base header field based on VMCOREINFO content
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+If the guest note is VMCOREINFO, try to get phys_base from it.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit d9feb51772b4ade9700c7fa54529327a6c8183a7)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ docs/specs/vmcoreinfo.txt |  8 +++++++
+ dump.c                    | 56 +++++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 62 insertions(+), 2 deletions(-)
+
+diff --git a/docs/specs/vmcoreinfo.txt b/docs/specs/vmcoreinfo.txt
+index 2868a77..8212610 100644
+--- a/docs/specs/vmcoreinfo.txt
++++ b/docs/specs/vmcoreinfo.txt
+@@ -39,3 +39,11 @@ qemu dumps.
+ 
+ The note format/class must be of the target bitness and the size must
+ be less than 1Mb.
++
++If the ELF note name is "VMCOREINFO", it is expected to be the Linux
++vmcoreinfo note (see Documentation/ABI/testing/sysfs-kernel-vmcoreinfo
++in Linux source). In this case, qemu dump code will read the content
++as a key=value text file, looking for "NUMBER(phys_base)" key
++value. The value is expected to be more accurate than architecture
++guess of the value. This is useful for KASLR-enabled guest with
++ancient tools not handling the VMCOREINFO note.
+diff --git a/dump.c b/dump.c
+index a4f175d..e3175d7 100644
+--- a/dump.c
++++ b/dump.c
+@@ -780,6 +780,23 @@ static void get_note_sizes(DumpState *s, const void *note,
+     }
+ }
+ 
++static bool note_name_equal(DumpState *s,
++                            const uint8_t *note, const char *name)
++{
++    int len = strlen(name) + 1;
++    uint64_t head_size, name_size;
++
++    get_note_sizes(s, note, &head_size, &name_size, NULL);
++    head_size = ROUND_UP(head_size, 4);
++
++    if (name_size != len ||
++        memcmp(note + head_size, "VMCOREINFO", len)) {
++        return false;
++    }
++
++    return true;
++}
++
+ /* write common header, sub header and elf note to vmcore */
+ static void create_header32(DumpState *s, Error **errp)
+ {
+@@ -1554,6 +1571,39 @@ static int64_t dump_calculate_size(DumpState *s)
+     return total;
+ }
+ 
++static void vmcoreinfo_update_phys_base(DumpState *s)
++{
++    uint64_t size, note_head_size, name_size, phys_base;
++    char **lines;
++    uint8_t *vmci;
++    size_t i;
++
++    if (!note_name_equal(s, s->guest_note, "VMCOREINFO")) {
++        return;
++    }
++
++    get_note_sizes(s, s->guest_note, &note_head_size, &name_size, &size);
++    note_head_size = ROUND_UP(note_head_size, 4);
++
++    vmci = s->guest_note + note_head_size + ROUND_UP(name_size, 4);
++    *(vmci + size) = '\0';
++
++    lines = g_strsplit((char *)vmci, "\n", -1);
++    for (i = 0; lines[i]; i++) {
++        if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
++            if (qemu_strtou64(lines[i] + 18, NULL, 16,
++                              &phys_base) < 0) {
++                warn_report("Failed to read NUMBER(phys_base)=");
++            } else {
++                s->dump_info.phys_base = phys_base;
++            }
++            break;
++        }
++    }
++
++    g_strfreev(lines);
++}
++
+ static void dump_init(DumpState *s, int fd, bool has_format,
+                       DumpGuestMemoryFormat format, bool paging, bool has_filter,
+                       int64_t begin, int64_t length, Error **errp)
+@@ -1637,8 +1687,9 @@ static void dump_init(DumpState *s, int fd, bool has_format,
+     }
+ 
+     /*
+-     * The goal of this block is to copy the guest note out of
+-     * the guest.  Failure to do so is not fatal for dumping.
++     * The goal of this block is to (a) update the previously guessed
++     * phys_base, (b) copy the guest note out of the guest.
++     * Failure to do so is not fatal for dumping.
+      */
+     if (vmci) {
+         uint64_t addr, note_head_size, name_size, desc_size;
+@@ -1671,6 +1722,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
+                 g_free(s->guest_note);
+                 s->guest_note = NULL;
+             } else {
++                vmcoreinfo_update_phys_base(s);
+                 s->note_size += s->guest_note_size;
+             }
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-exec-Explicitly-export-target-AS-from-address_space_.patch b/SOURCES/kvm-exec-Explicitly-export-target-AS-from-address_space_.patch
new file mode 100644
index 0000000..b327a76
--- /dev/null
+++ b/SOURCES/kvm-exec-Explicitly-export-target-AS-from-address_space_.patch
@@ -0,0 +1,92 @@
+From 7d5255d9aa2d1b0da0e7fae12264c7582080de63 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:14 +0100
+Subject: [PATCH 10/30] exec: Explicitly export target AS from
+ address_space_translate_internal
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-5-dgibson@redhat.com>
+Patchwork-id: 77696
+O-Subject: [PATCH 04/22] exec: Explicitly export target AS from address_space_translate_internal
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This adds an AS** parameter to address_space_do_translate()
+to make it easier for the next patch to share FlatViews.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-2-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit e76bb18f7e430e0c50fb38d051feacf268bd78f4)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	exec.c
+
+Conflicts because we applied 076a93d7 "exec: simplify
+address_space_get_iotlb_entry" out of order downstream.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ exec.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index ae37a60..f00bd4e 100644
+--- a/exec.c
++++ b/exec.c
+@@ -478,7 +478,8 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+                                                       hwaddr *plen_out,
+                                                       hwaddr *page_mask_out,
+                                                       bool is_write,
+-                                                      bool is_mmio)
++                                                      bool is_mmio,
++                                                      AddressSpace **target_as)
+ {
+     IOMMUTLBEntry iotlb;
+     MemoryRegionSection *section;
+@@ -512,6 +513,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+         }
+ 
+         as = iotlb.target_as;
++        *target_as = iotlb.target_as;
+     }
+ 
+     *xlat = addr;
+@@ -547,7 +549,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+      * but page mask.
+      */
+     section = address_space_do_translate(as, addr, &xlat, NULL,
+-                                         &page_mask, is_write, false);
++                                         &page_mask, is_write, false, &as);
+ 
+     /* Illegal translation */
+     if (section.mr == &io_mem_unassigned) {
+@@ -559,7 +561,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+         section.offset_within_region;
+ 
+     return (IOMMUTLBEntry) {
+-        .target_as = section.address_space,
++        .target_as = as,
+         .iova = addr & ~page_mask,
+         .translated_addr = xlat & ~page_mask,
+         .addr_mask = page_mask,
+@@ -581,7 +583,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
+ 
+     /* This can be MMIO, so setup MMIO bit. */
+     section = address_space_do_translate(as, addr, xlat, plen, NULL,
+-                                         is_write, true);
++                                         is_write, true, &as);
+     mr = section.mr;
+ 
+     if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-exec-add-page_mask-for-address_space_do_translate.patch b/SOURCES/kvm-exec-add-page_mask-for-address_space_do_translate.patch
new file mode 100644
index 0000000..cc3455a
--- /dev/null
+++ b/SOURCES/kvm-exec-add-page_mask-for-address_space_do_translate.patch
@@ -0,0 +1,145 @@
+From 59ad61373f73de6a3eb17e0c1989bc048b51b55c Mon Sep 17 00:00:00 2001
+From: Maxime Coquelin <maxime.coquelin@redhat.com>
+Date: Fri, 20 Oct 2017 14:17:06 +0200
+Subject: [PATCH 04/19] exec: add page_mask for address_space_do_translate
+
+RH-Author: Maxime Coquelin <maxime.coquelin@redhat.com>
+Message-id: <20171020141707.17637-2-maxime.coquelin@redhat.com>
+Patchwork-id: 77417
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/2] exec: add page_mask for address_space_do_translate
+Bugzilla: 1498817
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Peter Xu <peterx@redhat.com>
+
+The function is originally used for address_space_space_translate() and
+what we care about most is (xlat, plen) range. However for iotlb
+requests, we don't really care about "plen", but the size of the page
+that "xlat" is located on. While, plen cannot really contain this
+information.
+
+A simple example to show why "plen" is not good for IOTLB translations:
+
+E.g., for huge pages, it is possible that guest mapped 1G huge page on
+device side that used this GPA range:
+
+  0x100000000 - 0x13fffffff
+
+Then let's say we want to translate one IOVA that finally mapped to GPA
+0x13ffffe00 (which is located on this 1G huge page). Then here we'll
+get:
+
+  (xlat, plen) = (0x13fffe00, 0x200)
+
+So the IOTLB would be only covering a very small range since from
+"plen" (which is 0x200 bytes) we cannot tell the size of the page.
+
+Actually we can really know that this is a huge page - we just throw the
+information away in address_space_do_translate().
+
+This patch introduced "page_mask" optional parameter to capture that
+page mask info. Also, I made "plen" an optional parameter as well, with
+some comments for the whole function.
+
+No functional change yet.
+
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Message-Id: <20171010094247.10173-2-maxime.coquelin@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit d5e5fafd11be4458443c43f19c1ebdd24d99a751)
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	exec.c (Skipping 166206845f7f)
+---
+ exec.c | 32 +++++++++++++++++++++++++++-----
+ 1 file changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index d20c34c..e5f97fd 100644
+--- a/exec.c
++++ b/exec.c
+@@ -475,7 +475,8 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
+ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+                                                       hwaddr addr,
+                                                       hwaddr *xlat,
+-                                                      hwaddr *plen,
++                                                      hwaddr *plen_out,
++                                                      hwaddr *page_mask_out,
+                                                       bool is_write,
+                                                       bool is_mmio)
+ {
+@@ -483,10 +484,16 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+     MemoryRegionSection *section;
+     IOMMUMemoryRegion *iommu_mr;
+     IOMMUMemoryRegionClass *imrc;
++    hwaddr page_mask = (hwaddr)(-1);
++    hwaddr plen = (hwaddr)(-1);
++
++    if (plen_out) {
++        plen = *plen_out;
++    }
+ 
+     for (;;) {
+         AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
+-        section = address_space_translate_internal(d, addr, &addr, plen, is_mmio);
++        section = address_space_translate_internal(d, addr, &addr, &plen, is_mmio);
+ 
+         iommu_mr = memory_region_get_iommu(section->mr);
+         if (!iommu_mr) {
+@@ -498,7 +505,8 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+                                 IOMMU_WO : IOMMU_RO);
+         addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
+                 | (addr & iotlb.addr_mask));
+-        *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
++        page_mask &= iotlb.addr_mask;
++        plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1);
+         if (!(iotlb.perm & (1 << is_write))) {
+             goto translate_fail;
+         }
+@@ -508,6 +516,19 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+ 
+     *xlat = addr;
+ 
++    if (page_mask == (hwaddr)(-1)) {
++        /* Not behind an IOMMU, use default page size. */
++        page_mask = ~TARGET_PAGE_MASK;
++    }
++
++    if (page_mask_out) {
++        *page_mask_out = page_mask;
++    }
++
++    if (plen_out) {
++        *plen_out = plen;
++    }
++
+     return *section;
+ 
+ translate_fail:
+@@ -526,7 +547,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+ 
+     /* This can never be MMIO. */
+     section = address_space_do_translate(as, addr, &xlat, &plen,
+-                                         is_write, false);
++                                         NULL, is_write, false);
+ 
+     /* Illegal translation */
+     if (section.mr == &io_mem_unassigned) {
+@@ -570,7 +591,8 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
+     MemoryRegionSection section;
+ 
+     /* This can be MMIO, so setup MMIO bit. */
+-    section = address_space_do_translate(as, addr, xlat, plen, is_write, true);
++    section = address_space_do_translate(as, addr, xlat, plen, NULL,
++                                         is_write, true);
+     mr = section.mr;
+ 
+     if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-exec-simplify-address_space_get_iotlb_entry.patch b/SOURCES/kvm-exec-simplify-address_space_get_iotlb_entry.patch
new file mode 100644
index 0000000..cef5b63
--- /dev/null
+++ b/SOURCES/kvm-exec-simplify-address_space_get_iotlb_entry.patch
@@ -0,0 +1,92 @@
+From 134252b0775bcb125487eacc4d9f5a6921b0aa96 Mon Sep 17 00:00:00 2001
+From: Maxime Coquelin <maxime.coquelin@redhat.com>
+Date: Fri, 20 Oct 2017 14:17:07 +0200
+Subject: [PATCH 05/19] exec: simplify address_space_get_iotlb_entry
+
+RH-Author: Maxime Coquelin <maxime.coquelin@redhat.com>
+Message-id: <20171020141707.17637-3-maxime.coquelin@redhat.com>
+Patchwork-id: 77418
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/2] exec: simplify address_space_get_iotlb_entry
+Bugzilla: 1498817
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Peter Xu <peterx@redhat.com>
+
+This patch let address_space_get_iotlb_entry() to use the newly
+introduced page_mask parameter in address_space_do_translate().
+Then we will be sure the IOTLB can be aligned to page mask, also
+we should nicely support huge pages now when introducing a764040.
+
+Fixes: a764040 ("exec: abstract address_space_do_translate()")
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20171010094247.10173-3-maxime.coquelin@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 076a93d7972c9c1e3839d2f65edc32568a2cce93)
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	exec.c (Skipping 166206845f7f)
+---
+ exec.c | 31 ++++++++++---------------------
+ 1 file changed, 10 insertions(+), 21 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index e5f97fd..ae37a60 100644
+--- a/exec.c
++++ b/exec.c
+@@ -540,14 +540,14 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+                                             bool is_write)
+ {
+     MemoryRegionSection section;
+-    hwaddr xlat, plen;
++    hwaddr xlat, page_mask;
+ 
+-    /* Try to get maximum page mask during translation. */
+-    plen = (hwaddr)-1;
+-
+-    /* This can never be MMIO. */
+-    section = address_space_do_translate(as, addr, &xlat, &plen,
+-                                         NULL, is_write, false);
++     /*
++     * This can never be MMIO, and we don't really care about plen,
++     * but page mask.
++     */
++    section = address_space_do_translate(as, addr, &xlat, NULL,
++                                         &page_mask, is_write, false);
+ 
+     /* Illegal translation */
+     if (section.mr == &io_mem_unassigned) {
+@@ -558,22 +558,11 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+     xlat += section.offset_within_address_space -
+         section.offset_within_region;
+ 
+-    if (plen == (hwaddr)-1) {
+-        /*
+-         * We use default page size here. Logically it only happens
+-         * for identity mappings.
+-         */
+-        plen = TARGET_PAGE_SIZE;
+-    }
+-
+-    /* Convert to address mask */
+-    plen -= 1;
+-
+     return (IOMMUTLBEntry) {
+         .target_as = section.address_space,
+-        .iova = addr & ~plen,
+-        .translated_addr = xlat & ~plen,
+-        .addr_mask = plen,
++        .iova = addr & ~page_mask,
++        .translated_addr = xlat & ~page_mask,
++        .addr_mask = page_mask,
+         /* IOTLBs are for DMAs, and DMA only allows on RAMs. */
+         .perm = IOMMU_RW,
+     };
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-fw_cfg-add-write-callback.patch b/SOURCES/kvm-fw_cfg-add-write-callback.patch
new file mode 100644
index 0000000..07ae0d1
--- /dev/null
+++ b/SOURCES/kvm-fw_cfg-add-write-callback.patch
@@ -0,0 +1,210 @@
+From 57c6cfd7cf03d6fcc26dfd6a2481b8997616739a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:04 +0100
+Subject: [PATCH 06/21] fw_cfg: add write callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-3-marcandre.lureau@redhat.com>
+Patchwork-id: 77922
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/9] fw_cfg: add write callback
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Reintroduce the write callback that was removed when write support was
+removed in commit 023e3148567ac898c7258138f8e86c3c2bb40d07.
+
+Contrary to the previous callback implementation, the write_cb
+callback is called whenever a write happened, so handlers must be
+ready to handle partial write as necessary.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit 5f9252f7cc12c5cec1b3c6695aca02eb52ea7acc)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/acpi/vmgenid.c         |  2 +-
+ hw/core/loader.c          |  2 +-
+ hw/i386/acpi-build.c      |  2 +-
+ hw/isa/lpc_ich9.c         |  4 ++--
+ hw/nvram/fw_cfg.c         | 14 ++++++++++----
+ include/hw/nvram/fw_cfg.h |  3 +++
+ 6 files changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
+index a32b847..c1e935d 100644
+--- a/hw/acpi/vmgenid.c
++++ b/hw/acpi/vmgenid.c
+@@ -124,7 +124,7 @@ void vmgenid_add_fw_cfg(VmGenIdState *vms, FWCfgState *s, GArray *guid)
+     fw_cfg_add_file(s, VMGENID_GUID_FW_CFG_FILE, guid->data,
+                     VMGENID_FW_CFG_SIZE);
+     /* Create a read-write fw_cfg file for Address */
+-    fw_cfg_add_file_callback(s, VMGENID_ADDR_FW_CFG_FILE, NULL, NULL,
++    fw_cfg_add_file_callback(s, VMGENID_ADDR_FW_CFG_FILE, NULL, NULL, NULL,
+                              vms->vmgenid_addr_le,
+                              ARRAY_SIZE(vms->vmgenid_addr_le), false);
+ }
+diff --git a/hw/core/loader.c b/hw/core/loader.c
+index 4593061..91669d6 100644
+--- a/hw/core/loader.c
++++ b/hw/core/loader.c
+@@ -1023,7 +1023,7 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
+         }
+ 
+         fw_cfg_add_file_callback(fw_cfg, fw_file_name,
+-                                 fw_callback, callback_opaque,
++                                 fw_callback, NULL, callback_opaque,
+                                  data, rom->datasize, read_only);
+     }
+     return mr;
+diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
+index e38fff2..a61560f 100644
+--- a/hw/i386/acpi-build.c
++++ b/hw/i386/acpi-build.c
+@@ -2924,7 +2924,7 @@ void acpi_setup(void)
+ 
+         build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);
+         fw_cfg_add_file_callback(pcms->fw_cfg, ACPI_BUILD_RSDP_FILE,
+-                                 acpi_build_update, build_state,
++                                 acpi_build_update, NULL, build_state,
+                                  build_state->rsdp, rsdp_size, true);
+         build_state->rsdp_mr = NULL;
+     } else {
+diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
+index 39f56ba..ec3c9f7 100644
+--- a/hw/isa/lpc_ich9.c
++++ b/hw/isa/lpc_ich9.c
+@@ -402,12 +402,12 @@ void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
+          * just link them into fw_cfg here.
+          */
+         fw_cfg_add_file_callback(fw_cfg, "etc/smi/requested-features",
+-                                 NULL, NULL,
++                                 NULL, NULL, NULL,
+                                  lpc->smi_guest_features_le,
+                                  sizeof lpc->smi_guest_features_le,
+                                  false);
+         fw_cfg_add_file_callback(fw_cfg, "etc/smi/features-ok",
+-                                 smi_features_ok_callback, lpc,
++                                 smi_features_ok_callback, NULL, lpc,
+                                  &lpc->smi_features_ok,
+                                  sizeof lpc->smi_features_ok,
+                                  true);
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index e3bd626..753ac0e 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -56,6 +56,7 @@ struct FWCfgEntry {
+     uint8_t *data;
+     void *callback_opaque;
+     FWCfgCallback select_cb;
++    FWCfgWriteCallback write_cb;
+ };
+ 
+ #define JPG_FILE 0
+@@ -370,6 +371,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
+                     dma_memory_read(s->dma_as, dma.address,
+                                     &e->data[s->cur_offset], len)) {
+                     dma.control |= FW_CFG_DMA_CTL_ERROR;
++                } else if (e->write_cb) {
++                    e->write_cb(e->callback_opaque, s->cur_offset, len);
+                 }
+             }
+ 
+@@ -570,6 +573,7 @@ static const VMStateDescription vmstate_fw_cfg = {
+ 
+ static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
+                                       FWCfgCallback select_cb,
++                                      FWCfgWriteCallback write_cb,
+                                       void *callback_opaque,
+                                       void *data, size_t len,
+                                       bool read_only)
+@@ -584,6 +588,7 @@ static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
+     s->entries[arch][key].data = data;
+     s->entries[arch][key].len = (uint32_t)len;
+     s->entries[arch][key].select_cb = select_cb;
++    s->entries[arch][key].write_cb = write_cb;
+     s->entries[arch][key].callback_opaque = callback_opaque;
+     s->entries[arch][key].allow_write = !read_only;
+ }
+@@ -610,7 +615,7 @@ static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
+ 
+ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
+ {
+-    fw_cfg_add_bytes_callback(s, key, NULL, NULL, data, len, true);
++    fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, true);
+ }
+ 
+ void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
+@@ -737,6 +742,7 @@ static int get_fw_cfg_order(FWCfgState *s, const char *name)
+ 
+ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+                               FWCfgCallback select_cb,
++                              FWCfgWriteCallback write_cb,
+                               void *callback_opaque,
+                               void *data, size_t len, bool read_only)
+ {
+@@ -800,7 +806,7 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+     }
+ 
+     fw_cfg_add_bytes_callback(s, FW_CFG_FILE_FIRST + index,
+-                              select_cb,
++                              select_cb, write_cb,
+                               callback_opaque, data, len,
+                               read_only);
+ 
+@@ -815,7 +821,7 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+ void fw_cfg_add_file(FWCfgState *s,  const char *filename,
+                      void *data, size_t len)
+ {
+-    fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len, true);
++    fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
+ }
+ 
+ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
+@@ -838,7 +844,7 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
+         }
+     }
+     /* add new one */
+-    fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len, true);
++    fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
+     return NULL;
+ }
+ 
+diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
+index f50d068..7ccbae5 100644
+--- a/include/hw/nvram/fw_cfg.h
++++ b/include/hw/nvram/fw_cfg.h
+@@ -45,6 +45,7 @@ typedef struct FWCfgDmaAccess {
+ } QEMU_PACKED FWCfgDmaAccess;
+ 
+ typedef void (*FWCfgCallback)(void *opaque);
++typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len);
+ 
+ struct FWCfgState {
+     /*< private >*/
+@@ -183,6 +184,7 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
+  * @s: fw_cfg device being modified
+  * @filename: name of new fw_cfg file item
+  * @select_cb: callback function when selecting
++ * @write_cb: callback function after a write
+  * @callback_opaque: argument to be passed into callback function
+  * @data: pointer to start of item data
+  * @len: size of item data
+@@ -202,6 +204,7 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
+  */
+ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
+                               FWCfgCallback select_cb,
++                              FWCfgWriteCallback write_cb,
+                               void *callback_opaque,
+                               void *data, size_t len, bool read_only);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-fw_cfg-fix-memory-corruption-when-all-fw_cfg-slots-a.patch b/SOURCES/kvm-fw_cfg-fix-memory-corruption-when-all-fw_cfg-slots-a.patch
new file mode 100644
index 0000000..9a7c5c8
--- /dev/null
+++ b/SOURCES/kvm-fw_cfg-fix-memory-corruption-when-all-fw_cfg-slots-a.patch
@@ -0,0 +1,70 @@
+From 0df9f346cb7d66701c79cb6fa1b187aa603d659b Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Mon, 15 Jan 2018 10:06:42 +0100
+Subject: [PATCH 09/12] fw_cfg: fix memory corruption when all fw_cfg slots are
+ used
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20180115100642.64493-1-marcel@redhat.com>
+Patchwork-id: 78571
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] fw_cfg: fix memory corruption when all fw_cfg slots are used
+Bugzilla: 1462145
+RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+When all the fw_cfg slots are used, a write is made outside the
+bounds of the fw_cfg files array as part of the sort algorithm.
+
+Fix it by avoiding an unnecessary array element move.
+Fix also an assert while at it.
+
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Message-Id: <20180108215007.46471-1-marcel@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 45eda6c8eb45107630da670bc993074cf85ef64c)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/nvram/fw_cfg.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index 753ac0e..4313484 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -784,7 +784,7 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+      * index and "i - 1" is the one being copied from, thus the
+      * unusual start and end in the for statement.
+      */
+-    for (i = count + 1; i > index; i--) {
++    for (i = count; i > index; i--) {
+         s->files->f[i] = s->files->f[i - 1];
+         s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i);
+         s->entries[0][FW_CFG_FILE_FIRST + i] =
+@@ -833,7 +833,6 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
+     assert(s->files);
+ 
+     index = be32_to_cpu(s->files->count);
+-    assert(index < fw_cfg_file_slots(s));
+ 
+     for (i = 0; i < index; i++) {
+         if (strcmp(filename, s->files->f[i].name) == 0) {
+@@ -843,6 +842,9 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
+             return ptr;
+         }
+     }
++
++    assert(index < fw_cfg_file_slots(s));
++
+     /* add new one */
+     fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
+     return NULL;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-fw_cfg-rename-read-callback.patch b/SOURCES/kvm-fw_cfg-rename-read-callback.patch
new file mode 100644
index 0000000..b216681
--- /dev/null
+++ b/SOURCES/kvm-fw_cfg-rename-read-callback.patch
@@ -0,0 +1,180 @@
+From 571cf340ae415185ab21a1af146cb3df7b489286 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:03 +0100
+Subject: [PATCH 05/21] fw_cfg: rename read callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-2-marcandre.lureau@redhat.com>
+Patchwork-id: 77921
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/9] fw_cfg: rename read callback
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The callback is called on select.
+
+Furthermore, the next patch introduced a new callback, so rename the
+function type with a generic name.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit 6f6f4aec749ba9a4fb58c7c20536a61b0381ff35)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/core/loader.c          |  2 +-
+ hw/nvram/fw_cfg.c         | 30 ++++++++++++++++--------------
+ include/hw/loader.h       |  2 +-
+ include/hw/nvram/fw_cfg.h |  7 ++++---
+ 4 files changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/hw/core/loader.c b/hw/core/loader.c
+index ebe574c..4593061 100644
+--- a/hw/core/loader.c
++++ b/hw/core/loader.c
+@@ -989,7 +989,7 @@ err:
+ 
+ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
+                    size_t max_len, hwaddr addr, const char *fw_file_name,
+-                   FWCfgReadCallback fw_callback, void *callback_opaque,
++                   FWCfgCallback fw_callback, void *callback_opaque,
+                    AddressSpace *as, bool read_only)
+ {
+     MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index 5bd9044..e3bd626 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -55,7 +55,7 @@ struct FWCfgEntry {
+     bool allow_write;
+     uint8_t *data;
+     void *callback_opaque;
+-    FWCfgReadCallback read_callback;
++    FWCfgCallback select_cb;
+ };
+ 
+ #define JPG_FILE 0
+@@ -236,8 +236,8 @@ static int fw_cfg_select(FWCfgState *s, uint16_t key)
+         /* entry successfully selected, now run callback if present */
+         arch = !!(key & FW_CFG_ARCH_LOCAL);
+         e = &s->entries[arch][key & FW_CFG_ENTRY_MASK];
+-        if (e->read_callback) {
+-            e->read_callback(e->callback_opaque);
++        if (e->select_cb) {
++            e->select_cb(e->callback_opaque);
+         }
+     }
+ 
+@@ -568,11 +568,11 @@ static const VMStateDescription vmstate_fw_cfg = {
+     }
+ };
+ 
+-static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
+-                                           FWCfgReadCallback callback,
+-                                           void *callback_opaque,
+-                                           void *data, size_t len,
+-                                           bool read_only)
++static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
++                                      FWCfgCallback select_cb,
++                                      void *callback_opaque,
++                                      void *data, size_t len,
++                                      bool read_only)
+ {
+     int arch = !!(key & FW_CFG_ARCH_LOCAL);
+ 
+@@ -583,7 +583,7 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
+ 
+     s->entries[arch][key].data = data;
+     s->entries[arch][key].len = (uint32_t)len;
+-    s->entries[arch][key].read_callback = callback;
++    s->entries[arch][key].select_cb = select_cb;
+     s->entries[arch][key].callback_opaque = callback_opaque;
+     s->entries[arch][key].allow_write = !read_only;
+ }
+@@ -610,7 +610,7 @@ static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
+ 
+ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
+ {
+-    fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len, true);
++    fw_cfg_add_bytes_callback(s, key, NULL, NULL, data, len, true);
+ }
+ 
+ void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
+@@ -736,7 +736,8 @@ static int get_fw_cfg_order(FWCfgState *s, const char *name)
+ }
+ 
+ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+-                              FWCfgReadCallback callback, void *callback_opaque,
++                              FWCfgCallback select_cb,
++                              void *callback_opaque,
+                               void *data, size_t len, bool read_only)
+ {
+     int i, index, count;
+@@ -798,9 +799,10 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
+         }
+     }
+ 
+-    fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index,
+-                                   callback, callback_opaque, data, len,
+-                                   read_only);
++    fw_cfg_add_bytes_callback(s, FW_CFG_FILE_FIRST + index,
++                              select_cb,
++                              callback_opaque, data, len,
++                              read_only);
+ 
+     s->files->f[index].size   = cpu_to_be32(len);
+     s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
+diff --git a/include/hw/loader.h b/include/hw/loader.h
+index 490c9ff..355fe0f 100644
+--- a/include/hw/loader.h
++++ b/include/hw/loader.h
+@@ -192,7 +192,7 @@ int rom_add_file(const char *file, const char *fw_dir,
+ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
+                            size_t max_len, hwaddr addr,
+                            const char *fw_file_name,
+-                           FWCfgReadCallback fw_callback,
++                           FWCfgCallback fw_callback,
+                            void *callback_opaque, AddressSpace *as,
+                            bool read_only);
+ int rom_add_elf_program(const char *name, void *data, size_t datasize,
+diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
+index b77ea48..f50d068 100644
+--- a/include/hw/nvram/fw_cfg.h
++++ b/include/hw/nvram/fw_cfg.h
+@@ -44,7 +44,7 @@ typedef struct FWCfgDmaAccess {
+     uint64_t address;
+ } QEMU_PACKED FWCfgDmaAccess;
+ 
+-typedef void (*FWCfgReadCallback)(void *opaque);
++typedef void (*FWCfgCallback)(void *opaque);
+ 
+ struct FWCfgState {
+     /*< private >*/
+@@ -182,7 +182,7 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
+  * fw_cfg_add_file_callback:
+  * @s: fw_cfg device being modified
+  * @filename: name of new fw_cfg file item
+- * @callback: callback function
++ * @select_cb: callback function when selecting
+  * @callback_opaque: argument to be passed into callback function
+  * @data: pointer to start of item data
+  * @len: size of item data
+@@ -201,7 +201,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
+  * with FW_CFG_DMA_CTL_SELECT).
+  */
+ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
+-                              FWCfgReadCallback callback, void *callback_opaque,
++                              FWCfgCallback select_cb,
++                              void *callback_opaque,
+                               void *data, size_t len, bool read_only);
+ 
+ /**
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-gicv3-Convert-to-DEFINE_PROP_LINK.patch b/SOURCES/kvm-gicv3-Convert-to-DEFINE_PROP_LINK.patch
new file mode 100644
index 0000000..03d2e52
--- /dev/null
+++ b/SOURCES/kvm-gicv3-Convert-to-DEFINE_PROP_LINK.patch
@@ -0,0 +1,80 @@
+From 11098ad708cd535e4d79bf82c07ef78ca16b647c Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:02 +0100
+Subject: [PATCH 1/9] gicv3: Convert to DEFINE_PROP_LINK
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-2-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77939
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 1/7] gicv3: Convert to DEFINE_PROP_LINK
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+From: Fam Zheng <famz@redhat.com>
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-id: 20170905131149.10669-4-famz@redhat.com
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 9ea26c70498cde1887746222c3cada968e46ec23)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/intc/arm_gicv3_its_kvm.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
+index 1f8991b..39903d5 100644
+--- a/hw/intc/arm_gicv3_its_kvm.c
++++ b/hw/intc/arm_gicv3_its_kvm.c
+@@ -120,17 +120,6 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
+     qemu_add_vm_change_state_handler(vm_change_state_handler, s);
+ }
+ 
+-static void kvm_arm_its_init(Object *obj)
+-{
+-    GICv3ITSState *s = KVM_ARM_ITS(obj);
+-
+-    object_property_add_link(obj, "parent-gicv3",
+-                             "kvm-arm-gicv3", (Object **)&s->gicv3,
+-                             object_property_allow_set_link,
+-                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+-                             &error_abort);
+-}
+-
+ /**
+  * kvm_arm_its_pre_save - handles the saving of ITS registers.
+  * ITS tables are flushed into guest RAM separately and earlier,
+@@ -205,12 +194,19 @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
+                       GITS_CTLR, &s->ctlr, true, &error_abort);
+ }
+ 
++static Property kvm_arm_its_props[] = {
++    DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
++                     GICv3State *),
++    DEFINE_PROP_END_OF_LIST(),
++};
++
+ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
+ 
+     dc->realize = kvm_arm_its_realize;
++    dc->props   = kvm_arm_its_props;
+     icc->send_msi = kvm_its_send_msi;
+     icc->pre_save = kvm_arm_its_pre_save;
+     icc->post_load = kvm_arm_its_post_load;
+@@ -220,7 +216,6 @@ static const TypeInfo kvm_arm_its_info = {
+     .name = TYPE_KVM_ARM_ITS,
+     .parent = TYPE_ARM_GICV3_ITS_COMMON,
+     .instance_size = sizeof(GICv3ITSState),
+-    .instance_init = kvm_arm_its_init,
+     .class_init = kvm_arm_its_class_init,
+ };
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hostmem-file-Add-discard-data-option.patch b/SOURCES/kvm-hostmem-file-Add-discard-data-option.patch
new file mode 100644
index 0000000..7e5ffa2
--- /dev/null
+++ b/SOURCES/kvm-hostmem-file-Add-discard-data-option.patch
@@ -0,0 +1,122 @@
+From ebf96eb206cfc94a1db16f28b281fee0c56fef8c Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Thu, 19 Oct 2017 01:34:53 +0200
+Subject: [PATCH 64/69] hostmem-file: Add "discard-data" option
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171019013453.21449-5-ehabkost@redhat.com>
+Patchwork-id: 77370
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 4/4] hostmem-file: Add "discard-data" option
+Bugzilla: 1460848
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+The new option can be used to indicate that the file contents can
+be destroyed and don't need to be flushed to disk when QEMU exits
+or when the memory backend object is removed.
+
+Internally, it will trigger a madvise(MADV_REMOVE) call when the
+memory backend is removed.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20170824192315.5897-4-ehabkost@redhat.com>
+[ehabkost: fixup: improved documentation]
+Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
+Tested-by: Zack Cornelius <zack.cornelius@kove.net>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 11ae6ed8affdd131e735bac39b21e7d3cde66f7b)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ backends/hostmem-file.c | 29 +++++++++++++++++++++++++++++
+ qemu-options.hx         |  8 +++++++-
+ 2 files changed, 36 insertions(+), 1 deletion(-)
+
+diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
+index fc4ef46..e44c319 100644
+--- a/backends/hostmem-file.c
++++ b/backends/hostmem-file.c
+@@ -32,6 +32,7 @@ struct HostMemoryBackendFile {
+     HostMemoryBackend parent_obj;
+ 
+     bool share;
++    bool discard_data;
+     char *mem_path;
+ };
+ 
+@@ -103,16 +104,44 @@ static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
+     fb->share = value;
+ }
+ 
++static bool file_memory_backend_get_discard_data(Object *o, Error **errp)
++{
++    return MEMORY_BACKEND_FILE(o)->discard_data;
++}
++
++static void file_memory_backend_set_discard_data(Object *o, bool value,
++                                               Error **errp)
++{
++    MEMORY_BACKEND_FILE(o)->discard_data = value;
++}
++
++static void file_backend_unparent(Object *obj)
++{
++    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
++    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
++
++    if (host_memory_backend_mr_inited(backend) && fb->discard_data) {
++        void *ptr = memory_region_get_ram_ptr(&backend->mr);
++        uint64_t sz = memory_region_size(&backend->mr);
++
++        qemu_madvise(ptr, sz, QEMU_MADV_REMOVE);
++    }
++}
++
+ static void
+ file_backend_class_init(ObjectClass *oc, void *data)
+ {
+     HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+ 
+     bc->alloc = file_backend_memory_alloc;
++    oc->unparent = file_backend_unparent;
+ 
+     object_class_property_add_bool(oc, "share",
+         file_memory_backend_get_share, file_memory_backend_set_share,
+         &error_abort);
++    object_class_property_add_bool(oc, "discard-data",
++        file_memory_backend_get_discard_data, file_memory_backend_set_discard_data,
++        &error_abort);
+     object_class_property_add_str(oc, "mem-path",
+         get_mem_path, set_mem_path,
+         &error_abort);
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 5220120..50ba50e 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -4155,7 +4155,7 @@ property must be set.  These objects are placed in the
+ 
+ @table @option
+ 
+-@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off}
++@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off},discard-data=@var{on|off}
+ 
+ Creates a memory file backend object, which can be used to back
+ the guest RAM with huge pages. The @option{id} parameter is a
+@@ -4167,6 +4167,12 @@ the path to either a shared memory or huge page filesystem mount.
+ The @option{share} boolean option determines whether the memory
+ region is marked as private to QEMU, or shared. The latter allows
+ a co-operating external process to access the QEMU memory region.
++Setting the @option{discard-data} boolean option to @var{on}
++indicates that file contents can be destroyed when QEMU exits,
++to avoid unnecessarily flushing data to the backing file.  Note
++that @option{discard-data} is only an optimization, and QEMU
++might not discard file contents if it aborts unexpectedly or is
++terminated using SIGKILL.
+ 
+ @item -object rng-random,id=@var{id},filename=@var{/dev/random}
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-Remove-the-redundant-user_creatable-false-from-SY.patch b/SOURCES/kvm-hw-Remove-the-redundant-user_creatable-false-from-SY.patch
new file mode 100644
index 0000000..71baf41
--- /dev/null
+++ b/SOURCES/kvm-hw-Remove-the-redundant-user_creatable-false-from-SY.patch
@@ -0,0 +1,93 @@
+From e6c4563d68a353e9b3938c9f49a239b5dca61868 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Thu, 19 Oct 2017 10:16:49 +0200
+Subject: [PATCH 67/69] hw: Remove the redundant user_creatable = false from
+ SYS_BUS_DEVICEs
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1508408209-5712-4-git-send-email-thuth@redhat.com>
+Patchwork-id: 77375
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/3] hw: Remove the redundant user_creatable = false from SYS_BUS_DEVICEs
+Bugzilla: 1503998
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+The devices that are addressed by this patch are SYS_BUS_DEVICE, and
+in QEMU 2.10, sysbus devices are marked with user_creatable = false by
+default already. So there is now no need anymore to explicitely set
+this flag to false in the downstream qemu-kvm build.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/block/pflash_cfi01.c | 1 -
+ hw/i386/kvm/clock.c     | 1 -
+ hw/ide/ahci.c           | 1 -
+ hw/isa/isa-bus.c        | 1 -
+ hw/virtio/virtio-mmio.c | 1 -
+ 5 files changed, 5 deletions(-)
+
+diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
+index afe6230..1113ab1 100644
+--- a/hw/block/pflash_cfi01.c
++++ b/hw/block/pflash_cfi01.c
+@@ -925,7 +925,6 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
+     dc->realize = pflash_cfi01_realize;
+     dc->props = pflash_cfi01_properties;
+     dc->vmsd = &vmstate_pflash;
+-    dc->user_creatable = false; /* RH state preserve */
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ }
+ 
+diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
+index fc7212f..363d1b5 100644
+--- a/hw/i386/kvm/clock.c
++++ b/hw/i386/kvm/clock.c
+@@ -289,7 +289,6 @@ static void kvmclock_class_init(ObjectClass *klass, void *data)
+     dc->realize = kvmclock_realize;
+     dc->vmsd = &kvmclock_vmsd;
+     dc->props = kvmclock_properties;
+-    dc->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static const TypeInfo kvmclock_info = {
+diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
+index 2cb41fc..da6c23d 100644
+--- a/hw/ide/ahci.c
++++ b/hw/ide/ahci.c
+@@ -1720,7 +1720,6 @@ static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
+     dc->vmsd = &vmstate_sysbus_ahci;
+     dc->props = sysbus_ahci_properties;
+     dc->reset = sysbus_ahci_reset;
+-    dc->user_creatable = false; /* RH state preserve */
+     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ }
+ 
+diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
+index 467042f..348e0ea 100644
+--- a/hw/isa/isa-bus.c
++++ b/hw/isa/isa-bus.c
+@@ -221,7 +221,6 @@ static void isabus_bridge_class_init(ObjectClass *klass, void *data)
+ 
+     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+     dc->fw_name = "isa";
+-    dc->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static const TypeInfo isabus_bridge_info = {
+diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
+index 62df6c2..5807aa8 100644
+--- a/hw/virtio/virtio-mmio.c
++++ b/hw/virtio/virtio-mmio.c
+@@ -448,7 +448,6 @@ static void virtio_mmio_class_init(ObjectClass *klass, void *data)
+ 
+     dc->realize = virtio_mmio_realizefn;
+     dc->reset = virtio_mmio_reset;
+-    dc->user_creatable = false; /* RH state preserve */
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     dc->props = virtio_mmio_properties;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-acpi-Move-acpi_set_pci_info-to-pcihp.patch b/SOURCES/kvm-hw-acpi-Move-acpi_set_pci_info-to-pcihp.patch
new file mode 100644
index 0000000..1def82e
--- /dev/null
+++ b/SOURCES/kvm-hw-acpi-Move-acpi_set_pci_info-to-pcihp.patch
@@ -0,0 +1,202 @@
+From acb06b5ca2ea9f30a7b14c34674b930f0e8a1a60 Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Tue, 16 Jan 2018 14:15:34 +0100
+Subject: [PATCH 02/21] hw/acpi: Move acpi_set_pci_info to pcihp
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20180116141534.100478-1-marcel@redhat.com>
+Patchwork-id: 78628
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH V2] hw/acpi: Move acpi_set_pci_info to pcihp
+Bugzilla: 1507693
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Anthony PERARD <anthony.perard@citrix.com>
+
+RHEL Note:
+    rhel6 machine types don't generate their ACPI payload
+    (pcmc->has_acpi_build = false), SeaBIOS does it for them
+    (m->default_machine_opts = "firmware=bios.bin"). In turn, before the
+    patch, these machine types never call acpi_setup() ->
+    acpi_set_pci_info(), and never set BSEL. After the patch, BSEL is set in
+    all i440fx-based machine types, via piix4_reset() -> acpi_pcihp_reset()
+    -> acpi_set_pci_info().
+
+HW part of ACPI PCI hotplug in QEMU depends on ACPI_PCIHP_PROP_BSEL
+being set on a PCI bus that supports ACPI hotplug. It should work
+regardless of the source of ACPI tables (QEMU generator/legacy SeaBIOS/Xen).
+So move ACPI_PCIHP_PROP_BSEL initialization into HW ACPI implementation
+part from QEMU's ACPI table generator.
+
+To do PCI passthrough with Xen, the property ACPI_PCIHP_PROP_BSEL needs
+to be set, but this was done only when ACPI tables are built which is
+not needed for a Xen guest. The need for the property starts with commit
+"pc: pcihp: avoid adding ACPI_PCIHP_PROP_BSEL twice"
+(f0c9d64a68b776374ec4732424a3e27753ce37b6).
+
+Adding find_i440fx into stubs so that mips-softmmu target can be built.
+
+Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
+Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit ab938ae43f8a3a71a3525566edf586081b7a7452)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+
+ Conflicts:
+	stubs/Makefile.objs
+   (some stubs were added before it)
+
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+---
+
+V1 -> V2:
+   Added the RHEL Note (Laszlo)
+
+ hw/acpi/pcihp.c       | 38 ++++++++++++++++++++++++++++++++++++++
+ hw/i386/acpi-build.c  | 32 --------------------------------
+ stubs/Makefile.objs   |  1 +
+ stubs/pci-host-piix.c |  6 ++++++
+ 4 files changed, 45 insertions(+), 32 deletions(-)
+ create mode 100644 stubs/pci-host-piix.c
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/acpi/pcihp.c       | 38 ++++++++++++++++++++++++++++++++++++++
+ hw/i386/acpi-build.c  | 32 --------------------------------
+ stubs/Makefile.objs   |  1 +
+ stubs/pci-host-piix.c |  6 ++++++
+ 4 files changed, 45 insertions(+), 32 deletions(-)
+ create mode 100644 stubs/pci-host-piix.c
+
+diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
+index c420a38..9ad5edc 100644
+--- a/hw/acpi/pcihp.c
++++ b/hw/acpi/pcihp.c
+@@ -75,6 +75,43 @@ static int acpi_pcihp_get_bsel(PCIBus *bus)
+     }
+ }
+ 
++/* Assign BSEL property to all buses.  In the future, this can be changed
++ * to only assign to buses that support hotplug.
++ */
++static void *acpi_set_bsel(PCIBus *bus, void *opaque)
++{
++    unsigned *bsel_alloc = opaque;
++    unsigned *bus_bsel;
++
++    if (qbus_is_hotpluggable(BUS(bus))) {
++        bus_bsel = g_malloc(sizeof *bus_bsel);
++
++        *bus_bsel = (*bsel_alloc)++;
++        object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
++                                       bus_bsel, &error_abort);
++    }
++
++    return bsel_alloc;
++}
++
++static void acpi_set_pci_info(void)
++{
++    static bool bsel_is_set;
++    PCIBus *bus;
++    unsigned bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT;
++
++    if (bsel_is_set) {
++        return;
++    }
++    bsel_is_set = true;
++
++    bus = find_i440fx(); /* TODO: Q35 support */
++    if (bus) {
++        /* Scan all PCI buses. Set property to enable acpi based hotplug. */
++        pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
++    }
++}
++
+ static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
+ {
+     AcpiPciHpFind *find = opaque;
+@@ -177,6 +214,7 @@ static void acpi_pcihp_update(AcpiPciHpState *s)
+ 
+ void acpi_pcihp_reset(AcpiPciHpState *s)
+ {
++    acpi_set_pci_info();
+     acpi_pcihp_update(s);
+ }
+ 
+diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
+index a61560f..8117321 100644
+--- a/hw/i386/acpi-build.c
++++ b/hw/i386/acpi-build.c
+@@ -495,36 +495,6 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
+                  table_data->len - madt_start, 1, NULL, NULL);
+ }
+ 
+-/* Assign BSEL property to all buses.  In the future, this can be changed
+- * to only assign to buses that support hotplug.
+- */
+-static void *acpi_set_bsel(PCIBus *bus, void *opaque)
+-{
+-    unsigned *bsel_alloc = opaque;
+-    unsigned *bus_bsel;
+-
+-    if (qbus_is_hotpluggable(BUS(bus))) {
+-        bus_bsel = g_malloc(sizeof *bus_bsel);
+-
+-        *bus_bsel = (*bsel_alloc)++;
+-        object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
+-                                       bus_bsel, &error_abort);
+-    }
+-
+-    return bsel_alloc;
+-}
+-
+-static void acpi_set_pci_info(void)
+-{
+-    PCIBus *bus = find_i440fx(); /* TODO: Q35 support */
+-    unsigned bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT;
+-
+-    if (bus) {
+-        /* Scan all PCI buses. Set property to enable acpi based hotplug. */
+-        pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
+-    }
+-}
+-
+ static void build_append_pcihp_notify_entry(Aml *method, int slot)
+ {
+     Aml *if_ctx;
+@@ -2890,8 +2860,6 @@ void acpi_setup(void)
+ 
+     build_state = g_malloc0(sizeof *build_state);
+ 
+-    acpi_set_pci_info();
+-
+     acpi_build_tables_init(&tables);
+     acpi_build(&tables, MACHINE(pcms));
+ 
+diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
+index 7e9f94d..e3b9e6b 100644
+--- a/stubs/Makefile.objs
++++ b/stubs/Makefile.objs
+@@ -42,3 +42,4 @@ stub-obj-y += xen-common.o
+ stub-obj-y += xen-hvm.o
+ stub-obj-y += shadow-bios.o
+ stub-obj-y += ide-isa.o
++stub-obj-y += pci-host-piix.o
+diff --git a/stubs/pci-host-piix.c b/stubs/pci-host-piix.c
+new file mode 100644
+index 0000000..6ed81b1
+--- /dev/null
++++ b/stubs/pci-host-piix.c
+@@ -0,0 +1,6 @@
++#include "qemu/osdep.h"
++#include "hw/i386/pc.h"
++PCIBus *find_i440fx(void)
++{
++    return NULL;
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-arm-virt-Set-INTx-gsi-mapping.patch b/SOURCES/kvm-hw-arm-virt-Set-INTx-gsi-mapping.patch
new file mode 100644
index 0000000..42aa525
--- /dev/null
+++ b/SOURCES/kvm-hw-arm-virt-Set-INTx-gsi-mapping.patch
@@ -0,0 +1,48 @@
+From fe6e65efe39932521b861b4de358a9b73d2ac4cf Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Mon, 6 Nov 2017 17:08:43 +0100
+Subject: [PATCH 7/9] hw/arm/virt: Set INTx/gsi mapping
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1509988125-30275-3-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77508
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 2/4] hw/arm/virt: Set INTx/gsi mapping
+Bugzilla: 1460957
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
+
+Let's provide the GPEX host bridge with the INTx/gsi mapping. This is
+needed for INTx/gsi routing.
+
+Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
+Signed-off-by: Tushar Jagad <tushar.jagad@linaro.org>
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Tested-by: Feng Kan <fkan@apm.com>
+Message-id: 1505296004-6798-3-git-send-email-eric.auger@redhat.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit c9bb8e16080d189a0c393a1061b427993516ae2b)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/arm/virt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index f243536..b175e36 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -1079,6 +1079,7 @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
+ 
+     for (i = 0; i < GPEX_NUM_IRQS; i++) {
+         sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
++        gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
+     }
+ 
+     pci = PCI_HOST_BRIDGE(dev);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-dma-i8257-Remove-redundant-downstream-user_creata.patch b/SOURCES/kvm-hw-dma-i8257-Remove-redundant-downstream-user_creata.patch
new file mode 100644
index 0000000..489e513
--- /dev/null
+++ b/SOURCES/kvm-hw-dma-i8257-Remove-redundant-downstream-user_creata.patch
@@ -0,0 +1,41 @@
+From 374294de467ebc115e70f0804e98081753d51c3b Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Thu, 19 Oct 2017 10:16:47 +0200
+Subject: [PATCH 65/69] hw/dma/i8257: Remove redundant downstream
+ user_creatable = false
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1508408209-5712-2-git-send-email-thuth@redhat.com>
+Patchwork-id: 77372
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/3] hw/dma/i8257: Remove redundant downstream user_creatable = false
+Bugzilla: 1503998
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+The i8257_class_init() function has already user_creatable = false
+at the end of the function in the upstream code, so there is no
+need to set this again with downstream-only code.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/dma/i8257.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
+index e52a679..bd23e89 100644
+--- a/hw/dma/i8257.c
++++ b/hw/dma/i8257.c
+@@ -591,8 +591,6 @@ static void i8257_class_init(ObjectClass *klass, void *data)
+     dc->reset = i8257_reset;
+     dc->vmsd = &vmstate_i8257;
+     dc->props = i8257_properties;
+-    /* Disabled for Red Hat Enterprise Linux: */
+-    dc->user_creatable = false;
+ 
+     idc->get_transfer_mode = i8257_dma_get_transfer_mode;
+     idc->has_autoinitialization = i8257_dma_has_autoinitialization;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-gen_pcie_root_port-make-IO-RO-0-on-IO-disabled.patch b/SOURCES/kvm-hw-gen_pcie_root_port-make-IO-RO-0-on-IO-disabled.patch
new file mode 100644
index 0000000..73a8cd9
--- /dev/null
+++ b/SOURCES/kvm-hw-gen_pcie_root_port-make-IO-RO-0-on-IO-disabled.patch
@@ -0,0 +1,49 @@
+From 7802df183a0b1f457c97e6f920e720f6fef36a18 Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Mon, 13 Nov 2017 19:03:30 +0100
+Subject: [PATCH 04/30] hw/gen_pcie_root_port: make IO RO 0 on IO disabled
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20171113190330.57188-1-marcel@redhat.com>
+Patchwork-id: 77666
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] hw/gen_pcie_root_port: make IO RO 0 on IO disabled
+Bugzilla: 1344299
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+IO_LIMIT and IO_BASE registers should not be writable if
+gen_pcie_root_port's io-reserve property is set to 0.
+The COMMAND register should have the IO flag read only.
+
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 8e36c336d943c3bfe0d06f5465cc64d44b306e13)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-bridge/gen_pcie_root_port.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
+index ed03ffc..ad4e6aa 100644
+--- a/hw/pci-bridge/gen_pcie_root_port.c
++++ b/hw/pci-bridge/gen_pcie_root_port.c
+@@ -85,6 +85,13 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
+         rpc->parent_class.exit(d);
+         return;
+     }
++
++    if (!grp->io_reserve) {
++        pci_word_test_and_clear_mask(d->wmask + PCI_COMMAND,
++                                     PCI_COMMAND_IO);
++        d->wmask[PCI_IO_BASE] = 0;
++        d->wmask[PCI_IO_LIMIT] = 0;
++    }
+ }
+ 
+ static const VMStateDescription vmstate_rp_dev = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-intc-arm_gicv3_its-Don-t-abort-on-table-save-fail.patch b/SOURCES/kvm-hw-intc-arm_gicv3_its-Don-t-abort-on-table-save-fail.patch
new file mode 100644
index 0000000..4459ae0
--- /dev/null
+++ b/SOURCES/kvm-hw-intc-arm_gicv3_its-Don-t-abort-on-table-save-fail.patch
@@ -0,0 +1,67 @@
+From 3e611f18f7a3d0a76c07f822e6190a79c09f82e7 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:04 +0100
+Subject: [PATCH 3/9] hw/intc/arm_gicv3_its: Don't abort on table save failure
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-4-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77940
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 3/7] hw/intc/arm_gicv3_its: Don't abort on table save failure
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+The ITS is not fully properly reset at the moment. Caches are
+not emptied.
+
+After a reset, in case we attempt to save the state before
+the bound devices have registered their MSIs and after the
+1st level table has been allocated by the ITS driver
+(device BASER is valid), the first level entries are still
+invalid. If the device cache is not empty (devices registered
+before the reset), vgic_its_save_device_tables fails with -EINVAL.
+This causes a QEMU abort().
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reported-by: wanghaibin <wanghaibin.wang@huawei.com>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 8a7348b5d62d7ea16807e6bea54b448a0184bb0f)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/intc/arm_gicv3_its_kvm.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
+index 9b00ce5..6fb45df 100644
+--- a/hw/intc/arm_gicv3_its_kvm.c
++++ b/hw/intc/arm_gicv3_its_kvm.c
+@@ -64,20 +64,16 @@ static void vm_change_state_handler(void *opaque, int running,
+ {
+     GICv3ITSState *s = (GICv3ITSState *)opaque;
+     Error *err = NULL;
+-    int ret;
+ 
+     if (running) {
+         return;
+     }
+ 
+-    ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
+-                            KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
++    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
++                      KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
+     if (err) {
+         error_report_err(err);
+     }
+-    if (ret < 0 && ret != -EFAULT) {
+-        abort();
+-    }
+ }
+ 
+ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-intc-arm_gicv3_its-Don-t-call-post_load-on-reset.patch b/SOURCES/kvm-hw-intc-arm_gicv3_its-Don-t-call-post_load-on-reset.patch
new file mode 100644
index 0000000..1c9e871
--- /dev/null
+++ b/SOURCES/kvm-hw-intc-arm_gicv3_its-Don-t-call-post_load-on-reset.patch
@@ -0,0 +1,65 @@
+From c63efdd05d3c8c79fceba7bb55c4946685e2a191 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:05 +0100
+Subject: [PATCH 4/9] hw/intc/arm_gicv3_its: Don't call post_load on reset
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-5-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77941
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 4/7] hw/intc/arm_gicv3_its: Don't call post_load on reset
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+>From the very beginning, post_load() was called from common
+reset. This is not standard and obliged to discriminate the
+reset case from the restore case using the iidr value.
+
+Let's get rid of that call.
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+
+---
+
+v4 -> V5:
+- added Peter's R-b
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/intc/arm_gicv3_its_common.c | 2 --
+ hw/intc/arm_gicv3_its_kvm.c    | 4 ----
+ 2 files changed, 6 deletions(-)
+
+diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
+index 68b20fc..a029e3c 100644
+--- a/hw/intc/arm_gicv3_its_common.c
++++ b/hw/intc/arm_gicv3_its_common.c
+@@ -129,8 +129,6 @@ static void gicv3_its_common_reset(DeviceState *dev)
+     s->creadr = 0;
+     s->iidr = 0;
+     memset(&s->baser, 0, sizeof(s->baser));
+-
+-    gicv3_its_post_load(s, 0);
+ }
+ 
+ static void gicv3_its_common_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
+index 6fb45df..b1b322b 100644
+--- a/hw/intc/arm_gicv3_its_kvm.c
++++ b/hw/intc/arm_gicv3_its_kvm.c
+@@ -155,10 +155,6 @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
+ {
+     int i;
+ 
+-    if (!s->iidr) {
+-        return;
+-    }
+-
+     kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
+                       GITS_IIDR, &s->iidr, true, &error_abort);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-intc-arm_gicv3_its-Fix-the-VM-termination-in-vm_c.patch b/SOURCES/kvm-hw-intc-arm_gicv3_its-Fix-the-VM-termination-in-vm_c.patch
new file mode 100644
index 0000000..8cdf9b4
--- /dev/null
+++ b/SOURCES/kvm-hw-intc-arm_gicv3_its-Fix-the-VM-termination-in-vm_c.patch
@@ -0,0 +1,63 @@
+From 1bc2106857269cd428567fed2f8afedd25c2c288 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:03 +0100
+Subject: [PATCH 2/9] hw/intc/arm_gicv3_its: Fix the VM termination in
+ vm_change_state_handler()
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-3-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77937
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 2/7] hw/intc/arm_gicv3_its: Fix the VM termination in vm_change_state_handler()
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+From: Shanker Donthineni <shankerd@codeaurora.org>
+
+The commit cddafd8f353d ("hw/intc/arm_gicv3_its: Implement state save
+/restore") breaks the backward compatibility with the older kernels
+where vITS save/restore support is not available. The vmstate function
+vm_change_state_handler() should not be registered if the running kernel
+doesn't support ITS save/restore feature. Otherwise VM instance will be
+killed whenever vmstate callback function is invoked.
+
+Observed a virtual machine shutdown with QEMU-2.10+linux-4.11 when testing
+the reboot command "virsh reboot <domain> --mode acpi" instead of reboot.
+
+KVM Error: 'KVM_SET_DEVICE_ATTR failed: Group 4 attr 0x00000000000001'
+
+Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 1509712671-16299-1-git-send-email-shankerd@codeaurora.org
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 3a575cd2c2411f139a95ace4b2523bc1dfd21755)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/intc/arm_gicv3_its_kvm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
+index 39903d5..9b00ce5 100644
+--- a/hw/intc/arm_gicv3_its_kvm.c
++++ b/hw/intc/arm_gicv3_its_kvm.c
+@@ -111,13 +111,13 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
+             error_free(s->migration_blocker);
+             return;
+         }
++    } else {
++        qemu_add_vm_change_state_handler(vm_change_state_handler, s);
+     }
+ 
+     kvm_msi_use_devid = true;
+     kvm_gsi_direct_mapping = false;
+     kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
+-
+-    qemu_add_vm_change_state_handler(vm_change_state_handler, s);
+ }
+ 
+ /**
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-intc-arm_gicv3_its-Implement-a-minimalist-reset.patch b/SOURCES/kvm-hw-intc-arm_gicv3_its-Implement-a-minimalist-reset.patch
new file mode 100644
index 0000000..2dc874d
--- /dev/null
+++ b/SOURCES/kvm-hw-intc-arm_gicv3_its-Implement-a-minimalist-reset.patch
@@ -0,0 +1,122 @@
+From ef9a83242e22841ce988c14870fd9391dc832a99 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:06 +0100
+Subject: [PATCH 5/9] hw/intc/arm_gicv3_its: Implement a minimalist reset
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-6-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77943
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 5/7] hw/intc/arm_gicv3_its: Implement a minimalist reset
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+At the moment the ITS is not properly reset and this causes
+various bugs on save/restore. We implement a minimalist reset
+through individual register writes but for kernel versions
+before v4.15 this fails voiding the vITS cache. We cannot
+claim we have a comprehensive reset (hence the error message)
+but that's better than nothing.
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+
+---
+v5 -> v6:
+- add class_size
+
+v4 -> v5:
+- correct error message
+
+v2 -> v3:
+- individual register writes performed in kvm_arm_its_reset
+- check KVM_DEV_ARM_VGIC_GRP_ITS_REGS support
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/intc/arm_gicv3_its_kvm.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
+index b1b322b..1c663ac 100644
+--- a/hw/intc/arm_gicv3_its_kvm.c
++++ b/hw/intc/arm_gicv3_its_kvm.c
+@@ -28,6 +28,16 @@
+ 
+ #define TYPE_KVM_ARM_ITS "arm-its-kvm"
+ #define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
++#define KVM_ARM_ITS_CLASS(klass) \
++     OBJECT_CLASS_CHECK(KVMARMITSClass, (klass), TYPE_KVM_ARM_ITS)
++#define KVM_ARM_ITS_GET_CLASS(obj) \
++     OBJECT_GET_CLASS(KVMARMITSClass, (obj), TYPE_KVM_ARM_ITS)
++
++typedef struct KVMARMITSClass {
++    GICv3ITSCommonClass parent_class;
++    void (*parent_reset)(DeviceState *dev);
++} KVMARMITSClass;
++
+ 
+ static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
+ {
+@@ -186,6 +196,34 @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
+                       GITS_CTLR, &s->ctlr, true, &error_abort);
+ }
+ 
++static void kvm_arm_its_reset(DeviceState *dev)
++{
++    GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
++    KVMARMITSClass *c = KVM_ARM_ITS_GET_CLASS(s);
++    int i;
++
++    c->parent_reset(dev);
++
++    error_report("ITS KVM: full reset is not supported by QEMU");
++
++    if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
++                               GITS_CTLR)) {
++        return;
++    }
++
++    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
++                      GITS_CTLR, &s->ctlr, true, &error_abort);
++
++    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
++                      GITS_CBASER, &s->cbaser, true, &error_abort);
++
++    for (i = 0; i < 8; i++) {
++        kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
++                          GITS_BASER + i * 8, &s->baser[i], true,
++                          &error_abort);
++    }
++}
++
+ static Property kvm_arm_its_props[] = {
+     DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
+                      GICv3State *),
+@@ -196,12 +234,15 @@ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(klass);
+     GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
++    KVMARMITSClass *ic = KVM_ARM_ITS_CLASS(klass);
+ 
+     dc->realize = kvm_arm_its_realize;
+     dc->props   = kvm_arm_its_props;
++    ic->parent_reset = dc->reset;
+     icc->send_msi = kvm_its_send_msi;
+     icc->pre_save = kvm_arm_its_pre_save;
+     icc->post_load = kvm_arm_its_post_load;
++    dc->reset = kvm_arm_its_reset;
+ }
+ 
+ static const TypeInfo kvm_arm_its_info = {
+@@ -209,6 +250,7 @@ static const TypeInfo kvm_arm_its_info = {
+     .parent = TYPE_ARM_GICV3_ITS_COMMON,
+     .instance_size = sizeof(GICv3ITSState),
+     .class_init = kvm_arm_its_class_init,
++    .class_size = sizeof(KVMARMITSClass),
+ };
+ 
+ static void kvm_arm_its_register_types(void)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-intc-arm_gicv3_its-Implement-full-reset.patch b/SOURCES/kvm-hw-intc-arm_gicv3_its-Implement-full-reset.patch
new file mode 100644
index 0000000..82552ae
--- /dev/null
+++ b/SOURCES/kvm-hw-intc-arm_gicv3_its-Implement-full-reset.patch
@@ -0,0 +1,49 @@
+From 4a5658befb21d06adda6e6faf5c507990f08d270 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:08 +0100
+Subject: [PATCH 7/9] hw/intc/arm_gicv3_its: Implement full reset
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-8-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77942
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 7/7] hw/intc/arm_gicv3_its: Implement full reset
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+Voiding the ITS caches is not supposed to happen via
+individual register writes. So we introduced a dedicated
+ITS KVM device ioctl to perform a cold reset of the ITS:
+KVM_DEV_ARM_VGIC_GRP_CTRL/KVM_DEV_ARM_ITS_CTRL_RESET. Let's
+use this latter if the kernel supports it.
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/intc/arm_gicv3_its_kvm.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
+index 1c663ac..bf290b8 100644
+--- a/hw/intc/arm_gicv3_its_kvm.c
++++ b/hw/intc/arm_gicv3_its_kvm.c
+@@ -204,7 +204,14 @@ static void kvm_arm_its_reset(DeviceState *dev)
+ 
+     c->parent_reset(dev);
+ 
+-    error_report("ITS KVM: full reset is not supported by QEMU");
++    if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
++                               KVM_DEV_ARM_ITS_CTRL_RESET)) {
++        kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
++                          KVM_DEV_ARM_ITS_CTRL_RESET, NULL, true, &error_abort);
++        return;
++    }
++
++    error_report("ITS KVM: full reset is not supported by the host kernel");
+ 
+     if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
+                                GITS_CTLR)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-misc-add-vmcoreinfo-device.patch b/SOURCES/kvm-hw-misc-add-vmcoreinfo-device.patch
new file mode 100644
index 0000000..1feae60
--- /dev/null
+++ b/SOURCES/kvm-hw-misc-add-vmcoreinfo-device.patch
@@ -0,0 +1,257 @@
+From a230ce8214e3d23ddb3aae86c9afa9bfb0242e83 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:05 +0100
+Subject: [PATCH 07/21] hw/misc: add vmcoreinfo device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-4-marcandre.lureau@redhat.com>
+Patchwork-id: 77924
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/9] hw/misc: add vmcoreinfo device
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+See docs/specs/vmcoreinfo.txt for details.
+
+"etc/vmcoreinfo" fw_cfg entry is added when using "-device vmcoreinfo".
+
+Minor conflict in hw/misc/Makefile.objs due to commented device
+introduced in commit 0e72e616b2d80e47c0eb6c5976276e9f8d920e92
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit 6e43353f10c6688060af0bc26bdfdd4cf9c96ea2)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ docs/specs/vmcoreinfo.txt    | 41 +++++++++++++++++++
+ hw/misc/Makefile.objs        |  1 +
+ hw/misc/vmcoreinfo.c         | 96 ++++++++++++++++++++++++++++++++++++++++++++
+ include/hw/misc/vmcoreinfo.h | 46 +++++++++++++++++++++
+ 4 files changed, 184 insertions(+)
+ create mode 100644 docs/specs/vmcoreinfo.txt
+ create mode 100644 hw/misc/vmcoreinfo.c
+ create mode 100644 include/hw/misc/vmcoreinfo.h
+
+diff --git a/docs/specs/vmcoreinfo.txt b/docs/specs/vmcoreinfo.txt
+new file mode 100644
+index 0000000..2868a77
+--- /dev/null
++++ b/docs/specs/vmcoreinfo.txt
+@@ -0,0 +1,41 @@
++=================
++VMCoreInfo device
++=================
++
++The `-device vmcoreinfo` will create a fw_cfg entry for a guest to
++store dump details.
++
++etc/vmcoreinfo
++**************
++
++A guest may use this fw_cfg entry to add information details to qemu
++dumps.
++
++The entry of 16 bytes has the following layout, in little-endian::
++
++#define VMCOREINFO_FORMAT_NONE 0x0
++#define VMCOREINFO_FORMAT_ELF 0x1
++
++    struct FWCfgVMCoreInfo {
++        uint16_t host_format;  /* formats host supports */
++        uint16_t guest_format; /* format guest supplies */
++        uint32_t size;         /* size of vmcoreinfo region */
++        uint64_t paddr;        /* physical address of vmcoreinfo region */
++    };
++
++Only full write (of 16 bytes) are considered valid for further
++processing of entry values.
++
++A write of 0 in guest_format will disable further processing of
++vmcoreinfo entry values & content.
++
++Format & content
++****************
++
++As of qemu 2.11, only VMCOREINFO_FORMAT_ELF is supported.
++
++The entry gives location and size of an ELF note that is appended in
++qemu dumps.
++
++The note format/class must be of the target bitness and the size must
++be less than 1Mb.
+diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
+index a1007ae..b4cbebf 100644
+--- a/hw/misc/Makefile.objs
++++ b/hw/misc/Makefile.objs
+@@ -9,6 +9,7 @@ common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
+ common-obj-$(CONFIG_EDU) += edu.o
+ 
+ #common-obj-y += unimp.o
++common-obj-y += vmcoreinfo.o
+ 
+ obj-$(CONFIG_VMPORT) += vmport.o
+ 
+diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c
+new file mode 100644
+index 0000000..a618e12
+--- /dev/null
++++ b/hw/misc/vmcoreinfo.c
+@@ -0,0 +1,96 @@
++/*
++ * Virtual Machine coreinfo device
++ *
++ * Copyright (C) 2017 Red Hat, Inc.
++ *
++ * Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or later.
++ * See the COPYING file in the top-level directory.
++ *
++ */
++#include "qemu/osdep.h"
++#include "qapi/error.h"
++#include "hw/nvram/fw_cfg.h"
++#include "hw/misc/vmcoreinfo.h"
++
++static void fw_cfg_vmci_write(void *dev, off_t offset, size_t len)
++{
++    VMCoreInfoState *s = VMCOREINFO(dev);
++
++    s->has_vmcoreinfo = offset == 0 && len == sizeof(s->vmcoreinfo)
++        && s->vmcoreinfo.guest_format != VMCOREINFO_FORMAT_NONE;
++}
++
++static void vmcoreinfo_reset(void *dev)
++{
++    VMCoreInfoState *s = VMCOREINFO(dev);
++
++    s->has_vmcoreinfo = false;
++    memset(&s->vmcoreinfo, 0, sizeof(s->vmcoreinfo));
++    s->vmcoreinfo.host_format = cpu_to_le16(VMCOREINFO_FORMAT_ELF);
++}
++
++static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
++{
++    VMCoreInfoState *s = VMCOREINFO(dev);
++    FWCfgState *fw_cfg = fw_cfg_find();
++
++    /* Given that this function is executing, there is at least one VMCOREINFO
++     * device. Check if there are several.
++     */
++    if (!vmcoreinfo_find()) {
++        error_setg(errp, "at most one %s device is permitted",
++                   VMCOREINFO_DEVICE);
++        return;
++    }
++
++    if (!fw_cfg || !fw_cfg->dma_enabled) {
++        error_setg(errp, "%s device requires fw_cfg with DMA",
++                   VMCOREINFO_DEVICE);
++        return;
++    }
++
++    fw_cfg_add_file_callback(fw_cfg, "etc/vmcoreinfo",
++                             NULL, fw_cfg_vmci_write, s,
++                             &s->vmcoreinfo, sizeof(s->vmcoreinfo), false);
++
++    qemu_register_reset(vmcoreinfo_reset, dev);
++}
++
++static const VMStateDescription vmstate_vmcoreinfo = {
++    .name = "vmcoreinfo",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .fields = (VMStateField[]) {
++        VMSTATE_BOOL(has_vmcoreinfo, VMCoreInfoState),
++        VMSTATE_UINT16(vmcoreinfo.host_format, VMCoreInfoState),
++        VMSTATE_UINT16(vmcoreinfo.guest_format, VMCoreInfoState),
++        VMSTATE_UINT32(vmcoreinfo.size, VMCoreInfoState),
++        VMSTATE_UINT64(vmcoreinfo.paddr, VMCoreInfoState),
++        VMSTATE_END_OF_LIST()
++    },
++};
++
++static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data)
++{
++    DeviceClass *dc = DEVICE_CLASS(klass);
++
++    dc->vmsd = &vmstate_vmcoreinfo;
++    dc->realize = vmcoreinfo_realize;
++    dc->hotpluggable = false;
++}
++
++static const TypeInfo vmcoreinfo_device_info = {
++    .name          = VMCOREINFO_DEVICE,
++    .parent        = TYPE_DEVICE,
++    .instance_size = sizeof(VMCoreInfoState),
++    .class_init    = vmcoreinfo_device_class_init,
++};
++
++static void vmcoreinfo_register_types(void)
++{
++    type_register_static(&vmcoreinfo_device_info);
++}
++
++type_init(vmcoreinfo_register_types)
+diff --git a/include/hw/misc/vmcoreinfo.h b/include/hw/misc/vmcoreinfo.h
+new file mode 100644
+index 0000000..c3aa856
+--- /dev/null
++++ b/include/hw/misc/vmcoreinfo.h
+@@ -0,0 +1,46 @@
++/*
++ * Virtual Machine coreinfo device
++ *
++ * Copyright (C) 2017 Red Hat, Inc.
++ *
++ * Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or later.
++ * See the COPYING file in the top-level directory.
++ *
++ */
++#ifndef VMCOREINFO_H
++#define VMCOREINFO_H
++
++#include "hw/qdev.h"
++
++#define VMCOREINFO_DEVICE "vmcoreinfo"
++#define VMCOREINFO(obj) OBJECT_CHECK(VMCoreInfoState, (obj), VMCOREINFO_DEVICE)
++
++#define VMCOREINFO_FORMAT_NONE 0x0
++#define VMCOREINFO_FORMAT_ELF 0x1
++
++/* all fields are little-endian */
++typedef struct FWCfgVMCoreInfo {
++    uint16_t host_format; /* set on reset */
++    uint16_t guest_format;
++    uint32_t size;
++    uint64_t paddr;
++} QEMU_PACKED FWCfgVMCoreInfo;
++
++typedef struct VMCoreInfoState {
++    DeviceClass parent_obj;
++
++    bool has_vmcoreinfo;
++    FWCfgVMCoreInfo vmcoreinfo;
++} VMCoreInfoState;
++
++/* returns NULL unless there is exactly one device */
++static inline VMCoreInfoState *vmcoreinfo_find(void)
++{
++    Object *o = object_resolve_path_type("", VMCOREINFO_DEVICE, NULL);
++
++    return o ? VMCOREINFO(o) : NULL;
++}
++
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-nvram-spapr_nvram-Device-can-not-be-created-by-th.patch b/SOURCES/kvm-hw-nvram-spapr_nvram-Device-can-not-be-created-by-th.patch
new file mode 100644
index 0000000..fbc403f
--- /dev/null
+++ b/SOURCES/kvm-hw-nvram-spapr_nvram-Device-can-not-be-created-by-th.patch
@@ -0,0 +1,58 @@
+From 04b5f1821a275b874f372ad3c0f758305b856545 Mon Sep 17 00:00:00 2001
+From: Sam Bobroff <sbobroff@redhat.com>
+Date: Tue, 10 Oct 2017 03:07:14 +0200
+Subject: [PATCH 32/34] hw/nvram/spapr_nvram: Device can not be created by the
+ users
+
+RH-Author: Sam Bobroff <sbobroff@redhat.com>
+Message-id: <1507604834-28278-1-git-send-email-sbobroff@redhat.com>
+Patchwork-id: 77048
+O-Subject: [PATCH] hw/nvram/spapr_nvram: Device can not be created by the users
+Bugzilla: 1490869
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Thomas Huth <thuth@redhat.com>
+
+Trying to add a spapr-nvram device currently aborts QEMU like this:
+
+$ ppc64-softmmu/qemu-system-ppc64  -device spapr-nvram
+qemu-system-ppc64: hw/ppc/spapr_rtas.c:407: spapr_rtas_register:
+ Assertion `!rtas_table[token].name' failed.
+Aborted (core dumped)
+
+This NVRAM device registers RTAS calls during its realize function
+and thus can only be used once - and that's internally from spapr.c.
+So let's mark the device with user_creatable = false to avoid that
+the users can crash their QEMU this way.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 280503ee9d7833a793770d732dda5358659825e9)
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1490869
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14217542
+Testing: Run "ppc64-softmmu/qemu-system-ppc64  -device spapr-nvram".
+Signed-off-by: Sam Bobroff <sbobroff@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/nvram/spapr_nvram.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
+index bc355a4..4a0aec8 100644
+--- a/hw/nvram/spapr_nvram.c
++++ b/hw/nvram/spapr_nvram.c
+@@ -264,6 +264,8 @@ static void spapr_nvram_class_init(ObjectClass *klass, void *data)
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     dc->props = spapr_nvram_properties;
+     dc->vmsd = &vmstate_spapr_nvram;
++    /* Reason: Internal device only, uses spapr_rtas_register() in realize() */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo spapr_nvram_type_info = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-add-QEMU-specific-PCI-capability-to-the-Gener.patch b/SOURCES/kvm-hw-pci-add-QEMU-specific-PCI-capability-to-the-Gener.patch
new file mode 100644
index 0000000..8ea5a55
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-add-QEMU-specific-PCI-capability-to-the-Gener.patch
@@ -0,0 +1,128 @@
+From e624b4d9b2fcc27ce36cb2a37009d8083ee3ca9e Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Mon, 13 Nov 2017 15:59:40 +0100
+Subject: [PATCH 02/30] hw/pci: add QEMU-specific PCI capability to the Generic
+ PCI Express Root Port
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20171113155940.50793-3-marcel@redhat.com>
+Patchwork-id: 77663
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 2/2] hw/pci: add QEMU-specific PCI capability to the Generic PCI Express Root Port
+Bugzilla: 1437113
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+
+From: Aleksandr Bezzubikov <zuban32s@gmail.com>
+
+To enable hotplugging of a newly created pcie-pci-bridge,
+we need to tell firmware (e.g. SeaBIOS) to reserve
+additional buses or IO/MEM/PREF space for pcie-root-port.
+Additional bus reservation allows us to hotplug pcie-pci-bridge into this root port.
+The number of buses and IO/MEM/PREF space to reserve are provided to the device via
+a corresponding property, and to the firmware via new PCI capability.
+The properties' default values are -1 to keep default behavior unchanged.
+
+Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Tested-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 226263fb5cdaa4a4a95f1680fabbc9dd2123fd67)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-bridge/gen_pcie_root_port.c | 36 ++++++++++++++++++++++++++++++++++++
+ include/hw/pci/pcie_port.h         |  1 +
+ 2 files changed, 37 insertions(+)
+
+diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
+index cb694d6..ed03ffc 100644
+--- a/hw/pci-bridge/gen_pcie_root_port.c
++++ b/hw/pci-bridge/gen_pcie_root_port.c
+@@ -16,6 +16,8 @@
+ #include "hw/pci/pcie_port.h"
+ 
+ #define TYPE_GEN_PCIE_ROOT_PORT                "pcie-root-port"
++#define GEN_PCIE_ROOT_PORT(obj) \
++        OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT)
+ 
+ #define GEN_PCIE_ROOT_PORT_AER_OFFSET           0x100
+ #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR       1
+@@ -26,6 +28,13 @@ typedef struct GenPCIERootPort {
+     /*< public >*/
+ 
+     bool migrate_msix;
++
++    /* additional resources to reserve on firmware init */
++    uint32_t bus_reserve;
++    uint64_t io_reserve;
++    uint64_t mem_reserve;
++    uint64_t pref32_reserve;
++    uint64_t pref64_reserve;
+ } GenPCIERootPort;
+ 
+ static uint8_t gen_rp_aer_vector(const PCIDevice *d)
+@@ -60,6 +69,24 @@ static bool gen_rp_test_migrate_msix(void *opaque, int version_id)
+     return rp->migrate_msix;
+ }
+ 
++static void gen_rp_realize(DeviceState *dev, Error **errp)
++{
++    PCIDevice *d = PCI_DEVICE(dev);
++    GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d);
++    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
++
++    rpc->parent_realize(dev, errp);
++
++    int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve,
++            grp->io_reserve, grp->mem_reserve, grp->pref32_reserve,
++            grp->pref64_reserve, errp);
++
++    if (rc < 0) {
++        rpc->parent_class.exit(d);
++        return;
++    }
++}
++
+ static const VMStateDescription vmstate_rp_dev = {
+     .name = "pcie-root-port",
+     .version_id = 1,
+@@ -78,6 +105,11 @@ static const VMStateDescription vmstate_rp_dev = {
+ 
+ static Property gen_rp_props[] = {
+     DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true),
++    DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1),
++    DEFINE_PROP_SIZE("io-reserve", GenPCIERootPort, io_reserve, -1),
++    DEFINE_PROP_SIZE("mem-reserve", GenPCIERootPort, mem_reserve, -1),
++    DEFINE_PROP_SIZE("pref32-reserve", GenPCIERootPort, pref32_reserve, -1),
++    DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, pref64_reserve, -1),
+     DEFINE_PROP_END_OF_LIST()
+ };
+ 
+@@ -92,6 +124,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void *data)
+     dc->desc = "PCI Express Root Port";
+     dc->vmsd = &vmstate_rp_dev;
+     dc->props = gen_rp_props;
++
++    rpc->parent_realize = dc->realize;
++    dc->realize = gen_rp_realize;
++
+     rpc->aer_vector = gen_rp_aer_vector;
+     rpc->interrupts_init = gen_rp_interrupts_init;
+     rpc->interrupts_uninit = gen_rp_interrupts_uninit;
+diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
+index 1333266..0736014 100644
+--- a/include/hw/pci/pcie_port.h
++++ b/include/hw/pci/pcie_port.h
+@@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s);
+ 
+ typedef struct PCIERootPortClass {
+     PCIDeviceClass parent_class;
++    DeviceRealize parent_realize;
+ 
+     uint8_t (*aer_vector)(const PCIDevice *dev);
+     int (*interrupts_init)(PCIDevice *dev, Error **errp);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-bridge-fix-QEMU-crash-because-of-pcie-root-po.patch b/SOURCES/kvm-hw-pci-bridge-fix-QEMU-crash-because-of-pcie-root-po.patch
new file mode 100644
index 0000000..8eb5672
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-bridge-fix-QEMU-crash-because-of-pcie-root-po.patch
@@ -0,0 +1,53 @@
+From c424945b8ae8bbb6ce6aa6a9178b55b3b7498975 Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Thu, 18 Jan 2018 15:49:40 +0100
+Subject: [PATCH 07/21] hw/pci-bridge: fix QEMU crash because of pcie-root-port
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20180118154940.32815-1-marcel@redhat.com>
+Patchwork-id: 78666
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] hw/pci-bridge: fix QEMU crash because of pcie-root-port
+Bugzilla: 1520858
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+If we try to use more pcie_root_ports then available slots
+and an IO hint is passed to the port, QEMU crashes because
+we try to init the "IO hint" capability even if the device
+is not created.
+Fix it by checking for error before adding the capability,
+so QEMU can fail gracefully.
+
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit fced4d00e68e7559c73746d963265f7fd0b6abf9)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-bridge/gen_pcie_root_port.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
+index ad4e6aa..0e2f2e8 100644
+--- a/hw/pci-bridge/gen_pcie_root_port.c
++++ b/hw/pci-bridge/gen_pcie_root_port.c
+@@ -74,8 +74,13 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
+     PCIDevice *d = PCI_DEVICE(dev);
+     GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d);
+     PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
++    Error *local_err = NULL;
+ 
+-    rpc->parent_realize(dev, errp);
++    rpc->parent_realize(dev, &local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        return;
++    }
+ 
+     int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve,
+             grp->io_reserve, grp->mem_reserve, grp->pref32_reserve,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-host-Fix-x86-Host-Bridges-64bit-PCI-hole.patch b/SOURCES/kvm-hw-pci-host-Fix-x86-Host-Bridges-64bit-PCI-hole.patch
new file mode 100644
index 0000000..f1aa555
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-host-Fix-x86-Host-Bridges-64bit-PCI-hole.patch
@@ -0,0 +1,333 @@
+From 888e98c6d61b16f59867b91e41af9c878f4d1193 Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Fri, 17 Nov 2017 16:26:38 +0100
+Subject: [PATCH 29/30] hw/pci-host: Fix x86 Host Bridges 64bit PCI hole
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20171117162638.34466-1-marcel@redhat.com>
+Patchwork-id: 77746
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] hw/pci-host: Fix x86 Host Bridges 64bit PCI hole
+Bugzilla: 1390346
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+Tests: Hotplug an ivshmem device with 2G on Q35 and I440fx machines
+       (passes only if this patch is applied)
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+    - include/hw/i386/pc.h
+    Moved x-pci-hole64-fix compat property from PC_COMPAT_2_10
+    to PC_RHEL7_4_COMPAT
+
+Currently there is no MMIO range over 4G
+reserved for PCI hotplug. Since the 32bit PCI hole
+depends on the number of cold-plugged PCI devices
+and other factors, it is very possible is too small
+to hotplug PCI devices with large BARs.
+
+Fix it by reserving 2G for I4400FX chipset
+in order to comply with older Win32 Guest OSes
+and 32G for Q35 chipset.
+
+Even if the new defaults of pci-hole64-size will appear in
+"info qtree" also for older machines, the property was
+not implemented so no changes will be visible to guests.
+
+Note this is a regression since prev QEMU versions had
+some range reserved for 64bit PCI hotplug.
+
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 9fa99d2519cbf71f871e46871df12cb446dc1c3e)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+---
+ hw/i386/pc.c              | 22 ++++++++++++++++++++++
+ hw/pci-host/piix.c        | 32 ++++++++++++++++++++++++++++++--
+ hw/pci-host/q35.c         | 42 +++++++++++++++++++++++++++++++++++++++---
+ include/hw/i386/pc.h      | 12 +++++++++++-
+ include/hw/pci-host/q35.h |  1 +
+ 5 files changed, 103 insertions(+), 6 deletions(-)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index 83df57f..f37d60a 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -1482,6 +1482,28 @@ void pc_memory_init(PCMachineState *pcms,
+     pcms->ioapic_as = &address_space_memory;
+ }
+ 
++/*
++ * The 64bit pci hole starts after "above 4G RAM" and
++ * potentially the space reserved for memory hotplug.
++ */
++uint64_t pc_pci_hole64_start(void)
++{
++    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
++    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
++    uint64_t hole64_start = 0;
++
++    if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) {
++        hole64_start = pcms->hotplug_memory.base;
++        if (!pcmc->broken_reserved_end) {
++            hole64_start += memory_region_size(&pcms->hotplug_memory.mr);
++        }
++    } else {
++        hole64_start = 0x100000000ULL + pcms->above_4g_mem_size;
++    }
++
++    return ROUND_UP(hole64_start, 1ULL << 30);
++}
++
+ qemu_irq pc_allocate_cpu_irq(void)
+ {
+     return qemu_allocate_irq(pic_irq_request, NULL, 0);
+diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
+index 68c3922..dc37bdf 100644
+--- a/hw/pci-host/piix.c
++++ b/hw/pci-host/piix.c
+@@ -50,6 +50,7 @@ typedef struct I440FXState {
+     PCIHostState parent_obj;
+     Range pci_hole;
+     uint64_t pci_hole64_size;
++    bool pci_hole64_fix;
+     uint32_t short_root_bus;
+ } I440FXState;
+ 
+@@ -112,6 +113,9 @@ struct PCII440FXState {
+ #define I440FX_PAM_SIZE 7
+ #define I440FX_SMRAM    0x72
+ 
++/* Keep it 2G to comply with older win32 guests */
++#define I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 31)
++
+ /* Older coreboot versions (4.0 and older) read a config register that doesn't
+  * exist in real hardware, to get the RAM size from QEMU.
+  */
+@@ -238,29 +242,52 @@ static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v,
+     visit_type_uint32(v, name, &value, errp);
+ }
+ 
++/*
++ * The 64bit PCI hole start is set by the Guest firmware
++ * as the address of the first 64bit PCI MEM resource.
++ * If no PCI device has resources on the 64bit area,
++ * the 64bit PCI hole will start after "over 4G RAM" and the
++ * reserved space for memory hotplug if any.
++ */
+ static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
+                                                 const char *name,
+                                                 void *opaque, Error **errp)
+ {
+     PCIHostState *h = PCI_HOST_BRIDGE(obj);
++    I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
+     Range w64;
+     uint64_t value;
+ 
+     pci_bus_get_w64_range(h->bus, &w64);
+     value = range_is_empty(&w64) ? 0 : range_lob(&w64);
++    if (!value && s->pci_hole64_fix) {
++        value = pc_pci_hole64_start();
++    }
+     visit_type_uint64(v, name, &value, errp);
+ }
+ 
++/*
++ * The 64bit PCI hole end is set by the Guest firmware
++ * as the address of the last 64bit PCI MEM resource.
++ * Then it is expanded to the PCI_HOST_PROP_PCI_HOLE64_SIZE
++ * that can be configured by the user.
++ */
+ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
+                                               const char *name, void *opaque,
+                                               Error **errp)
+ {
+     PCIHostState *h = PCI_HOST_BRIDGE(obj);
++    I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
++    uint64_t hole64_start = pc_pci_hole64_start();
+     Range w64;
+-    uint64_t value;
++    uint64_t value, hole64_end;
+ 
+     pci_bus_get_w64_range(h->bus, &w64);
+     value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
++    hole64_end = ROUND_UP(hole64_start + s->pci_hole64_size, 1ULL << 30);
++    if (s->pci_hole64_fix && value < hole64_end) {
++        value = hole64_end;
++    }
+     visit_type_uint64(v, name, &value, errp);
+ }
+ 
+@@ -863,8 +890,9 @@ static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
+ 
+ static Property i440fx_props[] = {
+     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
+-                     pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
++                     pci_hole64_size, I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT),
+     DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
++    DEFINE_PROP_BOOL("x-pci-hole64-fix", I440FXState, pci_hole64_fix, true),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
+index 9cd07ce..d7cc898 100644
+--- a/hw/pci-host/q35.c
++++ b/hw/pci-host/q35.c
+@@ -37,6 +37,8 @@
+  * Q35 host
+  */
+ 
++#define Q35_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 35)
++
+ static void q35_host_realize(DeviceState *dev, Error **errp)
+ {
+     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+@@ -99,29 +101,52 @@ static void q35_host_get_pci_hole_end(Object *obj, Visitor *v,
+     visit_type_uint32(v, name, &value, errp);
+ }
+ 
++/*
++ * The 64bit PCI hole start is set by the Guest firmware
++ * as the address of the first 64bit PCI MEM resource.
++ * If no PCI device has resources on the 64bit area,
++ * the 64bit PCI hole will start after "over 4G RAM" and the
++ * reserved space for memory hotplug if any.
++ */
+ static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
+                                           const char *name, void *opaque,
+                                           Error **errp)
+ {
+     PCIHostState *h = PCI_HOST_BRIDGE(obj);
++    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
+     Range w64;
+     uint64_t value;
+ 
+     pci_bus_get_w64_range(h->bus, &w64);
+     value = range_is_empty(&w64) ? 0 : range_lob(&w64);
++    if (!value && s->pci_hole64_fix) {
++        value = pc_pci_hole64_start();
++    }
+     visit_type_uint64(v, name, &value, errp);
+ }
+ 
++/*
++ * The 64bit PCI hole end is set by the Guest firmware
++ * as the address of the last 64bit PCI MEM resource.
++ * Then it is expanded to the PCI_HOST_PROP_PCI_HOLE64_SIZE
++ * that can be configured by the user.
++ */
+ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
+                                         const char *name, void *opaque,
+                                         Error **errp)
+ {
+     PCIHostState *h = PCI_HOST_BRIDGE(obj);
++    Q35PCIHost *s = Q35_HOST_DEVICE(obj);
++    uint64_t hole64_start = pc_pci_hole64_start();
+     Range w64;
+-    uint64_t value;
++    uint64_t value, hole64_end;
+ 
+     pci_bus_get_w64_range(h->bus, &w64);
+     value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
++    hole64_end = ROUND_UP(hole64_start + s->mch.pci_hole64_size, 1ULL << 30);
++    if (s->pci_hole64_fix && value < hole64_end) {
++        value = hole64_end;
++    }
+     visit_type_uint64(v, name, &value, errp);
+ }
+ 
+@@ -133,16 +158,25 @@ static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name,
+     visit_type_uint64(v, name, &e->size, errp);
+ }
+ 
++/*
++ * NOTE: setting defaults for the mch.* fields in this table
++ * doesn't work, because mch is a separate QOM object that is
++ * zeroed by the object_initialize(&s->mch, ...) call inside
++ * q35_host_initfn().  The default values for those
++ * properties need to be initialized manually by
++ * q35_host_initfn() after the object_initialize() call.
++ */
+ static Property q35_host_props[] = {
+     DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
+                         MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
+     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
+-                     mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
++                     mch.pci_hole64_size, Q35_PCI_HOST_HOLE64_SIZE_DEFAULT),
+     DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
+     DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
+                      mch.below_4g_mem_size, 0),
+     DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
+                      mch.above_4g_mem_size, 0),
++    DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+@@ -174,7 +208,9 @@ static void q35_host_initfn(Object *obj)
+     object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
+     qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
+     qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
+-
++    /* mch's object_initialize resets the default value, set it again */
++    qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
++                         Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
+     object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
+                         q35_host_get_pci_hole_start,
+                         NULL, NULL, NULL, NULL);
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index 6f65d79..7b46121 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -241,7 +241,6 @@ void pc_guest_info_init(PCMachineState *pcms);
+ #define PCI_HOST_PROP_PCI_HOLE64_SIZE  "pci-hole64-size"
+ #define PCI_HOST_BELOW_4G_MEM_SIZE     "below-4g-mem-size"
+ #define PCI_HOST_ABOVE_4G_MEM_SIZE     "above-4g-mem-size"
+-#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
+ 
+ 
+ void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
+@@ -252,6 +251,7 @@ void pc_memory_init(PCMachineState *pcms,
+                     MemoryRegion *system_memory,
+                     MemoryRegion *rom_memory,
+                     MemoryRegion **ram_memory);
++uint64_t pc_pci_hole64_start(void);
+ qemu_irq pc_allocate_cpu_irq(void);
+ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
+ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
+@@ -1015,6 +1015,16 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+             .driver   = "ICH9-LPC",\
+             .property = "__com.redhat_force-rev1-fadt",\
+             .value    = "on",\
++        },\
++        { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \
++            .driver   = "i440FX-pcihost",\
++            .property = "x-pci-hole64-fix",\
++            .value    = "off",\
++        },\
++        { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \
++            .driver   = "q35-pcihost",\
++            .property = "x-pci-hole64-fix",\
++            .value    = "off",\
+         },
+ 
+ 
+diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
+index 58983c0..8f4ddde 100644
+--- a/include/hw/pci-host/q35.h
++++ b/include/hw/pci-host/q35.h
+@@ -68,6 +68,7 @@ typedef struct Q35PCIHost {
+     PCIExpressHost parent_obj;
+     /*< public >*/
+ 
++    bool pci_hole64_fix;
+     MCHPCIState mch;
+ } Q35PCIHost;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-host-gpex-Implement-PCI-INTx-routing.patch b/SOURCES/kvm-hw-pci-host-gpex-Implement-PCI-INTx-routing.patch
new file mode 100644
index 0000000..4199089
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-host-gpex-Implement-PCI-INTx-routing.patch
@@ -0,0 +1,67 @@
+From aeb5a8995d3eb533fb870f0493c7844679062610 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Mon, 6 Nov 2017 17:08:44 +0100
+Subject: [PATCH 8/9] hw/pci-host/gpex: Implement PCI INTx routing
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1509988125-30275-4-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77510
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 3/4] hw/pci-host/gpex: Implement PCI INTx routing
+Bugzilla: 1460957
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
+
+Now we are able to retrieve the gsi from the INTx pin, let's
+enable intx_to_irq routing. From that point on, irqfd becomes
+usable along with INTx when assigning a PCIe device.
+
+Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
+Signed-off-by: Tushar Jagad <tushar.jagad@linaro.org>
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Tested-by: Feng Kan <fkan@apm.com>
+Message-id: 1505296004-6798-4-git-send-email-eric.auger@redhat.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit d464814ae729f3200234ff74d5f050ddad4f1f20)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-host/gpex.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
+index d6cf621..4090793 100644
+--- a/hw/pci-host/gpex.c
++++ b/hw/pci-host/gpex.c
+@@ -53,6 +53,17 @@ int gpex_set_irq_num(GPEXHost *s, int index, int gsi)
+     return 0;
+ }
+ 
++static PCIINTxRoute gpex_route_intx_pin_to_irq(void *opaque, int pin)
++{
++    PCIINTxRoute route;
++    GPEXHost *s = opaque;
++
++    route.mode = PCI_INTX_ENABLED;
++    route.irq = s->irq_num[pin];
++
++    return route;
++}
++
+ static void gpex_host_realize(DeviceState *dev, Error **errp)
+ {
+     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+@@ -77,6 +88,7 @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
+                                 &s->io_ioport, 0, 4, TYPE_PCIE_BUS);
+ 
+     qdev_set_parent_bus(DEVICE(&s->gpex_root), BUS(pci->bus));
++    pci_bus_set_route_irq_fn(pci->bus, gpex_route_intx_pin_to_irq);
+     qdev_init_nofail(DEVICE(&s->gpex_root));
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-host-gpex-Improve-INTX-to-gsi-routing-error-c.patch b/SOURCES/kvm-hw-pci-host-gpex-Improve-INTX-to-gsi-routing-error-c.patch
new file mode 100644
index 0000000..65674d3
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-host-gpex-Improve-INTX-to-gsi-routing-error-c.patch
@@ -0,0 +1,65 @@
+From 8c777547f451a6d93ae258bbc794be6752af05c4 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Mon, 6 Nov 2017 17:08:45 +0100
+Subject: [PATCH 9/9] hw/pci-host/gpex: Improve INTX to gsi routing error
+ checking
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1509988125-30275-5-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77511
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 4/4] hw/pci-host/gpex: Improve INTX to gsi routing error checking
+Bugzilla: 1460957
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+We exposed gpex_set_irq_num() for machines to set the INTx to
+GSI routing. However if the machine forgets to call that
+function we currently do not check the association was properly
+done. Let's initialize gsi values to -1 and if this value is
+found in gpex_route_intx_pin_to_irq, set the routing mode as
+disabled.
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Message-id: 1508776211-22175-1-git-send-email-eric.auger@redhat.com
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 168df2dea701bbf3118bdfea7794369dfa694d3d)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-host/gpex.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
+index 4090793..edf305b 100644
+--- a/hw/pci-host/gpex.c
++++ b/hw/pci-host/gpex.c
+@@ -57,9 +57,14 @@ static PCIINTxRoute gpex_route_intx_pin_to_irq(void *opaque, int pin)
+ {
+     PCIINTxRoute route;
+     GPEXHost *s = opaque;
++    int gsi = s->irq_num[pin];
+ 
+-    route.mode = PCI_INTX_ENABLED;
+-    route.irq = s->irq_num[pin];
++    route.irq = gsi;
++    if (gsi < 0) {
++        route.mode = PCI_INTX_DISABLED;
++    } else {
++        route.mode = PCI_INTX_ENABLED;
++    }
+ 
+     return route;
+ }
+@@ -81,6 +86,7 @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
+     sysbus_init_mmio(sbd, &s->io_ioport);
+     for (i = 0; i < GPEX_NUM_IRQS; i++) {
+         sysbus_init_irq(sbd, &s->irq[i]);
++        s->irq_num[i] = -1;
+     }
+ 
+     pci->bus = pci_register_bus(dev, "pcie.0", gpex_set_irq,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-host-gpex-Set-INTx-index-gsi-mapping.patch b/SOURCES/kvm-hw-pci-host-gpex-Set-INTx-index-gsi-mapping.patch
new file mode 100644
index 0000000..c285ac9
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-host-gpex-Set-INTx-index-gsi-mapping.patch
@@ -0,0 +1,73 @@
+From 1cd93911c6a461bbe8585b9d4e2d76ba42abead3 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Mon, 6 Nov 2017 17:08:42 +0100
+Subject: [PATCH 6/9] hw/pci-host/gpex: Set INTx index/gsi mapping
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1509988125-30275-2-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77509
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 1/4] hw/pci-host/gpex: Set INTx index/gsi mapping
+Bugzilla: 1460957
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
+
+To implement INTx to gsi routing we need to pass the gpex host
+bridge the gsi associated to each INTx index. Let's introduce
+irq_num array and gpex_set_irq_num setter function.
+
+Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
+Signed-off-by: Tushar Jagad <tushar.jagad@linaro.org>
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Feng Kan <fkan@apm.com>
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Message-id: 1505296004-6798-2-git-send-email-eric.auger@redhat.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 70bfdce6a1263fd06144ecc1c3727c44e562d89b)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-host/gpex.c         | 10 ++++++++++
+ include/hw/pci-host/gpex.h |  3 +++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
+index 59f3132..d6cf621 100644
+--- a/hw/pci-host/gpex.c
++++ b/hw/pci-host/gpex.c
+@@ -43,6 +43,16 @@ static void gpex_set_irq(void *opaque, int irq_num, int level)
+     qemu_set_irq(s->irq[irq_num], level);
+ }
+ 
++int gpex_set_irq_num(GPEXHost *s, int index, int gsi)
++{
++    if (index >= GPEX_NUM_IRQS) {
++        return -EINVAL;
++    }
++
++    s->irq_num[index] = gsi;
++    return 0;
++}
++
+ static void gpex_host_realize(DeviceState *dev, Error **errp)
+ {
+     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
+diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
+index 68c9348..aef38b8 100644
+--- a/include/hw/pci-host/gpex.h
++++ b/include/hw/pci-host/gpex.h
+@@ -51,6 +51,9 @@ typedef struct GPEXHost {
+     MemoryRegion io_ioport;
+     MemoryRegion io_mmio;
+     qemu_irq irq[GPEX_NUM_IRQS];
++    int irq_num[GPEX_NUM_IRQS];
+ } GPEXHost;
+ 
++int gpex_set_irq_num(GPEXHost *s, int index, int gsi);
++
+ #endif /* HW_GPEX_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-host-q35-Remove-redundant-downstream-user_cre.patch b/SOURCES/kvm-hw-pci-host-q35-Remove-redundant-downstream-user_cre.patch
new file mode 100644
index 0000000..6ddb54b
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-host-q35-Remove-redundant-downstream-user_cre.patch
@@ -0,0 +1,40 @@
+From 35474b23b1f30a940333ea5c76ff85080ff4410c Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Thu, 19 Oct 2017 10:16:48 +0200
+Subject: [PATCH 66/69] hw/pci-host/q35: Remove redundant downstream
+ user_creatable = false
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1508408209-5712-3-git-send-email-thuth@redhat.com>
+Patchwork-id: 77374
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/3] hw/pci-host/q35: Remove redundant downstream user_creatable = false
+Bugzilla: 1503998
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+The q35_host_class_init() function already sets user_creatable = false
+in the upstream code, so there is no need to do this with a downstream
+patch again.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-host/q35.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
+index a91418c..0e472f2 100644
+--- a/hw/pci-host/q35.c
++++ b/hw/pci-host/q35.c
+@@ -158,7 +158,6 @@ static void q35_host_class_init(ObjectClass *klass, void *data)
+     dc->user_creatable = false;
+     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+     dc->fw_name = "pci";
+-    dc->user_creatable = false; /* RH state preserve */
+ }
+ 
+ static void q35_host_initfn(Object *obj)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-introduce-bridge-only-vendor-specific-capabil.patch b/SOURCES/kvm-hw-pci-introduce-bridge-only-vendor-specific-capabil.patch
new file mode 100644
index 0000000..0d4e7c4
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-introduce-bridge-only-vendor-specific-capabil.patch
@@ -0,0 +1,128 @@
+From 0153864e153e633e3ebfd4d4091971591d098385 Mon Sep 17 00:00:00 2001
+From: Marcel Apfelbaum <marcel@redhat.com>
+Date: Mon, 13 Nov 2017 15:59:39 +0100
+Subject: [PATCH 01/30] hw/pci: introduce bridge-only vendor-specific
+ capability to provide some hints to firmware
+
+RH-Author: Marcel Apfelbaum <marcel@redhat.com>
+Message-id: <20171113155940.50793-2-marcel@redhat.com>
+Patchwork-id: 77662
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/2] hw/pci: introduce bridge-only vendor-specific capability to provide some hints to firmware
+Bugzilla: 1437113
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+
+From: Aleksandr Bezzubikov <zuban32s@gmail.com>
+
+On PCI init PCI bridges may need some extra info about bus number,
+IO, memory and prefetchable memory to reserve. QEMU can provide this
+with a special vendor-specific PCI capability.
+
+Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Tested-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 70e1ee59bb9490d9ac529e96820a03b346086ca1)
+Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci/pci_bridge.c         | 46 +++++++++++++++++++++++++++++++++++++++++++++
+ include/hw/pci/pci_bridge.h | 25 ++++++++++++++++++++++++
+ 2 files changed, 71 insertions(+)
+
+diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
+index 720119b..17feae5 100644
+--- a/hw/pci/pci_bridge.c
++++ b/hw/pci/pci_bridge.c
+@@ -408,6 +408,52 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
+     br->bus_name = bus_name;
+ }
+ 
++
++int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
++                                     uint32_t bus_reserve, uint64_t io_reserve,
++                                     uint32_t mem_non_pref_reserve,
++                                     uint32_t mem_pref_32_reserve,
++                                     uint64_t mem_pref_64_reserve,
++                                     Error **errp)
++{
++    if (mem_pref_32_reserve != (uint32_t)-1 &&
++        mem_pref_64_reserve != (uint64_t)-1) {
++        error_setg(errp,
++                   "PCI resource reserve cap: PREF32 and PREF64 conflict");
++        return -EINVAL;
++    }
++
++    if (bus_reserve == (uint32_t)-1 &&
++        io_reserve == (uint64_t)-1 &&
++        mem_non_pref_reserve == (uint32_t)-1 &&
++        mem_pref_32_reserve == (uint32_t)-1 &&
++        mem_pref_64_reserve == (uint64_t)-1) {
++        return 0;
++    }
++
++    size_t cap_len = sizeof(PCIBridgeQemuCap);
++    PCIBridgeQemuCap cap = {
++            .len = cap_len,
++            .type = REDHAT_PCI_CAP_RESOURCE_RESERVE,
++            .bus_res = bus_reserve,
++            .io = io_reserve,
++            .mem = mem_non_pref_reserve,
++            .mem_pref_32 = mem_pref_32_reserve,
++            .mem_pref_64 = mem_pref_64_reserve
++    };
++
++    int offset = pci_add_capability(dev, PCI_CAP_ID_VNDR,
++                                    cap_offset, cap_len, errp);
++    if (offset < 0) {
++        return offset;
++    }
++
++    memcpy(dev->config + offset + PCI_CAP_FLAGS,
++           (char *)&cap + PCI_CAP_FLAGS,
++           cap_len - PCI_CAP_FLAGS);
++    return 0;
++}
++
+ static const TypeInfo pci_bridge_type_info = {
+     .name = TYPE_PCI_BRIDGE,
+     .parent = TYPE_PCI_DEVICE,
+diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
+index ff7cbaa..1acadc2 100644
+--- a/include/hw/pci/pci_bridge.h
++++ b/include/hw/pci/pci_bridge.h
+@@ -67,4 +67,29 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
+ #define  PCI_BRIDGE_CTL_DISCARD_STATUS	0x400	/* Discard timer status */
+ #define  PCI_BRIDGE_CTL_DISCARD_SERR	0x800	/* Discard timer SERR# enable */
+ 
++typedef struct PCIBridgeQemuCap {
++    uint8_t id;     /* Standard PCI capability header field */
++    uint8_t next;   /* Standard PCI capability header field */
++    uint8_t len;    /* Standard PCI vendor-specific capability header field */
++    uint8_t type;   /* Red Hat vendor-specific capability type.
++                       Types are defined with REDHAT_PCI_CAP_ prefix */
++
++    uint32_t bus_res;   /* Minimum number of buses to reserve */
++    uint64_t io;        /* IO space to reserve */
++    uint32_t mem;       /* Non-prefetchable memory to reserve */
++    /* At most one of the following two fields may be set to a value
++     * different from -1 */
++    uint32_t mem_pref_32; /* Prefetchable memory to reserve (32-bit MMIO) */
++    uint64_t mem_pref_64; /* Prefetchable memory to reserve (64-bit MMIO) */
++} PCIBridgeQemuCap;
++
++#define REDHAT_PCI_CAP_RESOURCE_RESERVE 1
++
++int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
++                              uint32_t bus_reserve, uint64_t io_reserve,
++                              uint32_t mem_non_pref_reserve,
++                              uint32_t mem_pref_32_reserve,
++                              uint64_t mem_pref_64_reserve,
++                              Error **errp);
++
+ #endif /* QEMU_PCI_BRIDGE_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-ppc-CAS-reset-on-early-device-hotplug.patch b/SOURCES/kvm-hw-ppc-CAS-reset-on-early-device-hotplug.patch
new file mode 100644
index 0000000..e91a1e0
--- /dev/null
+++ b/SOURCES/kvm-hw-ppc-CAS-reset-on-early-device-hotplug.patch
@@ -0,0 +1,157 @@
+From b6e63f25b4569d9e7c48862f3363b7002feec76f Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Wed, 4 Oct 2017 05:40:13 +0200
+Subject: [PATCH 06/34] hw/ppc: CAS reset on early device hotplug
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171004054014.14159-4-dgibson@redhat.com>
+Patchwork-id: 76801
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 3/4] hw/ppc: CAS reset on early device hotplug
+Bugzilla: 1448344
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+
+This patch is a follow up on the discussions made in patch
+"hw/ppc: disable hotplug before CAS is completed" that can be
+found at [1].
+
+At this moment, we do not support CPU/memory hotplug in early
+boot stages, before CAS. When a hotplug occurs, the event is logged
+in an internal RTAS event log queue and an IRQ pulse is fired. In
+regular conditions, the guest handles the interrupt by executing
+check_exception, fetching the generated hotplug event and enabling
+the device for use.
+
+In early boot, this IRQ isn't caught (SLOF does not handle hotplug
+events), leaving the event in the rtas event log queue. If the guest
+executes check_exception due to another hotplug event, the re-assertion
+of the IRQ ends up de-queuing the first hotplug event as well. In short,
+a device hotplugged before CAS is considered coldplugged by SLOF.
+This leads to device misbehavior and, in some cases, guest kernel
+Ooops when trying to unplug the device.
+
+A proper fix would be to turn every device hotplugged before CAS
+as a colplugged device. This is not trivial to do with the current
+code base though - the FDT is written in the guest memory at
+ppc_spapr_reset and can't be retrieved without adding extra state
+(fdt_size for example) that will need to managed and migrated. Adding
+the hotplugged DT in the middle of CAS negotiation via the updated DT
+tree works with CPU devs, but panics the guest kernel at boot. Additional
+analysis would be necessary for LMBs and PCI devices. There are
+questions to be made in QEMU/SLOF/kernel level about how we can make
+this change in a sustainable way.
+
+With Linux guests, a fix would be the kernel executing check_exception
+at boot time, de-queueing the events that happened in early boot and
+processing them. However, even if/when the newer kernels start
+fetching these events at boot time, we need to take care of older
+kernels that won't be doing that.
+
+This patch works around the situation by issuing a CAS reset if a hotplugged
+device is detected during CAS:
+
+- the DRC conditions that warrant a CAS reset is the same as those that
+triggers a DRC migration - the DRC must have a device attached and
+the DRC state is not equal to its ready_state. With that in mind, this
+patch makes use of 'spapr_drc_needed' to determine if a CAS reset
+is needed.
+
+- In the middle of CAS negotiations, the function
+'spapr_hotplugged_dev_before_cas' goes through all the DRCs to see
+if there are any DRC that requires a reset, using spapr_drc_needed. If
+that happens, returns '1' in 'spapr_h_cas_compose_response' which will set
+spapr->cas_reboot to true, causing the machine to reboot.
+
+No changes are made for coldplug devices.
+
+[1] http://lists.nongnu.org/archive/html/qemu-devel/2017-08/msg02855.html
+
+Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 10f12e6450407b18b4d5a6b50d3852dcfd7fff75)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c             | 26 +++++++++++++++++++++++++-
+ hw/ppc/spapr_drc.c         |  2 +-
+ include/hw/ppc/spapr_drc.h |  1 +
+ 3 files changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index a419aa7..d3db051 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -790,6 +790,26 @@ out:
+     return ret;
+ }
+ 
++static bool spapr_hotplugged_dev_before_cas(void)
++{
++    Object *drc_container, *obj;
++    ObjectProperty *prop;
++    ObjectPropertyIterator iter;
++
++    drc_container = container_get(object_get_root(), "/dr-connector");
++    object_property_iter_init(&iter, drc_container);
++    while ((prop = object_property_iter_next(&iter))) {
++        if (!strstart(prop->type, "link<", NULL)) {
++            continue;
++        }
++        obj = object_property_get_link(drc_container, prop->name, NULL);
++        if (spapr_drc_needed(obj)) {
++            return true;
++        }
++    }
++    return false;
++}
++
+ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
+                                  target_ulong addr, target_ulong size,
+                                  sPAPROptionVector *ov5_updates)
+@@ -797,9 +817,13 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
+     void *fdt, *fdt_skel;
+     sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
+ 
++    if (spapr_hotplugged_dev_before_cas()) {
++        return 1;
++    }
++
+     size -= sizeof(hdr);
+ 
+-    /* Create sceleton */
++    /* Create skeleton */
+     fdt_skel = g_malloc0(size);
+     _FDT((fdt_create(fdt_skel, size)));
+     _FDT((fdt_begin_node(fdt_skel, "")));
+diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
+index 031ba7c..85c999d 100644
+--- a/hw/ppc/spapr_drc.c
++++ b/hw/ppc/spapr_drc.c
+@@ -460,7 +460,7 @@ static void drc_reset(void *opaque)
+     spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
+ }
+ 
+-static bool spapr_drc_needed(void *opaque)
++bool spapr_drc_needed(void *opaque)
+ {
+     sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
+     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
+index a7958d0..f8d9f5b 100644
+--- a/include/hw/ppc/spapr_drc.h
++++ b/include/hw/ppc/spapr_drc.h
+@@ -257,6 +257,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
+ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
+                       int fdt_start_offset, Error **errp);
+ void spapr_drc_detach(sPAPRDRConnector *drc);
++bool spapr_drc_needed(void *opaque);
+ 
+ static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-ppc-clear-pending_events-on-machine-reset.patch b/SOURCES/kvm-hw-ppc-clear-pending_events-on-machine-reset.patch
new file mode 100644
index 0000000..a4be089
--- /dev/null
+++ b/SOURCES/kvm-hw-ppc-clear-pending_events-on-machine-reset.patch
@@ -0,0 +1,87 @@
+From 32a2cf9dfe251696b1d26b70723c5014e7ecbf45 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Wed, 4 Oct 2017 05:40:12 +0200
+Subject: [PATCH 05/34] hw/ppc: clear pending_events on machine reset
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171004054014.14159-3-dgibson@redhat.com>
+Patchwork-id: 76803
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 2/4] hw/ppc: clear pending_events on machine reset
+Bugzilla: 1448344
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+
+The sPAPR machine isn't clearing up the pending events QTAILQ on
+machine reboot. This allows for unprocessed hotplug/epow events
+to persist in the queue after reset and, when reasserting the IRQs in
+check_exception later on, these will be being processed by the OS.
+
+This patch implements a new function called 'spapr_clear_pending_events'
+that clears up the pending_events QTAILQ. This helper is then called
+inside ppc_spapr_reset to clear up the events queue, preventing
+old/deprecated events from persisting after a reset.
+
+Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 56258174238eb25df629a53a96e1ac16a32dc7d4)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c         |  1 +
+ hw/ppc/spapr_events.c  | 11 +++++++++++
+ include/hw/ppc/spapr.h |  1 +
+ 3 files changed, 13 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 8d1cfcf..a419aa7 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1393,6 +1393,7 @@ static void ppc_spapr_reset(void)
+     }
+ 
+     qemu_devices_reset();
++    spapr_clear_pending_events(spapr);
+ 
+     /*
+      * We place the device tree and RTAS just below either the top of the RMA,
+diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
+index f952b78..66b8164 100644
+--- a/hw/ppc/spapr_events.c
++++ b/hw/ppc/spapr_events.c
+@@ -700,6 +700,17 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+     rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
+ }
+ 
++void spapr_clear_pending_events(sPAPRMachineState *spapr)
++{
++    sPAPREventLogEntry *entry = NULL;
++
++    QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
++        QTAILQ_REMOVE(&spapr->pending_events, entry, next);
++        g_free(entry->extended_log);
++        g_free(entry);
++    }
++}
++
+ void spapr_events_init(sPAPRMachineState *spapr)
+ {
+     QTAILQ_INIT(&spapr->pending_events);
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 2a303a7..5d161ec 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -662,6 +662,7 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr);
+ int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
+ void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+                           Error **errp);
++void spapr_clear_pending_events(sPAPRMachineState *spapr);
+ 
+ /* CPU and LMB DRC release callbacks. */
+ void spapr_core_release(DeviceState *dev);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-ppc-spapr-Fix-virtio-scsi-bootindex-handling-for-.patch b/SOURCES/kvm-hw-ppc-spapr-Fix-virtio-scsi-bootindex-handling-for-.patch
new file mode 100644
index 0000000..8e3c9d4
--- /dev/null
+++ b/SOURCES/kvm-hw-ppc-spapr-Fix-virtio-scsi-bootindex-handling-for-.patch
@@ -0,0 +1,54 @@
+From 8a285115ee19166f22024326063d330706639914 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Thu, 23 Nov 2017 17:50:30 +0100
+Subject: [PATCH 4/7] hw/ppc/spapr: Fix virtio-scsi bootindex handling for LUNs
+ >= 256
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1511459430-7395-2-git-send-email-thuth@redhat.com>
+Patchwork-id: 77832
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 1/1] hw/ppc/spapr: Fix virtio-scsi bootindex handling for LUNs >= 256
+Bugzilla: 1515393
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+LUNs >= 256 have to be encoded with the so-called "flat space
+addressing method" for virtio-scsi, where an additional bit has to
+be set. SLOF already took care of this with the following commit:
+
+ https://git.qemu.org/?p=SLOF.git;a=commitdiff;h=f72a37713fea47da
+ (see https://bugzilla.redhat.com/show_bug.cgi?id=1431584 for details)
+
+But QEMU does not use this encoding yet for device tree paths
+that have to be handed over to SLOF to deal with the "bootindex"
+property, so SLOF currently fails to boot from virtio-scsi devices
+with LUNs >= 256 in the right boot order. Fix it by using the bit
+to indicate the "flat space addressing method" for LUNs >= 256.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit bac658d1a4dc9dd637b2eb5006abda137071f17f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 96df3a7..2065f09 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -2628,6 +2628,10 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
+              * swap 0100 or 10 << or 20 << ( target lun-id -- srplun )
+              */
+             unsigned id = 0x1000000 | (d->id << 16) | d->lun;
++            if (d->lun >= 256) {
++                /* Use the LUN "flat space addressing method" */
++                id |= 0x4000;
++            }
+             return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
+                                    (uint64_t)id << 32);
+         } else if (usb) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-ppc-spapr.c-abort-unplug_request-if-previous-unpl.patch b/SOURCES/kvm-hw-ppc-spapr.c-abort-unplug_request-if-previous-unpl.patch
new file mode 100644
index 0000000..47d45c4
--- /dev/null
+++ b/SOURCES/kvm-hw-ppc-spapr.c-abort-unplug_request-if-previous-unpl.patch
@@ -0,0 +1,103 @@
+From 351d24dd01468e63230c68aa27adfebbaf052f3e Mon Sep 17 00:00:00 2001
+From: Serhii Popovych <spopovyc@redhat.com>
+Date: Thu, 11 Jan 2018 10:37:46 +0100
+Subject: [PATCH 05/12] hw/ppc/spapr.c: abort unplug_request if previous unplug
+ isn't done
+
+RH-Author: Serhii Popovych <spopovyc@redhat.com>
+Message-id: <1515667066-41734-1-git-send-email-spopovyc@redhat.com>
+Patchwork-id: 78547
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] hw/ppc/spapr.c: abort unplug_request if previous unplug isn't done
+Bugzilla: 1528173
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+
+LMB removal is completed only when the spapr_lmb_release callback
+is called after all DRCs of the dimm are detached. During this
+time, it is possible that a unplug request for the same dimm
+arrives, trying to detach DRCs that were detached by the guest
+in the first unplug_request.
+
+BQL doesn't help in this case - the lock will prevent any concurrent
+removal from happening until the end of spapr_memory_unplug_request
+only. What happens is that the second unplug_request ends up calling
+spapr_drc_detach in a DRC that were detached already, causing an
+assert error in spapr_drc_detach (e.g
+https://bugs.launchpad.net/qemu/+bug/1718118).
+
+spapr_lmb_release uses a structure called sPAPRDIMMState, stored in the
+spapr->pending_dimm_unplugs QTAIL, to track how many LMB DRCs are left
+to be detached by the guest. When there are no more DRCs left, this
+structure is deleted and the pc-dimm unplug handler is called to
+finish the process.
+
+This patch reuses the sPAPRDIMMState to allow unplug_request to know
+if there is an ongoing unplug process for a given dimm, aborting the
+unplug request in this case, by doing the following changes:
+
+- in spapr_lmb_release callback, move the dimm state removal to the
+end, after pc-dimm unplug handler. With this change we can check for
+the existence of the dimm state to see if the unplug process is
+done.
+
+- use spapr_pending_dimm_unplugs_find in spapr_memory_unplug_request
+to check if the dimm state exists. If positive, there is an unplug
+operation already in progress for this dimm, meaning that we should
+abort it and warn the user about it.
+
+Fixes: https://bugs.launchpad.net/qemu/+bug/1718118
+Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 2a129767ebb13ffc29dad6a8e8e6eec06dc38b25)
+Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index d7fac62..e276632 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3070,14 +3070,13 @@ void spapr_lmb_release(DeviceState *dev)
+         return;
+     }
+ 
+-    spapr_pending_dimm_unplugs_remove(spapr, ds);
+-
+     /*
+      * Now that all the LMBs have been removed by the guest, call the
+      * pc-dimm unplug handler to cleanup up the pc-dimm device.
+      */
+     pc_dimm_memory_unplug(dev, &spapr->hotplug_memory, mr);
+     object_unparent(OBJECT(dev));
++    spapr_pending_dimm_unplugs_remove(spapr, ds);
+ }
+ 
+ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
+@@ -3106,6 +3105,19 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
+         goto out;
+     }
+ 
++    /*
++     * An existing pending dimm state for this DIMM means that there is an
++     * unplug operation in progress, waiting for the spapr_lmb_release
++     * callback to complete the job (BQL can't cover that far). In this case,
++     * bail out to avoid detaching DRCs that were already released.
++     */
++    if (spapr_pending_dimm_unplugs_find(spapr, dimm)) {
++        error_setg(&local_err,
++                   "Memory unplug already in progress for device %s",
++                   dev->id);
++        goto out;
++    }
++
+     spapr_pending_dimm_unplugs_add(spapr, nr_lmbs, dimm);
+ 
+     addr = addr_start;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-ppc-spapr_caps-Rework-spapr_caps-to-use-uint8-int.patch b/SOURCES/kvm-hw-ppc-spapr_caps-Rework-spapr_caps-to-use-uint8-int.patch
new file mode 100644
index 0000000..67bd478
--- /dev/null
+++ b/SOURCES/kvm-hw-ppc-spapr_caps-Rework-spapr_caps-to-use-uint8-int.patch
@@ -0,0 +1,719 @@
+From dde06ffd66bbc8aa9232dd2c0b849c074d9fcd06 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:41 +0100
+Subject: [PATCH 13/21] hw/ppc/spapr_caps: Rework spapr_caps to use uint8
+ internal representation
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-7-dgibson@redhat.com>
+Patchwork-id: 78674
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 6/7] hw/ppc/spapr_caps: Rework spapr_caps to use uint8 internal representation
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+Currently spapr_caps are tied to boolean values (on or off). This patch
+reworks the caps so that they can have any uint8 value. This allows more
+capabilities with various values to be represented in the same way
+internally. Capabilities are numbered in ascending order. The internal
+representation of capability values is an array of uint8s in the
+sPAPRMachineState, indexed by capability number.
+
+Capabilities can have their own name, description, options, getter and
+setter functions, type and allow functions. They also each have their own
+section in the migration stream. Capabilities are only migrated if they
+were explictly set on the command line, with the assumption that
+otherwise the default will match.
+
+On migration we ensure that the capability value on the destination
+is greater than or equal to the capability value from the source. So
+long at this remains the case then the migration is considered
+compatible and allowed to continue.
+
+This patch implements generic getter and setter functions for boolean
+capabilities. It also converts the existings cap-htm, cap-vsx and
+cap-dfp capabilities to this new format.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 4e5fe3688e23d61b45cc549ff1322aff8f50ef45)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr.c
+	include/hw/ppc/spapr.h
+
+Some trivial contextual conflicts.  Also conflicts due to difference
+between upstream and downstream machine type versions.  Converted to
+apply to relevant downstream versions.
+
+Again needed adjustment to the pre_save function because its return
+type has been changed upstream, but not downstream.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/spapr.c         |  38 ++++--
+ hw/ppc/spapr_caps.c    | 321 +++++++++++++++++++++++++------------------------
+ include/hw/ppc/spapr.h |  45 +++----
+ 3 files changed, 218 insertions(+), 186 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 41cb2fa..66227c3 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -320,7 +320,7 @@ static void spapr_populate_pa_features(sPAPRMachineState *spapr,
+          */
+         pa_features[3] |= 0x20;
+     }
+-    if (spapr_has_cap(spapr, SPAPR_CAP_HTM) && pa_size > 24) {
++    if ((spapr_get_cap(spapr, SPAPR_CAP_HTM) != 0) && pa_size > 24) {
+         pa_features[24] |= 0x80;    /* Transactional memory support */
+     }
+     if (legacy_guest && pa_size > 40) {
+@@ -566,7 +566,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+      *
+      * Only CPUs for which we create core types in spapr_cpu_core.c
+      * are possible, and all of those have VMX */
+-    if (spapr_has_cap(spapr, SPAPR_CAP_VSX)) {
++    if (spapr_get_cap(spapr, SPAPR_CAP_VSX) != 0) {
+         _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
+     } else {
+         _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
+@@ -575,7 +575,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+     /* Advertise DFP (Decimal Floating Point) if available
+      *   0 / no property == no DFP
+      *   1               == DFP available */
+-    if (spapr_has_cap(spapr, SPAPR_CAP_DFP)) {
++    if (spapr_get_cap(spapr, SPAPR_CAP_DFP) != 0) {
+         _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
+     }
+ 
+@@ -1544,6 +1544,18 @@ static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
+     }
+ }
+ 
++static int spapr_pre_load(void *opaque)
++{
++    int rc;
++
++    rc = spapr_caps_pre_load(opaque);
++    if (rc) {
++        return rc;
++    }
++
++    return 0;
++}
++
+ static int spapr_post_load(void *opaque, int version_id)
+ {
+     sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+@@ -1585,6 +1597,11 @@ static int spapr_post_load(void *opaque, int version_id)
+     return err;
+ }
+ 
++static void spapr_pre_save(void *opaque)
++{
++    spapr_caps_pre_save(opaque);
++}
++
+ static bool version_before_3(void *opaque, int version_id)
+ {
+     return version_id < 3;
+@@ -1705,7 +1722,9 @@ static const VMStateDescription vmstate_spapr = {
+     .name = "spapr",
+     .version_id = 3,
+     .minimum_version_id = 1,
++    .pre_load = spapr_pre_load,
+     .post_load = spapr_post_load,
++    .pre_save = spapr_pre_save,
+     .fields = (VMStateField[]) {
+         /* used to be @next_irq */
+         VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
+@@ -1720,7 +1739,9 @@ static const VMStateDescription vmstate_spapr = {
+         &vmstate_spapr_ov5_cas,
+         &vmstate_spapr_patb_entry,
+         &vmstate_spapr_pending_events,
+-        &vmstate_spapr_caps,
++        &vmstate_spapr_cap_htm,
++        &vmstate_spapr_cap_vsx,
++        &vmstate_spapr_cap_dfp,
+         NULL
+     }
+ };
+@@ -2279,8 +2300,6 @@ static void ppc_spapr_init(MachineState *machine)
+     char *filename;
+     Error *resize_hpt_err = NULL;
+ 
+-    spapr_caps_validate(spapr, &error_fatal);
+-
+     msi_nonbroken = true;
+ 
+     QLIST_INIT(&spapr->phbs);
+@@ -3650,7 +3669,9 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     mc->numa_mem_align_shift = 28;
+     smc->has_power9_support = true;
+ 
+-    smc->default_caps = spapr_caps(SPAPR_CAP_VSX | SPAPR_CAP_DFP);
++    smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
++    smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
++    smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
+     spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+@@ -4056,8 +4077,7 @@ static void spapr_machine_rhel740_class_options(MachineClass *mc)
+     smc->has_power9_support = false;
+     smc->pre_2_10_has_unused_icps = true;
+     smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
+-    smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX
+-                                   | SPAPR_CAP_DFP);
++    smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
+ }
+ 
+ DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false);
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index 2b67ac2..f95a785 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -35,18 +35,51 @@
+ typedef struct sPAPRCapabilityInfo {
+     const char *name;
+     const char *description;
+-    uint64_t flag;
++    const char *options;                        /* valid capability values */
++    int index;
+ 
++    /* Getter and Setter Function Pointers */
++    ObjectPropertyAccessor *get;
++    ObjectPropertyAccessor *set;
++    const char *type;
+     /* Make sure the virtual hardware can support this capability */
+-    void (*allow)(sPAPRMachineState *spapr, Error **errp);
+-
+-    /* If possible, tell the virtual hardware not to allow the cap to
+-     * be used at all */
+-    void (*disallow)(sPAPRMachineState *spapr, Error **errp);
++    void (*apply)(sPAPRMachineState *spapr, uint8_t val, Error **errp);
+ } sPAPRCapabilityInfo;
+ 
+-static void cap_htm_allow(sPAPRMachineState *spapr, Error **errp)
++static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
++                               void *opaque, Error **errp)
++{
++    sPAPRCapabilityInfo *cap = opaque;
++    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
++    bool value = spapr_get_cap(spapr, cap->index) == SPAPR_CAP_ON;
++
++    visit_type_bool(v, name, &value, errp);
++}
++
++static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
++                               void *opaque, Error **errp)
++{
++    sPAPRCapabilityInfo *cap = opaque;
++    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
++    bool value;
++    Error *local_err = NULL;
++
++    visit_type_bool(v, name, &value, &local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        return;
++    }
++
++    spapr->cmd_line_caps[cap->index] = true;
++    spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF;
++}
++
++static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+ {
++    if (!val) {
++        /* TODO: We don't support disabling htm yet */
++        return;
++    }
+     if (tcg_enabled()) {
+         error_setg(errp,
+                    "No Transactional Memory support in TCG, try cap-htm=off");
+@@ -57,11 +90,15 @@ static void cap_htm_allow(sPAPRMachineState *spapr, Error **errp)
+     }
+ }
+ 
+-static void cap_vsx_allow(sPAPRMachineState *spapr, Error **errp)
++static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+ {
+     PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+     CPUPPCState *env = &cpu->env;
+ 
++    if (!val) {
++        /* TODO: We don't support disabling vsx yet */
++        return;
++    }
+     /* Allowable CPUs in spapr_cpu_core.c should already have gotten
+      * rid of anything that doesn't do VMX */
+     g_assert(env->insns_flags & PPC_ALTIVEC);
+@@ -70,37 +107,51 @@ static void cap_vsx_allow(sPAPRMachineState *spapr, Error **errp)
+     }
+ }
+ 
+-static void cap_dfp_allow(sPAPRMachineState *spapr, Error **errp)
++static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+ {
+     PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+     CPUPPCState *env = &cpu->env;
+ 
++    if (!val) {
++        /* TODO: We don't support disabling dfp yet */
++        return;
++    }
+     if (!(env->insns_flags2 & PPC2_DFP)) {
+         error_setg(errp, "DFP support not available, try cap-dfp=off");
+     }
+ }
+ 
+-static sPAPRCapabilityInfo capability_table[] = {
+-    {
++
++sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
++    [SPAPR_CAP_HTM] = {
+         .name = "htm",
+         .description = "Allow Hardware Transactional Memory (HTM)",
+-        .flag = SPAPR_CAP_HTM,
+-        .allow = cap_htm_allow,
+-        /* TODO: add cap_htm_disallow */
++        .options = "",
++        .index = SPAPR_CAP_HTM,
++        .get = spapr_cap_get_bool,
++        .set = spapr_cap_set_bool,
++        .type = "bool",
++        .apply = cap_htm_apply,
+     },
+-    {
++    [SPAPR_CAP_VSX] = {
+         .name = "vsx",
+         .description = "Allow Vector Scalar Extensions (VSX)",
+-        .flag = SPAPR_CAP_VSX,
+-        .allow = cap_vsx_allow,
+-        /* TODO: add cap_vsx_disallow */
++        .options = "",
++        .index = SPAPR_CAP_VSX,
++        .get = spapr_cap_get_bool,
++        .set = spapr_cap_set_bool,
++        .type = "bool",
++        .apply = cap_vsx_apply,
+     },
+-    {
++    [SPAPR_CAP_DFP] = {
+         .name = "dfp",
+         .description = "Allow Decimal Floating Point (DFP)",
+-        .flag = SPAPR_CAP_DFP,
+-        .allow = cap_dfp_allow,
+-        /* TODO: add cap_dfp_disallow */
++        .options = "",
++        .index = SPAPR_CAP_DFP,
++        .get = spapr_cap_get_bool,
++        .set = spapr_cap_set_bool,
++        .type = "bool",
++        .apply = cap_dfp_apply,
+     },
+ };
+ 
+@@ -115,23 +166,33 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+ 
+     if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07,
+                           0, spapr->max_compat_pvr)) {
+-        caps.mask &= ~SPAPR_CAP_HTM;
++        caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
+     }
+ 
+     if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
+                           0, spapr->max_compat_pvr)) {
+-        caps.mask &= ~SPAPR_CAP_VSX;
+-        caps.mask &= ~SPAPR_CAP_DFP;
++        caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF;
++        caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_OFF;
+     }
+ 
+     return caps;
+ }
+ 
+-static bool spapr_caps_needed(void *opaque)
++int spapr_caps_pre_load(void *opaque)
+ {
+     sPAPRMachineState *spapr = opaque;
+ 
+-    return (spapr->forced_caps.mask != 0) || (spapr->forbidden_caps.mask != 0);
++    /* Set to default so we can tell if this came in with the migration */
++    spapr->mig = spapr->def;
++    return 0;
++}
++
++int spapr_caps_pre_save(void *opaque)
++{
++    sPAPRMachineState *spapr = opaque;
++
++    spapr->mig = spapr->eff;
++    return 0;
+ }
+ 
+ /* This has to be called from the top-level spapr post_load, not the
+@@ -140,175 +201,121 @@ static bool spapr_caps_needed(void *opaque)
+  * caps on the destination */
+ int spapr_caps_post_migration(sPAPRMachineState *spapr)
+ {
+-    uint64_t allcaps = 0;
+     int i;
+     bool ok = true;
+-    sPAPRCapabilities dstcaps = spapr->effective_caps;
++    sPAPRCapabilities dstcaps = spapr->eff;
+     sPAPRCapabilities srccaps;
+ 
+     srccaps = default_caps_with_cpu(spapr, first_cpu);
+-    srccaps.mask |= spapr->mig_forced_caps.mask;
+-    srccaps.mask &= ~spapr->mig_forbidden_caps.mask;
++    for (i = 0; i < SPAPR_CAP_NUM; i++) {
++        /* If not default value then assume came in with the migration */
++        if (spapr->mig.caps[i] != spapr->def.caps[i]) {
++            srccaps.caps[i] = spapr->mig.caps[i];
++        }
++    }
+ 
+-    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
++    for (i = 0; i < SPAPR_CAP_NUM; i++) {
+         sPAPRCapabilityInfo *info = &capability_table[i];
+ 
+-        allcaps |= info->flag;
+-
+-        if ((srccaps.mask & info->flag) && !(dstcaps.mask & info->flag)) {
+-            error_report("cap-%s=on in incoming stream, but off in destination",
+-                         info->name);
++        if (srccaps.caps[i] > dstcaps.caps[i]) {
++            error_report("cap-%s higher level (%d) in incoming stream than on destination (%d)",
++                         info->name, srccaps.caps[i], dstcaps.caps[i]);
+             ok = false;
+         }
+ 
+-        if (!(srccaps.mask & info->flag) && (dstcaps.mask & info->flag)) {
+-            warn_report("cap-%s=off in incoming stream, but on in destination",
+-                         info->name);
++        if (srccaps.caps[i] < dstcaps.caps[i]) {
++            warn_report("cap-%s lower level (%d) in incoming stream than on destination (%d)",
++                         info->name, srccaps.caps[i], dstcaps.caps[i]);
+         }
+     }
+ 
+-    if (spapr->mig_forced_caps.mask & ~allcaps) {
+-        error_report(
+-            "Unknown capabilities 0x%"PRIx64" enabled in incoming stream",
+-            spapr->mig_forced_caps.mask & ~allcaps);
+-        ok = false;
+-    }
+-    if (spapr->mig_forbidden_caps.mask & ~allcaps) {
+-        warn_report(
+-            "Unknown capabilities 0x%"PRIx64" disabled in incoming stream",
+-            spapr->mig_forbidden_caps.mask & ~allcaps);
+-    }
+-
+     return ok ? 0 : -EINVAL;
+ }
+ 
+-static void spapr_caps_pre_save(void *opaque)
++static bool spapr_cap_htm_needed(void *opaque)
+ {
+     sPAPRMachineState *spapr = opaque;
+ 
+-    spapr->mig_forced_caps = spapr->forced_caps;
+-    spapr->mig_forbidden_caps = spapr->forbidden_caps;
++    return spapr->cmd_line_caps[SPAPR_CAP_HTM] &&
++           (spapr->eff.caps[SPAPR_CAP_HTM] != spapr->def.caps[SPAPR_CAP_HTM]);
+ }
+ 
+-static int spapr_caps_pre_load(void *opaque)
++const VMStateDescription vmstate_spapr_cap_htm = {
++    .name = "spapr/cap/htm",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .needed = spapr_cap_htm_needed,
++    .fields = (VMStateField[]) {
++        VMSTATE_UINT8(mig.caps[SPAPR_CAP_HTM], sPAPRMachineState),
++        VMSTATE_END_OF_LIST()
++    },
++};
++
++static bool spapr_cap_vsx_needed(void *opaque)
+ {
+     sPAPRMachineState *spapr = opaque;
+ 
+-    spapr->mig_forced_caps = spapr_caps(0);
+-    spapr->mig_forbidden_caps = spapr_caps(0);
+-    return 0;
++    return spapr->cmd_line_caps[SPAPR_CAP_VSX] &&
++           (spapr->eff.caps[SPAPR_CAP_VSX] != spapr->def.caps[SPAPR_CAP_VSX]);
+ }
+ 
+-const VMStateDescription vmstate_spapr_caps = {
+-    .name = "spapr/caps",
++const VMStateDescription vmstate_spapr_cap_vsx = {
++    .name = "spapr/cap/vsx",
+     .version_id = 1,
+     .minimum_version_id = 1,
+-    .needed = spapr_caps_needed,
+-    .pre_save = spapr_caps_pre_save,
+-    .pre_load = spapr_caps_pre_load,
++    .needed = spapr_cap_vsx_needed,
+     .fields = (VMStateField[]) {
+-        VMSTATE_UINT64(mig_forced_caps.mask, sPAPRMachineState),
+-        VMSTATE_UINT64(mig_forbidden_caps.mask, sPAPRMachineState),
++        VMSTATE_UINT8(mig.caps[SPAPR_CAP_VSX], sPAPRMachineState),
+         VMSTATE_END_OF_LIST()
+     },
+ };
+ 
+-void spapr_caps_reset(sPAPRMachineState *spapr)
+-{
+-    Error *local_err = NULL;
+-    sPAPRCapabilities caps;
+-    int i;
+-
+-    /* First compute the actual set of caps we're running with.. */
+-    caps = default_caps_with_cpu(spapr, first_cpu);
+-
+-    /* Remove unnecessary forced/forbidden bits (this will help us
+-     * with migration) */
+-    spapr->forced_caps.mask &= ~caps.mask;
+-    spapr->forbidden_caps.mask &= caps.mask;
+-
+-    caps.mask |= spapr->forced_caps.mask;
+-    caps.mask &= ~spapr->forbidden_caps.mask;
+-
+-    spapr->effective_caps = caps;
+-
+-    /* .. then apply those caps to the virtual hardware */
+-
+-    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
+-        sPAPRCapabilityInfo *info = &capability_table[i];
+-
+-        if (spapr->effective_caps.mask & info->flag) {
+-            /* Failure to allow a cap is fatal - if the guest doesn't
+-             * have it, we'll be supplying an incorrect environment */
+-            if (info->allow) {
+-                info->allow(spapr, &error_fatal);
+-            }
+-        } else {
+-            /* Failure to enforce a cap is only a warning.  The guest
+-             * shouldn't be using it, since it's not advertised, so it
+-             * doesn't get to complain about weird behaviour if it
+-             * goes ahead anyway */
+-            if (info->disallow) {
+-                info->disallow(spapr, &local_err);
+-            }
+-            if (local_err) {
+-                warn_report_err(local_err);
+-                local_err = NULL;
+-            }
+-        }
+-    }
+-}
+-
+-static void spapr_cap_get(Object *obj, Visitor *v, const char *name,
+-                          void *opaque, Error **errp)
++static bool spapr_cap_dfp_needed(void *opaque)
+ {
+-    sPAPRCapabilityInfo *cap = opaque;
+-    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+-    bool value = spapr_has_cap(spapr, cap->flag);
+-
+-    /* TODO: Could this get called before effective_caps is finalized
+-     * in spapr_caps_reset()? */
++    sPAPRMachineState *spapr = opaque;
+ 
+-    visit_type_bool(v, name, &value, errp);
++    return spapr->cmd_line_caps[SPAPR_CAP_DFP] &&
++           (spapr->eff.caps[SPAPR_CAP_DFP] != spapr->def.caps[SPAPR_CAP_DFP]);
+ }
+ 
+-static void spapr_cap_set(Object *obj, Visitor *v, const char *name,
+-                          void *opaque, Error **errp)
+-{
+-    sPAPRCapabilityInfo *cap = opaque;
+-    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+-    bool value;
+-    Error *local_err = NULL;
+-
+-    visit_type_bool(v, name, &value, &local_err);
+-    if (local_err) {
+-        error_propagate(errp, local_err);
+-        return;
+-    }
+-
+-    if (value) {
+-        spapr->forced_caps.mask |= cap->flag;
+-    } else {
+-        spapr->forbidden_caps.mask |= cap->flag;
+-    }
+-}
++const VMStateDescription vmstate_spapr_cap_dfp = {
++    .name = "spapr/cap/dfp",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .needed = spapr_cap_dfp_needed,
++    .fields = (VMStateField[]) {
++        VMSTATE_UINT8(mig.caps[SPAPR_CAP_DFP], sPAPRMachineState),
++        VMSTATE_END_OF_LIST()
++    },
++};
+ 
+-void spapr_caps_validate(sPAPRMachineState *spapr, Error **errp)
++void spapr_caps_reset(sPAPRMachineState *spapr)
+ {
+-    uint64_t allcaps = 0;
++    sPAPRCapabilities default_caps;
+     int i;
+ 
+-    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
+-        g_assert((allcaps & capability_table[i].flag) == 0);
+-        allcaps |= capability_table[i].flag;
++    /* First compute the actual set of caps we're running with.. */
++    default_caps = default_caps_with_cpu(spapr, first_cpu);
++
++    for (i = 0; i < SPAPR_CAP_NUM; i++) {
++        /* Store the defaults */
++        spapr->def.caps[i] = default_caps.caps[i];
++        /* If not set on the command line then apply the default value */
++        if (!spapr->cmd_line_caps[i]) {
++            spapr->eff.caps[i] = default_caps.caps[i];
++        }
+     }
+ 
+-    g_assert((spapr->forced_caps.mask & ~allcaps) == 0);
+-    g_assert((spapr->forbidden_caps.mask & ~allcaps) == 0);
++    /* .. then apply those caps to the virtual hardware */
++
++    for (i = 0; i < SPAPR_CAP_NUM; i++) {
++        sPAPRCapabilityInfo *info = &capability_table[i];
+ 
+-    if (spapr->forced_caps.mask & spapr->forbidden_caps.mask) {
+-        error_setg(errp, "Some sPAPR capabilities set both on and off");
+-        return;
++        /*
++         * If the apply function can't set the desired level and thinks it's
++         * fatal, it should cause that.
++         */
++        info->apply(spapr, spapr->eff.caps[i], &error_fatal);
+     }
+ }
+ 
+@@ -321,17 +328,19 @@ void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
+     for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
+         sPAPRCapabilityInfo *cap = &capability_table[i];
+         const char *name = g_strdup_printf("cap-%s", cap->name);
++        char *desc;
+ 
+-        object_class_property_add(klass, name, "bool",
+-                                  spapr_cap_get, spapr_cap_set, NULL,
+-                                  cap, &local_err);
++        object_class_property_add(klass, name, cap->type,
++                                  cap->get, cap->set,
++                                  NULL, cap, &local_err);
+         if (local_err) {
+             error_propagate(errp, local_err);
+             return;
+         }
+ 
+-        object_class_property_set_description(klass, name, cap->description,
+-                                              &local_err);
++        desc = g_strdup_printf("%s%s", cap->description, cap->options);
++        object_class_property_set_description(klass, name, desc, &local_err);
++        g_free(desc);
+         if (local_err) {
+             error_propagate(errp, local_err);
+             return;
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index df767c3..7156a70 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -54,20 +54,25 @@ typedef enum {
+  * Capabilities
+  */
+ 
+-/* These bits go in the migration stream, so they can't be reassigned */
+-
+ /* Hardware Transactional Memory */
+-#define SPAPR_CAP_HTM               0x0000000000000001ULL
+-
++#define SPAPR_CAP_HTM                   0x00
+ /* Vector Scalar Extensions */
+-#define SPAPR_CAP_VSX               0x0000000000000002ULL
+-
++#define SPAPR_CAP_VSX                   0x01
+ /* Decimal Floating Point */
+-#define SPAPR_CAP_DFP               0x0000000000000004ULL
++#define SPAPR_CAP_DFP                   0x02
++/* Num Caps */
++#define SPAPR_CAP_NUM                   (SPAPR_CAP_DFP + 1)
++
++/*
++ * Capability Values
++ */
++/* Bool Caps */
++#define SPAPR_CAP_OFF                   0x00
++#define SPAPR_CAP_ON                    0x01
+ 
+ typedef struct sPAPRCapabilities sPAPRCapabilities;
+ struct sPAPRCapabilities {
+-    uint64_t mask;
++    uint8_t caps[SPAPR_CAP_NUM];
+ };
+ 
+ /**
+@@ -151,9 +156,8 @@ struct sPAPRMachineState {
+ 
+     const char *icp_type;
+ 
+-    sPAPRCapabilities forced_caps, forbidden_caps;
+-    sPAPRCapabilities mig_forced_caps, mig_forbidden_caps;
+-    sPAPRCapabilities effective_caps;
++    bool cmd_line_caps[SPAPR_CAP_NUM];
++    sPAPRCapabilities def, eff, mig;
+ };
+ 
+ #define H_SUCCESS         0
+@@ -732,24 +736,23 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
+ 
+ #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
+ 
++
++int spapr_caps_pre_load(void *opaque);
++int spapr_caps_pre_save(void *opaque);
++
+ /*
+  * Handling of optional capabilities
+  */
+-extern const VMStateDescription vmstate_spapr_caps;
+-
+-static inline sPAPRCapabilities spapr_caps(uint64_t mask)
+-{
+-    sPAPRCapabilities caps = { mask };
+-    return caps;
+-}
++extern const VMStateDescription vmstate_spapr_cap_htm;
++extern const VMStateDescription vmstate_spapr_cap_vsx;
++extern const VMStateDescription vmstate_spapr_cap_dfp;
+ 
+-static inline bool spapr_has_cap(sPAPRMachineState *spapr, uint64_t cap)
++static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
+ {
+-    return !!(spapr->effective_caps.mask & cap);
++    return spapr->eff.caps[cap];
+ }
+ 
+ void spapr_caps_reset(sPAPRMachineState *spapr);
+-void spapr_caps_validate(sPAPRMachineState *spapr, Error **errp);
+ void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
+ int spapr_caps_post_migration(sPAPRMachineState *spapr);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-ppc-spapr_drc.c-change-spapr_drc_needed-to-use-dr.patch b/SOURCES/kvm-hw-ppc-spapr_drc.c-change-spapr_drc_needed-to-use-dr.patch
new file mode 100644
index 0000000..ee261c3
--- /dev/null
+++ b/SOURCES/kvm-hw-ppc-spapr_drc.c-change-spapr_drc_needed-to-use-dr.patch
@@ -0,0 +1,58 @@
+From 6984d8d007ed94067b37af90b1e20a0aad76a205 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Wed, 4 Oct 2017 05:40:11 +0200
+Subject: [PATCH 04/34] hw/ppc/spapr_drc.c: change spapr_drc_needed to use
+ drc->dev
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171004054014.14159-2-dgibson@redhat.com>
+Patchwork-id: 76799
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/4] hw/ppc/spapr_drc.c: change spapr_drc_needed to use drc->dev
+Bugzilla: 1448344
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+
+This patch makes a small fix in 'spapr_drc_needed' to change how we detect
+if a DRC has a device attached. Previously it used dr_entity_sense for this,
+which  works for physical DRCs.
+
+However, for logical DRCs, it didn't cover the case where a logical DRC has
+a drc->dev but the state is LOGICAL_UNUSABLE (e.g. a hotplugged CPU before
+CAS). In this case, the dr_entity_sense of this DRC returns UNUSABLE and the
+code was considering that there were no dev attached, making spapr_drc_needed
+return 'false' when in fact we would like to migrate the DRC.
+
+Changing it to check for drc->dev instead works for all DRC types.
+
+Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit c618e300eb2276996e7004100686768cf1445128)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_drc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
+index 605697d..031ba7c 100644
+--- a/hw/ppc/spapr_drc.c
++++ b/hw/ppc/spapr_drc.c
+@@ -464,10 +464,9 @@ static bool spapr_drc_needed(void *opaque)
+ {
+     sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
+     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+-    sPAPRDREntitySense value = drck->dr_entity_sense(drc);
+ 
+     /* If no dev is plugged in there is no need to migrate the DRC state */
+-    if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
++    if (!drc->dev) {
+         return false;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-s390x-Mark-the-sclpquiesce-device-with-user_creat.patch b/SOURCES/kvm-hw-s390x-Mark-the-sclpquiesce-device-with-user_creat.patch
new file mode 100644
index 0000000..f9f86fb
--- /dev/null
+++ b/SOURCES/kvm-hw-s390x-Mark-the-sclpquiesce-device-with-user_creat.patch
@@ -0,0 +1,54 @@
+From b4f105203964676facfa604594dcae3e43ee7aa0 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:45 +0200
+Subject: [PATCH 26/34] hw/s390x: Mark the "sclpquiesce" device with
+ user_creatable = false
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-10-git-send-email-thuth@redhat.com>
+Patchwork-id: 77026
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 09/12] hw/s390x: Mark the "sclpquiesce" device with user_creatable = false
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The "sclpquiesce" device is just an internal device that should not be
+created by the user directly. Though it currently does not seem to cause
+any obvious trouble when the user instantiates an additional device, let's
+better mark it with user_creatable = false to avoid unexpected behavior,
+e.g. because the quiesce notifier gets registered multiple times.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1507193105-15627-1-git-send-email-thuth@redhat.com>
+Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit b923ab3112ed5ab47c2ff35776f17ab54c60d651)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/sclpquiesce.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c
+index 762cb18..0241643 100644
+--- a/hw/s390x/sclpquiesce.c
++++ b/hw/s390x/sclpquiesce.c
+@@ -118,8 +118,13 @@ static void quiesce_class_init(ObjectClass *klass, void *data)
+     dc->reset = quiesce_reset;
+     dc->vmsd = &vmstate_sclpquiesce;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+-    k->init = quiesce_init;
++    /*
++     * Reason: This is just an internal device - the notifier should
++     * not be registered multiple times in quiesce_init()
++     */
++    dc->user_creatable = false;
+ 
++    k->init = quiesce_init;
+     k->get_send_mask = send_mask;
+     k->get_receive_mask = receive_mask;
+     k->can_handle_event = can_handle_event;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-cpu-hyperv-support-over-64-vcpus-for-windows-gu.patch b/SOURCES/kvm-i386-cpu-hyperv-support-over-64-vcpus-for-windows-gu.patch
new file mode 100644
index 0000000..9c55fa9
--- /dev/null
+++ b/SOURCES/kvm-i386-cpu-hyperv-support-over-64-vcpus-for-windows-gu.patch
@@ -0,0 +1,116 @@
+From b2f9f4fcaad9c64f4551ab1dbe9e474c3dc6b2b4 Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Mon, 27 Nov 2017 12:59:13 +0100
+Subject: [PATCH 10/15] i386/cpu/hyperv: support over 64 vcpus for windows
+ guests
+
+RH-Author: vrozenfe <vrozenfe@redhat.com>
+Message-id: <1511256034-28105-1-git-send-email-vrozenfe@redhat.com>
+Patchwork-id: 77769
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH v2] i386/cpu/hyperv: support over 64 vcpus for windows guests
+Bugzilla: 1451959
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Gonglei <arei.gonglei@huawei.com>
+
+Upstream-status: 6c69dfb67e84747cf071958594d939e845dfcc0c
+
+Starting with Windows Server 2012 and Windows 8, if
+CPUID.40000005.EAX contains a value of -1, Windows assumes specific
+limit to the number of VPs. In this case, Windows Server 2012
+guest VMs may use more than 64 VPs, up to the maximum supported
+number of processors applicable to the specific Windows
+version being used.
+
+https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
+
+For compatibility, Let's introduce a new property for X86CPU,
+named "x-hv-max-vps" as Eduardo's suggestion, and set it
+to 0x40 before machine 2.10.
+
+(The "x-" prefix indicates that the property is not supposed to
+be a stable user interface.)
+
+Signed-off-by: Gonglei <arei.gonglei@huawei.com>
+Message-Id: <1505143227-14324-1-git-send-email-arei.gonglei@huawei.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com>
+---
+ include/hw/i386/pc.h |  5 +++++
+ target/i386/cpu.c    | 13 +++++++++++++
+ target/i386/cpu.h    |  2 ++
+ target/i386/kvm.c    |  3 ++-
+ 4 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index 7b46121..f9b7998 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -1089,6 +1089,11 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+             .driver = TYPE_X86_CPU,\
+             .property = "kvm-no-smi-migration",\
+             .value    = "on",\
++        },\
++        { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \
++             .driver   = TYPE_X86_CPU,\
++             .property = "x-hv-max-vps",\
++             .value    = "0x40",\
+         },
+ 
+ #define PC_RHEL7_2_COMPAT \
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index ca95336..c2dee60 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -4179,6 +4179,19 @@ static Property x86_cpu_properties[] = {
+                      false),
+     DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
+     DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
++    /*
++     * From "Requirements for Implementing the Microsoft
++     * Hypervisor Interface":
++     * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
++     *
++     * "Starting with Windows Server 2012 and Windows 8, if
++     * CPUID.40000005.EAX contains a value of -1, Windows assumes that
++     * the hypervisor imposes no specific limit to the number of VPs.
++     * In this case, Windows Server 2012 guest VMs may use more than
++     * 64 VPs, up to the maximum supported number of processors applicable
++     * to the specific Windows version being used."
++     */
++    DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
+     DEFINE_PROP_END_OF_LIST()
+ };
+ 
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 0518673..fd73888 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -1282,6 +1282,8 @@ struct X86CPU {
+     int32_t socket_id;
+     int32_t core_id;
+     int32_t thread_id;
++
++    int32_t hv_max_vps;
+ };
+ 
+ static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 739334a..ee4e91f 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -786,7 +786,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
+ 
+         c = &cpuid_data.entries[cpuid_i++];
+         c->function = HYPERV_CPUID_IMPLEMENT_LIMITS;
+-        c->eax = 0x40;
++
++        c->eax = cpu->hv_max_vps;
+         c->ebx = 0x40;
+ 
+         kvm_base = KVM_CPUID_SIGNATURE_NEXT;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-kvm-advertise-Hyper-V-frequency-MSRs.patch b/SOURCES/kvm-i386-kvm-advertise-Hyper-V-frequency-MSRs.patch
new file mode 100644
index 0000000..dd72f1a
--- /dev/null
+++ b/SOURCES/kvm-i386-kvm-advertise-Hyper-V-frequency-MSRs.patch
@@ -0,0 +1,74 @@
+From 8225804259b165300d2d1cc1c4bdbad32fadf6da Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Tue, 10 Oct 2017 14:02:51 +0200
+Subject: [PATCH 13/69] i386/kvm: advertise Hyper-V frequency MSRs
+
+RH-Author: Ladi Prosek <lprosek@redhat.com>
+Message-id: <20171010140251.23801-5-lprosek@redhat.com>
+Patchwork-id: 77063
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 4/4] i386/kvm: advertise Hyper-V frequency MSRs
+Bugzilla: 1500347
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+As of kernel commit eb82feea59d6 ("KVM: hyperv: support HV_X64_MSR_TSC_FREQUENCY
+and HV_X64_MSR_APIC_FREQUENCY"), KVM supports two new MSRs which are required
+for nested Hyper-V to read timestamps with RDTSC + TSC page.
+
+This commit makes QEMU advertise the MSRs with CPUID.40000003H:EAX[11] and
+CPUID.40000003H:EDX[8] as specified in the Hyper-V TLFS and experimentally
+verified on a Hyper-V host. The feature is enabled with the existing hv-time CPU
+flag, and only if the TSC frequency is stable across migrations and known.
+
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20170807085703.32267-5-lprosek@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit d72bc7f6f8a397790abee4a25ba1b8c35dd2b841)
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/kvm.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 2dc01c9..739334a 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -89,6 +89,7 @@ static bool has_msr_hv_vpindex;
+ static bool has_msr_hv_runtime;
+ static bool has_msr_hv_synic;
+ static bool has_msr_hv_stimer;
++static bool has_msr_hv_frequencies;
+ static bool has_msr_xss;
+ 
+ static bool has_msr_architectural_pmu;
+@@ -640,7 +641,13 @@ static int hyperv_handle_properties(CPUState *cs)
+     if (cpu->hyperv_time) {
+         env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
+         env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
+-        env->features[FEAT_HYPERV_EAX] |= 0x200;
++        env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_REFERENCE_TSC_AVAILABLE;
++
++        if (has_msr_hv_frequencies && tsc_is_stable_and_known(env)) {
++            env->features[FEAT_HYPERV_EAX] |= HV_X64_ACCESS_FREQUENCY_MSRS;
++            env->features[FEAT_HYPERV_EDX] |=
++                HV_FEATURE_FREQUENCY_MSRS_AVAILABLE;
++        }
+     }
+     if (cpu->hyperv_crash && has_msr_hv_crash) {
+         env->features[FEAT_HYPERV_EDX] |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
+@@ -1134,6 +1141,9 @@ static int kvm_get_supported_msrs(KVMState *s)
+                 case HV_X64_MSR_STIMER0_CONFIG:
+                     has_msr_hv_stimer = true;
+                     break;
++                case HV_X64_MSR_TSC_FREQUENCY:
++                    has_msr_hv_frequencies = true;
++                    break;
+                 }
+             }
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-kvm-introduce-tsc_is_stable_and_known.patch b/SOURCES/kvm-i386-kvm-introduce-tsc_is_stable_and_known.patch
new file mode 100644
index 0000000..c8f4690
--- /dev/null
+++ b/SOURCES/kvm-i386-kvm-introduce-tsc_is_stable_and_known.patch
@@ -0,0 +1,61 @@
+From d9e6ce9628a29f7992dd381a54aae14d45078bf8 Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Tue, 10 Oct 2017 14:02:50 +0200
+Subject: [PATCH 12/69] i386/kvm: introduce tsc_is_stable_and_known()
+
+RH-Author: Ladi Prosek <lprosek@redhat.com>
+Message-id: <20171010140251.23801-4-lprosek@redhat.com>
+Patchwork-id: 77062
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/4] i386/kvm: introduce tsc_is_stable_and_known()
+Bugzilla: 1500347
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+Move the "is TSC stable and known" condition to a reusable helper.
+
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20170807085703.32267-4-lprosek@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 4bb95b82df7ea4a1c7de15649dd16a70a19e6bab)
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/kvm.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 15d56ae..2dc01c9 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -611,6 +611,15 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
+     return 0;
+ }
+ 
++static bool tsc_is_stable_and_known(CPUX86State *env)
++{
++    if (!env->tsc_khz) {
++        return false;
++    }
++    return (env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
++        || env->user_tsc_khz;
++}
++
+ static int hyperv_handle_properties(CPUState *cs)
+ {
+     X86CPU *cpu = X86_CPU(cs);
+@@ -986,9 +995,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
+         && cpu->expose_kvm
+         && kvm_base == KVM_CPUID_SIGNATURE
+         /* TSC clock must be stable and known for this feature. */
+-        && ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
+-            || env->user_tsc_khz != 0)
+-        && env->tsc_khz != 0) {
++        && tsc_is_stable_and_known(env)) {
+ 
+         c = &cpuid_data.entries[cpuid_i++];
+         c->function = KVM_CPUID_SIGNATURE | 0x10;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-kvm-set-tsc_khz-before-configuring-Hyper-V-CPUI.patch b/SOURCES/kvm-i386-kvm-set-tsc_khz-before-configuring-Hyper-V-CPUI.patch
new file mode 100644
index 0000000..02db5ee
--- /dev/null
+++ b/SOURCES/kvm-i386-kvm-set-tsc_khz-before-configuring-Hyper-V-CPUI.patch
@@ -0,0 +1,87 @@
+From 4297501331fd196444ad0b830b026ae39c2744cf Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Tue, 10 Oct 2017 14:02:49 +0200
+Subject: [PATCH 11/69] i386/kvm: set tsc_khz before configuring Hyper-V CPUID
+
+RH-Author: Ladi Prosek <lprosek@redhat.com>
+Message-id: <20171010140251.23801-3-lprosek@redhat.com>
+Patchwork-id: 77060
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/4] i386/kvm: set tsc_khz before configuring Hyper-V CPUID
+Bugzilla: 1500347
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+Timing-related Hyper-V enlightenments will benefit from knowing the final
+tsc_khz value. This commit just moves the code in preparation for further
+changes.
+
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Message-Id: <20170807085703.32267-3-lprosek@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit ddb98b5a9ff27b21100da1d701ddf5da34c66673)
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/kvm.c | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index b14a0db..15d56ae 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -695,6 +695,25 @@ int kvm_arch_init_vcpu(CPUState *cs)
+ 
+     cpuid_i = 0;
+ 
++    r = kvm_arch_set_tsc_khz(cs);
++    if (r < 0) {
++        goto fail;
++    }
++
++    /* vcpu's TSC frequency is either specified by user, or following
++     * the value used by KVM if the former is not present. In the
++     * latter case, we query it from KVM and record in env->tsc_khz,
++     * so that vcpu's TSC frequency can be migrated later via this field.
++     */
++    if (!env->tsc_khz) {
++        r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
++            kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
++            -ENOTSUP;
++        if (r > 0) {
++            env->tsc_khz = r;
++        }
++    }
++
+     /* Paravirtualization CPUIDs */
+     if (hyperv_enabled(cpu)) {
+         c = &cpuid_data.entries[cpuid_i++];
+@@ -961,25 +980,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
+         }
+     }
+ 
+-    r = kvm_arch_set_tsc_khz(cs);
+-    if (r < 0) {
+-        goto fail;
+-    }
+-
+-    /* vcpu's TSC frequency is either specified by user, or following
+-     * the value used by KVM if the former is not present. In the
+-     * latter case, we query it from KVM and record in env->tsc_khz,
+-     * so that vcpu's TSC frequency can be migrated later via this field.
+-     */
+-    if (!env->tsc_khz) {
+-        r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+-            kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
+-            -ENOTSUP;
+-        if (r > 0) {
+-            env->tsc_khz = r;
+-        }
+-    }
+-
+     if (cpu->vmware_cpuid_freq
+         /* Guests depend on 0x40000000 to detect this feature, so only expose
+          * it if KVM exposes leaf 0x40000000. (Conflicts with Hyper-V) */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-kvm-use-a-switch-statement-for-MSR-detection.patch b/SOURCES/kvm-i386-kvm-use-a-switch-statement-for-MSR-detection.patch
new file mode 100644
index 0000000..d7a78f5
--- /dev/null
+++ b/SOURCES/kvm-i386-kvm-use-a-switch-statement-for-MSR-detection.patch
@@ -0,0 +1,131 @@
+From 5657d9d31587d9e5e2e89ec5036af88dccb3a6a7 Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Tue, 10 Oct 2017 14:02:48 +0200
+Subject: [PATCH 10/69] i386/kvm: use a switch statement for MSR detection
+
+RH-Author: Ladi Prosek <lprosek@redhat.com>
+Message-id: <20171010140251.23801-2-lprosek@redhat.com>
+Patchwork-id: 77059
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/4] i386/kvm: use a switch statement for MSR detection
+Bugzilla: 1500347
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+Switch is easier on the eye and might lead to better codegen.
+
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20170807085703.32267-2-lprosek@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 1d268dece4991915c0dd0f882248cbcb22ae8ffc)
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/kvm.c | 75 +++++++++++++++++++++++--------------------------------
+ 1 file changed, 31 insertions(+), 44 deletions(-)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 6db7783..b14a0db 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -1081,65 +1081,52 @@ static int kvm_get_supported_msrs(KVMState *s)
+             int i;
+ 
+             for (i = 0; i < kvm_msr_list->nmsrs; i++) {
+-                if (kvm_msr_list->indices[i] == MSR_STAR) {
++                switch (kvm_msr_list->indices[i]) {
++                case MSR_STAR:
+                     has_msr_star = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
++                    break;
++                case MSR_VM_HSAVE_PA:
+                     has_msr_hsave_pa = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_TSC_AUX) {
++                    break;
++                case MSR_TSC_AUX:
+                     has_msr_tsc_aux = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_TSC_ADJUST) {
++                    break;
++                case MSR_TSC_ADJUST:
+                     has_msr_tsc_adjust = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) {
++                    break;
++                case MSR_IA32_TSCDEADLINE:
+                     has_msr_tsc_deadline = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_IA32_SMBASE) {
++                    break;
++                case MSR_IA32_SMBASE:
+                     has_msr_smbase = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_IA32_MISC_ENABLE) {
++                    break;
++                case MSR_IA32_MISC_ENABLE:
+                     has_msr_misc_enable = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_IA32_BNDCFGS) {
++                    break;
++                case MSR_IA32_BNDCFGS:
+                     has_msr_bndcfgs = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == MSR_IA32_XSS) {
++                    break;
++                case MSR_IA32_XSS:
+                     has_msr_xss = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == HV_X64_MSR_CRASH_CTL) {
++                    break;;
++                case HV_X64_MSR_CRASH_CTL:
+                     has_msr_hv_crash = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) {
++                    break;
++                case HV_X64_MSR_RESET:
+                     has_msr_hv_reset = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) {
++                    break;
++                case HV_X64_MSR_VP_INDEX:
+                     has_msr_hv_vpindex = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) {
++                    break;
++                case HV_X64_MSR_VP_RUNTIME:
+                     has_msr_hv_runtime = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
++                    break;
++                case HV_X64_MSR_SCONTROL:
+                     has_msr_hv_synic = true;
+-                    continue;
+-                }
+-                if (kvm_msr_list->indices[i] == HV_X64_MSR_STIMER0_CONFIG) {
++                    break;
++                case HV_X64_MSR_STIMER0_CONFIG:
+                     has_msr_hv_stimer = true;
+-                    continue;
++                    break;
+                 }
+             }
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ide-avoid-referencing-NULL-dev-in-rotational-rate-se.patch b/SOURCES/kvm-ide-avoid-referencing-NULL-dev-in-rotational-rate-se.patch
new file mode 100644
index 0000000..c5947e8
--- /dev/null
+++ b/SOURCES/kvm-ide-avoid-referencing-NULL-dev-in-rotational-rate-se.patch
@@ -0,0 +1,46 @@
+From 565928c4292fcc32ecb34c1516283929d7fcaf90 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 29 Nov 2017 14:26:06 +0100
+Subject: [PATCH 20/21] ide: avoid referencing NULL dev in rotational rate
+ setting
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171129142606.15965-4-berrange@redhat.com>
+Patchwork-id: 77972
+O-Subject: [PATCH RHV-7.5 qemu-kvm-rhev 3/3] ide: avoid referencing NULL dev in rotational rate setting
+Bugzilla: 1498042
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+The 'dev' variable can be NULL when the guest OS calls identify on an IDE
+unit that does not have a drive attached to it.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: 20171020091403.1479-1-berrange@redhat.com
+Signed-off-by: John Snow <jsnow@redhat.com>
+(cherry picked from commit 96f43c2b0a663f4789b51ed97297163321e7ba5e)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ide/core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/ide/core.c b/hw/ide/core.c
+index 11986e3..506e8ed 100644
+--- a/hw/ide/core.c
++++ b/hw/ide/core.c
+@@ -191,7 +191,9 @@ static void ide_identify(IDEState *s)
+     if (dev && dev->conf.discard_granularity) {
+         put_le16(p + 169, 1); /* TRIM support */
+     }
+-    put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */
++    if (dev) {
++        put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */
++    }
+ 
+     ide_identify_size(s);
+     s->identify_set = 1;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ide-support-reporting-of-rotation-rate.patch b/SOURCES/kvm-ide-support-reporting-of-rotation-rate.patch
new file mode 100644
index 0000000..3569f44
--- /dev/null
+++ b/SOURCES/kvm-ide-support-reporting-of-rotation-rate.patch
@@ -0,0 +1,86 @@
+From 0bb526e2aa90f3f9143472da23ae3b64a4e3216d Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 29 Nov 2017 14:26:05 +0100
+Subject: [PATCH 19/21] ide: support reporting of rotation rate
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171129142606.15965-3-berrange@redhat.com>
+Patchwork-id: 77965
+O-Subject: [PATCH RHV-7.5 qemu-kvm-rhev 2/3] ide: support reporting of rotation rate
+Bugzilla: 1498042
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+The Linux kernel will query the ATA IDENTITY DEVICE data, word 217
+to determine the rotations per minute of the disk. If this has
+the value 1, it is taken to be an SSD and so Linux sets the
+'rotational' flag to 0 for the I/O queue and will stop using that
+disk as a source of random entropy. Other operating systems may
+also take into account rotation rate when setting up default
+behaviour.
+
+Mgmt apps should be able to set the rotation rate for virtualized
+block devices, based on characteristics of the host storage in use,
+so that the guest OS gets sensible behaviour out of the box. This
+patch thus adds a 'rotation-rate' parameter for 'ide-hd' device
+types.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Message-Id: <20171004114008.14849-3-berrange@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 3b19f4506901ecce25ff36cf62353a2b4bfe4f2b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ide/core.c             | 1 +
+ hw/ide/qdev.c             | 1 +
+ include/hw/ide/internal.h | 8 ++++++++
+ 3 files changed, 10 insertions(+)
+
+diff --git a/hw/ide/core.c b/hw/ide/core.c
+index bea3953..11986e3 100644
+--- a/hw/ide/core.c
++++ b/hw/ide/core.c
+@@ -191,6 +191,7 @@ static void ide_identify(IDEState *s)
+     if (dev && dev->conf.discard_granularity) {
+         put_le16(p + 169, 1); /* TRIM support */
+     }
++    put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */
+ 
+     ide_identify_size(s);
+     s->identify_set = 1;
+diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
+index cc2f5bd..a412d6f 100644
+--- a/hw/ide/qdev.c
++++ b/hw/ide/qdev.c
+@@ -304,6 +304,7 @@ static Property ide_hd_properties[] = {
+     DEFINE_BLOCK_CHS_PROPERTIES(IDEDrive, dev.conf),
+     DEFINE_PROP_BIOS_CHS_TRANS("bios-chs-trans",
+                 IDEDrive, dev.chs_trans, BIOS_ATA_TRANSLATION_AUTO),
++    DEFINE_PROP_UINT16("rotation_rate", IDEDrive, dev.rotation_rate, 0),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
+index 482a951..f1aca72 100644
+--- a/include/hw/ide/internal.h
++++ b/include/hw/ide/internal.h
+@@ -507,6 +507,14 @@ struct IDEDevice {
+     char *serial;
+     char *model;
+     uint64_t wwn;
++    /*
++     * 0x0000        - rotation rate not reported
++     * 0x0001        - non-rotating medium (SSD)
++     * 0x0002-0x0400 - reserved
++     * 0x0401-0xffe  - rotations per minute
++     * 0xffff        - reserved
++     */
++    uint16_t rotation_rate;
+ };
+ 
+ /* These are used for the error_status field of IDEBus */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-intel_iommu-fix-missing-BQL-in-pt-fast-path.patch b/SOURCES/kvm-intel_iommu-fix-missing-BQL-in-pt-fast-path.patch
new file mode 100644
index 0000000..f5b6ed5
--- /dev/null
+++ b/SOURCES/kvm-intel_iommu-fix-missing-BQL-in-pt-fast-path.patch
@@ -0,0 +1,74 @@
+From f2fb460ba2b9c5547f8bcf4d7542a5e17bbe09bd Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Mon, 9 Oct 2017 06:51:32 +0200
+Subject: [PATCH 05/69] intel_iommu: fix missing BQL in pt fast path
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20171009065132.5597-2-peterx@redhat.com>
+Patchwork-id: 76929
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 1/1] intel_iommu: fix missing BQL in pt fast path
+Bugzilla: 1449067
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+In vtd_switch_address_space() we did the memory region switch, however
+it's possible that the caller of it has not taken the BQL at all. Make
+sure we have it.
+
+CC: Paolo Bonzini <pbonzini@redhat.com>
+CC: Jason Wang <jasowang@redhat.com>
+CC: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 66a4a0318e6b9539505491e4576fb93a708095d8)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/i386/intel_iommu.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
+index a7bf87a..3a5bb0b 100644
+--- a/hw/i386/intel_iommu.c
++++ b/hw/i386/intel_iommu.c
+@@ -957,6 +957,8 @@ static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
+ static bool vtd_switch_address_space(VTDAddressSpace *as)
+ {
+     bool use_iommu;
++    /* Whether we need to take the BQL on our own */
++    bool take_bql = !qemu_mutex_iothread_locked();
+ 
+     assert(as);
+ 
+@@ -967,6 +969,15 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
+                                    VTD_PCI_FUNC(as->devfn),
+                                    use_iommu);
+ 
++    /*
++     * It's possible that we reach here without BQL, e.g., when called
++     * from vtd_pt_enable_fast_path(). However the memory APIs need
++     * it. We'd better make sure we have had it already, or, take it.
++     */
++    if (take_bql) {
++        qemu_mutex_lock_iothread();
++    }
++
+     /* Turn off first then on the other */
+     if (use_iommu) {
+         memory_region_set_enabled(&as->sys_alias, false);
+@@ -976,6 +987,10 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
+         memory_region_set_enabled(&as->sys_alias, true);
+     }
+ 
++    if (take_bql) {
++        qemu_mutex_unlock_iothread();
++    }
++
+     return use_iommu;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Add-missing-GCC_FMT_ATTR-fix-Werror-suggest-attri.patch b/SOURCES/kvm-io-Add-missing-GCC_FMT_ATTR-fix-Werror-suggest-attri.patch
new file mode 100644
index 0000000..f880743
--- /dev/null
+++ b/SOURCES/kvm-io-Add-missing-GCC_FMT_ATTR-fix-Werror-suggest-attri.patch
@@ -0,0 +1,56 @@
+From 14a39ceeb99060eae4088513e0e81f5946c442fd Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:57:02 +0100
+Subject: [PATCH 22/42] io: Add missing GCC_FMT_ATTR (fix
+ -Werror=suggest-attribute=format)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-21-berrange@redhat.com>
+Patchwork-id: 78473
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 20/20] io: Add missing GCC_FMT_ATTR (fix -Werror=suggest-attribute=format)
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Stefan Weil <sw@weilnetz.de>
+
+This fixes a compiler warning:
+
+/qemu/io/channel-websock.c:163:5: error:
+ function might be possible candidate for ‘gnu_printf’ format attribute
+ [-Werror=suggest-attribute=format]
+
+Signed-off-by: Stefan Weil <sw@weilnetz.de>
+Acked-by: Daniel P. Berrange <berrange@redhat.com>
+Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
+(cherry picked from commit 52aa5644e8e89ebfc3b1d0abdb7cc502ce9db599)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index df2c3a9..87ebdeb 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -152,9 +152,10 @@ enum {
+     QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA
+ };
+ 
+-static void qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
+-                                                   const char *resmsg,
+-                                                   ...)
++static void GCC_FMT_ATTR(2, 3)
++qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
++                                       const char *resmsg,
++                                       ...)
+ {
+     va_list vargs;
+     char *response;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Add-support-for-fragmented-websocket-binary-frame.patch b/SOURCES/kvm-io-Add-support-for-fragmented-websocket-binary-frame.patch
new file mode 100644
index 0000000..0a12afa
--- /dev/null
+++ b/SOURCES/kvm-io-Add-support-for-fragmented-websocket-binary-frame.patch
@@ -0,0 +1,95 @@
+From 6b05946c92a9fee7398d948be3505a294d27f76b Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:48 +0100
+Subject: [PATCH 08/42] io: Add support for fragmented websocket binary frames
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-7-berrange@redhat.com>
+Patchwork-id: 78461
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 06/20] io: Add support for fragmented websocket binary frames
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Allows fragmented binary frames by saving the previous opcode. Handles
+the case where an intermediary (i.e., web proxy) fragments frames
+originally sent unfragmented by the client.
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit ff1300e626949fa9850b0f91dc5e8c2cb45b6a88)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/io/channel-websock.h |  1 +
+ io/channel-websock.c         | 26 ++++++++++++++++++--------
+ 2 files changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/include/io/channel-websock.h b/include/io/channel-websock.h
+index 3c9ff84..7c89655 100644
+--- a/include/io/channel-websock.h
++++ b/include/io/channel-websock.h
+@@ -65,6 +65,7 @@ struct QIOChannelWebsock {
+     guint io_tag;
+     Error *io_err;
+     gboolean io_eof;
++    uint8_t opcode;
+ };
+ 
+ /**
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 4e5afb2..909d636 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -636,28 +636,38 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+     has_mask = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK;
+     payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;
+ 
++    /* Save or restore opcode. */
++    if (opcode) {
++        ioc->opcode = opcode;
++    } else {
++        opcode = ioc->opcode;
++    }
++
+     if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
+         /* disconnect */
+         return 0;
+     }
+ 
+     /* Websocket frame sanity check:
+-     * * Websocket fragmentation is not supported.
+-     * * All  websockets frames sent by a client have to be masked.
++     * * Fragmentation is only supported for binary frames.
++     * * All frames sent by a client MUST be masked.
+      * * Only binary encoding is supported.
+      */
+     if (!fin) {
+-        error_setg(errp, "websocket fragmentation is not supported");
+-        return -1;
++        if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
++            error_setg(errp, "only binary websocket frames may be fragmented");
++            return -1;
++        }
++    } else {
++        if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
++            error_setg(errp, "only binary websocket frames are supported");
++            return -1;
++        }
+     }
+     if (!has_mask) {
+         error_setg(errp, "client websocket frames must be masked");
+         return -1;
+     }
+-    if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+-        error_setg(errp, "only binary websocket frames are supported");
+-        return -1;
+-    }
+ 
+     if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) {
+         ioc->payload_remain = payload_len;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Allow-empty-websocket-payload.patch b/SOURCES/kvm-io-Allow-empty-websocket-payload.patch
new file mode 100644
index 0000000..ed08d1b
--- /dev/null
+++ b/SOURCES/kvm-io-Allow-empty-websocket-payload.patch
@@ -0,0 +1,109 @@
+From 56192448a2221f518f3e959f511e1244100de600 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:49 +0100
+Subject: [PATCH 09/42] io: Allow empty websocket payload
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-8-berrange@redhat.com>
+Patchwork-id: 78453
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 07/20] io: Allow empty websocket payload
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Some browsers send pings/pongs with no payload, so allow empty payloads
+instead of closing the connection.
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 3a29640e2cbae9d47b89ffaf98ed358920eb6797)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 62 +++++++++++++++++++++++++---------------------------
+ 1 file changed, 30 insertions(+), 32 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 909d636..b19b5d9 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -697,44 +697,42 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+                                               Error **errp)
+ {
+     size_t i;
+-    size_t payload_len;
++    size_t payload_len = 0;
+     uint32_t *payload32;
+ 
+-    if (!ioc->payload_remain) {
+-        error_setg(errp,
+-                   "Decoding payload but no bytes of payload remain");
+-        return -1;
+-    }
+-
+-    /* If we aren't at the end of the payload, then drop
+-     * off the last bytes, so we're always multiple of 4
+-     * for purpose of unmasking, except at end of payload
+-     */
+-    if (ioc->encinput.offset < ioc->payload_remain) {
+-        payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4);
+-    } else {
+-        payload_len = ioc->payload_remain;
+-    }
+-    if (payload_len == 0) {
+-        return QIO_CHANNEL_ERR_BLOCK;
+-    }
++    if (ioc->payload_remain) {
++        /* If we aren't at the end of the payload, then drop
++         * off the last bytes, so we're always multiple of 4
++         * for purpose of unmasking, except at end of payload
++         */
++        if (ioc->encinput.offset < ioc->payload_remain) {
++            payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4);
++        } else {
++            payload_len = ioc->payload_remain;
++        }
++        if (payload_len == 0) {
++            return QIO_CHANNEL_ERR_BLOCK;
++        }
+ 
+-    ioc->payload_remain -= payload_len;
++        ioc->payload_remain -= payload_len;
+ 
+-    /* unmask frame */
+-    /* process 1 frame (32 bit op) */
+-    payload32 = (uint32_t *)ioc->encinput.buffer;
+-    for (i = 0; i < payload_len / 4; i++) {
+-        payload32[i] ^= ioc->mask.u;
+-    }
+-    /* process the remaining bytes (if any) */
+-    for (i *= 4; i < payload_len; i++) {
+-        ioc->encinput.buffer[i] ^= ioc->mask.c[i % 4];
++        /* unmask frame */
++        /* process 1 frame (32 bit op) */
++        payload32 = (uint32_t *)ioc->encinput.buffer;
++        for (i = 0; i < payload_len / 4; i++) {
++            payload32[i] ^= ioc->mask.u;
++        }
++        /* process the remaining bytes (if any) */
++        for (i *= 4; i < payload_len; i++) {
++            ioc->encinput.buffer[i] ^= ioc->mask.c[i % 4];
++        }
+     }
+ 
+-    buffer_reserve(&ioc->rawinput, payload_len);
+-    buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
+-    buffer_advance(&ioc->encinput, payload_len);
++    if (payload_len) {
++        buffer_reserve(&ioc->rawinput, payload_len);
++        buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
++        buffer_advance(&ioc->encinput, payload_len);
++    }
+     return 0;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Attempt-to-send-websocket-close-messages-to-clien.patch b/SOURCES/kvm-io-Attempt-to-send-websocket-close-messages-to-clien.patch
new file mode 100644
index 0000000..5b1a5b9
--- /dev/null
+++ b/SOURCES/kvm-io-Attempt-to-send-websocket-close-messages-to-clien.patch
@@ -0,0 +1,163 @@
+From b3f0cf18f87238075db4091fbfa63921852aeca6 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:52 +0100
+Subject: [PATCH 12/42] io: Attempt to send websocket close messages to client
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-11-berrange@redhat.com>
+Patchwork-id: 78463
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 10/20] io: Attempt to send websocket close messages to client
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Make a best effort attempt to close websocket connections according to
+the RFC. Sends the close message, as room permits in the socket buffer,
+and immediately closes the socket.
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 530ca60c16c83435d4becc9916d74fa43e003815)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 65 insertions(+), 3 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index b6fc0c9..3195eb2 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -188,6 +188,15 @@ static void qio_channel_websock_handshake_send_res_err(QIOChannelWebsock *ioc,
+     g_free(date);
+ }
+ 
++enum {
++    QIO_CHANNEL_WEBSOCK_STATUS_NORMAL = 1000,
++    QIO_CHANNEL_WEBSOCK_STATUS_PROTOCOL_ERR = 1002,
++    QIO_CHANNEL_WEBSOCK_STATUS_INVALID_DATA = 1003,
++    QIO_CHANNEL_WEBSOCK_STATUS_POLICY = 1008,
++    QIO_CHANNEL_WEBSOCK_STATUS_TOO_LARGE = 1009,
++    QIO_CHANNEL_WEBSOCK_STATUS_SERVER_ERR = 1011,
++};
++
+ static size_t
+ qio_channel_websock_extract_headers(QIOChannelWebsock *ioc,
+                                     char *buffer,
+@@ -617,6 +626,27 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
+ }
+ 
+ 
++static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *, Error **);
++
++
++static void qio_channel_websock_write_close(QIOChannelWebsock *ioc,
++                                            uint16_t code, const char *reason)
++{
++    buffer_reserve(&ioc->rawoutput, 2 + (reason ? strlen(reason) : 0));
++    *(uint16_t *)(ioc->rawoutput.buffer + ioc->rawoutput.offset) =
++        cpu_to_be16(code);
++    ioc->rawoutput.offset += 2;
++    if (reason) {
++        buffer_append(&ioc->rawoutput, reason, strlen(reason));
++    }
++    qio_channel_websock_encode_buffer(
++        &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE, &ioc->rawoutput);
++    buffer_reset(&ioc->rawoutput);
++    qio_channel_websock_write_wire(ioc, NULL);
++    qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
++}
++
++
+ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+                                              Error **errp)
+ {
+@@ -630,6 +660,9 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         error_setg(errp,
+                    "Decoding header but %zu bytes of payload remain",
+                    ioc->payload_remain);
++        qio_channel_websock_write_close(
++            ioc, QIO_CHANNEL_WEBSOCK_STATUS_SERVER_ERR,
++            "internal server error");
+         return -1;
+     }
+     if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) {
+@@ -662,19 +695,29 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+     if (!fin) {
+         if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+             error_setg(errp, "only binary websocket frames may be fragmented");
++            qio_channel_websock_write_close(
++                ioc, QIO_CHANNEL_WEBSOCK_STATUS_POLICY ,
++                "only binary frames may be fragmented");
+             return -1;
+         }
+     } else {
+         if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &&
++            opcode != QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE &&
+             opcode != QIO_CHANNEL_WEBSOCK_OPCODE_PING &&
+             opcode != QIO_CHANNEL_WEBSOCK_OPCODE_PONG) {
+-            error_setg(errp, "unsupported opcode: %#04x; only binary, ping, "
+-                             "and pong websocket frames are supported", opcode);
++            error_setg(errp, "unsupported opcode: %#04x; only binary, close, "
++                       "ping, and pong websocket frames are supported", opcode);
++            qio_channel_websock_write_close(
++                ioc, QIO_CHANNEL_WEBSOCK_STATUS_INVALID_DATA ,
++                "only binary, close, ping, and pong frames are supported");
+             return -1;
+         }
+     }
+     if (!has_mask) {
+         error_setg(errp, "client websocket frames must be masked");
++        qio_channel_websock_write_close(
++            ioc, QIO_CHANNEL_WEBSOCK_STATUS_PROTOCOL_ERR,
++            "client frames must be masked");
+         return -1;
+     }
+ 
+@@ -684,6 +727,9 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         ioc->mask = header->u.m;
+     } else if (opcode & QIO_CHANNEL_WEBSOCK_CONTROL_OPCODE_MASK) {
+         error_setg(errp, "websocket control frame is too large");
++        qio_channel_websock_write_close(
++            ioc, QIO_CHANNEL_WEBSOCK_STATUS_PROTOCOL_ERR,
++            "control frame is too large");
+         return -1;
+     } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&
+                ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {
+@@ -701,7 +747,7 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+     }
+ 
+     buffer_advance(&ioc->encinput, header_size);
+-    return 1;
++    return 0;
+ }
+ 
+ 
+@@ -751,6 +797,22 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+             buffer_reserve(&ioc->rawinput, payload_len);
+             buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
+         }
++    } else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
++        /* close frames are echoed back */
++        error_setg(errp, "websocket closed by peer");
++        if (payload_len) {
++            /* echo client status */
++            qio_channel_websock_encode_buffer(
++                &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
++                &ioc->encinput);
++            qio_channel_websock_write_wire(ioc, NULL);
++            qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
++        } else {
++            /* send our own status */
++            qio_channel_websock_write_close(
++                ioc, QIO_CHANNEL_WEBSOCK_STATUS_NORMAL, "peer requested close");
++        }
++        return -1;
+     } else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_PING) {
+         /* ping frames produce an immediate reply */
+         buffer_reset(&ioc->ping_reply);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Ignore-websocket-PING-and-PONG-frames.patch b/SOURCES/kvm-io-Ignore-websocket-PING-and-PONG-frames.patch
new file mode 100644
index 0000000..59758f8
--- /dev/null
+++ b/SOURCES/kvm-io-Ignore-websocket-PING-and-PONG-frames.patch
@@ -0,0 +1,84 @@
+From 137479576664767db121c512db49f4c40789fa52 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:50 +0100
+Subject: [PATCH 10/42] io: Ignore websocket PING and PONG frames
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-9-berrange@redhat.com>
+Patchwork-id: 78460
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 08/20] io: Ignore websocket PING and PONG frames
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Keep pings and gratuitous pongs generated by web browsers from killing
+websocket connections.
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 01af17fc002414ee1ac0800babfb0edc2bef1a7d)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index b19b5d9..bfe4008 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -115,6 +115,7 @@
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f
++#define QIO_CHANNEL_WEBSOCK_CONTROL_OPCODE_MASK 0x8
+ 
+ typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader;
+ 
+@@ -659,8 +660,11 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+             return -1;
+         }
+     } else {
+-        if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+-            error_setg(errp, "only binary websocket frames are supported");
++        if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &&
++            opcode != QIO_CHANNEL_WEBSOCK_OPCODE_PING &&
++            opcode != QIO_CHANNEL_WEBSOCK_OPCODE_PONG) {
++            error_setg(errp, "unsupported opcode: %#04x; only binary, ping, "
++                             "and pong websocket frames are supported", opcode);
+             return -1;
+         }
+     }
+@@ -673,6 +677,9 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         ioc->payload_remain = payload_len;
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
+         ioc->mask = header->u.m;
++    } else if (opcode & QIO_CHANNEL_WEBSOCK_CONTROL_OPCODE_MASK) {
++        error_setg(errp, "websocket control frame is too large");
++        return -1;
+     } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&
+                ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {
+         ioc->payload_remain = be16_to_cpu(header->u.s16.l16);
+@@ -728,9 +735,15 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         }
+     }
+ 
++    /* Drop the payload of ping/pong packets */
++    if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
++        if (payload_len) {
++            buffer_reserve(&ioc->rawinput, payload_len);
++            buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
++        }
++    }
++
+     if (payload_len) {
+-        buffer_reserve(&ioc->rawinput, payload_len);
+-        buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
+         buffer_advance(&ioc->encinput, payload_len);
+     }
+     return 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Reply-to-ping-frames.patch b/SOURCES/kvm-io-Reply-to-ping-frames.patch
new file mode 100644
index 0000000..fef8711
--- /dev/null
+++ b/SOURCES/kvm-io-Reply-to-ping-frames.patch
@@ -0,0 +1,185 @@
+From 9fb29da8bb32eeead15ac4038cb9cbfca11066f5 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:51 +0100
+Subject: [PATCH 11/42] io: Reply to ping frames
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-10-berrange@redhat.com>
+Patchwork-id: 78462
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 09/20] io: Reply to ping frames
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Add an immediate ping reply (pong) to the outgoing stream when a ping
+is received. Unsolicited pongs are ignored.
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 268a53f50de795481dd73ffd0e0c1339ad3dc44b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/io/channel-websock.h |  1 +
+ io/channel-websock.c         | 66 +++++++++++++++++++++++++++++---------------
+ 2 files changed, 45 insertions(+), 22 deletions(-)
+
+diff --git a/include/io/channel-websock.h b/include/io/channel-websock.h
+index 7c89655..ff32d86 100644
+--- a/include/io/channel-websock.h
++++ b/include/io/channel-websock.h
+@@ -60,6 +60,7 @@ struct QIOChannelWebsock {
+     Buffer encoutput;
+     Buffer rawinput;
+     Buffer rawoutput;
++    Buffer ping_reply;
+     size_t payload_remain;
+     QIOChannelWebsockMask mask;
+     guint io_tag;
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index bfe4008..b6fc0c9 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -573,7 +573,8 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ }
+ 
+ 
+-static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
++static void qio_channel_websock_encode_buffer(Buffer *output,
++                                              uint8_t opcode, Buffer *buffer)
+ {
+     size_t header_size;
+     union {
+@@ -581,33 +582,37 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
+         QIOChannelWebsockHeader ws;
+     } header;
+ 
+-    if (!ioc->rawoutput.offset) {
+-        return;
+-    }
+-
+     header.ws.b0 = QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN |
+-        (QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &
+-         QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
+-    if (ioc->rawoutput.offset <
+-        QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
+-        header.ws.b1 = (uint8_t)ioc->rawoutput.offset;
++        (opcode & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
++    if (buffer->offset < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
++        header.ws.b1 = (uint8_t)buffer->offset;
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
+-    } else if (ioc->rawoutput.offset <
++    } else if (buffer->offset <
+                QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT) {
+         header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT;
+-        header.ws.u.s16.l16 = cpu_to_be16((uint16_t)ioc->rawoutput.offset);
++        header.ws.u.s16.l16 = cpu_to_be16((uint16_t)buffer->offset);
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;
+     } else {
+         header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT;
+-        header.ws.u.s64.l64 = cpu_to_be64(ioc->rawoutput.offset);
++        header.ws.u.s64.l64 = cpu_to_be64(buffer->offset);
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
+     }
+     header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK;
+ 
+-    buffer_reserve(&ioc->encoutput, header_size + ioc->rawoutput.offset);
+-    buffer_append(&ioc->encoutput, header.buf, header_size);
+-    buffer_append(&ioc->encoutput, ioc->rawoutput.buffer,
+-                  ioc->rawoutput.offset);
++    buffer_reserve(output, header_size + buffer->offset);
++    buffer_append(output, header.buf, header_size);
++    buffer_append(output, buffer->buffer, buffer->offset);
++}
++
++
++static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
++{
++    if (!ioc->rawoutput.offset) {
++        return;
++    }
++    qio_channel_websock_encode_buffer(
++        &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
++        &ioc->rawoutput);
+     buffer_reset(&ioc->rawoutput);
+ }
+ 
+@@ -652,7 +657,7 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+     /* Websocket frame sanity check:
+      * * Fragmentation is only supported for binary frames.
+      * * All frames sent by a client MUST be masked.
+-     * * Only binary encoding is supported.
++     * * Only binary and ping/pong encoding is supported.
+      */
+     if (!fin) {
+         if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+@@ -713,6 +718,11 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+          * for purpose of unmasking, except at end of payload
+          */
+         if (ioc->encinput.offset < ioc->payload_remain) {
++            /* Wait for the entire payload before processing control frames
++             * because the payload will most likely be echoed back. */
++            if (ioc->opcode & QIO_CHANNEL_WEBSOCK_CONTROL_OPCODE_MASK) {
++                return QIO_CHANNEL_ERR_BLOCK;
++            }
+             payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4);
+         } else {
+             payload_len = ioc->payload_remain;
+@@ -735,13 +745,18 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         }
+     }
+ 
+-    /* Drop the payload of ping/pong packets */
+     if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+         if (payload_len) {
++            /* binary frames are passed on */
+             buffer_reserve(&ioc->rawinput, payload_len);
+             buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
+         }
+-    }
++    } else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_PING) {
++        /* ping frames produce an immediate reply */
++        buffer_reset(&ioc->ping_reply);
++        qio_channel_websock_encode_buffer(
++            &ioc->ping_reply, QIO_CHANNEL_WEBSOCK_OPCODE_PONG, &ioc->encinput);
++    }   /* pong frames are ignored */
+ 
+     if (payload_len) {
+         buffer_advance(&ioc->encinput, payload_len);
+@@ -799,6 +814,7 @@ static void qio_channel_websock_finalize(Object *obj)
+     buffer_free(&ioc->encoutput);
+     buffer_free(&ioc->rawinput);
+     buffer_free(&ioc->rawoutput);
++    buffer_free(&ioc->ping_reply);
+     object_unref(OBJECT(ioc->master));
+     if (ioc->io_tag) {
+         g_source_remove(ioc->io_tag);
+@@ -855,7 +871,13 @@ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc,
+ {
+     ssize_t ret;
+     ssize_t done = 0;
+-    qio_channel_websock_encode(ioc);
++
++    /* ping replies take priority over binary data */
++    if (!ioc->ping_reply.offset) {
++        qio_channel_websock_encode(ioc);
++    } else if (!ioc->encoutput.offset) {
++        buffer_move_empty(&ioc->encoutput, &ioc->ping_reply);
++    }
+ 
+     while (ioc->encoutput.offset > 0) {
+         ret = qio_channel_write(ioc->master,
+@@ -930,7 +952,7 @@ static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc)
+         return;
+     }
+ 
+-    if (ioc->encoutput.offset) {
++    if (ioc->encoutput.offset || ioc->ping_reply.offset) {
+         cond |= G_IO_OUT;
+     }
+     if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER &&
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Small-updates-in-preparation-for-websocket-change.patch b/SOURCES/kvm-io-Small-updates-in-preparation-for-websocket-change.patch
new file mode 100644
index 0000000..4bebe90
--- /dev/null
+++ b/SOURCES/kvm-io-Small-updates-in-preparation-for-websocket-change.patch
@@ -0,0 +1,195 @@
+From 977ae916454f470780f7562b61c98718e2d0d49c Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:47 +0100
+Subject: [PATCH 07/42] io: Small updates in preparation for websocket changes
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-6-berrange@redhat.com>
+Patchwork-id: 78459
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 05/20] io: Small updates in preparation for websocket changes
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Gets rid of unnecessary bit shifting and performs proper EOF checking to
+avoid a large number of repeated calls to recvmsg() when a client
+abruptly terminates a connection (bug fix).
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit eefa3d8ef649f9055611361e2201cca49f8c3433)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 64 ++++++++++++++++------------------------------------
+ 1 file changed, 19 insertions(+), 45 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 2258557..4e5afb2 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -110,13 +110,11 @@
+ /* Magic 7-bit length to indicate use of 64-bit payload length */
+ #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT 127
+ 
+-/* Bitmasks & shifts for accessing header fields */
++/* Bitmasks for accessing header fields */
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN 0x80
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80
+ #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f
+-#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN 7
+-#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK 7
+ 
+ typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader;
+ 
+@@ -586,7 +584,7 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
+         return;
+     }
+ 
+-    header.ws.b0 = (1 << QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN) |
++    header.ws.b0 = QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN |
+         (QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &
+          QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
+     if (ioc->rawoutput.offset <
+@@ -613,8 +611,8 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
+ }
+ 
+ 
+-static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+-                                                 Error **errp)
++static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
++                                             Error **errp)
+ {
+     unsigned char opcode, fin, has_mask;
+     size_t header_size;
+@@ -633,11 +631,9 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         return QIO_CHANNEL_ERR_BLOCK;
+     }
+ 
+-    fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>
+-        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;
++    fin = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN;
+     opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;
+-    has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>
+-        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;
++    has_mask = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK;
+     payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;
+ 
+     if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
+@@ -655,7 +651,7 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         return -1;
+     }
+     if (!has_mask) {
+-        error_setg(errp, "websocket frames must be masked");
++        error_setg(errp, "client websocket frames must be masked");
+         return -1;
+     }
+     if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+@@ -687,8 +683,8 @@ static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+ }
+ 
+ 
+-static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+-                                                  Error **errp)
++static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
++                                              Error **errp)
+ {
+     size_t i;
+     size_t payload_len;
+@@ -729,7 +725,7 @@ static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+     buffer_reserve(&ioc->rawinput, payload_len);
+     buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
+     buffer_advance(&ioc->encinput, payload_len);
+-    return payload_len;
++    return 0;
+ }
+ 
+ 
+@@ -809,8 +805,8 @@ static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
+         if (ret < 0) {
+             return ret;
+         }
+-        if (ret == 0 &&
+-            ioc->encinput.offset == 0) {
++        if (ret == 0 && ioc->encinput.offset == 0) {
++            ioc->io_eof = TRUE;
+             return 0;
+         }
+         ioc->encinput.offset += ret;
+@@ -822,10 +818,6 @@ static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
+             if (ret < 0) {
+                 return ret;
+             }
+-            if (ret == 0) {
+-                ioc->io_eof = TRUE;
+-                break;
+-            }
+         }
+ 
+         ret = qio_channel_websock_decode_payload(ioc, errp);
+@@ -1090,14 +1082,12 @@ struct QIOChannelWebsockSource {
+ };
+ 
+ static gboolean
+-qio_channel_websock_source_prepare(GSource *source,
+-                                   gint *timeout)
++qio_channel_websock_source_check(GSource *source)
+ {
+     QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
+     GIOCondition cond = 0;
+-    *timeout = -1;
+ 
+-    if (wsource->wioc->rawinput.offset) {
++    if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) {
+         cond |= G_IO_IN;
+     }
+     if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
+@@ -1108,19 +1098,11 @@ qio_channel_websock_source_prepare(GSource *source,
+ }
+ 
+ static gboolean
+-qio_channel_websock_source_check(GSource *source)
++qio_channel_websock_source_prepare(GSource *source,
++                                   gint *timeout)
+ {
+-    QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
+-    GIOCondition cond = 0;
+-
+-    if (wsource->wioc->rawinput.offset) {
+-        cond |= G_IO_IN;
+-    }
+-    if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
+-        cond |= G_IO_OUT;
+-    }
+-
+-    return cond & wsource->condition;
++    *timeout = -1;
++    return qio_channel_websock_source_check(source);
+ }
+ 
+ static gboolean
+@@ -1130,17 +1112,9 @@ qio_channel_websock_source_dispatch(GSource *source,
+ {
+     QIOChannelFunc func = (QIOChannelFunc)callback;
+     QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
+-    GIOCondition cond = 0;
+-
+-    if (wsource->wioc->rawinput.offset) {
+-        cond |= G_IO_IN;
+-    }
+-    if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
+-        cond |= G_IO_OUT;
+-    }
+ 
+     return (*func)(QIO_CHANNEL(wsource->wioc),
+-                   (cond & wsource->condition),
++                   qio_channel_websock_source_check(source),
+                    user_data);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-Yield-rather-than-wait-when-already-in-coroutine.patch b/SOURCES/kvm-io-Yield-rather-than-wait-when-already-in-coroutine.patch
new file mode 100644
index 0000000..e42bb27
--- /dev/null
+++ b/SOURCES/kvm-io-Yield-rather-than-wait-when-already-in-coroutine.patch
@@ -0,0 +1,70 @@
+From 280e240cfa8e633dd062791b1d0d62fe0e642d46 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:38 +0100
+Subject: [PATCH 12/36] io: Yield rather than wait when already in coroutine
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-3-pbonzini@redhat.com>
+Patchwork-id: 78076
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 02/17] io: Yield rather than wait when already in coroutine
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Eric Blake <eblake@redhat.com>
+
+The new qio_channel_{read,write}{,v}_all functions are documented
+as yielding until data is available.  When used on a blocking
+channel, this yield is done via qio_channel_wait() which spawns
+a nested event loop under the hood (so it is that secondary loop
+which yields as needed); but if we are already in a coroutine (at
+which point QIO_CHANNEL_ERR_BLOCK is only possible if we are a
+non-blocking channel), we want to yield the current coroutine
+instead of spawning a nested event loop.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20170905191114.5959-2-eblake@redhat.com>
+Acked-by: Daniel P. Berrange <berrange@redhat.com>
+[commit message updated]
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 9ffb8270205a274a18ee4f8a735e2fccaf957246)
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/io/channel.c b/io/channel.c
+index 5e8c2f0..9e62794 100644
+--- a/io/channel.c
++++ b/io/channel.c
+@@ -105,7 +105,11 @@ int qio_channel_readv_all(QIOChannel *ioc,
+         ssize_t len;
+         len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp);
+         if (len == QIO_CHANNEL_ERR_BLOCK) {
+-            qio_channel_wait(ioc, G_IO_IN);
++            if (qemu_in_coroutine()) {
++                qio_channel_yield(ioc, G_IO_IN);
++            } else {
++                qio_channel_wait(ioc, G_IO_IN);
++            }
+             continue;
+         } else if (len < 0) {
+             goto cleanup;
+@@ -143,7 +147,11 @@ int qio_channel_writev_all(QIOChannel *ioc,
+         ssize_t len;
+         len = qio_channel_writev(ioc, local_iov, nlocal_iov, errp);
+         if (len == QIO_CHANNEL_ERR_BLOCK) {
+-            qio_channel_wait(ioc, G_IO_OUT);
++            if (qemu_in_coroutine()) {
++                qio_channel_yield(ioc, G_IO_OUT);
++            } else {
++                qio_channel_wait(ioc, G_IO_OUT);
++            }
+             continue;
+         }
+         if (len < 0) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-add-new-qio_channel_-readv-writev-read-write-_all.patch b/SOURCES/kvm-io-add-new-qio_channel_-readv-writev-read-write-_all.patch
new file mode 100644
index 0000000..f4b242b
--- /dev/null
+++ b/SOURCES/kvm-io-add-new-qio_channel_-readv-writev-read-write-_all.patch
@@ -0,0 +1,397 @@
+From 1bafd8e2d09bfdf4bb2098b82537a9baa170aabc Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:37 +0100
+Subject: [PATCH 11/36] io: add new qio_channel_{readv, writev, read,
+ write}_all functions
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-2-pbonzini@redhat.com>
+Patchwork-id: 78074
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 01/17] io: add new qio_channel_{readv, writev, read, write}_all functions
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+These functions wait until they are able to read / write the full
+requested data buffer(s).
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit d4622e55883211072621958d39ddaa73483d201e)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/io/channel.h       |  90 +++++++++++++++++++++++++++++++++++++++
+ io/channel.c               |  94 +++++++++++++++++++++++++++++++++++++++++
+ tests/io-channel-helpers.c | 102 ++++-----------------------------------------
+ 3 files changed, 193 insertions(+), 93 deletions(-)
+
+diff --git a/include/io/channel.h b/include/io/channel.h
+index db9bb02..e11a62e 100644
+--- a/include/io/channel.h
++++ b/include/io/channel.h
+@@ -269,6 +269,58 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
+                                 Error **errp);
+ 
+ /**
++ * qio_channel_readv_all:
++ * @ioc: the channel object
++ * @iov: the array of memory regions to read data into
++ * @niov: the length of the @iov array
++ * @errp: pointer to a NULL-initialized error object
++ *
++ * Read data from the IO channel, storing it in the
++ * memory regions referenced by @iov. Each element
++ * in the @iov will be fully populated with data
++ * before the next one is used. The @niov parameter
++ * specifies the total number of elements in @iov.
++ *
++ * The function will wait for all requested data
++ * to be read, yielding from the current coroutine
++ * if required.
++ *
++ * If end-of-file occurs before all requested data
++ * has been read, an error will be reported.
++ *
++ * Returns: 0 if all bytes were read, or -1 on error
++ */
++int qio_channel_readv_all(QIOChannel *ioc,
++                          const struct iovec *iov,
++                          size_t niov,
++                          Error **errp);
++
++
++/**
++ * qio_channel_writev_all:
++ * @ioc: the channel object
++ * @iov: the array of memory regions to write data from
++ * @niov: the length of the @iov array
++ * @errp: pointer to a NULL-initialized error object
++ *
++ * Write data to the IO channel, reading it from the
++ * memory regions referenced by @iov. Each element
++ * in the @iov will be fully sent, before the next
++ * one is used. The @niov parameter specifies the
++ * total number of elements in @iov.
++ *
++ * The function will wait for all requested data
++ * to be written, yielding from the current coroutine
++ * if required.
++ *
++ * Returns: 0 if all bytes were written, or -1 on error
++ */
++int qio_channel_writev_all(QIOChannel *ioc,
++                           const struct iovec *iov,
++                           size_t niov,
++                           Error **erp);
++
++/**
+  * qio_channel_readv:
+  * @ioc: the channel object
+  * @iov: the array of memory regions to read data into
+@@ -331,6 +383,44 @@ ssize_t qio_channel_write(QIOChannel *ioc,
+                           Error **errp);
+ 
+ /**
++ * qio_channel_read_all:
++ * @ioc: the channel object
++ * @buf: the memory region to read data into
++ * @buflen: the number of bytes to @buf
++ * @errp: pointer to a NULL-initialized error object
++ *
++ * Reads @buflen bytes into @buf, possibly blocking or (if the
++ * channel is non-blocking) yielding from the current coroutine
++ * multiple times until the entire content is read. If end-of-file
++ * occurs it will return an error rather than a short-read. Otherwise
++ * behaves as qio_channel_read().
++ *
++ * Returns: 0 if all bytes were read, or -1 on error
++ */
++int qio_channel_read_all(QIOChannel *ioc,
++                         char *buf,
++                         size_t buflen,
++                         Error **errp);
++/**
++ * qio_channel_write_all:
++ * @ioc: the channel object
++ * @buf: the memory region to write data into
++ * @buflen: the number of bytes to @buf
++ * @errp: pointer to a NULL-initialized error object
++ *
++ * Writes @buflen bytes from @buf, possibly blocking or (if the
++ * channel is non-blocking) yielding from the current coroutine
++ * multiple times until the entire content is written.  Otherwise
++ * behaves as qio_channel_write().
++ *
++ * Returns: 0 if all bytes were written, or -1 on error
++ */
++int qio_channel_write_all(QIOChannel *ioc,
++                          const char *buf,
++                          size_t buflen,
++                          Error **errp);
++
++/**
+  * qio_channel_set_blocking:
+  * @ioc: the channel object
+  * @enabled: the blocking flag state
+diff --git a/io/channel.c b/io/channel.c
+index 1cfb8b3..5e8c2f0 100644
+--- a/io/channel.c
++++ b/io/channel.c
+@@ -22,6 +22,7 @@
+ #include "io/channel.h"
+ #include "qapi/error.h"
+ #include "qemu/main-loop.h"
++#include "qemu/iov.h"
+ 
+ bool qio_channel_has_feature(QIOChannel *ioc,
+                              QIOChannelFeature feature)
+@@ -85,6 +86,79 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
+ }
+ 
+ 
++
++int qio_channel_readv_all(QIOChannel *ioc,
++                          const struct iovec *iov,
++                          size_t niov,
++                          Error **errp)
++{
++    int ret = -1;
++    struct iovec *local_iov = g_new(struct iovec, niov);
++    struct iovec *local_iov_head = local_iov;
++    unsigned int nlocal_iov = niov;
++
++    nlocal_iov = iov_copy(local_iov, nlocal_iov,
++                          iov, niov,
++                          0, iov_size(iov, niov));
++
++    while (nlocal_iov > 0) {
++        ssize_t len;
++        len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp);
++        if (len == QIO_CHANNEL_ERR_BLOCK) {
++            qio_channel_wait(ioc, G_IO_IN);
++            continue;
++        } else if (len < 0) {
++            goto cleanup;
++        } else if (len == 0) {
++            error_setg(errp,
++                       "Unexpected end-of-file before all bytes were read");
++            goto cleanup;
++        }
++
++        iov_discard_front(&local_iov, &nlocal_iov, len);
++    }
++
++    ret = 0;
++
++ cleanup:
++    g_free(local_iov_head);
++    return ret;
++}
++
++int qio_channel_writev_all(QIOChannel *ioc,
++                           const struct iovec *iov,
++                           size_t niov,
++                           Error **errp)
++{
++    int ret = -1;
++    struct iovec *local_iov = g_new(struct iovec, niov);
++    struct iovec *local_iov_head = local_iov;
++    unsigned int nlocal_iov = niov;
++
++    nlocal_iov = iov_copy(local_iov, nlocal_iov,
++                          iov, niov,
++                          0, iov_size(iov, niov));
++
++    while (nlocal_iov > 0) {
++        ssize_t len;
++        len = qio_channel_writev(ioc, local_iov, nlocal_iov, errp);
++        if (len == QIO_CHANNEL_ERR_BLOCK) {
++            qio_channel_wait(ioc, G_IO_OUT);
++            continue;
++        }
++        if (len < 0) {
++            goto cleanup;
++        }
++
++        iov_discard_front(&local_iov, &nlocal_iov, len);
++    }
++
++    ret = 0;
++ cleanup:
++    g_free(local_iov_head);
++    return ret;
++}
++
+ ssize_t qio_channel_readv(QIOChannel *ioc,
+                           const struct iovec *iov,
+                           size_t niov,
+@@ -123,6 +197,26 @@ ssize_t qio_channel_write(QIOChannel *ioc,
+ }
+ 
+ 
++int qio_channel_read_all(QIOChannel *ioc,
++                         char *buf,
++                         size_t buflen,
++                         Error **errp)
++{
++    struct iovec iov = { .iov_base = buf, .iov_len = buflen };
++    return qio_channel_readv_all(ioc, &iov, 1, errp);
++}
++
++
++int qio_channel_write_all(QIOChannel *ioc,
++                          const char *buf,
++                          size_t buflen,
++                          Error **errp)
++{
++    struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen };
++    return qio_channel_writev_all(ioc, &iov, 1, errp);
++}
++
++
+ int qio_channel_set_blocking(QIOChannel *ioc,
+                               bool enabled,
+                               Error **errp)
+diff --git a/tests/io-channel-helpers.c b/tests/io-channel-helpers.c
+index 05e5579..5430e13 100644
+--- a/tests/io-channel-helpers.c
++++ b/tests/io-channel-helpers.c
+@@ -21,6 +21,7 @@
+ #include "qemu/osdep.h"
+ #include "io-channel-helpers.h"
+ #include "qapi/error.h"
++#include "qemu/iov.h"
+ 
+ struct QIOChannelTest {
+     QIOChannel *src;
+@@ -37,77 +38,17 @@ struct QIOChannelTest {
+ };
+ 
+ 
+-static void test_skip_iovec(struct iovec **iov,
+-                            size_t *niov,
+-                            size_t skip,
+-                            struct iovec *old)
+-{
+-    size_t offset = 0;
+-    size_t i;
+-
+-    for (i = 0; i < *niov; i++) {
+-        if (skip < (*iov)[i].iov_len) {
+-            old->iov_len = (*iov)[i].iov_len;
+-            old->iov_base = (*iov)[i].iov_base;
+-
+-            (*iov)[i].iov_len -= skip;
+-            (*iov)[i].iov_base += skip;
+-            break;
+-        } else {
+-            skip -= (*iov)[i].iov_len;
+-
+-            if (i == 0 && old->iov_base) {
+-                (*iov)[i].iov_len = old->iov_len;
+-                (*iov)[i].iov_base = old->iov_base;
+-                old->iov_len = 0;
+-                old->iov_base = NULL;
+-            }
+-
+-            offset++;
+-        }
+-    }
+-
+-    *iov = *iov + offset;
+-    *niov -= offset;
+-}
+-
+-
+ /* This thread sends all data using iovecs */
+ static gpointer test_io_thread_writer(gpointer opaque)
+ {
+     QIOChannelTest *data = opaque;
+-    struct iovec *iov = data->inputv;
+-    size_t niov = data->niov;
+-    struct iovec old = { 0 };
+ 
+     qio_channel_set_blocking(data->src, data->blocking, NULL);
+ 
+-    while (niov) {
+-        ssize_t ret;
+-        ret = qio_channel_writev(data->src,
+-                                 iov,
+-                                 niov,
+-                                 &data->writeerr);
+-        if (ret == QIO_CHANNEL_ERR_BLOCK) {
+-            if (data->blocking) {
+-                error_setg(&data->writeerr,
+-                           "Unexpected I/O blocking");
+-                break;
+-            } else {
+-                qio_channel_wait(data->src,
+-                                 G_IO_OUT);
+-                continue;
+-            }
+-        } else if (ret < 0) {
+-            break;
+-        } else if (ret == 0) {
+-            error_setg(&data->writeerr,
+-                       "Unexpected zero length write");
+-            break;
+-        }
+-
+-        test_skip_iovec(&iov, &niov, ret, &old);
+-    }
++    qio_channel_writev_all(data->src,
++                           data->inputv,
++                           data->niov,
++                           &data->writeerr);
+ 
+     return NULL;
+ }
+@@ -117,38 +58,13 @@ static gpointer test_io_thread_writer(gpointer opaque)
+ static gpointer test_io_thread_reader(gpointer opaque)
+ {
+     QIOChannelTest *data = opaque;
+-    struct iovec *iov = data->outputv;
+-    size_t niov = data->niov;
+-    struct iovec old = { 0 };
+ 
+     qio_channel_set_blocking(data->dst, data->blocking, NULL);
+ 
+-    while (niov) {
+-        ssize_t ret;
+-
+-        ret = qio_channel_readv(data->dst,
+-                                iov,
+-                                niov,
+-                                &data->readerr);
+-
+-        if (ret == QIO_CHANNEL_ERR_BLOCK) {
+-            if (data->blocking) {
+-                error_setg(&data->readerr,
+-                           "Unexpected I/O blocking");
+-                break;
+-            } else {
+-                qio_channel_wait(data->dst,
+-                                 G_IO_IN);
+-                continue;
+-            }
+-        } else if (ret < 0) {
+-            break;
+-        } else if (ret == 0) {
+-            break;
+-        }
+-
+-        test_skip_iovec(&iov, &niov, ret, &old);
+-    }
++    qio_channel_readv_all(data->dst,
++                          data->outputv,
++                          data->niov,
++                          &data->readerr);
+ 
+     return NULL;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-add-trace-events-for-websockets-frame-handling.patch b/SOURCES/kvm-io-add-trace-events-for-websockets-frame-handling.patch
new file mode 100644
index 0000000..d2d5f2f
--- /dev/null
+++ b/SOURCES/kvm-io-add-trace-events-for-websockets-frame-handling.patch
@@ -0,0 +1,142 @@
+From 3b740258b14da87d647beb87275bf16136a00985 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:53 +0100
+Subject: [PATCH 13/42] io: add trace events for websockets frame handling
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-12-berrange@redhat.com>
+Patchwork-id: 78464
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 11/20] io: add trace events for websockets frame handling
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+It is useful to trace websockets frame encoding/decoding when debugging
+problems.
+
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 59f183bbd54eecffb8915bffe03f9c2720b28bcc)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 23 ++++++++++++++++++-----
+ io/trace-events      |  5 +++++
+ 2 files changed, 23 insertions(+), 5 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 3195eb2..d1d471f 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -582,7 +582,8 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ }
+ 
+ 
+-static void qio_channel_websock_encode_buffer(Buffer *output,
++static void qio_channel_websock_encode_buffer(QIOChannelWebsock *ioc,
++                                              Buffer *output,
+                                               uint8_t opcode, Buffer *buffer)
+ {
+     size_t header_size;
+@@ -608,6 +609,7 @@ static void qio_channel_websock_encode_buffer(Buffer *output,
+     }
+     header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK;
+ 
++    trace_qio_channel_websock_encode(ioc, opcode, header_size, buffer->offset);
+     buffer_reserve(output, header_size + buffer->offset);
+     buffer_append(output, header.buf, header_size);
+     buffer_append(output, buffer->buffer, buffer->offset);
+@@ -620,7 +622,7 @@ static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
+         return;
+     }
+     qio_channel_websock_encode_buffer(
+-        &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
++        ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
+         &ioc->rawoutput);
+     buffer_reset(&ioc->rawoutput);
+ }
+@@ -640,7 +642,8 @@ static void qio_channel_websock_write_close(QIOChannelWebsock *ioc,
+         buffer_append(&ioc->rawoutput, reason, strlen(reason));
+     }
+     qio_channel_websock_encode_buffer(
+-        &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE, &ioc->rawoutput);
++        ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
++        &ioc->rawoutput);
+     buffer_reset(&ioc->rawoutput);
+     qio_channel_websock_write_wire(ioc, NULL);
+     qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+@@ -682,6 +685,9 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         opcode = ioc->opcode;
+     }
+ 
++    trace_qio_channel_websock_header_partial_decode(ioc, payload_len,
++                                                    fin, opcode, (int)has_mask);
++
+     if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
+         /* disconnect */
+         return 0;
+@@ -746,6 +752,8 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
+         return QIO_CHANNEL_ERR_BLOCK;
+     }
+ 
++    trace_qio_channel_websock_header_full_decode(
++        ioc, header_size, ioc->payload_remain, ioc->mask.u);
+     buffer_advance(&ioc->encinput, header_size);
+     return 0;
+ }
+@@ -791,6 +799,9 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         }
+     }
+ 
++    trace_qio_channel_websock_payload_decode(
++        ioc, ioc->opcode, ioc->payload_remain);
++
+     if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
+         if (payload_len) {
+             /* binary frames are passed on */
+@@ -803,7 +814,7 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         if (payload_len) {
+             /* echo client status */
+             qio_channel_websock_encode_buffer(
+-                &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
++                ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
+                 &ioc->encinput);
+             qio_channel_websock_write_wire(ioc, NULL);
+             qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+@@ -817,7 +828,8 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         /* ping frames produce an immediate reply */
+         buffer_reset(&ioc->ping_reply);
+         qio_channel_websock_encode_buffer(
+-            &ioc->ping_reply, QIO_CHANNEL_WEBSOCK_OPCODE_PONG, &ioc->encinput);
++            ioc, &ioc->ping_reply, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
++            &ioc->encinput);
+     }   /* pong frames are ignored */
+ 
+     if (payload_len) {
+@@ -1176,6 +1188,7 @@ static int qio_channel_websock_close(QIOChannel *ioc,
+ {
+     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
+ 
++    trace_qio_channel_websock_close(ioc);
+     return qio_channel_close(wioc->master, errp);
+ }
+ 
+diff --git a/io/trace-events b/io/trace-events
+index 6459f71..801b5dc 100644
+--- a/io/trace-events
++++ b/io/trace-events
+@@ -48,6 +48,11 @@ qio_channel_websock_handshake_pending(void *ioc, int status) "Websock handshake
+ qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply ioc=%p"
+ qio_channel_websock_handshake_fail(void *ioc, const char *msg) "Websock handshake fail ioc=%p err=%s"
+ qio_channel_websock_handshake_complete(void *ioc) "Websock handshake complete ioc=%p"
++qio_channel_websock_header_partial_decode(void *ioc, size_t payloadlen, unsigned char fin, unsigned char opcode, unsigned char has_mask) "Websocket header decoded ioc=%p payload-len=%zu fin=0x%x opcode=0x%x has_mask=0x%x"
++qio_channel_websock_header_full_decode(void *ioc, size_t headerlen, size_t payloadlen, uint32_t mask) "Websocket header decoded ioc=%p header-len=%zu payload-len=%zu mask=0x%x"
++qio_channel_websock_payload_decode(void *ioc, uint8_t opcode, size_t payload_remain) "Websocket header decoded ioc=%p opcode=0x%x payload-remain=%zu"
++qio_channel_websock_encode(void *ioc, uint8_t opcode, size_t payloadlen, size_t headerlen) "Websocket encoded ioc=%p opcode=0x%x header-len=%zu payload-len=%zu"
++qio_channel_websock_close(void *ioc) "Websocket close ioc=%p"
+ 
+ # io/channel-command.c
+ qio_channel_command_new_pid(void *ioc, int writefd, int readfd, int pid) "Command new pid ioc=%p writefd=%d readfd=%d pid=%d"
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-add-trace-points-for-websocket-HTTP-protocol-head.patch b/SOURCES/kvm-io-add-trace-points-for-websocket-HTTP-protocol-head.patch
new file mode 100644
index 0000000..6ca9d28
--- /dev/null
+++ b/SOURCES/kvm-io-add-trace-points-for-websocket-HTTP-protocol-head.patch
@@ -0,0 +1,62 @@
+From 8043361fbb2617010aeb3d4009cd05636e2ff715 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:57:00 +0100
+Subject: [PATCH 20/42] io: add trace points for websocket HTTP protocol
+ headers
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-19-berrange@redhat.com>
+Patchwork-id: 78471
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 18/20] io: add trace points for websocket HTTP protocol headers
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 0efd6c9ec19a1ea6c413424fbea54e1dfe471026)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 4 ++++
+ io/trace-events      | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 0354845..aa35ef3 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -224,6 +224,7 @@ qio_channel_websock_extract_headers(QIOChannelWebsock *ioc,
+         goto bad_request;
+     }
+     *nl = '\0';
++    trace_qio_channel_websock_http_greeting(ioc, buffer);
+ 
+     tmp = strchr(buffer, ' ');
+     if (!tmp) {
+@@ -425,6 +426,9 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
+         goto bad_request;
+     }
+ 
++    trace_qio_channel_websock_http_request(ioc, protocols, version,
++                                           host, connection, upgrade, key);
++
+     if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) {
+         error_setg(errp, "No '%s' protocol is supported by client '%s'",
+                    QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols);
+diff --git a/io/trace-events b/io/trace-events
+index 801b5dc..f70bad7 100644
+--- a/io/trace-events
++++ b/io/trace-events
+@@ -48,6 +48,8 @@ qio_channel_websock_handshake_pending(void *ioc, int status) "Websock handshake
+ qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply ioc=%p"
+ qio_channel_websock_handshake_fail(void *ioc, const char *msg) "Websock handshake fail ioc=%p err=%s"
+ qio_channel_websock_handshake_complete(void *ioc) "Websock handshake complete ioc=%p"
++qio_channel_websock_http_greeting(void *ioc, const char *greeting) "Websocket HTTP request ioc=%p greeting='%s'"
++qio_channel_websock_http_request(void *ioc, const char *protocols, const char *version, const char *host, const char *connection, const char *upgrade, const char *key) "Websocket HTTP request ioc=%p protocols='%s' version='%s' host='%s' connection='%s' upgrade='%s' key='%s'"
+ qio_channel_websock_header_partial_decode(void *ioc, size_t payloadlen, unsigned char fin, unsigned char opcode, unsigned char has_mask) "Websocket header decoded ioc=%p payload-len=%zu fin=0x%x opcode=0x%x has_mask=0x%x"
+ qio_channel_websock_header_full_decode(void *ioc, size_t headerlen, size_t payloadlen, uint32_t mask) "Websocket header decoded ioc=%p header-len=%zu payload-len=%zu mask=0x%x"
+ qio_channel_websock_payload_decode(void *ioc, uint8_t opcode, size_t payload_remain) "Websocket header decoded ioc=%p opcode=0x%x payload-remain=%zu"
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-cope-with-websock-Connection-header-having-multip.patch b/SOURCES/kvm-io-cope-with-websock-Connection-header-having-multip.patch
new file mode 100644
index 0000000..3704a20
--- /dev/null
+++ b/SOURCES/kvm-io-cope-with-websock-Connection-header-having-multip.patch
@@ -0,0 +1,62 @@
+From 16063b60ae69a93169ab06265dc597072d9bd8ed Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:59 +0100
+Subject: [PATCH 19/42] io: cope with websock 'Connection' header having
+ multiple values
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-18-berrange@redhat.com>
+Patchwork-id: 78470
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 17/20] io: cope with websock 'Connection' header having multiple values
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The noVNC server sends a header "Connection: keep-alive, Upgrade" which
+fails our simple equality test. Split the header on ',', trim whitespace
+and then check for 'upgrade' token.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 6d5d23b00709510d55711661c7ca41408fd9934e)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index e82b1be..0354845 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -374,6 +374,9 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
+     size_t nhdrs = G_N_ELEMENTS(hdrs);
+     const char *protocols = NULL, *version = NULL, *key = NULL,
+         *host = NULL, *connection = NULL, *upgrade = NULL;
++    char **connectionv;
++    bool upgraded = false;
++    size_t i;
+ 
+     nhdrs = qio_channel_websock_extract_headers(ioc, buffer, hdrs, nhdrs, errp);
+     if (!nhdrs) {
+@@ -440,7 +443,16 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
+         goto bad_request;
+     }
+ 
+-    if (strcasecmp(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) != 0) {
++    connectionv = g_strsplit(connection, ",", 0);
++    for (i = 0; connectionv != NULL && connectionv[i] != NULL; i++) {
++        g_strstrip(connectionv[i]);
++        if (strcasecmp(connectionv[i],
++                       QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) == 0) {
++            upgraded = true;
++        }
++    }
++    g_strfreev(connectionv);
++    if (!upgraded) {
+         error_setg(errp, "No connection upgrade requested '%s'", connection);
+         goto bad_request;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-fix-mem-leak-in-websock-error-path.patch b/SOURCES/kvm-io-fix-mem-leak-in-websock-error-path.patch
new file mode 100644
index 0000000..dd6c9c9
--- /dev/null
+++ b/SOURCES/kvm-io-fix-mem-leak-in-websock-error-path.patch
@@ -0,0 +1,49 @@
+From 65fbe38c421960d5ad73e25b58593f58411422b8 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:57:01 +0100
+Subject: [PATCH 21/42] io: fix mem leak in websock error path
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-20-berrange@redhat.com>
+Patchwork-id: 78472
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 19/20] io: fix mem leak in websock error path
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Coverity pointed out the 'date' is not free()d in the error
+path
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 7fc3fcefe2fc5966c6aa1ef4f10e9740d8d73bf2)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index aa35ef3..df2c3a9 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -341,7 +341,7 @@ static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
+     char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
+                       QIO_CHANNEL_WEBSOCK_GUID_LEN + 1];
+     char *accept = NULL;
+-    char *date = qio_channel_websock_date_str();
++    char *date = NULL;
+ 
+     g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1);
+     g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID,
+@@ -360,6 +360,7 @@ static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
+         return;
+     }
+ 
++    date = qio_channel_websock_date_str();
+     qio_channel_websock_handshake_send_res(
+         ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-get-rid-of-bounce-buffering-in-websock-write-path.patch b/SOURCES/kvm-io-get-rid-of-bounce-buffering-in-websock-write-path.patch
new file mode 100644
index 0000000..da22dee
--- /dev/null
+++ b/SOURCES/kvm-io-get-rid-of-bounce-buffering-in-websock-write-path.patch
@@ -0,0 +1,164 @@
+From 4550459a8e915a74dfbeb97ab4b645f72165079c Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:58 +0100
+Subject: [PATCH 18/42] io: get rid of bounce buffering in websock write path
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-17-berrange@redhat.com>
+Patchwork-id: 78469
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 16/20] io: get rid of bounce buffering in websock write path
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Currently most outbound I/O on the websock channel gets copied into the
+rawoutput buffer, and then immediately copied again into the encoutput
+buffer, with a header prepended. Now that qio_channel_websock_encode
+accepts a struct iovec, we can trivially remove this bounce buffering
+and write directly to encoutput.
+
+In doing so, we also now correctly validate the encoutput size against
+the QIO_CHANNEL_WEBSOCK_MAX_BUFFER limit.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 8dfd5f96515ca20c4eb109cb0ee28e2bb32fc505)
+
+NB, include of iov.h was pushed into previous patch to fix bisect
+buld.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/io/channel-websock.h |  1 -
+ io/channel-websock.c         | 63 +++++++++++++++++++-------------------------
+ 2 files changed, 27 insertions(+), 37 deletions(-)
+
+diff --git a/include/io/channel-websock.h b/include/io/channel-websock.h
+index 3762707..a7e5e92 100644
+--- a/include/io/channel-websock.h
++++ b/include/io/channel-websock.h
+@@ -59,7 +59,6 @@ struct QIOChannelWebsock {
+     Buffer encinput;
+     Buffer encoutput;
+     Buffer rawinput;
+-    Buffer rawoutput;
+     size_t payload_remain;
+     size_t pong_remain;
+     QIOChannelWebsockMask mask;
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 11b6039..e82b1be 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -634,19 +634,22 @@ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *, Error **);
+ static void qio_channel_websock_write_close(QIOChannelWebsock *ioc,
+                                             uint16_t code, const char *reason)
+ {
+-    struct iovec iov;
+-    buffer_reserve(&ioc->rawoutput, 2 + (reason ? strlen(reason) : 0));
+-    *(uint16_t *)(ioc->rawoutput.buffer + ioc->rawoutput.offset) =
+-        cpu_to_be16(code);
+-    ioc->rawoutput.offset += 2;
++    struct iovec iov[2] = {
++        { .iov_base = &code, .iov_len = sizeof(code) },
++    };
++    size_t niov = 1;
++    size_t size = iov[0].iov_len;
++
++    cpu_to_be16s(&code);
++
+     if (reason) {
+-        buffer_append(&ioc->rawoutput, reason, strlen(reason));
++        iov[1].iov_base = (void *)reason;
++        iov[1].iov_len = strlen(reason);
++        size += iov[1].iov_len;
++        niov++;
+     }
+-    iov.iov_base = ioc->rawoutput.buffer;
+-    iov.iov_len = ioc->rawoutput.offset;
+     qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
+-                               &iov, 1, iov.iov_len);
+-    buffer_reset(&ioc->rawoutput);
++                               iov, niov, size);
+     qio_channel_websock_write_wire(ioc, NULL);
+     qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+ }
+@@ -894,7 +897,6 @@ static void qio_channel_websock_finalize(Object *obj)
+     buffer_free(&ioc->encinput);
+     buffer_free(&ioc->encoutput);
+     buffer_free(&ioc->rawinput);
+-    buffer_free(&ioc->rawoutput);
+     object_unref(OBJECT(ioc->master));
+     if (ioc->io_tag) {
+         g_source_remove(ioc->io_tag);
+@@ -1104,8 +1106,8 @@ static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
+                                           Error **errp)
+ {
+     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
+-    size_t i;
+-    ssize_t done = 0;
++    ssize_t want = iov_size(iov, niov);
++    ssize_t avail;
+     ssize_t ret;
+ 
+     if (wioc->io_err) {
+@@ -1118,32 +1120,21 @@ static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
+         return -1;
+     }
+ 
+-    for (i = 0; i < niov; i++) {
+-        size_t want = iov[i].iov_len;
+-        if ((want + wioc->rawoutput.offset) > QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
+-            want = (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->rawoutput.offset);
+-        }
+-        if (want == 0) {
+-            goto done;
+-        }
+-
+-        buffer_reserve(&wioc->rawoutput, want);
+-        buffer_append(&wioc->rawoutput, iov[i].iov_base, want);
+-        done += want;
+-        if (want < iov[i].iov_len) {
+-            break;
+-        }
++    avail = wioc->encoutput.offset >= QIO_CHANNEL_WEBSOCK_MAX_BUFFER ?
++        0 : (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->encoutput.offset);
++    if (want > avail) {
++        want = avail;
+     }
+ 
+- done:
+-    if (wioc->rawoutput.offset) {
+-        struct iovec iov = { .iov_base = wioc->rawoutput.buffer,
+-                             .iov_len = wioc->rawoutput.offset };
++    if (want) {
+         qio_channel_websock_encode(wioc,
+                                    QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
+-                                   &iov, 1, iov.iov_len);
+-        buffer_reset(&wioc->rawoutput);
++                                   iov, niov, want);
+     }
++
++    /* Even if want == 0, we'll try write_wire in case there's
++     * pending data we could usefully flush out
++     */
+     ret = qio_channel_websock_write_wire(wioc, errp);
+     if (ret < 0 &&
+         ret != QIO_CHANNEL_ERR_BLOCK) {
+@@ -1153,11 +1144,11 @@ static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
+ 
+     qio_channel_websock_set_watch(wioc);
+ 
+-    if (done == 0) {
++    if (want == 0) {
+         return QIO_CHANNEL_ERR_BLOCK;
+     }
+ 
+-    return done;
++    return want;
+ }
+ 
+ static int qio_channel_websock_set_blocking(QIOChannel *ioc,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-get-rid-of-qio_channel_websock_encode-helper-meth.patch b/SOURCES/kvm-io-get-rid-of-qio_channel_websock_encode-helper-meth.patch
new file mode 100644
index 0000000..9916af1
--- /dev/null
+++ b/SOURCES/kvm-io-get-rid-of-qio_channel_websock_encode-helper-meth.patch
@@ -0,0 +1,80 @@
+From 87e23865f2383a8befcba2908dcd56c708a2fbb8 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:56 +0100
+Subject: [PATCH 16/42] io: get rid of qio_channel_websock_encode helper method
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-15-berrange@redhat.com>
+Patchwork-id: 78467
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 14/20] io: get rid of qio_channel_websock_encode helper method
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The qio_channel_websock_encode method is only used in one place,
+everything else calls qio_channel_websock_encode_buffer directly.
+It can also be pushed up a level into the qio_channel_websock_writev
+method, since every other caller of qio_channel_websock_write_wire
+has already filled encoutput.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit bac6c95415788c03590542eb244c723a18d0771c)
+
+NB, in qio_channel_websock_writev  s/ioc/wioc/ to fix a typo
+upstream that would break builds during git bisect.
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 6083f74..403b72b 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -616,18 +616,6 @@ static void qio_channel_websock_encode_buffer(QIOChannelWebsock *ioc,
+ }
+ 
+ 
+-static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
+-{
+-    if (!ioc->rawoutput.offset) {
+-        return;
+-    }
+-    qio_channel_websock_encode_buffer(
+-        ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
+-        &ioc->rawoutput);
+-    buffer_reset(&ioc->rawoutput);
+-}
+-
+-
+ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *, Error **);
+ 
+ 
+@@ -948,8 +936,6 @@ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc,
+     ssize_t ret;
+     ssize_t done = 0;
+ 
+-    qio_channel_websock_encode(ioc);
+-
+     while (ioc->encoutput.offset > 0) {
+         ret = qio_channel_write(ioc->master,
+                                 (char *)ioc->encoutput.buffer,
+@@ -1134,6 +1120,12 @@ static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
+     }
+ 
+  done:
++    if (wioc->rawoutput.offset) {
++        qio_channel_websock_encode_buffer(
++            wioc, &wioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
++            &wioc->rawoutput);
++        buffer_reset(&wioc->rawoutput);
++    }
+     ret = qio_channel_websock_write_wire(wioc, errp);
+     if (ret < 0 &&
+         ret != QIO_CHANNEL_ERR_BLOCK) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-include-full-error-message-in-websocket-handshake.patch b/SOURCES/kvm-io-include-full-error-message-in-websocket-handshake.patch
new file mode 100644
index 0000000..be16f1e
--- /dev/null
+++ b/SOURCES/kvm-io-include-full-error-message-in-websocket-handshake.patch
@@ -0,0 +1,80 @@
+From 0ac33e4a0edae8877e2d400b9a3c5e7af902668f Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:44 +0100
+Subject: [PATCH 04/42] io: include full error message in websocket handshake
+ trace
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-3-berrange@redhat.com>
+Patchwork-id: 78458
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 02/20] io: include full error message in websocket handshake trace
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+When the websocket handshake fails it is useful to log the real
+error message via the trace points for debugging purposes.
+
+Fixes bug: #1715186
+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 3a3f8705962c8c8a47a9b981ffd5aab7274ad508)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 7 ++++---
+ io/trace-events      | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index f5fac5b..6ddcec1 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -507,7 +507,7 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+                             &err);
+ 
+     if (ret < 0) {
+-        trace_qio_channel_websock_handshake_fail(ioc);
++        trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
+         qio_task_set_error(task, err);
+         qio_task_complete(task);
+         return FALSE;
+@@ -516,7 +516,8 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+     buffer_advance(&wioc->encoutput, ret);
+     if (wioc->encoutput.offset == 0) {
+         if (wioc->io_err) {
+-            trace_qio_channel_websock_handshake_fail(ioc);
++            trace_qio_channel_websock_handshake_fail(
++                ioc, error_get_pretty(wioc->io_err));
+             qio_task_set_error(task, wioc->io_err);
+             wioc->io_err = NULL;
+             qio_task_complete(task);
+@@ -547,7 +548,7 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+          * client connection, as most of the time we have an
+          * HTTP 4xx err response to send instead
+          */
+-        trace_qio_channel_websock_handshake_fail(ioc);
++        trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
+         qio_task_set_error(task, err);
+         qio_task_complete(task);
+         return FALSE;
+diff --git a/io/trace-events b/io/trace-events
+index 3d23369..6459f71 100644
+--- a/io/trace-events
++++ b/io/trace-events
+@@ -46,7 +46,7 @@ qio_channel_websock_new_server(void *ioc, void *master) "Websock new client ioc=
+ qio_channel_websock_handshake_start(void *ioc) "Websock handshake start ioc=%p"
+ qio_channel_websock_handshake_pending(void *ioc, int status) "Websock handshake pending ioc=%p status=%d"
+ qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply ioc=%p"
+-qio_channel_websock_handshake_fail(void *ioc) "Websock handshake fail ioc=%p"
++qio_channel_websock_handshake_fail(void *ioc, const char *msg) "Websock handshake fail ioc=%p err=%s"
+ qio_channel_websock_handshake_complete(void *ioc) "Websock handshake complete ioc=%p"
+ 
+ # io/channel-command.c
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-monitor-encoutput-buffer-size-from-websocket-GSou.patch b/SOURCES/kvm-io-monitor-encoutput-buffer-size-from-websocket-GSou.patch
new file mode 100644
index 0000000..481d9fa
--- /dev/null
+++ b/SOURCES/kvm-io-monitor-encoutput-buffer-size-from-websocket-GSou.patch
@@ -0,0 +1,66 @@
+From c3a99fb2c831c2f3da069359a9a8a0c734923669 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:54 +0100
+Subject: [PATCH 14/42] io: monitor encoutput buffer size from websocket
+ GSource
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-13-berrange@redhat.com>
+Patchwork-id: 78466
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 12/20] io: monitor encoutput buffer size from websocket GSource
+Bugzilla: 1518650
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The websocket GSource is monitoring the size of the rawoutput
+buffer to determine if the channel can accepts more writes.
+The rawoutput buffer, however, is merely a temporary staging
+buffer before data is copied into the encoutput buffer. Thus
+its size will always be zero when the GSource runs.
+
+This flaw causes the encoutput buffer to grow without bound
+if the other end of the underlying data channel doesn't
+read data being sent. This can be seen with VNC if a client
+is on a slow WAN link and the guest OS is sending many screen
+updates. A malicious VNC client can act like it is on a slow
+link by playing a video in the guest and then reading data
+very slowly, causing QEMU host memory to expand arbitrarily.
+
+This issue is assigned CVE-2017-15268, publically reported in
+
+  https://bugs.launchpad.net/qemu/+bug/1718964
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit a7b20a8efa28e5f22c26c06cd06c2f12bc863493)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index d1d471f..04bcc05 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -28,7 +28,7 @@
+ #include <time.h>
+ 
+ 
+-/* Max amount to allow in rawinput/rawoutput buffers */
++/* Max amount to allow in rawinput/encoutput buffers */
+ #define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192
+ 
+ #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24
+@@ -1208,7 +1208,7 @@ qio_channel_websock_source_check(GSource *source)
+     if (wsource->wioc->rawinput.offset || wsource->wioc->io_eof) {
+         cond |= G_IO_IN;
+     }
+-    if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
++    if (wsource->wioc->encoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
+         cond |= G_IO_OUT;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-pass-a-struct-iovec-into-qio_channel_websock_enco.patch b/SOURCES/kvm-io-pass-a-struct-iovec-into-qio_channel_websock_enco.patch
new file mode 100644
index 0000000..25feaa5
--- /dev/null
+++ b/SOURCES/kvm-io-pass-a-struct-iovec-into-qio_channel_websock_enco.patch
@@ -0,0 +1,172 @@
+From 33c5c11a12bba1c60e75f716d7ddf09b99dc372a Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:57 +0100
+Subject: [PATCH 17/42] io: pass a struct iovec into qio_channel_websock_encode
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-16-berrange@redhat.com>
+Patchwork-id: 78468
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 15/20] io: pass a struct iovec into qio_channel_websock_encode
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Instead of requiring use of another Buffer, pass a struct iovec
+into qio_channel_websock_encode, which gives callers more
+flexibility in how they process data.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit fb74e5903914b9ec8c80b6f7a35da000f9f92ae7)
+
+NB, slight context difference due to typo fixup in previous
+patch. Also pulled in iov.h include, again, to fix bisect build
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 68 +++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 43 insertions(+), 25 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 403b72b..11b6039 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -24,6 +24,7 @@
+ #include "io/channel-websock.h"
+ #include "crypto/hash.h"
+ #include "trace.h"
++#include "qemu/iov.h"
+ 
+ #include <time.h>
+ 
+@@ -582,37 +583,48 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ }
+ 
+ 
+-static void qio_channel_websock_encode_buffer(QIOChannelWebsock *ioc,
+-                                              Buffer *output,
+-                                              uint8_t opcode, Buffer *buffer)
++static void qio_channel_websock_encode(QIOChannelWebsock *ioc,
++                                       uint8_t opcode,
++                                       const struct iovec *iov,
++                                       size_t niov,
++                                       size_t size)
+ {
+     size_t header_size;
++    size_t i;
+     union {
+         char buf[QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT];
+         QIOChannelWebsockHeader ws;
+     } header;
+ 
++    assert(size <= iov_size(iov, niov));
++
+     header.ws.b0 = QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN |
+         (opcode & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
+-    if (buffer->offset < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
+-        header.ws.b1 = (uint8_t)buffer->offset;
++    if (size < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
++        header.ws.b1 = (uint8_t)size;
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
+-    } else if (buffer->offset <
+-               QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT) {
++    } else if (size < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT) {
+         header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT;
+-        header.ws.u.s16.l16 = cpu_to_be16((uint16_t)buffer->offset);
++        header.ws.u.s16.l16 = cpu_to_be16((uint16_t)size);
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;
+     } else {
+         header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT;
+-        header.ws.u.s64.l64 = cpu_to_be64(buffer->offset);
++        header.ws.u.s64.l64 = cpu_to_be64(size);
+         header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
+     }
+     header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK;
+ 
+-    trace_qio_channel_websock_encode(ioc, opcode, header_size, buffer->offset);
+-    buffer_reserve(output, header_size + buffer->offset);
+-    buffer_append(output, header.buf, header_size);
+-    buffer_append(output, buffer->buffer, buffer->offset);
++    trace_qio_channel_websock_encode(ioc, opcode, header_size, size);
++    buffer_reserve(&ioc->encoutput, header_size + size);
++    buffer_append(&ioc->encoutput, header.buf, header_size);
++    for (i = 0; i < niov && size != 0; i++) {
++        size_t want = iov[i].iov_len;
++        if (want > size) {
++            want = size;
++        }
++        buffer_append(&ioc->encoutput, iov[i].iov_base, want);
++        size -= want;
++    }
+ }
+ 
+ 
+@@ -622,6 +634,7 @@ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *, Error **);
+ static void qio_channel_websock_write_close(QIOChannelWebsock *ioc,
+                                             uint16_t code, const char *reason)
+ {
++    struct iovec iov;
+     buffer_reserve(&ioc->rawoutput, 2 + (reason ? strlen(reason) : 0));
+     *(uint16_t *)(ioc->rawoutput.buffer + ioc->rawoutput.offset) =
+         cpu_to_be16(code);
+@@ -629,9 +642,10 @@ static void qio_channel_websock_write_close(QIOChannelWebsock *ioc,
+     if (reason) {
+         buffer_append(&ioc->rawoutput, reason, strlen(reason));
+     }
+-    qio_channel_websock_encode_buffer(
+-        ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
+-        &ioc->rawoutput);
++    iov.iov_base = ioc->rawoutput.buffer;
++    iov.iov_len = ioc->rawoutput.offset;
++    qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
++                               &iov, 1, iov.iov_len);
+     buffer_reset(&ioc->rawoutput);
+     qio_channel_websock_write_wire(ioc, NULL);
+     qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+@@ -801,9 +815,10 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         error_setg(errp, "websocket closed by peer");
+         if (payload_len) {
+             /* echo client status */
+-            qio_channel_websock_encode_buffer(
+-                ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
+-                &ioc->encinput);
++            struct iovec iov = { .iov_base = ioc->encinput.buffer,
++                                 .iov_len = ioc->encinput.offset };
++            qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
++                                       &iov, 1, iov.iov_len);
+             qio_channel_websock_write_wire(ioc, NULL);
+             qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+         } else {
+@@ -816,9 +831,10 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         /* ping frames produce an immediate reply, as long as we've not still
+          * got a previous pong queued, in which case we drop the new pong */
+         if (ioc->pong_remain == 0) {
+-            qio_channel_websock_encode_buffer(
+-                ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
+-                &ioc->encinput);
++            struct iovec iov = { .iov_base = ioc->encinput.buffer,
++                                 .iov_len = ioc->encinput.offset };
++            qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
++                                       &iov, 1, iov.iov_len);
+             ioc->pong_remain = ioc->encoutput.offset;
+         }
+     }   /* pong frames are ignored */
+@@ -1121,9 +1137,11 @@ static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
+ 
+  done:
+     if (wioc->rawoutput.offset) {
+-        qio_channel_websock_encode_buffer(
+-            wioc, &wioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
+-            &wioc->rawoutput);
++        struct iovec iov = { .iov_base = wioc->rawoutput.buffer,
++                             .iov_len = wioc->rawoutput.offset };
++        qio_channel_websock_encode(wioc,
++                                   QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
++                                   &iov, 1, iov.iov_len);
+         buffer_reset(&wioc->rawoutput);
+     }
+     ret = qio_channel_websock_write_wire(wioc, errp);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-send-proper-HTTP-response-for-websocket-errors.patch b/SOURCES/kvm-io-send-proper-HTTP-response-for-websocket-errors.patch
new file mode 100644
index 0000000..6bc8594
--- /dev/null
+++ b/SOURCES/kvm-io-send-proper-HTTP-response-for-websocket-errors.patch
@@ -0,0 +1,435 @@
+From 062b6fd62b387f4ea67f800ca956c87b28451a9c Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:43 +0100
+Subject: [PATCH 03/42] io: send proper HTTP response for websocket errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-2-berrange@redhat.com>
+Patchwork-id: 78454
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 01/20] io: send proper HTTP response for websocket errors
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+When any error occurs while processing the websockets handshake,
+QEMU just terminates the connection abruptly. This is in violation
+of the HTTP specs and does not help the client understand what they
+did wrong. This is particularly bad when the client gives the wrong
+path, as a "404 Not Found" would be very helpful.
+
+Refactor the handshake code so that it always sends a response to
+the client unless there was an I/O error.
+
+Fixes bug: #1715186
+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit f69a8bde29354493ff8aea64cc9cb3b531d16337)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 185 ++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 139 insertions(+), 46 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 5a3badb..f5fac5b 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -25,6 +25,8 @@
+ #include "crypto/hash.h"
+ #include "trace.h"
+ 
++#include <time.h>
++
+ 
+ /* Max amount to allow in rawinput/rawoutput buffers */
+ #define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192
+@@ -44,13 +46,40 @@
+ #define QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE "Upgrade"
+ #define QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET "websocket"
+ 
+-#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE  \
++#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
++    "Server: QEMU VNC\r\n"                       \
++    "Date: %s\r\n"
++
++#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK    \
+     "HTTP/1.1 101 Switching Protocols\r\n"      \
++    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON    \
+     "Upgrade: websocket\r\n"                    \
+     "Connection: Upgrade\r\n"                   \
+     "Sec-WebSocket-Accept: %s\r\n"              \
+     "Sec-WebSocket-Protocol: binary\r\n"        \
+     "\r\n"
++#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND \
++    "HTTP/1.1 404 Not Found\r\n"                    \
++    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON        \
++    "Connection: close\r\n"                         \
++    "\r\n"
++#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST \
++    "HTTP/1.1 400 Bad Request\r\n"                    \
++    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON          \
++    "Connection: close\r\n"                           \
++    "Sec-WebSocket-Version: "                         \
++    QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION             \
++    "\r\n"
++#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR \
++    "HTTP/1.1 500 Internal Server Error\r\n"         \
++    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON         \
++    "Connection: close\r\n"                          \
++    "\r\n"
++#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE  \
++    "HTTP/1.1 403 Request Entity Too Large\r\n"      \
++    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON         \
++    "Connection: close\r\n"                          \
++    "\r\n"
+ #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM "\r\n"
+ #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_END "\r\n\r\n"
+ #define QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "13"
+@@ -123,8 +152,46 @@ enum {
+     QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA
+ };
+ 
++static void qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
++                                                   const char *resmsg,
++                                                   ...)
++{
++    va_list vargs;
++    char *response;
++    size_t responselen;
++
++    va_start(vargs, resmsg);
++    response = g_strdup_vprintf(resmsg, vargs);
++    responselen = strlen(response);
++    buffer_reserve(&ioc->encoutput, responselen);
++    buffer_append(&ioc->encoutput, response, responselen);
++    va_end(vargs);
++}
++
++static gchar *qio_channel_websock_date_str(void)
++{
++    struct tm tm;
++    time_t now = time(NULL);
++    char datebuf[128];
++
++    gmtime_r(&now, &tm);
++
++    strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y %H:%M:%S GMT", &tm);
++
++    return g_strdup(datebuf);
++}
++
++static void qio_channel_websock_handshake_send_res_err(QIOChannelWebsock *ioc,
++                                                       const char *resdata)
++{
++    char *date = qio_channel_websock_date_str();
++    qio_channel_websock_handshake_send_res(ioc, resdata, date);
++    g_free(date);
++}
++
+ static size_t
+-qio_channel_websock_extract_headers(char *buffer,
++qio_channel_websock_extract_headers(QIOChannelWebsock *ioc,
++                                    char *buffer,
+                                     QIOChannelWebsockHTTPHeader *hdrs,
+                                     size_t nhdrsalloc,
+                                     Error **errp)
+@@ -145,7 +212,7 @@ qio_channel_websock_extract_headers(char *buffer,
+     nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
+     if (!nl) {
+         error_setg(errp, "Missing HTTP header delimiter");
+-        return 0;
++        goto bad_request;
+     }
+     *nl = '\0';
+ 
+@@ -158,18 +225,20 @@ qio_channel_websock_extract_headers(char *buffer,
+ 
+     if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_METHOD)) {
+         error_setg(errp, "Unsupported HTTP method %s", buffer);
+-        return 0;
++        goto bad_request;
+     }
+ 
+     buffer = tmp + 1;
+     tmp = strchr(buffer, ' ');
+     if (!tmp) {
+         error_setg(errp, "Missing HTTP version delimiter");
+-        return 0;
++        goto bad_request;
+     }
+     *tmp = '\0';
+ 
+     if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_PATH)) {
++        qio_channel_websock_handshake_send_res_err(
++            ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND);
+         error_setg(errp, "Unexpected HTTP path %s", buffer);
+         return 0;
+     }
+@@ -178,7 +247,7 @@ qio_channel_websock_extract_headers(char *buffer,
+ 
+     if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_VERSION)) {
+         error_setg(errp, "Unsupported HTTP version %s", buffer);
+-        return 0;
++        goto bad_request;
+     }
+ 
+     buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
+@@ -203,7 +272,7 @@ qio_channel_websock_extract_headers(char *buffer,
+         sep = strchr(buffer, ':');
+         if (!sep) {
+             error_setg(errp, "Malformed HTTP header");
+-            return 0;
++            goto bad_request;
+         }
+         *sep = '\0';
+         sep++;
+@@ -213,7 +282,7 @@ qio_channel_websock_extract_headers(char *buffer,
+ 
+         if (nhdrs >= nhdrsalloc) {
+             error_setg(errp, "Too many HTTP headers");
+-            return 0;
++            goto bad_request;
+         }
+ 
+         hdr = &hdrs[nhdrs++];
+@@ -231,6 +300,11 @@ qio_channel_websock_extract_headers(char *buffer,
+     } while (nl != NULL);
+ 
+     return nhdrs;
++
++ bad_request:
++    qio_channel_websock_handshake_send_res_err(
++        ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST);
++    return 0;
+ }
+ 
+ static const char *
+@@ -250,14 +324,14 @@ qio_channel_websock_find_header(QIOChannelWebsockHTTPHeader *hdrs,
+ }
+ 
+ 
+-static int qio_channel_websock_handshake_send_response(QIOChannelWebsock *ioc,
+-                                                       const char *key,
+-                                                       Error **errp)
++static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
++                                                      const char *key,
++                                                      Error **errp)
+ {
+     char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
+                       QIO_CHANNEL_WEBSOCK_GUID_LEN + 1];
+-    char *accept = NULL, *response = NULL;
+-    size_t responselen;
++    char *accept = NULL;
++    char *date = qio_channel_websock_date_str();
+ 
+     g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1);
+     g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID,
+@@ -271,105 +345,108 @@ static int qio_channel_websock_handshake_send_response(QIOChannelWebsock *ioc,
+                             QIO_CHANNEL_WEBSOCK_GUID_LEN,
+                             &accept,
+                             errp) < 0) {
+-        return -1;
++        qio_channel_websock_handshake_send_res_err(
++            ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR);
++        return;
+     }
+ 
+-    response = g_strdup_printf(QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE, accept);
+-    responselen = strlen(response);
+-    buffer_reserve(&ioc->encoutput, responselen);
+-    buffer_append(&ioc->encoutput, response, responselen);
++    qio_channel_websock_handshake_send_res(
++        ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
+ 
++    g_free(date);
+     g_free(accept);
+-    g_free(response);
+-
+-    return 0;
+ }
+ 
+-static int qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
+-                                                 char *buffer,
+-                                                 Error **errp)
++static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
++                                                  char *buffer,
++                                                  Error **errp)
+ {
+     QIOChannelWebsockHTTPHeader hdrs[32];
+     size_t nhdrs = G_N_ELEMENTS(hdrs);
+     const char *protocols = NULL, *version = NULL, *key = NULL,
+         *host = NULL, *connection = NULL, *upgrade = NULL;
+ 
+-    nhdrs = qio_channel_websock_extract_headers(buffer, hdrs, nhdrs, errp);
++    nhdrs = qio_channel_websock_extract_headers(ioc, buffer, hdrs, nhdrs, errp);
+     if (!nhdrs) {
+-        return -1;
++        return;
+     }
+ 
+     protocols = qio_channel_websock_find_header(
+         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL);
+     if (!protocols) {
+         error_setg(errp, "Missing websocket protocol header data");
+-        return -1;
++        goto bad_request;
+     }
+ 
+     version = qio_channel_websock_find_header(
+         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
+     if (!version) {
+         error_setg(errp, "Missing websocket version header data");
+-        return -1;
++        goto bad_request;
+     }
+ 
+     key = qio_channel_websock_find_header(
+         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_KEY);
+     if (!key) {
+         error_setg(errp, "Missing websocket key header data");
+-        return -1;
++        goto bad_request;
+     }
+ 
+     host = qio_channel_websock_find_header(
+         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_HOST);
+     if (!host) {
+         error_setg(errp, "Missing websocket host header data");
+-        return -1;
++        goto bad_request;
+     }
+ 
+     connection = qio_channel_websock_find_header(
+         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION);
+     if (!connection) {
+         error_setg(errp, "Missing websocket connection header data");
+-        return -1;
++        goto bad_request;
+     }
+ 
+     upgrade = qio_channel_websock_find_header(
+         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE);
+     if (!upgrade) {
+         error_setg(errp, "Missing websocket upgrade header data");
+-        return -1;
++        goto bad_request;
+     }
+ 
+     if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) {
+         error_setg(errp, "No '%s' protocol is supported by client '%s'",
+                    QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols);
+-        return -1;
++        goto bad_request;
+     }
+ 
+     if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) {
+         error_setg(errp, "Version '%s' is not supported by client '%s'",
+                    QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION, version);
+-        return -1;
++        goto bad_request;
+     }
+ 
+     if (strlen(key) != QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN) {
+         error_setg(errp, "Key length '%zu' was not as expected '%d'",
+                    strlen(key), QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN);
+-        return -1;
++        goto bad_request;
+     }
+ 
+     if (!g_strrstr(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE)) {
+         error_setg(errp, "No connection upgrade requested '%s'", connection);
+-        return -1;
++        goto bad_request;
+     }
+ 
+     if (!g_str_equal(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET)) {
+         error_setg(errp, "Incorrect upgrade method '%s'", upgrade);
+-        return -1;
++        goto bad_request;
+     }
+ 
+-    return qio_channel_websock_handshake_send_response(ioc, key, errp);
++    qio_channel_websock_handshake_send_res_ok(ioc, key, errp);
++    return;
++
++ bad_request:
++    qio_channel_websock_handshake_send_res_err(
++        ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST);
+ }
+ 
+ static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
+@@ -393,20 +470,20 @@ static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
+                                  QIO_CHANNEL_WEBSOCK_HANDSHAKE_END);
+     if (!handshake_end) {
+         if (ioc->encinput.offset >= 4096) {
++            qio_channel_websock_handshake_send_res_err(
++                ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE);
+             error_setg(errp,
+                        "End of headers not found in first 4096 bytes");
+-            return -1;
++            return 1;
+         } else {
+             return 0;
+         }
+     }
+     *handshake_end = '\0';
+ 
+-    if (qio_channel_websock_handshake_process(ioc,
+-                                              (char *)ioc->encinput.buffer,
+-                                              errp) < 0) {
+-        return -1;
+-    }
++    qio_channel_websock_handshake_process(ioc,
++                                          (char *)ioc->encinput.buffer,
++                                          errp);
+ 
+     buffer_advance(&ioc->encinput,
+                    handshake_end - (char *)ioc->encinput.buffer +
+@@ -438,8 +515,15 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
+ 
+     buffer_advance(&wioc->encoutput, ret);
+     if (wioc->encoutput.offset == 0) {
+-        trace_qio_channel_websock_handshake_complete(ioc);
+-        qio_task_complete(task);
++        if (wioc->io_err) {
++            trace_qio_channel_websock_handshake_fail(ioc);
++            qio_task_set_error(task, wioc->io_err);
++            wioc->io_err = NULL;
++            qio_task_complete(task);
++        } else {
++            trace_qio_channel_websock_handshake_complete(ioc);
++            qio_task_complete(task);
++        }
+         return FALSE;
+     }
+     trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT);
+@@ -458,6 +542,11 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+ 
+     ret = qio_channel_websock_handshake_read(wioc, &err);
+     if (ret < 0) {
++        /*
++         * We only take this path on a fatal I/O error reading from
++         * client connection, as most of the time we have an
++         * HTTP 4xx err response to send instead
++         */
+         trace_qio_channel_websock_handshake_fail(ioc);
+         qio_task_set_error(task, err);
+         qio_task_complete(task);
+@@ -469,6 +558,10 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
+         return TRUE;
+     }
+ 
++    if (err) {
++        error_propagate(&wioc->io_err, err);
++    }
++
+     trace_qio_channel_websock_handshake_reply(ioc);
+     qio_channel_add_watch(
+         wioc->master,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-simplify-websocket-ping-reply-handling.patch b/SOURCES/kvm-io-simplify-websocket-ping-reply-handling.patch
new file mode 100644
index 0000000..6ae67ee
--- /dev/null
+++ b/SOURCES/kvm-io-simplify-websocket-ping-reply-handling.patch
@@ -0,0 +1,121 @@
+From d467ff7abd1aa30dca064883071bdd74d238567e Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:55 +0100
+Subject: [PATCH 15/42] io: simplify websocket ping reply handling
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-14-berrange@redhat.com>
+Patchwork-id: 78465
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 13/20] io: simplify websocket ping reply handling
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+We must ensure we don't get flooded with ping replies if the outbound
+channel is slow. Currently we do this by keeping the ping reply in a
+separate temporary buffer and only writing it if the encoutput buffer
+is completely empty. This is overly pessimistic, as it is reasonable
+to add a ping reply to the encoutput buffer even if it has previous
+data in it, as long as that previous data doesn't include a ping
+reply.
+
+To track this better, put the ping reply directly into the encoutput
+buffer, and then record the size of encoutput at this time in
+pong_remain. As we write encoutput to the underlying channel, we
+can decrement the pong_remain counter. Once it hits zero, we can
+accept further ping replies for transmission.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 57b0cdf152b7266e68bfa3e84635d4bdb64ef2cd)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/io/channel-websock.h |  2 +-
+ io/channel-websock.c         | 28 +++++++++++++++-------------
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/include/io/channel-websock.h b/include/io/channel-websock.h
+index ff32d86..3762707 100644
+--- a/include/io/channel-websock.h
++++ b/include/io/channel-websock.h
+@@ -60,8 +60,8 @@ struct QIOChannelWebsock {
+     Buffer encoutput;
+     Buffer rawinput;
+     Buffer rawoutput;
+-    Buffer ping_reply;
+     size_t payload_remain;
++    size_t pong_remain;
+     QIOChannelWebsockMask mask;
+     guint io_tag;
+     Error *io_err;
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 04bcc05..6083f74 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -825,11 +825,14 @@ static int qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
+         }
+         return -1;
+     } else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_PING) {
+-        /* ping frames produce an immediate reply */
+-        buffer_reset(&ioc->ping_reply);
+-        qio_channel_websock_encode_buffer(
+-            ioc, &ioc->ping_reply, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
+-            &ioc->encinput);
++        /* ping frames produce an immediate reply, as long as we've not still
++         * got a previous pong queued, in which case we drop the new pong */
++        if (ioc->pong_remain == 0) {
++            qio_channel_websock_encode_buffer(
++                ioc, &ioc->encoutput, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
++                &ioc->encinput);
++            ioc->pong_remain = ioc->encoutput.offset;
++        }
+     }   /* pong frames are ignored */
+ 
+     if (payload_len) {
+@@ -888,7 +891,6 @@ static void qio_channel_websock_finalize(Object *obj)
+     buffer_free(&ioc->encoutput);
+     buffer_free(&ioc->rawinput);
+     buffer_free(&ioc->rawoutput);
+-    buffer_free(&ioc->ping_reply);
+     object_unref(OBJECT(ioc->master));
+     if (ioc->io_tag) {
+         g_source_remove(ioc->io_tag);
+@@ -946,12 +948,7 @@ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc,
+     ssize_t ret;
+     ssize_t done = 0;
+ 
+-    /* ping replies take priority over binary data */
+-    if (!ioc->ping_reply.offset) {
+-        qio_channel_websock_encode(ioc);
+-    } else if (!ioc->encoutput.offset) {
+-        buffer_move_empty(&ioc->encoutput, &ioc->ping_reply);
+-    }
++    qio_channel_websock_encode(ioc);
+ 
+     while (ioc->encoutput.offset > 0) {
+         ret = qio_channel_write(ioc->master,
+@@ -968,6 +965,11 @@ static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc,
+         }
+         buffer_advance(&ioc->encoutput, ret);
+         done += ret;
++        if (ioc->pong_remain < ret) {
++            ioc->pong_remain = 0;
++        } else {
++            ioc->pong_remain -= ret;
++        }
+     }
+     return done;
+ }
+@@ -1026,7 +1028,7 @@ static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc)
+         return;
+     }
+ 
+-    if (ioc->encoutput.offset || ioc->ping_reply.offset) {
++    if (ioc->encoutput.offset) {
+         cond |= G_IO_OUT;
+     }
+     if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER &&
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-io-use-case-insensitive-check-for-Connection-Upgrade.patch b/SOURCES/kvm-io-use-case-insensitive-check-for-Connection-Upgrade.patch
new file mode 100644
index 0000000..1dd540b
--- /dev/null
+++ b/SOURCES/kvm-io-use-case-insensitive-check-for-Connection-Upgrade.patch
@@ -0,0 +1,49 @@
+From dad42ba543ed6ed3db06e33a08466c7a912b777e Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:45 +0100
+Subject: [PATCH 05/42] io: use case insensitive check for Connection & Upgrade
+ websock headers
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-4-berrange@redhat.com>
+Patchwork-id: 78456
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 03/20] io: use case insensitive check for Connection & Upgrade websock headers
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+When checking the value of the Connection and Upgrade HTTP headers
+the websock RFC (6455) requires the comparison to be case insensitive.
+The Connection value should be an exact match not a substring.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 33badfd1e3735b877e41939100511c65572be6b9)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ io/channel-websock.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/io/channel-websock.c b/io/channel-websock.c
+index 6ddcec1..2258557 100644
+--- a/io/channel-websock.c
++++ b/io/channel-websock.c
+@@ -431,12 +431,12 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
+         goto bad_request;
+     }
+ 
+-    if (!g_strrstr(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE)) {
++    if (strcasecmp(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) != 0) {
+         error_setg(errp, "No connection upgrade requested '%s'", connection);
+         goto bad_request;
+     }
+ 
+-    if (!g_str_equal(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET)) {
++    if (strcasecmp(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET) != 0) {
+         error_setg(errp, "Incorrect upgrade method '%s'", upgrade);
+         goto bad_request;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Add-cluster_size-64k-to-125.patch b/SOURCES/kvm-iotests-Add-cluster_size-64k-to-125.patch
new file mode 100644
index 0000000..65385eb
--- /dev/null
+++ b/SOURCES/kvm-iotests-Add-cluster_size-64k-to-125.patch
@@ -0,0 +1,882 @@
+From 8e88c188f93cf53c2b1f411520eedd82a8ed72a0 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Mon, 27 Nov 2017 16:19:59 +0100
+Subject: [PATCH 04/21] iotests: Add cluster_size=64k to 125
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20171127161959.13234-5-mreitz@redhat.com>
+Patchwork-id: 77914
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 4/4] iotests: Add cluster_size=64k to 125
+Bugzilla: 1414049
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Apparently it would be a good idea to test that, too.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20171009215533.12530-4-mreitz@redhat.com
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 4c112a397c2f61038914fa315a7896ce6d645d18)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/125     |   7 +-
+ tests/qemu-iotests/125.out | 480 ++++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 437 insertions(+), 50 deletions(-)
+
+diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
+index 9424313..c20c715 100755
+--- a/tests/qemu-iotests/125
++++ b/tests/qemu-iotests/125
+@@ -69,13 +69,15 @@ fi
+ # in B
+ CREATION_SIZE=$((2 * 1024 * 1024 - 48 * 1024))
+ 
++# 512 is the actual test -- but it's good to test 64k as well, just to be sure.
++for cluster_size in 512 64k; do
+ # in kB
+ for GROWTH_SIZE in 16 48 80; do
+     for create_mode in off metadata falloc full; do
+         for growth_mode in off metadata falloc full; do
+-            echo "--- growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
++            echo "--- cluster_size=$cluster_size growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
+ 
+-            IMGOPTS="preallocation=$create_mode,cluster_size=512" _make_test_img ${CREATION_SIZE}
++            IMGOPTS="preallocation=$create_mode,cluster_size=$cluster_size" _make_test_img ${CREATION_SIZE}
+             $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
+ 
+             host_size_0=$(get_image_size_on_host)
+@@ -123,6 +125,7 @@ for GROWTH_SIZE in 16 48 80; do
+         done
+     done
+ done
++done
+ 
+ # success, all done
+ echo '*** done'
+diff --git a/tests/qemu-iotests/125.out b/tests/qemu-iotests/125.out
+index 3f4d6e3..596905f 100644
+--- a/tests/qemu-iotests/125.out
++++ b/tests/qemu-iotests/125.out
+@@ -1,5 +1,5 @@
+ QA output created by 125
+---- growth_size=16 create_mode=off growth_mode=off ---
++--- cluster_size=512 growth_size=16 create_mode=off growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -7,7 +7,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=off growth_mode=metadata ---
++--- cluster_size=512 growth_size=16 create_mode=off growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -15,7 +15,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=off growth_mode=falloc ---
++--- cluster_size=512 growth_size=16 create_mode=off growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -23,7 +23,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=off growth_mode=full ---
++--- cluster_size=512 growth_size=16 create_mode=off growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -31,7 +31,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=metadata growth_mode=off ---
++--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -39,7 +39,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=metadata growth_mode=metadata ---
++--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -47,7 +47,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=metadata growth_mode=falloc ---
++--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -55,7 +55,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=metadata growth_mode=full ---
++--- cluster_size=512 growth_size=16 create_mode=metadata growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -63,7 +63,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=falloc growth_mode=off ---
++--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -71,7 +71,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=falloc growth_mode=metadata ---
++--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -79,7 +79,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=falloc growth_mode=falloc ---
++--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -87,7 +87,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=falloc growth_mode=full ---
++--- cluster_size=512 growth_size=16 create_mode=falloc growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -95,7 +95,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=full growth_mode=off ---
++--- cluster_size=512 growth_size=16 create_mode=full growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -103,7 +103,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=full growth_mode=metadata ---
++--- cluster_size=512 growth_size=16 create_mode=full growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -111,7 +111,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=full growth_mode=falloc ---
++--- cluster_size=512 growth_size=16 create_mode=full growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -119,7 +119,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=16 create_mode=full growth_mode=full ---
++--- cluster_size=512 growth_size=16 create_mode=full growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -127,7 +127,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 16384/16384 bytes at offset 2048000
+ 16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=off growth_mode=off ---
++--- cluster_size=512 growth_size=48 create_mode=off growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -135,7 +135,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=off growth_mode=metadata ---
++--- cluster_size=512 growth_size=48 create_mode=off growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -143,7 +143,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=off growth_mode=falloc ---
++--- cluster_size=512 growth_size=48 create_mode=off growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -151,7 +151,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=off growth_mode=full ---
++--- cluster_size=512 growth_size=48 create_mode=off growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -159,7 +159,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=metadata growth_mode=off ---
++--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -167,7 +167,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=metadata growth_mode=metadata ---
++--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -175,7 +175,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=metadata growth_mode=falloc ---
++--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -183,7 +183,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=metadata growth_mode=full ---
++--- cluster_size=512 growth_size=48 create_mode=metadata growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -191,7 +191,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=falloc growth_mode=off ---
++--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -199,7 +199,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=falloc growth_mode=metadata ---
++--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -207,7 +207,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=falloc growth_mode=falloc ---
++--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -215,7 +215,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=falloc growth_mode=full ---
++--- cluster_size=512 growth_size=48 create_mode=falloc growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -223,7 +223,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=full growth_mode=off ---
++--- cluster_size=512 growth_size=48 create_mode=full growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -231,7 +231,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=full growth_mode=metadata ---
++--- cluster_size=512 growth_size=48 create_mode=full growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -239,7 +239,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=full growth_mode=falloc ---
++--- cluster_size=512 growth_size=48 create_mode=full growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -247,7 +247,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=48 create_mode=full growth_mode=full ---
++--- cluster_size=512 growth_size=48 create_mode=full growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -255,7 +255,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 49152/49152 bytes at offset 2048000
+ 48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=off growth_mode=off ---
++--- cluster_size=512 growth_size=80 create_mode=off growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -263,7 +263,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=off growth_mode=metadata ---
++--- cluster_size=512 growth_size=80 create_mode=off growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -271,7 +271,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=off growth_mode=falloc ---
++--- cluster_size=512 growth_size=80 create_mode=off growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -279,7 +279,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=off growth_mode=full ---
++--- cluster_size=512 growth_size=80 create_mode=off growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -287,7 +287,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=metadata growth_mode=off ---
++--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -295,7 +295,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=metadata growth_mode=metadata ---
++--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -303,7 +303,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=metadata growth_mode=falloc ---
++--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -311,7 +311,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=metadata growth_mode=full ---
++--- cluster_size=512 growth_size=80 create_mode=metadata growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -319,7 +319,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=falloc growth_mode=off ---
++--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -327,7 +327,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=falloc growth_mode=metadata ---
++--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -335,7 +335,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=falloc growth_mode=falloc ---
++--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -343,7 +343,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=falloc growth_mode=full ---
++--- cluster_size=512 growth_size=80 create_mode=falloc growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -351,7 +351,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=full growth_mode=off ---
++--- cluster_size=512 growth_size=80 create_mode=full growth_mode=off ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -359,7 +359,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=full growth_mode=metadata ---
++--- cluster_size=512 growth_size=80 create_mode=full growth_mode=metadata ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -367,7 +367,7 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=full growth_mode=falloc ---
++--- cluster_size=512 growth_size=80 create_mode=full growth_mode=falloc ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+@@ -375,7 +375,391 @@ wrote 2048000/2048000 bytes at offset 0
+ wrote 81920/81920 bytes at offset 2048000
+ 80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ 
+---- growth_size=80 create_mode=full growth_mode=full ---
++--- cluster_size=512 growth_size=80 create_mode=full growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=off growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=off growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=off growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=off growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=metadata growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=falloc growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=full growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=full growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=full growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=16 create_mode=full growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 16384/16384 bytes at offset 2048000
++16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=off growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=off growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=off growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=off growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=metadata growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=falloc growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=full growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=full growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=full growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=48 create_mode=full growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 49152/49152 bytes at offset 2048000
++48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=off growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=off growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=off growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=off growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=metadata growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=falloc growth_mode=full ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=full growth_mode=off ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=full growth_mode=metadata ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=full growth_mode=falloc ---
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
++Image resized.
++wrote 2048000/2048000 bytes at offset 0
++1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 81920/81920 bytes at offset 2048000
++80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++--- cluster_size=64k growth_size=80 create_mode=full growth_mode=full ---
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full
+ Image resized.
+ wrote 2048000/2048000 bytes at offset 0
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Fix-195-if-IMGFMT-is-part-of-TEST_DIR.patch b/SOURCES/kvm-iotests-Fix-195-if-IMGFMT-is-part-of-TEST_DIR.patch
new file mode 100644
index 0000000..7b97923
--- /dev/null
+++ b/SOURCES/kvm-iotests-Fix-195-if-IMGFMT-is-part-of-TEST_DIR.patch
@@ -0,0 +1,67 @@
+From d13b20d0650519722da79a9cb9e4e0a1f2bee26c Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:07 +0100
+Subject: [PATCH 36/36] iotests: Fix 195 if IMGFMT is part of TEST_DIR
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-9-kwolf@redhat.com>
+Patchwork-id: 78108
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 8/8] iotests: Fix 195 if IMGFMT is part of TEST_DIR
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+From: Max Reitz <mreitz@redhat.com>
+
+do_run_qemu() in iotest 195 first applies _filter_imgfmt when printing
+qemu's command line and _filter_testdir only afterwards.  Therefore, if
+the image format is part of the test directory path, _filter_testdir
+will no longer apply and the actual output will differ from the
+reference output even in case of success.
+
+For example, TEST_DIR might be "/tmp/test-qcow2", in which case
+_filter_imgfmt first transforms this to "/tmp/test-IMGFMT" which is no
+longer recognized as the TEST_DIR by _filter_testdir.
+
+Fix this by not applying _filter_imgfmt in do_run_qemu() but in
+run_qemu() instead, and only after _filter_testdir.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20170927211334.3988-1-mreitz@redhat.com
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 47500c6775813c8f2b5a5de04d84222f3cecc62d)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/195 | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
+index 05a239c..e7a403d 100644
+--- a/tests/qemu-iotests/195
++++ b/tests/qemu-iotests/195
+@@ -44,15 +44,16 @@ _supported_os Linux
+ 
+ function do_run_qemu()
+ {
+-    echo Testing: "$@" | _filter_imgfmt
++    echo Testing: "$@"
+     $QEMU -nographic -qmp-pretty stdio -serial none "$@"
+     echo
+ }
+ 
+ function run_qemu()
+ {
+-    do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp \
+-                          | _filter_qemu_io | _filter_generated_node_ids
++    do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \
++                          | _filter_qmp | _filter_qemu_io \
++                          | _filter_generated_node_ids
+ }
+ 
+ size=64M
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-add-VM.add_object.patch b/SOURCES/kvm-iotests-add-VM.add_object.patch
new file mode 100644
index 0000000..d95d7ce
--- /dev/null
+++ b/SOURCES/kvm-iotests-add-VM.add_object.patch
@@ -0,0 +1,47 @@
+From cc83ddb2ea7c12b48d78160bd60b703097d849ea Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:58 +0100
+Subject: [PATCH 40/42] iotests: add VM.add_object()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-19-stefanha@redhat.com>
+Patchwork-id: 78500
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 18/20] iotests: add VM.add_object()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The VM.add_object() method can be used to add IOThreads or memory
+backend objects.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171207201320.19284-5-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit ccc15f7dafff63cbcc3f6a7c51e380025d67f7f4)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/iotests.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
+index 07fa162..4a3d3fb 100644
+--- a/tests/qemu-iotests/iotests.py
++++ b/tests/qemu-iotests/iotests.py
+@@ -198,6 +198,11 @@ class VM(qtest.QEMUQtestMachine):
+             self._debug = True
+         self._num_drives = 0
+ 
++    def add_object(self, opts):
++        self._args.append('-object')
++        self._args.append(opts)
++        return self
++
+     def add_device(self, opts):
+         self._args.append('-device')
+         self._args.append(opts)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests.py-add-FilePath-context-manager.patch b/SOURCES/kvm-iotests.py-add-FilePath-context-manager.patch
new file mode 100644
index 0000000..0c49e1a
--- /dev/null
+++ b/SOURCES/kvm-iotests.py-add-FilePath-context-manager.patch
@@ -0,0 +1,76 @@
+From 2715cad830a73bb550a4645054ff2e008f7e08fa Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:42 +0100
+Subject: [PATCH 24/42] iotests.py: add FilePath context manager
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-3-stefanha@redhat.com>
+Patchwork-id: 78484
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 02/20] iotests.py: add FilePath context manager
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The scratch/ (TEST_DIR) directory is not automatically cleaned up after
+test execution.  It is the responsibility of tests to remove any files
+they create.
+
+A nice way of doing this is to declare files at the beginning of the
+test and automatically remove them with a context manager:
+
+  with iotests.FilePath('test.img') as img_path:
+      qemu_img(...)
+      qemu_io(...)
+  # img_path is guaranteed to be deleted here
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: 20170824072202.26818-3-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit f4844ac0adabc458ba4610a71155448783d37c73)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/iotests.py | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
+index 7233983..07fa162 100644
+--- a/tests/qemu-iotests/iotests.py
++++ b/tests/qemu-iotests/iotests.py
+@@ -160,6 +160,32 @@ class Timeout:
+     def timeout(self, signum, frame):
+         raise Exception(self.errmsg)
+ 
++
++class FilePath(object):
++    '''An auto-generated filename that cleans itself up.
++
++    Use this context manager to generate filenames and ensure that the file
++    gets deleted::
++
++        with TestFilePath('test.img') as img_path:
++            qemu_img('create', img_path, '1G')
++        # migration_sock_path is automatically deleted
++    '''
++    def __init__(self, name):
++        filename = '{0}-{1}'.format(os.getpid(), name)
++        self.path = os.path.join(test_dir, filename)
++
++    def __enter__(self):
++        return self.path
++
++    def __exit__(self, exc_type, exc_val, exc_tb):
++        try:
++            os.remove(self.path)
++        except OSError:
++            pass
++        return False
++
++
+ class VM(qtest.QEMUQtestMachine):
+     '''A QEMU VM'''
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iothread-Make-iothread_stop-idempotent.patch b/SOURCES/kvm-iothread-Make-iothread_stop-idempotent.patch
new file mode 100644
index 0000000..972447c
--- /dev/null
+++ b/SOURCES/kvm-iothread-Make-iothread_stop-idempotent.patch
@@ -0,0 +1,56 @@
+From aad2de527db618942ce1f5cad0d9c2e29ec42f2e Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Thu, 19 Oct 2017 01:34:50 +0200
+Subject: [PATCH 61/69] iothread: Make iothread_stop() idempotent
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171019013453.21449-2-ehabkost@redhat.com>
+Patchwork-id: 77367
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/4] iothread: Make iothread_stop() idempotent
+Bugzilla: 1460848
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Currently, iothread_stop_all() makes all iothread objects unsafe
+to be destroyed, because qemu_thread_join() ends up being called
+twice.
+
+To fix this, make iothread_stop() idempotent by checking
+thread->stopped.
+
+Fixes the following crash:
+
+  qemu-system-x86_64 -object iothread,id=iothread0 -monitor stdio -display none
+  QEMU 2.10.50 monitor - type 'help' for more information
+  (qemu) quit
+  qemu: qemu_thread_join: No such process
+  Aborted (core dumped)
+
+Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20170926130028.12471-1-ehabkost@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 65072c157e466db2785748a929e775703b20eefe)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ iothread.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/iothread.c b/iothread.c
+index beeb870..d67bdd4 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -68,7 +68,7 @@ static int iothread_stop(Object *object, void *opaque)
+     IOThread *iothread;
+ 
+     iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
+-    if (!iothread || !iothread->ctx) {
++    if (!iothread || !iothread->ctx || iothread->stopping) {
+         return 0;
+     }
+     iothread->stopping = true;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iothread-add-iothread_by_id-API.patch b/SOURCES/kvm-iothread-add-iothread_by_id-API.patch
new file mode 100644
index 0000000..261ec95
--- /dev/null
+++ b/SOURCES/kvm-iothread-add-iothread_by_id-API.patch
@@ -0,0 +1,60 @@
+From 84bd8f0e4da949579b20ea0879c8b44404ef2604 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:54 +0100
+Subject: [PATCH 36/42] iothread: add iothread_by_id() API
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-15-stefanha@redhat.com>
+Patchwork-id: 78498
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 14/20] iothread: add iothread_by_id() API
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Encapsulate IOThread QOM object lookup so that callers don't need to
+know how and where IOThread objects live.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-8-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit fbcc6923b00c2b468a7470fec7863f0403a65736)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/sysemu/iothread.h | 1 +
+ iothread.c                | 7 +++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
+index 110329b..55de171 100644
+--- a/include/sysemu/iothread.h
++++ b/include/sysemu/iothread.h
+@@ -42,6 +42,7 @@ typedef struct {
+    OBJECT_CHECK(IOThread, obj, TYPE_IOTHREAD)
+ 
+ char *iothread_get_id(IOThread *iothread);
++IOThread *iothread_by_id(const char *id);
+ AioContext *iothread_get_aio_context(IOThread *iothread);
+ void iothread_stop_all(void);
+ GMainContext *iothread_get_g_main_context(IOThread *iothread);
+diff --git a/iothread.c b/iothread.c
+index 27a4288..e7b93e0 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -380,3 +380,10 @@ void iothread_destroy(IOThread *iothread)
+ {
+     object_unparent(OBJECT(iothread));
+ }
++
++/* Lookup IOThread by its id.  Only finds user-created objects, not internal
++ * iothread_create() objects. */
++IOThread *iothread_by_id(const char *id)
++{
++    return IOTHREAD(object_resolve_path_type(id, TYPE_IOTHREAD, NULL));
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iothread-delay-the-context-release-to-finalize.patch b/SOURCES/kvm-iothread-delay-the-context-release-to-finalize.patch
new file mode 100644
index 0000000..3daf0f7
--- /dev/null
+++ b/SOURCES/kvm-iothread-delay-the-context-release-to-finalize.patch
@@ -0,0 +1,71 @@
+From 38a2a92899b4f351cb7f4c002428a064819a565a Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:47 +0100
+Subject: [PATCH 29/42] iothread: delay the context release to finalize
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-8-stefanha@redhat.com>
+Patchwork-id: 78489
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 07/20] iothread: delay the context release to finalize
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Peter Xu <peterx@redhat.com>
+
+When gcontext is used with iothread, the context will be destroyed
+during iothread_stop().  That's not good since sometimes we would like
+to keep the resources until iothread is destroyed, but we may want to
+stop the thread before that point.
+
+Delay the destruction of gcontext to iothread finalize.  Then we can do:
+
+  iothread_stop(thread);
+  some_cleanup_on_resources();
+  iothread_destroy(thread);
+
+We may need this patch if we want to run chardev IOs in iothreads and
+hopefully clean them up correctly.  For more specific information,
+please see 2b316774f6 ("qemu-char: do not operate on sources from
+finalize callbacks").
+
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-id: 20170928025958.1420-5-peterx@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 5b3ac23fee97fc1a79ad2bb1cf3a1ce518d27905)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ iothread.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/iothread.c b/iothread.c
+index b3c092b..27a4288 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -71,8 +71,6 @@ static void *iothread_run(void *opaque)
+             g_main_loop_unref(loop);
+ 
+             g_main_context_pop_thread_default(iothread->worker_context);
+-            g_main_context_unref(iothread->worker_context);
+-            iothread->worker_context = NULL;
+         }
+     }
+ 
+@@ -117,6 +115,10 @@ static void iothread_instance_finalize(Object *obj)
+     IOThread *iothread = IOTHREAD(obj);
+ 
+     iothread_stop(iothread);
++    if (iothread->worker_context) {
++        g_main_context_unref(iothread->worker_context);
++        iothread->worker_context = NULL;
++    }
+     qemu_cond_destroy(&iothread->init_done_cond);
+     qemu_mutex_destroy(&iothread->init_done_lock);
+     if (!iothread->ctx) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iothread-export-iothread_stop.patch b/SOURCES/kvm-iothread-export-iothread_stop.patch
new file mode 100644
index 0000000..76e665a
--- /dev/null
+++ b/SOURCES/kvm-iothread-export-iothread_stop.patch
@@ -0,0 +1,112 @@
+From 903416521c130289b769af87a70e19c2bbbff3aa Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:46 +0100
+Subject: [PATCH 28/42] iothread: export iothread_stop()
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-7-stefanha@redhat.com>
+Patchwork-id: 78488
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 06/20] iothread: export iothread_stop()
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Peter Xu <peterx@redhat.com>
+
+So that internal iothread users can explicitly stop one iothread without
+destroying it.
+
+Since at it, fix iothread_stop() to allow it to be called multiple
+times.  Before this patch we may call iothread_stop() more than once on
+single iothread, while that may not be correct since qemu_thread_join()
+is not allowed to run twice.  From manual of pthread_join():
+
+  Joining with a thread that has previously been joined results in
+  undefined behavior.
+
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-id: 20170928025958.1420-4-peterx@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 82d90705fe203cc6e150c10bd61f0dbe6979e8f4)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/sysemu/iothread.h |  1 +
+ iothread.c                | 24 ++++++++++++++++--------
+ 2 files changed, 17 insertions(+), 8 deletions(-)
+
+diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
+index b07663f..110329b 100644
+--- a/include/sysemu/iothread.h
++++ b/include/sysemu/iothread.h
+@@ -52,6 +52,7 @@ GMainContext *iothread_get_g_main_context(IOThread *iothread);
+  * "query-iothreads".
+  */
+ IOThread *iothread_create(const char *id, Error **errp);
++void iothread_stop(IOThread *iothread);
+ void iothread_destroy(IOThread *iothread);
+ 
+ #endif /* IOTHREAD_H */
+diff --git a/iothread.c b/iothread.c
+index 0672a91..b3c092b 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -80,13 +80,10 @@ static void *iothread_run(void *opaque)
+     return NULL;
+ }
+ 
+-static int iothread_stop(Object *object, void *opaque)
++void iothread_stop(IOThread *iothread)
+ {
+-    IOThread *iothread;
+-
+-    iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
+-    if (!iothread || !iothread->ctx || iothread->stopping) {
+-        return 0;
++    if (!iothread->ctx || iothread->stopping) {
++        return;
+     }
+     iothread->stopping = true;
+     aio_notify(iothread->ctx);
+@@ -94,6 +91,17 @@ static int iothread_stop(Object *object, void *opaque)
+         g_main_loop_quit(iothread->main_loop);
+     }
+     qemu_thread_join(&iothread->thread);
++}
++
++static int iothread_stop_iter(Object *object, void *opaque)
++{
++    IOThread *iothread;
++
++    iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
++    if (!iothread) {
++        return 0;
++    }
++    iothread_stop(iothread);
+     return 0;
+ }
+ 
+@@ -108,7 +116,7 @@ static void iothread_instance_finalize(Object *obj)
+ {
+     IOThread *iothread = IOTHREAD(obj);
+ 
+-    iothread_stop(obj, NULL);
++    iothread_stop(iothread);
+     qemu_cond_destroy(&iothread->init_done_cond);
+     qemu_mutex_destroy(&iothread->init_done_lock);
+     if (!iothread->ctx) {
+@@ -328,7 +336,7 @@ void iothread_stop_all(void)
+         aio_context_release(ctx);
+     }
+ 
+-    object_child_foreach(container, iothread_stop, NULL);
++    object_child_foreach(container, iothread_stop_iter, NULL);
+ }
+ 
+ static gpointer iothread_g_main_context_init(gpointer opaque)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iothread-fix-iothread_stop-race-condition.patch b/SOURCES/kvm-iothread-fix-iothread_stop-race-condition.patch
new file mode 100644
index 0000000..f3ace09
--- /dev/null
+++ b/SOURCES/kvm-iothread-fix-iothread_stop-race-condition.patch
@@ -0,0 +1,158 @@
+From 9750c7d9d35ac49262848a0996667f8e6c782dc8 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:59 +0100
+Subject: [PATCH 41/42] iothread: fix iothread_stop() race condition
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-20-stefanha@redhat.com>
+Patchwork-id: 78501
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 19/20] iothread: fix iothread_stop() race condition
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+There is a small chance that iothread_stop() hangs as follows:
+
+  Thread 3 (Thread 0x7f63eba5f700 (LWP 16105)):
+  #0  0x00007f64012c09b6 in ppoll () at /lib64/libc.so.6
+  #1  0x000055959992eac9 in ppoll (__ss=0x0, __timeout=0x0, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/bits/poll2.h:77
+  #2  0x000055959992eac9 in qemu_poll_ns (fds=<optimized out>, nfds=<optimized out>, timeout=<optimized out>) at util/qemu-timer.c:322
+  #3  0x0000559599930711 in aio_poll (ctx=0x55959bdb83c0, blocking=blocking@entry=true) at util/aio-posix.c:629
+  #4  0x00005595996806fe in iothread_run (opaque=0x55959bd78400) at iothread.c:59
+  #5  0x00007f640159f609 in start_thread () at /lib64/libpthread.so.0
+  #6  0x00007f64012cce6f in clone () at /lib64/libc.so.6
+
+  Thread 1 (Thread 0x7f640b45b280 (LWP 16103)):
+  #0  0x00007f64015a0b6d in pthread_join () at /lib64/libpthread.so.0
+  #1  0x00005595999332ef in qemu_thread_join (thread=<optimized out>) at util/qemu-thread-posix.c:547
+  #2  0x00005595996808ae in iothread_stop (iothread=<optimized out>) at iothread.c:91
+  #3  0x000055959968094d in iothread_stop_iter (object=<optimized out>, opaque=<optimized out>) at iothread.c:102
+  #4  0x0000559599857d97 in do_object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 <iothread_stop_iter>, opaque=opaque@entry=0x0, recurse=recurse@entry=false) at qom/object.c:852
+  #5  0x0000559599859477 in object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 <iothread_stop_iter>, opaque=opaque@entry=0x0) at qom/object.c:867
+  #6  0x0000559599680a6e in iothread_stop_all () at iothread.c:341
+  #7  0x000055959955b1d5 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4913
+
+The relevant code from iothread_run() is:
+
+  while (!atomic_read(&iothread->stopping)) {
+      aio_poll(iothread->ctx, true);
+
+and iothread_stop():
+
+  iothread->stopping = true;
+  aio_notify(iothread->ctx);
+  ...
+  qemu_thread_join(&iothread->thread);
+
+The following scenario can occur:
+
+1. IOThread:
+  while (!atomic_read(&iothread->stopping)) -> stopping=false
+
+2. Main loop:
+  iothread->stopping = true;
+  aio_notify(iothread->ctx);
+
+3. IOThread:
+  aio_poll(iothread->ctx, true); -> hang
+
+The bug is explained by the AioContext->notify_me doc comments:
+
+  "If this field is 0, everything (file descriptors, bottom halves,
+  timers) will be re-evaluated before the next blocking poll(), thus the
+  event_notifier_set call can be skipped."
+
+The problem is that "everything" does not include checking
+iothread->stopping.  This means iothread_run() will block in aio_poll()
+if aio_notify() was called just before aio_poll().
+
+This patch fixes the hang by replacing aio_notify() with
+aio_bh_schedule_oneshot().  This makes aio_poll() or g_main_loop_run()
+to return.
+
+Implementing this properly required a new bool running flag.  The new
+flag prevents races that are tricky if we try to use iothread->stopping.
+Now iothread->stopping is purely for iothread_stop() and
+iothread->running is purely for the iothread_run() thread.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171207201320.19284-6-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 2362a28ea11c145e1a13ae79342d76dc118a72a6)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/sysemu/iothread.h |  3 ++-
+ iothread.c                | 20 +++++++++++++++-----
+ 2 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
+index 55de171..799614f 100644
+--- a/include/sysemu/iothread.h
++++ b/include/sysemu/iothread.h
+@@ -29,7 +29,8 @@ typedef struct {
+     GOnce once;
+     QemuMutex init_done_lock;
+     QemuCond init_done_cond;    /* is thread initialization done? */
+-    bool stopping;
++    bool stopping;              /* has iothread_stop() been called? */
++    bool running;               /* should iothread_run() continue? */
+     int thread_id;
+ 
+     /* AioContext poll parameters */
+diff --git a/iothread.c b/iothread.c
+index e7b93e0..d8b6c1f 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -55,7 +55,7 @@ static void *iothread_run(void *opaque)
+     qemu_cond_signal(&iothread->init_done_cond);
+     qemu_mutex_unlock(&iothread->init_done_lock);
+ 
+-    while (!atomic_read(&iothread->stopping)) {
++    while (iothread->running) {
+         aio_poll(iothread->ctx, true);
+ 
+         if (atomic_read(&iothread->worker_context)) {
+@@ -78,16 +78,25 @@ static void *iothread_run(void *opaque)
+     return NULL;
+ }
+ 
++/* Runs in iothread_run() thread */
++static void iothread_stop_bh(void *opaque)
++{
++    IOThread *iothread = opaque;
++
++    iothread->running = false; /* stop iothread_run() */
++
++    if (iothread->main_loop) {
++        g_main_loop_quit(iothread->main_loop);
++    }
++}
++
+ void iothread_stop(IOThread *iothread)
+ {
+     if (!iothread->ctx || iothread->stopping) {
+         return;
+     }
+     iothread->stopping = true;
+-    aio_notify(iothread->ctx);
+-    if (atomic_read(&iothread->main_loop)) {
+-        g_main_loop_quit(iothread->main_loop);
+-    }
++    aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
+     qemu_thread_join(&iothread->thread);
+ }
+ 
+@@ -134,6 +143,7 @@ static void iothread_complete(UserCreatable *obj, Error **errp)
+     char *name, *thread_name;
+ 
+     iothread->stopping = false;
++    iothread->running = true;
+     iothread->thread_id = -1;
+     iothread->ctx = aio_context_new(&local_error);
+     if (!iothread->ctx) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iothread-provide-helpers-for-internal-use.patch b/SOURCES/kvm-iothread-provide-helpers-for-internal-use.patch
new file mode 100644
index 0000000..e7f0335
--- /dev/null
+++ b/SOURCES/kvm-iothread-provide-helpers-for-internal-use.patch
@@ -0,0 +1,79 @@
+From a709d66bc6e7b3559fbd8502c6f94b76b6a899d1 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:45 +0100
+Subject: [PATCH 27/42] iothread: provide helpers for internal use
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-6-stefanha@redhat.com>
+Patchwork-id: 78487
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 05/20] iothread: provide helpers for internal use
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Peter Xu <peterx@redhat.com>
+
+IOThread is a general framework that contains IO loop environment and a
+real thread behind.  It's also good to be used internally inside qemu.
+Provide some helpers for it to create iothreads to be used internally.
+
+Put all the internal used iothreads into the internal object container.
+
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-id: 20170928025958.1420-3-peterx@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 0173e21b617d3de1fcfa917e329bb9194ab332a4)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/sysemu/iothread.h |  8 ++++++++
+ iothread.c                | 16 ++++++++++++++++
+ 2 files changed, 24 insertions(+)
+
+diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
+index d2985b3..b07663f 100644
+--- a/include/sysemu/iothread.h
++++ b/include/sysemu/iothread.h
+@@ -46,4 +46,12 @@ AioContext *iothread_get_aio_context(IOThread *iothread);
+ void iothread_stop_all(void);
+ GMainContext *iothread_get_g_main_context(IOThread *iothread);
+ 
++/*
++ * Helpers used to allocate iothreads for internal use.  These
++ * iothreads will not be seen by monitor clients when query using
++ * "query-iothreads".
++ */
++IOThread *iothread_create(const char *id, Error **errp);
++void iothread_destroy(IOThread *iothread);
++
+ #endif /* IOTHREAD_H */
+diff --git a/iothread.c b/iothread.c
+index 59d0850..0672a91 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -354,3 +354,19 @@ GMainContext *iothread_get_g_main_context(IOThread *iothread)
+ 
+     return iothread->worker_context;
+ }
++
++IOThread *iothread_create(const char *id, Error **errp)
++{
++    Object *obj;
++
++    obj = object_new_with_props(TYPE_IOTHREAD,
++                                object_get_internal_root(),
++                                id, errp, NULL);
++
++    return IOTHREAD(obj);
++}
++
++void iothread_destroy(IOThread *iothread)
++{
++    object_unparent(OBJECT(iothread));
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-kdump-set-vmcoreinfo-location.patch b/SOURCES/kvm-kdump-set-vmcoreinfo-location.patch
new file mode 100644
index 0000000..aaadcaf
--- /dev/null
+++ b/SOURCES/kvm-kdump-set-vmcoreinfo-location.patch
@@ -0,0 +1,79 @@
+From b3bd980c95466b3bd35b784b2862a3896e4b3dbc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:08 +0100
+Subject: [PATCH 10/21] kdump: set vmcoreinfo location
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-7-marcandre.lureau@redhat.com>
+Patchwork-id: 77923
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 6/9] kdump: set vmcoreinfo location
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+kdump header provides offset and size of the vmcoreinfo content,
+append it if available (skip the ELF note header).
+
+crash-7.1.9 was the first version that started looking in the
+vmcoreinfo data for phys_base instead of in the kdump_sub_header.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit 9ada575bbafaf6d3724a7f59df9da89776817cac)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ dump.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/dump.c b/dump.c
+index e3175d7..1852db9 100644
+--- a/dump.c
++++ b/dump.c
+@@ -858,6 +858,18 @@ static void create_header32(DumpState *s, Error **errp)
+     kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
+ 
+     offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
++    if (s->guest_note &&
++        note_name_equal(s, s->guest_note, "VMCOREINFO")) {
++        uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
++
++        get_note_sizes(s, s->guest_note,
++                       &hsize, &name_size, &size_vmcoreinfo_desc);
++        offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
++            (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
++        kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
++        kh->size_vmcoreinfo = cpu_to_dump32(s, size_vmcoreinfo_desc);
++    }
++
+     kh->offset_note = cpu_to_dump64(s, offset_note);
+     kh->note_size = cpu_to_dump32(s, s->note_size);
+ 
+@@ -958,6 +970,18 @@ static void create_header64(DumpState *s, Error **errp)
+     kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
+ 
+     offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
++    if (s->guest_note &&
++        note_name_equal(s, s->guest_note, "VMCOREINFO")) {
++        uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
++
++        get_note_sizes(s, s->guest_note,
++                       &hsize, &name_size, &size_vmcoreinfo_desc);
++        offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
++            (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
++        kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
++        kh->size_vmcoreinfo = cpu_to_dump64(s, size_vmcoreinfo_desc);
++    }
++
+     kh->offset_note = cpu_to_dump64(s, offset_note);
+     kh->note_size = cpu_to_dump64(s, s->note_size);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-linux-headers-Partial-header-update-against-v4.15-rc.patch b/SOURCES/kvm-linux-headers-Partial-header-update-against-v4.15-rc.patch
new file mode 100644
index 0000000..6cb0baa
--- /dev/null
+++ b/SOURCES/kvm-linux-headers-Partial-header-update-against-v4.15-rc.patch
@@ -0,0 +1,52 @@
+From 0669bbc6c287d15912c9501b391f051ff463801e Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Tue, 28 Nov 2017 15:14:07 +0100
+Subject: [PATCH 6/9] linux-headers: Partial header update against v4.15-rc1
+ for ITS reset
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <1511882048-11256-7-git-send-email-eric.auger@redhat.com>
+Patchwork-id: 77938
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 6/7] linux-headers: Partial header update against v4.15-rc1 for ITS reset
+Bugzilla: 1513323
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Wei Huang <wei@redhat.com>
+
+This aims at importing the KVM_DEV_ARM_ITS_CTRL_RESET attribute
+which allows to trigger a reset of the in-kernel emulated ITS.
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ linux-headers/asm-arm/kvm.h   | 1 +
+ linux-headers/asm-arm64/kvm.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
+index fa9fae8..8dd0ba7 100644
+--- a/linux-headers/asm-arm/kvm.h
++++ b/linux-headers/asm-arm/kvm.h
+@@ -215,6 +215,7 @@ struct kvm_arch_memory_slot {
+ #define   KVM_DEV_ARM_ITS_SAVE_TABLES		1
+ #define   KVM_DEV_ARM_ITS_RESTORE_TABLES	2
+ #define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
++#define   KVM_DEV_ARM_ITS_CTRL_RESET		4
+ 
+ /* KVM_IRQ_LINE irq field index values */
+ #define KVM_ARM_IRQ_TYPE_SHIFT		24
+diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
+index d254700..2585a50 100644
+--- a/linux-headers/asm-arm64/kvm.h
++++ b/linux-headers/asm-arm64/kvm.h
+@@ -227,6 +227,7 @@ struct kvm_arch_memory_slot {
+ #define   KVM_DEV_ARM_ITS_SAVE_TABLES           1
+ #define   KVM_DEV_ARM_ITS_RESTORE_TABLES        2
+ #define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
++#define   KVM_DEV_ARM_ITS_CTRL_RESET		4
+ 
+ /* Device Control API on vcpu fd */
+ #define KVM_ARM_VCPU_PMU_V3_CTRL	0
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-linux-headers-update.patch b/SOURCES/kvm-linux-headers-update.patch
new file mode 100644
index 0000000..d968825
--- /dev/null
+++ b/SOURCES/kvm-linux-headers-update.patch
@@ -0,0 +1,176 @@
+From 170662bb45c6a4290391c8f896e437b5dc67e229 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 23 Jan 2018 19:12:44 +0100
+Subject: [PATCH 2/8] linux-headers: update
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1516734766-12075-2-git-send-email-thuth@redhat.com>
+Patchwork-id: 78699
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 1/3] linux-headers: update
+Bugzilla: 1535606
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Cornelia Huck <cohuck@redhat.com>
+
+Update headers against 4.15-rc9.
+
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 9cbb636270b4df6f0a548e5c34b895330db5df8b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	include/standard-headers/asm-s390/virtio-ccw.h
+	linux-headers/linux/kvm.h
+	(simple conflicts since commit dd8739669f95b3065 was missing)
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+---
+ include/standard-headers/asm-s390/virtio-ccw.h |  5 +----
+ linux-headers/asm-powerpc/kvm.h                | 25 +++++++++++++++++++++++++
+ linux-headers/asm-s390/kvm.h                   |  9 ++++-----
+ linux-headers/asm-s390/kvm_para.h              |  4 ----
+ linux-headers/linux/kvm.h                      |  9 +++++++--
+ 5 files changed, 37 insertions(+), 15 deletions(-)
+
+diff --git a/include/standard-headers/asm-s390/virtio-ccw.h b/include/standard-headers/asm-s390/virtio-ccw.h
+index a9a4ebf..2b605f7 100644
+--- a/include/standard-headers/asm-s390/virtio-ccw.h
++++ b/include/standard-headers/asm-s390/virtio-ccw.h
+@@ -1,12 +1,9 @@
++/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+ /*
+  * Definitions for virtio-ccw devices.
+  *
+  * Copyright IBM Corp. 2013
+  *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License (version 2 only)
+- * as published by the Free Software Foundation.
+- *
+  *  Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
+  */
+ #ifndef __KVM_VIRTIO_CCW_H
+diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
+index 8cf8f0c..a1cb407 100644
+--- a/linux-headers/asm-powerpc/kvm.h
++++ b/linux-headers/asm-powerpc/kvm.h
+@@ -442,6 +442,31 @@ struct kvm_ppc_rmmu_info {
+ 	__u32	ap_encodings[8];
+ };
+ 
++/* For KVM_PPC_GET_CPU_CHAR */
++struct kvm_ppc_cpu_char {
++	__u64	character;		/* characteristics of the CPU */
++	__u64	behaviour;		/* recommended software behaviour */
++	__u64	character_mask;		/* valid bits in character */
++	__u64	behaviour_mask;		/* valid bits in behaviour */
++};
++
++/*
++ * Values for character and character_mask.
++ * These are identical to the values used by H_GET_CPU_CHARACTERISTICS.
++ */
++#define KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31		(1ULL << 63)
++#define KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED	(1ULL << 62)
++#define KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30	(1ULL << 61)
++#define KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2	(1ULL << 60)
++#define KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV	(1ULL << 59)
++#define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED	(1ULL << 58)
++#define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF	(1ULL << 57)
++#define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS	(1ULL << 56)
++
++#define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY	(1ULL << 63)
++#define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR		(1ULL << 62)
++#define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR	(1ULL << 61)
++
+ /* Per-vcpu XICS interrupt controller state */
+ #define KVM_REG_PPC_ICP_STATE	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
+ 
+diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
+index 8387d71..08ee46a 100644
+--- a/linux-headers/asm-s390/kvm.h
++++ b/linux-headers/asm-s390/kvm.h
+@@ -5,10 +5,6 @@
+  *
+  * Copyright IBM Corp. 2008
+  *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License (version 2 only)
+- * as published by the Free Software Foundation.
+- *
+  *    Author(s): Carsten Otte <cotte@de.ibm.com>
+  *               Christian Borntraeger <borntraeger@de.ibm.com>
+  */
+@@ -221,6 +217,7 @@ struct kvm_guest_debug_arch {
+ #define KVM_SYNC_RICCB  (1UL << 7)
+ #define KVM_SYNC_FPRS   (1UL << 8)
+ #define KVM_SYNC_GSCB   (1UL << 9)
++#define KVM_SYNC_BPBC   (1UL << 10)
+ /* length and alignment of the sdnx as a power of two */
+ #define SDNXC 8
+ #define SDNXL (1UL << SDNXC)
+@@ -244,7 +241,9 @@ struct kvm_sync_regs {
+ 	};
+ 	__u8  reserved[512];	/* for future vector expansion */
+ 	__u32 fpc;		/* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
+-	__u8 padding1[52];	/* riccb needs to be 64byte aligned */
++	__u8 bpbc : 1;		/* bp mode */
++	__u8 reserved2 : 7;
++	__u8 padding1[51];	/* riccb needs to be 64byte aligned */
+ 	__u8 riccb[64];		/* runtime instrumentation controls block */
+ 	__u8 padding2[192];	/* sdnx needs to be 256byte aligned */
+ 	union {
+diff --git a/linux-headers/asm-s390/kvm_para.h b/linux-headers/asm-s390/kvm_para.h
+index ff1f4e7..1a81ec9 100644
+--- a/linux-headers/asm-s390/kvm_para.h
++++ b/linux-headers/asm-s390/kvm_para.h
+@@ -3,9 +3,5 @@
+  *
+  * Copyright IBM Corp. 2008
+  *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License (version 2 only)
+- * as published by the Free Software Foundation.
+- *
+  *    Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
+  */
+diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
+index 7971a4f..fabd075 100644
+--- a/linux-headers/linux/kvm.h
++++ b/linux-headers/linux/kvm.h
+@@ -629,9 +629,9 @@ struct kvm_s390_irq {
+ 
+ struct kvm_s390_irq_state {
+ 	__u64 buf;
+-	__u32 flags;
++	__u32 flags;        /* will stay unused for compatibility reasons */
+ 	__u32 len;
+-	__u32 reserved[4];
++	__u32 reserved[4];  /* will stay unused for compatibility reasons */
+ };
+ 
+ /* for KVM_SET_GUEST_DEBUG */
+@@ -929,6 +929,9 @@ struct kvm_ppc_resize_hpt {
+ #define KVM_CAP_PPC_SMT_POSSIBLE 147
+ #define KVM_CAP_HYPERV_SYNIC2 148
+ #define KVM_CAP_HYPERV_VP_INDEX 149
++#define KVM_CAP_S390_AIS_MIGRATION 150
++#define KVM_CAP_PPC_GET_CPU_CHAR 151
++#define KVM_CAP_S390_BPB 152
+ 
+ #ifdef KVM_CAP_IRQ_ROUTING
+ 
+@@ -1258,6 +1261,8 @@ struct kvm_s390_ucas_mapping {
+ #define KVM_PPC_CONFIGURE_V3_MMU  _IOW(KVMIO,  0xaf, struct kvm_ppc_mmuv3_cfg)
+ /* Available with KVM_CAP_PPC_RADIX_MMU */
+ #define KVM_PPC_GET_RMMU_INFO	  _IOW(KVMIO,  0xb0, struct kvm_ppc_rmmu_info)
++/* Available with KVM_CAP_PPC_GET_CPU_CHAR */
++#define KVM_PPC_GET_CPU_CHAR	  _IOR(KVMIO,  0xb1, struct kvm_ppc_cpu_char)
+ 
+ /* ioctl for vm fd */
+ #define KVM_CREATE_DEVICE	  _IOWR(KVMIO,  0xe0, struct kvm_create_device)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-machine-compat-pci_bridge-shpc-always-enable.patch b/SOURCES/kvm-machine-compat-pci_bridge-shpc-always-enable.patch
new file mode 100644
index 0000000..cecc604
--- /dev/null
+++ b/SOURCES/kvm-machine-compat-pci_bridge-shpc-always-enable.patch
@@ -0,0 +1,50 @@
+From 229441f111066fb4340ac6ae49cf26db2f81b884 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Fri, 3 Nov 2017 13:03:42 +0100
+Subject: [PATCH 5/9] machine compat: pci_bridge/shpc always enable
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171103130342.9839-1-dgilbert@redhat.com>
+Patchwork-id: 77494
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] machine compat: pci_bridge/shpc always enable
+Bugzilla: 1508271
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+The 'shpc' property on bridges has changed its default back and
+forward.
+Upstream it's off on 2.9 machine types but on for all the others
+(upstream dc0ae767 turned it off, 2fa35662 reverted it).
+Downstream we always had it on, even for 7.4 that was derived from
+2.9.
+Unfortunately we imported the 2.9 entry that turned it off, which
+breaks migration.  Remove that entry, shpc is now on again for
+all our machine types.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/hw/compat.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/include/hw/compat.h b/include/hw/compat.h
+index 85c6cbe..7a2a4a6 100644
+--- a/include/hw/compat.h
++++ b/include/hw/compat.h
+@@ -419,10 +419,6 @@
+  */
+ #define HW_COMPAT_RHEL7_4 \
+     { /* HW_COMPAT_RHEL7_4 */ \
+-        .driver   = "pci-bridge",\
+-        .property = "shpc",\
+-        .value    = "off",\
+-    },{ /* HW_COMPAT_RHEL7_4 */ \
+         .driver   = "intel-iommu",\
+         .property = "pt",\
+         .value    = "off",\
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Alloc-dispatch-tree-where-topology-is-generar.patch b/SOURCES/kvm-memory-Alloc-dispatch-tree-where-topology-is-generar.patch
new file mode 100644
index 0000000..c5b9f77
--- /dev/null
+++ b/SOURCES/kvm-memory-Alloc-dispatch-tree-where-topology-is-generar.patch
@@ -0,0 +1,76 @@
+From 3ff6f640c89c152317214aecb7cb8071f60164d5 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:23 +0100
+Subject: [PATCH 19/30] memory: Alloc dispatch tree where topology is generared
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-14-dgibson@redhat.com>
+Patchwork-id: 77704
+O-Subject: [PATCH 13/22] memory: Alloc dispatch tree where topology is generared
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This is to make next patches simpler.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-11-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 9bf561e36cf8fed9565011a19ba9ea0100e1811e)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 7972235..8034520 100644
+--- a/memory.c
++++ b/memory.c
+@@ -742,6 +742,7 @@ static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
+ /* Render a memory topology into a list of disjoint absolute ranges. */
+ static FlatView *generate_memory_topology(MemoryRegion *mr)
+ {
++    int i;
+     FlatView *view;
+ 
+     view = flatview_new(mr);
+@@ -752,6 +753,14 @@ static FlatView *generate_memory_topology(MemoryRegion *mr)
+     }
+     flatview_simplify(view);
+ 
++    view->dispatch = address_space_dispatch_new(view);
++    for (i = 0; i < view->nr; i++) {
++        MemoryRegionSection mrs =
++            section_from_flat_range(&view->ranges[i], view);
++        flatview_add_to_dispatch(view, &mrs);
++    }
++    address_space_dispatch_compact(view->dispatch);
++
+     return view;
+ }
+ 
+@@ -925,15 +934,6 @@ static void address_space_update_topology(AddressSpace *as)
+     FlatView *old_view = address_space_get_flatview(as);
+     MemoryRegion *physmr = memory_region_get_flatview_root(old_view->root);
+     FlatView *new_view = generate_memory_topology(physmr);
+-    int i;
+-
+-    new_view->dispatch = address_space_dispatch_new(new_view);
+-    for (i = 0; i < new_view->nr; i++) {
+-        MemoryRegionSection mrs =
+-            section_from_flat_range(&new_view->ranges[i], new_view);
+-        flatview_add_to_dispatch(new_view, &mrs);
+-    }
+-    address_space_dispatch_compact(new_view->dispatch);
+ 
+     if (!QTAILQ_EMPTY(&as->listeners)) {
+         address_space_update_topology_pass(as, old_view, new_view, false);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Cleanup-after-switching-to-FlatView.patch b/SOURCES/kvm-memory-Cleanup-after-switching-to-FlatView.patch
new file mode 100644
index 0000000..2affa44
--- /dev/null
+++ b/SOURCES/kvm-memory-Cleanup-after-switching-to-FlatView.patch
@@ -0,0 +1,98 @@
+From f11d0111c641b1ea0c961f1faee7f9682c4f272c Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:20 +0100
+Subject: [PATCH 16/30] memory: Cleanup after switching to FlatView
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-11-dgibson@redhat.com>
+Patchwork-id: 77701
+O-Subject: [PATCH 10/22] memory: Cleanup after switching to FlatView
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+We store AddressSpaceDispatch* in FlatView anyway so there is no need
+to carry it from mem_add() to register_subpage/register_multipage.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-8-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 9950322a593ff900a860fb52938159461798a831)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ exec.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 0eedeb2..d1d8486 100644
+--- a/exec.c
++++ b/exec.c
+@@ -1314,9 +1314,9 @@ static void phys_sections_free(PhysPageMap *map)
+     g_free(map->nodes);
+ }
+ 
+-static void register_subpage(FlatView *fv, AddressSpaceDispatch *d,
+-                             MemoryRegionSection *section)
++static void register_subpage(FlatView *fv, MemoryRegionSection *section)
+ {
++    AddressSpaceDispatch *d = flatview_to_dispatch(fv);
+     subpage_t *subpage;
+     hwaddr base = section->offset_within_address_space
+         & TARGET_PAGE_MASK;
+@@ -1345,9 +1345,10 @@ static void register_subpage(FlatView *fv, AddressSpaceDispatch *d,
+ }
+ 
+ 
+-static void register_multipage(AddressSpaceDispatch *d,
++static void register_multipage(FlatView *fv,
+                                MemoryRegionSection *section)
+ {
++    AddressSpaceDispatch *d = flatview_to_dispatch(fv);
+     hwaddr start_addr = section->offset_within_address_space;
+     uint16_t section_index = phys_section_add(&d->map, section);
+     uint64_t num_pages = int128_get64(int128_rshift(section->size,
+@@ -1359,7 +1360,6 @@ static void register_multipage(AddressSpaceDispatch *d,
+ 
+ void mem_add(FlatView *fv, MemoryRegionSection *section)
+ {
+-    AddressSpaceDispatch *d = flatview_to_dispatch(fv);
+     MemoryRegionSection now = *section, remain = *section;
+     Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
+ 
+@@ -1368,7 +1368,7 @@ void mem_add(FlatView *fv, MemoryRegionSection *section)
+                        - now.offset_within_address_space;
+ 
+         now.size = int128_min(int128_make64(left), now.size);
+-        register_subpage(fv, d, &now);
++        register_subpage(fv, &now);
+     } else {
+         now.size = int128_zero();
+     }
+@@ -1378,13 +1378,13 @@ void mem_add(FlatView *fv, MemoryRegionSection *section)
+         remain.offset_within_region += int128_get64(now.size);
+         now = remain;
+         if (int128_lt(remain.size, page_size)) {
+-            register_subpage(fv, d, &now);
++            register_subpage(fv, &now);
+         } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
+             now.size = page_size;
+-            register_subpage(fv, d, &now);
++            register_subpage(fv, &now);
+         } else {
+             now.size = int128_and(now.size, int128_neg(page_size));
+-            register_multipage(d, &now);
++            register_multipage(fv, &now);
+         }
+     }
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Create-FlatView-directly.patch b/SOURCES/kvm-memory-Create-FlatView-directly.patch
new file mode 100644
index 0000000..ab73cde
--- /dev/null
+++ b/SOURCES/kvm-memory-Create-FlatView-directly.patch
@@ -0,0 +1,81 @@
+From 61fad0cef2ed50a900717d11aab2e5e0ef121894 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:29 +0100
+Subject: [PATCH 25/30] memory: Create FlatView directly
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-20-dgibson@redhat.com>
+Patchwork-id: 77703
+O-Subject: [PATCH 19/22] memory: Create FlatView directly
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This avoids usual memory_region_transaction_commit() which rebuilds
+all FVs.
+
+On POWER8 with 255 CPUs, 255 virtio-net, 40 PCI bridges guest this brings
+down the boot time from 25s to 20s and reduces the amount of temporary FVs
+allocated during machine constructon (~800000 -> ~640000) and amount of
+temporary dispatch trees (~370000 -> ~300000), the total memory footprint
+goes down (18G -> 17G).
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-18-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 202fc01b05572ecb258fdf4c5bd56cf6de8140c7)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 00d5788..93b4221 100644
+--- a/memory.c
++++ b/memory.c
+@@ -1009,6 +1009,17 @@ static void address_space_set_flatview(AddressSpace *as)
+     }
+ }
+ 
++static void address_space_update_topology(AddressSpace *as)
++{
++    MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
++
++    flatviews_init();
++    if (!g_hash_table_lookup(flat_views, physmr)) {
++        generate_memory_topology(physmr);
++    }
++    address_space_set_flatview(as);
++}
++
+ void memory_region_transaction_begin(void)
+ {
+     qemu_flush_coalesced_mmio_buffer();
+@@ -2720,7 +2731,6 @@ void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
+ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+ {
+     memory_region_ref(root);
+-    memory_region_transaction_begin();
+     as->root = root;
+     as->current_map = NULL;
+     as->ioeventfd_nb = 0;
+@@ -2728,8 +2738,8 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+     QTAILQ_INIT(&as->listeners);
+     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
+     as->name = g_strdup(name ? name : "anonymous");
+-    memory_region_update_pending |= root->enabled;
+-    memory_region_transaction_commit();
++    address_space_update_topology(as);
++    address_space_update_ioeventfds(as);
+ }
+ 
+ static void do_address_space_destroy(AddressSpace *as)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Do-not-allocate-FlatView-in-address_space_ini.patch b/SOURCES/kvm-memory-Do-not-allocate-FlatView-in-address_space_ini.patch
new file mode 100644
index 0000000..0948209
--- /dev/null
+++ b/SOURCES/kvm-memory-Do-not-allocate-FlatView-in-address_space_ini.patch
@@ -0,0 +1,100 @@
+From 5bfc2be91ba382cf0c0353794ff9289cb9b064de Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:26 +0100
+Subject: [PATCH 22/30] memory: Do not allocate FlatView in address_space_init
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-17-dgibson@redhat.com>
+Patchwork-id: 77705
+O-Subject: [PATCH 16/22] memory: Do not allocate FlatView in address_space_init
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This creates a new AS object without any FlatView as
+memory_region_transaction_commit() may want to reuse the empty FV.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-14-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 67ace39b253ed5ae465275bc870f7e495547658b)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index f0c8642..6914d87 100644
+--- a/memory.c
++++ b/memory.c
+@@ -966,22 +966,37 @@ static void flatviews_reset(void)
+ 
+ static void address_space_set_flatview(AddressSpace *as)
+ {
+-    FlatView *old_view = address_space_get_flatview(as);
++    FlatView *old_view = address_space_to_flatview(as);
+     MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
+     FlatView *new_view = g_hash_table_lookup(flat_views, physmr);
+ 
+     assert(new_view);
+ 
++    if (old_view == new_view) {
++        return;
++    }
++
++    if (old_view) {
++        flatview_ref(old_view);
++    }
++
+     flatview_ref(new_view);
+ 
+     if (!QTAILQ_EMPTY(&as->listeners)) {
+-        address_space_update_topology_pass(as, old_view, new_view, false);
+-        address_space_update_topology_pass(as, old_view, new_view, true);
++        FlatView tmpview = { .nr = 0 }, *old_view2 = old_view;
++
++        if (!old_view2) {
++            old_view2 = &tmpview;
++        }
++        address_space_update_topology_pass(as, old_view2, new_view, false);
++        address_space_update_topology_pass(as, old_view2, new_view, true);
+     }
+ 
+     /* Writes are protected by the BQL.  */
+     atomic_rcu_set(&as->current_map, new_view);
+-    flatview_unref(old_view);
++    if (old_view) {
++        flatview_unref(old_view);
++    }
+ 
+     /* Note that all the old MemoryRegions are still alive up to this
+      * point.  This relieves most MemoryListeners from the need to
+@@ -989,7 +1004,9 @@ static void address_space_set_flatview(AddressSpace *as)
+      * outside the iothread mutex, in which case precise reference
+      * counting is necessary.
+      */
+-    flatview_unref(old_view);
++    if (old_view) {
++        flatview_unref(old_view);
++    }
+ }
+ 
+ void memory_region_transaction_begin(void)
+@@ -2707,7 +2724,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+     as->ref_count = 1;
+     as->root = root;
+     as->malloced = false;
+-    as->current_map = flatview_new(root);
++    as->current_map = NULL;
+     as->ioeventfd_nb = 0;
+     as->ioeventfds = NULL;
+     QTAILQ_INIT(&as->listeners);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Get-rid-of-address_space_init_shareable.patch b/SOURCES/kvm-memory-Get-rid-of-address_space_init_shareable.patch
new file mode 100644
index 0000000..4a5222c
--- /dev/null
+++ b/SOURCES/kvm-memory-Get-rid-of-address_space_init_shareable.patch
@@ -0,0 +1,264 @@
+From 9695c6db4ca09b6bebcffcccfd37aae5c1845021 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:28 +0100
+Subject: [PATCH 24/30] memory: Get rid of address_space_init_shareable
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-19-dgibson@redhat.com>
+Patchwork-id: 77710
+O-Subject: [PATCH 18/22] memory: Get rid of address_space_init_shareable
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+Since FlatViews are shared now and ASes not, this gets rid of
+address_space_init_shareable().
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-17-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit b516572f31c0ea0937cd9d11d9bd72dd83809886)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	target/arm/cpu.c
+
+Conflicts because we don't have 1d2091bc75a "target/arm: Register
+second AddressSpace for secure v8M CPUs" downstream.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ cpus.c                  |  5 +++--
+ hw/arm/armv7m.c         |  9 ++++-----
+ include/exec/memory.h   | 19 -------------------
+ include/hw/arm/armv7m.h |  2 +-
+ memory.c                | 21 ---------------------
+ target/arm/cpu.c        | 15 ++++++++-------
+ target/i386/cpu.c       |  5 +++--
+ 7 files changed, 19 insertions(+), 57 deletions(-)
+
+diff --git a/cpus.c b/cpus.c
+index 9bed61e..c9a6240 100644
+--- a/cpus.c
++++ b/cpus.c
+@@ -1764,8 +1764,9 @@ void qemu_init_vcpu(CPUState *cpu)
+         /* If the target cpu hasn't set up any address spaces itself,
+          * give it the default one.
+          */
+-        AddressSpace *as = address_space_init_shareable(cpu->memory,
+-                                                        "cpu-memory");
++        AddressSpace *as = g_new0(AddressSpace, 1);
++
++        address_space_init(as, cpu->memory, "cpu-memory");
+         cpu->num_ases = 1;
+         cpu_address_space_init(cpu, as, 0);
+     }
+diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
+index c8a11f2..475a88f 100644
+--- a/hw/arm/armv7m.c
++++ b/hw/arm/armv7m.c
+@@ -41,7 +41,7 @@ static MemTxResult bitband_read(void *opaque, hwaddr offset,
+ 
+     /* Find address in underlying memory and round down to multiple of size */
+     addr = bitband_addr(s, offset) & (-size);
+-    res = address_space_read(s->source_as, addr, attrs, buf, size);
++    res = address_space_read(&s->source_as, addr, attrs, buf, size);
+     if (res) {
+         return res;
+     }
+@@ -66,7 +66,7 @@ static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value,
+ 
+     /* Find address in underlying memory and round down to multiple of size */
+     addr = bitband_addr(s, offset) & (-size);
+-    res = address_space_read(s->source_as, addr, attrs, buf, size);
++    res = address_space_read(&s->source_as, addr, attrs, buf, size);
+     if (res) {
+         return res;
+     }
+@@ -79,7 +79,7 @@ static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value,
+     } else {
+         buf[bitpos >> 3] &= ~bit;
+     }
+-    return address_space_write(s->source_as, addr, attrs, buf, size);
++    return address_space_write(&s->source_as, addr, attrs, buf, size);
+ }
+ 
+ static const MemoryRegionOps bitband_ops = {
+@@ -117,8 +117,7 @@ static void bitband_realize(DeviceState *dev, Error **errp)
+         return;
+     }
+ 
+-    s->source_as = address_space_init_shareable(s->source_memory,
+-                                                "bitband-source");
++    address_space_init(&s->source_as, s->source_memory, "bitband-source");
+ }
+ 
+ /* Board init.  */
+diff --git a/include/exec/memory.h b/include/exec/memory.h
+index 157eae6..8d772b9 100644
+--- a/include/exec/memory.h
++++ b/include/exec/memory.h
+@@ -319,8 +319,6 @@ struct AddressSpace {
+     struct rcu_head rcu;
+     char *name;
+     MemoryRegion *root;
+-    int ref_count;
+-    bool malloced;
+ 
+     /* Accessed via RCU.  */
+     struct FlatView *current_map;
+@@ -1596,23 +1594,6 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
+ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name);
+ 
+ /**
+- * address_space_init_shareable: return an address space for a memory region,
+- *                               creating it if it does not already exist
+- *
+- * @root: a #MemoryRegion that routes addresses for the address space
+- * @name: an address space name.  The name is only used for debugging
+- *        output.
+- *
+- * This function will return a pointer to an existing AddressSpace
+- * which was initialized with the specified MemoryRegion, or it will
+- * create and initialize one if it does not already exist. The ASes
+- * are reference-counted, so the memory will be freed automatically
+- * when the AddressSpace is destroyed via address_space_destroy.
+- */
+-AddressSpace *address_space_init_shareable(MemoryRegion *root,
+-                                           const char *name);
+-
+-/**
+  * address_space_destroy: destroy an address space
+  *
+  * Releases all resources associated with an address space.  After an address space
+diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
+index a9b3f2a..dba77df 100644
+--- a/include/hw/arm/armv7m.h
++++ b/include/hw/arm/armv7m.h
+@@ -21,7 +21,7 @@ typedef struct {
+     SysBusDevice parent_obj;
+     /*< public >*/
+ 
+-    AddressSpace *source_as;
++    AddressSpace source_as;
+     MemoryRegion iomem;
+     uint32_t base;
+     MemoryRegion *source_memory;
+diff --git a/memory.c b/memory.c
+index 25a8bf2..00d5788 100644
+--- a/memory.c
++++ b/memory.c
+@@ -2721,9 +2721,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+ {
+     memory_region_ref(root);
+     memory_region_transaction_begin();
+-    as->ref_count = 1;
+     as->root = root;
+-    as->malloced = false;
+     as->current_map = NULL;
+     as->ioeventfd_nb = 0;
+     as->ioeventfds = NULL;
+@@ -2736,37 +2734,18 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+ 
+ static void do_address_space_destroy(AddressSpace *as)
+ {
+-    bool do_free = as->malloced;
+-
+     assert(QTAILQ_EMPTY(&as->listeners));
+ 
+     flatview_unref(as->current_map);
+     g_free(as->name);
+     g_free(as->ioeventfds);
+     memory_region_unref(as->root);
+-    if (do_free) {
+-        g_free(as);
+-    }
+-}
+-
+-AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name)
+-{
+-    AddressSpace *as;
+-
+-    as = g_malloc0(sizeof *as);
+-    address_space_init(as, root, name);
+-    as->malloced = true;
+-    return as;
+ }
+ 
+ void address_space_destroy(AddressSpace *as)
+ {
+     MemoryRegion *root = as->root;
+ 
+-    as->ref_count--;
+-    if (as->ref_count) {
+-        return;
+-    }
+     /* Flush out anything from MemoryListeners listening in on this */
+     memory_region_transaction_begin();
+     as->root = NULL;
+diff --git a/target/arm/cpu.c b/target/arm/cpu.c
+index 3f90b7e..b6c8d93 100644
+--- a/target/arm/cpu.c
++++ b/target/arm/cpu.c
+@@ -650,6 +650,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
+     CPUARMState *env = &cpu->env;
+     int pagebits;
+     Error *local_err = NULL;
++#ifndef CONFIG_USER_ONLY
++    AddressSpace *as;
++#endif
+ 
+     cpu_exec_realizefn(cs, &local_err);
+     if (local_err != NULL) {
+@@ -835,19 +838,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
+     }
+ 
+     if (cpu->has_el3) {
+-        AddressSpace *as;
++        as = g_new0(AddressSpace, 1);
+ 
+         if (!cpu->secure_memory) {
+             cpu->secure_memory = cs->memory;
+         }
+-        as = address_space_init_shareable(cpu->secure_memory,
+-                                          "cpu-secure-memory");
++        address_space_init(as, cpu->secure_memory, "cpu-secure-memory");
+         cpu_address_space_init(cs, as, ARMASIdx_S);
+     }
+-    cpu_address_space_init(cs,
+-                           address_space_init_shareable(cs->memory,
+-                                                        "cpu-memory"),
+-                           ARMASIdx_NS);
++    as = g_new0(AddressSpace, 1);
++    address_space_init(as, cs->memory, "cpu-memory");
++    cpu_address_space_init(cs, as, ARMASIdx_NS);
+ #endif
+ 
+     qemu_init_vcpu(cs);
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 1cae8fe..ca95336 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3772,10 +3772,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+ 
+ #ifndef CONFIG_USER_ONLY
+     if (tcg_enabled()) {
+-        AddressSpace *as_normal = address_space_init_shareable(cs->memory,
+-                                                               "cpu-memory");
++        AddressSpace *as_normal = g_new0(AddressSpace, 1);
+         AddressSpace *as_smm = g_new(AddressSpace, 1);
+ 
++        address_space_init(as_normal, cs->memory, "cpu-memory");
++
+         cpu->cpu_as_mem = g_new(MemoryRegion, 1);
+         cpu->cpu_as_root = g_new(MemoryRegion, 1);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Move-AddressSpaceDispatch-from-AddressSpace-t.patch b/SOURCES/kvm-memory-Move-AddressSpaceDispatch-from-AddressSpace-t.patch
new file mode 100644
index 0000000..aed8d91
--- /dev/null
+++ b/SOURCES/kvm-memory-Move-AddressSpaceDispatch-from-AddressSpace-t.patch
@@ -0,0 +1,296 @@
+From 30acf078fced0fac523d4773fe06983d4cfce64d Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:17 +0100
+Subject: [PATCH 13/30] memory: Move AddressSpaceDispatch from AddressSpace to
+ FlatView
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-8-dgibson@redhat.com>
+Patchwork-id: 77697
+O-Subject: [PATCH 07/22] memory: Move AddressSpaceDispatch from AddressSpace to FlatView
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+As we are going to share FlatView's between AddressSpace's,
+and AddressSpaceDispatch is a structure to perform quick lookup
+in FlatView, this moves ASD to FlatView.
+
+After previosly open coded ASD rendering, we can also remove
+as->next_dispatch as the new FlatView pointer is stored
+on a stack and set to an AS atomically.
+
+flatview_destroy() is executed under RCU instead of
+address_space_dispatch_free() now.
+
+This makes mem_begin/mem_commit to work with ASD and mem_add with FV
+as later on mem_add will be taking FV as an argument anyway.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-5-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 66a6df1dc6d5b28cc3e65db0d71683fbdddc6b62)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	exec.c
+
+Conflicts because we applied d5e5fafd "exec: add page_mask for
+flatview_do_translate" out of order downstream.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ exec.c                         | 41 +++++++++++------------------------------
+ include/exec/memory-internal.h | 12 +++++++-----
+ include/exec/memory.h          |  2 --
+ memory.c                       | 31 ++++++++++++++++++++++++-------
+ 4 files changed, 42 insertions(+), 44 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 4fed7b7..3c0b4f8 100644
+--- a/exec.c
++++ b/exec.c
+@@ -188,8 +188,6 @@ typedef struct PhysPageMap {
+ } PhysPageMap;
+ 
+ struct AddressSpaceDispatch {
+-    struct rcu_head rcu;
+-
+     MemoryRegionSection *mru_section;
+     /* This is a multi-level map on the physical address space.
+      * The bottom level has pointers to MemoryRegionSections.
+@@ -493,7 +491,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+     }
+ 
+     for (;;) {
+-        AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
++        AddressSpaceDispatch *d = address_space_to_dispatch(as);
+         section = address_space_translate_internal(d, addr, &addr, &plen, is_mmio);
+ 
+         iommu_mr = memory_region_get_iommu(section->mr);
+@@ -1233,7 +1231,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
+     } else {
+         AddressSpaceDispatch *d;
+ 
+-        d = atomic_rcu_read(&section->address_space->dispatch);
++        d = address_space_to_dispatch(section->address_space);
+         iotlb = section - d->map.sections;
+         iotlb += xlat;
+     }
+@@ -1358,9 +1356,9 @@ static void register_multipage(AddressSpaceDispatch *d,
+     phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
+ }
+ 
+-void mem_add(AddressSpace *as, MemoryRegionSection *section)
++void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
+ {
+-    AddressSpaceDispatch *d = as->next_dispatch;
++    AddressSpaceDispatch *d = flatview_to_dispatch(fv);
+     MemoryRegionSection now = *section, remain = *section;
+     Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
+ 
+@@ -2683,7 +2681,7 @@ static void io_mem_init(void)
+                           NULL, UINT64_MAX);
+ }
+ 
+-void mem_begin(AddressSpace *as)
++AddressSpaceDispatch *mem_begin(AddressSpace *as)
+ {
+     AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
+     uint16_t n;
+@@ -2699,26 +2697,19 @@ void mem_begin(AddressSpace *as)
+ 
+     d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
+     d->as = as;
+-    as->next_dispatch = d;
++
++    return d;
+ }
+ 
+-static void address_space_dispatch_free(AddressSpaceDispatch *d)
++void address_space_dispatch_free(AddressSpaceDispatch *d)
+ {
+     phys_sections_free(&d->map);
+     g_free(d);
+ }
+ 
+-void mem_commit(AddressSpace *as)
++void mem_commit(AddressSpaceDispatch *d)
+ {
+-    AddressSpaceDispatch *cur = as->dispatch;
+-    AddressSpaceDispatch *next = as->next_dispatch;
+-
+-    phys_page_compact_all(next, next->map.nodes_nb);
+-
+-    atomic_rcu_set(&as->dispatch, next);
+-    if (cur) {
+-        call_rcu(cur, address_space_dispatch_free, rcu);
+-    }
++    phys_page_compact_all(d, d->map.nodes_nb);
+ }
+ 
+ static void tcg_commit(MemoryListener *listener)
+@@ -2734,21 +2725,11 @@ static void tcg_commit(MemoryListener *listener)
+      * We reload the dispatch pointer now because cpu_reloading_memory_map()
+      * may have split the RCU critical section.
+      */
+-    d = atomic_rcu_read(&cpuas->as->dispatch);
++    d = address_space_to_dispatch(cpuas->as);
+     atomic_rcu_set(&cpuas->memory_dispatch, d);
+     tlb_flush(cpuas->cpu);
+ }
+ 
+-void address_space_destroy_dispatch(AddressSpace *as)
+-{
+-    AddressSpaceDispatch *d = as->dispatch;
+-
+-    atomic_rcu_set(&as->dispatch, NULL);
+-    if (d) {
+-        call_rcu(d, address_space_dispatch_free, rcu);
+-    }
+-}
+-
+ static void memory_map_init(void)
+ {
+     system_memory = g_malloc(sizeof(*system_memory));
+diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
+index 9abde2f..6e08eda 100644
+--- a/include/exec/memory-internal.h
++++ b/include/exec/memory-internal.h
+@@ -22,16 +22,18 @@
+ #ifndef CONFIG_USER_ONLY
+ typedef struct AddressSpaceDispatch AddressSpaceDispatch;
+ 
+-void address_space_destroy_dispatch(AddressSpace *as);
+-
+ extern const MemoryRegionOps unassigned_mem_ops;
+ 
+ bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
+                                 unsigned size, bool is_write);
+ 
+-void mem_add(AddressSpace *as, MemoryRegionSection *section);
+-void mem_begin(AddressSpace *as);
+-void mem_commit(AddressSpace *as);
++void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section);
++AddressSpaceDispatch *mem_begin(AddressSpace *as);
++void mem_commit(AddressSpaceDispatch *d);
++
++AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as);
++AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv);
++void address_space_dispatch_free(AddressSpaceDispatch *d);
+ 
+ #endif
+ #endif
+diff --git a/include/exec/memory.h b/include/exec/memory.h
+index 9ee0f2e..8f26d63 100644
+--- a/include/exec/memory.h
++++ b/include/exec/memory.h
+@@ -326,8 +326,6 @@ struct AddressSpace {
+ 
+     int ioeventfd_nb;
+     struct MemoryRegionIoeventfd *ioeventfds;
+-    struct AddressSpaceDispatch *dispatch;
+-    struct AddressSpaceDispatch *next_dispatch;
+     QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
+     QTAILQ_ENTRY(AddressSpace) address_spaces_link;
+ };
+diff --git a/memory.c b/memory.c
+index f51e499..41e2e67 100644
+--- a/memory.c
++++ b/memory.c
+@@ -229,6 +229,7 @@ struct FlatView {
+     FlatRange *ranges;
+     unsigned nr;
+     unsigned nr_allocated;
++    struct AddressSpaceDispatch *dispatch;
+ };
+ 
+ typedef struct AddressSpaceOps AddressSpaceOps;
+@@ -289,6 +290,9 @@ static void flatview_destroy(FlatView *view)
+ {
+     int i;
+ 
++    if (view->dispatch) {
++        address_space_dispatch_free(view->dispatch);
++    }
+     for (i = 0; i < view->nr; i++) {
+         memory_region_unref(view->ranges[i].mr);
+     }
+@@ -304,10 +308,25 @@ static bool flatview_ref(FlatView *view)
+ static void flatview_unref(FlatView *view)
+ {
+     if (atomic_fetch_dec(&view->ref) == 1) {
+-        flatview_destroy(view);
++        call_rcu(view, flatview_destroy, rcu);
+     }
+ }
+ 
++static FlatView *address_space_to_flatview(AddressSpace *as)
++{
++    return atomic_rcu_read(&as->current_map);
++}
++
++AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv)
++{
++    return fv->dispatch;
++}
++
++AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
++{
++    return flatview_to_dispatch(address_space_to_flatview(as));
++}
++
+ static bool can_merge(FlatRange *r1, FlatRange *r2)
+ {
+     return int128_eq(addrrange_end(r1->addr), r2->addr.start)
+@@ -890,13 +909,13 @@ static void address_space_update_topology(AddressSpace *as)
+     FlatView *new_view = generate_memory_topology(as->root);
+     int i;
+ 
+-    mem_begin(as);
++    new_view->dispatch = mem_begin(as);
+     for (i = 0; i < new_view->nr; i++) {
+         MemoryRegionSection mrs =
+             section_from_flat_range(&new_view->ranges[i], as);
+-        mem_add(as, &mrs);
++        mem_add(as, new_view, &mrs);
+     }
+-    mem_commit(as);
++    mem_commit(new_view->dispatch);
+ 
+     if (!QTAILQ_EMPTY(&as->listeners)) {
+         address_space_update_topology_pass(as, old_view, new_view, false);
+@@ -905,7 +924,7 @@ static void address_space_update_topology(AddressSpace *as)
+ 
+     /* Writes are protected by the BQL.  */
+     atomic_rcu_set(&as->current_map, new_view);
+-    call_rcu(old_view, flatview_unref, rcu);
++    flatview_unref(old_view);
+ 
+     /* Note that all the old MemoryRegions are still alive up to this
+      * point.  This relieves most MemoryListeners from the need to
+@@ -2635,7 +2654,6 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+     QTAILQ_INIT(&as->listeners);
+     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
+     as->name = g_strdup(name ? name : "anonymous");
+-    as->dispatch = NULL;
+     memory_region_update_pending |= root->enabled;
+     memory_region_transaction_commit();
+ }
+@@ -2644,7 +2662,6 @@ static void do_address_space_destroy(AddressSpace *as)
+ {
+     bool do_free = as->malloced;
+ 
+-    address_space_destroy_dispatch(as);
+     assert(QTAILQ_EMPTY(&as->listeners));
+ 
+     flatview_unref(as->current_map);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Move-FlatView-allocation-to-a-helper.patch b/SOURCES/kvm-memory-Move-FlatView-allocation-to-a-helper.patch
new file mode 100644
index 0000000..5293194
--- /dev/null
+++ b/SOURCES/kvm-memory-Move-FlatView-allocation-to-a-helper.patch
@@ -0,0 +1,80 @@
+From f99aa9de16a53a783a88cb9049ef42977037c935 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:16 +0100
+Subject: [PATCH 12/30] memory: Move FlatView allocation to a helper
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-7-dgibson@redhat.com>
+Patchwork-id: 77693
+O-Subject: [PATCH 06/22] memory: Move FlatView allocation to a helper
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This moves a FlatView allocation and initialization to a helper.
+While we are nere, replace g_new with g_new0 to not to bother if we add
+new fields in the future.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-4-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit cc94cd6d36602d976a5e7bc29134d1eaefb4102e)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 8bc1f56..f51e499 100644
+--- a/memory.c
++++ b/memory.c
+@@ -258,12 +258,14 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
+         && a->readonly == b->readonly;
+ }
+ 
+-static void flatview_init(FlatView *view)
++static FlatView *flatview_new(void)
+ {
++    FlatView *view;
++
++    view = g_new0(FlatView, 1);
+     view->ref = 1;
+-    view->ranges = NULL;
+-    view->nr = 0;
+-    view->nr_allocated = 0;
++
++    return view;
+ }
+ 
+ /* Insert a range into a given position.  Caller is responsible for maintaining
+@@ -706,8 +708,7 @@ static FlatView *generate_memory_topology(MemoryRegion *mr)
+ {
+     FlatView *view;
+ 
+-    view = g_new(FlatView, 1);
+-    flatview_init(view);
++    view = flatview_new();
+ 
+     if (mr) {
+         render_memory_region(view, mr, int128_zero(),
+@@ -2628,8 +2629,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+     as->ref_count = 1;
+     as->root = root;
+     as->malloced = false;
+-    as->current_map = g_new(FlatView, 1);
+-    flatview_init(as->current_map);
++    as->current_map = flatview_new();
+     as->ioeventfd_nb = 0;
+     as->ioeventfds = NULL;
+     QTAILQ_INIT(&as->listeners);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Move-address_space_update_ioeventfds.patch b/SOURCES/kvm-memory-Move-address_space_update_ioeventfds.patch
new file mode 100644
index 0000000..777e2de
--- /dev/null
+++ b/SOURCES/kvm-memory-Move-address_space_update_ioeventfds.patch
@@ -0,0 +1,55 @@
+From b512b7ed1761bb5a288314e3f1ed674bcc40a22c Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:24 +0100
+Subject: [PATCH 20/30] memory: Move address_space_update_ioeventfds
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-15-dgibson@redhat.com>
+Patchwork-id: 77702
+O-Subject: [PATCH 14/22] memory: Move address_space_update_ioeventfds
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+So it is called (twice) from the same function. This is to make the next
+patches a bit simpler.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-12-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 02218487649558ed66c3689d4cc55250a42601d8)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 8034520..1f58d29 100644
+--- a/memory.c
++++ b/memory.c
+@@ -951,8 +951,6 @@ static void address_space_update_topology(AddressSpace *as)
+      * counting is necessary.
+      */
+     flatview_unref(old_view);
+-
+-    address_space_update_ioeventfds(as);
+ }
+ 
+ void memory_region_transaction_begin(void)
+@@ -975,6 +973,7 @@ void memory_region_transaction_commit(void)
+ 
+             QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+                 address_space_update_topology(as);
++                address_space_update_ioeventfds(as);
+             }
+             memory_region_update_pending = false;
+             MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Open-code-FlatView-rendering.patch b/SOURCES/kvm-memory-Open-code-FlatView-rendering.patch
new file mode 100644
index 0000000..dabf0ab
--- /dev/null
+++ b/SOURCES/kvm-memory-Open-code-FlatView-rendering.patch
@@ -0,0 +1,190 @@
+From 8ce98f8422946cc39437a06fcab4498350d4d482 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:15 +0100
+Subject: [PATCH 11/30] memory: Open code FlatView rendering
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-6-dgibson@redhat.com>
+Patchwork-id: 77695
+O-Subject: [PATCH 05/22] memory: Open code FlatView rendering
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+We are going to share FlatView's between AddressSpace's and per-AS
+memory listeners won't suit the purpose anymore so open code
+the dispatch tree rendering.
+
+Since there is a good chance that dispatch_listener was the only
+listener, this avoids address_space_update_topology_pass() if there is
+no registered listeners; this should improve starting time.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-3-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 9a62e24f45bc97f8eaf198caf58906b47c50a8d5)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ exec.c                         | 27 +++------------------------
+ include/exec/memory-internal.h |  6 ++++--
+ include/exec/memory.h          |  1 -
+ memory.c                       | 19 ++++++++++++++-----
+ 4 files changed, 21 insertions(+), 32 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index f00bd4e..4fed7b7 100644
+--- a/exec.c
++++ b/exec.c
+@@ -1358,9 +1358,8 @@ static void register_multipage(AddressSpaceDispatch *d,
+     phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
+ }
+ 
+-static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
++void mem_add(AddressSpace *as, MemoryRegionSection *section)
+ {
+-    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
+     AddressSpaceDispatch *d = as->next_dispatch;
+     MemoryRegionSection now = *section, remain = *section;
+     Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
+@@ -2684,9 +2683,8 @@ static void io_mem_init(void)
+                           NULL, UINT64_MAX);
+ }
+ 
+-static void mem_begin(MemoryListener *listener)
++void mem_begin(AddressSpace *as)
+ {
+-    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
+     AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
+     uint16_t n;
+ 
+@@ -2710,9 +2708,8 @@ static void address_space_dispatch_free(AddressSpaceDispatch *d)
+     g_free(d);
+ }
+ 
+-static void mem_commit(MemoryListener *listener)
++void mem_commit(AddressSpace *as)
+ {
+-    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
+     AddressSpaceDispatch *cur = as->dispatch;
+     AddressSpaceDispatch *next = as->next_dispatch;
+ 
+@@ -2742,24 +2739,6 @@ static void tcg_commit(MemoryListener *listener)
+     tlb_flush(cpuas->cpu);
+ }
+ 
+-void address_space_init_dispatch(AddressSpace *as)
+-{
+-    as->dispatch = NULL;
+-    as->dispatch_listener = (MemoryListener) {
+-        .begin = mem_begin,
+-        .commit = mem_commit,
+-        .region_add = mem_add,
+-        .region_nop = mem_add,
+-        .priority = 0,
+-    };
+-    memory_listener_register(&as->dispatch_listener, as);
+-}
+-
+-void address_space_unregister(AddressSpace *as)
+-{
+-    memory_listener_unregister(&as->dispatch_listener);
+-}
+-
+ void address_space_destroy_dispatch(AddressSpace *as)
+ {
+     AddressSpaceDispatch *d = as->dispatch;
+diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
+index fb467ac..9abde2f 100644
+--- a/include/exec/memory-internal.h
++++ b/include/exec/memory-internal.h
+@@ -22,8 +22,6 @@
+ #ifndef CONFIG_USER_ONLY
+ typedef struct AddressSpaceDispatch AddressSpaceDispatch;
+ 
+-void address_space_init_dispatch(AddressSpace *as);
+-void address_space_unregister(AddressSpace *as);
+ void address_space_destroy_dispatch(AddressSpace *as);
+ 
+ extern const MemoryRegionOps unassigned_mem_ops;
+@@ -31,5 +29,9 @@ extern const MemoryRegionOps unassigned_mem_ops;
+ bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
+                                 unsigned size, bool is_write);
+ 
++void mem_add(AddressSpace *as, MemoryRegionSection *section);
++void mem_begin(AddressSpace *as);
++void mem_commit(AddressSpace *as);
++
+ #endif
+ #endif
+diff --git a/include/exec/memory.h b/include/exec/memory.h
+index 400dd44..9ee0f2e 100644
+--- a/include/exec/memory.h
++++ b/include/exec/memory.h
+@@ -328,7 +328,6 @@ struct AddressSpace {
+     struct MemoryRegionIoeventfd *ioeventfds;
+     struct AddressSpaceDispatch *dispatch;
+     struct AddressSpaceDispatch *next_dispatch;
+-    MemoryListener dispatch_listener;
+     QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
+     QTAILQ_ENTRY(AddressSpace) address_spaces_link;
+ };
+diff --git a/memory.c b/memory.c
+index ca160de..8bc1f56 100644
+--- a/memory.c
++++ b/memory.c
+@@ -883,14 +883,24 @@ static void address_space_update_topology_pass(AddressSpace *as,
+     }
+ }
+ 
+-
+ static void address_space_update_topology(AddressSpace *as)
+ {
+     FlatView *old_view = address_space_get_flatview(as);
+     FlatView *new_view = generate_memory_topology(as->root);
++    int i;
+ 
+-    address_space_update_topology_pass(as, old_view, new_view, false);
+-    address_space_update_topology_pass(as, old_view, new_view, true);
++    mem_begin(as);
++    for (i = 0; i < new_view->nr; i++) {
++        MemoryRegionSection mrs =
++            section_from_flat_range(&new_view->ranges[i], as);
++        mem_add(as, &mrs);
++    }
++    mem_commit(as);
++
++    if (!QTAILQ_EMPTY(&as->listeners)) {
++        address_space_update_topology_pass(as, old_view, new_view, false);
++        address_space_update_topology_pass(as, old_view, new_view, true);
++    }
+ 
+     /* Writes are protected by the BQL.  */
+     atomic_rcu_set(&as->current_map, new_view);
+@@ -2625,7 +2635,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+     QTAILQ_INIT(&as->listeners);
+     QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
+     as->name = g_strdup(name ? name : "anonymous");
+-    address_space_init_dispatch(as);
++    as->dispatch = NULL;
+     memory_region_update_pending |= root->enabled;
+     memory_region_transaction_commit();
+ }
+@@ -2676,7 +2686,6 @@ void address_space_destroy(AddressSpace *as)
+     as->root = NULL;
+     memory_region_transaction_commit();
+     QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
+-    address_space_unregister(as);
+ 
+     /* At this point, as->dispatch and as->current_map are dummy
+      * entries that the guest should never use.  Wait for the old
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Remove-AddressSpace-pointer-from-AddressSpace.patch b/SOURCES/kvm-memory-Remove-AddressSpace-pointer-from-AddressSpace.patch
new file mode 100644
index 0000000..1b80c0a
--- /dev/null
+++ b/SOURCES/kvm-memory-Remove-AddressSpace-pointer-from-AddressSpace.patch
@@ -0,0 +1,100 @@
+From 4fe0681fd4d203f6db9f6f025c373a5550c428c7 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:18 +0100
+Subject: [PATCH 14/30] memory: Remove AddressSpace pointer from
+ AddressSpaceDispatch
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-9-dgibson@redhat.com>
+Patchwork-id: 77700
+O-Subject: [PATCH 08/22] memory: Remove AddressSpace pointer from AddressSpaceDispatch
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+AS in ASD is only used to pass AS from mem_begin() to register_subpage()
+to store it in MemoryRegionSection, we can do this directly now.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-6-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit c7752523787dc148f5ee976162e80ab594c386a1)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ exec.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 3c0b4f8..6b84771 100644
+--- a/exec.c
++++ b/exec.c
+@@ -194,7 +194,6 @@ struct AddressSpaceDispatch {
+      */
+     PhysPageEntry phys_map;
+     PhysPageMap map;
+-    AddressSpace *as;
+ };
+ 
+ #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
+@@ -1314,7 +1313,8 @@ static void phys_sections_free(PhysPageMap *map)
+     g_free(map->nodes);
+ }
+ 
+-static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
++static void register_subpage(AddressSpace *as, AddressSpaceDispatch *d,
++                             MemoryRegionSection *section)
+ {
+     subpage_t *subpage;
+     hwaddr base = section->offset_within_address_space
+@@ -1329,8 +1329,8 @@ static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *secti
+     assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);
+ 
+     if (!(existing->mr->subpage)) {
+-        subpage = subpage_init(d->as, base);
+-        subsection.address_space = d->as;
++        subpage = subpage_init(as, base);
++        subsection.address_space = as;
+         subsection.mr = &subpage->iomem;
+         phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
+                       phys_section_add(&d->map, &subsection));
+@@ -1367,7 +1367,7 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
+                        - now.offset_within_address_space;
+ 
+         now.size = int128_min(int128_make64(left), now.size);
+-        register_subpage(d, &now);
++        register_subpage(as, d, &now);
+     } else {
+         now.size = int128_zero();
+     }
+@@ -1377,10 +1377,10 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
+         remain.offset_within_region += int128_get64(now.size);
+         now = remain;
+         if (int128_lt(remain.size, page_size)) {
+-            register_subpage(d, &now);
++            register_subpage(as, d, &now);
+         } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
+             now.size = page_size;
+-            register_subpage(d, &now);
++            register_subpage(as, d, &now);
+         } else {
+             now.size = int128_and(now.size, int128_neg(page_size));
+             register_multipage(d, &now);
+@@ -2696,7 +2696,6 @@ AddressSpaceDispatch *mem_begin(AddressSpace *as)
+     assert(n == PHYS_SECTION_WATCH);
+ 
+     d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
+-    d->as = as;
+ 
+     return d;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Rename-mem_begin-mem_commit-mem_add-helpers.patch b/SOURCES/kvm-memory-Rename-mem_begin-mem_commit-mem_add-helpers.patch
new file mode 100644
index 0000000..91da3a3
--- /dev/null
+++ b/SOURCES/kvm-memory-Rename-mem_begin-mem_commit-mem_add-helpers.patch
@@ -0,0 +1,120 @@
+From 1b3b5dcbfa953d50e2b9df7d620bb53234a4f477 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:21 +0100
+Subject: [PATCH 17/30] memory: Rename mem_begin/mem_commit/mem_add helpers
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-12-dgibson@redhat.com>
+Patchwork-id: 77698
+O-Subject: [PATCH 11/22] memory: Rename mem_begin/mem_commit/mem_add helpers
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This renames some helpers to reflect better what they do.
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-9-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 8629d3fcb77e9775e44d9051bad0fb5187925eae)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ exec.c                         | 12 +++---------
+ include/exec/memory-internal.h |  6 +++---
+ memory.c                       |  6 +++---
+ 3 files changed, 9 insertions(+), 15 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index d1d8486..1b30e1e 100644
+--- a/exec.c
++++ b/exec.c
+@@ -359,7 +359,7 @@ static void phys_page_compact(PhysPageEntry *lp, Node *nodes)
+     }
+ }
+ 
+-static void phys_page_compact_all(AddressSpaceDispatch *d, int nodes_nb)
++void address_space_dispatch_compact(AddressSpaceDispatch *d)
+ {
+     if (d->phys_map.skip) {
+         phys_page_compact(&d->phys_map, d->map.nodes);
+@@ -1358,7 +1358,7 @@ static void register_multipage(FlatView *fv,
+     phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
+ }
+ 
+-void mem_add(FlatView *fv, MemoryRegionSection *section)
++void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section)
+ {
+     MemoryRegionSection now = *section, remain = *section;
+     Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
+@@ -2684,9 +2684,8 @@ static void io_mem_init(void)
+                           NULL, UINT64_MAX);
+ }
+ 
+-AddressSpaceDispatch *mem_begin(AddressSpace *as)
++AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv)
+ {
+-    FlatView *fv = address_space_to_flatview(as);
+     AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
+     uint16_t n;
+ 
+@@ -2710,11 +2709,6 @@ void address_space_dispatch_free(AddressSpaceDispatch *d)
+     g_free(d);
+ }
+ 
+-void mem_commit(AddressSpaceDispatch *d)
+-{
+-    phys_page_compact_all(d, d->map.nodes_nb);
+-}
+-
+ static void tcg_commit(MemoryListener *listener)
+ {
+     CPUAddressSpace *cpuas;
+diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
+index 1cf8ad9..d4a35c6 100644
+--- a/include/exec/memory-internal.h
++++ b/include/exec/memory-internal.h
+@@ -27,9 +27,9 @@ extern const MemoryRegionOps unassigned_mem_ops;
+ bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
+                                 unsigned size, bool is_write);
+ 
+-void mem_add(FlatView *fv, MemoryRegionSection *section);
+-AddressSpaceDispatch *mem_begin(AddressSpace *as);
+-void mem_commit(AddressSpaceDispatch *d);
++void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
++AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
++void address_space_dispatch_compact(AddressSpaceDispatch *d);
+ 
+ AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as);
+ AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv);
+diff --git a/memory.c b/memory.c
+index 6678a53..b7d2536 100644
+--- a/memory.c
++++ b/memory.c
+@@ -909,13 +909,13 @@ static void address_space_update_topology(AddressSpace *as)
+     FlatView *new_view = generate_memory_topology(as->root);
+     int i;
+ 
+-    new_view->dispatch = mem_begin(as);
++    new_view->dispatch = address_space_dispatch_new(new_view);
+     for (i = 0; i < new_view->nr; i++) {
+         MemoryRegionSection mrs =
+             section_from_flat_range(&new_view->ranges[i], new_view);
+-        mem_add(new_view, &mrs);
++        flatview_add_to_dispatch(new_view, &mrs);
+     }
+-    mem_commit(new_view->dispatch);
++    address_space_dispatch_compact(new_view->dispatch);
+ 
+     if (!QTAILQ_EMPTY(&as->listeners)) {
+         address_space_update_topology_pass(as, old_view, new_view, false);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Rework-info-mtree-to-print-flat-views-and-dis.patch b/SOURCES/kvm-memory-Rework-info-mtree-to-print-flat-views-and-dis.patch
new file mode 100644
index 0000000..c903921
--- /dev/null
+++ b/SOURCES/kvm-memory-Rework-info-mtree-to-print-flat-views-and-dis.patch
@@ -0,0 +1,321 @@
+From 6a1a074890aa228417dffb2afb49f56234e99c8d Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:27 +0100
+Subject: [PATCH 23/30] memory: Rework "info mtree" to print flat views and
+ dispatch trees
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-18-dgibson@redhat.com>
+Patchwork-id: 77709
+O-Subject: [PATCH 17/22] memory: Rework "info mtree" to print flat views and dispatch trees
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This adds a new "-d" switch to "info mtree" to print dispatch tree
+internals.
+
+This changes the way "-f" is handled - it prints now flat views and
+associated address spaces.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-15-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 5e8fd947e2670c3c18f139de6a83fafcb56abbcc)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ exec.c                         | 84 +++++++++++++++++++++++++++++++++++++++
+ hmp-commands-info.hx           |  7 ++--
+ include/exec/memory-internal.h |  4 ++
+ include/exec/memory.h          |  3 +-
+ memory.c                       | 90 +++++++++++++++++++++++++++++++++++++-----
+ monitor.c                      |  3 +-
+ 6 files changed, 176 insertions(+), 15 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 1b30e1e..5a12e55 100644
+--- a/exec.c
++++ b/exec.c
+@@ -3628,3 +3628,87 @@ void page_size_init(void)
+     }
+     qemu_host_page_mask = -(intptr_t)qemu_host_page_size;
+ }
++
++#if !defined(CONFIG_USER_ONLY)
++
++static void mtree_print_phys_entries(fprintf_function mon, void *f,
++                                     int start, int end, int skip, int ptr)
++{
++    if (start == end - 1) {
++        mon(f, "\t%3d      ", start);
++    } else {
++        mon(f, "\t%3d..%-3d ", start, end - 1);
++    }
++    mon(f, " skip=%d ", skip);
++    if (ptr == PHYS_MAP_NODE_NIL) {
++        mon(f, " ptr=NIL");
++    } else if (!skip) {
++        mon(f, " ptr=#%d", ptr);
++    } else {
++        mon(f, " ptr=[%d]", ptr);
++    }
++    mon(f, "\n");
++}
++
++#define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
++                           int128_sub((size), int128_one())) : 0)
++
++void mtree_print_dispatch(fprintf_function mon, void *f,
++                          AddressSpaceDispatch *d, MemoryRegion *root)
++{
++    int i;
++
++    mon(f, "  Dispatch\n");
++    mon(f, "    Physical sections\n");
++
++    for (i = 0; i < d->map.sections_nb; ++i) {
++        MemoryRegionSection *s = d->map.sections + i;
++        const char *names[] = { " [unassigned]", " [not dirty]",
++                                " [ROM]", " [watch]" };
++
++        mon(f, "      #%d @" TARGET_FMT_plx ".." TARGET_FMT_plx " %s%s%s%s%s",
++            i,
++            s->offset_within_address_space,
++            s->offset_within_address_space + MR_SIZE(s->mr->size),
++            s->mr->name ? s->mr->name : "(noname)",
++            i < ARRAY_SIZE(names) ? names[i] : "",
++            s->mr == root ? " [ROOT]" : "",
++            s == d->mru_section ? " [MRU]" : "",
++            s->mr->is_iommu ? " [iommu]" : "");
++
++        if (s->mr->alias) {
++            mon(f, " alias=%s", s->mr->alias->name ?
++                    s->mr->alias->name : "noname");
++        }
++        mon(f, "\n");
++    }
++
++    mon(f, "    Nodes (%d bits per level, %d levels) ptr=[%d] skip=%d\n",
++               P_L2_BITS, P_L2_LEVELS, d->phys_map.ptr, d->phys_map.skip);
++    for (i = 0; i < d->map.nodes_nb; ++i) {
++        int j, jprev;
++        PhysPageEntry prev;
++        Node *n = d->map.nodes + i;
++
++        mon(f, "      [%d]\n", i);
++
++        for (j = 0, jprev = 0, prev = *n[0]; j < ARRAY_SIZE(*n); ++j) {
++            PhysPageEntry *pe = *n + j;
++
++            if (pe->ptr == prev.ptr && pe->skip == prev.skip) {
++                continue;
++            }
++
++            mtree_print_phys_entries(mon, f, jprev, j, prev.skip, prev.ptr);
++
++            jprev = j;
++            prev = *pe;
++        }
++
++        if (jprev != ARRAY_SIZE(*n)) {
++            mtree_print_phys_entries(mon, f, jprev, j, prev.skip, prev.ptr);
++        }
++    }
++}
++
++#endif
+diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
+index 0967e41..30b335f 100644
+--- a/hmp-commands-info.hx
++++ b/hmp-commands-info.hx
+@@ -253,9 +253,10 @@ ETEXI
+ 
+     {
+         .name       = "mtree",
+-        .args_type  = "flatview:-f",
+-        .params     = "[-f]",
+-        .help       = "show memory tree (-f: dump flat view for address spaces)",
++        .args_type  = "flatview:-f,dispatch_tree:-d",
++        .params     = "[-f][-d]",
++        .help       = "show memory tree (-f: dump flat view for address spaces;"
++                      "-d: dump dispatch tree, valid with -f only)",
+         .cmd        = hmp_info_mtree,
+     },
+ 
+diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
+index d4a35c6..647e9bd 100644
+--- a/include/exec/memory-internal.h
++++ b/include/exec/memory-internal.h
+@@ -35,5 +35,9 @@ AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as);
+ AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv);
+ void address_space_dispatch_free(AddressSpaceDispatch *d);
+ 
++void mtree_print_dispatch(fprintf_function mon, void *f,
++                          struct AddressSpaceDispatch *d,
++                          MemoryRegion *root);
++
+ #endif
+ #endif
+diff --git a/include/exec/memory.h b/include/exec/memory.h
+index 6715551..157eae6 100644
+--- a/include/exec/memory.h
++++ b/include/exec/memory.h
+@@ -1525,7 +1525,8 @@ void memory_global_dirty_log_start(void);
+  */
+ void memory_global_dirty_log_stop(void);
+ 
+-void mtree_info(fprintf_function mon_printf, void *f, bool flatview);
++void mtree_info(fprintf_function mon_printf, void *f, bool flatview,
++                bool dispatch_tree);
+ 
+ /**
+  * memory_region_request_mmio_ptr: request a pointer to an mmio
+diff --git a/memory.c b/memory.c
+index 6914d87..25a8bf2 100644
+--- a/memory.c
++++ b/memory.c
+@@ -2906,18 +2906,44 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
+     }
+ }
+ 
+-static void mtree_print_flatview(fprintf_function p, void *f,
+-                                 AddressSpace *as)
++struct FlatViewInfo {
++    fprintf_function mon_printf;
++    void *f;
++    int counter;
++    bool dispatch_tree;
++};
++
++static void mtree_print_flatview(gpointer key, gpointer value,
++                                 gpointer user_data)
+ {
+-    FlatView *view = address_space_get_flatview(as);
++    FlatView *view = key;
++    GArray *fv_address_spaces = value;
++    struct FlatViewInfo *fvi = user_data;
++    fprintf_function p = fvi->mon_printf;
++    void *f = fvi->f;
+     FlatRange *range = &view->ranges[0];
+     MemoryRegion *mr;
+     int n = view->nr;
++    int i;
++    AddressSpace *as;
++
++    p(f, "FlatView #%d\n", fvi->counter);
++    ++fvi->counter;
++
++    for (i = 0; i < fv_address_spaces->len; ++i) {
++        as = g_array_index(fv_address_spaces, AddressSpace*, i);
++        p(f, " AS \"%s\", root: %s", as->name, memory_region_name(as->root));
++        if (as->root->alias) {
++            p(f, ", alias %s", memory_region_name(as->root->alias));
++        }
++        p(f, "\n");
++    }
++
++    p(f, " Root memory region: %s\n",
++      view->root ? memory_region_name(view->root) : "(none)");
+ 
+     if (n <= 0) {
+-        p(f, MTREE_INDENT "No rendered FlatView for "
+-          "address space '%s'\n", as->name);
+-        flatview_unref(view);
++        p(f, MTREE_INDENT "No rendered FlatView\n\n");
+         return;
+     }
+ 
+@@ -2944,21 +2970,65 @@ static void mtree_print_flatview(fprintf_function p, void *f,
+         range++;
+     }
+ 
++#if !defined(CONFIG_USER_ONLY)
++    if (fvi->dispatch_tree && view->root) {
++        mtree_print_dispatch(p, f, view->dispatch, view->root);
++    }
++#endif
++
++    p(f, "\n");
++}
++
++static gboolean mtree_info_flatview_free(gpointer key, gpointer value,
++                                      gpointer user_data)
++{
++    FlatView *view = key;
++    GArray *fv_address_spaces = value;
++
++    g_array_unref(fv_address_spaces);
+     flatview_unref(view);
++
++    return true;
+ }
+ 
+-void mtree_info(fprintf_function mon_printf, void *f, bool flatview)
++void mtree_info(fprintf_function mon_printf, void *f, bool flatview,
++                bool dispatch_tree)
+ {
+     MemoryRegionListHead ml_head;
+     MemoryRegionList *ml, *ml2;
+     AddressSpace *as;
+ 
+     if (flatview) {
++        FlatView *view;
++        struct FlatViewInfo fvi = {
++            .mon_printf = mon_printf,
++            .f = f,
++            .counter = 0,
++            .dispatch_tree = dispatch_tree
++        };
++        GArray *fv_address_spaces;
++        GHashTable *views = g_hash_table_new(g_direct_hash, g_direct_equal);
++
++        /* Gather all FVs in one table */
+         QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+-            mon_printf(f, "address-space (flat view): %s\n", as->name);
+-            mtree_print_flatview(mon_printf, f, as);
+-            mon_printf(f, "\n");
++            view = address_space_get_flatview(as);
++
++            fv_address_spaces = g_hash_table_lookup(views, view);
++            if (!fv_address_spaces) {
++                fv_address_spaces = g_array_new(false, false, sizeof(as));
++                g_hash_table_insert(views, view, fv_address_spaces);
++            }
++
++            g_array_append_val(fv_address_spaces, as);
+         }
++
++        /* Print */
++        g_hash_table_foreach(views, mtree_print_flatview, &fvi);
++
++        /* Free */
++        g_hash_table_foreach_remove(views, mtree_info_flatview_free, 0);
++        g_hash_table_unref(views);
++
+         return;
+     }
+ 
+diff --git a/monitor.c b/monitor.c
+index c0a8dbc..6380e4a 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -1734,8 +1734,9 @@ static void hmp_boot_set(Monitor *mon, const QDict *qdict)
+ static void hmp_info_mtree(Monitor *mon, const QDict *qdict)
+ {
+     bool flatview = qdict_get_try_bool(qdict, "flatview", false);
++    bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
+ 
+-    mtree_info((fprintf_function)monitor_printf, mon, flatview);
++    mtree_info((fprintf_function)monitor_printf, mon, flatview, dispatch_tree);
+ }
+ 
+ static void hmp_info_numa(Monitor *mon, const QDict *qdict)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Share-FlatView-s-and-dispatch-trees-between-a.patch b/SOURCES/kvm-memory-Share-FlatView-s-and-dispatch-trees-between-a.patch
new file mode 100644
index 0000000..bd8279a
--- /dev/null
+++ b/SOURCES/kvm-memory-Share-FlatView-s-and-dispatch-trees-between-a.patch
@@ -0,0 +1,143 @@
+From f47eec19ea8dd0f693755cf42e4962e3ec43b06b Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:25 +0100
+Subject: [PATCH 21/30] memory: Share FlatView's and dispatch trees between
+ address spaces
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-16-dgibson@redhat.com>
+Patchwork-id: 77707
+O-Subject: [PATCH 15/22] memory: Share FlatView's and dispatch trees between address spaces
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This allows sharing flat views between address spaces (AS) when
+the same root memory region is used when creating a new address space.
+This is done by walking through all ASes and caching one FlatView per
+a physical root MR (i.e. not aliased).
+
+This removes search for duplicates from address_space_init_shareable() as
+FlatViews are shared elsewhere and keeping as::ref_count correct seems
+an unnecessary and useless complication.
+
+This should cause no change and memory use or boot time yet.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-13-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 967dc9b1194a9281124b2e1ce67b6c3359a2138f)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 45 insertions(+), 11 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 1f58d29..f0c8642 100644
+--- a/memory.c
++++ b/memory.c
+@@ -47,6 +47,8 @@ static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
+ static QTAILQ_HEAD(, AddressSpace) address_spaces
+     = QTAILQ_HEAD_INITIALIZER(address_spaces);
+ 
++static GHashTable *flat_views;
++
+ typedef struct AddrRange AddrRange;
+ 
+ /*
+@@ -760,6 +762,7 @@ static FlatView *generate_memory_topology(MemoryRegion *mr)
+         flatview_add_to_dispatch(view, &mrs);
+     }
+     address_space_dispatch_compact(view->dispatch);
++    g_hash_table_replace(flat_views, mr, view);
+ 
+     return view;
+ }
+@@ -929,11 +932,47 @@ static void address_space_update_topology_pass(AddressSpace *as,
+     }
+ }
+ 
+-static void address_space_update_topology(AddressSpace *as)
++static void flatviews_init(void)
++{
++    if (flat_views) {
++        return;
++    }
++
++    flat_views = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
++                                       (GDestroyNotify) flatview_unref);
++}
++
++static void flatviews_reset(void)
++{
++    AddressSpace *as;
++
++    if (flat_views) {
++        g_hash_table_unref(flat_views);
++        flat_views = NULL;
++    }
++    flatviews_init();
++
++    /* Render unique FVs */
++    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
++        MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
++
++        if (g_hash_table_lookup(flat_views, physmr)) {
++            continue;
++        }
++
++        generate_memory_topology(physmr);
++    }
++}
++
++static void address_space_set_flatview(AddressSpace *as)
+ {
+     FlatView *old_view = address_space_get_flatview(as);
+-    MemoryRegion *physmr = memory_region_get_flatview_root(old_view->root);
+-    FlatView *new_view = generate_memory_topology(physmr);
++    MemoryRegion *physmr = memory_region_get_flatview_root(as->root);
++    FlatView *new_view = g_hash_table_lookup(flat_views, physmr);
++
++    assert(new_view);
++
++    flatview_ref(new_view);
+ 
+     if (!QTAILQ_EMPTY(&as->listeners)) {
+         address_space_update_topology_pass(as, old_view, new_view, false);
+@@ -969,10 +1008,12 @@ void memory_region_transaction_commit(void)
+     --memory_region_transaction_depth;
+     if (!memory_region_transaction_depth) {
+         if (memory_region_update_pending) {
++            flatviews_reset();
++
+             MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
+ 
+             QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+-                address_space_update_topology(as);
++                address_space_set_flatview(as);
+                 address_space_update_ioeventfds(as);
+             }
+             memory_region_update_pending = false;
+@@ -2695,13 +2736,6 @@ AddressSpace *address_space_init_shareable(MemoryRegion *root, const char *name)
+ {
+     AddressSpace *as;
+ 
+-    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+-        if (root == as->root && as->malloced) {
+-            as->ref_count++;
+-            return as;
+-        }
+-    }
+-
+     as = g_malloc0(sizeof *as);
+     address_space_init(as, root, name);
+     as->malloced = true;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Share-special-empty-FlatView.patch b/SOURCES/kvm-memory-Share-special-empty-FlatView.patch
new file mode 100644
index 0000000..9ab915b
--- /dev/null
+++ b/SOURCES/kvm-memory-Share-special-empty-FlatView.patch
@@ -0,0 +1,100 @@
+From 5643e64ad775e2a14c76faa867ad698c5e1fe9c7 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:32 +0100
+Subject: [PATCH 28/30] memory: Share special empty FlatView
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-23-dgibson@redhat.com>
+Patchwork-id: 77711
+O-Subject: [PATCH 22/22] memory: Share special empty FlatView
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+This shares an cached empty FlatView among address spaces. The empty
+FV is used every time when a root MR renders into a FV without memory
+sections which happens when MR or its children are not enabled or
+zero-sized. The empty_view is not NULL to keep the rest of memory
+API intact; it also has a dispatch tree for the same reason.
+
+On POWER8 with 255 CPUs, 255 virtio-net, 40 PCI bridges guest this halves
+the amount of FlatView's in use (557 -> 260) and dispatch tables
+(~800000 -> ~370000).  In an unrelated experiment with 112 non-virtio
+devices on x86 ("-M pc"), only 4 FlatViews are alive, and about ~2000
+are created at startup.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-16-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 092aa2fc65b7a35121616aad8f39d47b8f921618)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 38eabe7..a1f1e68 100644
+--- a/memory.c
++++ b/memory.c
+@@ -317,6 +317,7 @@ static void flatview_unref(FlatView *view)
+ {
+     if (atomic_fetch_dec(&view->ref) == 1) {
+         trace_flatview_destroy_rcu(view, view->root);
++        assert(view->root);
+         call_rcu(view, flatview_destroy, rcu);
+     }
+ }
+@@ -760,16 +761,19 @@ static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
+                     }
+                 }
+             }
++            if (found == 0) {
++                return NULL;
++            }
+             if (next) {
+                 mr = next;
+                 continue;
+             }
+         }
+ 
+-        break;
++        return mr;
+     }
+ 
+-    return mr;
++    return NULL;
+ }
+ 
+ /* Render a memory topology into a list of disjoint absolute ranges. */
+@@ -965,12 +969,22 @@ static void address_space_update_topology_pass(AddressSpace *as,
+ 
+ static void flatviews_init(void)
+ {
++    static FlatView *empty_view;
++
+     if (flat_views) {
+         return;
+     }
+ 
+     flat_views = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+                                        (GDestroyNotify) flatview_unref);
++    if (!empty_view) {
++        empty_view = generate_memory_topology(NULL);
++        /* We keep it alive forever in the global variable.  */
++        flatview_ref(empty_view);
++    } else {
++        g_hash_table_replace(flat_views, NULL, empty_view);
++        flatview_ref(empty_view);
++    }
+ }
+ 
+ static void flatviews_reset(void)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Store-physical-root-MR-in-FlatView.patch b/SOURCES/kvm-memory-Store-physical-root-MR-in-FlatView.patch
new file mode 100644
index 0000000..0a56068
--- /dev/null
+++ b/SOURCES/kvm-memory-Store-physical-root-MR-in-FlatView.patch
@@ -0,0 +1,117 @@
+From 44af3e507b25491e8ee996f83076138925a23e16 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:22 +0100
+Subject: [PATCH 18/30] memory: Store physical root MR in FlatView
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-13-dgibson@redhat.com>
+Patchwork-id: 77699
+O-Subject: [PATCH 12/22] memory: Store physical root MR in FlatView
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+Address spaces get to keep a root MR (alias or not) but FlatView stores
+the actual MR as this is going to be used later on to decide whether to
+share a particular FlatView or not.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-10-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 89c177bbdd6cf8e50b3fd4831697d50e195d6432)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 26 ++++++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index b7d2536..7972235 100644
+--- a/memory.c
++++ b/memory.c
+@@ -230,6 +230,7 @@ struct FlatView {
+     unsigned nr;
+     unsigned nr_allocated;
+     struct AddressSpaceDispatch *dispatch;
++    MemoryRegion *root;
+ };
+ 
+ typedef struct AddressSpaceOps AddressSpaceOps;
+@@ -259,12 +260,14 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
+         && a->readonly == b->readonly;
+ }
+ 
+-static FlatView *flatview_new(void)
++static FlatView *flatview_new(MemoryRegion *mr_root)
+ {
+     FlatView *view;
+ 
+     view = g_new0(FlatView, 1);
+     view->ref = 1;
++    view->root = mr_root;
++    memory_region_ref(mr_root);
+ 
+     return view;
+ }
+@@ -297,6 +300,7 @@ static void flatview_destroy(FlatView *view)
+         memory_region_unref(view->ranges[i].mr);
+     }
+     g_free(view->ranges);
++    memory_region_unref(view->root);
+     g_free(view);
+ }
+ 
+@@ -722,12 +726,25 @@ static void render_memory_region(FlatView *view,
+     }
+ }
+ 
++static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
++{
++    while (mr->alias && !mr->alias_offset &&
++           int128_ge(mr->size, mr->alias->size)) {
++        /* The alias is included in its entirety.  Use it as
++         * the "real" root, so that we can share more FlatViews.
++         */
++        mr = mr->alias;
++    }
++
++    return mr;
++}
++
+ /* Render a memory topology into a list of disjoint absolute ranges. */
+ static FlatView *generate_memory_topology(MemoryRegion *mr)
+ {
+     FlatView *view;
+ 
+-    view = flatview_new();
++    view = flatview_new(mr);
+ 
+     if (mr) {
+         render_memory_region(view, mr, int128_zero(),
+@@ -906,7 +923,8 @@ static void address_space_update_topology_pass(AddressSpace *as,
+ static void address_space_update_topology(AddressSpace *as)
+ {
+     FlatView *old_view = address_space_get_flatview(as);
+-    FlatView *new_view = generate_memory_topology(as->root);
++    MemoryRegion *physmr = memory_region_get_flatview_root(old_view->root);
++    FlatView *new_view = generate_memory_topology(physmr);
+     int i;
+ 
+     new_view->dispatch = address_space_dispatch_new(new_view);
+@@ -2649,7 +2667,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
+     as->ref_count = 1;
+     as->root = root;
+     as->malloced = false;
+-    as->current_map = flatview_new();
++    as->current_map = flatview_new(root);
+     as->ioeventfd_nb = 0;
+     as->ioeventfds = NULL;
+     QTAILQ_INIT(&as->listeners);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-Switch-memory-from-using-AddressSpace-to-Flat.patch b/SOURCES/kvm-memory-Switch-memory-from-using-AddressSpace-to-Flat.patch
new file mode 100644
index 0000000..d547631
--- /dev/null
+++ b/SOURCES/kvm-memory-Switch-memory-from-using-AddressSpace-to-Flat.patch
@@ -0,0 +1,814 @@
+From f343747d64a32b4642b7969f97d43d820cc2d8ce Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:19 +0100
+Subject: [PATCH 15/30] memory: Switch memory from using AddressSpace to
+ FlatView
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-10-dgibson@redhat.com>
+Patchwork-id: 77694
+O-Subject: [PATCH 09/22] memory: Switch memory from using AddressSpace to FlatView
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+FlatView's will be shared between AddressSpace's and subpage_t
+and MemoryRegionSection cannot store AS anymore, hence this change.
+
+In particular, for:
+
+ typedef struct subpage_t {
+     MemoryRegion iomem;
+-    AddressSpace *as;
++    FlatView *fv;
+     hwaddr base;
+     uint16_t sub_section[];
+ } subpage_t;
+
+  struct MemoryRegionSection {
+     MemoryRegion *mr;
+-    AddressSpace *address_space;
++    FlatView *fv;
+     hwaddr offset_within_region;
+     Int128 size;
+     hwaddr offset_within_address_space;
+     bool readonly;
+ };
+
+This should cause no behavioural change.
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Message-Id: <20170921085110.25598-7-aik@ozlabs.ru>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 166206845f7fd75e720e6feea0bb01957c8da07f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	exec.c
+
+Conflicts because we applied d5e5fafd "exec: add page_mask for
+flatview_do_translate" out of order downstream.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ exec.c                         | 183 ++++++++++++++++++++++++-----------------
+ hw/intc/openpic_kvm.c          |   2 +-
+ include/exec/memory-internal.h |   2 +-
+ include/exec/memory.h          |  51 ++++++++----
+ memory.c                       |  33 ++++----
+ 5 files changed, 161 insertions(+), 110 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 6b84771..0eedeb2 100644
+--- a/exec.c
++++ b/exec.c
+@@ -199,7 +199,7 @@ struct AddressSpaceDispatch {
+ #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
+ typedef struct subpage_t {
+     MemoryRegion iomem;
+-    AddressSpace *as;
++    FlatView *fv;
+     hwaddr base;
+     uint16_t sub_section[];
+ } subpage_t;
+@@ -469,14 +469,14 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
+ }
+ 
+ /* Called from RCU critical section */
+-static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+-                                                      hwaddr addr,
+-                                                      hwaddr *xlat,
+-                                                      hwaddr *plen_out,
+-                                                      hwaddr *page_mask_out,
+-                                                      bool is_write,
+-                                                      bool is_mmio,
+-                                                      AddressSpace **target_as)
++static MemoryRegionSection flatview_do_translate(FlatView *fv,
++                                                 hwaddr addr,
++                                                 hwaddr *xlat,
++                                                 hwaddr *plen_out,
++                                                 hwaddr *page_mask_out,
++                                                 bool is_write,
++                                                 bool is_mmio,
++                                                 AddressSpace **target_as)
+ {
+     IOMMUTLBEntry iotlb;
+     MemoryRegionSection *section;
+@@ -490,8 +490,9 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+     }
+ 
+     for (;;) {
+-        AddressSpaceDispatch *d = address_space_to_dispatch(as);
+-        section = address_space_translate_internal(d, addr, &addr, &plen, is_mmio);
++        section = address_space_translate_internal(
++            flatview_to_dispatch(fv), addr, &addr,
++            &plen, is_mmio);
+ 
+         iommu_mr = memory_region_get_iommu(section->mr);
+         if (!iommu_mr) {
+@@ -509,7 +510,7 @@ static MemoryRegionSection address_space_do_translate(AddressSpace *as,
+             goto translate_fail;
+         }
+ 
+-        as = iotlb.target_as;
++        fv = address_space_to_flatview(iotlb.target_as);
+         *target_as = iotlb.target_as;
+     }
+ 
+@@ -545,8 +546,8 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+      * This can never be MMIO, and we don't really care about plen,
+      * but page mask.
+      */
+-    section = address_space_do_translate(as, addr, &xlat, NULL,
+-                                         &page_mask, is_write, false, &as);
++    section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat, NULL,
++                                    &page_mask, is_write, false, &as);
+ 
+     /* Illegal translation */
+     if (section.mr == &io_mem_unassigned) {
+@@ -571,16 +572,16 @@ iotlb_fail:
+ }
+ 
+ /* Called from RCU critical section */
+-MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
+-                                      hwaddr *xlat, hwaddr *plen,
+-                                      bool is_write)
++MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
++                                 hwaddr *plen, bool is_write)
+ {
+     MemoryRegion *mr;
+     MemoryRegionSection section;
++    AddressSpace *as = NULL;
+ 
+     /* This can be MMIO, so setup MMIO bit. */
+-    section = address_space_do_translate(as, addr, xlat, plen, NULL,
+-                                         is_write, true, &as);
++    section = flatview_do_translate(fv, addr, xlat, plen, NULL,
++                                    is_write, true, &as);
+     mr = section.mr;
+ 
+     if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
+@@ -1230,7 +1231,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
+     } else {
+         AddressSpaceDispatch *d;
+ 
+-        d = address_space_to_dispatch(section->address_space);
++        d = flatview_to_dispatch(section->fv);
+         iotlb = section - d->map.sections;
+         iotlb += xlat;
+     }
+@@ -1256,7 +1257,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
+ 
+ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+                              uint16_t section);
+-static subpage_t *subpage_init(AddressSpace *as, hwaddr base);
++static subpage_t *subpage_init(FlatView *fv, hwaddr base);
+ 
+ static void *(*phys_mem_alloc)(size_t size, uint64_t *align) =
+                                qemu_anon_ram_alloc;
+@@ -1313,7 +1314,7 @@ static void phys_sections_free(PhysPageMap *map)
+     g_free(map->nodes);
+ }
+ 
+-static void register_subpage(AddressSpace *as, AddressSpaceDispatch *d,
++static void register_subpage(FlatView *fv, AddressSpaceDispatch *d,
+                              MemoryRegionSection *section)
+ {
+     subpage_t *subpage;
+@@ -1329,8 +1330,8 @@ static void register_subpage(AddressSpace *as, AddressSpaceDispatch *d,
+     assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);
+ 
+     if (!(existing->mr->subpage)) {
+-        subpage = subpage_init(as, base);
+-        subsection.address_space = as;
++        subpage = subpage_init(fv, base);
++        subsection.fv = fv;
+         subsection.mr = &subpage->iomem;
+         phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
+                       phys_section_add(&d->map, &subsection));
+@@ -1356,7 +1357,7 @@ static void register_multipage(AddressSpaceDispatch *d,
+     phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
+ }
+ 
+-void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
++void mem_add(FlatView *fv, MemoryRegionSection *section)
+ {
+     AddressSpaceDispatch *d = flatview_to_dispatch(fv);
+     MemoryRegionSection now = *section, remain = *section;
+@@ -1367,7 +1368,7 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
+                        - now.offset_within_address_space;
+ 
+         now.size = int128_min(int128_make64(left), now.size);
+-        register_subpage(as, d, &now);
++        register_subpage(fv, d, &now);
+     } else {
+         now.size = int128_zero();
+     }
+@@ -1377,10 +1378,10 @@ void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section)
+         remain.offset_within_region += int128_get64(now.size);
+         now = remain;
+         if (int128_lt(remain.size, page_size)) {
+-            register_subpage(as, d, &now);
++            register_subpage(fv, d, &now);
+         } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
+             now.size = page_size;
+-            register_subpage(as, d, &now);
++            register_subpage(fv, d, &now);
+         } else {
+             now.size = int128_and(now.size, int128_neg(page_size));
+             register_multipage(d, &now);
+@@ -2511,6 +2512,11 @@ static const MemoryRegionOps watch_mem_ops = {
+     .endianness = DEVICE_NATIVE_ENDIAN,
+ };
+ 
++static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
++                                  const uint8_t *buf, int len);
++static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
++                                  bool is_write);
++
+ static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
+                                 unsigned len, MemTxAttrs attrs)
+ {
+@@ -2522,8 +2528,7 @@ static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
+     printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__,
+            subpage, len, addr);
+ #endif
+-    res = address_space_read(subpage->as, addr + subpage->base,
+-                             attrs, buf, len);
++    res = flatview_read(subpage->fv, addr + subpage->base, attrs, buf, len);
+     if (res) {
+         return res;
+     }
+@@ -2572,8 +2577,7 @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
+     default:
+         abort();
+     }
+-    return address_space_write(subpage->as, addr + subpage->base,
+-                               attrs, buf, len);
++    return flatview_write(subpage->fv, addr + subpage->base, attrs, buf, len);
+ }
+ 
+ static bool subpage_accepts(void *opaque, hwaddr addr,
+@@ -2585,8 +2589,8 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
+            __func__, subpage, is_write ? 'w' : 'r', len, addr);
+ #endif
+ 
+-    return address_space_access_valid(subpage->as, addr + subpage->base,
+-                                      len, is_write);
++    return flatview_access_valid(subpage->fv, addr + subpage->base,
++                                 len, is_write);
+ }
+ 
+ static const MemoryRegionOps subpage_ops = {
+@@ -2620,12 +2624,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+     return 0;
+ }
+ 
+-static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
++static subpage_t *subpage_init(FlatView *fv, hwaddr base)
+ {
+     subpage_t *mmio;
+ 
+     mmio = g_malloc0(sizeof(subpage_t) + TARGET_PAGE_SIZE * sizeof(uint16_t));
+-    mmio->as = as;
++    mmio->fv = fv;
+     mmio->base = base;
+     memory_region_init_io(&mmio->iomem, NULL, &subpage_ops, mmio,
+                           NULL, TARGET_PAGE_SIZE);
+@@ -2639,12 +2643,11 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
+     return mmio;
+ }
+ 
+-static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
+-                              MemoryRegion *mr)
++static uint16_t dummy_section(PhysPageMap *map, FlatView *fv, MemoryRegion *mr)
+ {
+-    assert(as);
++    assert(fv);
+     MemoryRegionSection section = {
+-        .address_space = as,
++        .fv = fv,
+         .mr = mr,
+         .offset_within_address_space = 0,
+         .offset_within_region = 0,
+@@ -2683,16 +2686,17 @@ static void io_mem_init(void)
+ 
+ AddressSpaceDispatch *mem_begin(AddressSpace *as)
+ {
++    FlatView *fv = address_space_to_flatview(as);
+     AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
+     uint16_t n;
+ 
+-    n = dummy_section(&d->map, as, &io_mem_unassigned);
++    n = dummy_section(&d->map, fv, &io_mem_unassigned);
+     assert(n == PHYS_SECTION_UNASSIGNED);
+-    n = dummy_section(&d->map, as, &io_mem_notdirty);
++    n = dummy_section(&d->map, fv, &io_mem_notdirty);
+     assert(n == PHYS_SECTION_NOTDIRTY);
+-    n = dummy_section(&d->map, as, &io_mem_rom);
++    n = dummy_section(&d->map, fv, &io_mem_rom);
+     assert(n == PHYS_SECTION_ROM);
+-    n = dummy_section(&d->map, as, &io_mem_watch);
++    n = dummy_section(&d->map, fv, &io_mem_watch);
+     assert(n == PHYS_SECTION_WATCH);
+ 
+     d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
+@@ -2872,11 +2876,11 @@ static bool prepare_mmio_access(MemoryRegion *mr)
+ }
+ 
+ /* Called within RCU critical section.  */
+-static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
+-                                                MemTxAttrs attrs,
+-                                                const uint8_t *buf,
+-                                                int len, hwaddr addr1,
+-                                                hwaddr l, MemoryRegion *mr)
++static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
++                                           MemTxAttrs attrs,
++                                           const uint8_t *buf,
++                                           int len, hwaddr addr1,
++                                           hwaddr l, MemoryRegion *mr)
+ {
+     uint8_t *ptr;
+     uint64_t val;
+@@ -2938,14 +2942,14 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
+         }
+ 
+         l = len;
+-        mr = address_space_translate(as, addr, &addr1, &l, true);
++        mr = flatview_translate(fv, addr, &addr1, &l, true);
+     }
+ 
+     return result;
+ }
+ 
+-MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+-                                const uint8_t *buf, int len)
++static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
++                                  const uint8_t *buf, int len)
+ {
+     hwaddr l;
+     hwaddr addr1;
+@@ -2955,20 +2959,27 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+     if (len > 0) {
+         rcu_read_lock();
+         l = len;
+-        mr = address_space_translate(as, addr, &addr1, &l, true);
+-        result = address_space_write_continue(as, addr, attrs, buf, len,
+-                                              addr1, l, mr);
++        mr = flatview_translate(fv, addr, &addr1, &l, true);
++        result = flatview_write_continue(fv, addr, attrs, buf, len,
++                                         addr1, l, mr);
+         rcu_read_unlock();
+     }
+ 
+     return result;
+ }
+ 
++MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
++                                              MemTxAttrs attrs,
++                                              const uint8_t *buf, int len)
++{
++    return flatview_write(address_space_to_flatview(as), addr, attrs, buf, len);
++}
++
+ /* Called within RCU critical section.  */
+-MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
+-                                        MemTxAttrs attrs, uint8_t *buf,
+-                                        int len, hwaddr addr1, hwaddr l,
+-                                        MemoryRegion *mr)
++MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
++                                   MemTxAttrs attrs, uint8_t *buf,
++                                   int len, hwaddr addr1, hwaddr l,
++                                   MemoryRegion *mr)
+ {
+     uint8_t *ptr;
+     uint64_t val;
+@@ -3028,14 +3039,14 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
+         }
+ 
+         l = len;
+-        mr = address_space_translate(as, addr, &addr1, &l, false);
++        mr = flatview_translate(fv, addr, &addr1, &l, false);
+     }
+ 
+     return result;
+ }
+ 
+-MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+-                                    MemTxAttrs attrs, uint8_t *buf, int len)
++MemTxResult flatview_read_full(FlatView *fv, hwaddr addr,
++                               MemTxAttrs attrs, uint8_t *buf, int len)
+ {
+     hwaddr l;
+     hwaddr addr1;
+@@ -3045,25 +3056,33 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+     if (len > 0) {
+         rcu_read_lock();
+         l = len;
+-        mr = address_space_translate(as, addr, &addr1, &l, false);
+-        result = address_space_read_continue(as, addr, attrs, buf, len,
+-                                             addr1, l, mr);
++        mr = flatview_translate(fv, addr, &addr1, &l, false);
++        result = flatview_read_continue(fv, addr, attrs, buf, len,
++                                        addr1, l, mr);
+         rcu_read_unlock();
+     }
+ 
+     return result;
+ }
+ 
+-MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+-                             uint8_t *buf, int len, bool is_write)
++static MemTxResult flatview_rw(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
++                               uint8_t *buf, int len, bool is_write)
+ {
+     if (is_write) {
+-        return address_space_write(as, addr, attrs, (uint8_t *)buf, len);
++        return flatview_write(fv, addr, attrs, (uint8_t *)buf, len);
+     } else {
+-        return address_space_read(as, addr, attrs, (uint8_t *)buf, len);
++        return flatview_read(fv, addr, attrs, (uint8_t *)buf, len);
+     }
+ }
+ 
++MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
++                             MemTxAttrs attrs, uint8_t *buf,
++                             int len, bool is_write)
++{
++    return flatview_rw(address_space_to_flatview(as),
++                       addr, attrs, buf, len, is_write);
++}
++
+ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
+                             int len, int is_write)
+ {
+@@ -3221,7 +3240,8 @@ static void cpu_notify_map_clients(void)
+     qemu_mutex_unlock(&map_client_list_lock);
+ }
+ 
+-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
++static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
++                                  bool is_write)
+ {
+     MemoryRegion *mr;
+     hwaddr l, xlat;
+@@ -3229,7 +3249,7 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
+     rcu_read_lock();
+     while (len > 0) {
+         l = len;
+-        mr = address_space_translate(as, addr, &xlat, &l, is_write);
++        mr = flatview_translate(fv, addr, &xlat, &l, is_write);
+         if (!memory_access_is_direct(mr, is_write)) {
+             l = memory_access_size(mr, l, addr);
+             if (!memory_region_access_valid(mr, xlat, l, is_write)) {
+@@ -3245,8 +3265,16 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
+     return true;
+ }
+ 
++bool address_space_access_valid(AddressSpace *as, hwaddr addr,
++                                int len, bool is_write)
++{
++    return flatview_access_valid(address_space_to_flatview(as),
++                                 addr, len, is_write);
++}
++
+ static hwaddr
+-address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_len,
++flatview_extend_translation(FlatView *fv, hwaddr addr,
++                                 hwaddr target_len,
+                                  MemoryRegion *mr, hwaddr base, hwaddr len,
+                                  bool is_write)
+ {
+@@ -3263,7 +3291,8 @@ address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_le
+         }
+ 
+         len = target_len;
+-        this_mr = address_space_translate(as, addr, &xlat, &len, is_write);
++        this_mr = flatview_translate(fv, addr, &xlat,
++                                                   &len, is_write);
+         if (this_mr != mr || xlat != base + done) {
+             return done;
+         }
+@@ -3286,6 +3315,7 @@ void *address_space_map(AddressSpace *as,
+     hwaddr l, xlat;
+     MemoryRegion *mr;
+     void *ptr;
++    FlatView *fv = address_space_to_flatview(as);
+ 
+     if (len == 0) {
+         return NULL;
+@@ -3293,7 +3323,7 @@ void *address_space_map(AddressSpace *as,
+ 
+     l = len;
+     rcu_read_lock();
+-    mr = address_space_translate(as, addr, &xlat, &l, is_write);
++    mr = flatview_translate(fv, addr, &xlat, &l, is_write);
+ 
+     if (!memory_access_is_direct(mr, is_write)) {
+         if (atomic_xchg(&bounce.in_use, true)) {
+@@ -3309,7 +3339,7 @@ void *address_space_map(AddressSpace *as,
+         memory_region_ref(mr);
+         bounce.mr = mr;
+         if (!is_write) {
+-            address_space_read(as, addr, MEMTXATTRS_UNSPECIFIED,
++            flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
+                                bounce.buffer, l);
+         }
+ 
+@@ -3320,7 +3350,8 @@ void *address_space_map(AddressSpace *as,
+ 
+ 
+     memory_region_ref(mr);
+-    *plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write);
++    *plen = flatview_extend_translation(fv, addr, len, mr, xlat,
++                                             l, is_write);
+     ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
+     rcu_read_unlock();
+ 
+diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
+index 0518e01..fa83420 100644
+--- a/hw/intc/openpic_kvm.c
++++ b/hw/intc/openpic_kvm.c
+@@ -124,7 +124,7 @@ static void kvm_openpic_region_add(MemoryListener *listener,
+     uint64_t reg_base;
+     int ret;
+ 
+-    if (section->address_space != &address_space_memory) {
++    if (section->fv != address_space_to_flatview(&address_space_memory)) {
+         abort();
+     }
+ 
+diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
+index 6e08eda..1cf8ad9 100644
+--- a/include/exec/memory-internal.h
++++ b/include/exec/memory-internal.h
+@@ -27,7 +27,7 @@ extern const MemoryRegionOps unassigned_mem_ops;
+ bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
+                                 unsigned size, bool is_write);
+ 
+-void mem_add(AddressSpace *as, FlatView *fv, MemoryRegionSection *section);
++void mem_add(FlatView *fv, MemoryRegionSection *section);
+ AddressSpaceDispatch *mem_begin(AddressSpace *as);
+ void mem_commit(AddressSpaceDispatch *d);
+ 
+diff --git a/include/exec/memory.h b/include/exec/memory.h
+index 8f26d63..6715551 100644
+--- a/include/exec/memory.h
++++ b/include/exec/memory.h
+@@ -48,6 +48,7 @@
+ 
+ typedef struct MemoryRegionOps MemoryRegionOps;
+ typedef struct MemoryRegionMmio MemoryRegionMmio;
++typedef struct FlatView FlatView;
+ 
+ struct MemoryRegionMmio {
+     CPUReadMemoryFunc *read[3];
+@@ -330,6 +331,8 @@ struct AddressSpace {
+     QTAILQ_ENTRY(AddressSpace) address_spaces_link;
+ };
+ 
++FlatView *address_space_to_flatview(AddressSpace *as);
++
+ /**
+  * MemoryRegionSection: describes a fragment of a #MemoryRegion
+  *
+@@ -343,7 +346,7 @@ struct AddressSpace {
+  */
+ struct MemoryRegionSection {
+     MemoryRegion *mr;
+-    AddressSpace *address_space;
++    FlatView *fv;
+     hwaddr offset_within_region;
+     Int128 size;
+     hwaddr offset_within_address_space;
+@@ -1852,9 +1855,17 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+  * @len: pointer to length
+  * @is_write: indicates the transfer direction
+  */
+-MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
+-                                      hwaddr *xlat, hwaddr *len,
+-                                      bool is_write);
++MemoryRegion *flatview_translate(FlatView *fv,
++                                 hwaddr addr, hwaddr *xlat,
++                                 hwaddr *len, bool is_write);
++
++static inline MemoryRegion *address_space_translate(AddressSpace *as,
++                                                    hwaddr addr, hwaddr *xlat,
++                                                    hwaddr *len, bool is_write)
++{
++    return flatview_translate(address_space_to_flatview(as),
++                              addr, xlat, len, is_write);
++}
+ 
+ /* address_space_access_valid: check for validity of accessing an address
+  * space range
+@@ -1905,12 +1916,13 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
+ 
+ 
+ /* Internal functions, part of the implementation of address_space_read.  */
+-MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
+-                                        MemTxAttrs attrs, uint8_t *buf,
+-                                        int len, hwaddr addr1, hwaddr l,
+-					MemoryRegion *mr);
+-MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+-                                    MemTxAttrs attrs, uint8_t *buf, int len);
++MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
++                                   MemTxAttrs attrs, uint8_t *buf,
++                                   int len, hwaddr addr1, hwaddr l,
++                                   MemoryRegion *mr);
++
++MemTxResult flatview_read_full(FlatView *fv, hwaddr addr,
++                               MemTxAttrs attrs, uint8_t *buf, int len);
+ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
+ 
+ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+@@ -1937,8 +1949,8 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+  * @buf: buffer with the data transferred
+  */
+ static inline __attribute__((__always_inline__))
+-MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+-                               uint8_t *buf, int len)
++MemTxResult flatview_read(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
++                          uint8_t *buf, int len)
+ {
+     MemTxResult result = MEMTX_OK;
+     hwaddr l, addr1;
+@@ -1949,22 +1961,29 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+         if (len) {
+             rcu_read_lock();
+             l = len;
+-            mr = address_space_translate(as, addr, &addr1, &l, false);
++            mr = flatview_translate(fv, addr, &addr1, &l, false);
+             if (len == l && memory_access_is_direct(mr, false)) {
+                 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+                 memcpy(buf, ptr, len);
+             } else {
+-                result = address_space_read_continue(as, addr, attrs, buf, len,
+-                                                     addr1, l, mr);
++                result = flatview_read_continue(fv, addr, attrs, buf, len,
++                                                addr1, l, mr);
+             }
+             rcu_read_unlock();
+         }
+     } else {
+-        result = address_space_read_full(as, addr, attrs, buf, len);
++        result = flatview_read_full(fv, addr, attrs, buf, len);
+     }
+     return result;
+ }
+ 
++static inline MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
++                                             MemTxAttrs attrs, uint8_t *buf,
++                                             int len)
++{
++    return flatview_read(address_space_to_flatview(as), addr, attrs, buf, len);
++}
++
+ /**
+  * address_space_read_cached: read from a cached RAM region
+  *
+diff --git a/memory.c b/memory.c
+index 41e2e67..6678a53 100644
+--- a/memory.c
++++ b/memory.c
+@@ -154,7 +154,8 @@ enum ListenerDirection { Forward, Reverse };
+ /* No need to ref/unref .mr, the FlatRange keeps it alive.  */
+ #define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...)  \
+     do {                                                                \
+-        MemoryRegionSection mrs = section_from_flat_range(fr, as);      \
++        MemoryRegionSection mrs = section_from_flat_range(fr,           \
++                address_space_to_flatview(as));                         \
+         MEMORY_LISTENER_CALL(as, callback, dir, &mrs, ##_args);         \
+     } while(0)
+ 
+@@ -208,7 +209,6 @@ static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
+ }
+ 
+ typedef struct FlatRange FlatRange;
+-typedef struct FlatView FlatView;
+ 
+ /* Range of memory in the global map.  Addresses are absolute. */
+ struct FlatRange {
+@@ -238,11 +238,11 @@ typedef struct AddressSpaceOps AddressSpaceOps;
+     for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
+ 
+ static inline MemoryRegionSection
+-section_from_flat_range(FlatRange *fr, AddressSpace *as)
++section_from_flat_range(FlatRange *fr, FlatView *fv)
+ {
+     return (MemoryRegionSection) {
+         .mr = fr->mr,
+-        .address_space = as,
++        .fv = fv,
+         .offset_within_region = fr->offset_in_region,
+         .size = fr->addr.size,
+         .offset_within_address_space = int128_get64(fr->addr.start),
+@@ -312,7 +312,7 @@ static void flatview_unref(FlatView *view)
+     }
+ }
+ 
+-static FlatView *address_space_to_flatview(AddressSpace *as)
++FlatView *address_space_to_flatview(AddressSpace *as)
+ {
+     return atomic_rcu_read(&as->current_map);
+ }
+@@ -760,7 +760,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
+                                                   fds_new[inew]))) {
+             fd = &fds_old[iold];
+             section = (MemoryRegionSection) {
+-                .address_space = as,
++                .fv = address_space_to_flatview(as),
+                 .offset_within_address_space = int128_get64(fd->addr.start),
+                 .size = fd->addr.size,
+             };
+@@ -773,7 +773,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
+                                                          fds_old[iold]))) {
+             fd = &fds_new[inew];
+             section = (MemoryRegionSection) {
+-                .address_space = as,
++                .fv = address_space_to_flatview(as),
+                 .offset_within_address_space = int128_get64(fd->addr.start),
+                 .size = fd->addr.size,
+             };
+@@ -793,7 +793,7 @@ static FlatView *address_space_get_flatview(AddressSpace *as)
+ 
+     rcu_read_lock();
+     do {
+-        view = atomic_rcu_read(&as->current_map);
++        view = address_space_to_flatview(as);
+         /* If somebody has replaced as->current_map concurrently,
+          * flatview_ref returns false.
+          */
+@@ -912,8 +912,8 @@ static void address_space_update_topology(AddressSpace *as)
+     new_view->dispatch = mem_begin(as);
+     for (i = 0; i < new_view->nr; i++) {
+         MemoryRegionSection mrs =
+-            section_from_flat_range(&new_view->ranges[i], as);
+-        mem_add(as, new_view, &mrs);
++            section_from_flat_range(&new_view->ranges[i], new_view);
++        mem_add(new_view, &mrs);
+     }
+     mem_commit(new_view->dispatch);
+ 
+@@ -1869,7 +1869,7 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
+         view = address_space_get_flatview(as);
+         FOR_EACH_FLAT_RANGE(fr, view) {
+             if (fr->mr == mr) {
+-                MemoryRegionSection mrs = section_from_flat_range(fr, as);
++                MemoryRegionSection mrs = section_from_flat_range(fr, view);
+                 listener->log_sync(listener, &mrs);
+             }
+         }
+@@ -1972,7 +1972,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
+     FOR_EACH_FLAT_RANGE(fr, view) {
+         if (fr->mr == mr) {
+             section = (MemoryRegionSection) {
+-                .address_space = as,
++                .fv = view,
+                 .offset_within_address_space = int128_get64(fr->addr.start),
+                 .size = fr->addr.size,
+             };
+@@ -2323,7 +2323,7 @@ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr,
+     }
+     range = addrrange_make(int128_make64(addr), int128_make64(size));
+ 
+-    view = atomic_rcu_read(&as->current_map);
++    view = address_space_to_flatview(as);
+     fr = flatview_lookup(view, range);
+     if (!fr) {
+         return ret;
+@@ -2334,7 +2334,7 @@ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr,
+     }
+ 
+     ret.mr = fr->mr;
+-    ret.address_space = as;
++    ret.fv = view;
+     range = addrrange_intersection(range, fr->addr);
+     ret.offset_within_region = fr->offset_in_region;
+     ret.offset_within_region += int128_get64(int128_sub(range.start,
+@@ -2383,7 +2383,8 @@ void memory_global_dirty_log_sync(void)
+         view = address_space_get_flatview(as);
+         FOR_EACH_FLAT_RANGE(fr, view) {
+             if (fr->dirty_log_mask) {
+-                MemoryRegionSection mrs = section_from_flat_range(fr, as);
++                MemoryRegionSection mrs = section_from_flat_range(fr, view);
++
+                 listener->log_sync(listener, &mrs);
+             }
+         }
+@@ -2468,7 +2469,7 @@ static void listener_add_address_space(MemoryListener *listener,
+     FOR_EACH_FLAT_RANGE(fr, view) {
+         MemoryRegionSection section = {
+             .mr = fr->mr,
+-            .address_space = as,
++            .fv = view,
+             .offset_within_region = fr->offset_in_region,
+             .size = fr->addr.size,
+             .offset_within_address_space = int128_get64(fr->addr.start),
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-avoid-resurrection-of-dead-FlatViews.patch b/SOURCES/kvm-memory-avoid-resurrection-of-dead-FlatViews.patch
new file mode 100644
index 0000000..3cb4595
--- /dev/null
+++ b/SOURCES/kvm-memory-avoid-resurrection-of-dead-FlatViews.patch
@@ -0,0 +1,115 @@
+From 7de5d186bd03511cd5fa4dcd32876efb034f1dd0 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:13 +0100
+Subject: [PATCH 09/30] memory: avoid "resurrection" of dead FlatViews
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-4-dgibson@redhat.com>
+Patchwork-id: 77691
+O-Subject: [PATCH 03/22] memory: avoid "resurrection" of dead FlatViews
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+It's possible for address_space_get_flatview() as it currently stands
+to cause a use-after-free for the returned FlatView, if the reference
+count is incremented after the FlatView has been replaced by a writer:
+
+   thread 1             thread 2             RCU thread
+  -------------------------------------------------------------
+   rcu_read_lock
+   read as->current_map
+                        set as->current_map
+                        flatview_unref
+                           '--> call_rcu
+   flatview_ref
+     [ref=1]
+   rcu_read_unlock
+                                             flatview_destroy
+   <badness>
+
+Since FlatViews are not updated very often, we can just detect the
+situation using a new atomic op atomic_fetch_inc_nonzero, similar to
+Linux's atomic_inc_not_zero, which performs the refcount increment only if
+it hasn't already hit zero.  This is similar to Linux commit de09a9771a53
+("CRED: Fix get_task_cred() and task_state() to not resurrect dead
+credentials", 2010-07-29).
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 447b0d0b9ee8a0ac216c3186e0f3c427a1001f0c)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ docs/devel/atomics.txt |  1 +
+ include/qemu/atomic.h  |  8 ++++++++
+ memory.c               | 12 ++++++++----
+ 3 files changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/docs/devel/atomics.txt b/docs/devel/atomics.txt
+index 048e5f2..10c5fa3 100644
+--- a/docs/devel/atomics.txt
++++ b/docs/devel/atomics.txt
+@@ -64,6 +64,7 @@ operations:
+     typeof(*ptr) atomic_fetch_and(ptr, val)
+     typeof(*ptr) atomic_fetch_or(ptr, val)
+     typeof(*ptr) atomic_fetch_xor(ptr, val)
++    typeof(*ptr) atomic_fetch_inc_nonzero(ptr)
+     typeof(*ptr) atomic_xchg(ptr, val)
+     typeof(*ptr) atomic_cmpxchg(ptr, old, new)
+ 
+diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
+index b6b62fb..d73c9e1 100644
+--- a/include/qemu/atomic.h
++++ b/include/qemu/atomic.h
+@@ -442,4 +442,12 @@
+ } while(0)
+ #endif
+ 
++#define atomic_fetch_inc_nonzero(ptr) ({                                \
++    typeof_strip_qual(*ptr) _oldn = atomic_read(ptr);                   \
++    while (_oldn && atomic_cmpxchg(ptr, _oldn, _oldn + 1) != _oldn) {   \
++        _oldn = atomic_read(ptr);                                       \
++    }                                                                   \
++    _oldn;                                                              \
++})
++
+ #endif /* QEMU_ATOMIC_H */
+diff --git a/memory.c b/memory.c
+index c0adc35..ca160de 100644
+--- a/memory.c
++++ b/memory.c
+@@ -294,9 +294,9 @@ static void flatview_destroy(FlatView *view)
+     g_free(view);
+ }
+ 
+-static void flatview_ref(FlatView *view)
++static bool flatview_ref(FlatView *view)
+ {
+-    atomic_inc(&view->ref);
++    return atomic_fetch_inc_nonzero(&view->ref) > 0;
+ }
+ 
+ static void flatview_unref(FlatView *view)
+@@ -772,8 +772,12 @@ static FlatView *address_space_get_flatview(AddressSpace *as)
+     FlatView *view;
+ 
+     rcu_read_lock();
+-    view = atomic_rcu_read(&as->current_map);
+-    flatview_ref(view);
++    do {
++        view = atomic_rcu_read(&as->current_map);
++        /* If somebody has replaced as->current_map concurrently,
++         * flatview_ref returns false.
++         */
++    } while (!flatview_ref(view));
+     rcu_read_unlock();
+     return view;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-seek-FlatView-sharing-candidates-among-childr.patch b/SOURCES/kvm-memory-seek-FlatView-sharing-candidates-among-childr.patch
new file mode 100644
index 0000000..357bde5
--- /dev/null
+++ b/SOURCES/kvm-memory-seek-FlatView-sharing-candidates-among-childr.patch
@@ -0,0 +1,92 @@
+From 34644299c4e930a16b7e0a7725f69b7b83ca600e Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:31 +0100
+Subject: [PATCH 27/30] memory: seek FlatView sharing candidates among children
+ subregions
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-22-dgibson@redhat.com>
+Patchwork-id: 77708
+O-Subject: [PATCH 21/22] memory: seek FlatView sharing candidates among children subregions
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+A container can be used instead of an alias to allow switching between
+multiple subregions.  In this case we cannot directly share the
+subregions (since they only belong to a single parent), but if the
+subregions are aliases we can in turn walk those.
+
+This is not enough to remove all source of quadratic FlatView creation,
+but it enables sharing of the PCI bus master FlatViews (and their
+AddressSpaceDispatch structures) across all PCI devices.  For 112
+virtio-net-pci devices, boot time is reduced from 25 to 10 seconds and
+memory consumption from 1.4 to 1 G.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit e673ba9af9bf8fd8e0f44025ac738b8285b3ed27)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ memory.c | 40 ++++++++++++++++++++++++++++++++++------
+ 1 file changed, 34 insertions(+), 6 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 8733efc..38eabe7 100644
+--- a/memory.c
++++ b/memory.c
+@@ -733,12 +733,40 @@ static void render_memory_region(FlatView *view,
+ 
+ static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
+ {
+-    while (mr->alias && !mr->alias_offset &&
+-           int128_ge(mr->size, mr->alias->size)) {
+-        /* The alias is included in its entirety.  Use it as
+-         * the "real" root, so that we can share more FlatViews.
+-         */
+-        mr = mr->alias;
++    while (mr->enabled) {
++        if (mr->alias) {
++            if (!mr->alias_offset && int128_ge(mr->size, mr->alias->size)) {
++                /* The alias is included in its entirety.  Use it as
++                 * the "real" root, so that we can share more FlatViews.
++                 */
++                mr = mr->alias;
++                continue;
++            }
++        } else if (!mr->terminates) {
++            unsigned int found = 0;
++            MemoryRegion *child, *next = NULL;
++            QTAILQ_FOREACH(child, &mr->subregions, subregions_link) {
++                if (child->enabled) {
++                    if (++found > 1) {
++                        next = NULL;
++                        break;
++                    }
++                    if (!child->addr && int128_ge(mr->size, child->size)) {
++                        /* A child is included in its entirety.  If it's the only
++                         * enabled one, use it in the hope of finding an alias down the
++                         * way. This will also let us share FlatViews.
++                         */
++                        next = child;
++                    }
++                }
++            }
++            if (next) {
++                mr = next;
++                continue;
++            }
++        }
++
++        break;
+     }
+ 
+     return mr;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-memory-trace-FlatView-creation-and-destruction.patch b/SOURCES/kvm-memory-trace-FlatView-creation-and-destruction.patch
new file mode 100644
index 0000000..38233e4
--- /dev/null
+++ b/SOURCES/kvm-memory-trace-FlatView-creation-and-destruction.patch
@@ -0,0 +1,98 @@
+From b546f002c27078f5aa7c29d85615e8b0b28a26b1 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:30 +0100
+Subject: [PATCH 26/30] memory: trace FlatView creation and destruction
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-21-dgibson@redhat.com>
+Patchwork-id: 77706
+O-Subject: [PATCH 20/22] memory: trace FlatView creation and destruction
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 02d9651d6a46479e9d70b72dca34e43605d06cda)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/exec/memory.h   | 1 -
+ include/qemu/typedefs.h | 1 +
+ memory.c                | 3 +++
+ trace-events            | 3 +++
+ 4 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/include/exec/memory.h b/include/exec/memory.h
+index 8d772b9..b100df6 100644
+--- a/include/exec/memory.h
++++ b/include/exec/memory.h
+@@ -48,7 +48,6 @@
+ 
+ typedef struct MemoryRegionOps MemoryRegionOps;
+ typedef struct MemoryRegionMmio MemoryRegionMmio;
+-typedef struct FlatView FlatView;
+ 
+ struct MemoryRegionMmio {
+     CPUReadMemoryFunc *read[3];
+diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
+index 39bc835..d44dfc7 100644
+--- a/include/qemu/typedefs.h
++++ b/include/qemu/typedefs.h
+@@ -30,6 +30,7 @@ typedef struct DisplaySurface DisplaySurface;
+ typedef struct DriveInfo DriveInfo;
+ typedef struct Error Error;
+ typedef struct EventNotifier EventNotifier;
++typedef struct FlatView FlatView;
+ typedef struct FWCfgEntry FWCfgEntry;
+ typedef struct FWCfgIoState FWCfgIoState;
+ typedef struct FWCfgMemState FWCfgMemState;
+diff --git a/memory.c b/memory.c
+index 93b4221..8733efc 100644
+--- a/memory.c
++++ b/memory.c
+@@ -270,6 +270,7 @@ static FlatView *flatview_new(MemoryRegion *mr_root)
+     view->ref = 1;
+     view->root = mr_root;
+     memory_region_ref(mr_root);
++    trace_flatview_new(view, mr_root);
+ 
+     return view;
+ }
+@@ -295,6 +296,7 @@ static void flatview_destroy(FlatView *view)
+ {
+     int i;
+ 
++    trace_flatview_destroy(view, view->root);
+     if (view->dispatch) {
+         address_space_dispatch_free(view->dispatch);
+     }
+@@ -314,6 +316,7 @@ static bool flatview_ref(FlatView *view)
+ static void flatview_unref(FlatView *view)
+ {
+     if (atomic_fetch_dec(&view->ref) == 1) {
++        trace_flatview_destroy_rcu(view, view->root);
+         call_rcu(view, flatview_destroy, rcu);
+     }
+ }
+diff --git a/trace-events b/trace-events
+index 1f50f56..1d2eb5d 100644
+--- a/trace-events
++++ b/trace-events
+@@ -64,6 +64,9 @@ memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned siz
+ memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
+ memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
+ memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
++flatview_new(FlatView *view, MemoryRegion *root) "%p (root %p)"
++flatview_destroy(FlatView *view, MemoryRegion *root) "%p (root %p)"
++flatview_destroy_rcu(FlatView *view, MemoryRegion *root) "%p (root %p)"
+ 
+ ### Guest events, keep at bottom
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migrate-HMP-migate_continue.patch b/SOURCES/kvm-migrate-HMP-migate_continue.patch
new file mode 100644
index 0000000..9b97780
--- /dev/null
+++ b/SOURCES/kvm-migrate-HMP-migate_continue.patch
@@ -0,0 +1,98 @@
+From ca573248c7d3e8070722316b168f94b79fd75357 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:36 +0200
+Subject: [PATCH 17/19] migrate: HMP migate_continue
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-6-dgilbert@redhat.com>
+Patchwork-id: 77440
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 5/7] migrate: HMP migate_continue
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+HMP equivalent to the just added migrate-continue
+Unpause a migrate paused at a given state.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit 94ae12cba4f18253e3cf5f9a70335e22870053b4)
+  Conflict:
+     Change in qapi_enum_parse parameters
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hmp-commands.hx | 12 ++++++++++++
+ hmp.c           | 14 ++++++++++++++
+ hmp.h           |  1 +
+ 3 files changed, 27 insertions(+)
+
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 5b4cf6b..c16d270 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -979,7 +979,19 @@ STEXI
+ @item migrate_cancel
+ @findex migrate_cancel
+ Cancel the current VM migration.
++ETEXI
+ 
++    {
++        .name       = "migrate_continue",
++        .args_type  = "state:s",
++        .params     = "state",
++        .help       = "Continue migration from the given paused state",
++        .cmd        = hmp_migrate_continue,
++    },
++STEXI
++@item migrate_continue @var{state}
++@findex migrate_continue
++Continue migration from the paused state @var{state}
+ ETEXI
+ 
+     {
+diff --git a/hmp.c b/hmp.c
+index 5b6eeba..261c17b 100644
+--- a/hmp.c
++++ b/hmp.c
+@@ -1493,6 +1493,20 @@ void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
+     qmp_migrate_cancel(NULL);
+ }
+ 
++void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
++{
++    Error *err = NULL;
++    const char *state = qdict_get_str(qdict, "state");
++    int val = qapi_enum_parse(MigrationStatus_lookup, state,
++                              MIGRATION_STATUS__MAX, -1, &err);
++
++    if (val >= 0) {
++        qmp_migrate_continue(val, &err);
++    }
++
++    hmp_handle_error(mon, &err);
++}
++
+ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
+ {
+     Error *err = NULL;
+diff --git a/hmp.h b/hmp.h
+index 8d9cb29..8dc865d 100644
+--- a/hmp.h
++++ b/hmp.h
+@@ -68,6 +68,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict);
+ void hmp_delvm(Monitor *mon, const QDict *qdict);
+ void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
+ void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
++void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
+ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
+ void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
+ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-Add-pause-before-switchover-capability.patch b/SOURCES/kvm-migration-Add-pause-before-switchover-capability.patch
new file mode 100644
index 0000000..b1aa903
--- /dev/null
+++ b/SOURCES/kvm-migration-Add-pause-before-switchover-capability.patch
@@ -0,0 +1,98 @@
+From 13a626395dc1a35e7a7ab0a501a83c5647e3267a Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:32 +0200
+Subject: [PATCH 13/19] migration: Add 'pause-before-switchover' capability
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-2-dgilbert@redhat.com>
+Patchwork-id: 77435
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 1/7] migration: Add 'pause-before-switchover' capability
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+When 'pause-before-switchover' is enabled, the outgoing migration
+will pause before invalidating the block devices and serializing
+the device state.
+At this point the management layer gets the chance to clean up any
+device jobs or other device users before the migration completes.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit 93fbd0314ec060ffaf90169a06d5737fa97ffb25)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+        migration/migration.c
+	migration/migration.h
+           Differences with other flags added
+	qapi/migration.json
+           Still in qapi-schema.json for us
+---
+ migration/migration.c | 10 ++++++++++
+ migration/migration.h |  1 +
+ qapi-schema.json      |  5 ++++-
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index c7b4d3d..d4356a4 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -1426,6 +1426,16 @@ bool migrate_use_events(void)
+     return s->enabled_capabilities[MIGRATION_CAPABILITY_EVENTS];
+ }
+ 
++bool migrate_pause_before_switchover(void)
++{
++    MigrationState *s;
++
++    s = migrate_get_current();
++
++    return s->enabled_capabilities[
++        MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
++}
++
+ int migrate_use_xbzrle(void)
+ {
+     MigrationState *s;
+diff --git a/migration/migration.h b/migration/migration.h
+index 8771ab0..2eebad8 100644
+--- a/migration/migration.h
++++ b/migration/migration.h
+@@ -170,6 +170,7 @@ bool migrate_postcopy_ram(void);
+ bool migrate_zero_blocks(void);
+ 
+ bool migrate_auto_converge(void);
++bool migrate_pause_before_switchover(void);
+ 
+ int migrate_use_xbzrle(void);
+ int64_t migrate_xbzrle_cache_size(void);
+diff --git a/qapi-schema.json b/qapi-schema.json
+index 0591d9d..9b9ec9a 100644
+--- a/qapi-schema.json
++++ b/qapi-schema.json
+@@ -919,12 +919,15 @@
+ # @return-path: If enabled, migration will use the return path even
+ #               for precopy. (since 2.10)
+ #
++# @pause-before-switchover: Pause outgoing migration before serialising device
++#          state and before disabling block IO (since 2.11)
++#
+ # Since: 1.2
+ ##
+ { 'enum': 'MigrationCapability',
+   'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
+            'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
+-           'block', 'return-path' ] }
++           'block', 'return-path', 'pause-before-switchover' ] }
+ 
+ ##
+ # @MigrationCapabilityStatus:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-Add-pre-switchover-and-device-statuses.patch b/SOURCES/kvm-migration-Add-pre-switchover-and-device-statuses.patch
new file mode 100644
index 0000000..20d75a7
--- /dev/null
+++ b/SOURCES/kvm-migration-Add-pre-switchover-and-device-statuses.patch
@@ -0,0 +1,97 @@
+From 7d98216efe37db465e3819912a014086e33c3bdd Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:33 +0200
+Subject: [PATCH 14/19] migration: Add 'pre-switchover' and 'device' statuses
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-3-dgilbert@redhat.com>
+Patchwork-id: 77436
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 2/7] migration: Add 'pre-switchover' and 'device' statuses
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Add two statuses for use when the 'pause-before-switchover'
+capability is enabled.
+
+'pre-switchover' is the state that we wait in for management
+to allow us to continue.
+'device' is the state we enter while serialising the devices
+after management gives us the OK.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit 31e060774cf5c3b9945f6f16d6c18d6eae18e4d9)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	qapi/migration.json
+            still in qapi-schema.json
+---
+ migration/migration.c | 6 ++++++
+ qapi-schema.json      | 8 +++++++-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index d4356a4..54db29f 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -473,6 +473,8 @@ static bool migration_is_setup_or_active(int state)
+     case MIGRATION_STATUS_ACTIVE:
+     case MIGRATION_STATUS_POSTCOPY_ACTIVE:
+     case MIGRATION_STATUS_SETUP:
++    case MIGRATION_STATUS_PRE_SWITCHOVER:
++    case MIGRATION_STATUS_DEVICE:
+         return true;
+ 
+     default:
+@@ -547,6 +549,8 @@ MigrationInfo *qmp_query_migrate(Error **errp)
+     case MIGRATION_STATUS_ACTIVE:
+     case MIGRATION_STATUS_CANCELLING:
+     case MIGRATION_STATUS_POSTCOPY_ACTIVE:
++    case MIGRATION_STATUS_PRE_SWITCHOVER:
++    case MIGRATION_STATUS_DEVICE:
+          /* TODO add some postcopy stats */
+         info->has_status = true;
+         info->has_total_time = true;
+@@ -1102,6 +1106,8 @@ bool migration_is_idle(void)
+     case MIGRATION_STATUS_ACTIVE:
+     case MIGRATION_STATUS_POSTCOPY_ACTIVE:
+     case MIGRATION_STATUS_COLO:
++    case MIGRATION_STATUS_PRE_SWITCHOVER:
++    case MIGRATION_STATUS_DEVICE:
+         return false;
+     case MIGRATION_STATUS__MAX:
+         g_assert_not_reached();
+diff --git a/qapi-schema.json b/qapi-schema.json
+index 9b9ec9a..de8c611 100644
+--- a/qapi-schema.json
++++ b/qapi-schema.json
+@@ -674,12 +674,18 @@
+ # @colo: VM is in the process of fault tolerance, VM can not get into this
+ #        state unless colo capability is enabled for migration. (since 2.8)
+ #
++# @pre-switchover: Paused before device serialisation. (since 2.11)
++#
++# @device: During device serialisation when pause-before-switchover is enabled
++#        (since 2.11)
++#
+ # Since: 2.3
+ #
+ ##
+ { 'enum': 'MigrationStatus',
+   'data': [ 'none', 'setup', 'cancelling', 'cancelled',
+-            'active', 'postcopy-active', 'completed', 'failed', 'colo' ] }
++            'active', 'postcopy-active', 'completed', 'failed', 'colo',
++            'pre-switchover', 'device' ] }
+ 
+ ##
+ # @MigrationInfo:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-Recover-block-devices-if-failure-in-device.patch b/SOURCES/kvm-migration-Recover-block-devices-if-failure-in-device.patch
new file mode 100644
index 0000000..2bfd130
--- /dev/null
+++ b/SOURCES/kvm-migration-Recover-block-devices-if-failure-in-device.patch
@@ -0,0 +1,57 @@
+From 2b263ba2282ac34afa1f9fd1892db868d8b91dba Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 7 Feb 2018 12:24:49 +0100
+Subject: [PATCH 01/15] migration: Recover block devices if failure in device
+ state
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20180207122449.11675-2-dgilbert@redhat.com>
+Patchwork-id: 78915
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] migration: Recover block devices if failure in device state
+Bugzilla: 1538494
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+In e91d895 I added the new pause-before-switchover mechanism
+to allow migration completion to be delayed; this changes the
+last state prior to completion to MIGRATE_STATUS_DEVICE rather
+than MIGRATE_STATUS_ACTIVE.
+
+Fix the failure path in migration_completion to recover the block
+devices if it fails in MIGRATE_STATUS_DEVICE, not just the
+MIGRATE_STATUS_ACTIVE that it previously had.
+
+This corresponds to rh bz:
+  https://bugzilla.redhat.com/show_bug.cgi?id=1538494
+whose symptom is an occasional source crash on a failed migration.
+
+Fixes: e91d8951d59d483f085f
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 6039dd5b1c45d76403b9dcadd2afd7efd8f42330)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/migration.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index cd33718..38d4d9f 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -1990,7 +1990,8 @@ fail_invalidate:
+     /* If not doing postcopy, vm_start() will be called: let's regain
+      * control on images.
+      */
+-    if (s->state == MIGRATION_STATUS_ACTIVE) {
++    if (s->state == MIGRATION_STATUS_ACTIVE ||
++        s->state == MIGRATION_STATUS_DEVICE) {
+         Error *local_err = NULL;
+ 
+         qemu_mutex_lock_iothread();
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-Reenable-incoming-live-block-migration.patch b/SOURCES/kvm-migration-Reenable-incoming-live-block-migration.patch
new file mode 100644
index 0000000..d846bb8
--- /dev/null
+++ b/SOURCES/kvm-migration-Reenable-incoming-live-block-migration.patch
@@ -0,0 +1,87 @@
+From e6f62c7eb81f164ad5aef99a4f7ff48200928938 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 22 Nov 2017 15:41:32 +0100
+Subject: [PATCH 2/7] migration: Reenable incoming live-block-migration
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171122154132.15363-1-dgilbert@redhat.com>
+Patchwork-id: 77779
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] migration: Reenable incoming live-block-migration
+Bugzilla: 1515173
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+rhel7 has always disabled outgoing old-style live block migration
+(but in -rhev enabled nbd block migration); however it allows
+incoming old-style live block migration to allow reception of a stream
+from rhel6.
+
+I added --disable-live-block-migration to upstream in ed1701c6a5a,
+however that really did disable it completely.
+
+In the 7.5 world we've inherited the upstream version and lost the
+incoming support.
+
+Reenable incoming support even when outgoing is disabled.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/migration/misc.h | 7 +++----
+ migration/Makefile.objs  | 2 +-
+ migration/block.h        | 6 +++++-
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/include/migration/misc.h b/include/migration/misc.h
+index c079b77..1d060df 100644
+--- a/include/migration/misc.h
++++ b/include/migration/misc.h
+@@ -22,11 +22,10 @@ void ram_mig_init(void);
+ 
+ /* migration/block.c */
+ 
+-#ifdef CONFIG_LIVE_BLOCK_MIGRATION
++/* RHEL7 allows incoming block migration even with
++ * --disable-live-block-migration to allow RHEL6->7 migration.
++ */
+ void blk_mig_init(void);
+-#else
+-static inline void blk_mig_init(void) {}
+-#endif
+ 
+ #define SELF_ANNOUNCE_ROUNDS 5
+ 
+diff --git a/migration/Makefile.objs b/migration/Makefile.objs
+index 1c7770d..4277c88 100644
+--- a/migration/Makefile.objs
++++ b/migration/Makefile.objs
+@@ -9,5 +9,5 @@ common-obj-y += qjson.o
+ 
+ common-obj-$(CONFIG_RDMA) += rdma.o
+ 
+-common-obj-$(CONFIG_LIVE_BLOCK_MIGRATION) += block.o
++common-obj-y += block.o
+ 
+diff --git a/migration/block.h b/migration/block.h
+index 22ebe94..c4ab848 100644
+--- a/migration/block.h
++++ b/migration/block.h
+@@ -14,7 +14,11 @@
+ #ifndef MIGRATION_BLOCK_H
+ #define MIGRATION_BLOCK_H
+ 
+-#ifdef CONFIG_LIVE_BLOCK_MIGRATION
++/* RHEL7: live block migration is still compiled in even
++ * with --disable-live-block-migration since we must
++ * allow inbound migration from RHEL6.
++ */
++#if 1 /* CONFIG_LIVE_BLOCK_MIGRATION */
+ int blk_mig_active(void);
+ uint64_t blk_mig_bytes_transferred(void);
+ uint64_t blk_mig_bytes_remaining(void);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-Reset-rather-than-destroy-main_thread_load.patch b/SOURCES/kvm-migration-Reset-rather-than-destroy-main_thread_load.patch
new file mode 100644
index 0000000..bba3547
--- /dev/null
+++ b/SOURCES/kvm-migration-Reset-rather-than-destroy-main_thread_load.patch
@@ -0,0 +1,49 @@
+From 21133ce1a56f6490a7ea9dd107013088c1fc05ed Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Thu, 2 Nov 2017 15:36:56 +0100
+Subject: [PATCH 3/9] migration: Reset rather than destroy
+ main_thread_load_event
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171102153657.13452-2-dgilbert@redhat.com>
+Patchwork-id: 77481
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/2] migration: Reset rather than destroy main_thread_load_event
+Bugzilla: 1508799
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+migration_incoming_state_destroy doesn't really destroy, it cleans up.
+After a loadvm it's called, but the loadvm command can be run twice,
+and so destroying an init-once mutex breaks on the second loadvm.
+
+Reported-by: Stafford Horne <shorne@gmail.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-Id: <20170825141940.20740-2-dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Tested-by: Stafford Horne <shorne@gmail.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 5089e1862fe80b6f23ba4c494e2902cbe3d9d48e)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/migration.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index 1288697..cd33718 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -172,7 +172,7 @@ void migration_incoming_state_destroy(void)
+         mis->from_src_file = NULL;
+     }
+ 
+-    qemu_event_destroy(&mis->main_thread_load_event);
++    qemu_event_reset(&mis->main_thread_load_event);
+ }
+ 
+ static void migrate_generate_event(int new_state)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-Wait-for-semaphore-before-completing-migra.patch b/SOURCES/kvm-migration-Wait-for-semaphore-before-completing-migra.patch
new file mode 100644
index 0000000..c53f246
--- /dev/null
+++ b/SOURCES/kvm-migration-Wait-for-semaphore-before-completing-migra.patch
@@ -0,0 +1,118 @@
+From 926144680056dd6773d9ef8ad64c4a593dd597a9 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:34 +0200
+Subject: [PATCH 15/19] migration: Wait for semaphore before completing
+ migration
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-4-dgilbert@redhat.com>
+Patchwork-id: 77439
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 3/7] migration: Wait for semaphore before completing migration
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Wait for a semaphore before completing the migration,
+if the previously added capability was enabled.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit e91d8951d59d483f085f7650381b8e55a1a55e4c)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/migration.c | 38 ++++++++++++++++++++++++++++++++++++++
+ migration/migration.h |  3 +++
+ 2 files changed, 41 insertions(+)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index 54db29f..436e122 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -1847,6 +1847,39 @@ fail:
+ }
+ 
+ /**
++ * migration_maybe_pause: Pause if required to by
++ * migrate_pause_before_switchover called with the iothread locked
++ * Returns: 0 on success
++ */
++static int migration_maybe_pause(MigrationState *s, int *current_active_state)
++{
++    if (!migrate_pause_before_switchover()) {
++        return 0;
++    }
++
++    /* Since leaving this state is not atomic with posting the semaphore
++     * it's possible that someone could have issued multiple migrate_continue
++     * and the semaphore is incorrectly positive at this point;
++     * the docs say it's undefined to reinit a semaphore that's already
++     * init'd, so use timedwait to eat up any existing posts.
++     */
++    while (qemu_sem_timedwait(&s->pause_sem, 1) == 0) {
++        /* This block intentionally left blank */
++    }
++
++    qemu_mutex_unlock_iothread();
++    migrate_set_state(&s->state, *current_active_state,
++                      MIGRATION_STATUS_PRE_SWITCHOVER);
++    qemu_sem_wait(&s->pause_sem);
++    migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
++                      MIGRATION_STATUS_DEVICE);
++    *current_active_state = MIGRATION_STATUS_DEVICE;
++    qemu_mutex_lock_iothread();
++
++    return s->state == MIGRATION_STATUS_DEVICE ? 0 : -EINVAL;
++}
++
++/**
+  * migration_completion: Used by migration_thread when there's not much left.
+  *   The caller 'breaks' the loop when this returns.
+  *
+@@ -1872,6 +1905,9 @@ static void migration_completion(MigrationState *s, int current_active_state,
+             bool inactivate = !migrate_colo_enabled();
+             ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+             if (ret >= 0) {
++                ret = migration_maybe_pause(s, &current_active_state);
++            }
++            if (ret >= 0) {
+                 qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
+                 ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
+                                                          inactivate);
+@@ -2239,6 +2275,7 @@ static void migration_instance_finalize(Object *obj)
+ 
+     g_free(params->tls_hostname);
+     g_free(params->tls_creds);
++    qemu_sem_destroy(&ms->pause_sem);
+ }
+ 
+ static void migration_instance_init(Object *obj)
+@@ -2249,6 +2286,7 @@ static void migration_instance_init(Object *obj)
+     ms->state = MIGRATION_STATUS_NONE;
+     ms->xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE;
+     ms->mbps = -1;
++    qemu_sem_init(&ms->pause_sem, 0);
+ 
+     params->tls_hostname = g_strdup("");
+     params->tls_creds = g_strdup("");
+diff --git a/migration/migration.h b/migration/migration.h
+index 2eebad8..895cc34 100644
+--- a/migration/migration.h
++++ b/migration/migration.h
+@@ -120,6 +120,9 @@ struct MigrationState
+     /* Flag set once the migration thread called bdrv_inactivate_all */
+     bool block_inactive;
+ 
++    /* Migration is paused due to pause-before-switchover */
++    QemuSemaphore pause_sem;
++
+     /* The semaphore is used to notify COLO thread that failover is finished */
+     QemuSemaphore colo_exit_sem;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-allow-cancel-to-unpause.patch b/SOURCES/kvm-migration-allow-cancel-to-unpause.patch
new file mode 100644
index 0000000..562a714
--- /dev/null
+++ b/SOURCES/kvm-migration-allow-cancel-to-unpause.patch
@@ -0,0 +1,47 @@
+From a25e94a891b4633f6039e39f5c63041f4a0b6722 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:37 +0200
+Subject: [PATCH 18/19] migration: allow cancel to unpause
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-7-dgilbert@redhat.com>
+Patchwork-id: 77438
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 6/7] migration: allow cancel to unpause
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+If a migration_cancel is issued during the new paused state,
+kick the pause_sem to get to unpause so it can cancel.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit a7b36b486dd58d8f44f788a2a2efa6a4fa3b1223)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/migration.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index 3a1dabb..3f23ed0 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -1027,6 +1027,10 @@ static void migrate_fd_cancel(MigrationState *s)
+         if (!migration_is_setup_or_active(old_state)) {
+             break;
+         }
++        /* If the migration is paused, kick it out of the pause */
++        if (old_state == MIGRATION_STATUS_PRE_SWITCHOVER) {
++            qemu_sem_post(&s->pause_sem);
++        }
+         migrate_set_state(&s->state, old_state, MIGRATION_STATUS_CANCELLING);
+     } while (s->state != MIGRATION_STATUS_CANCELLING);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-migrate-continue.patch b/SOURCES/kvm-migration-migrate-continue.patch
new file mode 100644
index 0000000..91fe7f8
--- /dev/null
+++ b/SOURCES/kvm-migration-migrate-continue.patch
@@ -0,0 +1,89 @@
+From d6a77c209ff177aef13b9a52277a80c855b72c27 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:35 +0200
+Subject: [PATCH 16/19] migration: migrate-continue
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-5-dgilbert@redhat.com>
+Patchwork-id: 77437
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 4/7] migration: migrate-continue
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+A new qmp command allows the caller to continue from a given
+paused state.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit 89cfc02cb6e3fdaf8ae246493ea51e75be2818c1)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	qapi/migration.json
+          still in qapi-schema.json
+        migration/migration.c
+          use MigrationState_lookup[] rather than new _str() function
+---
+ migration/migration.c | 11 +++++++++++
+ qapi-schema.json      | 17 +++++++++++++++++
+ 2 files changed, 28 insertions(+)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index 436e122..3a1dabb 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -1287,6 +1287,17 @@ void qmp_migrate_cancel(Error **errp)
+     migrate_fd_cancel(migrate_get_current());
+ }
+ 
++void qmp_migrate_continue(MigrationStatus state, Error **errp)
++{
++    MigrationState *s = migrate_get_current();
++    if (s->state != state) {
++        error_setg(errp,  "Migration not in expected state: %s",
++                   MigrationStatus_lookup[s->state]);
++        return;
++    }
++    qemu_sem_post(&s->pause_sem);
++}
++
+ void qmp_migrate_set_cache_size(int64_t value, Error **errp)
+ {
+     MigrationState *s = migrate_get_current();
+diff --git a/qapi-schema.json b/qapi-schema.json
+index de8c611..cd528c8 100644
+--- a/qapi-schema.json
++++ b/qapi-schema.json
+@@ -2837,6 +2837,23 @@
+ { 'command': 'migrate_cancel' }
+ 
+ ##
++# @migrate-continue:
++#
++# Continue migration when it's in a paused state.
++#
++# @state: The state the migration is currently expected to be in
++#
++# Returns: nothing on success
++# Since: 2.11
++# Example:
++#
++# -> { "execute": "migrate-continue" , "arguments":
++#      { "state": "pre-switchover" } }
++# <- { "return": {} }
++##
++{ 'command': 'migrate-continue', 'data': {'state': 'MigrationStatus'} }
++
++##
+ # @migrate_set_downtime:
+ #
+ # Set maximum tolerated downtime for migration.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-pause-before-switchover-for-postcopy.patch b/SOURCES/kvm-migration-pause-before-switchover-for-postcopy.patch
new file mode 100644
index 0000000..8e699af
--- /dev/null
+++ b/SOURCES/kvm-migration-pause-before-switchover-for-postcopy.patch
@@ -0,0 +1,110 @@
+From 2dc02b39b051394ddbd01aec19bf2f0658d9b56c Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 25 Oct 2017 18:28:38 +0200
+Subject: [PATCH 19/19] migration: pause-before-switchover for postcopy
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171025182838.31829-8-dgilbert@redhat.com>
+Patchwork-id: 77441
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 7/7] migration: pause-before-switchover for postcopy
+Bugzilla: 1497120
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Add pause-before-switchover support for postcopy.
+After starting postcopy it will transition
+    active->pre-switchover->postcopy_active
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit 0331c8cabf6168aa263aa0b25f5e135b328606ac)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/migration.c | 29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/migration/migration.c b/migration/migration.c
+index 3f23ed0..1288697 100644
+--- a/migration/migration.c
++++ b/migration/migration.c
+@@ -105,6 +105,9 @@ bool migrate_pre_2_2;
+ static MigrationState *current_migration;
+ 
+ static bool migration_object_check(MigrationState *ms, Error **errp);
++static int migration_maybe_pause(MigrationState *s,
++                                 int *current_active_state,
++                                 int new_state);
+ 
+ void migration_object_init(void)
+ {
+@@ -1717,8 +1720,11 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
+     QEMUFile *fb;
+     int64_t time_at_stop = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+     bool restart_block = false;
+-    migrate_set_state(&ms->state, MIGRATION_STATUS_ACTIVE,
+-                      MIGRATION_STATUS_POSTCOPY_ACTIVE);
++    int cur_state = MIGRATION_STATUS_ACTIVE;
++    if (!migrate_pause_before_switchover()) {
++        migrate_set_state(&ms->state, MIGRATION_STATUS_ACTIVE,
++                          MIGRATION_STATUS_POSTCOPY_ACTIVE);
++    }
+ 
+     trace_postcopy_start();
+     qemu_mutex_lock_iothread();
+@@ -1732,6 +1738,12 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
+         goto fail;
+     }
+ 
++    ret = migration_maybe_pause(ms, &cur_state,
++                                MIGRATION_STATUS_POSTCOPY_ACTIVE);
++    if (ret < 0) {
++        goto fail;
++    }
++
+     ret = bdrv_inactivate_all();
+     if (ret < 0) {
+         goto fail;
+@@ -1866,7 +1878,9 @@ fail:
+  * migrate_pause_before_switchover called with the iothread locked
+  * Returns: 0 on success
+  */
+-static int migration_maybe_pause(MigrationState *s, int *current_active_state)
++static int migration_maybe_pause(MigrationState *s,
++                                 int *current_active_state,
++                                 int new_state)
+ {
+     if (!migrate_pause_before_switchover()) {
+         return 0;
+@@ -1887,11 +1901,11 @@ static int migration_maybe_pause(MigrationState *s, int *current_active_state)
+                       MIGRATION_STATUS_PRE_SWITCHOVER);
+     qemu_sem_wait(&s->pause_sem);
+     migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
+-                      MIGRATION_STATUS_DEVICE);
+-    *current_active_state = MIGRATION_STATUS_DEVICE;
++                      new_state);
++    *current_active_state = new_state;
+     qemu_mutex_lock_iothread();
+ 
+-    return s->state == MIGRATION_STATUS_DEVICE ? 0 : -EINVAL;
++    return s->state == new_state ? 0 : -EINVAL;
+ }
+ 
+ /**
+@@ -1920,7 +1934,8 @@ static void migration_completion(MigrationState *s, int current_active_state,
+             bool inactivate = !migrate_colo_enabled();
+             ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+             if (ret >= 0) {
+-                ret = migration_maybe_pause(s, &current_active_state);
++                ret = migration_maybe_pause(s, &current_active_state,
++                                            MIGRATION_STATUS_DEVICE);
+             }
+             if (ret >= 0) {
+                 qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-ram.c-do-not-set-postcopy_running-in-POSTC.patch b/SOURCES/kvm-migration-ram.c-do-not-set-postcopy_running-in-POSTC.patch
new file mode 100644
index 0000000..69fbee4
--- /dev/null
+++ b/SOURCES/kvm-migration-ram.c-do-not-set-postcopy_running-in-POSTC.patch
@@ -0,0 +1,124 @@
+From 50f063769cf74d2d37adbc5b568b545d2562af65 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Tue, 28 Nov 2017 10:30:08 +0100
+Subject: [PATCH 15/21] migration/ram.c: do not set 'postcopy_running' in
+ POSTCOPY_INCOMING_END
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171128103008.1150-1-lvivier@redhat.com>
+Patchwork-id: 77931
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] migration/ram.c: do not set 'postcopy_running' in POSTCOPY_INCOMING_END
+Bugzilla: 1516956
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Juan Quintela <quintela@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+
+When migrating a VM with 'migrate_set_capability postcopy-ram on'
+a postcopy_state is set during the process, ending up with the
+state POSTCOPY_INCOMING_END when the migration is over. This
+postcopy_state is taken into account inside ram_load to check
+how it will load the memory pages. This same ram_load is called when
+in a loadvm command.
+
+Inside ram_load, the logic to see if we're at postcopy_running state
+is:
+
+postcopy_running = postcopy_state_get() >= POSTCOPY_INCOMING_LISTENING
+
+postcopy_state_get() returns this enum type:
+
+typedef enum {
+    POSTCOPY_INCOMING_NONE = 0,
+    POSTCOPY_INCOMING_ADVISE,
+    POSTCOPY_INCOMING_DISCARD,
+    POSTCOPY_INCOMING_LISTENING,
+    POSTCOPY_INCOMING_RUNNING,
+    POSTCOPY_INCOMING_END
+} PostcopyState;
+
+In the case where ram_load is executed and postcopy_state is
+POSTCOPY_INCOMING_END, postcopy_running will be set to 'true' and
+ram_load will behave like a postcopy is in progress. This scenario isn't
+achievable in a migration but it is reproducible when executing
+savevm/loadvm after migrating with 'postcopy-ram on', causing loadvm
+to fail with Error -22:
+
+Source:
+
+(qemu) migrate_set_capability postcopy-ram on
+(qemu) migrate tcp:127.0.0.1:4444
+
+Dest:
+
+(qemu) migrate_set_capability postcopy-ram on
+(qemu)
+ubuntu1704-intel login:
+Ubuntu 17.04 ubuntu1704-intel ttyS0
+
+ubuntu1704-intel login: (qemu)
+(qemu) savevm test1
+(qemu) loadvm test1
+Unknown combination of migration flags: 0x4 (postcopy mode)
+error while loading state for instance 0x0 of device 'ram'
+Error -22 while loading VM state
+(qemu)
+
+This patch fixes this problem by changing the existing logic for
+postcopy_advised and postcopy_running in ram_load, making them
+'false' if we're at POSTCOPY_INCOMING_END state.
+
+Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+CC: Juan Quintela <quintela@redhat.com>
+CC: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+(cherry picked from commit acab30b85db0885ab161aff4c83c550628f6d8ca)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/ram.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/migration/ram.c b/migration/ram.c
+index e18b3e2..fef80fd 100644
+--- a/migration/ram.c
++++ b/migration/ram.c
+@@ -2484,6 +2484,18 @@ static int ram_load_postcopy(QEMUFile *f)
+     return ret;
+ }
+ 
++static bool postcopy_is_advised(void)
++{
++    PostcopyState ps = postcopy_state_get();
++    return ps >= POSTCOPY_INCOMING_ADVISE && ps < POSTCOPY_INCOMING_END;
++}
++
++static bool postcopy_is_running(void)
++{
++    PostcopyState ps = postcopy_state_get();
++    return ps >= POSTCOPY_INCOMING_LISTENING && ps < POSTCOPY_INCOMING_END;
++}
++
+ static int ram_load(QEMUFile *f, void *opaque, int version_id)
+ {
+     int flags = 0, ret = 0, invalid_flags = 0;
+@@ -2493,9 +2505,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
+      * If system is running in postcopy mode, page inserts to host memory must
+      * be atomic
+      */
+-    bool postcopy_running = postcopy_state_get() >= POSTCOPY_INCOMING_LISTENING;
++    bool postcopy_running = postcopy_is_running();
+     /* ADVISE is earlier, it shows the source has the postcopy capability on */
+-    bool postcopy_advised = postcopy_state_get() >= POSTCOPY_INCOMING_ADVISE;
++    bool postcopy_advised = postcopy_is_advised();
+ 
+     seq_iter++;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-migration-savevm.c-set-MAX_VM_CMD_PACKAGED_SIZE-to-1.patch b/SOURCES/kvm-migration-savevm.c-set-MAX_VM_CMD_PACKAGED_SIZE-to-1.patch
new file mode 100644
index 0000000..76f29f3
--- /dev/null
+++ b/SOURCES/kvm-migration-savevm.c-set-MAX_VM_CMD_PACKAGED_SIZE-to-1.patch
@@ -0,0 +1,79 @@
+From a3df1677bfe1f2ae0a6bcb54f745b08b211369ce Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 7 Feb 2018 15:47:54 +0100
+Subject: [PATCH 02/15] migration/savevm.c: set MAX_VM_CMD_PACKAGED_SIZE to 1ul
+ << 32
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20180207154754.9064-1-lvivier@redhat.com>
+Patchwork-id: 78921
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] migration/savevm.c: set MAX_VM_CMD_PACKAGED_SIZE to 1ul << 32
+Bugzilla: 1540003
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+
+MAX_VM_CMD_PACKAGED_SIZE is a constant used in qemu_savevm_send_packaged
+and loadvm_handle_cmd_packaged to determine whether a package is too
+big to be sent or received. qemu_savevm_send_packaged is called inside
+postcopy_start (migration/migration.c) to send the MigrationState
+in a single blob to the destination, using the MIG_CMD_PACKAGED subcommand,
+which will read it up using loadvm_handle_cmd_packaged. If the blob is
+larger than MAX_VM_CMD_PACKAGED_SIZE, an error is thrown and the postcopy
+migration is aborted. Both MAX_VM_CMD_PACKAGED_SIZE and MIG_CMD_PACKAGED
+were introduced by commit 11cf1d984b ("MIG_CMD_PACKAGED: Send a packaged
+chunk ..."). The constant has its original value of 1ul << 24 (16MB).
+
+The current MAX_VM_CMD_PACKAGED_SIZE value is not enough to support postcopy
+migration of bigger pseries guests. The blob size for a postcopy migration of
+a pseries guest with the following setup:
+
+qemu-system-ppc64 --nographic -vga none -machine pseries,accel=kvm -m 64G \
+-smp 1,maxcpus=32 -device virtio-blk-pci,drive=rootdisk \
+-drive file=f27.qcow2,if=none,cache=none,format=qcow2,id=rootdisk \
+-netdev user,id=u1 -net nic,netdev=u1
+
+Goes around 12MB. Bumping the RAM to 128G makes the blob sizes goes to 20MB.
+With 256G the blob goes to 37MB - more than twice the current maximum size.
+At this moment the pseries machine can handle guests with up to 1TB of RAM,
+making this postcopy blob goes to 128MB of size approximately.
+
+Following the discussions made in [1], there is a need to understand what
+devices are aggressively consuming the blob in that manner and see if that
+can be mitigated. Until then, we can set MAX_VM_CMD_PACKAGED_SIZE to the
+maximum value allowed. Since the size is a 32 bit int variable, we can set
+it as 1ul << 32, giving a maximum blob size of 4G that is enough to support
+postcopy migration of 32TB RAM guests given the above constraints.
+
+[1] https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg06313.html
+
+Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Reported-by: Balamuruhan S <bala24@linux.vnet.ibm.com>
+Reviewed-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Juan Quintela <quintela@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit ee555cdf4d495ddd83633406e3099c5d1ef22e0a)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ migration/savevm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/migration/savevm.c b/migration/savevm.c
+index 5eb3504..c466921 100644
+--- a/migration/savevm.c
++++ b/migration/savevm.c
+@@ -83,7 +83,7 @@ enum qemu_vm_cmd {
+ };
+ bool shadow_bios_after_incoming;
+ 
+-#define MAX_VM_CMD_PACKAGED_SIZE (1ul << 24)
++#define MAX_VM_CMD_PACKAGED_SIZE UINT32_MAX
+ static struct mig_cmd_args {
+     ssize_t     len; /* -1 = variable */
+     const char *name;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-monitor-fix-dangling-CPU-pointer.patch b/SOURCES/kvm-monitor-fix-dangling-CPU-pointer.patch
new file mode 100644
index 0000000..0395a8b
--- /dev/null
+++ b/SOURCES/kvm-monitor-fix-dangling-CPU-pointer.patch
@@ -0,0 +1,115 @@
+From 062ffad79316d7c3a2ace6d96ffc1f90d61469ec Mon Sep 17 00:00:00 2001
+From: Serhii Popovych <spopovyc@redhat.com>
+Date: Wed, 8 Nov 2017 13:35:20 +0100
+Subject: [PATCH 2/7] monitor: fix dangling CPU pointer
+
+RH-Author: Serhii Popovych <spopovyc@redhat.com>
+Message-id: <1510148120-54741-1-git-send-email-spopovyc@redhat.com>
+Patchwork-id: 77520
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2] monitor: fix dangling CPU pointer
+Bugzilla: 1510001
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+Test: replay case as described in comment 4 on bz: qemu does not crash
+
+If a CPU selected with the "cpu" command is hot-unplugged then "info cpus"
+causes QEMU to exit:
+
+(qemu) device_del cpu1
+(qemu) info cpus
+qemu:qemu_cpu_kick_thread: No such process
+
+This happens because "cpu" stores the pointer to the selected CPU into
+the monitor structure. When the CPU is hot-unplugged, we end up with a
+dangling pointer. The "info cpus" command then does:
+
+hmp_info_cpus()
+ monitor_get_cpu_index()
+  mon_get_cpu()
+   cpu_synchronize_state() <--- called with dangling pointer
+
+This could cause a QEMU crash as well.
+
+This patch switches the monitor to store the QOM path instead of a
+pointer to the current CPU. The path is then resolved when needed.
+If the resolution fails, we assume that the CPU was removed and the
+path is resetted to the default (ie, path of first_cpu).
+
+Reported-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
+Suggested-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Message-Id: <150822818243.26242.12993827911736928961.stgit@bahia.lan>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 751f8cfe2a556b3ef49f6af2860e2d1d2a1ec66a)
+Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ monitor.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/monitor.c b/monitor.c
+index bade261..c0a8dbc 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -200,7 +200,7 @@ struct Monitor {
+ 
+     ReadLineState *rs;
+     MonitorQMP qmp;
+-    CPUState *mon_cpu;
++    gchar *mon_cpu_path;
+     BlockCompletionFunc *password_completion_cb;
+     void *password_opaque;
+     mon_cmd_t *cmd_table;
+@@ -579,6 +579,7 @@ static void monitor_data_init(Monitor *mon)
+ 
+ static void monitor_data_destroy(Monitor *mon)
+ {
++    g_free(mon->mon_cpu_path);
+     qemu_chr_fe_deinit(&mon->chr, false);
+     if (monitor_is_qmp(mon)) {
+         json_message_parser_destroy(&mon->qmp.parser);
+@@ -1065,20 +1066,32 @@ int monitor_set_cpu(int cpu_index)
+     if (cpu == NULL) {
+         return -1;
+     }
+-    cur_mon->mon_cpu = cpu;
++    g_free(cur_mon->mon_cpu_path);
++    cur_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
+     return 0;
+ }
+ 
+ CPUState *mon_get_cpu(void)
+ {
+-    if (!cur_mon->mon_cpu) {
++    CPUState *cpu;
++
++    if (cur_mon->mon_cpu_path) {
++        cpu = (CPUState *) object_resolve_path_type(cur_mon->mon_cpu_path,
++                                                    TYPE_CPU, NULL);
++        if (!cpu) {
++            g_free(cur_mon->mon_cpu_path);
++            cur_mon->mon_cpu_path = NULL;
++        }
++    }
++    if (!cur_mon->mon_cpu_path) {
+         if (!first_cpu) {
+             return NULL;
+         }
+         monitor_set_cpu(first_cpu->cpu_index);
++        cpu = first_cpu;
+     }
+-    cpu_synchronize_state(cur_mon->mon_cpu);
+-    return cur_mon->mon_cpu;
++    cpu_synchronize_state(cpu);
++    return cpu;
+ }
+ 
+ CPUArchState *mon_get_cpu_env(void)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch b/SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch
new file mode 100644
index 0000000..6f0227a
--- /dev/null
+++ b/SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch
@@ -0,0 +1,74 @@
+From de21908e4f8daf06b67ba2118c5d2e41da9c51a6 Mon Sep 17 00:00:00 2001
+From: Bandan Das <bsd@redhat.com>
+Date: Thu, 26 Oct 2017 09:55:58 +0200
+Subject: [PATCH 1/7] multiboot: validate multiboot header address values
+
+RH-Author: Bandan Das <bsd@redhat.com>
+Message-id: <jpgh8ump70x.fsf@linux.bootlegged.copy>
+Patchwork-id: 77442
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] multiboot: validate multiboot header address values
+Bugzilla: 1501124
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+While loading kernel via multiboot-v1 image, (flags & 0x00010000)
+indicates that multiboot header contains valid addresses to load
+the kernel image. These addresses are used to compute kernel
+size and kernel text offset in the OS image. Validate these
+address values to avoid an OOB access issue.
+
+This is CVE-2017-14167.
+
+Reported-by: Thomas Garnier <thgarnie@google.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-Id: <20170907063256.7418-1-ppandit@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/i386/multiboot.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
+index f13e231..22688d3 100644
+--- a/hw/i386/multiboot.c
++++ b/hw/i386/multiboot.c
+@@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg,
+         uint32_t mh_header_addr = ldl_p(header+i+12);
+         uint32_t mh_load_end_addr = ldl_p(header+i+20);
+         uint32_t mh_bss_end_addr = ldl_p(header+i+24);
++
+         mh_load_addr = ldl_p(header+i+16);
++        if (mh_header_addr < mh_load_addr) {
++            fprintf(stderr, "invalid mh_load_addr address\n");
++            exit(1);
++        }
++
+         uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
+         uint32_t mb_load_size = 0;
+         mh_entry_addr = ldl_p(header+i+28);
+ 
+         if (mh_load_end_addr) {
++            if (mh_bss_end_addr < mh_load_addr) {
++                fprintf(stderr, "invalid mh_bss_end_addr address\n");
++                exit(1);
++            }
+             mb_kernel_size = mh_bss_end_addr - mh_load_addr;
++
++            if (mh_load_end_addr < mh_load_addr) {
++                fprintf(stderr, "invalid mh_load_end_addr address\n");
++                exit(1);
++            }
+             mb_load_size = mh_load_end_addr - mh_load_addr;
+         } else {
++            if (kernel_file_size < mb_kernel_text_offset) {
++                fprintf(stderr, "invalid kernel_file_size\n");
++                exit(1);
++            }
+             mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
+             mb_load_size = mb_kernel_size;
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-nbd-client-avoid-read_reply_co-entry-if-send-failed.patch b/SOURCES/kvm-nbd-client-avoid-read_reply_co-entry-if-send-failed.patch
new file mode 100644
index 0000000..071816d
--- /dev/null
+++ b/SOURCES/kvm-nbd-client-avoid-read_reply_co-entry-if-send-failed.patch
@@ -0,0 +1,160 @@
+From d532d1959bdce14c56e2dd37a5dd013dd7c5ed39 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Fri, 6 Oct 2017 19:24:06 +0200
+Subject: [PATCH 14/34] nbd-client: avoid read_reply_co entry if send failed
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171006192409.29915-2-eblake@redhat.com>
+Patchwork-id: 76913
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 1/4] nbd-client: avoid read_reply_co entry if send failed
+Bugzilla: 1482478
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+The following segfault is encountered if the NBD server closes the UNIX
+domain socket immediately after negotiation:
+
+  Program terminated with signal SIGSEGV, Segmentation fault.
+  #0  aio_co_schedule (ctx=0x0, co=0xd3c0ff2ef0) at util/async.c:441
+  441       QSLIST_INSERT_HEAD_ATOMIC(&ctx->scheduled_coroutines,
+  (gdb) bt
+  #0  0x000000d3c01a50f8 in aio_co_schedule (ctx=0x0, co=0xd3c0ff2ef0) at util/async.c:441
+  #1  0x000000d3c012fa90 in nbd_coroutine_end (bs=bs@entry=0xd3c0fec650, request=<optimized out>) at block/nbd-client.c:207
+  #2  0x000000d3c012fb58 in nbd_client_co_preadv (bs=0xd3c0fec650, offset=0, bytes=<optimized out>, qiov=0x7ffc10a91b20, flags=0) at block/nbd-client.c:237
+  #3  0x000000d3c0128e63 in bdrv_driver_preadv (bs=bs@entry=0xd3c0fec650, offset=offset@entry=0, bytes=bytes@entry=512, qiov=qiov@entry=0x7ffc10a91b20, flags=0) at block/io.c:836
+  #4  0x000000d3c012c3e0 in bdrv_aligned_preadv (child=child@entry=0xd3c0ff51d0, req=req@entry=0x7f31885d6e90, offset=offset@entry=0, bytes=bytes@entry=512, align=align@entry=1, qiov=qiov@entry=0x7ffc10a91b20, f
++lags=0) at block/io.c:1086
+  #5  0x000000d3c012c6b8 in bdrv_co_preadv (child=0xd3c0ff51d0, offset=offset@entry=0, bytes=bytes@entry=512, qiov=qiov@entry=0x7ffc10a91b20, flags=flags@entry=0) at block/io.c:1182
+  #6  0x000000d3c011cc17 in blk_co_preadv (blk=0xd3c0ff4f80, offset=0, bytes=512, qiov=0x7ffc10a91b20, flags=0) at block/block-backend.c:1032
+  #7  0x000000d3c011ccec in blk_read_entry (opaque=0x7ffc10a91b40) at block/block-backend.c:1079
+  #8  0x000000d3c01bbb96 in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at util/coroutine-ucontext.c:79
+  #9  0x00007f3196cb8600 in __start_context () at /lib64/libc.so.6
+
+The problem is that nbd_client_init() uses
+nbd_client_attach_aio_context() -> aio_co_schedule(new_context,
+client->read_reply_co).  Execution of read_reply_co is deferred to a BH
+which doesn't run until later.
+
+In the mean time blk_co_preadv() can be called and nbd_coroutine_end()
+calls aio_wake() on read_reply_co.  At this point in time
+read_reply_co's ctx isn't set because it has never been entered yet.
+
+This patch simplifies the nbd_co_send_request() ->
+nbd_co_receive_reply() -> nbd_coroutine_end() lifecycle to just
+nbd_co_send_request() -> nbd_co_receive_reply().  The request is "ended"
+if an error occurs at any point.  Callers no longer have to invoke
+nbd_coroutine_end().
+
+This cleanup also eliminates the segfault because we don't call
+aio_co_schedule() to wake up s->read_reply_co if sending the request
+failed.  It is only necessary to wake up s->read_reply_co if a reply was
+received.
+
+Note this only happens with UNIX domain sockets on Linux.  It doesn't
+seem possible to reproduce this with TCP sockets.
+
+Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20170829122745.14309-2-stefanha@redhat.com>
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 3c2d5183f9fa4eac3d17d841e26da65a0181ae7b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/nbd-client.c | 25 +++++++++----------------
+ 1 file changed, 9 insertions(+), 16 deletions(-)
+
+diff --git a/block/nbd-client.c b/block/nbd-client.c
+index 25bcaa2..ea728ff 100644
+--- a/block/nbd-client.c
++++ b/block/nbd-client.c
+@@ -144,12 +144,12 @@ static int nbd_co_send_request(BlockDriverState *bs,
+     request->handle = INDEX_TO_HANDLE(s, i);
+ 
+     if (s->quit) {
+-        qemu_co_mutex_unlock(&s->send_mutex);
+-        return -EIO;
++        rc = -EIO;
++        goto err;
+     }
+     if (!s->ioc) {
+-        qemu_co_mutex_unlock(&s->send_mutex);
+-        return -EPIPE;
++        rc = -EPIPE;
++        goto err;
+     }
+ 
+     if (qiov) {
+@@ -166,8 +166,13 @@ static int nbd_co_send_request(BlockDriverState *bs,
+     } else {
+         rc = nbd_send_request(s->ioc, request);
+     }
++
++err:
+     if (rc < 0) {
+         s->quit = true;
++        s->requests[i].coroutine = NULL;
++        s->in_flight--;
++        qemu_co_queue_next(&s->free_sema);
+     }
+     qemu_co_mutex_unlock(&s->send_mutex);
+     return rc;
+@@ -201,13 +206,6 @@ static void nbd_co_receive_reply(NBDClientSession *s,
+         /* Tell the read handler to read another header.  */
+         s->reply.handle = 0;
+     }
+-}
+-
+-static void nbd_coroutine_end(BlockDriverState *bs,
+-                              NBDRequest *request)
+-{
+-    NBDClientSession *s = nbd_get_client_session(bs);
+-    int i = HANDLE_TO_INDEX(s, request->handle);
+ 
+     s->requests[i].coroutine = NULL;
+ 
+@@ -243,7 +241,6 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
+     } else {
+         nbd_co_receive_reply(client, &request, &reply, qiov);
+     }
+-    nbd_coroutine_end(bs, &request);
+     return -reply.error;
+ }
+ 
+@@ -272,7 +269,6 @@ int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
+     } else {
+         nbd_co_receive_reply(client, &request, &reply, NULL);
+     }
+-    nbd_coroutine_end(bs, &request);
+     return -reply.error;
+ }
+ 
+@@ -306,7 +302,6 @@ int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
+     } else {
+         nbd_co_receive_reply(client, &request, &reply, NULL);
+     }
+-    nbd_coroutine_end(bs, &request);
+     return -reply.error;
+ }
+ 
+@@ -330,7 +325,6 @@ int nbd_client_co_flush(BlockDriverState *bs)
+     } else {
+         nbd_co_receive_reply(client, &request, &reply, NULL);
+     }
+-    nbd_coroutine_end(bs, &request);
+     return -reply.error;
+ }
+ 
+@@ -355,7 +349,6 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
+     } else {
+         nbd_co_receive_reply(client, &request, &reply, NULL);
+     }
+-    nbd_coroutine_end(bs, &request);
+     return -reply.error;
+ 
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-nbd-server-CVE-2017-15118-Stack-smash-on-large-expor.patch b/SOURCES/kvm-nbd-server-CVE-2017-15118-Stack-smash-on-large-expor.patch
new file mode 100644
index 0000000..4ac95bb
--- /dev/null
+++ b/SOURCES/kvm-nbd-server-CVE-2017-15118-Stack-smash-on-large-expor.patch
@@ -0,0 +1,62 @@
+From dd7511a6effe839c73ed8f71ceaa3c53f16ebdbd Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Wed, 13 Dec 2017 18:17:30 +0100
+Subject: [PATCH 5/6] nbd/server: CVE-2017-15118 Stack smash on large export
+ name
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171213181730.1278-3-eblake@redhat.com>
+Patchwork-id: 78393
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 2/2] nbd/server: CVE-2017-15118 Stack smash on large export name
+Bugzilla: 1516545 1518548
+CVE: CVE-2017-15118/20171128
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+Introduced in commit f37708f6b8 (2.10).  The NBD spec says a client
+can request export names up to 4096 bytes in length, even though
+they should not expect success on names longer than 256.  However,
+qemu hard-codes the limit of 256, and fails to filter out a client
+that probes for a longer name; the result is a stack smash that can
+potentially give an attacker arbitrary control over the qemu
+process.
+
+The smash can be easily demonstrated with this client:
+$ qemu-io f raw nbd://localhost:10809/$(printf %3000d 1 | tr ' ' a)
+
+If the qemu NBD server binary (whether the standalone qemu-nbd, or
+the builtin server of QMP nbd-server-start) was compiled with
+-fstack-protector-strong, the ability to exploit the stack smash
+into arbitrary execution is a lot more difficult (but still
+theoretically possible to a determined attacker, perhaps in
+combination with other CVEs).  Still, crashing a running qemu (and
+losing the VM) is bad enough, even if the attacker did not obtain
+full execution control.
+
+CC: qemu-stable@nongnu.org
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 51ae4f8455c9e32c54770c4ebc25bf86a8128183)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ nbd/server.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/nbd/server.c b/nbd/server.c
+index b93cb88..56aed3a 100644
+--- a/nbd/server.c
++++ b/nbd/server.c
+@@ -393,6 +393,10 @@ static int nbd_negotiate_handle_info(NBDClient *client, uint32_t length,
+         msg = "name length is incorrect";
+         goto invalid;
+     }
++    if (namelen >= sizeof(name)) {
++        msg = "name too long for qemu";
++        goto invalid;
++    }
+     if (nbd_read(client->ioc, name, namelen, errp) < 0) {
+         return -EIO;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-nbd-server-CVE-2017-15119-Reject-options-larger-than.patch b/SOURCES/kvm-nbd-server-CVE-2017-15119-Reject-options-larger-than.patch
new file mode 100644
index 0000000..50a893b
--- /dev/null
+++ b/SOURCES/kvm-nbd-server-CVE-2017-15119-Reject-options-larger-than.patch
@@ -0,0 +1,71 @@
+From 0ce164b7410c1c4a75eefaef48896ee245eeba5c Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Wed, 13 Dec 2017 18:17:29 +0100
+Subject: [PATCH 4/6] nbd/server: CVE-2017-15119 Reject options larger than 32M
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171213181730.1278-2-eblake@redhat.com>
+Patchwork-id: 78394
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 1/2] nbd/server: CVE-2017-15119 Reject options larger than 32M
+Bugzilla: 1518529 1518551
+CVE: CVE-2017-15119/20171128
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+The NBD spec gives us permission to abruptly disconnect on clients
+that send outrageously large option requests, rather than having
+to spend the time reading to the end of the option.  No real
+option request requires that much data anyways; and meanwhile, we
+already have the practice of abruptly dropping the connection on
+any client that sends NBD_CMD_WRITE with a payload larger than 32M.
+
+For comparison, nbdkit drops the connection on any request with
+more than 4096 bytes; however, that limit is probably too low
+(as the NBD spec states an export name can theoretically be up
+to 4096 bytes, which means a valid NBD_OPT_INFO could be even
+longer) - even if qemu doesn't permit exports longer than 256
+bytes.
+
+It could be argued that a malicious client trying to get us to
+read nearly 4G of data on a bad request is a form of denial of
+service.  In particular, if the server requires TLS, but a client
+that does not know the TLS credentials sends any option (other
+than NBD_OPT_STARTTLS or NBD_OPT_EXPORT_NAME) with a stated
+payload of nearly 4G, then the server was keeping the connection
+alive trying to read all the payload, tying up resources that it
+would rather be spending on a client that can get past the TLS
+handshake.  Hence, this warranted a CVE.
+
+Present since at least 2.5 when handling known options, and made
+worse in 2.6 when fixing support for NBD_FLAG_C_FIXED_NEWSTYLE
+to handle unknown options.
+
+CC: qemu-stable@nongnu.org
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit fdad35ef6c5839d50dfc14073364ac893afebc30)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ nbd/server.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/nbd/server.c b/nbd/server.c
+index 993ade3..b93cb88 100644
+--- a/nbd/server.c
++++ b/nbd/server.c
+@@ -661,6 +661,12 @@ static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
+         }
+         length = be32_to_cpu(length);
+ 
++        if (length > NBD_MAX_BUFFER_SIZE) {
++            error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
++                       length, NBD_MAX_BUFFER_SIZE);
++            return -EINVAL;
++        }
++
+         trace_nbd_negotiate_options_check_option(option,
+                                                  nbd_opt_lookup(option));
+         if (client->tlscreds &&
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-osdep-Define-QEMU_MADV_REMOVE.patch b/SOURCES/kvm-osdep-Define-QEMU_MADV_REMOVE.patch
new file mode 100644
index 0000000..be9a40e
--- /dev/null
+++ b/SOURCES/kvm-osdep-Define-QEMU_MADV_REMOVE.patch
@@ -0,0 +1,63 @@
+From 50789e32c0d8f91b69c918f43ee9415b2fbd86e0 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Thu, 19 Oct 2017 01:34:52 +0200
+Subject: [PATCH 63/69] osdep: Define QEMU_MADV_REMOVE
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171019013453.21449-4-ehabkost@redhat.com>
+Patchwork-id: 77369
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/4] osdep: Define QEMU_MADV_REMOVE
+Bugzilla: 1460848
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Define QEMU_MADV_REMOVE, so we can use it with qemu_madvise().
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20170824192315.5897-3-ehabkost@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Tested-by: Zack Cornelius <zack.cornelius@kove.net>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 0f81d3353029d26c6f8731a65d8052c532b1ced6)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/qemu/osdep.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
+index 6855b94..e9fa217 100644
+--- a/include/qemu/osdep.h
++++ b/include/qemu/osdep.h
+@@ -257,6 +257,11 @@ void qemu_anon_ram_free(void *ptr, size_t size);
+ #else
+ #define QEMU_MADV_NOHUGEPAGE QEMU_MADV_INVALID
+ #endif
++#ifdef MADV_REMOVE
++#define QEMU_MADV_REMOVE MADV_REMOVE
++#else
++#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
++#endif
+ 
+ #elif defined(CONFIG_POSIX_MADVISE)
+ 
+@@ -269,6 +274,7 @@ void qemu_anon_ram_free(void *ptr, size_t size);
+ #define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
+ #define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
+ #define QEMU_MADV_NOHUGEPAGE  QEMU_MADV_INVALID
++#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
+ 
+ #else /* no-op */
+ 
+@@ -281,6 +287,7 @@ void qemu_anon_ram_free(void *ptr, size_t size);
+ #define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
+ #define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
+ #define QEMU_MADV_NOHUGEPAGE  QEMU_MADV_INVALID
++#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
+ 
+ #endif
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-osdep-Force-define-F_OFD_GETLK-RHEL-only.patch b/SOURCES/kvm-osdep-Force-define-F_OFD_GETLK-RHEL-only.patch
new file mode 100644
index 0000000..cc443da
--- /dev/null
+++ b/SOURCES/kvm-osdep-Force-define-F_OFD_GETLK-RHEL-only.patch
@@ -0,0 +1,52 @@
+From ac74b9067d079b03f3fe4236270f9eb34121009b Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Thu, 12 Oct 2017 13:54:45 +0200
+Subject: [PATCH 16/69] osdep: Force define F_OFD_GETLK (RHEL only)
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20171012135445.4214-1-famz@redhat.com>
+Patchwork-id: 77220
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH] osdep: Force define F_OFD_GETLK (RHEL only)
+Bugzilla: 1378241
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+BZ: 1378241
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14254218
+
+glibc is not ready yet (BZ 1461231, which is deferred to 7.6 due to
+capacity), so the OFD constants are not defined in the system headers we
+pull in. (They do exist in the headers of latest kernel-headers package,
+but we don't want to include that anyway.)
+
+Actually the constants are all that are missing before we can call image
+locking done in 7.5, so there is no reason to wait for glibc.
+
+This patch can be reverted once the new glibc headers are in place.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/osdep.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/util/osdep.c b/util/osdep.c
+index a479fed..8358a44 100644
+--- a/util/osdep.c
++++ b/util/osdep.c
+@@ -23,6 +23,11 @@
+  */
+ #include "qemu/osdep.h"
+ 
++#ifndef F_OFD_SETLK
++#define F_OFD_GETLK    36
++#define F_OFD_SETLK    37
++#endif
++
+ /* Needed early for CONFIG_BSD etc. */
+ 
+ #ifdef CONFIG_SOLARIS
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-osdep-Retry-SETLK-upon-EINTR.patch b/SOURCES/kvm-osdep-Retry-SETLK-upon-EINTR.patch
new file mode 100644
index 0000000..24c241f
--- /dev/null
+++ b/SOURCES/kvm-osdep-Retry-SETLK-upon-EINTR.patch
@@ -0,0 +1,46 @@
+From 3227ce9e3ea004e742f2a3390c426c9699e26a16 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Fri, 26 Jan 2018 02:07:36 +0100
+Subject: [PATCH 5/8] osdep: Retry SETLK upon EINTR
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20180126020736.24596-1-famz@redhat.com>
+Patchwork-id: 78706
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] osdep: Retry SETLK upon EINTR
+Bugzilla: 1529053
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+We could hit lock failure if there is a signal that makes fcntl return
+-1 and errno set to EINTR. In this case we should retry.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit f86428a1f4f91a460ed585682af70d3e8c31dc06)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/osdep.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/util/osdep.c b/util/osdep.c
+index 8358a44..ac7d1b2 100644
+--- a/util/osdep.c
++++ b/util/osdep.c
+@@ -208,7 +208,9 @@ static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
+         .l_type   = fl_type,
+     };
+     qemu_probe_lock_ops();
+-    ret = fcntl(fd, fcntl_op_setlk, &fl);
++    do {
++        ret = fcntl(fd, fcntl_op_setlk, &fl);
++    } while (ret == -1 && errno == EINTR);
+     return ret == -1 ? -errno : 0;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-bios-keymaps-keymaps-update.patch b/SOURCES/kvm-pc-bios-keymaps-keymaps-update.patch
new file mode 100644
index 0000000..08d6c93
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-keymaps-keymaps-update.patch
@@ -0,0 +1,27918 @@
+From 1e23fbdd90c3004fcf833222801dc69cc524bdca Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Mon, 23 Oct 2017 12:29:35 +0200
+Subject: [PATCH 2/9] pc-bios/keymaps: keymaps update
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171023122935.11297-2-kraxel@redhat.com>
+Patchwork-id: 77430
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] pc-bios/keymaps: keymaps update
+Bugzilla: 1503128
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Update the keymaps with the ones generated by qemu-keymap
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20171005153330.19210-4-kraxel@redhat.com
+(cherry picked from commit a7815faffb2bd594b92aa3542d7b799cc89c5414)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ pc-bios/keymaps/ar    |  819 ++++++++++++++++++++++++++++++++----
+ pc-bios/keymaps/bepo  | 1108 ++++++++++++++++++++++++++++++++++---------------
+ pc-bios/keymaps/cz    |  853 ++++++++++++++++++++++++++++++++++---
+ pc-bios/keymaps/da    |  732 +++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/de    |  767 +++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/de-ch |  921 ++++++++++++++++++++++++++++++++++------
+ pc-bios/keymaps/en-gb |  724 +++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/en-us |  718 +++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/es    |  744 ++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/et    |  818 ++++++++++++++++++++++++++++++++----
+ pc-bios/keymaps/fi    |  814 +++++++++++++++++++++++++++++++++---
+ pc-bios/keymaps/fo    |  879 ++++++++++++++++++++++++++++++++++++---
+ pc-bios/keymaps/fr    |  706 +++++++++++++++++++++++++++++--
+ pc-bios/keymaps/fr-be |  724 +++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/fr-ca |  802 ++++++++++++++++++++++++++++++++---
+ pc-bios/keymaps/fr-ch |  800 +++++++++++++++++++++++++++++++++--
+ pc-bios/keymaps/hr    |  752 ++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/hu    |  883 +++++++++++++++++++++++++++++++++++----
+ pc-bios/keymaps/is    |  802 ++++++++++++++++++++++++++++++++---
+ pc-bios/keymaps/it    |  757 ++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/ja    |  792 +++++++++++++++++++++++++++++++----
+ pc-bios/keymaps/lt    |  844 +++++++++++++++++++++++++++++++++++--
+ pc-bios/keymaps/lv    |  766 ++++++++++++++++++++++++++++++++--
+ pc-bios/keymaps/mk    |  814 ++++++++++++++++++++++++++++++++----
+ pc-bios/keymaps/nl    |  794 ++++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/no    |  758 ++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/pl    |  789 +++++++++++++++++++++++++++++++++--
+ pc-bios/keymaps/pt    |  737 +++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/pt-br |  775 +++++++++++++++++++++++++++++++++-
+ pc-bios/keymaps/ru    |  835 ++++++++++++++++++++++++++++++++-----
+ pc-bios/keymaps/th    |  878 +++++++++++++++++++++++++++++++++------
+ pc-bios/keymaps/tr    |  819 +++++++++++++++++++++++++++++++++---
+ 32 files changed, 24007 insertions(+), 1717 deletions(-)
+
+diff --git a/pc-bios/keymaps/ar b/pc-bios/keymaps/ar
+index c430c03..a763c9a 100644
+--- a/pc-bios/keymaps/ar
++++ b/pc-bios/keymaps/ar
+@@ -1,98 +1,753 @@
+-# generated from XKB map ar
+-include common
+-map 0x401
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : ar
++#    variant : -
++#    options : -
++
++# name: "Arabic"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ at 0x03 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ asciicircum 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
+-parenleft 0x0a shift
+-parenright 0x0b shift
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
++parenright 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
++parenleft 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+-Arabic_dad 0x10 altgr
+-Arabic_fatha 0x10 shift altgr
+-Arabic_sad 0x11 altgr
+-Arabic_fathatan 0x11 shift altgr
+-Arabic_theh 0x12 altgr
+-Arabic_damma 0x12 shift altgr
+-Arabic_qaf 0x13 altgr
+-Arabic_dammatan 0x13 shift altgr
+-Arabic_feh 0x14 altgr
+-UFEF9 0x14 shift altgr
+-Arabic_ghain 0x15 altgr
+-Arabic_hamzaunderalef 0x15 shift altgr
+-Arabic_ain 0x16 altgr
+-grave 0x16 shift altgr
+-Arabic_ha 0x17 altgr
+-division 0x17 shift altgr
+-Arabic_khah 0x18 altgr
+-multiply 0x18 shift altgr
+-Arabic_hah 0x19 altgr
+-Arabic_semicolon 0x19 shift altgr
+-bracketleft 0x1a
+-braceleft 0x1a shift
+-Arabic_jeem 0x1a altgr
+-bracketright 0x1b
+-braceright 0x1b shift
+-Arabic_dal 0x1b altgr
+-Arabic_sheen 0x1e altgr
+-backslash 0x1e shift altgr
+-Arabic_seen 0x1f altgr
+-Arabic_yeh 0x20 altgr
+-bracketleft 0x20 shift altgr
+-Arabic_beh 0x21 altgr
+-bracketright 0x21 shift altgr
+-Arabic_lam 0x22 altgr
+-UFEF7 0x22 shift altgr
+-Arabic_alef 0x23 altgr
+-Arabic_hamzaonalef 0x23 shift altgr
+-Arabic_teh 0x24 altgr
+-Arabic_tatweel 0x24 shift altgr
+-Arabic_noon 0x25 altgr
+-Arabic_comma 0x25 shift altgr
+-Arabic_meem 0x26 altgr
+-slash 0x26 shift altgr
+-semicolon 0x27
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++Arabic_dad 0x10
++Arabic_fatha 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++Arabic_sad 0x11
++Arabic_fathatan 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++Arabic_theh 0x12
++Arabic_damma 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++Arabic_qaf 0x13
++Arabic_dammatan 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++Arabic_feh 0x14
++UFEF9 0x14 shift
++Arabic_veh 0x14 altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++Arabic_ghain 0x15
++Arabic_hamzaunderalef 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++Arabic_ain 0x16
++grave 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++Arabic_ha 0x17
++division 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++Arabic_khah 0x18
++multiply 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++Arabic_hah 0x19
++Arabic_semicolon 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++Arabic_jeem 0x1a
++less 0x1a shift
++Arabic_tcheh 0x1a altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++Arabic_dal 0x1b
++greater 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++Arabic_sheen 0x1e
++Arabic_kasra 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++Arabic_seen 0x1f
++Arabic_kasratan 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++Arabic_yeh 0x20
++bracketright 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++Arabic_beh 0x21
++bracketleft 0x21 shift
++Arabic_peh 0x21 altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++Arabic_lam 0x22
++UFEF7 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++Arabic_alef 0x23
++Arabic_hamzaonalef 0x23 shift
++U0671 0x23 altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++Arabic_teh 0x24
++Arabic_tatweel 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++Arabic_noon 0x25
++Arabic_comma 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++Arabic_meem 0x26
++slash 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++Arabic_kaf 0x27
+ colon 0x27 shift
+-Arabic_kaf 0x27 altgr
+-apostrophe 0x28
++Arabic_gaf 0x27 altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++Arabic_tah 0x28
+ quotedbl 0x28 shift
+-Arabic_tah 0x28 altgr
+-grave 0x29
+-asciitilde 0x29 shift
+-Arabic_thal 0x29 altgr
+-Arabic_shadda 0x29 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++Arabic_thal 0x29
++Arabic_shadda 0x29 shift
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ backslash 0x2b
+ bar 0x2b shift
+-less 0x2b altgr
+-greater 0x2b shift altgr
+-Arabic_hamzaonyeh 0x2c altgr
+-asciitilde 0x2c shift altgr
+-Arabic_hamza 0x2d altgr
+-Arabic_sukun 0x2d shift altgr
+-Arabic_hamzaonwaw 0x2e altgr
+-Arabic_kasra 0x2e shift altgr
+-Arabic_ra 0x2f altgr
+-Arabic_kasratan 0x2f shift altgr
+-UFEFB 0x30 altgr
+-UFEF5 0x30 shift altgr
+-Arabic_alefmaksura 0x31 altgr
+-Arabic_maddaonalef 0x31 shift altgr
+-Arabic_tehmarbuta 0x32 altgr
+-apostrophe 0x32 shift altgr
+-comma 0x33
+-less 0x33 shift
+-Arabic_waw 0x33 altgr
+-period 0x34
+-greater 0x34 shift
+-Arabic_zain 0x34 altgr
+-slash 0x35
+-question 0x35 shift
+-Arabic_zah 0x35 altgr
+-Arabic_question_mark 0x35 shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++Arabic_hamzaonyeh 0x2c
++asciitilde 0x2c shift
++guillemotright 0x2c altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++Arabic_hamza 0x2d
++Arabic_sukun 0x2d shift
++guillemotleft 0x2d altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++Arabic_hamzaonwaw 0x2e
++braceright 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++Arabic_ra 0x2f
++braceleft 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++UFEFB 0x30
++UFEF5 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++Arabic_alefmaksura 0x31
++Arabic_maddaonalef 0x31 shift
++Arabic_superscript_alef 0x31 altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++Arabic_tehmarbuta 0x32
++apostrophe 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
++Arabic_waw 0x33
++comma 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
++Arabic_zain 0x34
++period 0x34 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++Arabic_zah 0x35
++Arabic_question_mark 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++bar 0x56
++brokenbar 0x56 shift
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/bepo b/pc-bios/keymaps/bepo
+index d40041a..dbe8daa 100644
+--- a/pc-bios/keymaps/bepo
++++ b/pc-bios/keymaps/bepo
+@@ -1,333 +1,781 @@
+-include common
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : fr
++#    variant : dvorak
++#    options : -
++
++# name: "French (Dvorak)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++equal 0x02
++1 0x02 shift
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++slash 0x03
++2 0x03 shift
++plusminus 0x03 altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++minus 0x04
++3 0x04 shift
++onequarter 0x04 altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++egrave 0x05
++4 0x05 shift
++onehalf 0x05 altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++backslash 0x06
++5 0x06 shift
++threequarters 0x06 altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++dead_circumflex 0x07
++6 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++parenleft 0x08
++7 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++ISO_Level3_Latch 0x09
++8 0x09 shift
++grave 0x09 altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++parenright 0x0a
++9 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++quotedbl 0x0b
++0 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++bracketleft 0x0c
++plus 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++bracketright 0x0d
++percent 0x0d shift
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++colon 0x10
++question 0x10 shift
++ae 0x10 altgr
++AE 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++apostrophe 0x11
++less 0x11 shift
++dollar 0x11 altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++eacute 0x12
++greater 0x12 shift
++Eacute 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++g 0x13
++G 0x13 shift
++EuroSign 0x13 altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++period 0x14
++exclam 0x14 shift
++degree 0x14 altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++h 0x15
++H 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++v 0x16
++V 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++c 0x17
++C 0x17 shift
++ccedilla 0x17 altgr
++Ccedilla 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++m 0x18
++M 0x18 shift
++mu 0x18 altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++k 0x19
++K 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++z 0x1a
++Z 0x1a shift
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++dead_diaeresis 0x1b
++ampersand 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++o 0x1e
++O 0x1e shift
++ograve 0x1e altgr
++Ograve 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++a 0x1f
++A 0x1f shift
++agrave 0x1f altgr
++Agrave 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++u 0x20
++U 0x20 shift
++ugrave 0x20 altgr
++Ugrave 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++e 0x21
++E 0x21 shift
++egrave 0x21 altgr
++Egrave 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++b 0x22
++B 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++f 0x23
++F 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++s 0x24
++S 0x24 shift
++guillemotleft 0x24 altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++t 0x25
++T 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++n 0x26
++N 0x26 shift
++guillemotright 0x26 altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++d 0x27
++D 0x27 shift
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++w 0x28
++W 0x28 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++underscore 0x29
++asterisk 0x29 shift
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
++asciitilde 0x2b
++numbersign 0x2b shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++semicolon 0x2c
++bar 0x2c shift
++oe 0x2c altgr
++OE 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++q 0x2d
++Q 0x2d shift
++braceleft 0x2d altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++comma 0x2e
++at 0x2e shift
++braceright 0x2e altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++i 0x2f
++I 0x2f shift
++igrave 0x2f altgr
++Igrave 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++y 0x30
++Y 0x30 shift
++sterling 0x30 altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++x 0x31
++X 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++r 0x32
++R 0x32 shift
++masculine 0x32 altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
++l 0x33
++L 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
++p 0x34
++P 0x34 shift
++section 0x34 altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++j 0x35
++J 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++nobreakspace 0x39 altgr
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++agrave 0x56
++ccedilla 0x56 shift
++Agrave 0x56 altgr
++Ccedilla 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+ 
+-# Bépo : Improved ergonomic french keymap using Dvorak method.
+-# Built by community on 'Dvorak Fr / Bépo' :
+-# see http://www.clavier-dvorak.org/wiki/ to join and help.
+ #
+-# Bépo layout (1.0rc2 version) for a pc105 keyboard (french) :
+-# ┌────┐
+-# │ S A│   S = Shift,  A = AltGr + Shift
+-# │ s a│   s = normal, a = AltGr
+-# └────┘
++# quirks section start
+ #
+-# ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┲━━━━━━━━━┓
+-# │ # ¶ │ 1 „ │ 2 “ │ 3 ” │ 4 ≤ │ 5 ≥ │ 6   │ 7 ¬ │ 8 ¼ │ 9 ½ │ 0 ¾ │ ° ′ │ ` ″ ┃ ⌫ Retour┃
+-# │ $ – │ " — │ « < │ » > │ ( [ │ ) ] │ @ ^ │ + ± │ - − │ / ÷ │ * × │ = ≠ │ % ‰ ┃  arrière┃
+-# ┢━━━━━┷━┱───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┺━┳━━━━━━━┫
+-# ┃       ┃ B ¦ │ É ˝ │ P § │ O Œ │ È ` │ !   │ V   │ D Ð │ L   │ J IJ │ Z Ə │ W   ┃Entrée ┃
+-# ┃Tab ↹  ┃ b | │ é ˊ │ p & │ o œ │ è ` │ ˆ ¡ │ v ˇ │ d ð │ l / │ j ij │ z ə │ w ̆ ┃   ⏎   ┃
+-# ┣━━━━━━━┻┱────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┴┬────┺┓      ┃
+-# ┃        ┃ A Æ │ U Ù │ I ˙ │ E ¤ │ ; ̛ │ C ſ │ T Þ │ S ẞ │ R ™ │ N   │ M º │ Ç , ┃      ┃
+-# ┃Maj ⇬   ┃ a æ │ u ù │ i ̈ │ e € │ , ’ │ c © │ t þ │ s ß │ r ® │ n ˜ │ m ¯ │ ç ¸ ┃      ┃
+-# ┣━━━━━━━┳┹────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴────┲┷━━━━━┻━━━━━━┫
+-# ┃       ┃ Ê   │ À   │ Y ‘ │ X ’ │ : · │ K   │ ? ̉ │ Q ̣ │ G   │ H ‡ │ F ª ┃             ┃
+-# ┃Shift ⇧┃ ê / │ à \ │ y { │ x } │ . … │ k ~ │ ' ¿ │ q ˚ │ g µ │ h † │ f ˛ ┃Shift ⇧      ┃
+-# ┣━━━━━━━╋━━━━━┷━┳━━━┷━━━┱─┴─────┴─────┴─────┴─────┴─────┴───┲━┷━━━━━╈━━━━━┻━┳━━━━━━━┳━━━┛
+-# ┃       ┃       ┃       ┃ Espace inséc.   Espace inséc. fin ┃       ┃       ┃       ┃
+-# ┃Ctrl   ┃Meta   ┃Alt    ┃ ␣ (Espace)      _               ␣ ┃AltGr ⇮┃Menu   ┃Ctrl   ┃
+-# ┗━━━━━━━┻━━━━━━━┻━━━━━━━┹───────────────────────────────────┺━━━━━━━┻━━━━━━━┻━━━━━━━┛
+-
+-
+-# First row
+-## keycode  41 = dollar numbersign       U+2013  U+00b6
+-dollar        0x29
+-numbersign    0x29  shift
+-U2013         0x29        altgr
+-U00b6         0x29  shift altgr
+-
+-## keycode   2 = +quotedbl +one          U+2014  U+201e
+-quotedbl      0x2
+-one           0x2  shift
+-U2014         0x2        altgr
+-U201e         0x2  shift altgr
+-
+-## keycode   3 = +guillemotleft  +two     less    U+201c
+-guillemotleft  0x3
+-two           0x3  shift
+-less          0x3        altgr
+-U201c         0x3  shift altgr
+-
+-## keycode   4 = +guillemotright +three  greater U+201d
+-guillemotright  0x4
+-three         0x4  shift
+-greater       0x4        altgr
+-U201d         0x4  shift altgr
+-
+-## keycode   5 = +parenleft +four        bracketleft  U+2264
+-parenleft     0x5
+-four          0x5  shift
+-bracketleft   0x5        altgr
+-U2264         0x5  shift altgr
+-
+-## keycode   6 = +parenright +five       bracketright  U+2265
+-parenright    0x6
+-five          0x6  shift
+-bracketright  0x6        altgr
+-U2265         0x6  shift altgr
+-
+-## keycode   7 = +at       +six          asciicircum
+-at            0x7
+-six           0x7  shift
+-asciicircum   0x7        altgr
+-
+-## keycode   8 = +plus     +seven        U+00b1  U+00ac
+-plus          0x8
+-seven         0x8  shift
+-U00b1         0x8        altgr
+-U00ac         0x8  shift altgr
+-
+-## keycode   9 = +minus    +eight        U+2212  U+00bc
+-minus         0x9
+-eight         0x9  shift
+-U2212         0x9        altgr
+-U00bc         0x9  shift altgr
+-
+-## keycode  10 = +slash    +nine         U+00f7  U+00bd
+-slash         0xa
+-nine          0xa  shift
+-U00f7         0xa        altgr
+-U00bd         0xa  shift altgr
+-
+-## keycode  11 = +asterisk +zero         U+00d7  U+00be
+-asterisk      0xb
+-zero          0xb  shift
+-U00d7         0xb        altgr
+-U00be         0xb  shift altgr
+-
+-## keycode  12 = equal     U+00b0        U+2260  U+2032
+-equal         0xc
+-U00b0         0xc  shift
+-U2260         0xc        altgr
+-U2032         0xc  shift altgr
+-
+-## keycode  13 = percent   grave         U+2030  U+2033
+-percent       0xd
+-grave         0xd  shift
+-U2030         0xd        altgr
+-U2033         0xd  shift altgr
+-
+-
+-# Second row
+-
+-# simplified letter definitions notation :
+-## keycode 16 = b
+-b             0x10  addupper
+-## keycode 18 = p
+-p             0x12  addupper
+-## keycode 19 = o
+-o             0x13  addupper
+-## keycode 22 = v
+-v             0x16  addupper
+-## keycode 23 = d
+-d             0x17  addupper
+-## keycode 24 = l
+-l             0x18  addupper
+-## keycode 25 = j
+-j             0x19  addupper
+-## keycode 26 = z
+-z             0x1a  addupper
+-## keycode 27 = w
+-w             0x1b  addupper
+-
+-# then, add specific definitions
+-##                    AltGr keycode  16 = bar
+-bar           0x10        altgr
+-##              Shift AltGr keycode  16 = brokenbar
+-brokenbar     0x10  shift altgr
+-
+-## keycode 17 = +eacute +Eacute dead_acute
+-eacute        0x11
+-Eacute        0x11  shift
+-dead_acute    0x11        altgr
+-
+-##                    AltGr keycode  18 = ampersand
+-ampersand     0x12        altgr
+-##              Shift AltGr keycode  18 = U+00a7
+-U00a7         0x12  shift altgr
+-
+-##                    AltGr keycode  19 = +U+0153
+-U+0153        0x13        altgr
+-##              Shift AltGr keycode  19 = +U+0152
+-U+0152        0x13  shift altgr
+-
+-## keycode 20 = +egrave +Egrave dead_grave grave # no Meta !
+-egrave        0x14
+-Egrave        0x14  shift
+-dead_grave    0x14        altgr
+-
+-## keycode 21 = dead_circumflex exclam exclamdown
+-dead_circumflex  0x15
+-exclam        0x15  shift
+-exclamdown    0x15        altgr
+-
+-##                    AltGr keycode  22 = dead_caron
+-dead_caron    0x16        altgr
+-
+-##                    AltGr keycode  23 = eth
+-eth           0x17        altgr
+-##              Shift AltGr keycode  23 = ETH
+-ETH           0x17  shift altgr
+-
+-##                    AltGr keycode  25 = +U+0133
+-U+0133        0x19        altgr
+-##              Shift AltGr keycode  25 = +U+0132
+-U+0132        0x19  shift altgr
+-
+-##                    AltGr keycode  26 = +U+0259
+-U+0259        0x1a        altgr
+-##              Shift AltGr keycode  26 = +U+018f
+-U+018f        0x1a  shift altgr
+-
+-
+-
+-# Third row
+-
+-# simplified letter definitions notation :
+-## keycode 30 = a
+-a             0x1e  addupper
+-## keycode 31 = u
+-u             0x1f  addupper
+-## keycode 32 = i
+-i             0x20  addupper
+-## keycode 33 = e
+-e             0x21  addupper
+-## keycode 35 = c
+-c             0x23  addupper
+-## keycode 36 = t
+-t             0x24  addupper
+-## keycode 37 = s
+-s             0x25  addupper
+-## keycode 38 = r
+-r             0x26  addupper
+-## keycode 39 = n
+-n             0x27  addupper
+-## keycode 40 = m
+-m             0x28  addupper
+-
+-# then, add specific definitions
+-##                    AltGr keycode  30 = +ae
+-ae            0x1e        altgr
+-##              Shift AltGr keycode  30 = +AE
+-AE            0x1e  shift altgr
+-
+-##                    AltGr keycode  31 = +ugrave
+-ugrave        0x1f        altgr
+-##              Shift AltGr keycode  31 = +Ugrave
+-Ugrave        0x1f  shift altgr
+-
+-##                    AltGr keycode  32 = dead_diaeresis
+-dead_diaeresis  0x20        altgr
+-
+-
+-##                    AltGr keycode  33 = U+20ac
+-U20ac         0x21        altgr
+-
+-## keycode 34 = comma semicolon U+2019 +U+031b
+-comma         0x22
+-semicolon     0x22  shift
+-U2019         0x22        altgr
+-U+031b        0x22  shift altgr
+-
+-##                    AltGr keycode  35 = copyright
+-copyright     0x23        altgr
+-##              Shift AltGr keycode  35 = U+017f
+-U017f         0x23  shift altgr
+-
+-##                    AltGr keycode  36 = +thorn
+-thorn         0x24        altgr
+-##              Shift AltGr keycode  36 = +THORN
+-THORN         0x24  shift altgr
+-
+-##                    AltGr keycode  37 = +ssharp
+-ssharp        0x25        altgr
+-##              Shift AltGr keycode  37 = U+1e9e
+-U1e9e         0x25  shift altgr
+-
+-##                    AltGr keycode  38 = registered
+-registered    0x26        altgr
+-##              Shift AltGr keycode  38 = U+2122
+-U2122         0x26  shift altgr
+-
+-##                    AltGr keycode  39 = dead_tilde
+-dead_tilde    0x27        altgr
+-
+-##              Shift AltGr keycode  40 = masculine
+-masculine     0x28  shift altgr
+-
+-## keycode 43 = +ccedilla +Ccedilla dead_cedilla
+-ccedilla      0x2b
+-Ccedilla      0x2b  shift
+-dead_cedilla  0x2b        altgr
+-
+-
+-# Fourth row
+-
+-# simplified letter definitions notation :
+-## keycode 45 = y
+-y             0x2d  addupper
+-## keycode 46 = x
+-x             0x2e  addupper
+-## keycode 48 = k
+-k             0x30  addupper
+-## keycode 50 = q
+-q             0x32  addupper
+-## keycode 51 = g
+-g             0x33  addupper
+-## keycode 52 = h
+-h             0x34  addupper
+-## keycode 53 = f
+-f             0x35  addupper
+-
+-# then, add specific definitions
+-## keycode 86 = +ecircumflex +Ecircumflex slash slash
+-ecircumflex   0x56
+-Ecircumflex   0x56  shift
+-
+-## keycode 44 = +agrave +Agrave backslash
+-agrave        0x2c
+-Agrave        0x2c  shift
+-backslash     0x2c        altgr
+-
+-##                    AltGr keycode  45 = braceleft
+-braceleft     0x2d        altgr
+-##              Shift AltGr keycode  45 = U+2018
+-U2018         0x2d  shift altgr
+-
+-##                    AltGr keycode  46 = braceright
+-braceright    0x2e        altgr
+-
+-## keycode 47 = period colon U+2026 periodcentered
+-period        0x2f
+-colon         0x2f  shift
+-U2026         0x2f        altgr
+-periodcentered  0x2f  shift altgr
+-
+-##                    AltGr keycode  48 = asciitilde
+-asciitilde    0x30        altgr
+-##              Shift AltGr keycode  48 = U+2328
+-U2328         0x30  shift altgr
+-
+-## keycode 49 = apostrophe question questiondown +U+0309
+-apostrophe    0x31
+-question      0x31  shift
+-questiondown  0x31        altgr
+-U+0309        0x31  shift altgr
+-
+-##                    AltGr keycode  51 = mu
+-mu            0x33        altgr
+-
+-##                    AltGr keycode  52 = U+2020
+-U2020         0x34        altgr
+-##              Shift AltGr keycode  52 = U+2021
+-U2021         0x34  shift altgr
+-
+-##              Shift AltGr keycode  53 = ordfeminine
+-ordfeminine   0x35  shift altgr
+-
+-
+-
+-## keycode 57 = space nobreakspace underscore U+202f
+-space         0x39
+-nobreakspace  0x39  shift
+-underscore    0x39        altgr
+-U202f         0x39  shift altgr
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/cz b/pc-bios/keymaps/cz
+index 6584bfb..46b3775 100644
+--- a/pc-bios/keymaps/cz
++++ b/pc-bios/keymaps/cz
+@@ -1,94 +1,837 @@
+-include common
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : cz
++#    variant : -
++#    options : -
+ 
+-# Czech qwertz layout
+-# comments are czech descriptions of the characters
++# name: "Czech"
+ 
+-# -----------
+-#  First row
+-# -----------
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
+ 
+-# strednik, kolecko
+-semicolon 0x29
+-dead_abovering 0x29 shift
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++plus 0x02
++1 0x02 shift
++exclam 0x02 altgr
++dead_tilde 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++ecaron 0x03
++2 0x03 shift
++at 0x03 altgr
++dead_caron 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++scaron 0x04
++3 0x04 shift
++numbersign 0x04 altgr
++dead_circumflex 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++ccaron 0x05
++4 0x05 shift
++dollar 0x05 altgr
++dead_breve 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++rcaron 0x06
++5 0x06 shift
++percent 0x06 altgr
++dead_abovering 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++zcaron 0x07
++6 0x07 shift
++asciicircum 0x07 altgr
++dead_ogonek 0x07 shift altgr
+ 
+-# numbers
+-plus 0x2
+-1 0x2 shift
+-ecaron 0x3
+-2 0x3 shift
+-scaron 0x4
+-3 0x4 shift
+-ccaron 0x5
+-4 0x5 shift
+-rcaron 0x6
+-5 0x6 shift
+-zcaron 0x7
+-6 0x7 shift
+-yacute 0x8
+-7 0x8 shift
+-aacute 0x9
+-8 0x9 shift
+-iacute 0xa
+-9 0xa shift
+-eacute 0xb
+-0 0xb shift
+-
+-# rovnitko
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++yacute 0x08
++7 0x08 shift
++ampersand 0x08 altgr
++dead_grave 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++aacute 0x09
++8 0x09 shift
++asterisk 0x09 altgr
++dead_abovedot 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++iacute 0x0a
++9 0x0a shift
++braceleft 0x0a altgr
++dead_acute 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++eacute 0x0b
++0 0x0b shift
++braceright 0x0b altgr
++dead_doubleacute 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ equal 0x0c
+ percent 0x0c shift
++backslash 0x0c altgr
++dead_diaeresis 0x0c shift altgr
+ 
+-# carka, hacek
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ dead_acute 0x0d
+ dead_caron 0x0d shift
++dead_macron 0x0d altgr
++dead_cedilla 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++backslash 0x10 altgr
++Greek_OMEGA 0x10 shift altgr
+ 
+-# ------------
+-#  Second row
+-# ------------
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++bar 0x11 altgr
++Lstroke 0x11 shift altgr
+ 
+-z 0x15 addupper
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++EuroSign 0x12 altgr
+ 
+-# u s carkou, zpetne lomitko
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++paragraph 0x13 altgr
++registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++tslash 0x14 altgr
++Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++z 0x15
++Z 0x15 shift
++leftarrow 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++downarrow 0x16 altgr
++uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++rightarrow 0x17 altgr
++idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oslash 0x18 altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++thorn 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ uacute 0x1a
+ slash 0x1a shift
++bracketleft 0x1a altgr
++division 0x1a shift altgr
+ 
+-# prava zavorka, leva zavorka
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ parenright 0x1b
+ parenleft 0x1b shift
++bracketright 0x1b altgr
++multiply 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++asciitilde 0x1e altgr
++AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++dstroke 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++Dstroke 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++bracketleft 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++bracketright 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++grave 0x23 altgr
++Hstroke 0x23 shift altgr
+ 
+-# -----------
+-#  Third row
+-# -----------
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++apostrophe 0x24 altgr
++dead_horn 0x24 shift altgr
+ 
+-# u s krouzkem, uvozovky
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++lstroke 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++Lstroke 0x26 altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ uring 0x27
+ quotedbl 0x27 shift
++dollar 0x27 altgr
++dead_doubleacute 0x27 shift altgr
+ 
+-# paragraf, vykricnik
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ section 0x28
+ exclam 0x28 shift
++apostrophe 0x28 altgr
++ssharp 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++semicolon 0x29
++dead_abovering 0x29 shift
++grave 0x29 altgr
++asciitilde 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
+ 
+-# vodorovna dvojtecka, apostrof
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ dead_diaeresis 0x2b
+ apostrophe 0x2b shift
++backslash 0x2b altgr
++bar 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++y 0x2c
++Y 0x2c shift
++degree 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++numbersign 0x2d altgr
++greater 0x2d shift altgr
+ 
+-# ------------
+-#  Fourth row
+-# ------------
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++ampersand 0x2e altgr
++copyright 0x2e shift altgr
+ 
+-# zpetne lomitko, roura
+-backslash 0x2b
+-bar 0x2b shift
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++at 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
+ 
+-y 0x2c addupper
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++braceleft 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
+ 
+-# carka, otaznik
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++braceright 0x31 altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++asciicircum 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ question 0x33 shift
++less 0x33 altgr
++multiply 0x33 shift altgr
+ 
+-# tecka, dvojtecka
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
++greater 0x34 altgr
++division 0x34 shift altgr
+ 
+-# minus, podtrzitko
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
++asterisk 0x35 altgr
++dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++backslash 0x56
++bar 0x56 shift
++slash 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/da b/pc-bios/keymaps/da
+index 3884dcf..f7cdad7 100644
+--- a/pc-bios/keymaps/da
++++ b/pc-bios/keymaps/da
+@@ -1,120 +1,836 @@
+-# generated from XKB map dk
+-include common
+-map 0x406
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : dk
++#    variant : -
++#    options : -
++
++# name: "Danish"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ exclamdown 0x02 altgr
+ onesuperior 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ at 0x03 altgr
+ twosuperior 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ sterling 0x04 altgr
+ threesuperior 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ currency 0x05 shift
+ dollar 0x05 altgr
+ onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ cent 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+ yen 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+ division 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+ guillemotleft 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ guillemotright 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ plus 0x0c
+ question 0x0c shift
+ plusminus 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ dead_acute 0x0d
+ dead_grave 0x0d shift
+ bar 0x0d altgr
+ brokenbar 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+ cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ registered 0x13 altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ thorn 0x14 altgr
+ THORN 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oe 0x18 altgr
+ OE 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ aring 0x1a
+ Aring 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dead_diaeresis 0x1b
+ dead_circumflex 0x1b shift
+ dead_tilde 0x1b altgr
+ dead_caron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ordfeminine 0x1e altgr
+ masculine 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
+ section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ae 0x27
+ AE 0x27 shift
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ oslash 0x28
+-Ooblique 0x28 shift
++Oslash 0x28 shift
++dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ onehalf 0x29
+ section 0x29 shift
+ threequarters 0x29 altgr
+ paragraph 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ apostrophe 0x2b
+ asterisk 0x2b shift
+ dead_doubleacute 0x2b altgr
+ multiply 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ copyright 0x2e altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+ dead_cedilla 0x33 altgr
+ dead_ogonek 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+ periodcentered 0x34 altgr
+ dead_abovedot 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+-hyphen 0x35 altgr
+-macron 0x35 shift altgr
+-nobreakspace 0x39 altgr
++dead_belowdot 0x35 altgr
++dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
+ less 0x56
+ greater 0x56 shift
+ backslash 0x56 altgr
+ notsign 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/de b/pc-bios/keymaps/de
+index ed929c7..d0b4715 100644
+--- a/pc-bios/keymaps/de
++++ b/pc-bios/keymaps/de
+@@ -1,114 +1,839 @@
+-# generated from XKB map de
+-include common
+-map 0x407
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : de
++#    variant : -
++#    options : -
++
++# name: "German"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ twosuperior 0x03 altgr
+ oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ section 0x04 shift
+ threesuperior 0x04 altgr
+ sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ onequarter 0x05 altgr
+ currency 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-threequarters 0x07 altgr
++notsign 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
++degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ ssharp 0x0c
+ question 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
+-acute 0x0d
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ dead_acute 0x0d
+-grave 0x0d shift
+ dead_grave 0x0d shift
+ dead_cedilla 0x0d altgr
+ dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
+-z 0x15 addupper
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++z 0x15
++Z 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ udiaeresis 0x1a
+ Udiaeresis 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ plus 0x1b
+ asterisk 0x1b shift
+ asciitilde 0x1b altgr
+-dead_tilde 0x1b altgr
+-dead_macron 0x1b shift altgr
++macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++U017F 0x1f altgr
++U1E9E 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_belowdot 0x24 altgr
++dead_abovedot 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ odiaeresis 0x27
+ Odiaeresis 0x27 shift
+ dead_doubleacute 0x27 altgr
++dead_belowdot 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ adiaeresis 0x28
+ Adiaeresis 0x28 shift
++dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
+-asciicircum 0x29
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ dead_circumflex 0x29
+ degree 0x29 shift
+-notsign 0x29 altgr
++U2032 0x29 altgr
++U2033 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ numbersign 0x2b
+ apostrophe 0x2b shift
++rightsinglequotemark 0x2b altgr
+ dead_breve 0x2b shift altgr
+-y 0x2c addupper
+-guillemotleft 0x2c altgr
+-guillemotright 0x2d altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++y 0x2c
++Y 0x2c shift
++guillemotright 0x2c altgr
++U203A 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++guillemotleft 0x2d altgr
++U2039 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
+-leftdoublequotemark 0x2f altgr
+-rightdoublequotemark 0x30 altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++doublelowquotemark 0x2f altgr
++singlelowquotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++leftdoublequotemark 0x30 altgr
++leftsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++rightdoublequotemark 0x31 altgr
++rightsinglequotemark 0x31 shift altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+-horizconnector 0x33 altgr
++periodcentered 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+-periodcentered 0x34 altgr
++U2026 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+-dead_belowdot 0x35 altgr
+-dead_abovedot 0x35 shift altgr
++endash 0x35 altgr
++emdash 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/de-ch b/pc-bios/keymaps/de-ch
+index 852f8b8..ad37f6c 100644
+--- a/pc-bios/keymaps/de-ch
++++ b/pc-bios/keymaps/de-ch
+@@ -1,169 +1,836 @@
+-# rdesktop Swiss-German (de-ch) keymap file
+-# 2003-06-03 by noldi@tristar.ch
+ #
+-include common
+-map 0x00000807
+-#
+-# Scan Code 1
+-section 0x29
+-degree 0x29 shift
+-notsign 0x29 altgr inhibit
+-#
+-# Scan Code 2
+-plus 0x2 shift
+-brokenbar 0x02 altgr
+-#
+-# Scan Code 3
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : ch
++#    variant : -
++#    options : -
++
++# name: "German (Switzerland)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
++plus 0x02 shift
++bar 0x02 altgr
++exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ at 0x03 altgr
+-#
+-# Scan Code 4
++oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ asterisk 0x04 shift
+ numbersign 0x04 altgr
+-#
+-# Scan Code 5
++sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ ccedilla 0x05 shift
+-onequarter 0x05 altgr inhibit
+-#
+-# Scan Code 6
++onequarter 0x05 altgr
++dollar 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+-onehalf 0x06 altgr inhibit
+-#
+-# Scan Code 7
++onehalf 0x06 altgr
++threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+ notsign 0x07 altgr
+-#
+-# Scan Code 8
++fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ bar 0x08 altgr
+-#
+-# Scan Code 9
++seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ cent 0x09 altgr
+-#
+-# Scan Code 10
++trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+-#
+-# Scan Code 11
++bracketright 0x0a altgr
++plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+-braceright 0x0b altgr inhibit
+-#
+-# Scan Code 12
++braceright 0x0b altgr
++degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ apostrophe 0x0c
+ question 0x0c shift
+ dead_acute 0x0c altgr
+-#
+-# Scan Code 13
++questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ dead_circumflex 0x0d
+ dead_grave 0x0d shift
+ dead_tilde 0x0d altgr
+-#
+-# Scan Code 19
++dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
++Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+-#
+-# Scan Code 22
+-z 0x15 addupper
+-#
+-# Scan Code 27
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++paragraph 0x13 altgr
++registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++tslash 0x14 altgr
++Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++z 0x15
++Z 0x15 shift
++leftarrow 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++downarrow 0x16 altgr
++uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++rightarrow 0x17 altgr
++idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oe 0x18 altgr
++OE 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++thorn 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ udiaeresis 0x1a
+ egrave 0x1a shift
+ bracketleft 0x1a altgr
+-#
+-# Scan Code 28
++dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dead_diaeresis 0x1b
+ exclam 0x1b shift
+ bracketright 0x1b altgr
+-#
+-# Scan Code 40
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++ae 0x1e altgr
++AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++eth 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++dstroke 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++eng 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++hstroke 0x23 altgr
++Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ odiaeresis 0x27
+ eacute 0x27 shift
+-#
+-# Scan Code 41
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ adiaeresis 0x28
+ agrave 0x28 shift
+ braceleft 0x28 altgr
+-#
+-# Scan Code 42 (only on international keyboards)
++dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++section 0x29
++degree 0x29 shift
++notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ dollar 0x2b
+ sterling 0x2b shift
+ braceright 0x2b altgr
+-#
+-# Scan Code 45 (only on international keyboards)
+-backslash 0x56 altgr
+-#
+-# Scan Code 46
+-y 0x2c addupper
+-#
+-# Scan Code 53
++dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++y 0x2c
++Y 0x2c shift
++guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++cent 0x2e altgr
++copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++mu 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+-#
+-# Scan Code 54
++horizconnector 0x33 altgr
++multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+-#
+-# Scan Code 55
++periodcentered 0x34 altgr
++division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+-#
+-# Suppress Windows unsupported AltGr keys
+-#
+-# Scan Code 17
+-paragraph 0x10 altgr inhibit
+-#
+-# Scan Code 21
+-tslash 0x14 altgr inhibit
+-#
+-# Scan Code 22
+-leftarrow 0x15 altgr inhibit
+-#
+-# Scan Code 23
+-downarrow 0x16 altgr inhibit
+-#
+-# Scan Code 24
+-rightarrow 0x17 altgr inhibit
+-#
+-# Scan Code 25
+-oslash 0x18 altgr inhibit
+-#
+-# Scan Code 26
+-thorn 0x19 altgr inhibit
+-#
+-# Scan Code 31
+-ae 0x1e altgr inhibit
+-#
+-# Scan Code 32
+-ssharp 0x1f altgr inhibit
+-#
+-# Scan Code 33
+-eth 0x20 altgr inhibit
+-#
+-# Scan Code 34
+-dstroke 0x21 altgr inhibit
+-#
+-# Scan Code 35
+-eng 0x22 altgr inhibit
+-#
+-# Scan Code 36
+-hstroke 0x23 altgr inhibit
+-#
+-# Scan Code 38
+-kra 0x25 altgr inhibit
+-#
+-# Scan Code 39
+-lstroke 0x26 altgr inhibit
+-#
+-# Scan Code 46
+-guillemotleft 0x2c altgr inhibit
+-#
+-# Scan Code 47
+-guillemotright 0x2d altgr inhibit
+-#
+-# Scan Code 49
+-leftdoublequotemark 0x2f altgr inhibit
+-#
+-# Scan Code 50
+-rightdoublequotemark 0x30 altgr inhibit
+-#
+-# Scan Code 52
+-mu 0x32 altgr inhibit
++dead_belowdot 0x35 altgr
++dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++backslash 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/en-gb b/pc-bios/keymaps/en-gb
+index b45f06c..999cca7 100644
+--- a/pc-bios/keymaps/en-gb
++++ b/pc-bios/keymaps/en-gb
+@@ -1,119 +1,835 @@
+-# generated from XKB map gb
+-include common
+-map 0x809
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : gb
++#    variant : -
++#    options : -
++
++# name: "English (UK)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ twosuperior 0x03 altgr
+ oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ sterling 0x04 shift
+ threesuperior 0x04 altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ EuroSign 0x05 altgr
++onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ asciicircum 0x07 shift
+ threequarters 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
+ bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+ dead_cedilla 0x0d altgr
+ dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ bracketleft 0x1a
+ braceleft 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketright 0x1b
+ braceright 0x1b shift
+ dead_tilde 0x1b altgr
+ dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
+ section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ semicolon 0x27
+ colon 0x27 shift
+ dead_acute 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ apostrophe 0x28
+ at 0x28 shift
+ dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ grave 0x29
+ notsign 0x29 shift
+ bar 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ numbersign 0x2b
+ asciitilde 0x2b shift
+ dead_grave 0x2b altgr
+ dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
+ less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
+ greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
+ backslash 0x56
+ bar 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++Multi_key 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/en-us b/pc-bios/keymaps/en-us
+index f5784bb..a70e03a 100644
+--- a/pc-bios/keymaps/en-us
++++ b/pc-bios/keymaps/en-us
+@@ -1,35 +1,747 @@
+-# generated from XKB map us
+-include common
+-map 0x409
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : us
++#    variant : -
++#    options : -
++
++# name: "English (US)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ at 0x03 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ asciicircum 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ bracketleft 0x1a
+ braceleft 0x1a shift
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketright 0x1b
+ braceright 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ semicolon 0x27
+ colon 0x27 shift
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ apostrophe 0x28
+ quotedbl 0x28 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ grave 0x29
+ asciitilde 0x29 shift
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ backslash 0x2b
+ bar 0x2b shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/es b/pc-bios/keymaps/es
+index 0c29eec..53e66e8 100644
+--- a/pc-bios/keymaps/es
++++ b/pc-bios/keymaps/es
+@@ -1,105 +1,835 @@
+-# generated from XKB map es
+-include common
+-map 0x40a
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : es
++#    variant : -
++#    options : -
++
++# name: "Spanish"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ bar 0x02 altgr
++exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ at 0x03 altgr
+ oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ periodcentered 0x04 shift
+ numbersign 0x04 altgr
+ sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ asciitilde 0x05 altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+ notsign 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
++braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
++bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
++bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
++braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ apostrophe 0x0c
+ question 0x0c shift
++backslash 0x0c altgr
++questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ exclamdown 0x0d
+ questiondown 0x0d shift
++dead_tilde 0x0d altgr
++asciitilde 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ dead_grave 0x1a
+ dead_circumflex 0x1a shift
+ bracketleft 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ plus 0x1b
+ asterisk 0x1b shift
+ bracketright 0x1b altgr
+ dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
+ section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ntilde 0x27
+ Ntilde 0x27 shift
++asciitilde 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ dead_acute 0x28
+ dead_diaeresis 0x28 shift
+ braceleft 0x28 altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ masculine 0x29
+ ordfeminine 0x29 shift
+ backslash 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ ccedilla 0x2b
+ Ccedilla 0x2b shift
+ braceright 0x2b altgr
+ dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
+-less 0x56
+-greater 0x56 shift
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
++periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/et b/pc-bios/keymaps/et
+index 85541a3..7bed679 100644
+--- a/pc-bios/keymaps/et
++++ b/pc-bios/keymaps/et
+@@ -1,85 +1,745 @@
+-map 0x00000425
+-include common
+-
+-#
+-# Top row
+ #
+-dead_caron 0x29
+-dead_tilde 0x29 shift
+-
+-# 1
+-exclam 0x2 shift
+-
+-# 2
+-quotedbl 0x3 shift
+-at 0x3 altgr
+-
+-# 3
+-numbersign 0x4 shift
+-sterling 0x4 altgr
+-# 4
+-currency 0x5 shift
+-dollar 0x5 altgr
+-# 5
+-percent 0x6 shift
+-# 6
+-ampersand 0x7 shift
+-# 7
+-slash 0x8 shift
+-braceleft 0x8 altgr
+-# 8
+-parenleft 0x9 shift
+-bracketleft 0x9 altgr
+-# 9
+-parenright 0xa shift
+-bracketright 0xa altgr
+-# 0
+-equal 0xb shift
+-braceright 0xb altgr
+-
+-plus 0xc
+-question 0xc shift
+-backslash 0xc altgr
+-
+-acute 0xd
+-dead_acute 0xd
+-grave 0xd shift
+-dead_grave 0xd shift
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : et
++#    variant : -
++#    options : -
+ 
+-#
+-# QWERTY first row
+-#
+-EuroSign 0x12 altgr
+-udiaeresis 0x1a
+-Udiaeresis 0x1a shift
+-otilde 0x1b
+-Otilde 0x1b shift
+-section 0x1b altgr
++# name: "Amharic"
+ 
+-#
+-# QWERTY second row
+-#
+-scaron 0x1f altgr
+-Scaron 0x1f altgr shift
+-odiaeresis 0x27
+-Odiaeresis 0x27 shift
+-adiaeresis 0x28
+-Adiaeresis 0x28 shift
+-asciicircum 0x28 altgr
+-apostrophe 0x2b
+-asterisk 0x2b shift
+-onehalf 0x2b altgr
+-#
+-# QWERTY third row
+-#
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++U1369 0x02
++U1372 0x02 shift
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++U136A 0x03
++U1373 0x03 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++U136B 0x04
++U1374 0x04 shift
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++U136C 0x05
++U1375 0x05 shift
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++U136D 0x06
++U1376 0x06 shift
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++U136E 0x07
++U1377 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++U136F 0x08
++U1378 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++U1370 0x09
++U1379 0x09 shift
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++U1371 0x0a
++U137A 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++U137B 0x0b
++U137C 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++minus 0x0c
++underscore 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++equal 0x0d
++plus 0x0d shift
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++U1240 0x10
++U1250 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++U12C8 0x11
++VoidSymbol 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++UFE69 0x12
++UFE70 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++U1228 0x13
++VoidSymbol 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++U1270 0x14
++U1320 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++U12E8 0x15
++VoidSymbol 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++UFE75 0x16
++UFE76 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++UFE71 0x17
++UFE72 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++UFE73 0x18
++UFE74 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++U1350 0x19
++U1330 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++U1340 0x1a
++U1338 0x1a shift
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++U1328 0x1b
++U1280 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++UFE67 0x1e
++UFE68 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++U1230 0x1f
++U1220 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++U12F0 0x20
++U12F8 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++U1348 0x21
++VoidSymbol 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++U1308 0x22
++U1318 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++U1200 0x23
++U1210 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++U1300 0x24
++VoidSymbol 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++U12A8 0x25
++U12B8 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++U1208 0x26
++VoidSymbol 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++U1362 0x27
++U1361 0x27 shift
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++U1366 0x28
++U1365 0x28 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
++VoidSymbol 0x2b
++U2010 0x2b shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++U12D8 0x2c
++U12E0 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++U12A0 0x2d
++U12D0 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++U1278 0x2e
++UFE78 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++U1238 0x2f
++U1268 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++U1260 0x30
++VoidSymbol 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++U1290 0x31
++U1298 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++U1218 0x32
++VoidSymbol 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
++U1363 0x33
++VoidSymbol 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
++U1364 0x34
++VoidSymbol 0x34 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++U1367 0x35
++question 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
+ less 0x56
+ greater 0x56 shift
+ bar 0x56 altgr
+-zcaron 0x2c altgr
+-Zcaron 0x2c altgr shift
+-comma 0x33
+-semicolon 0x33 shift
+-period 0x34
+-colon 0x34 shift
+-minus 0x35
+-underscore 0x35 shift
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym ISO_Next_Group)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/fi b/pc-bios/keymaps/fi
+index 4be7586..1c7653d 100644
+--- a/pc-bios/keymaps/fi
++++ b/pc-bios/keymaps/fi
+@@ -1,122 +1,810 @@
+-# generated from XKB map se_FI
+-include common
+-map 0x40b
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : fi
++#    variant : -
++#    options : -
++
++# name: "Finnish"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+-exclamdown 0x02 altgr
+-onesuperior 0x02 shift altgr
++exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ at 0x03 altgr
+-twosuperior 0x03 shift altgr
++rightdoublequotemark 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ sterling 0x04 altgr
+-threesuperior 0x04 shift altgr
++guillemotright 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ currency 0x05 shift
+ dollar 0x05 altgr
+-onequarter 0x05 shift altgr
++guillemotleft 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+-onehalf 0x06 altgr
+-cent 0x06 shift altgr
++permille 0x06 altgr
++leftdoublequotemark 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-yen 0x07 altgr
+-fiveeighths 0x07 shift altgr
++singlelowquotemark 0x07 altgr
++doublelowquotemark 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+-division 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+-guillemotleft 0x09 shift altgr
++less 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+-guillemotright 0x0a shift altgr
++greater 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ plus 0x0c
+ question 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ dead_acute 0x0d
+ dead_grave 0x0d shift
+-plusminus 0x0d altgr
+-notsign 0x0d shift altgr
+-at 0x10 altgr
+-Greek_OMEGA 0x10 shift altgr
+-lstroke 0x11 altgr
+-Lstroke 0x11 shift altgr
++dead_cedilla 0x0d altgr
++dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+-cent 0x12 shift altgr
+-registered 0x13 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ thorn 0x14 altgr
+ THORN 0x14 shift altgr
+-leftarrow 0x15 altgr
+-yen 0x15 shift altgr
+-downarrow 0x16 altgr
+-uparrow 0x16 shift altgr
+-rightarrow 0x17 altgr
+-idotless 0x17 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++idotless 0x17 altgr
++bar 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oe 0x18 altgr
+ OE 0x18 shift altgr
+-thorn 0x19 altgr
+-THORN 0x19 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++dead_horn 0x19 altgr
++dead_hook 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ aring 0x1a
+ Aring 0x1a shift
+-dead_diaeresis 0x1a altgr
++dead_doubleacute 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dead_diaeresis 0x1b
+ dead_circumflex 0x1b shift
+ dead_tilde 0x1b altgr
+-dead_caron 0x1b shift altgr
+-ordfeminine 0x1e altgr
+-masculine 0x1e shift altgr
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++schwa 0x1e altgr
++SCHWA 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
+-section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
+-dstroke 0x21 altgr
+-ordfeminine 0x21 shift altgr
+-eng 0x22 altgr
+-ENG 0x22 shift altgr
+-hstroke 0x23 altgr
+-Hstroke 0x23 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
+-ampersand 0x25 shift altgr
+-lstroke 0x26 altgr
+-Lstroke 0x26 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++dead_stroke 0x26 altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ odiaeresis 0x27
+ Odiaeresis 0x27 shift
+ oslash 0x27 altgr
+-Ooblique 0x27 shift altgr
++Oslash 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ adiaeresis 0x28
+ Adiaeresis 0x28 shift
+ ae 0x28 altgr
+ AE 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ section 0x29
+ onehalf 0x29 shift
+-paragraph 0x29 altgr
+-threequarters 0x29 shift altgr
++dead_stroke 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ apostrophe 0x2b
+ asterisk 0x2b shift
+-acute 0x2b altgr
+-multiply 0x2b shift altgr
+-guillemotleft 0x2c altgr
+-guillemotright 0x2d altgr
+-copyright 0x2e altgr
+-leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
+-rightdoublequotemark 0x30 altgr
+-apostrophe 0x30 shift altgr
++dead_caron 0x2b altgr
++dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++ezh 0x2c altgr
++EZH 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++multiply 0x2d altgr
++periodcentered 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++eng 0x31 altgr
++ENG 0x31 shift altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+-masculine 0x32 shift altgr
++emdash 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+-dead_cedilla 0x33 altgr
+-dead_ogonek 0x33 shift altgr
++rightsinglequotemark 0x33 altgr
++leftsinglequotemark 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+-periodcentered 0x34 altgr
++dead_belowdot 0x34 altgr
+ dead_abovedot 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+-hyphen 0x35 altgr
+-macron 0x35 shift altgr
++endash 0x35 altgr
++dead_belowcomma 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
+ nobreakspace 0x39 altgr
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/fo b/pc-bios/keymaps/fo
+index c00d9d4..e69575b 100644
+--- a/pc-bios/keymaps/fo
++++ b/pc-bios/keymaps/fo
+@@ -1,76 +1,837 @@
+-map 0x438
+-include common
+-
+-#
+-# Top row
+ #
+-onehalf 0x29
+-section 0x29 shift
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : fo
++#    variant : -
++#    options : -
+ 
+-# 1
+-exclam 0x2 shift
+-
+-# 2
+-quotedbl 0x3 shift
+-at 0x3 altgr
+-
+-# 3
+-numbersign 0x4 shift
+-sterling 0x4 altgr
+-# 4
+-currency 0x5 shift
+-dollar 0x5 altgr
+-# 5
+-percent 0x6 shift
+-# 6
+-ampersand 0x7 shift
+-# 7
+-slash 0x8 shift
+-braceleft 0x8 altgr
+-# 8
+-parenleft 0x9 shift
+-bracketleft 0x9 altgr
+-# 9
+-parenright 0xa shift
+-bracketright 0xa altgr
+-# 0
+-equal 0xb shift
+-braceright 0xb altgr
+-
+-plus 0xc
+-question 0xc shift
+-plusminus 0xc altgr
+-
+-bar 0xd altgr
+-dead_acute 0xd
++# name: "Faroese"
+ 
+-#
+-# QWERTY first row
+-#
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
++exclam 0x02 shift
++exclamdown 0x02 altgr
++onesuperior 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
++quotedbl 0x03 shift
++at 0x03 altgr
++twosuperior 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
++numbersign 0x04 shift
++sterling 0x04 altgr
++threesuperior 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
++currency 0x05 shift
++dollar 0x05 altgr
++onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
++percent 0x06 shift
++onehalf 0x06 altgr
++cent 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
++ampersand 0x07 shift
++yen 0x07 altgr
++fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
++slash 0x08 shift
++braceleft 0x08 altgr
++division 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
++parenleft 0x09 shift
++bracketleft 0x09 altgr
++guillemotleft 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
++parenright 0x0a shift
++bracketright 0x0a altgr
++guillemotright 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
++equal 0x0b shift
++braceright 0x0b altgr
++degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++plus 0x0c
++question 0x0c shift
++plusminus 0x0c altgr
++questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++dead_acute 0x0d
++dead_grave 0x0d shift
++bar 0x0d altgr
++brokenbar 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
++Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++registered 0x13 altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++thorn 0x14 altgr
++THORN 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++leftarrow 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++downarrow 0x16 altgr
++uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++rightarrow 0x17 altgr
++idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oe 0x18 altgr
++OE 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++thorn 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ aring 0x1a
+ Aring 0x1a shift
+-eth 0x1b addupper
+-asciitilde 0x1b altgr
++dead_diaeresis 0x1a altgr
++dead_circumflex 0x1a shift altgr
+ 
+-#
+-# QWERTY second row
+-#
+-ae 0x27 addupper
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++eth 0x1b
++ETH 0x1b shift
++dead_tilde 0x1b altgr
++dead_caron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++ordfeminine 0x1e altgr
++masculine 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++eth 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++dstroke 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++eng 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++hstroke 0x23 altgr
++Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++ae 0x27
++AE 0x27 shift
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ oslash 0x28
+-Ooblique 0x28 shift
++Oslash 0x28 shift
++dead_circumflex 0x28 altgr
++dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++onehalf 0x29
++section 0x29 shift
++threequarters 0x29 altgr
++paragraph 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ apostrophe 0x2b
+ asterisk 0x2b shift
++dead_doubleacute 0x2b altgr
++multiply 0x2b shift altgr
+ 
+-#
+-# QWERTY third row
+-#
+-less 0x56
+-greater 0x56 shift
+-backslash 0x56 altgr
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++copyright 0x2e altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++mu 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
++dead_cedilla 0x33 altgr
++dead_ogonek 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
++periodcentered 0x34 altgr
++dead_abovedot 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
++hyphen 0x35 altgr
++macron 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++nobreakspace 0x39 altgr
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++backslash 0x56 altgr
++notsign 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/fr b/pc-bios/keymaps/fr
+index ba5a176..5b25227 100644
+--- a/pc-bios/keymaps/fr
++++ b/pc-bios/keymaps/fr
+@@ -1,181 +1,837 @@
+-include common
+-map 0x40c
+ #
+-# Top row
+-#
+-twosuperior 0x29
+-notsign 0x29 altgr
+-
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : fr
++#    variant : -
++#    options : -
++
++# name: "French"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
+ ampersand 0x02
+ 1 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
+ 
++# evdev 3 (0x3), QKeyCode "2", number 0x3
+ eacute 0x03
+ 2 0x03 shift
+ asciitilde 0x03 altgr
+ oneeighth 0x03 shift altgr
+ 
++# evdev 4 (0x4), QKeyCode "3", number 0x4
+ quotedbl 0x04
+ 3 0x04 shift
+ numbersign 0x04 altgr
++sterling 0x04 shift altgr
+ 
++# evdev 5 (0x5), QKeyCode "4", number 0x5
+ apostrophe 0x05
+ 4 0x05 shift
+ braceleft 0x05 altgr
++dollar 0x05 shift altgr
+ 
++# evdev 6 (0x6), QKeyCode "5", number 0x6
+ parenleft 0x06
+ 5 0x06 shift
+ bracketleft 0x06 altgr
+ threeeighths 0x06 shift altgr
+ 
++# evdev 7 (0x7), QKeyCode "6", number 0x7
+ minus 0x07
+ 6 0x07 shift
+ bar 0x07 altgr
+ fiveeighths 0x07 shift altgr
+ 
++# evdev 8 (0x8), QKeyCode "7", number 0x8
+ egrave 0x08
+ 7 0x08 shift
+ grave 0x08 altgr
+ seveneighths 0x08 shift altgr
+ 
++# evdev 9 (0x9), QKeyCode "8", number 0x9
+ underscore 0x09
+ 8 0x09 shift
+ backslash 0x09 altgr
+ trademark 0x09 shift altgr
+ 
++# evdev 10 (0xa), QKeyCode "9", number 0xa
+ ccedilla 0x0a
+ 9 0x0a shift
+ asciicircum 0x0a altgr
+ plusminus 0x0a shift altgr
+ 
++# evdev 11 (0xb), QKeyCode "0", number 0xb
+ agrave 0x0b
+ 0 0x0b shift
+ at 0x0b altgr
++degree 0x0b shift altgr
+ 
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ parenright 0x0c
+ degree 0x0c shift
+ bracketright 0x0c altgr
+ questiondown 0x0c shift altgr
+ 
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+ braceright 0x0d altgr
+ dead_ogonek 0x0d shift altgr
+ 
+-#
+-# AZERTY first row
+-#
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
+ 
+-a 0x10 addupper
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++a 0x10
++A 0x10 shift
+ ae 0x10 altgr
+ AE 0x10 shift altgr
+ 
+-z 0x11 addupper
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++z 0x11
++Z 0x11 shift
+ guillemotleft 0x11 altgr
++less 0x11 shift altgr
+ 
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++cent 0x12 shift altgr
+ 
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
+ 
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
+ 
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
+ 
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
+ 
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
+ 
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
+ 
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
+ 
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ dead_circumflex 0x1a
+ dead_diaeresis 0x1a shift
++dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
+ 
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dollar 0x1b
+ sterling 0x1b shift
+ currency 0x1b altgr
+ dead_macron 0x1b shift altgr
+ 
+-#
+-# AZERTY second row
+-#
+-q 0x1e addupper
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++q 0x1e
++Q 0x1e shift
++at 0x1e altgr
+ Greek_OMEGA 0x1e shift altgr
+ 
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
++section 0x1f shift altgr
+ 
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
+ 
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
+ 
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
+ 
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
+ 
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
+ 
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
+ 
+-m 0x27 addupper
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++m 0x27
++M 0x27 shift
++mu 0x27 altgr
+ masculine 0x27 shift altgr
+ 
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ ugrave 0x28
+ percent 0x28 shift
++dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
+ 
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++twosuperior 0x29
++asciitilde 0x29 shift
++notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ asterisk 0x2b
+ mu 0x2b shift
+ dead_grave 0x2b altgr
+ dead_breve 0x2b shift altgr
+ 
+-#
+-# AZERTY third row
+-#
+-less 0x56
+-greater 0x56 shift
+-
+-w 0x2c addupper
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++w 0x2c
++W 0x2c shift
++lstroke 0x2c altgr
++Lstroke 0x2c shift altgr
+ 
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
+ 
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
+ 
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
+ 
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
+ 
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
+ comma 0x32
+ question 0x32 shift
+ dead_acute 0x32 altgr
+ dead_doubleacute 0x32 shift altgr
+ 
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ semicolon 0x33
+ period 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
+ 
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ colon 0x34
+ slash 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
+ 
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ exclam 0x35
+ section 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/fr-be b/pc-bios/keymaps/fr-be
+index 62f7128..9d2ac5d 100644
+--- a/pc-bios/keymaps/fr-be
++++ b/pc-bios/keymaps/fr-be
+@@ -1,134 +1,836 @@
+-# generated from XKB map be
+-include common
+-map 0x80c
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : be
++#    variant : -
++#    options : -
++
++# name: "Belgian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
+ ampersand 0x02
+ 1 0x02 shift
+ bar 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
+ eacute 0x03
+ 2 0x03 shift
+ at 0x03 altgr
+ oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
+ quotedbl 0x04
+ 3 0x04 shift
+ numbersign 0x04 altgr
+ sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
+ apostrophe 0x05
+ 4 0x05 shift
+ onequarter 0x05 altgr
+ dollar 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
+ parenleft 0x06
+ 5 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
+ section 0x07
+ 6 0x07 shift
+ asciicircum 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
+ egrave 0x08
+ 7 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
+ exclam 0x09
+ 8 0x09 shift
+ bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
+ ccedilla 0x0a
+ 9 0x0a shift
+ braceleft 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
+ agrave 0x0b
+ 0 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ parenright 0x0c
+ degree 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ minus 0x0d
+ underscore 0x0d shift
+ dead_cedilla 0x0d altgr
+ dead_ogonek 0x0d shift altgr
+-a 0x10 addupper
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++a 0x10
++A 0x10 shift
++at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
+-z 0x11 addupper
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++z 0x11
++Z 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+ cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
+-oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oe 0x18 altgr
++OE 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ dead_circumflex 0x1a
+ dead_diaeresis 0x1a shift
+ bracketleft 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dollar 0x1b
+ asterisk 0x1b shift
+ bracketright 0x1b altgr
+ dead_macron 0x1b shift altgr
+-q 0x1e addupper
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++q 0x1e
++Q 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
+-m 0x27 addupper
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++m 0x27
++M 0x27 shift
+ dead_acute 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ ugrave 0x28
+ percent 0x28 shift
+ dead_acute 0x28 altgr
+ dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ twosuperior 0x29
+ threesuperior 0x29 shift
+ notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ mu 0x2b
+ sterling 0x2b shift
+ dead_grave 0x2b altgr
+ dead_breve 0x2b shift altgr
+-w 0x2c addupper
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++w 0x2c
++W 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
+ comma 0x32
+ question 0x32 shift
+ dead_cedilla 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ semicolon 0x33
+ period 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ colon 0x34
+ slash 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ equal 0x35
+ plus 0x35 shift
+ dead_tilde 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
+ backslash 0x56 altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/fr-ca b/pc-bios/keymaps/fr-ca
+index 13a0306..736897b 100644
+--- a/pc-bios/keymaps/fr-ca
++++ b/pc-bios/keymaps/fr-ca
+@@ -1,60 +1,768 @@
+-# Canadian French
+-# By Simon Germain
+-include common
+-map 0xc0c
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : ca
++#    variant : fr
++#    options : -
+ 
+-backslash 0x29 altgr
+-plusminus 0x2 altgr
+-at 0x3 altgr
+-sterling 0x4 altgr
+-cent 0x5 altgr
+-currency 0x6 altgr
+-notsign 0x7 altgr
+-numbersign 0x29
+-bar 0x29 shift
+-twosuperior 0x9 altgr
+-threesuperior 0xa altgr
+-onequarter 0xb altgr
+-onehalf 0xc altgr
+-threequarters 0xd altgr
++# name: "French (Canada)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
++exclam 0x02 shift
++plusminus 0x02 altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
++quotedbl 0x03 shift
++at 0x03 altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
++slash 0x04 shift
++sterling 0x04 altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
++dollar 0x05 shift
++cent 0x05 altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
++percent 0x06 shift
++currency 0x06 altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
++question 0x07 shift
++notsign 0x07 altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
++ampersand 0x08 shift
++brokenbar 0x08 altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
++asterisk 0x09 shift
++twosuperior 0x09 altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
++parenleft 0x0a shift
++threesuperior 0x0a altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
++parenright 0x0b shift
++onequarter 0x0b altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++minus 0x0c
++underscore 0x0c shift
++onehalf 0x0c altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++equal 0x0d
++plus 0x0d shift
++threequarters 0x0d altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ section 0x18 altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ paragraph 0x19 altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++dead_circumflex 0x1a
+ bracketleft 0x1a altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++dead_cedilla 0x1b
++dead_diaeresis 0x1b shift
+ bracketright 0x1b altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++semicolon 0x27
++colon 0x27 shift
+ asciitilde 0x27 altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++dead_grave 0x28
+ braceleft 0x28 altgr
+-braceright 0x2b altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++numbersign 0x29
++bar 0x29 shift
++backslash 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ less 0x2b
+ greater 0x2b shift
+-guillemotleft 0x56
+-guillemotright 0x56 shift
+-degree 0x56 altgr
++braceright 0x2b altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+-eacute 0x35
+-dead_acute 0x35 altgr
+-dead_grave 0x28
+-dead_circumflex 0x1a
+-dead_circumflex 0x1a shift
+-dead_cedilla 0x1b
+-dead_diaeresis 0x1b shift
+-exclam 0x2 shift
+-quotedbl 0x3 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ apostrophe 0x33 shift
++macron 0x33 altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+-period 0x34 shift
+-slash 0x4 shift
+-dollar 0x5 shift
+-percent 0x6 shift
+-question 0x7 shift
+-ampersand 0x8 shift
+-asterisk 0x9 shift
+-parenleft 0xa shift
+-parenright 0xb shift
+-underscore 0xc shift
+-minus 0xc
+-underscore 0xc shift
+-equal 0xd
+-plus 0xd shift
+-semicolon 0x27
+-colon 0x27 shift
++hyphen 0x34 altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++eacute 0x35
++Eacute 0x35 shift
++dead_acute 0x35 altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++nobreakspace 0x39 altgr
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++guillemotleft 0x56
++guillemotright 0x56 shift
++degree 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/fr-ch b/pc-bios/keymaps/fr-ch
+index 4620d20..40e1fef 100644
+--- a/pc-bios/keymaps/fr-ch
++++ b/pc-bios/keymaps/fr-ch
+@@ -1,114 +1,836 @@
+-# generated from XKB map fr_CH
+-include common
+-map 0x100c
+-exclam 0x02 shift
+-onesuperior 0x02 altgr
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : ch
++#    variant : fr
++#    options : -
++
++# name: "French (Switzerland)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
++plus 0x02 shift
++bar 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+-twosuperior 0x03 altgr
++at 0x03 altgr
+ oneeighth 0x03 shift altgr
+-section 0x04 shift
+-threesuperior 0x04 altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
++asterisk 0x04 shift
++numbersign 0x04 altgr
+ sterling 0x04 shift altgr
+-dollar 0x05 shift
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
++ccedilla 0x05 shift
+ onequarter 0x05 altgr
+-currency 0x05 shift altgr
++dollar 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-threequarters 0x07 altgr
++notsign 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+-braceleft 0x08 altgr
++bar 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+-bracketleft 0x09 altgr
++cent 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+-ssharp 0x0c
++degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++apostrophe 0x0c
+ question 0x0c shift
+-backslash 0x0c altgr
++dead_acute 0x0c altgr
+ questiondown 0x0c shift altgr
+-acute 0x0d
+-dead_acute 0x0d
+-grave 0x0d shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++dead_circumflex 0x0d
+ dead_grave 0x0d shift
+-dead_cedilla 0x0d altgr
++dead_tilde 0x0d altgr
+ dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
+-z 0x15 addupper
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++z 0x15
++Z 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
+-oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oe 0x18 altgr
++OE 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
+-udiaeresis 0x1a
+-Udiaeresis 0x1a shift
+-dead_diaeresis 0x1a altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++egrave 0x1a
++udiaeresis 0x1a shift
++bracketleft 0x1a altgr
+ dead_abovering 0x1a shift altgr
+-plus 0x1b
+-asterisk 0x1b shift
+-asciitilde 0x1b altgr
+-dead_tilde 0x1b altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++dead_diaeresis 0x1b
++exclam 0x1b shift
++bracketright 0x1b altgr
+ dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
+-odiaeresis 0x27
+-Odiaeresis 0x27 shift
+-dead_doubleacute 0x27 altgr
+-adiaeresis 0x28
+-Adiaeresis 0x28 shift
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++eacute 0x27
++odiaeresis 0x27 shift
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++agrave 0x28
++adiaeresis 0x28 shift
++braceleft 0x28 altgr
+ dead_caron 0x28 shift altgr
+-asciicircum 0x29
+-dead_circumflex 0x29
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++section 0x29
+ degree 0x29 shift
+ notsign 0x29 altgr
+-numbersign 0x2b
+-apostrophe 0x2b shift
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
++dollar 0x2b
++sterling 0x2b shift
++braceright 0x2b altgr
+ dead_breve 0x2b shift altgr
+-y 0x2c addupper
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++y 0x2c
++Y 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++backslash 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/hr b/pc-bios/keymaps/hr
+index 613aa69..6b89f09 100644
+--- a/pc-bios/keymaps/hr
++++ b/pc-bios/keymaps/hr
+@@ -1,125 +1,837 @@
+-# generated from XKB map hr
+-include common
+-map 0x41a
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : hr
++#    variant : -
++#    options : -
++
++# name: "Croatian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ asciitilde 0x02 altgr
+ dead_tilde 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ dead_caron 0x03 altgr
+ caron 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ asciicircum 0x04 altgr
+ dead_circumflex 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ dead_breve 0x05 altgr
+ breve 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ degree 0x06 altgr
+ dead_abovering 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+ dead_ogonek 0x07 altgr
+ ogonek 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ grave 0x08 altgr
+ dead_grave 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ dead_abovedot 0x09 altgr
+ abovedot 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ dead_acute 0x0a altgr
+ apostrophe 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ dead_doubleacute 0x0b altgr
+ doubleacute 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ apostrophe 0x0c
+ question 0x0c shift
+ dead_diaeresis 0x0c altgr
+ diaeresis 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ plus 0x0d
+ asterisk 0x0d shift
+ dead_cedilla 0x0d altgr
+ cedilla 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ backslash 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ bar 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
+-z 0x15 addupper
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++z 0x15
++Z 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ scaron 0x1a
+ Scaron 0x1a shift
+ division 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dstroke 0x1b
+ Dstroke 0x1b shift
+ multiply 0x1b altgr
+ dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
+-ssharp 0x1f altgr
+-section 0x1f shift altgr
+-eth 0x20 altgr
+-ETH 0x20 shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++doublelowquotemark 0x1f altgr
++guillemotright 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++leftdoublequotemark 0x20 altgr
++guillemotleft 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ bracketleft 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ bracketright 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ lstroke 0x25 altgr
+ ampersand 0x25 shift altgr
+-Lstroke 0x26 altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ccaron 0x27
+ Ccaron 0x27 shift
+ dead_acute 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ cacute 0x28
+ Cacute 0x28 shift
+ ssharp 0x28 altgr
+ dead_caron 0x28 shift altgr
+-dead_cedilla 0x29
+-dead_diaeresis 0x29 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++grave 0x29
++asciitilde 0x29 shift
+ notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ zcaron 0x2b
+ Zcaron 0x2b shift
+ currency 0x2b altgr
+ dead_breve 0x2b shift altgr
+-y 0x2c addupper
+-guillemotleft 0x2c altgr
+-less 0x2c shift altgr
+-guillemotright 0x2d altgr
+-greater 0x2d shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++y 0x2c
++Y 0x2c shift
++leftsinglequotemark 0x2c altgr
++guillemotright 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++rightsinglequotemark 0x2d altgr
++guillemotleft 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ at 0x2f altgr
+ grave 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ braceleft 0x30 altgr
+ apostrophe 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
+ braceright 0x31 altgr
+-section 0x32 altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++asciicircum 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+-horizconnector 0x33 altgr
++less 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+-periodcentered 0x34 altgr
++greater 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/hu b/pc-bios/keymaps/hu
+index 8aba444..a6bd66d 100644
+--- a/pc-bios/keymaps/hu
++++ b/pc-bios/keymaps/hu
+@@ -1,115 +1,836 @@
+-# Hungarian keyboard layout (QWERTZ)
+-# Created by: The NeverGone <never@delfin.klte.hu>
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : hu
++#    variant : -
++#    options : -
+ 
+-include common
+-map 0x40e
++# name: "Hungarian"
+ 
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
+ 
+-# AltGr keys:
+-notsign 0x29 altgr
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
++apostrophe 0x02 shift
+ asciitilde 0x02 altgr
+-caron 0x03 altgr
++dead_tilde 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
++quotedbl 0x03 shift
++dead_caron 0x03 altgr
++caron 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
++plus 0x04 shift
+ asciicircum 0x04 altgr
+-breve 0x05 altgr
+-degree 0x06 altgr
+-ogonek 0x07 altgr
++dead_circumflex 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
++exclam 0x05 shift
++dead_breve 0x05 altgr
++breve 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
++percent 0x06 shift
++dead_abovering 0x06 altgr
++degree 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
++slash 0x07 shift
++dead_ogonek 0x07 altgr
++ogonek 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
++equal 0x08 shift
+ grave 0x08 altgr
+-abovedot 0x09 altgr
+-acute 0x0a altgr
+-doubleacute 0x0b altgr
+-diaeresis 0x0c altgr
+-cedilla 0x0d altgr
++dead_grave 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
++parenleft 0x09 shift
++dead_abovedot 0x09 altgr
++abovedot 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
++parenright 0x0a shift
++dead_acute 0x0a altgr
++acute 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++odiaeresis 0x0b
++Odiaeresis 0x0b shift
++dead_doubleacute 0x0b altgr
++doubleacute 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++udiaeresis 0x0c
++Udiaeresis 0x0c shift
++dead_diaeresis 0x0c altgr
++diaeresis 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++oacute 0x0d
++Oacute 0x0d shift
++dead_cedilla 0x0d altgr
++cedilla 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ backslash 0x10 altgr
++Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ bar 0x11 altgr
+-EuroSign 0x12 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++Adiaeresis 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++paragraph 0x13 altgr
++registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++tslash 0x14 altgr
++Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++z 0x15
++Z 0x15 shift
++endash 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++EuroSign 0x16 altgr
++uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ Iacute 0x17 altgr
++iacute 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++doublelowquotemark 0x18 altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++rightdoublequotemark 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++odoubleacute 0x1a
++Odoubleacute 0x1a shift
+ division 0x1a altgr
++dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++uacute 0x1b
++Uacute 0x1b shift
+ multiply 0x1b altgr
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++adiaeresis 0x1e altgr
++Adiaeresis 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ dstroke 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ Dstroke 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ bracketleft 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ bracketright 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++hstroke 0x23 altgr
++Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
+ iacute 0x24 altgr
++Iacute 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ lstroke 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ Lstroke 0x26 altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++eacute 0x27
++Eacute 0x27 shift
+ dollar 0x27 altgr
++cent 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++aacute 0x28
++Aacute 0x28 shift
+ ssharp 0x28 altgr
++dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++0 0x29
++section 0x29 shift
++notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
++udoubleacute 0x2b
++Udoubleacute 0x2b shift
+ currency 0x2b altgr
+-less 0x56 altgr
++dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++y 0x2c
++Y 0x2c shift
+ greater 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ numbersign 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ ampersand 0x2e altgr
++copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ at 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ braceleft 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
+ braceright 0x31 altgr
+-semicolon 0x33 altgr
+-asterisk 0x35 altgr
+ 
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++less 0x32 altgr
++masculine 0x32 shift altgr
+ 
+-# Shift keys:
+-section 0x29 shift
+-apostrophe 0x02 shift
+-quotedbl 0x03 shift
+-plus 0x04 shift
+-exclam 0x05 shift
+-percent 0x06 shift
+-slash 0x07 shift
+-equal 0x08 shift
+-parenleft 0x09 shift
+-parenright 0x0a shift
+-Odiaeresis 0x0b shift
+-Udiaeresis 0x0c shift
+-Oacute 0x0d shift
+-Z 0x15 shift
+-Odoubleacute 0x1a shift
+-Uacute 0x1b shift
+-Eacute 0x27 shift
+-Aacute 0x28 shift
+-Udoubleacute 0x2b shift
+-Y 0x2c shift
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
++comma 0x33
+ question 0x33 shift
++semicolon 0x33 altgr
++multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
++period 0x34
+ colon 0x34 shift
++greater 0x34 altgr
++division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++minus 0x35
+ underscore 0x35 shift
+-F13 0x3b shift
+-F14 0x3c shift
+-F15 0x3d shift
+-F16 0x3e shift
+-F17 0x3f shift
+-F18 0x40 shift
+-F19 0x41 shift
+-F20 0x42 shift
+-F21 0x43 shift
+-F22 0x44 shift
+-F23 0x57 shift
+-F24 0x58 shift
+-
+-
+-# Ctrl keys:
+-F25 0x3b ctrl
+-F26 0x3c ctrl
+-F27 0x3d ctrl
+-F28 0x3e ctrl
+-F29 0x3f ctrl
+-F30 0x40 ctrl
+-F31 0x41 ctrl
+-F32 0x42 ctrl
+-F33 0x43 ctrl
+-F34 0x44 ctrl
+-F35 0x57 ctrl
+-#NoSymbol 0x58 ctrl
++asterisk 0x35 altgr
++dead_abovedot 0x35 shift altgr
+ 
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
+ 
+-0 0x29
+-odiaeresis 0x0b
+-udiaeresis 0x0c
+-oacute 0x0d
+-z 0x15
+-odoubleacute 0x1a
+-uacute 0x1b
+-eacute 0x27
+-aacute 0x28
+-udoubleacute 0x2b
+-y 0x2c
+-comma 0x33
+-period 0x34
+-minus 0x35
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++iacute 0x56
++Iacute 0x56 shift
++less 0x56 altgr
++greater 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/is b/pc-bios/keymaps/is
+index 935ac1d..063675d 100644
+--- a/pc-bios/keymaps/is
++++ b/pc-bios/keymaps/is
+@@ -1,139 +1,837 @@
+-# 2004-03-16 Halldór Guðmundsson and Morten Lange
+-# Keyboard definition file for the Icelandic keyboard
+-# to be used in rdesktop 1.3.x ( See rdesktop.org)
+-# generated from XKB map de, and changed manually
+-# Location for example /usr/local/share/rdesktop/keymaps/is
+-include common
+-map 0x40f
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : is
++#    variant : -
++#    options : -
++
++# name: "Icelandic"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ twosuperior 0x03 altgr
+ oneeighth 0x03 shift altgr
+-#section 0x04 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ threesuperior 0x04 altgr
+ sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ onequarter 0x05 altgr
+ currency 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-threequarters 0x07 altgr
++notsign 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+-#ssharp 0x0c
++degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ odiaeresis 0x0c
+-#question 0x0c shift
+ Odiaeresis 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
+-#acute 0x0d
+-minus  0x0d
+-#dead_acute 0x0d
+-#grave 0x0d shift
+-#dead_grave 0x0d shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++minus 0x0d
+ underscore 0x0d shift
+ dead_cedilla 0x0d altgr
+ dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
+-#z 0x15 addupper
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
+-#thorn 0x19 altgr
+-#THORN 0x19 shift altgr
+-#udiaeresis 0x1a
+-#Udiaeresis 0x1a shift
+-#dead_diaeresis 0x1a altgr
+-#dead_abovering 0x1a shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++thorn 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ eth 0x1a
+ ETH 0x1a shift
++dead_diaeresis 0x1a altgr
++dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ apostrophe 0x1b
+ question 0x1b shift
+-#plus 0x1b
+-#asterisk 0x1b shift
+ asciitilde 0x1b altgr
+-#grave 0x1b altgr
+-#dead_tilde 0x1b altgr
+-#dead_macron 0x1b shift altgr
+-#ae 0x1e altgr
+-#AE 0x1e shift altgr
+-#eth 0x20 altgr
+-#eth 0x20
+-#ETH 0x20 shift altgr
+-#ETH 0x20 shift
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++ae 0x1e altgr
++AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++U201E 0x20 altgr
++U201C 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
+-#adiaeresis 0x27
+-#Adiaeresis 0x27 shift
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ae 0x27
+ AE 0x27 shift
+-dead_doubleacute 0x27 altgr
+-#adiaeresis 0x28
+-#Adiaeresis 0x28 shift
+-#dead_caron 0x28 shift altgr
+-#asciicircum 0x29
+-acute  0x28
++asciicircum 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ dead_acute 0x28
+-#dead_circumflex 0x29
+-#degree 0x29 shift
+-#notsign 0x29 altgr
++dead_circumflex 0x28 altgr
++dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++dead_abovering 0x29
++dead_diaeresis 0x29 shift
++notsign 0x29 altgr
++hyphen 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ plus 0x2b
+ asterisk 0x2b shift
+ grave 0x2b altgr
+-#numbersign 0x2b
+-#apostrophe 0x2b shift
+-#dead_breve 0x2b shift altgr
+-#y 0x2c addupper
++dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
+-#minus 0x35
+-#underscore 0x35 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ thorn 0x35
+ THORN 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/it b/pc-bios/keymaps/it
+index 00ca73a..abc3ed1 100644
+--- a/pc-bios/keymaps/it
++++ b/pc-bios/keymaps/it
+@@ -1,115 +1,840 @@
+-# generated from XKB map it
+-include common
+-map 0x410
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : it
++#    variant : -
++#    options : -
++
++# name: "Italian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ twosuperior 0x03 altgr
+-oneeighth 0x03 shift altgr
++dead_doubleacute 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ sterling 0x04 shift
+ threesuperior 0x04 altgr
++dead_tilde 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ onequarter 0x05 altgr
++oneeighth 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-threequarters 0x07 altgr
++notsign 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
++bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
++bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+-degree 0x0b shift altgr
++dead_ogonek 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ apostrophe 0x0c
+ question 0x0c shift
+ grave 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ igrave 0x0d
+ asciicircum 0x0d shift
+ asciitilde 0x0d altgr
+-dead_ogonek 0x0d shift altgr
++dead_circumflex 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+ cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ egrave 0x1a
+ eacute 0x1a shift
+ bracketleft 0x1a altgr
+-dead_abovering 0x1a shift altgr
++braceleft 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ plus 0x1b
+ asterisk 0x1b shift
+ bracketright 0x1b altgr
+-dead_macron 0x1b shift altgr
++braceright 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
+ section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ograve 0x27
+ ccedilla 0x27 shift
+ at 0x27 altgr
+-dead_doubleacute 0x27 shift altgr
++dead_cedilla 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ agrave 0x28
+ degree 0x28 shift
+ numbersign 0x28 altgr
++dead_abovering 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ backslash 0x29
+ bar 0x29 shift
+ notsign 0x29 altgr
++brokenbar 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ ugrave 0x2b
+ section 0x2b shift
+ dead_grave 0x2b altgr
+ dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++ntilde 0x31 altgr
++Ntilde 0x31 shift altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+-horizconnector 0x33 altgr
++dead_acute 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+ periodcentered 0x34 altgr
+-division 0x34 shift altgr
++dead_diaeresis 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+-dead_belowdot 0x35 altgr
+-dead_abovedot 0x35 shift altgr
++dead_macron 0x35 altgr
++division 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++guillemotleft 0x56 altgr
++guillemotright 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/ja b/pc-bios/keymaps/ja
+index 9d90a78..aae93e8 100644
+--- a/pc-bios/keymaps/ja
++++ b/pc-bios/keymaps/ja
+@@ -1,109 +1,751 @@
+-# generated from XKB map jp106
+-include common
+-map 0x411
++#
++# generated by qemu-keymap
++#    model   : jp106
++#    layout  : jp
++#    variant : -
++#    options : -
++
++# name: "Japanese"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+-kana_NU 0x02 altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+-kana_FU 0x03 altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+-kana_A 0x04 altgr
+-kana_a 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+-kana_U 0x05 altgr
+-kana_u 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+-kana_E 0x06 altgr
+-kana_e 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-kana_O 0x07 altgr
+-kana_o 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ apostrophe 0x08 shift
+-kana_YA 0x08 altgr
+-kana_ya 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+-kana_YU 0x09 altgr
+-kana_yu 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+-kana_YO 0x0a altgr
+-kana_yo 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ asciitilde 0x0b shift
+-kana_WA 0x0b altgr
+-kana_WO 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ equal 0x0c shift
+-kana_HO 0x0c altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ asciicircum 0x0d
+ asciitilde 0x0d shift
+-kana_HE 0x0d altgr
+-kana_TA 0x10 altgr
+-kana_TE 0x11 altgr
+-kana_I 0x12 altgr
+-kana_i 0x12 shift altgr
+-kana_SU 0x13 altgr
+-kana_KA 0x14 altgr
+-kana_N 0x15 altgr
+-kana_NA 0x16 altgr
+-kana_NI 0x17 altgr
+-kana_RA 0x18 altgr
+-kana_SE 0x19 altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ at 0x1a
+ grave 0x1a shift
+-voicedsound 0x1a altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketleft 0x1b
+ braceleft 0x1b shift
+-semivoicedsound 0x1b altgr
+-kana_openingbracket 0x1b shift altgr
+-kana_CHI 0x1e altgr
+-kana_TO 0x1f altgr
+-kana_SHI 0x20 altgr
+-kana_HA 0x21 altgr
+-kana_KI 0x22 altgr
+-kana_KU 0x23 altgr
+-kana_MA 0x24 altgr
+-kana_NO 0x25 altgr
+-kana_RI 0x26 altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ semicolon 0x27
+ plus 0x27 shift
+-kana_RE 0x27 altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ colon 0x28
+ asterisk 0x28 shift
+-kana_KE 0x28 altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ Zenkaku_Hankaku 0x29
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ bracketright 0x2b
+ braceright 0x2b shift
+-kana_MU 0x2b altgr
+-kana_closingbracket 0x2b shift altgr
+-kana_TSU 0x2c altgr
+-kana_tsu 0x2c shift altgr
+-kana_SA 0x2d altgr
+-kana_SO 0x2e altgr
+-kana_HI 0x2f altgr
+-kana_KO 0x30 altgr
+-kana_MI 0x31 altgr
+-kana_MO 0x32 altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
+-kana_NE 0x33 altgr
+-kana_comma 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
+-kana_RU 0x34 altgr
+-kana_fullstop 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
+-kana_ME 0x35 altgr
+-kana_conjunctive 0x35 shift altgr
+-Eisu_toggle 0x3a shift
+-Execute 0x54 shift
+-Kanji 0x70
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Eisu_toggle 0x3a
++Caps_Lock 0x3a shift
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
+ backslash 0x73
+-yen 0x7d
+-bar 0x7d shift
+ underscore 0x73 shift
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
+ Henkan_Mode 0x79
+-Katakana_Real 0x70
+-Katakana 0x70
+-Muhenkan 0x7b
+-Henkan_Mode_Real 0x79
+-Henkan_Mode_Ultra 0x79
+-backslash_ja 0x73
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++backslash 0x7d
++bar 0x7d shift
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/lt b/pc-bios/keymaps/lt
+index 3d9d619..4101367 100644
+--- a/pc-bios/keymaps/lt
++++ b/pc-bios/keymaps/lt
+@@ -1,57 +1,835 @@
+-# generated from XKB map lt
+-include common
+-map 0x427
+-exclam 0x02 shift
+-aogonek 0x02 altgr
+-Aogonek 0x02 shift altgr
+-at 0x03 shift
+-ccaron 0x03 altgr
+-Ccaron 0x03 shift altgr
+-numbersign 0x04 shift
+-eogonek 0x04 altgr
+-Eogonek 0x04 shift altgr
+-dollar 0x05 shift
+-eabovedot 0x05 altgr
+-Eabovedot 0x05 shift altgr
+-percent 0x06 shift
+-iogonek 0x06 altgr
+-Iogonek 0x06 shift altgr
+-asciicircum 0x07 shift
+-scaron 0x07 altgr
+-Scaron 0x07 shift altgr
+-ampersand 0x08 shift
+-uogonek 0x08 altgr
+-Uogonek 0x08 shift altgr
+-asterisk 0x09 shift
+-umacron 0x09 altgr
+-Umacron 0x09 shift altgr
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : lt
++#    variant : -
++#    options : -
++
++# name: "Lithuanian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++aogonek 0x02
++Aogonek 0x02 shift
++1 0x02 altgr
++exclam 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++ccaron 0x03
++Ccaron 0x03 shift
++2 0x03 altgr
++at 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++eogonek 0x04
++Eogonek 0x04 shift
++3 0x04 altgr
++numbersign 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++eabovedot 0x05
++Eabovedot 0x05 shift
++4 0x05 altgr
++dollar 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++iogonek 0x06
++Iogonek 0x06 shift
++5 0x06 altgr
++percent 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++scaron 0x07
++Scaron 0x07 shift
++6 0x07 altgr
++asciicircum 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++uogonek 0x08
++Uogonek 0x08 shift
++7 0x08 altgr
++ampersand 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++umacron 0x09
++Umacron 0x09 shift
++8 0x09 altgr
++asterisk 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++doublelowquotemark 0x0a
+ parenleft 0x0a shift
+-doublelowquotemark 0x0a altgr
++9 0x0a altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++leftdoublequotemark 0x0b
+ parenright 0x0b shift
+-leftdoublequotemark 0x0b altgr
++0 0x0b altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
+-equal 0x0d
+-plus 0x0d shift
+-zcaron 0x0d altgr
+-Zcaron 0x0d shift altgr
++endash 0x0c altgr
++questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++zcaron 0x0d
++Zcaron 0x0d shift
++equal 0x0d altgr
++plus 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
++Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
++EuroSign 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++paragraph 0x13 altgr
++registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++tslash 0x14 altgr
++Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++leftarrow 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++downarrow 0x16 altgr
++uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++rightarrow 0x17 altgr
++idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oslash 0x18 altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++thorn 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ bracketleft 0x1a
+ braceleft 0x1a shift
++dead_diaeresis 0x1a altgr
++dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketright 0x1b
+ braceright 0x1b shift
++dead_tilde 0x1b altgr
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++ae 0x1e altgr
++AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++eth 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++dstroke 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++eng 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++hstroke 0x23 altgr
++Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ semicolon 0x27
+ colon 0x27 shift
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ apostrophe 0x28
+ quotedbl 0x28 shift
++dead_circumflex 0x28 altgr
++dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ grave 0x29
+ asciitilde 0x29 shift
++acute 0x29 altgr
++notsign 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ backslash 0x2b
+ bar 0x2b shift
++dead_grave 0x2b altgr
++dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++cent 0x2e altgr
++copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++mu 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
++horizconnector 0x33 altgr
++multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
++periodcentered 0x34 altgr
++division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
++dead_belowdot 0x35 altgr
++dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
+ endash 0x56
+ EuroSign 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/lv b/pc-bios/keymaps/lv
+index 1d91727..27260ce 100644
+--- a/pc-bios/keymaps/lv
++++ b/pc-bios/keymaps/lv
+@@ -1,128 +1,810 @@
+-# generated from XKB map lv
+-include common
+-map 0x426
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : lv
++#    variant : -
++#    options : -
++
++# name: "Latvian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ at 0x03 shift
+ twosuperior 0x03 altgr
+ oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ threesuperior 0x04 altgr
+ sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ EuroSign 0x05 altgr
+ cent 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ asciicircum 0x07 shift
+ threequarters 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
+ bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+-dead_cedilla 0x0d altgr
+-dead_ogonek 0x0d shift altgr
+-at 0x10 altgr
+-Greek_OMEGA 0x10 shift altgr
+-lstroke 0x11 altgr
+-Lstroke 0x11 shift altgr
++endash 0x0d altgr
++emdash 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ emacron 0x12 altgr
+ Emacron 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ rcedilla 0x13 altgr
+ Rcedilla 0x13 shift altgr
+-tslash 0x14 altgr
+-Tslash 0x14 shift altgr
+-leftarrow 0x15 altgr
+-yen 0x15 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ umacron 0x16 altgr
+ Umacron 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ imacron 0x17 altgr
+ Imacron 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ omacron 0x18 altgr
+ Omacron 0x18 shift altgr
+-thorn 0x19 altgr
+-THORN 0x19 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ bracketleft 0x1a
+ braceleft 0x1a shift
+-dead_diaeresis 0x1a altgr
+-dead_abovering 0x1a shift altgr
++guillemotleft 0x1a altgr
++leftdoublequotemark 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketright 0x1b
+ braceright 0x1b shift
+-dead_tilde 0x1b altgr
+-dead_macron 0x1b shift altgr
+-ISO_Next_Group 0x1c shift
++guillemotright 0x1b altgr
++rightdoublequotemark 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ amacron 0x1e altgr
+ Amacron 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ scaron 0x1f altgr
+ Scaron 0x1f shift altgr
+-eth 0x20 altgr
+-ETH 0x20 shift altgr
+-dstroke 0x21 altgr
+-ordfeminine 0x21 shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ gcedilla 0x22 altgr
+ Gcedilla 0x22 shift altgr
+-hstroke 0x23 altgr
+-Hstroke 0x23 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kcedilla 0x25 altgr
+ Kcedilla 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lcedilla 0x26 altgr
+ Lcedilla 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ semicolon 0x27
+ colon 0x27 shift
+-dead_acute 0x27 altgr
+-dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ apostrophe 0x28
+ quotedbl 0x28 shift
+ leftdoublequotemark 0x28 altgr
+ doublelowquotemark 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ grave 0x29
+ asciitilde 0x29 shift
+-notsign 0x29 altgr
++acute 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ backslash 0x2b
+ bar 0x2b shift
+-dead_grave 0x2b altgr
+-dead_breve 0x2b shift altgr
++grave 0x2b altgr
++breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ zcaron 0x2c altgr
+ Zcaron 0x2c shift altgr
+-guillemotright 0x2d altgr
+-greater 0x2d shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ ccaron 0x2e altgr
+ Ccaron 0x2e shift altgr
+-leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
+-rightdoublequotemark 0x30 altgr
+-apostrophe 0x30 shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
+ ncedilla 0x31 altgr
+ Ncedilla 0x31 shift altgr
+-mu 0x32 altgr
+-masculine 0x32 shift altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
+-dead_belowdot 0x35 altgr
+-dead_abovedot 0x35 shift altgr
+-nobreakspace 0x39 altgr
++abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/mk b/pc-bios/keymaps/mk
+index 18c1504..30a597c 100644
+--- a/pc-bios/keymaps/mk
++++ b/pc-bios/keymaps/mk
+@@ -1,101 +1,747 @@
+-# generated from XKB map mk
+-include common
+-map 0x42f
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : mk
++#    variant : -
++#    options : -
++
++# name: "Macedonian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+-at 0x03 shift
+-doublelowquotemark 0x03 shift altgr
+-numbersign 0x04 shift
+-leftdoublequotemark 0x04 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
++doublelowquotemark 0x03 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
++leftdoublequotemark 0x04 shift
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ asciicircum 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+-Cyrillic_lje 0x10 altgr
+-Cyrillic_LJE 0x10 shift altgr
+-Cyrillic_nje 0x11 altgr
+-Cyrillic_NJE 0x11 shift altgr
+-Cyrillic_ie 0x12 altgr
+-Cyrillic_IE 0x12 shift altgr
+-Cyrillic_er 0x13 altgr
+-Cyrillic_ER 0x13 shift altgr
+-Cyrillic_te 0x14 altgr
+-Cyrillic_TE 0x14 shift altgr
+-Macedonia_dse 0x15 altgr
+-Macedonia_DSE 0x15 shift altgr
+-Cyrillic_u 0x16 altgr
+-Cyrillic_U 0x16 shift altgr
+-Cyrillic_i 0x17 altgr
+-Cyrillic_I 0x17 shift altgr
+-Cyrillic_o 0x18 altgr
+-Cyrillic_O 0x18 shift altgr
+-Cyrillic_pe 0x19 altgr
+-Cyrillic_PE 0x19 shift altgr
+-bracketleft 0x1a
+-braceleft 0x1a shift
+-Cyrillic_sha 0x1a altgr
+-Cyrillic_SHA 0x1a shift altgr
+-bracketright 0x1b
+-braceright 0x1b shift
+-Macedonia_gje 0x1b altgr
+-Macedonia_GJE 0x1b shift altgr
+-Cyrillic_a 0x1e altgr
+-Cyrillic_A 0x1e shift altgr
+-Cyrillic_es 0x1f altgr
+-Cyrillic_ES 0x1f shift altgr
+-Cyrillic_de 0x20 altgr
+-Cyrillic_DE 0x20 shift altgr
+-Cyrillic_ef 0x21 altgr
+-Cyrillic_EF 0x21 shift altgr
+-Cyrillic_ghe 0x22 altgr
+-Cyrillic_GHE 0x22 shift altgr
+-Cyrillic_ha 0x23 altgr
+-Cyrillic_HA 0x23 shift altgr
+-Cyrillic_je 0x24 altgr
+-Cyrillic_JE 0x24 shift altgr
+-Cyrillic_ka 0x25 altgr
+-Cyrillic_KA 0x25 shift altgr
+-Cyrillic_el 0x26 altgr
+-Cyrillic_EL 0x26 shift altgr
+-semicolon 0x27
+-colon 0x27 shift
+-Cyrillic_che 0x27 altgr
+-Cyrillic_CHE 0x27 shift altgr
+-apostrophe 0x28
+-quotedbl 0x28 shift
+-Macedonia_kje 0x28 altgr
+-Macedonia_KJE 0x28 shift altgr
+-grave 0x29
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++Cyrillic_lje 0x10
++Cyrillic_LJE 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++Cyrillic_nje 0x11
++Cyrillic_NJE 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++Cyrillic_ie 0x12
++Cyrillic_IE 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++Cyrillic_er 0x13
++Cyrillic_ER 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++Cyrillic_te 0x14
++Cyrillic_TE 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++Macedonia_dse 0x15
++Macedonia_DSE 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++Cyrillic_u 0x16
++Cyrillic_U 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++Cyrillic_i 0x17
++Cyrillic_I 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++Cyrillic_o 0x18
++Cyrillic_O 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++Cyrillic_pe 0x19
++Cyrillic_PE 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++Cyrillic_sha 0x1a
++Cyrillic_SHA 0x1a shift
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++Macedonia_gje 0x1b
++Macedonia_GJE 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++Cyrillic_a 0x1e
++Cyrillic_A 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++Cyrillic_es 0x1f
++Cyrillic_ES 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++Cyrillic_de 0x20
++Cyrillic_DE 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++Cyrillic_ef 0x21
++Cyrillic_EF 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++Cyrillic_ghe 0x22
++Cyrillic_GHE 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++Cyrillic_ha 0x23
++Cyrillic_HA 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++Cyrillic_je 0x24
++Cyrillic_JE 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++Cyrillic_ka 0x25
++Cyrillic_KA 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++Cyrillic_el 0x26
++Cyrillic_EL 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++Cyrillic_che 0x27
++Cyrillic_CHE 0x27 shift
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++Macedonia_kje 0x28
++Macedonia_KJE 0x28 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++dead_grave 0x29
+ asciitilde 0x29 shift
+-backslash 0x2b
+-bar 0x2b shift
+-Cyrillic_zhe 0x2b altgr
+-Cyrillic_ZHE 0x2b shift altgr
+-Cyrillic_ze 0x2c altgr
+-Cyrillic_ZE 0x2c shift altgr
+-Cyrillic_dzhe 0x2d altgr
+-Cyrillic_DZHE 0x2d shift altgr
+-Cyrillic_tse 0x2e altgr
+-Cyrillic_TSE 0x2e shift altgr
+-Cyrillic_ve 0x2f altgr
+-Cyrillic_VE 0x2f shift altgr
+-Cyrillic_be 0x30 altgr
+-Cyrillic_BE 0x30 shift altgr
+-Cyrillic_en 0x31 altgr
+-Cyrillic_EN 0x31 shift altgr
+-Cyrillic_em 0x32 altgr
+-Cyrillic_EM 0x32 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
++Cyrillic_zhe 0x2b
++Cyrillic_ZHE 0x2b shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++Cyrillic_ze 0x2c
++Cyrillic_ZE 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++Cyrillic_dzhe 0x2d
++Cyrillic_DZHE 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++Cyrillic_tse 0x2e
++Cyrillic_TSE 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++Cyrillic_ve 0x2f
++Cyrillic_VE 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++Cyrillic_be 0x30
++Cyrillic_BE 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++Cyrillic_en 0x31
++Cyrillic_EN 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++Cyrillic_em 0x32
++Cyrillic_EM 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+-less 0x33 shift
+-semicolon 0x33 shift altgr
++semicolon 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+-greater 0x34 shift
+-colon 0x34 shift altgr
++colon 0x34 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/nl b/pc-bios/keymaps/nl
+index b4892f9..ae7c8f5 100644
+--- a/pc-bios/keymaps/nl
++++ b/pc-bios/keymaps/nl
+@@ -1,59 +1,837 @@
+-# Dutch (Netherlands)
+-include common
+-map 0x413
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : nl
++#    variant : -
++#    options : -
+ 
++# name: "Dutch"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+-quotebl 0x03 shift
++exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
++quotedbl 0x03 shift
+ twosuperior 0x03 altgr
++oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ threesuperior 0x04 altgr
++sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ onequarter 0x05 altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
++threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+ threequarters 0x07 altgr
++fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ underscore 0x08 shift
+ sterling 0x08 altgr
++seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ braceleft 0x09 altgr
++bracketleft 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ braceright 0x0a altgr
++bracketright 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ apostrophe 0x0b shift
++degree 0x0b altgr
++trademark 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ slash 0x0c
+ question 0x0c shift
+ backslash 0x0c altgr
++questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ degree 0x0d
+ dead_tilde 0x0d shift
+ dead_cedilla 0x0d altgr
++dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
++Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++lstroke 0x11 altgr
++Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
++registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++thorn 0x14 altgr
++THORN 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++ydiaeresis 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++udiaeresis 0x16 altgr
++Udiaeresis 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++idiaeresis 0x17 altgr
++Idiaeresis 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++ograve 0x18 altgr
++Ograve 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++paragraph 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ dead_diaeresis 0x1a
+ dead_circumflex 0x1a shift
++asciitilde 0x1a altgr
++asciicircum 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ asterisk 0x1b
+ bar 0x1b shift
++dead_tilde 0x1b altgr
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++aacute 0x1e altgr
++Aacute 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++eth 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++ordfeminine 0x21 altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++eng 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++hstroke 0x23 altgr
++Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ plus 0x27
+ plusminus 0x27 shift
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ dead_acute 0x28
+ dead_grave 0x28 shift
++apostrophe 0x28 altgr
++grave 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ at 0x29
+ section 0x29 shift
+ notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ less 0x2b
+ greater 0x2b shift
++dead_grave 0x2b altgr
++dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
+-copyright 0x2e altgr
+-mu 0x32 altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
++cent 0x2e altgr
++copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++ntilde 0x31 altgr
++Ntilde 0x31 shift altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
++Greek_mu 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
++cedilla 0x33 altgr
++guillemotleft 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+ periodcentered 0x34 altgr
+-hyphen 0x35
++guillemotright 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++minus 0x35
+ equal 0x35 shift
++hyphen 0x35 altgr
++dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
+ bracketright 0x56
+ bracketleft 0x56 shift
+-brokenbar 0x56 altgr
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/no b/pc-bios/keymaps/no
+index 40a6479..8afd199 100644
+--- a/pc-bios/keymaps/no
++++ b/pc-bios/keymaps/no
+@@ -1,119 +1,851 @@
+-# generated from XKB map no
+-include common
+-map 0x414
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : no
++#    variant : -
++#    options : -
++
++# name: "Norwegian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ exclamdown 0x02 altgr
+ onesuperior 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ at 0x03 altgr
+ twosuperior 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ sterling 0x04 altgr
+ threesuperior 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ currency 0x05 shift
+ dollar 0x05 altgr
+ onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+-cent 0x06 shift altgr
++U2030 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+ yen 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+ division 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+ guillemotleft 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ guillemotright 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ plus 0x0c
+ question 0x0c shift
+ plusminus 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ backslash 0x0d
+ dead_grave 0x0d shift
+ dead_acute 0x0d altgr
+ notsign 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+ cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ registered 0x13 altgr
++trademark 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ thorn 0x14 altgr
+ THORN 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oe 0x18 altgr
+ OE 0x18 shift altgr
+-thorn 0x19 altgr
+-THORN 0x19 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++Greek_pi 0x19 altgr
++Greek_PI 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ aring 0x1a
+ Aring 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dead_diaeresis 0x1b
+ dead_circumflex 0x1b shift
+-asciicircum 0x01b shift
+ dead_tilde 0x1b altgr
+-asciitilde 0x1b altgr
+ dead_caron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ordfeminine 0x1e altgr
+ masculine 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
+ section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ oslash 0x27
+-Ooblique 0x27 shift
++Oslash 0x27 shift
++dead_acute 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ ae 0x28
+ AE 0x28 shift
++dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ bar 0x29
+ section 0x29 shift
+ brokenbar 0x29 altgr
+ paragraph 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ apostrophe 0x2b
+ asterisk 0x2b shift
++dead_doubleacute 0x2b altgr
+ multiply 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ copyright 0x2e altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+ dead_cedilla 0x33 altgr
+ dead_ogonek 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+-periodcentered 0x34 altgr
+-dead_abovedot 0x34 shift altgr
++ellipsis 0x34 altgr
++periodcentered 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+-hyphen 0x35 altgr
+-macron 0x35 shift altgr
++endash 0x35 altgr
++emdash 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++U22C5 0x37 shift
++0x010000d7 0x37 altgr
++VoidSymbol 0x37 shift altgr
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
+ nobreakspace 0x39 altgr
++U202F 0x39 shift altgr
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++U2212 0x4a shift
++U2212 0x4a altgr
++VoidSymbol 0x4a shift altgr
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++0x0100002b 0x4e shift
++0x0100002b 0x4e altgr
++VoidSymbol 0x4e shift altgr
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
+ onehalf 0x56 altgr
+ threequarters 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++U2215 0xb5 shift
++0x010000f7 0xb5 altgr
++VoidSymbol 0xb5 shift altgr
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/pl b/pc-bios/keymaps/pl
+index 09c600d..df27206 100644
+--- a/pc-bios/keymaps/pl
++++ b/pc-bios/keymaps/pl
+@@ -1,122 +1,841 @@
+-# generated from XKB map pl
+-include common
+-map 0x415
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : pl
++#    variant : -
++#    options : -
++
++# name: "Polish"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+-onesuperior 0x02 altgr
++notequal 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ at 0x03 shift
+ twosuperior 0x03 altgr
+-oneeighth 0x03 shift altgr
++questiondown 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ threesuperior 0x04 altgr
+ sterling 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+-onequarter 0x05 altgr
++cent 0x05 altgr
++onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+-onehalf 0x06 altgr
+-threeeighths 0x06 shift altgr
++EuroSign 0x06 altgr
++U2030 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ asciicircum 0x07 shift
+-threequarters 0x07 altgr
+-fiveeighths 0x07 shift altgr
++onehalf 0x07 altgr
++logicaland 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
+-braceleft 0x08 altgr
+-seveneighths 0x08 shift altgr
++section 0x08 altgr
++approxeq 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
+-bracketleft 0x09 altgr
+-trademark 0x09 shift altgr
++periodcentered 0x09 altgr
++threequarters 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
+-bracketright 0x0a altgr
++guillemotleft 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
+-braceright 0x0b altgr
++guillemotright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
+-backslash 0x0c altgr
+-questiondown 0x0c shift altgr
++endash 0x0c altgr
++emdash 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+ dead_cedilla 0x0d altgr
+ dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++Greek_pi 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
+-lstroke 0x11 altgr
+-Lstroke 0x11 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++oe 0x11 altgr
++OE 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ eogonek 0x12 altgr
+ Eogonek 0x12 shift altgr
+-paragraph 0x13 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
++copyright 0x13 altgr
+ registered 0x13 shift altgr
+-tslash 0x14 altgr
+-Tslash 0x14 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++ssharp 0x14 altgr
++trademark 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
+-EuroSign 0x16 altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+-idotless 0x17 shift altgr
++U2194 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oacute 0x18 altgr
+ Oacute 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ bracketleft 0x1a
+ braceleft 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketright 0x1b
+ braceright 0x1b shift
+ dead_tilde 0x1b altgr
+ dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ aogonek 0x1e altgr
+ Aogonek 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ sacute 0x1f altgr
+ Sacute 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
+-dstroke 0x21 altgr
+-ordfeminine 0x21 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++ae 0x21 altgr
++AE 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
+-hstroke 0x23 altgr
+-Hstroke 0x23 shift altgr
+-kra 0x25 altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++rightsinglequotemark 0x23 altgr
++U2022 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++schwa 0x24 altgr
++SCHWA 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++ellipsis 0x25 altgr
++dead_stroke 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ semicolon 0x27
+ colon 0x27 shift
+ dead_acute 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ apostrophe 0x28
+ quotedbl 0x28 shift
+ dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ grave 0x29
+ asciitilde 0x29 shift
+ notsign 0x29 altgr
++logicalor 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ backslash 0x2b
+ bar 0x2b shift
+ dead_grave 0x2b altgr
+ dead_breve 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ zabovedot 0x2c altgr
+ Zabovedot 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ zacute 0x2d altgr
+ Zacute 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cacute 0x2e altgr
+ Cacute 0x2e shift altgr
+-leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++doublelowquotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++leftdoublequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
+ nacute 0x31 altgr
+ Nacute 0x31 shift altgr
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+-masculine 0x32 shift altgr
++infinity 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
+-horizconnector 0x33 altgr
++lessthanequal 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
+-periodcentered 0x34 altgr
++greaterthanequal 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ slash 0x35
+ question 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++nobreakspace 0x39 altgr
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/pt b/pc-bios/keymaps/pt
+index c6941f6..ab59001 100644
+--- a/pc-bios/keymaps/pt
++++ b/pc-bios/keymaps/pt
+@@ -1,113 +1,834 @@
+-# generated from XKB map pt
+-include common
+-map 0x816
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : pt
++#    variant : -
++#    options : -
++
++# name: "Portuguese"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ quotedbl 0x03 shift
+ at 0x03 altgr
+ oneeighth 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ sterling 0x04 altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ section 0x05 altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-threequarters 0x07 altgr
++notsign 0x07 altgr
+ fiveeighths 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+ seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+ trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ apostrophe 0x0c
+ question 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ guillemotleft 0x0d
+ guillemotright 0x0d shift
+ dead_cedilla 0x0d altgr
+ dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
+ lstroke 0x11 altgr
+ Lstroke 0x11 shift altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
+ cent 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
+ tslash 0x14 altgr
+ Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
+ downarrow 0x16 altgr
+ uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
+ rightarrow 0x17 altgr
+ idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
+ oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
+ thorn 0x19 altgr
+ THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ plus 0x1a
+ asterisk 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ dead_acute 0x1b
+ dead_grave 0x1b shift
+ dead_tilde 0x1b altgr
+ dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
+ ae 0x1e altgr
+ AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
+ ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
+ eth 0x20 altgr
+ ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
+ dstroke 0x21 altgr
+ ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
+ eng 0x22 altgr
+ ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
+ hstroke 0x23 altgr
+ Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
+ kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
+ lstroke 0x26 altgr
+ Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ccedilla 0x27
+ Ccedilla 0x27 shift
++dead_acute 0x27 altgr
+ dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ masculine 0x28
+ ordfeminine 0x28 shift
+ dead_circumflex 0x28 altgr
+ dead_caron 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ backslash 0x29
+ bar 0x29 shift
+ notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ dead_tilde 0x2b
+ dead_circumflex 0x2b shift
++dead_grave 0x2b altgr
+ dead_breve 0x2b shift altgr
+-less 0x56
+-greater 0x56 shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
++masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ semicolon 0x33 shift
+ horizconnector 0x33 altgr
+ multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ colon 0x34 shift
+ periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ minus 0x35
+ underscore 0x35 shift
+ dead_belowdot 0x35 altgr
+ dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++backslash 0x56 altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/pt-br b/pc-bios/keymaps/pt-br
+index 54bafc5..fe9ec81 100644
+--- a/pc-bios/keymaps/pt-br
++++ b/pc-bios/keymaps/pt-br
+@@ -1,69 +1,834 @@
+-# generated from XKB map br
+-include common
+-map 0x416
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : br
++#    variant : -
++#    options : -
++
++# name: "Portuguese (Brazil)"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+ onesuperior 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ at 0x03 shift
+ twosuperior 0x03 altgr
+ onehalf 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numbersign 0x04 shift
+ threesuperior 0x04 altgr
+ threequarters 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ dollar 0x05 shift
+ sterling 0x05 altgr
+ onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ cent 0x06 altgr
++threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ dead_diaeresis 0x07 shift
+ notsign 0x07 altgr
+ diaeresis 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ ampersand 0x08 shift
+ braceleft 0x08 altgr
++seveneighths 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
+ bracketleft 0x09 altgr
++trademark 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
+ bracketright 0x0a altgr
++plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
+ braceright 0x0b altgr
++degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
+ backslash 0x0c altgr
++questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+ section 0x0d altgr
++dead_ogonek 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
++slash 0x10 altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++question 0x11 altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ registered 0x13 altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++tslash 0x14 altgr
++Tslash 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
++leftarrow 0x15 altgr
++yen 0x15 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++downarrow 0x16 altgr
++uparrow 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++i 0x17
++I 0x17 shift
++rightarrow 0x17 altgr
++idotless 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++oslash 0x18 altgr
++Oslash 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++thorn 0x19 altgr
++THORN 0x19 shift altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ dead_acute 0x1a
+ dead_grave 0x1a shift
+ acute 0x1a altgr
+ grave 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ bracketleft 0x1b
+ braceleft 0x1b shift
+ ordfeminine 0x1b altgr
++dead_macron 0x1b shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++ae 0x1e altgr
++AE 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++ssharp 0x1f altgr
++section 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++eth 0x20 altgr
++ETH 0x20 shift altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++dstroke 0x21 altgr
++ordfeminine 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++eng 0x22 altgr
++ENG 0x22 shift altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++hstroke 0x23 altgr
++Hstroke 0x23 shift altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++kra 0x25 altgr
++ampersand 0x25 shift altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++lstroke 0x26 altgr
++Lstroke 0x26 shift altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ ccedilla 0x27
+ Ccedilla 0x27 shift
++dead_acute 0x27 altgr
++dead_doubleacute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ dead_tilde 0x28
+ dead_circumflex 0x28 shift
+ asciitilde 0x28 altgr
+ asciicircum 0x28 shift altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+ apostrophe 0x29
+ quotedbl 0x29 shift
++notsign 0x29 altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ bracketright 0x2b
+ braceright 0x2b shift
+ masculine 0x2b altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
++guillemotleft 0x2c altgr
++less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
++guillemotright 0x2d altgr
++greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ copyright 0x2e altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
++leftdoublequotemark 0x2f altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
++rightdoublequotemark 0x30 altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ comma 0x33
+ less 0x33 shift
++horizconnector 0x33 altgr
++multiply 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ period 0x34
+ greater 0x34 shift
++periodcentered 0x34 altgr
++division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ semicolon 0x35
+ colon 0x35 shift
+-comma 0x53 numlock
++dead_belowdot 0x35 altgr
++dead_abovedot 0x35 shift altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
+ backslash 0x56
+ bar 0x56 shift
++masculine 0x56 altgr
++dead_breve 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
+ slash 0x73
+ question 0x73 shift
+ degree 0x73 altgr
+-KP_Decimal 0x34
++questiondown 0x73 shift altgr
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/ru b/pc-bios/keymaps/ru
+index 8f652d5..7566052 100644
+--- a/pc-bios/keymaps/ru
++++ b/pc-bios/keymaps/ru
+@@ -1,109 +1,748 @@
+-# generated from XKB map ru
+-include common
+-map 0x419
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : ru
++#    variant : -
++#    options : -
++
++# name: "Russian"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+-at 0x03 shift
+-quotedbl 0x03 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
++quotedbl 0x03 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
+ numerosign 0x04 shift
+-dollar 0x05 shift
+-asterisk 0x05 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
++semicolon 0x05 shift
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+-colon 0x06 shift altgr
+-asciicircum 0x07 shift
+-comma 0x07 shift altgr
+-ampersand 0x08 shift
+-period 0x08 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
++colon 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
++question 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ asterisk 0x09 shift
+-semicolon 0x09 shift altgr
++U20BD 0x09 altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenleft 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ parenright 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ minus 0x0c
+ underscore 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ equal 0x0d
+ plus 0x0d shift
+-Cyrillic_shorti 0x10 altgr
+-Cyrillic_SHORTI 0x10 shift altgr
+-Cyrillic_tse 0x11 altgr
+-Cyrillic_TSE 0x11 shift altgr
+-Cyrillic_u 0x12 altgr
+-Cyrillic_U 0x12 shift altgr
+-Cyrillic_ka 0x13 altgr
+-Cyrillic_KA 0x13 shift altgr
+-Cyrillic_ie 0x14 altgr
+-Cyrillic_IE 0x14 shift altgr
+-Cyrillic_en 0x15 altgr
+-Cyrillic_EN 0x15 shift altgr
+-Cyrillic_ghe 0x16 altgr
+-Cyrillic_GHE 0x16 shift altgr
+-Cyrillic_sha 0x17 altgr
+-Cyrillic_SHA 0x17 shift altgr
+-Cyrillic_shcha 0x18 altgr
+-Cyrillic_SHCHA 0x18 shift altgr
+-Cyrillic_ze 0x19 altgr
+-Cyrillic_ZE 0x19 shift altgr
+-bracketleft 0x1a
+-braceleft 0x1a shift
+-Cyrillic_ha 0x1a altgr
+-Cyrillic_HA 0x1a shift altgr
+-bracketright 0x1b
+-braceright 0x1b shift
+-Cyrillic_hardsign 0x1b altgr
+-Cyrillic_HARDSIGN 0x1b shift altgr
+-Cyrillic_ef 0x1e altgr
+-Cyrillic_EF 0x1e shift altgr
+-Cyrillic_yeru 0x1f altgr
+-Cyrillic_YERU 0x1f shift altgr
+-Cyrillic_ve 0x20 altgr
+-Cyrillic_VE 0x20 shift altgr
+-Cyrillic_a 0x21 altgr
+-Cyrillic_A 0x21 shift altgr
+-Cyrillic_pe 0x22 altgr
+-Cyrillic_PE 0x22 shift altgr
+-Cyrillic_er 0x23 altgr
+-Cyrillic_ER 0x23 shift altgr
+-Cyrillic_o 0x24 altgr
+-Cyrillic_O 0x24 shift altgr
+-Cyrillic_el 0x25 altgr
+-Cyrillic_EL 0x25 shift altgr
+-Cyrillic_de 0x26 altgr
+-Cyrillic_DE 0x26 shift altgr
+-semicolon 0x27
+-colon 0x27 shift
+-Cyrillic_zhe 0x27 altgr
+-Cyrillic_ZHE 0x27 shift altgr
+-apostrophe 0x28
+-quotedbl 0x28 shift
+-Cyrillic_e 0x28 altgr
+-Cyrillic_E 0x28 shift altgr
+-grave 0x29
+-asciitilde 0x29 shift
+-Cyrillic_io 0x29 altgr
+-Cyrillic_IO 0x29 shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++Cyrillic_shorti 0x10
++Cyrillic_SHORTI 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++Cyrillic_tse 0x11
++Cyrillic_TSE 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++Cyrillic_u 0x12
++Cyrillic_U 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++Cyrillic_ka 0x13
++Cyrillic_KA 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++Cyrillic_ie 0x14
++Cyrillic_IE 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++Cyrillic_en 0x15
++Cyrillic_EN 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++Cyrillic_ghe 0x16
++Cyrillic_GHE 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++Cyrillic_sha 0x17
++Cyrillic_SHA 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++Cyrillic_shcha 0x18
++Cyrillic_SHCHA 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++Cyrillic_ze 0x19
++Cyrillic_ZE 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++Cyrillic_ha 0x1a
++Cyrillic_HA 0x1a shift
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++Cyrillic_hardsign 0x1b
++Cyrillic_HARDSIGN 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++Cyrillic_ef 0x1e
++Cyrillic_EF 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++Cyrillic_yeru 0x1f
++Cyrillic_YERU 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++Cyrillic_ve 0x20
++Cyrillic_VE 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++Cyrillic_a 0x21
++Cyrillic_A 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++Cyrillic_pe 0x22
++Cyrillic_PE 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++Cyrillic_er 0x23
++Cyrillic_ER 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++Cyrillic_o 0x24
++Cyrillic_O 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++Cyrillic_el 0x25
++Cyrillic_EL 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++Cyrillic_de 0x26
++Cyrillic_DE 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++Cyrillic_zhe 0x27
++Cyrillic_ZHE 0x27 shift
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++Cyrillic_e 0x28
++Cyrillic_E 0x28 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++Cyrillic_io 0x29
++Cyrillic_IO 0x29 shift
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ backslash 0x2b
+-bar 0x2b shift
+-Cyrillic_ya 0x2c altgr
+-Cyrillic_YA 0x2c shift altgr
+-Cyrillic_che 0x2d altgr
+-Cyrillic_CHE 0x2d shift altgr
+-Cyrillic_es 0x2e altgr
+-Cyrillic_ES 0x2e shift altgr
+-Cyrillic_em 0x2f altgr
+-Cyrillic_EM 0x2f shift altgr
+-Cyrillic_i 0x30 altgr
+-Cyrillic_I 0x30 shift altgr
+-Cyrillic_te 0x31 altgr
+-Cyrillic_TE 0x31 shift altgr
+-Cyrillic_softsign 0x32 altgr
+-Cyrillic_SOFTSIGN 0x32 shift altgr
+-comma 0x33
+-less 0x33 shift
+-Cyrillic_be 0x33 altgr
+-Cyrillic_BE 0x33 shift altgr
+-period 0x34
+-greater 0x34 shift
+-Cyrillic_yu 0x34 altgr
+-Cyrillic_YU 0x34 shift altgr
+-slash 0x35
+-question 0x35 shift
+-slash 0x56 altgr
+-bar 0x56 shift altgr
++slash 0x2b shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++Cyrillic_ya 0x2c
++Cyrillic_YA 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++Cyrillic_che 0x2d
++Cyrillic_CHE 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++Cyrillic_es 0x2e
++Cyrillic_ES 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++Cyrillic_em 0x2f
++Cyrillic_EM 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++Cyrillic_i 0x30
++Cyrillic_I 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++Cyrillic_te 0x31
++Cyrillic_TE 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++Cyrillic_softsign 0x32
++Cyrillic_SOFTSIGN 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
++Cyrillic_be 0x33
++Cyrillic_BE 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
++Cyrillic_yu 0x34
++Cyrillic_YU 0x34 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++period 0x35
++comma 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++slash 0x56
++bar 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/th b/pc-bios/keymaps/th
+index b65b6da..56a0135 100644
+--- a/pc-bios/keymaps/th
++++ b/pc-bios/keymaps/th
+@@ -1,131 +1,747 @@
+-# generated from XKB map th
+-include common
+-map 0x41e
+-exclam 0x02 shift
+-Thai_lakkhangyao 0x02 altgr
+-plus 0x02 shift altgr
+-at 0x03 shift
+-slash 0x03 altgr
+-Thai_leknung 0x03 shift altgr
+-numbersign 0x04 shift
+-minus 0x04 altgr
+-Thai_leksong 0x04 shift altgr
+-dollar 0x05 shift
+-Thai_phosamphao 0x05 altgr
+-Thai_leksam 0x05 shift altgr
+-percent 0x06 shift
+-Thai_thothung 0x06 altgr
+-Thai_leksi 0x06 shift altgr
+-asciicircum 0x07 shift
+-Thai_sarau 0x07 altgr
+-Thai_sarauu 0x07 shift altgr
+-ampersand 0x08 shift
+-Thai_saraue 0x08 altgr
+-Thai_baht 0x08 shift altgr
+-asterisk 0x09 shift
+-Thai_khokhwai 0x09 altgr
+-Thai_lekha 0x09 shift altgr
+-parenleft 0x0a shift
+-Thai_totao 0x0a altgr
+-Thai_lekhok 0x0a shift altgr
+-parenright 0x0b shift
+-Thai_chochan 0x0b altgr
+-Thai_lekchet 0x0b shift altgr
+-minus 0x0c
+-underscore 0x0c shift
+-Thai_khokhai 0x0c altgr
+-Thai_lekpaet 0x0c shift altgr
+-equal 0x0d
+-plus 0x0d shift
+-Thai_chochang 0x0d altgr
+-Thai_lekkao 0x0d shift altgr
+-Thai_maiyamok 0x10 altgr
+-Thai_leksun 0x10 shift altgr
+-Thai_saraaimaimalai 0x11 altgr
+-quotedbl 0x11 shift altgr
+-Thai_saraam 0x12 altgr
+-Thai_dochada 0x12 shift altgr
+-Thai_phophan 0x13 altgr
+-Thai_thonangmontho 0x13 shift altgr
+-Thai_saraa 0x14 altgr
+-Thai_thothong 0x14 shift altgr
+-Thai_maihanakat 0x15 altgr
+-Thai_nikhahit 0x15 shift altgr
+-Thai_saraii 0x16 altgr
+-Thai_maitri 0x16 shift altgr
+-Thai_rorua 0x17 altgr
+-Thai_nonen 0x17 shift altgr
+-Thai_nonu 0x18 altgr
+-Thai_paiyannoi 0x18 shift altgr
+-Thai_yoyak 0x19 altgr
+-Thai_yoying 0x19 shift altgr
+-bracketleft 0x1a
+-braceleft 0x1a shift
+-Thai_bobaimai 0x1a altgr
+-Thai_thothan 0x1a shift altgr
+-bracketright 0x1b
+-braceright 0x1b shift
+-Thai_loling 0x1b altgr
+-comma 0x1b shift altgr
+-Thai_fofan 0x1e altgr
+-Thai_ru 0x1e shift altgr
+-Thai_hohip 0x1f altgr
+-Thai_khorakhang 0x1f shift altgr
+-Thai_kokai 0x20 altgr
+-Thai_topatak 0x20 shift altgr
+-Thai_dodek 0x21 altgr
+-Thai_sarao 0x21 shift altgr
+-Thai_sarae 0x22 altgr
+-Thai_chochoe 0x22 shift altgr
+-Thai_maitho 0x23 altgr
+-Thai_maitaikhu 0x23 shift altgr
+-Thai_maiek 0x24 altgr
+-Thai_maichattawa 0x24 shift altgr
+-Thai_saraaa 0x25 altgr
+-Thai_sorusi 0x25 shift altgr
+-Thai_sosua 0x26 altgr
+-Thai_sosala 0x26 shift altgr
+-semicolon 0x27
+-colon 0x27 shift
+-Thai_wowaen 0x27 altgr
+-Thai_soso 0x27 shift altgr
+-apostrophe 0x28
+-quotedbl 0x28 shift
+-Thai_ngongu 0x28 altgr
+-period 0x28 shift altgr
+-grave 0x29
+-asciitilde 0x29 shift
+-underscore 0x29 altgr
+-percent 0x29 shift altgr
+-ISO_First_Group 0x2a shift
+-backslash 0x2b
+-bar 0x2b shift
+-Thai_khokhuat 0x2b altgr
+-Thai_khokhon 0x2b shift altgr
+-Thai_phophung 0x2c altgr
+-parenleft 0x2c shift altgr
+-Thai_popla 0x2d altgr
+-parenright 0x2d shift altgr
+-Thai_saraae 0x2e altgr
+-Thai_choching 0x2e shift altgr
+-Thai_oang 0x2f altgr
+-Thai_honokhuk 0x2f shift altgr
+-Thai_sarai 0x30 altgr
+-Thai_phinthu 0x30 shift altgr
+-Thai_sarauee 0x31 altgr
+-Thai_thanthakhat 0x31 shift altgr
+-Thai_thothahan 0x32 altgr
+-question 0x32 shift altgr
+-comma 0x33
+-less 0x33 shift
+-Thai_moma 0x33 altgr
+-Thai_thophuthao 0x33 shift altgr
+-period 0x34
+-greater 0x34 shift
+-Thai_saraaimaimuan 0x34 altgr
+-Thai_lochula 0x34 shift altgr
+-slash 0x35
+-question 0x35 shift
+-Thai_fofa 0x35 altgr
+-Thai_lu 0x35 shift altgr
+-ISO_Last_Group 0x36 shift
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : th
++#    variant : -
++#    options : -
++
++# name: "Thai"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++Thai_lakkhangyao 0x02
++plus 0x02 shift
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++slash 0x03
++Thai_leknung 0x03 shift
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++minus 0x04
++Thai_leksong 0x04 shift
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++Thai_phosamphao 0x05
++Thai_leksam 0x05 shift
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++Thai_thothung 0x06
++Thai_leksi 0x06 shift
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++Thai_sarau 0x07
++Thai_sarauu 0x07 shift
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++Thai_saraue 0x08
++Thai_baht 0x08 shift
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++Thai_khokhwai 0x09
++Thai_lekha 0x09 shift
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++Thai_totao 0x0a
++Thai_lekhok 0x0a shift
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++Thai_chochan 0x0b
++Thai_lekchet 0x0b shift
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
++Thai_khokhai 0x0c
++Thai_lekpaet 0x0c shift
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
++Thai_chochang 0x0d
++Thai_lekkao 0x0d shift
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++Thai_maiyamok 0x10
++Thai_leksun 0x10 shift
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++Thai_saraaimaimalai 0x11
++quotedbl 0x11 shift
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++Thai_saraam 0x12
++Thai_dochada 0x12 shift
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++Thai_phophan 0x13
++Thai_thonangmontho 0x13 shift
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++Thai_saraa 0x14
++Thai_thothong 0x14 shift
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++Thai_maihanakat 0x15
++Thai_nikhahit 0x15 shift
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++Thai_saraii 0x16
++Thai_maitri 0x16 shift
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
++Thai_rorua 0x17
++Thai_nonen 0x17 shift
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++Thai_nonu 0x18
++Thai_paiyannoi 0x18 shift
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++Thai_yoyak 0x19
++Thai_yoying 0x19 shift
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
++Thai_bobaimai 0x1a
++Thai_thothan 0x1a shift
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
++Thai_loling 0x1b
++comma 0x1b shift
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++Thai_fofan 0x1e
++Thai_ru 0x1e shift
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++Thai_hohip 0x1f
++Thai_khorakhang 0x1f shift
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++Thai_kokai 0x20
++Thai_topatak 0x20 shift
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++Thai_dodek 0x21
++Thai_sarao 0x21 shift
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++Thai_sarae 0x22
++Thai_chochoe 0x22 shift
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++Thai_maitho 0x23
++Thai_maitaikhu 0x23 shift
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++Thai_maiek 0x24
++Thai_maichattawa 0x24 shift
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++Thai_saraaa 0x25
++Thai_sorusi 0x25 shift
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++Thai_sosua 0x26
++Thai_sosala 0x26 shift
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
++Thai_wowaen 0x27
++Thai_soso 0x27 shift
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
++Thai_ngongu 0x28
++period 0x28 shift
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++underscore 0x29
++percent 0x29 shift
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
++Thai_khokhuat 0x2b
++Thai_khokhon 0x2b shift
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++Thai_phophung 0x2c
++parenleft 0x2c shift
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++Thai_popla 0x2d
++parenright 0x2d shift
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++Thai_saraae 0x2e
++Thai_choching 0x2e shift
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++Thai_oang 0x2f
++Thai_honokhuk 0x2f shift
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++Thai_sarai 0x30
++Thai_phinthu 0x30 shift
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++Thai_sarauee 0x31
++Thai_thanthakhat 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++Thai_thothahan 0x32
++question 0x32 shift
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
++Thai_moma 0x33
++Thai_thophuthao 0x33 shift
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
++Thai_saraaimaimuan 0x34
++Thai_lochula 0x34 shift
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
++Thai_fofa 0x35
++Thai_lu 0x35 shift
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Decimal 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++Alt_R 0xb8
++Meta_R 0xb8 shift
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+diff --git a/pc-bios/keymaps/tr b/pc-bios/keymaps/tr
+index 5650e1e..4d1a4c3 100644
+--- a/pc-bios/keymaps/tr
++++ b/pc-bios/keymaps/tr
+@@ -1,123 +1,830 @@
+-# generated from XKB map tr
+-include common
+-map 0x41f
++#
++# generated by qemu-keymap
++#    model   : pc105
++#    layout  : tr
++#    variant : -
++#    options : -
++
++# name: "Turkish"
++
++# modifiers
++#     0: Shift
++#     1: Lock
++#     2: Control
++#     3: Mod1
++#     4: Mod2
++#     5: Mod3
++#     6: Mod4
++#     7: Mod5
++#     8: NumLock
++#     9: Alt
++#    10: LevelThree
++#    11: LAlt
++#    12: RAlt
++#    13: RControl
++#    14: LControl
++#    15: ScrollLock
++#    16: LevelFive
++#    17: AltGr
++#    18: Meta
++#    19: Super
++#    20: Hyper
++
++# evdev 1 (0x1), QKeyCode "esc", number 0x1
++Escape 0x01
++
++# evdev 2 (0x2), QKeyCode "1", number 0x2
++1 0x02
+ exclam 0x02 shift
+-onesuperior 0x02 altgr
++greater 0x02 altgr
+ exclamdown 0x02 shift altgr
++
++# evdev 3 (0x3), QKeyCode "2", number 0x3
++2 0x03
+ apostrophe 0x03 shift
+-at 0x03 altgr
+-oneeighth 0x03 shift altgr
+-dead_circumflex 0x04 shift
++sterling 0x03 altgr
++twosuperior 0x03 shift altgr
++
++# evdev 4 (0x4), QKeyCode "3", number 0x4
++3 0x04
++asciicircum 0x04 shift
+ numbersign 0x04 altgr
+-sterling 0x04 shift altgr
++threesuperior 0x04 shift altgr
++
++# evdev 5 (0x5), QKeyCode "4", number 0x5
++4 0x05
+ plus 0x05 shift
+ dollar 0x05 altgr
++onequarter 0x05 shift altgr
++
++# evdev 6 (0x6), QKeyCode "5", number 0x6
++5 0x06
+ percent 0x06 shift
+ onehalf 0x06 altgr
+ threeeighths 0x06 shift altgr
++
++# evdev 7 (0x7), QKeyCode "6", number 0x7
++6 0x07
+ ampersand 0x07 shift
+-asciicircum 0x07 altgr
+-fiveeighths 0x07 shift altgr
++threequarters 0x07 altgr
++VoidSymbol 0x07 shift altgr
++
++# evdev 8 (0x8), QKeyCode "7", number 0x8
++7 0x08
+ slash 0x08 shift
+ braceleft 0x08 altgr
+-seveneighths 0x08 shift altgr
++VoidSymbol 0x08 shift altgr
++
++# evdev 9 (0x9), QKeyCode "8", number 0x9
++8 0x09
+ parenleft 0x09 shift
+ bracketleft 0x09 altgr
+-trademark 0x09 shift altgr
++VoidSymbol 0x09 shift altgr
++
++# evdev 10 (0xa), QKeyCode "9", number 0xa
++9 0x0a
+ parenright 0x0a shift
+ bracketright 0x0a altgr
+ plusminus 0x0a shift altgr
++
++# evdev 11 (0xb), QKeyCode "0", number 0xb
++0 0x0b
+ equal 0x0b shift
+ braceright 0x0b altgr
+ degree 0x0b shift altgr
++
++# evdev 12 (0xc), QKeyCode "minus", number 0xc
+ asterisk 0x0c
+ question 0x0c shift
+ backslash 0x0c altgr
+ questiondown 0x0c shift altgr
++
++# evdev 13 (0xd), QKeyCode "equal", number 0xd
+ minus 0x0d
+ underscore 0x0d shift
+-dead_cedilla 0x0d altgr
+-dead_ogonek 0x0d shift altgr
++bar 0x0d altgr
++VoidSymbol 0x0d shift altgr
++
++# evdev 14 (0xe), QKeyCode "backspace", number 0xe
++BackSpace 0x0e
++
++# evdev 15 (0xf), QKeyCode "tab", number 0xf
++Tab 0x0f
++ISO_Left_Tab 0x0f shift
++
++# evdev 16 (0x10), QKeyCode "q", number 0x10
++q 0x10
++Q 0x10 shift
+ at 0x10 altgr
+ Greek_OMEGA 0x10 shift altgr
+-lstroke 0x11 altgr
+-Lstroke 0x11 shift altgr
++
++# evdev 17 (0x11), QKeyCode "w", number 0x11
++w 0x11
++W 0x11 shift
++VoidSymbol 0x11 altgr
++
++# evdev 18 (0x12), QKeyCode "e", number 0x12
++e 0x12
++E 0x12 shift
+ EuroSign 0x12 altgr
++VoidSymbol 0x12 shift altgr
++
++# evdev 19 (0x13), QKeyCode "r", number 0x13
++r 0x13
++R 0x13 shift
+ paragraph 0x13 altgr
+ registered 0x13 shift altgr
+-tslash 0x14 altgr
+-Tslash 0x14 shift altgr
++
++# evdev 20 (0x14), QKeyCode "t", number 0x14
++t 0x14
++T 0x14 shift
++U20BA 0x14 altgr
++VoidSymbol 0x14 shift altgr
++
++# evdev 21 (0x15), QKeyCode "y", number 0x15
++y 0x15
++Y 0x15 shift
+ leftarrow 0x15 altgr
+ yen 0x15 shift altgr
+-downarrow 0x16 altgr
+-uparrow 0x16 shift altgr
++
++# evdev 22 (0x16), QKeyCode "u", number 0x16
++u 0x16
++U 0x16 shift
++ucircumflex 0x16 altgr
++Ucircumflex 0x16 shift altgr
++
++# evdev 23 (0x17), QKeyCode "i", number 0x17
+ idotless 0x17
+ I 0x17 shift
+-rightarrow 0x17 altgr
+-oslash 0x18 altgr
+-Ooblique 0x18 shift altgr
+-thorn 0x19 altgr
+-THORN 0x19 shift altgr
++icircumflex 0x17 altgr
++Icircumflex 0x17 shift altgr
++
++# evdev 24 (0x18), QKeyCode "o", number 0x18
++o 0x18
++O 0x18 shift
++ocircumflex 0x18 altgr
++Ocircumflex 0x18 shift altgr
++
++# evdev 25 (0x19), QKeyCode "p", number 0x19
++p 0x19
++P 0x19 shift
++VoidSymbol 0x19 altgr
++
++# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+ gbreve 0x1a
+ Gbreve 0x1a shift
+ dead_diaeresis 0x1a altgr
+ dead_abovering 0x1a shift altgr
++
++# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+ udiaeresis 0x1b
+ Udiaeresis 0x1b shift
+ asciitilde 0x1b altgr
+ dead_macron 0x1b shift altgr
+-ae 0x1e altgr
+-AE 0x1e shift altgr
+-ssharp 0x1f altgr
+-section 0x1f shift altgr
+-eth 0x20 altgr
+-ETH 0x20 shift altgr
+-dstroke 0x21 altgr
+-ordfeminine 0x21 shift altgr
+-eng 0x22 altgr
+-ENG 0x22 shift altgr
+-hstroke 0x23 altgr
+-Hstroke 0x23 shift altgr
+-kra 0x25 altgr
+-ampersand 0x25 shift altgr
+-lstroke 0x26 altgr
+-Lstroke 0x26 shift altgr
++
++# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
++Return 0x1c
++
++# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
++Control_L 0x1d
++
++# evdev 30 (0x1e), QKeyCode "a", number 0x1e
++a 0x1e
++A 0x1e shift
++acircumflex 0x1e altgr
++Acircumflex 0x1e shift altgr
++
++# evdev 31 (0x1f), QKeyCode "s", number 0x1f
++s 0x1f
++S 0x1f shift
++section 0x1f altgr
++VoidSymbol 0x1f shift altgr
++
++# evdev 32 (0x20), QKeyCode "d", number 0x20
++d 0x20
++D 0x20 shift
++VoidSymbol 0x20 altgr
++
++# evdev 33 (0x21), QKeyCode "f", number 0x21
++f 0x21
++F 0x21 shift
++ordfeminine 0x21 altgr
++VoidSymbol 0x21 shift altgr
++
++# evdev 34 (0x22), QKeyCode "g", number 0x22
++g 0x22
++G 0x22 shift
++VoidSymbol 0x22 altgr
++
++# evdev 35 (0x23), QKeyCode "h", number 0x23
++h 0x23
++H 0x23 shift
++VoidSymbol 0x23 altgr
++
++# evdev 36 (0x24), QKeyCode "j", number 0x24
++j 0x24
++J 0x24 shift
++dead_hook 0x24 altgr
++dead_horn 0x24 shift altgr
++
++# evdev 37 (0x25), QKeyCode "k", number 0x25
++k 0x25
++K 0x25 shift
++VoidSymbol 0x25 altgr
++
++# evdev 38 (0x26), QKeyCode "l", number 0x26
++l 0x26
++L 0x26 shift
++VoidSymbol 0x26 altgr
++
++# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+ scedilla 0x27
+ Scedilla 0x27 shift
+-dead_acute 0x27 altgr
+-dead_doubleacute 0x27 shift altgr
++acute 0x27 altgr
++dead_acute 0x27 shift altgr
++
++# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+ i 0x28
+ Iabovedot 0x28 shift
+-dead_circumflex 0x28 altgr
++apostrophe 0x28 altgr
+ dead_caron 0x28 shift altgr
+-backslash 0x29
+-quotedbl 0x29 shift
+-asciitilde 0x29 altgr
++
++# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
++quotedbl 0x29
++eacute 0x29 shift
++less 0x29 altgr
++degree 0x29 shift altgr
++
++# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
++Shift_L 0x2a
++
++# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+ comma 0x2b
+ semicolon 0x2b shift
+-bar 0x2b altgr
+-dead_breve 0x2b shift altgr
++grave 0x2b altgr
++dead_grave 0x2b shift altgr
++
++# evdev 44 (0x2c), QKeyCode "z", number 0x2c
++z 0x2c
++Z 0x2c shift
+ guillemotleft 0x2c altgr
+ less 0x2c shift altgr
++
++# evdev 45 (0x2d), QKeyCode "x", number 0x2d
++x 0x2d
++X 0x2d shift
+ guillemotright 0x2d altgr
+ greater 0x2d shift altgr
++
++# evdev 46 (0x2e), QKeyCode "c", number 0x2e
++c 0x2e
++C 0x2e shift
+ cent 0x2e altgr
+ copyright 0x2e shift altgr
++
++# evdev 47 (0x2f), QKeyCode "v", number 0x2f
++v 0x2f
++V 0x2f shift
+ leftdoublequotemark 0x2f altgr
+-grave 0x2f shift altgr
++leftsinglequotemark 0x2f shift altgr
++
++# evdev 48 (0x30), QKeyCode "b", number 0x30
++b 0x30
++B 0x30 shift
+ rightdoublequotemark 0x30 altgr
+-apostrophe 0x30 shift altgr
++rightsinglequotemark 0x30 shift altgr
++
++# evdev 49 (0x31), QKeyCode "n", number 0x31
++n 0x31
++N 0x31 shift
++
++# evdev 50 (0x32), QKeyCode "m", number 0x32
++m 0x32
++M 0x32 shift
+ mu 0x32 altgr
+ masculine 0x32 shift altgr
++
++# evdev 51 (0x33), QKeyCode "comma", number 0x33
+ odiaeresis 0x33
+ Odiaeresis 0x33 shift
+-less 0x33 altgr
+-multiply 0x33 shift altgr
++multiply 0x33 altgr
++VoidSymbol 0x33 shift altgr
++
++# evdev 52 (0x34), QKeyCode "dot", number 0x34
+ ccedilla 0x34
+ Ccedilla 0x34 shift
+-greater 0x34 altgr
++periodcentered 0x34 altgr
+ division 0x34 shift altgr
++
++# evdev 53 (0x35), QKeyCode "slash", number 0x35
+ period 0x35
+ colon 0x35 shift
+-dead_belowdot 0x35 altgr
+-dead_abovedot 0x35 shift altgr
++dead_abovedot 0x35 altgr
++
++# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
++Shift_R 0x36
++
++# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
++KP_Multiply 0x37
++
++# evdev 56 (0x38), QKeyCode "alt", number 0x38
++Alt_L 0x38
++Meta_L 0x38 shift
++
++# evdev 57 (0x39), QKeyCode "spc", number 0x39
++space 0x39
++
++# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
++Caps_Lock 0x3a
++
++# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
++F1 0x3b
++
++# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
++F2 0x3c
++
++# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
++F3 0x3d
++
++# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
++F4 0x3e
++
++# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
++F5 0x3f
++
++# evdev 64 (0x40), QKeyCode "f6", number 0x40
++F6 0x40
++
++# evdev 65 (0x41), QKeyCode "f7", number 0x41
++F7 0x41
++
++# evdev 66 (0x42), QKeyCode "f8", number 0x42
++F8 0x42
++
++# evdev 67 (0x43), QKeyCode "f9", number 0x43
++F9 0x43
++
++# evdev 68 (0x44), QKeyCode "f10", number 0x44
++F10 0x44
++
++# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
++Num_Lock 0x45
++
++# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
++Scroll_Lock 0x46
++
++# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
++KP_Home 0x47
++KP_7 0x47 numlock
++
++# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
++KP_Up 0x48
++KP_8 0x48 numlock
++
++# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
++KP_Prior 0x49
++KP_9 0x49 numlock
++
++# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
++KP_Subtract 0x4a
++
++# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
++KP_Left 0x4b
++KP_4 0x4b numlock
++
++# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
++KP_Begin 0x4c
++KP_5 0x4c numlock
++
++# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
++KP_Right 0x4d
++KP_6 0x4d numlock
++
++# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
++KP_Add 0x4e
++
++# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
++KP_End 0x4f
++KP_1 0x4f numlock
++
++# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
++KP_Down 0x50
++KP_2 0x50 numlock
++
++# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
++KP_Next 0x51
++KP_3 0x51 numlock
++
++# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
++KP_Insert 0x52
++KP_0 0x52 numlock
++
++# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
++KP_Delete 0x53
++KP_Separator 0x53 numlock
++
++# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
++
++# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 86 (0x56), QKeyCode "less", number 0x56
++less 0x56
++greater 0x56 shift
++bar 0x56 altgr
++brokenbar 0x56 shift altgr
++
++# evdev 87 (0x57), QKeyCode "f11", number 0x57
++F11 0x57
++
++# evdev 88 (0x58), QKeyCode "f12", number 0x58
++F12 0x58
++
++# evdev 89 (0x59), QKeyCode "ro", number 0x73
++
++# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
++
++# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
++Hiragana 0x77
++
++# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
++Henkan_Mode 0x79
++
++# evdev 93 (0x5d): no evdev -> QKeyCode mapping (xkb keysym Hiragana_Katakana)
++
++# evdev 94 (0x5e): no evdev -> QKeyCode mapping (xkb keysym Muhenkan)
++
++# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
++KP_Enter 0x9c
++
++# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
++Control_R 0x9d
++
++# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
++KP_Divide 0xb5
++
++# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
++Print 0x54
++
++# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
++ISO_Level3_Shift 0xb8
++
++# evdev 101 (0x65), QKeyCode "lf", number 0x5b
++Linefeed 0x5b
++
++# evdev 102 (0x66), QKeyCode "home", number 0xc7
++Home 0xc7
++
++# evdev 103 (0x67), QKeyCode "up", number 0xc8
++Up 0xc8
++
++# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
++Prior 0xc9
++
++# evdev 105 (0x69), QKeyCode "left", number 0xcb
++Left 0xcb
++
++# evdev 106 (0x6a), QKeyCode "right", number 0xcd
++Right 0xcd
++
++# evdev 107 (0x6b), QKeyCode "end", number 0xcf
++End 0xcf
++
++# evdev 108 (0x6c), QKeyCode "down", number 0xd0
++Down 0xd0
++
++# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
++Next 0xd1
++
++# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
++Insert 0xd2
++
++# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
++Delete 0xd3
++
++# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
++XF86AudioMute 0xa0
++
++# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
++XF86AudioLowerVolume 0xae
++
++# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
++XF86AudioRaiseVolume 0xb0
++
++# evdev 116 (0x74), QKeyCode "power", number 0xde
++XF86PowerOff 0xde
++
++# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
++KP_Equal 0x59
++
++# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
++
++# evdev 119 (0x77), QKeyCode "pause", number 0xc6
++Pause 0xc6
++
++# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
++
++# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
++KP_Decimal 0x7e
++
++# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
++
++# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
++
++# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
++
++# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
++Super_L 0xdb
++
++# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
++Super_R 0xdc
++
++# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
++Menu 0xdd
++
++# evdev 128 (0x80), QKeyCode "stop", number 0xe8
++Cancel 0xe8
++
++# evdev 129 (0x81), QKeyCode "again", number 0x85
++Redo 0x85
++
++# evdev 130 (0x82), QKeyCode "props", number 0x86
++SunProps 0x86
++
++# evdev 131 (0x83), QKeyCode "undo", number 0x87
++Undo 0x87
++
++# evdev 132 (0x84), QKeyCode "front", number 0x8c
++SunFront 0x8c
++
++# evdev 133 (0x85), QKeyCode "copy", number 0xf8
++XF86Copy 0xf8
++
++# evdev 134 (0x86), QKeyCode "open", number 0x64
++XF86Open 0x64
++
++# evdev 135 (0x87), QKeyCode "paste", number 0x65
++XF86Paste 0x65
++
++# evdev 136 (0x88), QKeyCode "find", number 0xc1
++Find 0xc1
++
++# evdev 137 (0x89), QKeyCode "cut", number 0xbc
++XF86Cut 0xbc
++
++# evdev 138 (0x8a), QKeyCode "help", number 0xf5
++Help 0xf5
++
++# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
++XF86MenuKB 0x9e
++
++# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
++XF86Calculator 0xa1
++
++# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
++XF86Sleep 0xdf
++
++# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
++XF86WakeUp 0xe3
++
++# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
++
++# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
++
++# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
++
++# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
++
++# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
++
++# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
++
++# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
++
++# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
++
++# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
++
++# evdev 155 (0x9b), QKeyCode "mail", number 0xec
++XF86Mail 0xec
++
++# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
++XF86Favorites 0xe6
++
++# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
++XF86MyComputer 0xeb
++
++# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
++XF86Back 0xea
++
++# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
++XF86Forward 0xe9
++
++# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
++
++# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
++XF86AudioNext 0x99
++
++# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
++XF86AudioPlay 0xa2
++XF86AudioPause 0xa2 shift
++
++# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
++XF86AudioPrev 0x90
++
++# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
++XF86AudioStop 0xa4
++XF86Eject 0xa4 shift
++
++# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
++
++# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
++
++# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
++
++# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
++XF86HomePage 0xb2
++
++# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
++XF86Reload 0xe7
++
++# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
++
++# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
++
++# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
++
++# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
++
++# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
++
++# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
++
++# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
++
++# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
++
++# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
++
++# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
++
++# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
++
++# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
++
++# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
++
++# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
++
++# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
++
++# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
++
++# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
++
++# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
++
++# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
++
++# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
++
++# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
++
++# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
++
++# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
++
++# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
++
++# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
++
++# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
++
++# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
++
++# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
++
++# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
++
++# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
++
++# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
++
++# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
++
++# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
++
++# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
++
++# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
++
++# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
++
++# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
++
++# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
++XF86AudioMedia 0xed
++
++# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
++
++# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
++
++# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
++
++# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
++
++# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
++
++# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
++
++# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
++
++# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
++
++# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
++
++# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
++
++# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
++
++# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
++
++# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
++
++#
++# quirks section start
++#
++# Sometimes multiple keysyms map to the same keycodes.
++# The keycode -> keysym lookup finds only one of the
++# keysyms.  So append them here.
++#
++
++Print 0x54
++Sys_Req 0x54
++Execute 0x54
++KP_Decimal 0x53 numlock
++KP_Separator 0x53 numlock
++Alt_R 0xb8
++ISO_Level3_Shift 0xb8
++Mode_switch 0xb8
++
++# quirks section end
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Fix-problem-with-invalid-virtio-scs.patch b/SOURCES/kvm-pc-bios-s390-ccw-Fix-problem-with-invalid-virtio-scs.patch
new file mode 100644
index 0000000..6876bd7
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390-ccw-Fix-problem-with-invalid-virtio-scs.patch
@@ -0,0 +1,58 @@
+From 544ee34c5f878c51e72d75d1384eed8ae38cf2a5 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Wed, 22 Nov 2017 10:43:31 +0100
+Subject: [PATCH 14/15] pc-bios/s390-ccw: Fix problem with invalid virtio-scsi
+ LUN when rebooting
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1511347411-16226-4-git-send-email-thuth@redhat.com>
+Patchwork-id: 77776
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 3/3] pc-bios/s390-ccw: Fix problem with invalid virtio-scsi LUN when rebooting
+Bugzilla: 1514352
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+When rebooting a guest that has a virtio-scsi disk, the s390-ccw
+bios sometimes bails out with an error message like this:
+
+! SCSI cannot report LUNs: STATUS=02 RSPN=70 KEY=05 CODE=25 QLFR=00, sure !
+
+Enabling the scsi_req* tracing in QEMU shows that the ccw bios is
+trying to execute the REPORT LUNS SCSI command with a LUN != 0, and
+this causes the SCSI command to fail.
+Looks like we neither clear the BSS of the s390-ccw bios during reboot,
+nor do we explicitly set the default_scsi_device.lun value to 0, so
+this variable can contain random values from the OS after the reboot.
+By setting this variable explicitly to 0, the problem is fixed and
+the reboots always succeed.
+
+Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1514352
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1510942228-22822-1-git-send-email-thuth@redhat.com>
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 8775d91a0f42d016833330881bb587982db88a3c)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ pc-bios/s390-ccw/virtio-scsi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c
+index c92f5d3..4fe4b9d 100644
+--- a/pc-bios/s390-ccw/virtio-scsi.c
++++ b/pc-bios/s390-ccw/virtio-scsi.c
+@@ -223,7 +223,8 @@ static void virtio_scsi_locate_device(VDev *vdev)
+ 
+     for (target = 0; target <= vdev->config.scsi.max_target; target++) {
+         sdev->channel = channel;
+-        sdev->target = target; /* sdev->lun will be 0 here */
++        sdev->target = target;
++        sdev->lun = 0;          /* LUN has to be 0 for REPORT LUNS */
+         if (!scsi_report_luns(vdev, data, sizeof(data))) {
+             if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) {
+                 continue;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-fix-crash-on-attempted-cpu-unplug.patch b/SOURCES/kvm-pc-fix-crash-on-attempted-cpu-unplug.patch
new file mode 100644
index 0000000..d523083
--- /dev/null
+++ b/SOURCES/kvm-pc-fix-crash-on-attempted-cpu-unplug.patch
@@ -0,0 +1,58 @@
+From f8394b69cee118293a1983ebc99492f113d57704 Mon Sep 17 00:00:00 2001
+From: Igor Mammedov <imammedo@redhat.com>
+Date: Wed, 6 Dec 2017 13:47:58 +0100
+Subject: [PATCH 20/21] pc: fix crash on attempted cpu unplug
+
+RH-Author: Igor Mammedov <imammedo@redhat.com>
+Message-id: <1512568078-280557-1-git-send-email-imammedo@redhat.com>
+Patchwork-id: 78212
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH] pc: fix crash on attempted cpu unplug
+Bugzilla: 1506856
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+when qemu is started with '-no-acpi' CLI option, an attempt
+to unplug a CPU using device_del results in null pointer
+dereference at:
+
+  #0 object_get_class
+  #1 pc_machine_device_unplug_request_cb
+  #2 qmp_marshal_device_del
+
+which is caused by pcms->acpi_dev == NULL due to ACPI support
+being disabled.
+
+Considering that ACPI support is necessary for unplug to work,
+check that it's enabled and fail unplug request gracefully
+if no acpi device were found.
+
+Signed-off-by: Igor Mammedov <imammedo@redhat.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 75ba2ddb188fa07c3442446766782036e3085cba)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/i386/pc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index f37d60a..db57b51 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -1879,6 +1879,11 @@ static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
+     X86CPU *cpu = X86_CPU(dev);
+     PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+ 
++    if (!pcms->acpi_dev) {
++        error_setg(&local_err, "CPU hot unplug not supported without ACPI");
++        goto out;
++    }
++
+     pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx);
+     assert(idx != -1);
+     if (idx == 0) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-make-pc_rom-RO-only-on-new-machine-types.patch b/SOURCES/kvm-pc-make-pc_rom-RO-only-on-new-machine-types.patch
new file mode 100644
index 0000000..61b1716
--- /dev/null
+++ b/SOURCES/kvm-pc-make-pc_rom-RO-only-on-new-machine-types.patch
@@ -0,0 +1,104 @@
+From c091cd7a1b3799d3d2d657bc3dc66dec90eb86f1 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 11 Oct 2017 17:55:00 +0200
+Subject: [PATCH 15/69] pc: make pc_rom RO only on new machine types
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171011175500.12390-3-dgilbert@redhat.com>
+Patchwork-id: 77178
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v3 2/2] pc: make pc_rom RO only on new machine types
+Bugzilla: 1489800
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+Upstream lp 1715700 reported that the RO pc_rom settings caused
+problems with Windows 7 under OVMF.
+This is fixed in a new OVMF, but lets keep things stable on
+older machine types.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/i386/pc.c         | 4 +++-
+ hw/i386/pc_piix.c    | 2 ++
+ hw/i386/pc_q35.c     | 2 ++
+ include/hw/i386/pc.h | 3 +++
+ 4 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index ccaa832..83df57f 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -1444,7 +1444,8 @@ void pc_memory_init(PCMachineState *pcms,
+     option_rom_mr = g_malloc(sizeof(*option_rom_mr));
+     memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
+                            &error_fatal);
+-    if (pcmc->pci_enabled) {
++    /* RH difference: See bz 1489800, explicitly make ROM ro */
++    if (pcmc->pc_rom_ro) {
+         memory_region_set_readonly(option_rom_mr, true);
+     }
+     memory_region_add_subregion_overlap(rom_memory,
+@@ -2350,6 +2351,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
+     pcmc->acpi_data_size = 0x20000 + 0x8000;
+     pcmc->save_tsc_khz = true;
+     pcmc->linuxboot_dma_enabled = true;
++    pcmc->pc_rom_ro = true;
+     mc->get_hotplug_handler = pc_get_hotpug_handler;
+     mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
+     mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
+diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
+index 935391f..09bfc5a 100644
+--- a/hw/i386/pc_piix.c
++++ b/hw/i386/pc_piix.c
+@@ -1164,11 +1164,13 @@ static void pc_init_rhel740(MachineState *machine)
+ 
+ static void pc_machine_rhel740_options(MachineClass *m)
+ {
++    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+     pc_machine_rhel750_options(m);
+     m->alias = NULL;
+     m->is_default = 0;
+     m->desc = "RHEL 7.4.0 PC (i440FX + PIIX, 1996)";
+     m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
++    pcmc->pc_rom_ro = false;
+     SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT);
+ }
+ 
+diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
+index e73097b..27c85c5 100644
+--- a/hw/i386/pc_q35.c
++++ b/hw/i386/pc_q35.c
+@@ -416,10 +416,12 @@ static void pc_q35_init_rhel740(MachineState *machine)
+ 
+ static void pc_q35_machine_rhel740_options(MachineClass *m)
+ {
++    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+     pc_q35_machine_rhel750_options(m);
+     m->alias = NULL;
+     m->desc = "RHEL-7.4.0 PC (Q35 + ICH9, 2009)";
+     m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
++    pcmc->pc_rom_ro = false;
+     SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT);
+ }
+ 
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index a8d6857..6f65d79 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -141,6 +141,9 @@ struct PCMachineClass {
+ 
+     /* use DMA capable linuxboot option rom */
+     bool linuxboot_dma_enabled;
++
++    /* RH only, see bz 1489800 */
++    bool pc_rom_ro;
+ };
+ 
+ #define TYPE_PC_MACHINE "generic-pc-machine"
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pci-Add-INTERFACE_CONVENTIONAL_PCI_DEVICE-to-Convent.patch b/SOURCES/kvm-pci-Add-INTERFACE_CONVENTIONAL_PCI_DEVICE-to-Convent.patch
new file mode 100644
index 0000000..2e048c0
--- /dev/null
+++ b/SOURCES/kvm-pci-Add-INTERFACE_CONVENTIONAL_PCI_DEVICE-to-Convent.patch
@@ -0,0 +1,1208 @@
+From 54ed98827de5ad796b429aa2163d039cbf242c39 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:15 +0200
+Subject: [PATCH 10/19] pci: Add INTERFACE_CONVENTIONAL_PCI_DEVICE to
+ Conventional PCI devices
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-6-ehabkost@redhat.com>
+Patchwork-id: 77424
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 5/7] pci: Add INTERFACE_CONVENTIONAL_PCI_DEVICE to Conventional PCI devices
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Add INTERFACE_CONVENTIONAL_PCI_DEVICE to all direct subtypes of
+TYPE_PCI_DEVICE, except:
+
+1) The ones that already have INTERFACE_PCIE_DEVICE set:
+
+* base-xhci
+* e1000e
+* nvme
+* pvscsi
+* vfio-pci
+* virtio-pci
+* vmxnet3
+
+2) base-pci-bridge
+
+Not all PCI bridges are Conventional PCI devices, so
+INTERFACE_CONVENTIONAL_PCI_DEVICE is added only to the subtypes
+that are actually Conventional PCI:
+
+* dec-21154-p2p-bridge
+* i82801b11-bridge
+* pbm-bridge
+* pci-bridge
+
+The direct subtypes of base-pci-bridge not touched by this patch
+are:
+
+* xilinx-pcie-root: Already marked as PCIe-only.
+* pcie-pci-bridge: Already marked as PCIe-only.
+* pcie-port: all non-abstract subtypes of pcie-port are already
+  marked as PCIe-only devices.
+
+3) megasas-base
+
+Not all megasas devices are Conventional PCI devices, so the
+interface names are added to the subclasses registered by
+megasas_register_types(), according to information in the
+megasas_devices[] array.
+
+"megasas-gen2" already implements INTERFACE_PCIE_DEVICE, so add
+INTERFACE_CONVENTIONAL_PCI_DEVICE only to "megasas".
+
+Backport notes:
+* Trivial conflicts:
+  * hw/net/sungem.c
+  * hw/net/sunhme.c
+  * hw/pci-host/apb.c
+
+Acked-by: Alberto Garcia <berto@igalia.com>
+Acked-by: John Snow <jsnow@redhat.com>
+Acked-by: Anthony PERARD <anthony.perard@citrix.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Acked-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit fd3b02c8896d597dd8b9e053dec579cf0386aee1)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+Changes v1 -> v2:
+* Removed hw/net/sungem.c and hw/net/sunhme.c
+  (Mistake spotted by David Gibson)
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/acpi/piix4.c                     |  1 +
+ hw/audio/ac97.c                     |  4 ++++
+ hw/audio/es1370.c                   |  4 ++++
+ hw/audio/intel-hda.c                |  4 ++++
+ hw/char/serial-pci.c                | 12 ++++++++++++
+ hw/display/cirrus_vga.c             |  4 ++++
+ hw/display/qxl.c                    |  4 ++++
+ hw/display/sm501.c                  |  4 ++++
+ hw/display/vga-pci.c                |  4 ++++
+ hw/display/vmware_vga.c             |  4 ++++
+ hw/i2c/smbus_ich9.c                 |  4 ++++
+ hw/i386/amd_iommu.c                 |  4 ++++
+ hw/i386/kvm/pci-assign.c            |  4 ++++
+ hw/i386/pc_piix.c                   |  4 ++++
+ hw/i386/xen/xen_platform.c          |  4 ++++
+ hw/i386/xen/xen_pvdevice.c          |  4 ++++
+ hw/ide/ich.c                        |  4 ++++
+ hw/ide/pci.c                        |  4 ++++
+ hw/ipack/tpci200.c                  |  4 ++++
+ hw/isa/i82378.c                     |  4 ++++
+ hw/isa/lpc_ich9.c                   |  1 +
+ hw/isa/piix4.c                      |  4 ++++
+ hw/isa/vt82c686.c                   | 16 ++++++++++++++++
+ hw/mips/gt64xxx_pci.c               |  4 ++++
+ hw/misc/edu.c                       |  5 +++++
+ hw/misc/ivshmem.c                   |  4 ++++
+ hw/misc/macio/macio.c               |  4 ++++
+ hw/misc/pci-testdev.c               |  4 ++++
+ hw/net/e1000.c                      |  4 ++++
+ hw/net/eepro100.c                   |  4 ++++
+ hw/net/ne2000.c                     |  4 ++++
+ hw/net/pcnet-pci.c                  |  4 ++++
+ hw/net/rocker/rocker.c              |  4 ++++
+ hw/net/rtl8139.c                    |  4 ++++
+ hw/pci-bridge/dec.c                 |  8 ++++++++
+ hw/pci-bridge/i82801b11.c           |  4 ++++
+ hw/pci-bridge/pci_bridge_dev.c      |  1 +
+ hw/pci-bridge/pci_expander_bridge.c |  8 ++++++++
+ hw/pci-host/apb.c                   |  8 ++++++++
+ hw/pci-host/bonito.c                |  4 ++++
+ hw/pci-host/gpex.c                  |  4 ++++
+ hw/pci-host/grackle.c               |  4 ++++
+ hw/pci-host/piix.c                  |  8 ++++++++
+ hw/pci-host/ppce500.c               |  4 ++++
+ hw/pci-host/prep.c                  |  4 ++++
+ hw/pci-host/q35.c                   |  4 ++++
+ hw/pci-host/uninorth.c              | 16 ++++++++++++++++
+ hw/pci-host/versatile.c             |  4 ++++
+ hw/ppc/ppc4xx_pci.c                 |  4 ++++
+ hw/scsi/esp-pci.c                   |  4 ++++
+ hw/scsi/lsi53c895a.c                |  4 ++++
+ hw/scsi/megasas.c                   |  4 ++++
+ hw/scsi/mptsas.c                    |  4 ++++
+ hw/sd/sdhci.c                       |  4 ++++
+ hw/sh4/sh_pci.c                     |  4 ++++
+ hw/sparc64/sun4u.c                  |  4 ++++
+ hw/usb/hcd-ehci-pci.c               |  4 ++++
+ hw/usb/hcd-ohci.c                   |  4 ++++
+ hw/usb/hcd-uhci.c                   |  4 ++++
+ hw/vfio/pci-quirks.c                |  4 ++++
+ hw/watchdog/wdt_i6300esb.c          |  4 ++++
+ hw/xen/xen_pt.c                     |  4 ++++
+ 62 files changed, 288 insertions(+)
+
+diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
+index efd80d1..34c6e22 100644
+--- a/hw/acpi/piix4.c
++++ b/hw/acpi/piix4.c
+@@ -723,6 +723,7 @@ static const TypeInfo piix4_pm_info = {
+     .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
+         { TYPE_ACPI_DEVICE_IF },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+         { }
+     }
+ };
+diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
+index 959c786..337402e 100644
+--- a/hw/audio/ac97.c
++++ b/hw/audio/ac97.c
+@@ -1431,6 +1431,10 @@ static const TypeInfo ac97_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof (AC97LinkState),
+     .class_init    = ac97_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void ac97_register_types (void)
+diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
+index dd7c23d..59cf252 100644
+--- a/hw/audio/es1370.c
++++ b/hw/audio/es1370.c
+@@ -1082,6 +1082,10 @@ static const TypeInfo es1370_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof (ES1370State),
+     .class_init    = es1370_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void es1370_register_types (void)
+diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
+index 06acc98..b786491 100644
+--- a/hw/audio/intel-hda.c
++++ b/hw/audio/intel-hda.c
+@@ -1299,6 +1299,10 @@ static const TypeInfo intel_hda_info = {
+     .instance_size = sizeof(IntelHDAState),
+     .class_init    = intel_hda_class_init,
+     .abstract      = true,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static const TypeInfo intel_hda_info_ich6 = {
+diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
+index 24ce17b..d426982 100644
+--- a/hw/char/serial-pci.c
++++ b/hw/char/serial-pci.c
+@@ -254,6 +254,10 @@ static const TypeInfo serial_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCISerialState),
+     .class_init    = serial_pci_class_initfn,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static const TypeInfo multi_2x_serial_pci_info = {
+@@ -261,6 +265,10 @@ static const TypeInfo multi_2x_serial_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIMultiSerialState),
+     .class_init    = multi_2x_serial_pci_class_initfn,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static const TypeInfo multi_4x_serial_pci_info = {
+@@ -268,6 +276,10 @@ static const TypeInfo multi_4x_serial_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIMultiSerialState),
+     .class_init    = multi_4x_serial_pci_class_initfn,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void serial_pci_register_types(void)
+diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
+index e53c6f2..633d555 100644
+--- a/hw/display/cirrus_vga.c
++++ b/hw/display/cirrus_vga.c
+@@ -3162,6 +3162,10 @@ static const TypeInfo cirrus_vga_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCICirrusVGAState),
+     .class_init    = cirrus_vga_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void cirrus_vga_register_types(void)
+diff --git a/hw/display/qxl.c b/hw/display/qxl.c
+index ae3677f..b20e259 100644
+--- a/hw/display/qxl.c
++++ b/hw/display/qxl.c
+@@ -2430,6 +2430,10 @@ static const TypeInfo qxl_pci_type_info = {
+     .instance_size = sizeof(PCIQXLDevice),
+     .abstract = true,
+     .class_init = qxl_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void qxl_primary_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/display/sm501.c b/hw/display/sm501.c
+index 6f3dfe0..7f18224 100644
+--- a/hw/display/sm501.c
++++ b/hw/display/sm501.c
+@@ -1843,6 +1843,10 @@ static const TypeInfo sm501_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(SM501PCIState),
+     .class_init    = sm501_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void sm501_register_types(void)
+diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
+index ac9a764..7adb89f 100644
+--- a/hw/display/vga-pci.c
++++ b/hw/display/vga-pci.c
+@@ -338,6 +338,10 @@ static const TypeInfo vga_pci_type_info = {
+     .instance_size = sizeof(PCIVGAState),
+     .abstract = true,
+     .class_init = vga_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void vga_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
+index 4a64b41..cdc3fed 100644
+--- a/hw/display/vmware_vga.c
++++ b/hw/display/vmware_vga.c
+@@ -1350,6 +1350,10 @@ static const TypeInfo vmsvga_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(struct pci_vmsvga_state_s),
+     .class_init    = vmsvga_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void vmsvga_register_types(void)
+diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
+index ea51e09..e47556c 100644
+--- a/hw/i2c/smbus_ich9.c
++++ b/hw/i2c/smbus_ich9.c
+@@ -119,6 +119,10 @@ static const TypeInfo ich9_smb_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(ICH9SMBState),
+     .class_init = ich9_smb_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void ich9_smb_register(void)
+diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
+index 334938a..ad8155c 100644
+--- a/hw/i386/amd_iommu.c
++++ b/hw/i386/amd_iommu.c
+@@ -1227,6 +1227,10 @@ static const TypeInfo amdviPCI = {
+     .name = "AMDVI-PCI",
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(AMDVIPCIState),
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
+index 33e20cb..d8559d8 100644
+--- a/hw/i386/kvm/pci-assign.c
++++ b/hw/i386/kvm/pci-assign.c
+@@ -1864,6 +1864,10 @@ static const TypeInfo assign_info = {
+     .instance_size      = sizeof(AssignedDevice),
+     .class_init         = assign_class_init,
+     .instance_init      = assigned_dev_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void assign_register_types(void)
+diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
+index 09bfc5a..c10e462 100644
+--- a/hw/i386/pc_piix.c
++++ b/hw/i386/pc_piix.c
+@@ -1051,6 +1051,10 @@ static TypeInfo isa_bridge_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init = isa_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pt_graphics_register_types(void)
+diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
+index 9ba7474..056b87d 100644
+--- a/hw/i386/xen/xen_platform.c
++++ b/hw/i386/xen/xen_platform.c
+@@ -517,6 +517,10 @@ static const TypeInfo xen_platform_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIXenPlatformState),
+     .class_init    = xen_platform_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void xen_platform_register_types(void)
+diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c
+index c093b34..f748823 100644
+--- a/hw/i386/xen/xen_pvdevice.c
++++ b/hw/i386/xen/xen_pvdevice.c
+@@ -127,6 +127,10 @@ static const TypeInfo xen_pv_type_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(XenPVDevice),
+     .class_init    = xen_pv_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void xen_pv_register_types(void)
+diff --git a/hw/ide/ich.c b/hw/ide/ich.c
+index 9472a60..8dd0ced 100644
+--- a/hw/ide/ich.c
++++ b/hw/ide/ich.c
+@@ -184,6 +184,10 @@ static const TypeInfo ich_ahci_info = {
+     .instance_size = sizeof(AHCIPCIState),
+     .instance_init = pci_ich9_ahci_init,
+     .class_init    = ich_ahci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void ich_ahci_register_types(void)
+diff --git a/hw/ide/pci.c b/hw/ide/pci.c
+index 3cfb510..428980b 100644
+--- a/hw/ide/pci.c
++++ b/hw/ide/pci.c
+@@ -458,6 +458,10 @@ static const TypeInfo pci_ide_type_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIIDEState),
+     .abstract = true,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pci_ide_register_types(void)
+diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c
+index 4dfa6b3..da05c85 100644
+--- a/hw/ipack/tpci200.c
++++ b/hw/ipack/tpci200.c
+@@ -646,6 +646,10 @@ static const TypeInfo tpci200_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(TPCI200State),
+     .class_init    = tpci200_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void tpci200_register_types(void)
+diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
+index 4d29a99..d20ea4c 100644
+--- a/hw/isa/i82378.c
++++ b/hw/isa/i82378.c
+@@ -138,6 +138,10 @@ static const TypeInfo i82378_type_info = {
+     .instance_size = sizeof(I82378State),
+     .instance_init = i82378_init,
+     .class_init = i82378_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void i82378_register_types(void)
+diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
+index ac8416d..39f56ba 100644
+--- a/hw/isa/lpc_ich9.c
++++ b/hw/isa/lpc_ich9.c
+@@ -823,6 +823,7 @@ static const TypeInfo ich9_lpc_info = {
+     .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
+         { TYPE_ACPI_DEVICE_IF },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+         { }
+     }
+ };
+diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
+index f811eba..6b8bc3f 100644
+--- a/hw/isa/piix4.c
++++ b/hw/isa/piix4.c
+@@ -132,6 +132,10 @@ static const TypeInfo piix4_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PIIX4State),
+     .class_init    = piix4_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void piix4_register_types(void)
+diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
+index 50dc83d..c129985 100644
+--- a/hw/isa/vt82c686.c
++++ b/hw/isa/vt82c686.c
+@@ -301,6 +301,10 @@ static const TypeInfo via_ac97_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(VT686AC97State),
+     .class_init    = via_ac97_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp)
+@@ -341,6 +345,10 @@ static const TypeInfo via_mc97_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(VT686MC97State),
+     .class_init    = via_mc97_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ /* vt82c686 pm init */
+@@ -419,6 +427,10 @@ static const TypeInfo via_pm_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(VT686PMState),
+     .class_init    = via_pm_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static const VMStateDescription vmstate_via = {
+@@ -502,6 +514,10 @@ static const TypeInfo via_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(VT82C686BState),
+     .class_init    = via_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void vt82c686b_register_types(void)
+diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
+index e8b2eef..5a9dad9 100644
+--- a/hw/mips/gt64xxx_pci.c
++++ b/hw/mips/gt64xxx_pci.c
+@@ -1232,6 +1232,10 @@ static const TypeInfo gt64120_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init    = gt64120_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void gt64120_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/misc/edu.c b/hw/misc/edu.c
+index 01acacf..34eb05d 100644
+--- a/hw/misc/edu.c
++++ b/hw/misc/edu.c
+@@ -408,12 +408,17 @@ static void edu_class_init(ObjectClass *class, void *data)
+ 
+ static void pci_edu_register_types(void)
+ {
++    static InterfaceInfo interfaces[] = {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    };
+     static const TypeInfo edu_info = {
+         .name          = "edu",
+         .parent        = TYPE_PCI_DEVICE,
+         .instance_size = sizeof(EduState),
+         .instance_init = edu_instance_init,
+         .class_init    = edu_class_init,
++        .interfaces = interfaces,
+     };
+ 
+     type_register_static(&edu_info);
+diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
+index 33ef10b..a0a1480 100644
+--- a/hw/misc/ivshmem.c
++++ b/hw/misc/ivshmem.c
+@@ -1017,6 +1017,10 @@ static const TypeInfo ivshmem_common_info = {
+     .instance_size = sizeof(IVShmemState),
+     .abstract      = true,
+     .class_init    = ivshmem_common_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static const VMStateDescription ivshmem_plain_vmsd = {
+diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
+index 5d57f45..298e650 100644
+--- a/hw/misc/macio/macio.c
++++ b/hw/misc/macio/macio.c
+@@ -415,6 +415,10 @@ static const TypeInfo macio_type_info = {
+     .instance_init = macio_instance_init,
+     .abstract      = true,
+     .class_init    = macio_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void macio_register_types(void)
+diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c
+index 7d59902..32041f5 100644
+--- a/hw/misc/pci-testdev.c
++++ b/hw/misc/pci-testdev.c
+@@ -326,6 +326,10 @@ static const TypeInfo pci_testdev_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCITestDevState),
+     .class_init    = pci_testdev_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pci_testdev_register_types(void)
+diff --git a/hw/net/e1000.c b/hw/net/e1000.c
+index d29e9ee..793d54a 100644
+--- a/hw/net/e1000.c
++++ b/hw/net/e1000.c
+@@ -1695,6 +1695,10 @@ static const TypeInfo e1000_base_info = {
+     .instance_init = e1000_instance_init,
+     .class_size    = sizeof(E1000BaseClass),
+     .abstract      = true,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static const E1000Info e1000_devices[] = {
+diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
+index 5a4774a..522deb7 100644
+--- a/hw/net/eepro100.c
++++ b/hw/net/eepro100.c
+@@ -2117,6 +2117,10 @@ static void eepro100_register_types(void)
+         type_info.class_init = eepro100_class_init;
+         type_info.instance_size = sizeof(EEPRO100State);
+         type_info.instance_init = eepro100_instance_init;
++        type_info.interfaces = (InterfaceInfo[]) {
++            { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++            { },
++        };
+ 
+         type_register(&type_info);
+     }
+diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
+index 8660955..2284308 100644
+--- a/hw/net/ne2000.c
++++ b/hw/net/ne2000.c
+@@ -786,6 +786,10 @@ static const TypeInfo ne2000_info = {
+     .instance_size = sizeof(PCINE2000State),
+     .class_init    = ne2000_class_init,
+     .instance_init = ne2000_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void ne2000_register_types(void)
+diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
+index eeab4ca..0e4d4f7 100644
+--- a/hw/net/pcnet-pci.c
++++ b/hw/net/pcnet-pci.c
+@@ -365,6 +365,10 @@ static const TypeInfo pcnet_info = {
+     .instance_size = sizeof(PCIPCNetState),
+     .class_init    = pcnet_class_init,
+     .instance_init = pcnet_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pci_pcnet_register_types(void)
+diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
+index 4f0f6d7..26d78eb 100644
+--- a/hw/net/rocker/rocker.c
++++ b/hw/net/rocker/rocker.c
+@@ -1573,6 +1573,10 @@ static const TypeInfo rocker_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(Rocker),
+     .class_init    = rocker_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void rocker_register_types(void)
+diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
+index 80c62dc..52eafc3 100644
+--- a/hw/net/rtl8139.c
++++ b/hw/net/rtl8139.c
+@@ -3491,6 +3491,10 @@ static const TypeInfo rtl8139_info = {
+     .instance_size = sizeof(RTL8139State),
+     .class_init    = rtl8139_class_init,
+     .instance_init = rtl8139_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void rtl8139_register_types(void)
+diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
+index eb275e1..84492d5 100644
+--- a/hw/pci-bridge/dec.c
++++ b/hw/pci-bridge/dec.c
+@@ -79,6 +79,10 @@ static const TypeInfo dec_21154_pci_bridge_info = {
+     .parent        = TYPE_PCI_BRIDGE,
+     .instance_size = sizeof(PCIBridge),
+     .class_init    = dec_21154_pci_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
+@@ -138,6 +142,10 @@ static const TypeInfo dec_21154_pci_host_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init    = dec_21154_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
+index 2c1b747..cb522bf 100644
+--- a/hw/pci-bridge/i82801b11.c
++++ b/hw/pci-bridge/i82801b11.c
+@@ -106,6 +106,10 @@ static const TypeInfo i82801b11_bridge_info = {
+     .parent        = TYPE_PCI_BRIDGE,
+     .instance_size = sizeof(I82801b11Bridge),
+     .class_init    = i82801b11_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void d2pbr_register(void)
+diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
+index 4373f1d..d56f663 100644
+--- a/hw/pci-bridge/pci_bridge_dev.c
++++ b/hw/pci-bridge/pci_bridge_dev.c
+@@ -238,6 +238,7 @@ static const TypeInfo pci_bridge_dev_info = {
+     .instance_finalize = pci_bridge_dev_instance_finalize,
+     .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+         { }
+     }
+ };
+diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
+index ff59abf..8c8ac73 100644
+--- a/hw/pci-bridge/pci_expander_bridge.c
++++ b/hw/pci-bridge/pci_expander_bridge.c
+@@ -316,6 +316,10 @@ static const TypeInfo pxb_dev_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PXBDev),
+     .class_init    = pxb_dev_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
+@@ -350,6 +354,10 @@ static const TypeInfo pxb_pcie_dev_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PXBDev),
+     .class_init    = pxb_pcie_dev_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pxb_register_types(void)
+diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
+index 96e5d0b..6cf7279 100644
+--- a/hw/pci-host/apb.c
++++ b/hw/pci-host/apb.c
+@@ -817,6 +817,10 @@ static const TypeInfo pbm_pci_host_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init    = pbm_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pbm_host_class_init(ObjectClass *klass, void *data)
+@@ -857,6 +861,10 @@ static const TypeInfo pbm_pci_bridge_info = {
+     .name          = "pbm-bridge",
+     .parent        = TYPE_PCI_BRIDGE,
+     .class_init    = pbm_pci_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
+index 89133a9..9f61e27 100644
+--- a/hw/pci-host/bonito.c
++++ b/hw/pci-host/bonito.c
+@@ -833,6 +833,10 @@ static const TypeInfo bonito_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIBonitoState),
+     .class_init    = bonito_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
+index 83084b9..59f3132 100644
+--- a/hw/pci-host/gpex.c
++++ b/hw/pci-host/gpex.c
+@@ -144,6 +144,10 @@ static const TypeInfo gpex_root_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(GPEXRootState),
+     .class_init = gpex_root_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void gpex_register(void)
+diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
+index 2e281f6..38cd279 100644
+--- a/hw/pci-host/grackle.c
++++ b/hw/pci-host/grackle.c
+@@ -142,6 +142,10 @@ static const TypeInfo grackle_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init = grackle_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pci_grackle_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
+index 90c50b0..68c3922 100644
+--- a/hw/pci-host/piix.c
++++ b/hw/pci-host/piix.c
+@@ -694,6 +694,10 @@ static const TypeInfo piix3_pci_type_info = {
+     .instance_size = sizeof(PIIX3State),
+     .abstract = true,
+     .class_init = pci_piix3_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void piix3_class_init(ObjectClass *klass, void *data)
+@@ -748,6 +752,10 @@ static const TypeInfo i440fx_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCII440FXState),
+     .class_init    = i440fx_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ #if 0 /*  Disabled in Red Hat Enterprise Linux */
+diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
+index becc0ee..39cd244 100644
+--- a/hw/pci-host/ppce500.c
++++ b/hw/pci-host/ppce500.c
+@@ -516,6 +516,10 @@ static const TypeInfo e500_host_bridge_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PPCE500PCIBridgeState),
+     .class_init    = e500_host_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static Property pcihost_properties[] = {
+diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
+index 8b293ba..92eed0f 100644
+--- a/hw/pci-host/prep.c
++++ b/hw/pci-host/prep.c
+@@ -372,6 +372,10 @@ static const TypeInfo raven_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(RavenPCIState),
+     .class_init = raven_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static Property raven_pcihost_properties[] = {
+diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
+index 0e472f2..9cd07ce 100644
+--- a/hw/pci-host/q35.c
++++ b/hw/pci-host/q35.c
+@@ -591,6 +591,10 @@ static const TypeInfo mch_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(MCHPCIState),
+     .class_init = mch_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void q35_register(void)
+diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
+index 6cf5e59..ea5c265 100644
+--- a/hw/pci-host/uninorth.c
++++ b/hw/pci-host/uninorth.c
+@@ -374,6 +374,10 @@ static const TypeInfo unin_main_pci_host_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init = unin_main_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
+@@ -398,6 +402,10 @@ static const TypeInfo u3_agp_pci_host_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init = u3_agp_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
+@@ -422,6 +430,10 @@ static const TypeInfo unin_agp_pci_host_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init = unin_agp_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
+@@ -446,6 +458,10 @@ static const TypeInfo unin_internal_pci_host_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init = unin_internal_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void pci_unin_main_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
+index aa1fdf7..6394a52 100644
+--- a/hw/pci-host/versatile.c
++++ b/hw/pci-host/versatile.c
+@@ -487,6 +487,10 @@ static const TypeInfo versatile_pci_host_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init    = versatile_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static Property pci_vpb_properties[] = {
+diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
+index 6953f8b..4765dce 100644
+--- a/hw/ppc/ppc4xx_pci.c
++++ b/hw/ppc/ppc4xx_pci.c
+@@ -359,6 +359,10 @@ static const TypeInfo ppc4xx_host_bridge_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init    = ppc4xx_host_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
+index e295d88..419fc66 100644
+--- a/hw/scsi/esp-pci.c
++++ b/hw/scsi/esp-pci.c
+@@ -398,6 +398,10 @@ static const TypeInfo esp_pci_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIESPState),
+     .class_init = esp_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ typedef struct {
+diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
+index 3e56ab2..423a284 100644
+--- a/hw/scsi/lsi53c895a.c
++++ b/hw/scsi/lsi53c895a.c
+@@ -2244,6 +2244,10 @@ static const TypeInfo lsi_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(LSIState),
+     .class_init    = lsi_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void lsi53c810_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
+index 3641c30..4ae10e3 100644
+--- a/hw/scsi/megasas.c
++++ b/hw/scsi/megasas.c
+@@ -2468,6 +2468,10 @@ static struct MegasasInfo megasas_devices[] = {
+         .is_express = false,
+         .vmsd = &vmstate_megasas_gen1,
+         .props = megasas_properties_gen1,
++        .interfaces = (InterfaceInfo[]) {
++            { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++            { },
++        },
+     },{
+         .name = TYPE_MEGASAS_GEN2,
+         .desc = "LSI MegaRAID SAS 2108",
+diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
+index 765ab53..f807dc6 100644
+--- a/hw/scsi/mptsas.c
++++ b/hw/scsi/mptsas.c
+@@ -1441,6 +1441,10 @@ static const TypeInfo mptsas_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(MPTSASState),
+     .class_init = mptsas1068_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void mptsas_register_types(void)
+diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
+index 6d6a791..b064a08 100644
+--- a/hw/sd/sdhci.c
++++ b/hw/sd/sdhci.c
+@@ -1315,6 +1315,10 @@ static const TypeInfo sdhci_pci_info = {
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(SDHCIState),
+     .class_init = sdhci_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static Property sdhci_sysbus_properties[] = {
+diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
+index 38395c0..cbb01af 100644
+--- a/hw/sh4/sh_pci.c
++++ b/hw/sh4/sh_pci.c
+@@ -179,6 +179,10 @@ static const TypeInfo sh_pci_host_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(PCIDevice),
+     .class_init    = sh_pci_host_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void sh_pci_device_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
+index bbdb40c..13bc121 100644
+--- a/hw/sparc64/sun4u.c
++++ b/hw/sparc64/sun4u.c
+@@ -277,6 +277,10 @@ static const TypeInfo ebus_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(EbusState),
+     .class_init    = ebus_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ #define TYPE_OPENPROM "openprom"
+diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
+index 6dedcb8..8c0fc53 100644
+--- a/hw/usb/hcd-ehci-pci.c
++++ b/hw/usb/hcd-ehci-pci.c
+@@ -170,6 +170,10 @@ static const TypeInfo ehci_pci_type_info = {
+     .instance_finalize = usb_ehci_pci_finalize,
+     .abstract = true,
+     .class_init = ehci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void ehci_data_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
+index 267982e..a31df67 100644
+--- a/hw/usb/hcd-ohci.c
++++ b/hw/usb/hcd-ohci.c
+@@ -2139,6 +2139,10 @@ static const TypeInfo ohci_pci_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(OHCIPCIState),
+     .class_init    = ohci_pci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static Property ohci_sysbus_properties[] = {
+diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
+index 465ed42..86d6ab8 100644
+--- a/hw/usb/hcd-uhci.c
++++ b/hw/usb/hcd-uhci.c
+@@ -1336,6 +1336,10 @@ static const TypeInfo uhci_pci_type_info = {
+     .class_size    = sizeof(UHCIPCIDeviceClass),
+     .abstract = true,
+     .class_init = uhci_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void uhci_data_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
+index 58046e6..4199771 100644
+--- a/hw/vfio/pci-quirks.c
++++ b/hw/vfio/pci-quirks.c
+@@ -1199,6 +1199,10 @@ static TypeInfo vfio_pci_igd_lpc_bridge_info = {
+     .name = "vfio-pci-igd-lpc-bridge",
+     .parent = TYPE_PCI_DEVICE,
+     .class_init = vfio_pci_igd_lpc_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void vfio_pci_igd_register_types(void)
+diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
+index 49b3cd1..e596b08 100644
+--- a/hw/watchdog/wdt_i6300esb.c
++++ b/hw/watchdog/wdt_i6300esb.c
+@@ -463,6 +463,10 @@ static const TypeInfo i6300esb_info = {
+     .parent        = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(I6300State),
+     .class_init    = i6300esb_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void i6300esb_register_types(void)
+diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
+index 375efa6..01df341 100644
+--- a/hw/xen/xen_pt.c
++++ b/hw/xen/xen_pt.c
+@@ -964,6 +964,10 @@ static const TypeInfo xen_pci_passthrough_info = {
+     .instance_size = sizeof(XenPCIPassthroughState),
+     .instance_finalize = xen_pci_passthrough_finalize,
+     .class_init = xen_pci_passthrough_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { },
++    },
+ };
+ 
+ static void xen_pci_passthrough_register_types(void)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pci-Add-INTERFACE_PCIE_DEVICE-to-all-PCIe-devices.patch b/SOURCES/kvm-pci-Add-INTERFACE_PCIE_DEVICE-to-all-PCIe-devices.patch
new file mode 100644
index 0000000..7af8f59
--- /dev/null
+++ b/SOURCES/kvm-pci-Add-INTERFACE_PCIE_DEVICE-to-all-PCIe-devices.patch
@@ -0,0 +1,174 @@
+From 4dc6726309313a4c2e508d2ac9ec3bd7ea29cde2 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:14 +0200
+Subject: [PATCH 09/19] pci: Add INTERFACE_PCIE_DEVICE to all PCIe devices
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-5-ehabkost@redhat.com>
+Patchwork-id: 77423
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 4/7] pci: Add INTERFACE_PCIE_DEVICE to all PCIe devices
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Change all devices that set is_express=1 to implement
+INTERFACE_PCIE_DEVICE.
+
+Backport notes:
+* Not included: hw/pci-bridge/pcie_pci_bridge.c
+
+Cc: Keith Busch <keith.busch@intel.com>
+Cc: Kevin Wolf <kwolf@redhat.com>
+Cc: Max Reitz <mreitz@redhat.com>
+Cc: Dmitry Fleytman <dmitry@daynix.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Cc: Marcel Apfelbaum <marcel@redhat.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Hannes Reinecke <hare@suse.com>
+Cc: qemu-block@nongnu.org
+Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 71d787677d0cacea846dc851c3e56ad076d59c04)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/block/nvme.c                    | 4 ++++
+ hw/net/e1000e.c                    | 4 ++++
+ hw/pci-bridge/pcie_root_port.c     | 4 ++++
+ hw/pci-bridge/xio3130_downstream.c | 4 ++++
+ hw/pci-bridge/xio3130_upstream.c   | 4 ++++
+ hw/pci-host/xilinx-pcie.c          | 4 ++++
+ hw/scsi/megasas.c                  | 6 ++++++
+ 7 files changed, 30 insertions(+)
+
+diff --git a/hw/block/nvme.c b/hw/block/nvme.c
+index 6071dc1..26d58b6 100644
+--- a/hw/block/nvme.c
++++ b/hw/block/nvme.c
+@@ -1110,6 +1110,10 @@ static const TypeInfo nvme_info = {
+     .instance_size = sizeof(NvmeCtrl),
+     .class_init    = nvme_class_init,
+     .instance_init = nvme_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { }
++    },
+ };
+ 
+ static void nvme_register_types(void)
+diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
+index d6ca464..ac9b1e3 100644
+--- a/hw/net/e1000e.c
++++ b/hw/net/e1000e.c
+@@ -729,6 +729,10 @@ static const TypeInfo e1000e_info = {
+     .instance_size = sizeof(E1000EState),
+     .class_init = e1000e_class_init,
+     .instance_init = e1000e_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { }
++    },
+ };
+ 
+ static void e1000e_register_types(void)
+diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
+index 4d588cb..9b6e4ce 100644
+--- a/hw/pci-bridge/pcie_root_port.c
++++ b/hw/pci-bridge/pcie_root_port.c
+@@ -161,6 +161,10 @@ static const TypeInfo rp_info = {
+     .class_init    = rp_class_init,
+     .abstract      = true,
+     .class_size = sizeof(PCIERootPortClass),
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { }
++    },
+ };
+ 
+ static void rp_register_types(void)
+diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
+index 5a882b0..1e09d2a 100644
+--- a/hw/pci-bridge/xio3130_downstream.c
++++ b/hw/pci-bridge/xio3130_downstream.c
+@@ -196,6 +196,10 @@ static const TypeInfo xio3130_downstream_info = {
+     .name          = "xio3130-downstream",
+     .parent        = TYPE_PCIE_SLOT,
+     .class_init    = xio3130_downstream_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { }
++    },
+ };
+ 
+ static void xio3130_downstream_register_types(void)
+diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
+index a052224..227997c 100644
+--- a/hw/pci-bridge/xio3130_upstream.c
++++ b/hw/pci-bridge/xio3130_upstream.c
+@@ -166,6 +166,10 @@ static const TypeInfo xio3130_upstream_info = {
+     .name          = "x3130-upstream",
+     .parent        = TYPE_PCIE_PORT,
+     .class_init    = xio3130_upstream_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { }
++    },
+ };
+ 
+ static void xio3130_upstream_register_types(void)
+diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
+index 4613dda..7659253 100644
+--- a/hw/pci-host/xilinx-pcie.c
++++ b/hw/pci-host/xilinx-pcie.c
+@@ -317,6 +317,10 @@ static const TypeInfo xilinx_pcie_root_info = {
+     .parent = TYPE_PCI_BRIDGE,
+     .instance_size = sizeof(XilinxPCIERoot),
+     .class_init = xilinx_pcie_root_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { }
++    },
+ };
+ 
+ static void xilinx_pcie_register(void)
+diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
+index 734fdae..3641c30 100644
+--- a/hw/scsi/megasas.c
++++ b/hw/scsi/megasas.c
+@@ -2451,6 +2451,7 @@ typedef struct MegasasInfo {
+     int osts;
+     const VMStateDescription *vmsd;
+     Property *props;
++    InterfaceInfo *interfaces;
+ } MegasasInfo;
+ 
+ static struct MegasasInfo megasas_devices[] = {
+@@ -2480,6 +2481,10 @@ static struct MegasasInfo megasas_devices[] = {
+         .is_express = true,
+         .vmsd = &vmstate_megasas_gen2,
+         .props = megasas_properties_gen2,
++        .interfaces = (InterfaceInfo[]) {
++            { INTERFACE_PCIE_DEVICE },
++            { }
++        },
+     }
+ };
+ 
+@@ -2531,6 +2536,7 @@ static void megasas_register_types(void)
+         type_info.parent = TYPE_MEGASAS_BASE;
+         type_info.class_data = (void *)info;
+         type_info.class_init = megasas_class_init;
++        type_info.interfaces = info->interfaces;
+ 
+         type_register(&type_info);
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pci-Add-interface-names-to-hybrid-PCI-devices.patch b/SOURCES/kvm-pci-Add-interface-names-to-hybrid-PCI-devices.patch
new file mode 100644
index 0000000..326fb96
--- /dev/null
+++ b/SOURCES/kvm-pci-Add-interface-names-to-hybrid-PCI-devices.patch
@@ -0,0 +1,132 @@
+From 0e3c4dff97fed5335c1af115e06d329e2f705022 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:13 +0200
+Subject: [PATCH 08/19] pci: Add interface names to hybrid PCI devices
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-4-ehabkost@redhat.com>
+Patchwork-id: 77425
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 3/7] pci: Add interface names to hybrid PCI devices
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+The following devices support both PCI Express and Conventional
+PCI, by including special code to handle the QEMU_PCI_CAP_EXPRESS
+flag and/or conditional pcie_endpoint_cap_init() calls:
+
+* vfio-pci (is_express=1, but legacy PCI handled by
+  vfio_populate_device())
+* vmxnet3 (is_express=0, but PCIe handled by vmxnet3_realize())
+* pvscsi (is_express=0, but PCIe handled by pvscsi_realize())
+* virtio-pci (is_express=0, but PCIe handled by
+  virtio_pci_dc_realize(), and additional legacy PCI code at
+  virtio_pci_realize())
+* base-xhci (is_express=1, but pcie_endpoint_cap_init() call
+  is conditional on pci_bus_is_express(dev->bus)
+  * Note that xhci does not clear QEMU_PCI_CAP_EXPRESS like the
+    other hybrid devices
+
+Cc: Dmitry Fleytman <dmitry@daynix.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Gerd Hoffmann <kraxel@redhat.com>
+Cc: Alex Williamson <alex.williamson@redhat.com>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit a5fa336f11a1eddad9f2be6506e59ba50ed81818)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/net/vmxnet3.c       | 5 +++++
+ hw/scsi/vmw_pvscsi.c   | 2 ++
+ hw/usb/hcd-xhci.c      | 5 +++++
+ hw/vfio/pci.c          | 5 +++++
+ hw/virtio/virtio-pci.c | 5 +++++
+ 5 files changed, 22 insertions(+)
+
+diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
+index a19a7a3..f99d9a6 100644
+--- a/hw/net/vmxnet3.c
++++ b/hw/net/vmxnet3.c
+@@ -2651,6 +2651,11 @@ static const TypeInfo vmxnet3_info = {
+     .instance_size = sizeof(VMXNET3State),
+     .class_init    = vmxnet3_class_init,
+     .instance_init = vmxnet3_instance_init,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { }
++    },
+ };
+ 
+ static void vmxnet3_register_types(void)
+diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
+index 77d8b6f..d185393 100644
+--- a/hw/scsi/vmw_pvscsi.c
++++ b/hw/scsi/vmw_pvscsi.c
+@@ -1300,6 +1300,8 @@ static const TypeInfo pvscsi_info = {
+     .class_init    = pvscsi_class_init,
+     .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
++        { INTERFACE_PCIE_DEVICE },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+         { }
+     }
+ };
+diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
+index 53de805..d92e633 100644
+--- a/hw/usb/hcd-xhci.c
++++ b/hw/usb/hcd-xhci.c
+@@ -3688,6 +3688,11 @@ static const TypeInfo xhci_info = {
+     .instance_size = sizeof(XHCIState),
+     .class_init    = xhci_class_init,
+     .abstract      = true,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { }
++    },
+ };
+ 
+ static void qemu_xhci_class_init(ObjectClass *klass, void *data)
+diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
+index f3f1ce6..b3a2889 100644
+--- a/hw/vfio/pci.c
++++ b/hw/vfio/pci.c
+@@ -3036,6 +3036,11 @@ static const TypeInfo vfio_pci_dev_info = {
+     .class_init = vfio_pci_dev_class_init,
+     .instance_init = vfio_instance_init,
+     .instance_finalize = vfio_instance_finalize,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { }
++    },
+ };
+ 
+ static void register_vfio_pci_dev_type(void)
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index 8208aa2..6e497c8 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -1958,6 +1958,11 @@ static const TypeInfo virtio_pci_info = {
+     .class_init    = virtio_pci_class_init,
+     .class_size    = sizeof(VirtioPCIClass),
+     .abstract      = true,
++    .interfaces = (InterfaceInfo[]) {
++        { INTERFACE_PCIE_DEVICE },
++        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { }
++    },
+ };
+ 
+ /* virtio-blk-pci */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pci-Validate-interfaces-on-base_class_init.patch b/SOURCES/kvm-pci-Validate-interfaces-on-base_class_init.patch
new file mode 100644
index 0000000..972a64d
--- /dev/null
+++ b/SOURCES/kvm-pci-Validate-interfaces-on-base_class_init.patch
@@ -0,0 +1,62 @@
+From 091efe6a8488e0eac52d78fd5db2db76efb891d3 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:17 +0200
+Subject: [PATCH 12/19] pci: Validate interfaces on base_class_init
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-8-ehabkost@redhat.com>
+Patchwork-id: 77427
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 7/7] pci: Validate interfaces on base_class_init
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Make sure we don't forget to add the Conventional PCI or PCI
+Express interface names on PCI device classes in the future.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Revieed-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 2fefa16cec5a719f5cbc26c0672dd2099cd2ed9b)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci/pci.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 1226696..f0c98cd 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -2525,6 +2525,17 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
+     pc->realize = pci_default_realize;
+ }
+ 
++static void pci_device_class_base_init(ObjectClass *klass, void *data)
++{
++    if (!object_class_is_abstract(klass)) {
++        ObjectClass *conventional =
++            object_class_dynamic_cast(klass, INTERFACE_CONVENTIONAL_PCI_DEVICE);
++        ObjectClass *pcie =
++            object_class_dynamic_cast(klass, INTERFACE_PCIE_DEVICE);
++        assert(conventional || pcie);
++    }
++}
++
+ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
+ {
+     PCIBus *bus = PCI_BUS(dev->bus);
+@@ -2649,6 +2660,7 @@ static const TypeInfo pci_device_type_info = {
+     .abstract = true,
+     .class_size = sizeof(PCIDeviceClass),
+     .class_init = pci_device_class_init,
++    .class_base_init = pci_device_class_base_init,
+ };
+ 
+ static void pci_register_types(void)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pci-bus-let-it-has-higher-migration-priority.patch b/SOURCES/kvm-pci-bus-let-it-has-higher-migration-priority.patch
new file mode 100644
index 0000000..7b35ea8
--- /dev/null
+++ b/SOURCES/kvm-pci-bus-let-it-has-higher-migration-priority.patch
@@ -0,0 +1,159 @@
+From a80ee7295748aeadc1e2c37a71ee46699c9324cb Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Fri, 9 Feb 2018 06:02:44 +0100
+Subject: [PATCH 03/15] pci/bus: let it has higher migration priority
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20180209060244.17420-1-peterx@redhat.com>
+Patchwork-id: 78963
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] pci/bus: let it has higher migration priority
+Bugzilla: 1538953
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+NOTE: downstream does not have hw/pci-bridge/pcie_pci_bridge.c, so the
+      original change to that file is not needed.
+
+In the past, we prioritized IOMMU migration so that we have such a
+priority order:
+
+    IOMMU > PCI Devices
+
+When migrating a guest with both vIOMMU and a pcie-root-port, we'll
+always migrate vIOMMU first, since pci buses will be seen to have the
+same priority of general PCI devices.
+
+That's problematic.
+
+The thing is that PCI bus number information is stored in the root port,
+and that is needed by vIOMMU during post_load(), e.g., to figure out
+context entry for a device.  If we don't have correct bus numbers for
+devices, we won't be able to recover device state of the DMAR memory
+regions, and things will be messed up.
+
+So let's boost the PCIe root ports to be even with higher priority:
+
+   PCIe Root Port > IOMMU > PCI Devices
+
+A smoke test shows that this patch fixes bug 1538953.
+
+Also, apply this rule to all the PCI bus/bridge devices: ioh3420,
+xio3130_downstream, xio3130_upstream, pcie_pci_bridge, pci-pci bridge,
+i82801b11.
+
+I noted that we set pcie_pci_bridge_dev_vmstate twice.  Clean that up
+together.
+
+CC: Alex Williamson <alex.williamson@redhat.com>
+CC: Marcel Apfelbaum <marcel@redhat.com>
+CC: Michael S. Tsirkin <mst@redhat.com>
+CC: Dr. David Alan Gilbert <dgilbert@redhat.com>
+CC: Juan Quintela <quintela@redhat.com>
+CC: Laurent Vivier <lvivier@redhat.com>
+Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1538953
+Reported-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 9d6b9db19c4b99ce5a1ad75b490c01edd2c2b0cf)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-bridge/gen_pcie_root_port.c | 1 +
+ hw/pci-bridge/i82801b11.c          | 1 +
+ hw/pci-bridge/ioh3420.c            | 1 +
+ hw/pci-bridge/pci_bridge_dev.c     | 1 +
+ hw/pci-bridge/xio3130_downstream.c | 1 +
+ hw/pci-bridge/xio3130_upstream.c   | 1 +
+ include/migration/vmstate.h        | 1 +
+ 7 files changed, 7 insertions(+)
+
+diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
+index 0e2f2e8..435fbaa 100644
+--- a/hw/pci-bridge/gen_pcie_root_port.c
++++ b/hw/pci-bridge/gen_pcie_root_port.c
+@@ -101,6 +101,7 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
+ 
+ static const VMStateDescription vmstate_rp_dev = {
+     .name = "pcie-root-port",
++    .priority = MIG_PRI_PCI_BUS,
+     .version_id = 1,
+     .minimum_version_id = 1,
+     .post_load = pcie_cap_slot_post_load,
+diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
+index cb522bf..60df9b2 100644
+--- a/hw/pci-bridge/i82801b11.c
++++ b/hw/pci-bridge/i82801b11.c
+@@ -80,6 +80,7 @@ err_bridge:
+ 
+ static const VMStateDescription i82801b11_bridge_dev_vmstate = {
+     .name = "i82801b11_bridge",
++    .priority = MIG_PRI_PCI_BUS,
+     .fields = (VMStateField[]) {
+         VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
+         VMSTATE_END_OF_LIST()
+diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
+index da4e5bd..a26d104 100644
+--- a/hw/pci-bridge/ioh3420.c
++++ b/hw/pci-bridge/ioh3420.c
+@@ -85,6 +85,7 @@ static void ioh3420_interrupts_uninit(PCIDevice *d)
+ 
+ static const VMStateDescription vmstate_ioh3420 = {
+     .name = "ioh-3240-express-root-port",
++    .priority = MIG_PRI_PCI_BUS,
+     .version_id = 1,
+     .minimum_version_id = 1,
+     .post_load = pcie_cap_slot_post_load,
+diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
+index d56f663..b2d861d 100644
+--- a/hw/pci-bridge/pci_bridge_dev.c
++++ b/hw/pci-bridge/pci_bridge_dev.c
+@@ -174,6 +174,7 @@ static bool pci_device_shpc_present(void *opaque, int version_id)
+ 
+ static const VMStateDescription pci_bridge_dev_vmstate = {
+     .name = "pci_bridge",
++    .priority = MIG_PRI_PCI_BUS,
+     .fields = (VMStateField[]) {
+         VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
+         SHPC_VMSTATE(shpc, PCIDevice, pci_device_shpc_present),
+diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
+index 1e09d2a..4dd2e65 100644
+--- a/hw/pci-bridge/xio3130_downstream.c
++++ b/hw/pci-bridge/xio3130_downstream.c
+@@ -161,6 +161,7 @@ static Property xio3130_downstream_props[] = {
+ 
+ static const VMStateDescription vmstate_xio3130_downstream = {
+     .name = "xio3130-express-downstream-port",
++    .priority = MIG_PRI_PCI_BUS,
+     .version_id = 1,
+     .minimum_version_id = 1,
+     .post_load = pcie_cap_slot_post_load,
+diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
+index 227997c..c5f02a6 100644
+--- a/hw/pci-bridge/xio3130_upstream.c
++++ b/hw/pci-bridge/xio3130_upstream.c
+@@ -133,6 +133,7 @@ PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction,
+ 
+ static const VMStateDescription vmstate_xio3130_upstream = {
+     .name = "xio3130-express-upstream-port",
++    .priority = MIG_PRI_PCI_BUS,
+     .version_id = 1,
+     .minimum_version_id = 1,
+     .fields = (VMStateField[]) {
+diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
+index 85e43da..d23555b 100644
+--- a/include/migration/vmstate.h
++++ b/include/migration/vmstate.h
+@@ -148,6 +148,7 @@ enum VMStateFlags {
+ typedef enum {
+     MIG_PRI_DEFAULT = 0,
+     MIG_PRI_IOMMU,              /* Must happen before PCI devices */
++    MIG_PRI_PCI_BUS,            /* Must happen before IOMMU */
+     MIG_PRI_GICV3_ITS,          /* Must happen before PCI devices */
+     MIG_PRI_GICV3,              /* Must happen before the ITS */
+     MIG_PRI_MAX,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pci-conventional-pci-device-and-pci-express-device-i.patch b/SOURCES/kvm-pci-conventional-pci-device-and-pci-express-device-i.patch
new file mode 100644
index 0000000..f869465
--- /dev/null
+++ b/SOURCES/kvm-pci-conventional-pci-device-and-pci-express-device-i.patch
@@ -0,0 +1,83 @@
+From e4794a20f02368af6260ed3b4d9e040b41734459 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:12 +0200
+Subject: [PATCH 07/19] pci: conventional-pci-device and pci-express-device
+ interfaces
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-3-ehabkost@redhat.com>
+Patchwork-id: 77422
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 2/7] pci: conventional-pci-device and pci-express-device interfaces
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Those two interfaces will be used to indicate which device types
+support Conventional PCI or PCI Express buses.  Management
+software will be able to use the qom-list-types QMP command to
+query that information.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 619f02aefc587e5e2821cd84b584eba199c97c9e)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci/pci.c         | 12 ++++++++++++
+ include/hw/pci/pci.h |  6 ++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 258fbe5..1226696 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -168,6 +168,16 @@ static const TypeInfo pci_bus_info = {
+     .class_init = pci_bus_class_init,
+ };
+ 
++static const TypeInfo pcie_interface_info = {
++    .name          = INTERFACE_PCIE_DEVICE,
++    .parent        = TYPE_INTERFACE,
++};
++
++static const TypeInfo conventional_pci_interface_info = {
++    .name          = INTERFACE_CONVENTIONAL_PCI_DEVICE,
++    .parent        = TYPE_INTERFACE,
++};
++
+ static const TypeInfo pcie_bus_info = {
+     .name = TYPE_PCIE_BUS,
+     .parent = TYPE_PCI_BUS,
+@@ -2645,6 +2655,8 @@ static void pci_register_types(void)
+ {
+     type_register_static(&pci_bus_info);
+     type_register_static(&pcie_bus_info);
++    type_register_static(&conventional_pci_interface_info);
++    type_register_static(&pcie_interface_info);
+     type_register_static(&pci_device_type_info);
+ }
+ 
+diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
+index e598b09..cc6f5d2 100644
+--- a/include/hw/pci/pci.h
++++ b/include/hw/pci/pci.h
+@@ -195,6 +195,12 @@ enum {
+ #define PCI_DEVICE_GET_CLASS(obj) \
+      OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE)
+ 
++/* Implemented by devices that can be plugged on PCI Express buses */
++#define INTERFACE_PCIE_DEVICE "pci-express-device"
++
++/* Implemented by devices that can be plugged on Conventional PCI buses */
++#define INTERFACE_CONVENTIONAL_PCI_DEVICE "conventional-pci-device"
++
+ typedef struct PCIINTxRoute {
+     enum {
+         PCI_INTX_ENABLED,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pcie_root_port-Fix-x-migrate-msix-compat.patch b/SOURCES/kvm-pcie_root_port-Fix-x-migrate-msix-compat.patch
new file mode 100644
index 0000000..c2f317c
--- /dev/null
+++ b/SOURCES/kvm-pcie_root_port-Fix-x-migrate-msix-compat.patch
@@ -0,0 +1,63 @@
+From 917c9e7df753cd941ddb6f8a8212bd1a45bf3d09 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 15 Nov 2017 12:29:19 +0100
+Subject: [PATCH 05/30] pcie_root_port: Fix x-migrate-msix compat
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171115122920.7207-2-dgilbert@redhat.com>
+Patchwork-id: 77679
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/2] pcie_root_port: Fix x-migrate-msix compat
+Bugzilla: 1511312
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+2.9 gained a property, x-migrate-msix, on pcie-root-ports
+to enable migration of the msix data, it defaulted to on but
+was marked as off for backwards compatibility on old machine
+types.  We picked up this compatibility entry for
+HW_COMPAT_RHEL7_4.
+
+However, this had already been backported to 7.4
+(b131cb258ae, bz 1455150) and since this device was new downstream
+in 7.4 there was no need for a compatibility entry.
+
+Remove the compatibility entry so that x-migrate-msix is true
+for all our machine types just like it is in 7.4.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/hw/compat.h | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/include/hw/compat.h b/include/hw/compat.h
+index 7a2a4a6..3f9d356 100644
+--- a/include/hw/compat.h
++++ b/include/hw/compat.h
+@@ -414,18 +414,14 @@
+     },
+ 
+ /* Mostly like HW_COMPAT_2_9 except
+- * x-mtu-bypass-backend has already been
+- * backported to RHEL7.4
++ * x-mtu-bypass-backend, x-migrate-msix has already been
++ * backported to RHEL7.4. shpc was already on in 7.4.
+  */
+ #define HW_COMPAT_RHEL7_4 \
+     { /* HW_COMPAT_RHEL7_4 */ \
+         .driver   = "intel-iommu",\
+         .property = "pt",\
+         .value    = "off",\
+-    },{ /* HW_COMPAT_RHEL7_4 */ \
+-        .driver   = "pcie-root-port",\
+-        .property = "x-migrate-msix",\
+-        .value    = "false",\
+     },
+ 
+ #endif /* HW_COMPAT_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ppc-Change-Power9-compat-table-to-support-at-most-8-.patch b/SOURCES/kvm-ppc-Change-Power9-compat-table-to-support-at-most-8-.patch
new file mode 100644
index 0000000..903a9d9
--- /dev/null
+++ b/SOURCES/kvm-ppc-Change-Power9-compat-table-to-support-at-most-8-.patch
@@ -0,0 +1,59 @@
+From ff6a3c436c561a73b00e8dbe4b5c8dc52ecfda40 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 04:04:55 +0100
+Subject: [PATCH 15/21] ppc: Change Power9 compat table to support at most 8
+ threads/core
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119040458.5629-2-dgibson@redhat.com>
+Patchwork-id: 78675
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/4] ppc: Change Power9 compat table to support at most 8 threads/core
+Bugzilla: 1529243
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
+
+Increases the max smt mode to 8 for Power9. That's because KVM supports
+smt emulation in this platform so QEMU should allow users to use it as
+well.
+
+Today if we try to pass -smp ...,threads=8, QEMU will silently truncate
+it to smt4 mode and may cause a crash if we try to perform a cpu
+hotplug.
+
+Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
+[dwg: Added an explanatory comment]
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 03ee51d3548f5f553a3089f466483c1c6d5c666b)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/ppc/compat.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/target/ppc/compat.c b/target/ppc/compat.c
+index 2d95434..94ff14a 100644
+--- a/target/ppc/compat.c
++++ b/target/ppc/compat.c
+@@ -73,7 +73,14 @@ static const CompatInfo compat_table[] = {
+         .pvr = CPU_POWERPC_LOGICAL_3_00,
+         .pcr = PCR_COMPAT_3_00,
+         .pcr_level = PCR_COMPAT_3_00,
+-        .max_threads = 4,
++        /*
++         * POWER9 hardware only supports 4 threads / core, but this
++         * limit is for guests.  We need to support 8 vthreads/vcore
++         * on POWER9 for POWER8 compatibility guests, and it's very
++         * confusing if half of the threads disappear from the guest
++         * if it announces it's POWER9 aware at CAS time.
++         */
++        .max_threads = 8,
+     },
+ };
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ppc-fix-VTB-migration.patch b/SOURCES/kvm-ppc-fix-VTB-migration.patch
new file mode 100644
index 0000000..abd373e
--- /dev/null
+++ b/SOURCES/kvm-ppc-fix-VTB-migration.patch
@@ -0,0 +1,70 @@
+From 43f0b133d1312d042fb31bf7f63bb31a642eef26 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Thu, 23 Nov 2017 16:14:21 +0100
+Subject: [PATCH 3/7] ppc: fix VTB migration
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171123161421.30320-1-lvivier@redhat.com>
+Patchwork-id: 77796
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] ppc: fix VTB migration
+Bugzilla: 1506882
+RH-Acked-by: Serhii Popovych <spopovyc@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Migration of a system under stress (for example, with
+"stress-ng --numa 2") triggers on the destination
+some kernel watchdog messages like:
+
+NMI watchdog: BUG: soft lockup - CPU#0 stuck for 3489660870s!
+NMI watchdog: BUG: soft lockup - CPU#1 stuck for 3489660884s!
+
+This problem appears with the changes introduced by
+    42043e4 spapr: clock should count only if vm is running
+
+I think this commit only triggers the problem.
+
+Kernel computes the soft lockup duration using the
+Virtual Timebase register (VTB), not using the Timebase
+Register (TBR, the one 42043e4 stops).
+
+It appears VTB is not migrated, so this patch adds it in
+the list of the SPRs to migrate, and fixes the problem.
+
+For the migration, I've tested a migration from qemu-2.8.0 and
+pseries-2.8.0 to a patched master (qemu-2.11.0-rc1). The received
+VTB is 0 (as is it not initialized by qemu-2.8.0), but the value
+seems to be ignored by KVM and a non zero VTB is used by the kernel.
+I have no explanation for that, but as the original problem appears
+only with SMP system under stress I suspect some problems in KVM
+(I think because VTB is shared by all threads of a core).
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 6dd836f5d32b989e18c6dda655a26f4d73a52f6a)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/ppc/translate_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
+index 371bbae..9d38882 100644
+--- a/target/ppc/translate_init.c
++++ b/target/ppc/translate_init.c
+@@ -8168,10 +8168,10 @@ static void gen_spr_power8_ebb(CPUPPCState *env)
+ /* Virtual Time Base */
+ static void gen_spr_vtb(CPUPPCState *env)
+ {
+-    spr_register(env, SPR_VTB, "VTB",
++    spr_register_kvm(env, SPR_VTB, "VTB",
+                  SPR_NOACCESS, SPR_NOACCESS,
+                  &spr_read_tbl, SPR_NOACCESS,
+-                 0x00000000);
++                 KVM_REG_PPC_VTB, 0x00000000);
+ }
+ 
+ static void gen_spr_power8_fscr(CPUPPCState *env)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ppc-fix-setting-of-compat-mode.patch b/SOURCES/kvm-ppc-fix-setting-of-compat-mode.patch
new file mode 100644
index 0000000..32cad00
--- /dev/null
+++ b/SOURCES/kvm-ppc-fix-setting-of-compat-mode.patch
@@ -0,0 +1,76 @@
+From 7f958a52f5e8e4dd02182b308c96d5bde25a1327 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Wed, 6 Dec 2017 02:57:59 +0100
+Subject: [PATCH 19/21] ppc: fix setting of compat mode
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1512529079-12590-1-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78173
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH] ppc: fix setting of compat mode
+Bugzilla: 1396119
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+While trying to make KVM PR usable again, commit 5dfaa532ae introduced a
+regression: the current compat_pvr value is passed to KVM instead of the
+new one. This means that we always pass 0 instead of the max-cpu-compat
+PVR during the initial machine reset. And at CAS time, we either pass
+the PVR from the command line or even don't call kvmppc_set_compat() at
+all, ie, the PCR will not be set as expected.
+
+For example if we start a big endian fedora26 guest in power7 compat
+mode on a POWER8 host, we get this in the guest:
+
+$ cat /proc/cpuinfo
+processor       : 0
+cpu             : POWER7 (architected), altivec supported
+clock           : 4024.000000MHz
+revision        : 2.0 (pvr 004d 0200)
+
+timebase        : 512000000
+platform        : pSeries
+model           : IBM pSeries (emulated by qemu)
+machine         : CHRP IBM pSeries (emulated by qemu)
+MMU             : Hash
+
+but the guest can still execute POWER8 instructions, and the following
+program succeeds:
+
+int main()
+{
+        asm("vncipher 0,0,0"); // ISA 2.07 instruction
+}
+
+Let's pass the new compat_pvr to kvmppc_set_compat() and the program fails
+with SIGILL as expected.
+
+Reported-by: Nageswara R Sastry <rnsastry@linux.vnet.ibm.com>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit e4f0c6bb1a9f72ad9e32c3171d36bae17ea1cd67)
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/ppc/compat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/target/ppc/compat.c b/target/ppc/compat.c
+index 540b4eb..2d95434 100644
+--- a/target/ppc/compat.c
++++ b/target/ppc/compat.c
+@@ -152,7 +152,7 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp)
+     cpu_synchronize_state(CPU(cpu));
+ 
+     if (kvm_enabled() && cpu->compat_pvr != compat_pvr) {
+-        int ret = kvmppc_set_compat(cpu, cpu->compat_pvr);
++        int ret = kvmppc_set_compat(cpu, compat_pvr);
+         if (ret < 0) {
+             error_setg_errno(errp, -ret,
+                              "Unable to set CPU compatibility mode in KVM");
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-q35-Fix-mismerge.patch b/SOURCES/kvm-q35-Fix-mismerge.patch
new file mode 100644
index 0000000..0ab0a8f
--- /dev/null
+++ b/SOURCES/kvm-q35-Fix-mismerge.patch
@@ -0,0 +1,43 @@
+From b0c06140414df1c0637c3d06f67e0292c31f967d Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 15 Nov 2017 12:29:20 +0100
+Subject: [PATCH 06/30] q35: Fix mismerge
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171115122920.7207-3-dgilbert@redhat.com>
+Patchwork-id: 77677
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 2/2] q35: Fix mismerge
+Bugzilla: 1511312
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+There's a mismerged line calling SET_MACHINE_COMPAT for the
+RHEL macro in the base pc_q35_machine_option that's ifdef'd
+out, it's correctly called later in pc_q35_machine_rhel7_options.
+
+Clean it up (should be no effect).
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/i386/pc_q35.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
+index 27c85c5..0818a96 100644
+--- a/hw/i386/pc_q35.c
++++ b/hw/i386/pc_q35.c
+@@ -301,7 +301,6 @@ static void pc_q35_machine_options(MachineClass *m)
+     m->no_floppy = 1;
+     m->has_dynamic_sysbus = true;
+     m->max_cpus = 288;
+-    SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT);
+ }
+ 
+ static void pc_q35_2_10_machine_options(MachineClass *m)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-Always-execute-preallocate-in-a-coroutine.patch b/SOURCES/kvm-qcow2-Always-execute-preallocate-in-a-coroutine.patch
new file mode 100644
index 0000000..453efad
--- /dev/null
+++ b/SOURCES/kvm-qcow2-Always-execute-preallocate-in-a-coroutine.patch
@@ -0,0 +1,113 @@
+From 98ebc4e55985747726bbcbedecbe06fed8d7ea0a Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Mon, 27 Nov 2017 16:19:58 +0100
+Subject: [PATCH 03/21] qcow2: Always execute preallocate() in a coroutine
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20171127161959.13234-4-mreitz@redhat.com>
+Patchwork-id: 77913
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 3/4] qcow2: Always execute preallocate() in a coroutine
+Bugzilla: 1414049
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Some qcow2 functions (at least perform_cow()) expect s->lock to be
+taken.  Therefore, if we want to make use of them, we should execute
+preallocate() (as "preallocate_co") in a coroutine so that we can use
+the qemu_co_mutex_* functions.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20171009215533.12530-3-mreitz@redhat.com
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 572b07bea1d1a0f7726fd95c2613c76002a379bc)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/qcow2.c | 41 ++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 34 insertions(+), 7 deletions(-)
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 2cfe706..b26cbbf 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -2476,6 +2476,14 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
+ }
+ 
+ 
++typedef struct PreallocCo {
++    BlockDriverState *bs;
++    uint64_t offset;
++    uint64_t new_length;
++
++    int ret;
++} PreallocCo;
++
+ /**
+  * Preallocates metadata structures for data clusters between @offset (in the
+  * guest disk) and @new_length (which is thus generally the new guest disk
+@@ -2483,9 +2491,12 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
+  *
+  * Returns: 0 on success, -errno on failure.
+  */
+-static int preallocate(BlockDriverState *bs,
+-                       uint64_t offset, uint64_t new_length)
++static void coroutine_fn preallocate_co(void *opaque)
+ {
++    PreallocCo *params = opaque;
++    BlockDriverState *bs = params->bs;
++    uint64_t offset = params->offset;
++    uint64_t new_length = params->new_length;
+     BDRVQcow2State *s = bs->opaque;
+     uint64_t bytes;
+     uint64_t host_offset = 0;
+@@ -2493,9 +2504,7 @@ static int preallocate(BlockDriverState *bs,
+     int ret;
+     QCowL2Meta *meta;
+ 
+-    if (qemu_in_coroutine()) {
+-        qemu_co_mutex_lock(&s->lock);
+-    }
++    qemu_co_mutex_lock(&s->lock);
+ 
+     assert(offset <= new_length);
+     bytes = new_length - offset;
+@@ -2549,10 +2558,28 @@ static int preallocate(BlockDriverState *bs,
+     ret = 0;
+ 
+ done:
++    qemu_co_mutex_unlock(&s->lock);
++    params->ret = ret;
++}
++
++static int preallocate(BlockDriverState *bs,
++                       uint64_t offset, uint64_t new_length)
++{
++    PreallocCo params = {
++        .bs         = bs,
++        .offset     = offset,
++        .new_length = new_length,
++        .ret        = -EINPROGRESS,
++    };
++
+     if (qemu_in_coroutine()) {
+-        qemu_co_mutex_unlock(&s->lock);
++        preallocate_co(&params);
++    } else {
++        Coroutine *co = qemu_coroutine_create(preallocate_co, &params);
++        bdrv_coroutine_enter(bs, co);
++        BDRV_POLL_WHILE(bs, params.ret == -EINPROGRESS);
+     }
+-    return ret;
++    return params.ret;
+ }
+ 
+ /* qcow2_refcount_metadata_size:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-Fix-unaligned-preallocated-truncation.patch b/SOURCES/kvm-qcow2-Fix-unaligned-preallocated-truncation.patch
new file mode 100644
index 0000000..924ef3d
--- /dev/null
+++ b/SOURCES/kvm-qcow2-Fix-unaligned-preallocated-truncation.patch
@@ -0,0 +1,51 @@
+From f2c23150bc8b51e7b6c78f98cc38880ff1e5e811 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Mon, 27 Nov 2017 16:19:57 +0100
+Subject: [PATCH 02/21] qcow2: Fix unaligned preallocated truncation
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20171127161959.13234-3-mreitz@redhat.com>
+Patchwork-id: 77911
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 2/4] qcow2: Fix unaligned preallocated truncation
+Bugzilla: 1414049
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+A qcow2 image file's length is not required to have a length that is a
+multiple of the cluster size.  However, qcow2_refcount_area() expects an
+aligned value for its @start_offset parameter, so we need to round
+@old_file_size up to the next cluster boundary.
+
+Reported-by: Ping Li <pingl@redhat.com>
+Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1414049
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20171009215533.12530-2-mreitz@redhat.com
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit e400ad1e1f0127b4fdabcb1c8de1e99be91788df)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/qcow2.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index af7b1e7..2cfe706 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3161,6 +3161,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
+                              "Failed to inquire current file length");
+             return old_file_size;
+         }
++        old_file_size = ROUND_UP(old_file_size, s->cluster_size);
+ 
+         nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
+                                             s->cluster_size);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-don-t-permit-changing-encryption-parameters.patch b/SOURCES/kvm-qcow2-don-t-permit-changing-encryption-parameters.patch
new file mode 100644
index 0000000..3f12d48
--- /dev/null
+++ b/SOURCES/kvm-qcow2-don-t-permit-changing-encryption-parameters.patch
@@ -0,0 +1,46 @@
+From e28736d3d0b2e1a8bf4e9d0bb9c6bca8d972b043 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 29 Nov 2017 15:09:19 +0100
+Subject: [PATCH 01/36] qcow2: don't permit changing encryption parameters
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171129150920.8539-2-berrange@redhat.com>
+Patchwork-id: 77973
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 1/2] qcow2: don't permit changing encryption parameters
+Bugzilla: 1406803
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Currently if trying to change encryption parameters on a qcow2 image, qemu-img
+will abort. We already explicitly check for attempt to change encrypt.format
+but missed other parameters like encrypt.key-secret. Rather than list each
+parameter, just blacklist changing of all parameters with a 'encrypt.' prefix.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit f66afbe26f0c093d639610d70d16d7cc3183b652)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/qcow2.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index b26cbbf..6e8f753 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -4044,6 +4044,9 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
+                 error_report("Changing the encryption format is not supported");
+                 return -ENOTSUP;
+             }
++        } else if (g_str_has_prefix(desc->name, "encrypt.")) {
++            error_report("Changing the encryption parameters is not supported");
++            return -ENOTSUP;
+         } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) {
+             cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE,
+                                              cluster_size);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-fix-image-corruption-after-committing-qcow2-im.patch b/SOURCES/kvm-qcow2-fix-image-corruption-after-committing-qcow2-im.patch
new file mode 100644
index 0000000..37aaaf8
--- /dev/null
+++ b/SOURCES/kvm-qcow2-fix-image-corruption-after-committing-qcow2-im.patch
@@ -0,0 +1,331 @@
+From 97c8bc6029a1f88ee5bd737b2bf257139d533fea Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 29 Nov 2017 15:09:20 +0100
+Subject: [PATCH 02/36] qcow2: fix image corruption after committing qcow2
+ image into base
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171129150920.8539-3-berrange@redhat.com>
+Patchwork-id: 77975
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 2/2] qcow2: fix image corruption after committing qcow2 image into base
+Bugzilla: 1406803
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+After committing the qcow2 image contents into the base image, qemu-img
+will call bdrv_make_empty to drop the payload in the layered image.
+
+When this is done for qcow2 images, it blows away the LUKS encryption
+header, making the resulting image unusable. There are two codepaths
+for emptying a qcow2 image, and the second (slower) codepath leaves
+the LUKS header intact, so force use of that codepath.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit f06033295b51d4868c2b4921ad2287e8f55eb688)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+  tests/qemu-iotests/group - some earlier tests don't exist yet
+---
+ block/qcow2.c                    |   6 +-
+ tests/qemu-iotests/198           | 104 ++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/198.out       | 126 +++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/common.filter |   4 +-
+ tests/qemu-iotests/group         |   1 +
+ 5 files changed, 238 insertions(+), 3 deletions(-)
+ create mode 100755 tests/qemu-iotests/198
+ create mode 100644 tests/qemu-iotests/198.out
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 6e8f753..a51efcc 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3567,12 +3567,14 @@ static int qcow2_make_empty(BlockDriverState *bs)
+     l1_clusters = DIV_ROUND_UP(s->l1_size, s->cluster_size / sizeof(uint64_t));
+ 
+     if (s->qcow_version >= 3 && !s->snapshots &&
+-        3 + l1_clusters <= s->refcount_block_size) {
++        3 + l1_clusters <= s->refcount_block_size &&
++        s->crypt_method_header != QCOW_CRYPT_LUKS) {
+         /* The following function only works for qcow2 v3 images (it requires
+          * the dirty flag) and only as long as there are no snapshots (because
+          * it completely empties the image). Furthermore, the L1 table and three
+          * additional clusters (image header, refcount table, one refcount
+-         * block) have to fit inside one refcount block. */
++         * block) have to fit inside one refcount block. It cannot be used
++         * for LUKS (yet) as it throws away the LUKS header cluster(s) */
+         return make_completely_empty(bs);
+     }
+ 
+diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198
+new file mode 100755
+index 0000000..34ef666
+--- /dev/null
++++ b/tests/qemu-iotests/198
+@@ -0,0 +1,104 @@
++#!/bin/bash
++#
++# Test commit of encrypted qcow2 files
++#
++# Copyright (C) 2017 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++
++# creator
++owner=berrange@redhat.com
++
++seq=`basename $0`
++echo "QA output created by $seq"
++
++here=`pwd`
++status=1	# failure is the default!
++
++_cleanup()
++{
++	_cleanup_test_img
++}
++trap "_cleanup; exit \$status" 0 1 2 3 15
++
++# get standard environment, filters and checks
++. ./common.rc
++. ./common.filter
++
++_supported_fmt qcow2
++_supported_proto generic
++_supported_os Linux
++
++
++size=16M
++TEST_IMG_BASE=$TEST_IMG.base
++SECRET0="secret,id=sec0,data=astrochicken"
++SECRET1="secret,id=sec1,data=furby"
++
++TEST_IMG_SAVE=$TEST_IMG
++TEST_IMG=$TEST_IMG_BASE
++echo "== create base =="
++_make_test_img --object $SECRET0 -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10" $size
++TEST_IMG=$TEST_IMG_SAVE
++
++IMGSPECBASE="driver=$IMGFMT,file.filename=$TEST_IMG_BASE,encrypt.key-secret=sec0"
++IMGSPECLAYER="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec1"
++IMGSPEC="$IMGSPECLAYER,backing.driver=$IMGFMT,backing.file.filename=$TEST_IMG_BASE,backing.encrypt.key-secret=sec0"
++QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
++
++echo
++echo "== writing whole image base =="
++$QEMU_IO --object $SECRET0 -c "write -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
++
++echo "== create overlay =="
++_make_test_img --object $SECRET1 -o "encrypt.format=luks,encrypt.key-secret=sec1,encrypt.iter-time=10" -u -b "$TEST_IMG_BASE" $size
++
++echo
++echo "== writing whole image layer =="
++$QEMU_IO --object $SECRET0 --object $SECRET1 -c "write -P 0x9 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
++
++echo
++echo "== verify pattern base =="
++$QEMU_IO --object $SECRET0 -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
++
++echo
++echo "== verify pattern layer =="
++$QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0x9 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
++
++echo
++echo "== committing layer into base =="
++$QEMU_IMG commit --object $SECRET0 --object $SECRET1 --image-opts $IMGSPEC | _filter_testdir
++
++echo
++echo "== verify pattern base =="
++$QEMU_IO --object $SECRET0 -c "read -P 0x9 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
++
++echo
++echo "== verify pattern layer =="
++$QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0x9 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
++
++echo
++echo "== checking image base =="
++$QEMU_IMG info --image-opts $IMGSPECBASE | _filter_img_info | _filter_testdir | sed -e "/^disk size:/ D"
++
++echo
++echo "== checking image layer =="
++$QEMU_IMG info --image-opts $IMGSPECLAYER | _filter_img_info | _filter_testdir | sed -e "/^disk size:/ D"
++
++
++# success, all done
++echo "*** done"
++rm -f $seq.full
++status=0
+diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
+new file mode 100644
+index 0000000..2db565e
+--- /dev/null
++++ b/tests/qemu-iotests/198.out
+@@ -0,0 +1,126 @@
++QA output created by 198
++== create base ==
++Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
++
++== writing whole image base ==
++wrote 16777216/16777216 bytes at offset 0
++16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++== create overlay ==
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base encrypt.format=luks encrypt.key-secret=sec1 encrypt.iter-time=10
++
++== writing whole image layer ==
++wrote 16777216/16777216 bytes at offset 0
++16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== verify pattern base ==
++read 16777216/16777216 bytes at offset 0
++16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== verify pattern layer ==
++read 16777216/16777216 bytes at offset 0
++16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== committing layer into base ==
++Image committed.
++
++== verify pattern base ==
++read 16777216/16777216 bytes at offset 0
++16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== verify pattern layer ==
++read 16777216/16777216 bytes at offset 0
++16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== checking image base ==
++image: json:{"encrypt.key-secret": "sec0", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.base"}}
++file format: IMGFMT
++virtual size: 16M (16777216 bytes)
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    refcount bits: 16
++    encrypt:
++        ivgen alg: plain64
++        hash alg: sha256
++        cipher alg: aes-256
++        uuid: 00000000-0000-0000-0000-000000000000
++        format: luks
++        cipher mode: xts
++        slots:
++            [0]:
++                active: true
++                iters: 1024
++                key offset: 4096
++                stripes: 4000
++            [1]:
++                active: false
++                key offset: 262144
++            [2]:
++                active: false
++                key offset: 520192
++            [3]:
++                active: false
++                key offset: 778240
++            [4]:
++                active: false
++                key offset: 1036288
++            [5]:
++                active: false
++                key offset: 1294336
++            [6]:
++                active: false
++                key offset: 1552384
++            [7]:
++                active: false
++                key offset: 1810432
++        payload offset: 2068480
++        master key iters: 1024
++    corrupt: false
++
++== checking image layer ==
++image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}
++file format: IMGFMT
++virtual size: 16M (16777216 bytes)
++backing file: TEST_DIR/t.IMGFMT.base
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    refcount bits: 16
++    encrypt:
++        ivgen alg: plain64
++        hash alg: sha256
++        cipher alg: aes-256
++        uuid: 00000000-0000-0000-0000-000000000000
++        format: luks
++        cipher mode: xts
++        slots:
++            [0]:
++                active: true
++                iters: 1024
++                key offset: 4096
++                stripes: 4000
++            [1]:
++                active: false
++                key offset: 262144
++            [2]:
++                active: false
++                key offset: 520192
++            [3]:
++                active: false
++                key offset: 778240
++            [4]:
++                active: false
++                key offset: 1036288
++            [5]:
++                active: false
++                key offset: 1294336
++            [6]:
++                active: false
++                key offset: 1552384
++            [7]:
++                active: false
++                key offset: 1810432
++        payload offset: 2068480
++        master key iters: 1024
++    corrupt: false
++*** done
+diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
+index 9d5442e..b0140d8 100644
+--- a/tests/qemu-iotests/common.filter
++++ b/tests/qemu-iotests/common.filter
+@@ -150,7 +150,9 @@ _filter_img_info()
+         -e "/lazy_refcounts: \\(on\\|off\\)/d" \
+         -e "/block_size: [0-9]\\+/d" \
+         -e "/block_state_zero: \\(on\\|off\\)/d" \
+-        -e "/log_size: [0-9]\\+/d"
++        -e "/log_size: [0-9]\\+/d" \
++        -e "s/iters: [0-9]\\+/iters: 1024/" \
++        -e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/"
+ }
+ 
+ # filter out offsets and file names from qemu-img map; good for both
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 0c2bda3..13760b3 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -188,3 +188,4 @@
+ 190 rw auto quick
+ 192 rw auto quick
+ 194 rw auto migration quick
++198 rw auto
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-fix-return-error-code-in-qcow2_truncate.patch b/SOURCES/kvm-qcow2-fix-return-error-code-in-qcow2_truncate.patch
new file mode 100644
index 0000000..9a098ff
--- /dev/null
+++ b/SOURCES/kvm-qcow2-fix-return-error-code-in-qcow2_truncate.patch
@@ -0,0 +1,55 @@
+From cf6287bc4212ad744d04e72ccdd015b9d9552e23 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Mon, 27 Nov 2017 16:19:56 +0100
+Subject: [PATCH 01/21] qcow2: fix return error code in qcow2_truncate()
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20171127161959.13234-2-mreitz@redhat.com>
+Patchwork-id: 77912
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH 1/4] qcow2: fix return error code in qcow2_truncate()
+Bugzilla: 1414049
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Pavel Butsykin <pbutsykin@virtuozzo.com>
+
+Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20170929121613.25997-2-pbutsykin@virtuozzo.com
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 76a2a30a99c670e9ec1b4a5d976868059c6bc258)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/qcow2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 40ba26c..af7b1e7 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3159,7 +3159,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
+         if (old_file_size < 0) {
+             error_setg_errno(errp, -old_file_size,
+                              "Failed to inquire current file length");
+-            return ret;
++            return old_file_size;
+         }
+ 
+         nb_new_data_clusters = DIV_ROUND_UP(offset - old_length,
+@@ -3188,7 +3188,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
+         if (allocation_start < 0) {
+             error_setg_errno(errp, -allocation_start,
+                              "Failed to resize refcount structures");
+-            return -allocation_start;
++            return allocation_start;
+         }
+ 
+         clusters_allocated = qcow2_alloc_clusters_at(bs, allocation_start,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qdev-defer-DEVICE_DEL-event-until-instance_finalize.patch b/SOURCES/kvm-qdev-defer-DEVICE_DEL-event-until-instance_finalize.patch
new file mode 100644
index 0000000..6462807
--- /dev/null
+++ b/SOURCES/kvm-qdev-defer-DEVICE_DEL-event-until-instance_finalize.patch
@@ -0,0 +1,111 @@
+From 13bceabad00d232b71f34bc62b6bbda3f7279601 Mon Sep 17 00:00:00 2001
+From: Serhii Popovych <spopovyc@redhat.com>
+Date: Thu, 9 Nov 2017 15:30:05 +0100
+Subject: [PATCH 5/7] qdev: defer DEVICE_DEL event until instance_finalize()
+
+RH-Author: Serhii Popovych <spopovyc@redhat.com>
+Message-id: <1510241405-20597-4-git-send-email-spopovyc@redhat.com>
+Patchwork-id: 77631
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/3] qdev: defer DEVICE_DEL event until instance_finalize()
+Bugzilla: 1445460
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Michael Roth <mdroth@linux.vnet.ibm.com>
+
+DEVICE_DEL is currently emitted when a Device is unparented, as
+opposed to when it is finalized. The main design motivation for this
+seems to be that after unparent()/unrealize(), the Device is no
+longer visible to the guest, and thus the operation is complete
+from the perspective of management.
+
+However, there are cases where remaining host-side cleanup is also
+pertinent to management. The is generally handled by treating these
+resources as aspects of the "backend", which can be managed via
+separate interfaces/events, such as blockdev_add/del, netdev_add/del,
+object_add/del, etc, but some devices do not have this level of
+compartmentalization, namely vfio-pci, and possibly to lend themselves
+well to it.
+
+In the case of vfio-pci, the "backend" cleanup happens as part of
+the finalization of the vfio-pci device itself, in particular the
+cleanup of the VFIO group FD. Failing to wait for this cleanup can
+result in tools like libvirt attempting to rebind the device to
+the host while it's still being used by VFIO, which can result in
+host crashes or other misbehavior depending on the host driver.
+
+Deferring DEVICE_DEL still affords us the ability to manage backends
+explicitly, while also addressing cases like vfio-pci's, so we
+implement that approach here.
+
+An alternative proposal involving having VFIO emit a separate event
+to denote completion of host-side cleanup was discussed, but the
+prevailing opinion seems to be that it is not worth the added
+complexity, and leaves the issue open for other Device implementations
+to solve in the future.
+
+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Message-Id: <20171016222315.407-4-mdroth@linux.vnet.ibm.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit f7b879e072ae6839b1b1d1312f48fa7f256397e2)
+Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/core/qdev.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index 418cdac..1111295 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -1069,7 +1069,6 @@ static void device_finalize(Object *obj)
+     NamedGPIOList *ngl, *next;
+ 
+     DeviceState *dev = DEVICE(obj);
+-    qemu_opts_del(dev->opts);
+ 
+     QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
+         QLIST_REMOVE(ngl, node);
+@@ -1080,6 +1079,18 @@ static void device_finalize(Object *obj)
+          * here
+          */
+     }
++
++    /* Only send event if the device had been completely realized */
++    if (dev->pending_deleted_event) {
++        g_assert(dev->canonical_path);
++
++        qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
++                                       &error_abort);
++        g_free(dev->canonical_path);
++        dev->canonical_path = NULL;
++    }
++
++    qemu_opts_del(dev->opts);
+ }
+ 
+ static void device_class_base_init(ObjectClass *class, void *data)
+@@ -1109,16 +1120,6 @@ static void device_unparent(Object *obj)
+         object_unref(OBJECT(dev->parent_bus));
+         dev->parent_bus = NULL;
+     }
+-
+-    /* Only send event if the device had been completely realized */
+-    if (dev->pending_deleted_event) {
+-        g_assert(dev->canonical_path);
+-
+-        qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
+-                                       &error_abort);
+-        g_free(dev->canonical_path);
+-        dev->canonical_path = NULL;
+-    }
+ }
+ 
+ static void device_class_init(ObjectClass *class, void *data)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qdev-store-DeviceState-s-canonical-path-to-use-when-.patch b/SOURCES/kvm-qdev-store-DeviceState-s-canonical-path-to-use-when-.patch
new file mode 100644
index 0000000..3773609
--- /dev/null
+++ b/SOURCES/kvm-qdev-store-DeviceState-s-canonical-path-to-use-when-.patch
@@ -0,0 +1,125 @@
+From a6dae62ef051773c0198f8ebd47a79d8f1157000 Mon Sep 17 00:00:00 2001
+From: Serhii Popovych <spopovyc@redhat.com>
+Date: Thu, 9 Nov 2017 15:30:03 +0100
+Subject: [PATCH 3/7] qdev: store DeviceState's canonical path to use when
+ unparenting
+
+RH-Author: Serhii Popovych <spopovyc@redhat.com>
+Message-id: <1510241405-20597-2-git-send-email-spopovyc@redhat.com>
+Patchwork-id: 77632
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/3] qdev: store DeviceState's canonical path to use when unparenting
+Bugzilla: 1445460
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Michael Roth <mdroth@linux.vnet.ibm.com>
+
+device_unparent(dev, ...) is called when a device is unparented,
+either directly, or as a result of a parent device being
+finalized, and handles some final cleanup for the device. Part
+of this includes emiting a DEVICE_DELETED QMP event to notify
+management, which includes the device's path in the composition
+tree as provided by object_get_canonical_path().
+
+object_get_canonical_path() assumes the device is still connected
+to the machine/root container, and will assert otherwise, but
+in some situations this isn't the case:
+
+If the parent is finalized as a result of object_unparent(), it
+will still be attached to the composition tree at the time any
+children are unparented as a result of that same call to
+object_unparent(). However, in some cases, object_unparent()
+will complete without finalizing the parent device, due to
+lingering references that won't be released till some time later.
+One such example is if the parent has MemoryRegion children (which
+take a ref on their parent), who in turn have AddressSpace's (which
+take a ref on their regions), since those AddressSpaces get cleaned
+up asynchronously by the RCU thread.
+
+In this case qdev:device_unparent() may be called for a child Device
+that no longer has a path to the root/machine container, causing
+object_get_canonical_path() to assert.
+
+Fix this by storing the canonical path during realize() so the
+information will still be available for device_unparent() in such
+cases.
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Message-Id: <20171016222315.407-2-mdroth@linux.vnet.ibm.com>
+[Clear dev->canonical_path at the post_realize_fail label, which is
+ cleaner.  Suggested by David Gibson. - Paolo]
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+(cherry picked from commit 04162f8f4bcf8c9ae2422def4357289b44208c8c)
+Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/core/qdev.c         | 17 ++++++++++++++---
+ include/hw/qdev-core.h |  1 +
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index 606ab53..0019a49 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -928,6 +928,13 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
+             goto post_realize_fail;
+         }
+ 
++        /*
++         * always free/re-initialize here since the value cannot be cleaned up
++         * in device_unrealize due to its usage later on in the unplug path
++         */
++        g_free(dev->canonical_path);
++        dev->canonical_path = object_get_canonical_path(OBJECT(dev));
++
+         if (qdev_get_vmsd(dev)) {
+             if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
+                                                dev->instance_id_alias,
+@@ -984,6 +991,8 @@ child_realize_fail:
+     }
+ 
+ post_realize_fail:
++    g_free(dev->canonical_path);
++    dev->canonical_path = NULL;
+     if (dc->unrealize) {
+         dc->unrealize(dev, NULL);
+     }
+@@ -1102,10 +1111,12 @@ static void device_unparent(Object *obj)
+ 
+     /* Only send event if the device had been completely realized */
+     if (dev->pending_deleted_event) {
+-        gchar *path = object_get_canonical_path(OBJECT(dev));
++        g_assert(dev->canonical_path);
+ 
+-        qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
+-        g_free(path);
++        qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path,
++                                       &error_abort);
++        g_free(dev->canonical_path);
++        dev->canonical_path = NULL;
+     }
+ 
+     qemu_opts_del(dev->opts);
+diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
+index ae31728..9237b68 100644
+--- a/include/hw/qdev-core.h
++++ b/include/hw/qdev-core.h
+@@ -153,6 +153,7 @@ struct DeviceState {
+     /*< public >*/
+ 
+     const char *id;
++    char *canonical_path;
+     bool realized;
+     bool pending_deleted_event;
+     QemuOpts *opts;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-doc-Add-UUID-support-in-initiator-name.patch b/SOURCES/kvm-qemu-doc-Add-UUID-support-in-initiator-name.patch
new file mode 100644
index 0000000..84a8d61
--- /dev/null
+++ b/SOURCES/kvm-qemu-doc-Add-UUID-support-in-initiator-name.patch
@@ -0,0 +1,54 @@
+From 09899daebbc5b41e11de57442939e5b71ac28085 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Thu, 30 Nov 2017 09:25:40 +0100
+Subject: [PATCH 03/36] qemu-doc: Add UUID support in initiator name
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20171130092544.19231-2-famz@redhat.com>
+Patchwork-id: 78017
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 1/5] qemu-doc: Add UUID support in initiator name
+Bugzilla: 1494210
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Fred Rolland <rollandf@gmail.com>
+
+Update doc with the usage of UUID for initiator name.
+
+Related-To: https://bugzilla.redhat.com/1006468
+Signed-off-by: Fred Rolland <frolland@redhat.com>
+Message-id: 20170823084830.30500-1-frolland@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit fb9429ddc124c46731185b2781804d4fd39b658c)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	qemu-doc.texi
+We use "qemu-kvm" in the text instead of "qemu" in downstream.
+---
+ qemu-doc.texi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/qemu-doc.texi b/qemu-doc.texi
+index da0e513..db09b7e 100644
+--- a/qemu-doc.texi
++++ b/qemu-doc.texi
+@@ -1066,10 +1066,11 @@ in a configuration file provided via '-readconfig' or directly on the
+ command line.
+ 
+ If the initiator-name is not specified qemu-kvm will use a default name
+-of 'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
++of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
++virtual machine. If the UUID is not specified qemu will use
++'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
+ virtual machine.
+ 
+-
+ @example
+ Setting a specific initiator name to use when logging in to the target
+ -iscsi initiator-name=iqn.qemu.test:my-initiator
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-img-Clarify-about-relative-backing-file-options.patch b/SOURCES/kvm-qemu-img-Clarify-about-relative-backing-file-options.patch
new file mode 100644
index 0000000..7c1a595
--- /dev/null
+++ b/SOURCES/kvm-qemu-img-Clarify-about-relative-backing-file-options.patch
@@ -0,0 +1,70 @@
+From 8da92a8a73295fe3239124d26507c5cf0276ddab Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Tue, 12 Dec 2017 02:19:20 +0100
+Subject: [PATCH 3/6] qemu-img: Clarify about relative backing file options
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20171212021920.25231-1-famz@redhat.com>
+Patchwork-id: 78306
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] qemu-img: Clarify about relative backing file options
+Bugzilla: 1451269
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+It's not too surprising when a user specifies the backing file relative
+to the current working directory instead of the top layer image. This
+causes error when they differ. Though the error message has enough
+information to infer the fact about the misunderstanding, it is better
+if we document this explicitly, so that users don't have to learn from
+mistakes.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit a16efd53406bc8d89f87253ab10290f8d1b145a7)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qemu-img.texi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/qemu-img.texi b/qemu-img.texi
+index 72dabd6..90c7eab 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -244,6 +244,9 @@ only the differences from @var{backing_file}. No size needs to be specified in
+ this case. @var{backing_file} will never be modified unless you use the
+ @code{commit} monitor command (or qemu-img commit).
+ 
++If a relative path name is given, the backing file is looked up relative to
++the directory containing @var{filename}.
++
+ Note that a given backing file will be opened to check that it is valid. Use
+ the @code{-u} option to enable unsafe backing file mode, which means that the
+ image will be created even if the associated backing file cannot be opened. A
+@@ -343,6 +346,9 @@ created as a copy on write image of the specified base image; the
+ @var{backing_file} should have the same content as the input's base image,
+ however the path, image format, etc may differ.
+ 
++If a relative path name is given, the backing file is looked up relative to
++the directory containing @var{output_filename}.
++
+ If the @code{-n} option is specified, the target volume creation will be
+ skipped. This is useful for formats such as @code{rbd} if the target
+ volume has already been created with site specific options that cannot
+@@ -490,6 +496,9 @@ The backing file is changed to @var{backing_file} and (if the image format of
+ string), then the image is rebased onto no backing file (i.e. it will exist
+ independently of any backing file).
+ 
++If a relative path name is given, the backing file is looked up relative to
++the directory containing @var{filename}.
++
+ @var{cache} specifies the cache mode to be used for @var{filename}, whereas
+ @var{src_cache} specifies the cache mode for reading backing files.
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-img-info-Force-U-downstream.patch b/SOURCES/kvm-qemu-img-info-Force-U-downstream.patch
new file mode 100644
index 0000000..8df5d34
--- /dev/null
+++ b/SOURCES/kvm-qemu-img-info-Force-U-downstream.patch
@@ -0,0 +1,48 @@
+From 40a03299cb7297e5b5c52b671f4c0b7af501673f Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Mon, 22 Jan 2018 03:07:16 +0100
+Subject: [PATCH 19/21] qemu-img: info: Force -U [downstream]
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20180122030716.611-1-famz@redhat.com>
+Patchwork-id: 78688
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] qemu-img: info: Force -U [downstream]
+Bugzilla: 1535992
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Current version of RHV has to work with the coming RHEL 7.5, which means
+that customers will encounter error without this patch: RHV invokes
+"qemu-img info" while VM is running, and only until the next release it
+knows to use "-U". For the existing RHV, we need to ship one version of
+qemu-img that doesn't enforce this option yet.
+
+Upstream already has releases (2.10 and 2.11) that has the new behavior,
+so this "moving a step back" patch has no place there.
+
+I created BZ 1536912 so that we remember to revert this in RHEL
+7.6.1536912 so that we remember to revert this in 7.6 time.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qemu-img.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index 56ef49e..dccfc10 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -2532,7 +2532,7 @@ static int img_info(int argc, char **argv)
+     const char *filename, *fmt, *output;
+     ImageInfoList *list;
+     bool image_opts = false;
+-    bool force_share = false;
++    bool force_share = true;
+ 
+     fmt = NULL;
+     output = NULL;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-io-Drop-write-permissions-before-read-only-reop.patch b/SOURCES/kvm-qemu-io-Drop-write-permissions-before-read-only-reop.patch
new file mode 100644
index 0000000..bdaf652
--- /dev/null
+++ b/SOURCES/kvm-qemu-io-Drop-write-permissions-before-read-only-reop.patch
@@ -0,0 +1,73 @@
+From 1c4c0df8838e32c524c86ae7ab0fcdc56cb0cad0 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 4 Dec 2017 12:10:00 +0100
+Subject: [PATCH 29/36] qemu-io: Drop write permissions before read-only reopen
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-2-kwolf@redhat.com>
+Patchwork-id: 78106
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 1/8] qemu-io: Drop write permissions before read-only reopen
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+qemu-io provides a 'reopen' command that allows switching from writable
+to read-only access. We need to make sure that we don't try to keep
+write permissions to a BlockBackend that becomes read-only, otherwise
+things are going to fail.
+
+This requires a bdrv_drain() call because otherwise in-flight AIO
+write requests could issue new internal requests while the permission
+has already gone away, which would cause assertion failures. Draining
+the queue doesn't break AIO requests in any new way, bdrv_reopen() would
+drain it anyway only a few lines later.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+(cherry picked from commit f3adefb2cea1c63b7b198acaef5e40eb4b2d2d39)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qemu-io-cmds.c             | 12 ++++++++++++
+ tests/qemu-iotests/187.out |  2 +-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
+index 2811a89..3727fb4 100644
+--- a/qemu-io-cmds.c
++++ b/qemu-io-cmds.c
+@@ -2010,6 +2010,18 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
+         return 0;
+     }
+ 
++    if (!(flags & BDRV_O_RDWR)) {
++        uint64_t orig_perm, orig_shared_perm;
++
++        bdrv_drain(bs);
++
++        blk_get_perm(blk, &orig_perm, &orig_shared_perm);
++        blk_set_perm(blk,
++                     orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
++                     orig_shared_perm,
++                     &error_abort);
++    }
++
+     qopts = qemu_opts_find(&reopen_opts, NULL);
+     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL;
+     qemu_opts_reset(&reopen_opts);
+diff --git a/tests/qemu-iotests/187.out b/tests/qemu-iotests/187.out
+index 68fb944..30b987f 100644
+--- a/tests/qemu-iotests/187.out
++++ b/tests/qemu-iotests/187.out
+@@ -12,7 +12,7 @@ Start from read-write
+ 
+ wrote 65536/65536 bytes at offset 0
+ 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+-write failed: Operation not permitted
++Block node is read-only
+ wrote 65536/65536 bytes at offset 0
+ 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ *** done
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotest-add-test-for-blockjob-coroutine-race-con.patch b/SOURCES/kvm-qemu-iotest-add-test-for-blockjob-coroutine-race-con.patch
new file mode 100644
index 0000000..b66a394
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotest-add-test-for-blockjob-coroutine-race-con.patch
@@ -0,0 +1,165 @@
+From 1d27a8067135c09ecbb2aa7e4af6184aba67e86c Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Mon, 11 Dec 2017 09:06:23 +0100
+Subject: [PATCH 06/21] qemu-iotest: add test for blockjob coroutine race
+ condition
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <bb398a83a095183453bbf2cab4656dd60dfd4637.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78042
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 06/11] qemu-iotest: add test for blockjob coroutine race condition
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit d975301dc8ae56fb3154348878e47a6211843c0b)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/200     | 99 ++++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/200.out | 14 +++++++
+ tests/qemu-iotests/group   |  1 +
+ 3 files changed, 114 insertions(+)
+ create mode 100644 tests/qemu-iotests/200
+ create mode 100644 tests/qemu-iotests/200.out
+
+diff --git a/tests/qemu-iotests/200 b/tests/qemu-iotests/200
+new file mode 100644
+index 0000000..d8787dd
+--- /dev/null
++++ b/tests/qemu-iotests/200
+@@ -0,0 +1,99 @@
++#!/bin/bash
++#
++# Block job co-routine race condition test.
++#
++# See: https://bugzilla.redhat.com/show_bug.cgi?id=1508708
++#
++# Copyright (C) 2017 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++
++# creator
++owner=jcody@redhat.com
++
++seq=`basename $0`
++echo "QA output created by $seq"
++
++here=`pwd`
++status=1    # failure is the default!
++
++_cleanup()
++{
++    _cleanup_qemu
++    rm -f "${TEST_IMG}" "${BACKING_IMG}"
++}
++trap "_cleanup; exit \$status" 0 1 2 3 15
++
++# get standard environment, filters and checks
++. ./common.rc
++. ./common.filter
++. ./common.qemu
++
++_supported_fmt qcow2 qed
++_supported_proto file
++_supported_os Linux
++
++BACKING_IMG="${TEST_DIR}/backing.img"
++TEST_IMG="${TEST_DIR}/test.img"
++
++${QEMU_IMG} create -f $IMGFMT "${BACKING_IMG}" 512M | _filter_img_create
++${QEMU_IMG} create -f $IMGFMT -F $IMGFMT "${TEST_IMG}" -b "${BACKING_IMG}" 512M | _filter_img_create
++
++${QEMU_IO} -c "write -P 0xa5 512 300M" "${BACKING_IMG}" | _filter_qemu_io
++
++echo
++echo === Starting QEMU VM ===
++echo
++qemu_comm_method="qmp"
++_launch_qemu -device pci-bridge,id=bridge1,chassis_nr=1,bus=pci.0 \
++             -object iothread,id=iothread0 \
++             -device virtio-scsi-pci,bus=bridge1,addr=0x1f,id=scsi0,iothread=iothread0 \
++             -drive file="${TEST_IMG}",media=disk,if=none,cache=none,id=drive_sysdisk,aio=native,format=$IMGFMT \
++             -device scsi-hd,drive=drive_sysdisk,bus=scsi0.0,id=sysdisk,bootindex=0
++h1=$QEMU_HANDLE
++
++_send_qemu_cmd $h1 "{ 'execute': 'qmp_capabilities' }" 'return'
++
++echo
++echo === Sending stream/cancel, checking for SIGSEGV only  ===
++echo
++for (( i=1;i<500;i++ ))
++do
++    mismatch_only='y' qemu_error_no_exit='n' _send_qemu_cmd $h1 \
++                       "{
++                            'execute': 'block-stream',
++                            'arguments': {
++                                'device': 'drive_sysdisk',
++                                'speed': 10000000,
++                                'on-error': 'report',
++                                'job-id': 'job-$i'
++                             }
++                        }
++                        {
++                            'execute': 'block-job-cancel',
++                            'arguments': {
++                                'device': 'job-$i'
++                             }
++                        }" \
++                       "{.*{.*}.*}"  # should match all well-formed QMP responses
++done
++
++silent='y' _send_qemu_cmd $h1  "{ 'execute': 'quit' }" 'return'
++
++echo "$i iterations performed"
++
++echo "*** done"
++rm -f $seq.full
++status=0
+diff --git a/tests/qemu-iotests/200.out b/tests/qemu-iotests/200.out
+new file mode 100644
+index 0000000..af6a809
+--- /dev/null
++++ b/tests/qemu-iotests/200.out
+@@ -0,0 +1,14 @@
++QA output created by 200
++Formatting 'TEST_DIR/backing.img', fmt=IMGFMT size=536870912
++Formatting 'TEST_DIR/test.img', fmt=IMGFMT size=536870912 backing_file=TEST_DIR/backing.img backing_fmt=IMGFMT
++wrote 314572800/314572800 bytes at offset 512
++300 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Starting QEMU VM ===
++
++{"return": {}}
++
++=== Sending stream/cancel, checking for SIGSEGV only ===
++
++500 iterations performed
++*** done
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 491a5f5..39b61ce 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -190,3 +190,4 @@
+ 194 rw auto migration quick
+ 195 rw auto quick
+ 198 rw auto
++200 rw auto
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-Test-I-O-limits-with-removable-media.patch b/SOURCES/kvm-qemu-iotests-Test-I-O-limits-with-removable-media.patch
new file mode 100644
index 0000000..26ee22e
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-Test-I-O-limits-with-removable-media.patch
@@ -0,0 +1,129 @@
+From 3725eae71ddcc6f053793a530c1f4e3a43e9c4df Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:07 +0100
+Subject: [PATCH 08/15] qemu-iotests: Test I/O limits with removable media
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-9-stefanha@redhat.com>
+Patchwork-id: 77743
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 8/9] qemu-iotests: Test I/O limits with removable media
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alberto Garcia <berto@igalia.com>
+
+This test hotplugs a CD drive to a VM and checks that I/O limits can
+be set only when the drive has media inserted and that they are kept
+when the media is replaced.
+
+This also tests the removal of a device with valid I/O limits set but
+no media inserted. This involves deleting and disabling the limits
+of a BlockBackend without BlockDriverState, a scenario that has been
+crashing until the fixes from the last couple of patches.
+
+[Python PEP8 fixup: "Don't use spaces are the = sign when used to
+indicate a keyword argument or a default parameter value"
+--Stefan]
+
+Signed-off-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-id: 071eb397118ed207c5a7f01d58766e415ee18d6a.1510339534.git.berto@igalia.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 0761562687e0d8135310a94b1d3e08376387c027)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/093     | 62 ++++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/093.out |  4 +--
+ 2 files changed, 64 insertions(+), 2 deletions(-)
+
+diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
+index ef39972..5c36a5f 100755
+--- a/tests/qemu-iotests/093
++++ b/tests/qemu-iotests/093
+@@ -308,6 +308,68 @@ class ThrottleTestGroupNames(iotests.QMPTestCase):
+             groupname = "group%d" % i
+             self.verify_name(devname, groupname)
+ 
++class ThrottleTestRemovableMedia(iotests.QMPTestCase):
++    def setUp(self):
++        self.vm = iotests.VM()
++        if iotests.qemu_default_machine == 's390-ccw-virtio':
++            self.vm.add_device("virtio-scsi-ccw,id=virtio-scsi")
++        else:
++            self.vm.add_device("virtio-scsi-pci,id=virtio-scsi")
++        self.vm.launch()
++
++    def tearDown(self):
++        self.vm.shutdown()
++
++    def test_removable_media(self):
++        # Add a couple of dummy nodes named cd0 and cd1
++        result = self.vm.qmp("blockdev-add", driver="null-aio",
++                             node_name="cd0")
++        self.assert_qmp(result, 'return', {})
++        result = self.vm.qmp("blockdev-add", driver="null-aio",
++                             node_name="cd1")
++        self.assert_qmp(result, 'return', {})
++
++        # Attach a CD drive with cd0 inserted
++        result = self.vm.qmp("device_add", driver="scsi-cd",
++                             id="dev0", drive="cd0")
++        self.assert_qmp(result, 'return', {})
++
++        # Set I/O limits
++        args = { "id": "dev0", "iops": 100, "iops_rd": 0, "iops_wr": 0,
++                                "bps":  50,  "bps_rd": 0,  "bps_wr": 0 }
++        result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
++        self.assert_qmp(result, 'return', {})
++
++        # Check that the I/O limits have been set
++        result = self.vm.qmp("query-block")
++        self.assert_qmp(result, 'return[0]/inserted/iops', 100)
++        self.assert_qmp(result, 'return[0]/inserted/bps',   50)
++
++        # Now eject cd0 and insert cd1
++        result = self.vm.qmp("blockdev-open-tray", id='dev0')
++        self.assert_qmp(result, 'return', {})
++        result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
++        self.assert_qmp(result, 'return', {})
++        result = self.vm.qmp("x-blockdev-insert-medium", id='dev0', node_name='cd1')
++        self.assert_qmp(result, 'return', {})
++
++        # Check that the I/O limits are still the same
++        result = self.vm.qmp("query-block")
++        self.assert_qmp(result, 'return[0]/inserted/iops', 100)
++        self.assert_qmp(result, 'return[0]/inserted/bps',   50)
++
++        # Eject cd1
++        result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
++        self.assert_qmp(result, 'return', {})
++
++        # Check that we can't set limits if the device has no medium
++        result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
++        self.assert_qmp(result, 'error/class', 'GenericError')
++
++        # Remove the CD drive
++        result = self.vm.qmp("device_del", id='dev0')
++        self.assert_qmp(result, 'return', {})
++
+ 
+ if __name__ == '__main__':
+     iotests.main(supported_fmts=["raw"])
+diff --git a/tests/qemu-iotests/093.out b/tests/qemu-iotests/093.out
+index 2f7d390..594c16f 100644
+--- a/tests/qemu-iotests/093.out
++++ b/tests/qemu-iotests/093.out
+@@ -1,5 +1,5 @@
+-.......
++........
+ ----------------------------------------------------------------------
+-Ran 7 tests
++Ran 8 tests
+ 
+ OK
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-Test-change-backing-file-command.patch b/SOURCES/kvm-qemu-iotests-Test-change-backing-file-command.patch
new file mode 100644
index 0000000..49a4f52
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-Test-change-backing-file-command.patch
@@ -0,0 +1,224 @@
+From f3eb0c097a879c9bc80a5a2589560b7ebde3720b Mon Sep 17 00:00:00 2001
+From: Miroslav Rezanina <mrezanin@redhat.com>
+Date: Tue, 5 Dec 2017 10:26:10 +0100
+Subject: [PATCH 35/36] qemu-iotests: Test change-backing-file command
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20171204121007.12964-8-kwolf@redhat.com>
+Patchwork-id: 78111
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 7/8] qemu-iotests: Test change-backing-file command
+Bugzilla: 1492178
+RH-Acked-by: Fam Zheng <famz@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+This involves a temporary read-write reopen if the backing file link in
+the middle of a backing file chain should be changed and is therefore a
+good test for the latest bdrv_reopen() vs. op blockers fixes.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 3fb23e07516aae13d1ba566740c1c81ae12184b7)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/195     | 92 ++++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/195.out | 78 +++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/group   |  1 +
+ 3 files changed, 171 insertions(+)
+ create mode 100644 tests/qemu-iotests/195
+ create mode 100644 tests/qemu-iotests/195.out
+
+diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
+new file mode 100644
+index 0000000..05a239c
+--- /dev/null
++++ b/tests/qemu-iotests/195
+@@ -0,0 +1,92 @@
++#!/bin/bash
++#
++# Test change-backing-file command
++#
++# Copyright (C) 2017 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++
++# creator
++owner=kwolf@redhat.com
++
++seq=`basename $0`
++echo "QA output created by $seq"
++
++here=`pwd`
++status=1 # failure is the default!
++
++_cleanup()
++{
++    _cleanup_test_img
++    rm -f "$TEST_IMG.mid"
++}
++trap "_cleanup; exit \$status" 0 1 2 3 15
++
++# get standard environment, filters and checks
++. ./common.rc
++. ./common.filter
++
++_supported_fmt qcow2
++_supported_proto file
++_supported_os Linux
++
++function do_run_qemu()
++{
++    echo Testing: "$@" | _filter_imgfmt
++    $QEMU -nographic -qmp-pretty stdio -serial none "$@"
++    echo
++}
++
++function run_qemu()
++{
++    do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp \
++                          | _filter_qemu_io | _filter_generated_node_ids
++}
++
++size=64M
++TEST_IMG="$TEST_IMG.base" _make_test_img $size
++TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
++_make_test_img -b "$TEST_IMG.mid"
++
++echo
++echo "Change backing file of mid (opened read-only)"
++echo
++
++run_qemu -drive if=none,file="$TEST_IMG",backing.node-name=mid <<EOF
++{"execute":"qmp_capabilities"}
++{"execute":"change-backing-file", "arguments":{"device":"none0","image-node-name":"mid","backing-file":"/dev/null"}}
++{"execute":"quit"}
++EOF
++
++TEST_IMG="$TEST_IMG.mid" _img_info
++
++echo
++echo "Change backing file of top (opened writable)"
++echo
++
++TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
++
++run_qemu -drive if=none,file="$TEST_IMG",node-name=top <<EOF
++{"execute":"qmp_capabilities"}
++{"execute":"change-backing-file", "arguments":{"device":"none0","image-node-name":"top","backing-file":"/dev/null"}}
++{"execute":"quit"}
++EOF
++
++_img_info
++
++# success, all done
++echo "*** done"
++rm -f $seq.full
++status=0
+diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
+new file mode 100644
+index 0000000..7613575
+--- /dev/null
++++ b/tests/qemu-iotests/195.out
+@@ -0,0 +1,78 @@
++QA output created by 195
++Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
++
++Change backing file of mid (opened read-only)
++
++Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
++{
++    QMP_VERSION
++}
++{
++    "return": {
++    }
++}
++{
++    "return": {
++    }
++}
++{
++    "return": {
++    }
++}
++{
++    "timestamp": {
++        "seconds":  TIMESTAMP,
++        "microseconds":  TIMESTAMP
++    },
++    "event": "SHUTDOWN",
++    "data": {
++        "guest": false
++    }
++}
++
++image: TEST_DIR/t.IMGFMT.mid
++file format: IMGFMT
++virtual size: 64M (67108864 bytes)
++cluster_size: 65536
++backing file: /dev/null
++backing file format: IMGFMT
++
++Change backing file of top (opened writable)
++
++Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
++Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
++{
++    QMP_VERSION
++}
++{
++    "return": {
++    }
++}
++{
++    "return": {
++    }
++}
++{
++    "return": {
++    }
++}
++{
++    "timestamp": {
++        "seconds":  TIMESTAMP,
++        "microseconds":  TIMESTAMP
++    },
++    "event": "SHUTDOWN",
++    "data": {
++        "guest": false
++    }
++}
++
++image: TEST_DIR/t.IMGFMT
++file format: IMGFMT
++virtual size: 64M (67108864 bytes)
++cluster_size: 65536
++backing file: /dev/null
++backing file format: IMGFMT
++*** done
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 13760b3..491a5f5 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -188,4 +188,5 @@
+ 190 rw auto quick
+ 192 rw auto quick
+ 194 rw auto migration quick
++195 rw auto quick
+ 198 rw auto
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-add-202-external-snapshots-IOThread-tes.patch b/SOURCES/kvm-qemu-iotests-add-202-external-snapshots-IOThread-tes.patch
new file mode 100644
index 0000000..3e31fec
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-add-202-external-snapshots-IOThread-tes.patch
@@ -0,0 +1,165 @@
+From c5ff50d391e5a1afa55d6f2394f404ce27c6ceb5 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:56 +0100
+Subject: [PATCH 38/42] qemu-iotests: add 202 external snapshots IOThread test
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-17-stefanha@redhat.com>
+Patchwork-id: 78496
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 16/20] qemu-iotests: add 202 external snapshots IOThread test
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+QMP 'transaction' blockdev-snapshot-sync with multiple disks in an
+IOThread is an untested code path.  Several bugs have been found in
+connection with this command.  This patch adds a test case to prevent
+future regressions.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171206144550.22295-10-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 6dd64919ea36db9fd7e754ed394c25ced45ea39a)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/202     | 95 ++++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/202.out | 11 ++++++
+ tests/qemu-iotests/group   |  1 +
+ 3 files changed, 107 insertions(+)
+ create mode 100755 tests/qemu-iotests/202
+ create mode 100644 tests/qemu-iotests/202.out
+
+diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202
+new file mode 100755
+index 0000000..581ca34
+--- /dev/null
++++ b/tests/qemu-iotests/202
+@@ -0,0 +1,95 @@
++#!/usr/bin/env python
++#
++# Copyright (C) 2017 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com>
++#
++# Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a
++# single IOThread completes successfully.  This particular command triggered a
++# hang due to recursive AioContext locking and BDRV_POLL_WHILE().  Protect
++# against regressions.
++
++import iotests
++
++iotests.verify_image_format(supported_fmts=['qcow2'])
++iotests.verify_platform(['linux'])
++
++with iotests.FilePath('disk0.img') as disk0_img_path, \
++     iotests.FilePath('disk1.img') as disk1_img_path, \
++     iotests.FilePath('disk0-snap.img') as disk0_snap_img_path, \
++     iotests.FilePath('disk1-snap.img') as disk1_snap_img_path, \
++     iotests.VM() as vm:
++
++    img_size = '10M'
++    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size)
++    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size)
++
++    iotests.log('Launching VM...')
++    vm.launch()
++
++    iotests.log('Adding IOThread...')
++    iotests.log(vm.qmp('object-add',
++                       qom_type='iothread',
++                       id='iothread0'))
++
++    iotests.log('Adding blockdevs...')
++    iotests.log(vm.qmp('blockdev-add',
++                       driver=iotests.imgfmt,
++                       node_name='disk0',
++                       file={
++                           'driver': 'file',
++                           'filename': disk0_img_path,
++                       }))
++    iotests.log(vm.qmp('blockdev-add',
++                       driver=iotests.imgfmt,
++                       node_name='disk1',
++                       file={
++                           'driver': 'file',
++                           'filename': disk1_img_path,
++                       }))
++
++    iotests.log('Setting iothread...')
++    iotests.log(vm.qmp('x-blockdev-set-iothread',
++                       node_name='disk0',
++                       iothread='iothread0'))
++    iotests.log(vm.qmp('x-blockdev-set-iothread',
++                       node_name='disk1',
++                       iothread='iothread0'))
++
++    iotests.log('Creating external snapshots...')
++    iotests.log(vm.qmp(
++                  'transaction',
++                  actions=[
++                      {
++                          'data': {
++                              'node-name': 'disk0',
++                              'snapshot-file': disk0_snap_img_path,
++                              'snapshot-node-name': 'disk0-snap',
++                              'mode': 'absolute-paths',
++                              'format': iotests.imgfmt,
++                          },
++                          'type': 'blockdev-snapshot-sync'
++                      }, {
++                          'data': {
++                              'node-name': 'disk1',
++                              'snapshot-file': disk1_snap_img_path,
++                              'snapshot-node-name': 'disk1-snap',
++                              'mode': 'absolute-paths',
++                              'format': iotests.imgfmt
++                          },
++                          'type': 'blockdev-snapshot-sync'
++                      }
++                  ]))
+diff --git a/tests/qemu-iotests/202.out b/tests/qemu-iotests/202.out
+new file mode 100644
+index 0000000..d5ea374
+--- /dev/null
++++ b/tests/qemu-iotests/202.out
+@@ -0,0 +1,11 @@
++Launching VM...
++Adding IOThread...
++{u'return': {}}
++Adding blockdevs...
++{u'return': {}}
++{u'return': {}}
++Setting iothread...
++{u'return': {}}
++{u'return': {}}
++Creating external snapshots...
++{u'return': {}}
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 39b61ce..8d3752c 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -191,3 +191,4 @@
+ 195 rw auto quick
+ 198 rw auto
+ 200 rw auto
++202 rw auto quick
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-add-203-savevm-with-IOThreads-test.patch b/SOURCES/kvm-qemu-iotests-add-203-savevm-with-IOThreads-test.patch
new file mode 100644
index 0000000..4c1a34c
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-add-203-savevm-with-IOThreads-test.patch
@@ -0,0 +1,121 @@
+From 8c4af840ec684f51a9159ab65550653600ade7e8 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:09:00 +0100
+Subject: [PATCH 42/42] qemu-iotests: add 203 savevm with IOThreads test
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-21-stefanha@redhat.com>
+Patchwork-id: 78502
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 20/20] qemu-iotests: add 203 savevm with IOThreads test
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+This test case will prevent future regressions with savevm and
+IOThreads.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-id: 20171207201320.19284-7-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 7a9dda0d7f9831c2432620dcfefdadbb7ae888dc)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/203     | 59 ++++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/203.out |  6 +++++
+ tests/qemu-iotests/group   |  1 +
+ 3 files changed, 66 insertions(+)
+ create mode 100755 tests/qemu-iotests/203
+ create mode 100644 tests/qemu-iotests/203.out
+
+diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203
+new file mode 100755
+index 0000000..2c81191
+--- /dev/null
++++ b/tests/qemu-iotests/203
+@@ -0,0 +1,59 @@
++#!/usr/bin/env python
++#
++# Copyright (C) 2017 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com>
++#
++# Check that QMP 'migrate' with multiple drives on a single IOThread completes
++# successfully.  This particular command triggered a hang in the source QEMU
++# process due to recursive AioContext locking in bdrv_invalidate_all() and
++# BDRV_POLL_WHILE().
++
++import iotests
++
++iotests.verify_image_format(supported_fmts=['qcow2'])
++iotests.verify_platform(['linux'])
++
++with iotests.FilePath('disk0.img') as disk0_img_path, \
++     iotests.FilePath('disk1.img') as disk1_img_path, \
++     iotests.VM() as vm:
++
++    img_size = '10M'
++    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size)
++    iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size)
++
++    iotests.log('Launching VM...')
++    (vm.add_object('iothread,id=iothread0')
++       .add_drive(disk0_img_path, 'node-name=drive0-node', interface='none')
++       .add_drive(disk1_img_path, 'node-name=drive1-node', interface='none')
++       .launch())
++
++    iotests.log('Setting IOThreads...')
++    iotests.log(vm.qmp('x-blockdev-set-iothread',
++                       node_name='drive0-node', iothread='iothread0',
++                       force=True))
++    iotests.log(vm.qmp('x-blockdev-set-iothread',
++                       node_name='drive1-node', iothread='iothread0',
++                       force=True))
++
++    iotests.log('Starting migration...')
++    iotests.log(vm.qmp('migrate', uri='exec:cat >/dev/null'))
++    while True:
++        vm.get_qmp_event(wait=60.0)
++        result = vm.qmp('query-migrate')
++        status = result.get('return', {}).get('status', None)
++        if status == 'completed':
++            break
+diff --git a/tests/qemu-iotests/203.out b/tests/qemu-iotests/203.out
+new file mode 100644
+index 0000000..3f1ff90
+--- /dev/null
++++ b/tests/qemu-iotests/203.out
+@@ -0,0 +1,6 @@
++Launching VM...
++Setting IOThreads...
++{u'return': {}}
++{u'return': {}}
++Starting migration...
++{u'return': {}}
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 8d3752c..67b197e 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -192,3 +192,4 @@
+ 198 rw auto
+ 200 rw auto
+ 202 rw auto quick
++203 rw auto
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-add-option-in-common.qemu-for-mismatch-.patch b/SOURCES/kvm-qemu-iotests-add-option-in-common.qemu-for-mismatch-.patch
new file mode 100644
index 0000000..2b96a5b
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-add-option-in-common.qemu-for-mismatch-.patch
@@ -0,0 +1,65 @@
+From ebcc9ff9c53aca4d9fab9a0839ccbaf54fbf9943 Mon Sep 17 00:00:00 2001
+From: Jeffrey Cody <jcody@redhat.com>
+Date: Thu, 30 Nov 2017 22:49:09 +0100
+Subject: [PATCH 05/21] qemu-iotests: add option in common.qemu for mismatch
+ only
+
+RH-Author: Jeffrey Cody <jcody@redhat.com>
+Message-id: <050629fe443e53475eed8d77b0d6ed321bd42967.1511985875.git.jcody@redhat.com>
+Patchwork-id: 78043
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 05/11] qemu-iotests: add option in common.qemu for mismatch only
+Bugzilla: 1506531
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Add option to echo response to QMP / HMP command only on mismatch.
+
+Useful for ignore all normal responses, but catching things like
+segfaults.
+
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit a2339699c3d35f19253b3b9b51f8a9b8e24f90eb)
+Signed-off-by: Jeff Cody <jcody@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/common.qemu | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
+index 7645f1d..f646d81 100644
+--- a/tests/qemu-iotests/common.qemu
++++ b/tests/qemu-iotests/common.qemu
+@@ -49,6 +49,8 @@ _in_fd=4
+ #
+ # If $silent is set to anything but an empty string, then
+ # response is not echoed out.
++# If $mismatch_only is set, only non-matching responses will
++# be echoed.
+ function _timed_wait_for()
+ {
+     local h=${1}
+@@ -57,14 +59,18 @@ function _timed_wait_for()
+     QEMU_STATUS[$h]=0
+     while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
+     do
+-        if [ -z "${silent}" ]; then
++        if [ -z "${silent}" ] && [ -z "${mismatch_only}" ]; then
+             echo "${resp}" | _filter_testdir | _filter_qemu \
+                            | _filter_qemu_io | _filter_qmp | _filter_hmp
+         fi
+         grep -q "${*}" < <(echo ${resp})
+         if [ $? -eq 0 ]; then
+             return
++        elif [ -z "${silent}" ] && [ -n "${mismatch_only}" ]; then
++            echo "${resp}" | _filter_testdir | _filter_qemu \
++                           | _filter_qemu_io | _filter_qmp | _filter_hmp
+         fi
++
+     done
+     QEMU_STATUS[$h]=-1
+     if [ -z "${qemu_error_no_exit}" ]; then
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-improve-nbd-fault-injector.py-startup-p.patch b/SOURCES/kvm-qemu-iotests-improve-nbd-fault-injector.py-startup-p.patch
new file mode 100644
index 0000000..b908f2d
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-improve-nbd-fault-injector.py-startup-p.patch
@@ -0,0 +1,61 @@
+From 2f7ffaddd0a233a233125320b6595a091c19c18f Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Fri, 6 Oct 2017 19:24:07 +0200
+Subject: [PATCH 15/34] qemu-iotests: improve nbd-fault-injector.py startup
+ protocol
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171006192409.29915-3-eblake@redhat.com>
+Patchwork-id: 76914
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 2/4] qemu-iotests: improve nbd-fault-injector.py startup protocol
+Bugzilla: 1482478
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+Currently 083 waits for the nbd-fault-injector.py server to start up by
+looping until netstat shows the TCP listen socket.
+
+The startup protocol can be simplified by passing a 0 port number to
+nbd-fault-injector.py.  The kernel will allocate a port in bind(2) and
+the final port number can be printed by nbd-fault-injector.py.
+
+This should make it slightly nicer and less TCP-specific to wait for
+server startup.  This patch changes nbd-fault-injector.py, the next one
+will rewrite server startup in 083.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20170829122745.14309-3-stefanha@redhat.com>
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 6e592fc92234a58c7156c385840633c17dedd24f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/nbd-fault-injector.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/qemu-iotests/nbd-fault-injector.py b/tests/qemu-iotests/nbd-fault-injector.py
+index 6c07191..1c10dcb 100755
+--- a/tests/qemu-iotests/nbd-fault-injector.py
++++ b/tests/qemu-iotests/nbd-fault-injector.py
+@@ -235,11 +235,15 @@ def open_socket(path):
+         sock = socket.socket()
+         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+         sock.bind((host, int(port)))
++
++        # If given port was 0 the final port number is now available
++        path = '%s:%d' % sock.getsockname()
+     else:
+         sock = socket.socket(socket.AF_UNIX)
+         sock.bind(path)
+     sock.listen(0)
+     print 'Listening on %s' % path
++    sys.stdout.flush() # another process may be waiting, show message now
+     return sock
+ 
+ def usage(args):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iotests-test-NBD-over-UNIX-domain-sockets-in-08.patch b/SOURCES/kvm-qemu-iotests-test-NBD-over-UNIX-domain-sockets-in-08.patch
new file mode 100644
index 0000000..0549bfc
--- /dev/null
+++ b/SOURCES/kvm-qemu-iotests-test-NBD-over-UNIX-domain-sockets-in-08.patch
@@ -0,0 +1,451 @@
+From 91394fd12be59351787e34e0f18de8b2ff06441f Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Fri, 6 Oct 2017 19:24:08 +0200
+Subject: [PATCH 16/34] qemu-iotests: test NBD over UNIX domain sockets in 083
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20171006192409.29915-4-eblake@redhat.com>
+Patchwork-id: 76910
+O-Subject: [RHEV-7.5 qemu-kvm-rhev PATCH 3/4] qemu-iotests: test NBD over UNIX domain sockets in 083
+Bugzilla: 1482478
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+083 only tests TCP.  Some failures might be specific to UNIX domain
+sockets.
+
+A few adjustments are necessary:
+
+1. Generating a port number and waiting for server startup is
+   TCP-specific.  Use the new nbd-fault-injector.py startup protocol to
+   fetch the address.  This is a little more elegant because we don't
+   need netstat anymore.
+
+2. The NBD filter does not work for the UNIX domain sockets URIs we
+   generate and must be extended.
+
+3. Run all tests twice: once for TCP and once for UNIX domain sockets.
+
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20170829122745.14309-4-stefanha@redhat.com>
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 02d2d860d25e439f0e88658c701668ab684568fb)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/083           | 136 ++++++++++++++++++++++--------------
+ tests/qemu-iotests/083.out       | 145 ++++++++++++++++++++++++++++++++++-----
+ tests/qemu-iotests/common.filter |   4 +-
+ 3 files changed, 214 insertions(+), 71 deletions(-)
+
+diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
+index bff9360..0306f11 100755
+--- a/tests/qemu-iotests/083
++++ b/tests/qemu-iotests/083
+@@ -27,6 +27,14 @@ echo "QA output created by $seq"
+ here=`pwd`
+ status=1	# failure is the default!
+ 
++_cleanup()
++{
++	rm -f nbd.sock
++	rm -f nbd-fault-injector.out
++	rm -f nbd-fault-injector.conf
++}
++trap "_cleanup; exit \$status" 0 1 2 3 15
++
+ # get standard environment, filters and checks
+ . ./common.rc
+ . ./common.filter
+@@ -35,81 +43,105 @@ _supported_fmt generic
+ _supported_proto nbd
+ _supported_os Linux
+ 
+-# Pick a TCP port based on our pid.  This way multiple instances of this test
+-# can run in parallel without conflicting.
+-choose_tcp_port() {
+-	echo $((($$ % 31744) + 1024)) # 1024 <= port < 32768
+-}
+-
+-wait_for_tcp_port() {
+-	while ! (netstat --tcp --listening --numeric | \
+-		 grep "$1.*0\\.0\\.0\\.0:\\*.*LISTEN") >/dev/null 2>&1; do
+-		sleep 0.1
++check_disconnect() {
++	local event export_name=foo extra_args nbd_addr nbd_url proto when
++
++	while true; do
++		case $1 in
++		--classic-negotiation)
++			shift
++			extra_args=--classic-negotiation
++			export_name=
++			;;
++		--tcp)
++			shift
++			proto=tcp
++			;;
++		--unix)
++			shift
++			proto=unix
++			;;
++		*)
++			break
++			;;
++		esac
+ 	done
+-}
+ 
+-check_disconnect() {
+ 	event=$1
+ 	when=$2
+-	negotiation=$3
+ 	echo "=== Check disconnect $when $event ==="
+ 	echo
+ 
+-	port=$(choose_tcp_port)
+-
+ 	cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF
+ [inject-error]
+ event=$event
+ when=$when
+ EOF
+ 
+-	if [ "$negotiation" = "--classic-negotiation" ]; then
+-		extra_args=--classic-negotiation
+-		nbd_url="nbd:127.0.0.1:$port"
++	if [ "$proto" = "tcp" ]; then
++		nbd_addr="127.0.0.1:0"
+ 	else
+-		nbd_url="nbd:127.0.0.1:$port:exportname=foo"
++		nbd_addr="$TEST_DIR/nbd.sock"
++	fi
++
++	rm -f "$TEST_DIR/nbd.sock"
++
++	$PYTHON nbd-fault-injector.py $extra_args "$nbd_addr" "$TEST_DIR/nbd-fault-injector.conf" >"$TEST_DIR/nbd-fault-injector.out" 2>&1 &
++
++	# Wait for server to be ready
++	while ! grep -q 'Listening on ' "$TEST_DIR/nbd-fault-injector.out"; do
++		sleep 0.1
++	done
++
++	# Extract the final address (port number has now been assigned in tcp case)
++	nbd_addr=$(sed 's/Listening on \(.*\)$/\1/' "$TEST_DIR/nbd-fault-injector.out")
++
++	if [ "$proto" = "tcp" ]; then
++		nbd_url="nbd+tcp://$nbd_addr/$export_name"
++	else
++		nbd_url="nbd+unix:///$export_name?socket=$nbd_addr"
+ 	fi
+ 
+-	$PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" >/dev/null 2>&1 &
+-	wait_for_tcp_port "127\\.0\\.0\\.1:$port"
+ 	$QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd
+ 
+ 	echo
+ }
+ 
+-for event in neg1 "export" neg2 request reply data; do
+-	for when in before after; do
+-		check_disconnect "$event" "$when"
+-	done
+-
+-	# Also inject short replies from the NBD server
+-	case "$event" in
+-	neg1)
+-		for when in 8 16; do
+-			check_disconnect "$event" "$when"
+-		done
+-		;;
+-	"export")
+-		for when in 4 12 16; do
+-			check_disconnect "$event" "$when"
++for proto in tcp unix; do
++	for event in neg1 "export" neg2 request reply data; do
++		for when in before after; do
++			check_disconnect "--$proto" "$event" "$when"
+ 		done
+-		;;
+-	neg2)
+-		for when in 8 10; do
+-			check_disconnect "$event" "$when"
+-		done
+-		;;
+-	reply)
+-		for when in 4 8; do
+-			check_disconnect "$event" "$when"
+-		done
+-		;;
+-	esac
+-done
+ 
+-# Also check classic negotiation without export information
+-for when in before 8 16 24 28 after; do
+-	check_disconnect "neg-classic" "$when" --classic-negotiation
++		# Also inject short replies from the NBD server
++		case "$event" in
++		neg1)
++			for when in 8 16; do
++				check_disconnect "--$proto" "$event" "$when"
++			done
++			;;
++		"export")
++			for when in 4 12 16; do
++				check_disconnect "--$proto" "$event" "$when"
++			done
++			;;
++		neg2)
++			for when in 8 10; do
++				check_disconnect "--$proto" "$event" "$when"
++			done
++			;;
++		reply)
++			for when in 4 8; do
++				check_disconnect "--$proto" "$event" "$when"
++			done
++			;;
++		esac
++	done
++
++	# Also check classic negotiation without export information
++	for when in before 8 16 24 28 after; do
++		check_disconnect "--$proto" --classic-negotiation "neg-classic" "$when"
++	done
+ done
+ 
+ # success, all done
+diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out
+index a24c6bf..a7fb081 100644
+--- a/tests/qemu-iotests/083.out
++++ b/tests/qemu-iotests/083.out
+@@ -1,43 +1,43 @@
+ QA output created by 083
+ === Check disconnect before neg1 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect after neg1 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect 8 neg1 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect 16 neg1 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect before export ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect after export ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect 4 export ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect 12 export ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect 16 export ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect before neg2 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect after neg2 ===
+ 
+@@ -45,11 +45,11 @@ read failed: Input/output error
+ 
+ === Check disconnect 8 neg2 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect 10 neg2 ===
+ 
+-can't open device nbd:127.0.0.1:PORT:exportname=foo
++can't open device nbd+tcp://127.0.0.1:PORT/foo
+ 
+ === Check disconnect before request ===
+ 
+@@ -88,23 +88,134 @@ read 512/512 bytes at offset 0
+ 
+ === Check disconnect before neg-classic ===
+ 
+-can't open device nbd:127.0.0.1:PORT
++can't open device nbd+tcp://127.0.0.1:PORT/
+ 
+ === Check disconnect 8 neg-classic ===
+ 
+-can't open device nbd:127.0.0.1:PORT
++can't open device nbd+tcp://127.0.0.1:PORT/
+ 
+ === Check disconnect 16 neg-classic ===
+ 
+-can't open device nbd:127.0.0.1:PORT
++can't open device nbd+tcp://127.0.0.1:PORT/
+ 
+ === Check disconnect 24 neg-classic ===
+ 
+-can't open device nbd:127.0.0.1:PORT
++can't open device nbd+tcp://127.0.0.1:PORT/
+ 
+ === Check disconnect 28 neg-classic ===
+ 
+-can't open device nbd:127.0.0.1:PORT
++can't open device nbd+tcp://127.0.0.1:PORT/
++
++=== Check disconnect after neg-classic ===
++
++read failed: Input/output error
++
++=== Check disconnect before neg1 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect after neg1 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 8 neg1 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 16 neg1 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect before export ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect after export ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 4 export ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 12 export ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 16 export ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect before neg2 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect after neg2 ===
++
++read failed: Input/output error
++
++=== Check disconnect 8 neg2 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 10 neg2 ===
++
++can't open device nbd+unix:///foo?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect before request ===
++
++read failed: Input/output error
++
++=== Check disconnect after request ===
++
++read failed: Input/output error
++
++=== Check disconnect before reply ===
++
++read failed: Input/output error
++
++=== Check disconnect after reply ===
++
++read failed: Input/output error
++
++=== Check disconnect 4 reply ===
++
++read failed
++read failed: Input/output error
++
++=== Check disconnect 8 reply ===
++
++read failed
++read failed: Input/output error
++
++=== Check disconnect before data ===
++
++read failed: Input/output error
++
++=== Check disconnect after data ===
++
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Check disconnect before neg-classic ===
++
++can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 8 neg-classic ===
++
++can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 16 neg-classic ===
++
++can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 24 neg-classic ===
++
++can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
++
++=== Check disconnect 28 neg-classic ===
++
++can't open device nbd+unix:///?socket=TEST_DIR/nbd.sock
+ 
+ === Check disconnect after neg-classic ===
+ 
+diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
+index 7a58e57..9d5442e 100644
+--- a/tests/qemu-iotests/common.filter
++++ b/tests/qemu-iotests/common.filter
+@@ -170,9 +170,9 @@ _filter_nbd()
+     #
+     # Filter out the TCP port number since this changes between runs.
+     sed -e '/nbd\/.*\.c:/d' \
+-        -e 's#nbd:\(//\)\?127\.0\.0\.1:[0-9]*#nbd:\1127.0.0.1:PORT#g' \
++        -e 's#127\.0\.0\.1:[0-9]*#127.0.0.1:PORT#g' \
+         -e "s#?socket=$TEST_DIR#?socket=TEST_DIR#g" \
+-        -e 's#\(exportname=foo\|PORT\): Failed to .*$#\1#'
++        -e 's#\(foo\|PORT/\?\|.sock\): Failed to .*$#\1#'
+ }
+ 
+ # make sure this script returns success
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-iothread-IOThread-supports-the-GMainContext-eve.patch b/SOURCES/kvm-qemu-iothread-IOThread-supports-the-GMainContext-eve.patch
new file mode 100644
index 0000000..c395845
--- /dev/null
+++ b/SOURCES/kvm-qemu-iothread-IOThread-supports-the-GMainContext-eve.patch
@@ -0,0 +1,134 @@
+From 79000a2843af86fcd026ba8eb899dfeb1da0e04d Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:43 +0100
+Subject: [PATCH 25/42] qemu-iothread: IOThread supports the GMainContext event
+ loop
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-4-stefanha@redhat.com>
+Patchwork-id: 78485
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 03/20] qemu-iothread: IOThread supports the GMainContext event loop
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Wang Yong <wang.yong155@zte.com.cn>
+
+IOThread uses AioContext event loop and does not run a GMainContext.
+Therefore,chardev cannot work in IOThread,such as the chardev is
+used for colo-compare packets reception.
+
+This patch makes the IOThread run the GMainContext event loop,
+chardev and IOThread can work together.
+
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
+Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+(cherry picked from commit 329163cbe64a615b4edf6c40f2fff8c79dbc8fb4)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/sysemu/iothread.h |  4 ++++
+ iothread.c                | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 49 insertions(+)
+
+diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
+index e6da1a4..d2985b3 100644
+--- a/include/sysemu/iothread.h
++++ b/include/sysemu/iothread.h
+@@ -24,6 +24,9 @@ typedef struct {
+ 
+     QemuThread thread;
+     AioContext *ctx;
++    GMainContext *worker_context;
++    GMainLoop *main_loop;
++    GOnce once;
+     QemuMutex init_done_lock;
+     QemuCond init_done_cond;    /* is thread initialization done? */
+     bool stopping;
+@@ -41,5 +44,6 @@ typedef struct {
+ char *iothread_get_id(IOThread *iothread);
+ AioContext *iothread_get_aio_context(IOThread *iothread);
+ void iothread_stop_all(void);
++GMainContext *iothread_get_g_main_context(IOThread *iothread);
+ 
+ #endif /* IOTHREAD_H */
+diff --git a/iothread.c b/iothread.c
+index d67bdd4..59d0850 100644
+--- a/iothread.c
++++ b/iothread.c
+@@ -57,6 +57,23 @@ static void *iothread_run(void *opaque)
+ 
+     while (!atomic_read(&iothread->stopping)) {
+         aio_poll(iothread->ctx, true);
++
++        if (atomic_read(&iothread->worker_context)) {
++            GMainLoop *loop;
++
++            g_main_context_push_thread_default(iothread->worker_context);
++            iothread->main_loop =
++                g_main_loop_new(iothread->worker_context, TRUE);
++            loop = iothread->main_loop;
++
++            g_main_loop_run(iothread->main_loop);
++            iothread->main_loop = NULL;
++            g_main_loop_unref(loop);
++
++            g_main_context_pop_thread_default(iothread->worker_context);
++            g_main_context_unref(iothread->worker_context);
++            iothread->worker_context = NULL;
++        }
+     }
+ 
+     rcu_unregister_thread();
+@@ -73,6 +90,9 @@ static int iothread_stop(Object *object, void *opaque)
+     }
+     iothread->stopping = true;
+     aio_notify(iothread->ctx);
++    if (atomic_read(&iothread->main_loop)) {
++        g_main_loop_quit(iothread->main_loop);
++    }
+     qemu_thread_join(&iothread->thread);
+     return 0;
+ }
+@@ -125,6 +145,7 @@ static void iothread_complete(UserCreatable *obj, Error **errp)
+ 
+     qemu_mutex_init(&iothread->init_done_lock);
+     qemu_cond_init(&iothread->init_done_cond);
++    iothread->once = (GOnce) G_ONCE_INIT;
+ 
+     /* This assumes we are called from a thread with useful CPU affinity for us
+      * to inherit.
+@@ -309,3 +330,27 @@ void iothread_stop_all(void)
+ 
+     object_child_foreach(container, iothread_stop, NULL);
+ }
++
++static gpointer iothread_g_main_context_init(gpointer opaque)
++{
++    AioContext *ctx;
++    IOThread *iothread = opaque;
++    GSource *source;
++
++    iothread->worker_context = g_main_context_new();
++
++    ctx = iothread_get_aio_context(iothread);
++    source = aio_get_g_source(ctx);
++    g_source_attach(source, iothread->worker_context);
++    g_source_unref(source);
++
++    aio_notify(iothread->ctx);
++    return NULL;
++}
++
++GMainContext *iothread_get_g_main_context(IOThread *iothread)
++{
++    g_once(&iothread->once, iothread_g_main_context_init, iothread);
++
++    return iothread->worker_context;
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-kvm-ma-define-only-pseries-rhel7.5.0-machine-ty.patch b/SOURCES/kvm-qemu-kvm-ma-define-only-pseries-rhel7.5.0-machine-ty.patch
new file mode 100644
index 0000000..3cdd38b
--- /dev/null
+++ b/SOURCES/kvm-qemu-kvm-ma-define-only-pseries-rhel7.5.0-machine-ty.patch
@@ -0,0 +1,67 @@
+From d8bf28e9ec1a5d854c3fa6f17001db2e8bc59a7a Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Mon, 9 Oct 2017 14:23:18 +0200
+Subject: [PATCH 08/69] qemu-kvm-ma: define only pseries-rhel7.5.0 machine type
+ for -ma
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171009142318.6262-5-lvivier@redhat.com>
+Patchwork-id: 77032
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 4/4] qemu-kvm-ma: define only pseries-rhel7.5.0 machine type for -ma
+Bugzilla: 1478478
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+qemu-kvm-ma doesn't support pseries-rhel7.2.0,
+pseries-rhel7.3.0, pseries-rhel7.4.0 whereas
+qemu-kvm-rhev does. And as the sources are shared
+we use a configuration switch to disable this part
+of the code.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index cb317f8..3c598fd 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3734,6 +3734,7 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false);
+     },
+ #endif
+ 
++#if defined(CONFIG_RHV)
+ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
+                               uint64_t *buid, hwaddr *pio,
+                               hwaddr *mmio32, hwaddr *mmio64,
+@@ -3782,6 +3783,7 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
+      * window into contiguous 32-bit and 64-bit windows
+      */
+ }
++#endif /* CONFIG_RHV */
+ 
+ #if 0 /* Disabled for Red Hat Enterprise Linux */
+ static void spapr_machine_2_7_instance_options(MachineState *machine)
+@@ -3960,6 +3962,8 @@ static void spapr_machine_rhel750_class_options(MachineClass *mc)
+ 
+ DEFINE_SPAPR_MACHINE(rhel750, "rhel7.5.0", true);
+ 
++#if defined(CONFIG_RHV)
++
+ /*
+  * pseries-rhel7.4.0
+  * like SPAPR_COMPAT_2_9
+@@ -4079,6 +4083,7 @@ static void spapr_machine_rhel720_class_options(MachineClass *mc)
+ }
+ 
+ DEFINE_SPAPR_MACHINE(rhel720, "rhel7.2.0", false);
++#endif /* CONFIG_RHV */
+ 
+ static void spapr_machine_register_types(void)
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-kvm-rhev-only-allows-pseries-rhel7.5.0-machine-.patch b/SOURCES/kvm-qemu-kvm-rhev-only-allows-pseries-rhel7.5.0-machine-.patch
new file mode 100644
index 0000000..57e3767
--- /dev/null
+++ b/SOURCES/kvm-qemu-kvm-rhev-only-allows-pseries-rhel7.5.0-machine-.patch
@@ -0,0 +1,151 @@
+From 8663586f2bc64d4761d4f621bc7aa781a4a450b2 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Fri, 20 Oct 2017 14:02:07 +0200
+Subject: [PATCH 1/9] qemu-kvm-rhev: only allows pseries-rhel7.5.0 machine type
+ with POWER9 guest
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171020140207.15190-1-lvivier@redhat.com>
+Patchwork-id: 77416
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v3 3/4] qemu-kvm-rhev: only allows pseries-rhel7.5.0 machine type with POWER9 guest
+Bugzilla: 1478469
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+
+We disable all machine types except pseries-rhel7.5.0 for POWER9
+guest.
+
+qemu-kvm-rhev does't not support POWER9 with former machine types
+so disable them dynamically. We allow all machine types on POWER9
+host but with guest in POWER8 CPU mode
+(for instance "-M pseries-rhel7.4.0,max-cpu-compat=power8")
+
+"-M help" display all the machine types, but if the guest is started
+with "-cpu POWER9" and with a machine type which is not
+"pseries-rhel7.5.0" an error message is displayed and the guest is
+stopped.
+
+We use the ppc_check_compat() to compare current CPU version with ISA
+level of POWER9 (CPU_POWERPC_LOGICAL_3_00), but as POWER9 DD1 has some
+bugs, POWER9 DD1 does not advertise PCR_COMPAT_3_00 (see
+kvmppc_host_cpu_class_init()), and thus this allows to run all the machine
+types with POWER9 DD1.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c          |  2 ++
+ hw/ppc/spapr_cpu_core.c | 13 +++++++++++++
+ include/hw/ppc/spapr.h  |  1 +
+ target/ppc/compat.c     | 11 +++++++++++
+ target/ppc/cpu.h        |  1 +
+ 5 files changed, 28 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 5fe7769..42028ef 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3592,6 +3592,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+      * in which LMBs are represented and hot-added
+      */
+     mc->numa_mem_align_shift = 28;
++    smc->has_power9_support = true;
+ }
+ 
+ static const TypeInfo spapr_machine_info = {
+@@ -3993,6 +3994,7 @@ static void spapr_machine_rhel740_class_options(MachineClass *mc)
+     spapr_machine_rhel750_class_options(mc);
+     SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_4);
+     mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
++    smc->has_power9_support = false;
+     smc->pre_2_10_has_unused_icps = true;
+     smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
+ }
+diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
+index 3e731e4..400ab56 100644
+--- a/hw/ppc/spapr_cpu_core.c
++++ b/hw/ppc/spapr_cpu_core.c
+@@ -19,6 +19,7 @@
+ #include "target/ppc/mmu-hash64.h"
+ #include "sysemu/numa.h"
+ #include "qemu/error-report.h"
++#include "cpu-models.h"
+ 
+ void spapr_cpu_parse_features(sPAPRMachineState *spapr)
+ {
+@@ -111,6 +112,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+                            Error **errp)
+ {
+     CPUPPCState *env = &cpu->env;
++    sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ 
+     /* Set time-base frequency to 512 MHz */
+     cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
+@@ -118,6 +120,17 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
+     /* Enable PAPR mode in TCG or KVM */
+     cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
+ 
++    if (!smc->has_power9_support &&
++        (((spapr->max_compat_pvr &&
++           ppc_compat_cmp(spapr->max_compat_pvr,
++                          CPU_POWERPC_LOGICAL_3_00) >= 0)) ||
++          (!spapr->max_compat_pvr &&
++           ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) {
++        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
++                  "POWER9 CPU is not supported by this machine class");
++        return;
++    }
++
+     qemu_register_reset(spapr_cpu_reset, cpu);
+     spapr_cpu_reset(cpu);
+ }
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 3d0d206..d9e8e5a 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -62,6 +62,7 @@ struct sPAPRMachineClass {
+     bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
+     const char *tcg_default_cpu; /* which (TCG) CPU to simulate by default */
+     bool pre_2_10_has_unused_icps;
++    bool has_power9_support;
+     void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
+                           uint64_t *buid, hwaddr *pio, 
+                           hwaddr *mmio32, hwaddr *mmio64,
+diff --git a/target/ppc/compat.c b/target/ppc/compat.c
+index f8729fe..540b4eb 100644
+--- a/target/ppc/compat.c
++++ b/target/ppc/compat.c
+@@ -89,6 +89,17 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr)
+     return NULL;
+ }
+ 
++long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2)
++{
++    const CompatInfo *compat1 = compat_by_pvr(pvr1);
++    const CompatInfo *compat2 = compat_by_pvr(pvr2);
++
++    g_assert(compat1);
++    g_assert(compat2);
++
++    return compat1 - compat2;
++}
++
+ bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
+                       uint32_t min_compat_pvr, uint32_t max_compat_pvr)
+ {
+diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
+index 46d3dd8..6c770a2 100644
+--- a/target/ppc/cpu.h
++++ b/target/ppc/cpu.h
+@@ -1367,6 +1367,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
+ 
+ /* Compatibility modes */
+ #if defined(TARGET_PPC64)
++long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2);
+ bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
+                       uint32_t min_compat_pvr, uint32_t max_compat_pvr);
+ void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-options-Mention-locking-option-of-file-driver.patch b/SOURCES/kvm-qemu-options-Mention-locking-option-of-file-driver.patch
new file mode 100644
index 0000000..aefaf26
--- /dev/null
+++ b/SOURCES/kvm-qemu-options-Mention-locking-option-of-file-driver.patch
@@ -0,0 +1,41 @@
+From 47c794c7f8010caf97447badfb059fc8fd6aa89f Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Thu, 30 Nov 2017 09:25:43 +0100
+Subject: [PATCH 06/36] qemu-options: Mention locking option of file driver
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20171130092544.19231-5-famz@redhat.com>
+Patchwork-id: 78018
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 4/5] qemu-options: Mention locking option of file driver
+Bugzilla: 1494210
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 1878eaff9bdeece4546d4f9587e6c75ab0b79b8b)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qemu-options.hx | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 50ba50e..5878359 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -693,6 +693,10 @@ This is the protocol-level block driver for accessing regular files.
+ The path to the image file in the local filesystem
+ @item aio
+ Specifies the AIO backend (threads/native, default: threads)
++@item locking
++Specifies whether the image file is protected with Linux OFD / POSIX locks. The
++default is to use the Linux Open File Descriptor API if available, otherwise no
++lock is applied.  (auto/on/off, default: auto)
+ @end table
+ Example:
+ @example
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-pr-helper-miscellaneous-fixes.patch b/SOURCES/kvm-qemu-pr-helper-miscellaneous-fixes.patch
new file mode 100644
index 0000000..7c0fc31
--- /dev/null
+++ b/SOURCES/kvm-qemu-pr-helper-miscellaneous-fixes.patch
@@ -0,0 +1,131 @@
+From 35c11f52fe8423b40d133e22150354a595fd109f Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:53 +0100
+Subject: [PATCH 27/36] qemu-pr-helper: miscellaneous fixes
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-18-pbonzini@redhat.com>
+Patchwork-id: 78090
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 17/17] qemu-pr-helper: miscellaneous fixes
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+1) Return a generic sense if TEST UNIT READY does not provide one;
+
+2) Fix two mistakes in copying from the spec.
+
+Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 041a4acfdf4d9b2db60b10805aed94178dbf0463)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/scsi/utils.h  |  6 +++++-
+ scsi/qemu-pr-helper.c | 30 ++++++++++++++++++++++++++----
+ scsi/utils.c          | 10 ++++++++++
+ 3 files changed, 41 insertions(+), 5 deletions(-)
+
+diff --git a/include/scsi/utils.h b/include/scsi/utils.h
+index 00a4bdb..eb07e47 100644
+--- a/include/scsi/utils.h
++++ b/include/scsi/utils.h
+@@ -76,7 +76,11 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
+ extern const struct SCSISense sense_code_LUN_COMM_FAILURE;
+ /* Command aborted, Overlapped Commands Attempted */
+ extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
+-/* LUN not ready, Capacity data has changed */
++/* Medium error, Unrecovered read error */
++extern const struct SCSISense sense_code_READ_ERROR;
++/* LUN not ready, Cause not reportable */
++extern const struct SCSISense sense_code_NOT_READY;
++/* Unit attention, Capacity data has changed */
+ extern const struct SCSISense sense_code_CAPACITY_CHANGED;
+ /* Unit attention, SCSI bus reset */
+ extern const struct SCSISense sense_code_SCSI_BUS_RESET;
+diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
+index 42bc2cf..4c6ca63 100644
+--- a/scsi/qemu-pr-helper.c
++++ b/scsi/qemu-pr-helper.c
+@@ -303,6 +303,22 @@ static int is_mpath(int fd)
+     return !strncmp(tgt->target_type, "multipath", DM_MAX_TYPE_NAME);
+ }
+ 
++static SCSISense mpath_generic_sense(int r)
++{
++    switch (r) {
++    case MPATH_PR_SENSE_NOT_READY:
++         return SENSE_CODE(NOT_READY);
++    case MPATH_PR_SENSE_MEDIUM_ERROR:
++         return SENSE_CODE(READ_ERROR);
++    case MPATH_PR_SENSE_HARDWARE_ERROR:
++         return SENSE_CODE(TARGET_FAILURE);
++    case MPATH_PR_SENSE_ABORTED_COMMAND:
++         return SENSE_CODE(IO_ERROR);
++    default:
++         abort();
++    }
++}
++
+ static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
+ {
+     switch (r) {
+@@ -318,7 +334,13 @@ static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
+              */
+             uint8_t cdb[6] = { TEST_UNIT_READY };
+             int sz = 0;
+-            return do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
++            int r = do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
++
++            if (r != GOOD) {
++                return r;
++            }
++            scsi_build_sense(sense, mpath_generic_sense(r));
++            return CHECK_CONDITION;
+         }
+ 
+     case MPATH_PR_SENSE_UNIT_ATTENTION:
+@@ -438,7 +460,7 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
+     memset(&paramp, 0, sizeof(paramp));
+     memcpy(&paramp.key, &param[0], 8);
+     memcpy(&paramp.sa_key, &param[8], 8);
+-    paramp.sa_flags = param[10];
++    paramp.sa_flags = param[20];
+     if (sz > PR_OUT_FIXED_PARAM_SIZE) {
+         size_t transportid_len;
+         int i, j;
+@@ -467,8 +489,8 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
+                 j += offsetof(struct transportid, n_port_name[8]);
+                 i += 24;
+                 break;
+-            case 3:
+-            case 0x43:
++            case 5:
++            case 0x45:
+                 /* iSCSI transport.  */
+                 len = lduw_be_p(&param[i + 2]);
+                 if (len > 252 || (len & 3) || i + len + 4 > transportid_len) {
+diff --git a/scsi/utils.c b/scsi/utils.c
+index 5684951..e4182a9 100644
+--- a/scsi/utils.c
++++ b/scsi/utils.c
+@@ -211,6 +211,16 @@ const struct SCSISense sense_code_LUN_COMM_FAILURE = {
+     .key = ABORTED_COMMAND, .asc = 0x08, .ascq = 0x00
+ };
+ 
++/* Medium Error, Unrecovered read error */
++const struct SCSISense sense_code_READ_ERROR = {
++    .key = MEDIUM_ERROR, .asc = 0x11, .ascq = 0x00
++};
++
++/* Not ready, Cause not reportable */
++const struct SCSISense sense_code_NOT_READY = {
++    .key = NOT_READY, .asc = 0x04, .ascq = 0x00
++};
++
+ /* Unit attention, Capacity data has changed */
+ const struct SCSISense sense_code_CAPACITY_CHANGED = {
+     .key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu.py-make-VM-a-context-manager.patch b/SOURCES/kvm-qemu.py-make-VM-a-context-manager.patch
new file mode 100644
index 0000000..8ea3252
--- /dev/null
+++ b/SOURCES/kvm-qemu.py-make-VM-a-context-manager.patch
@@ -0,0 +1,74 @@
+From da96c55a017fbc750b49550c6e7a523dcdab0dbe Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:41 +0100
+Subject: [PATCH 23/42] qemu.py: make VM() a context manager
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-2-stefanha@redhat.com>
+Patchwork-id: 78483
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 01/20] qemu.py: make VM() a context manager
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+There are a number of ways to ensure that the QEMU process is shut down
+when the test ends, including atexit.register(), try: finally:, or
+unittest.teardown() methods.  All of these require extra code and the
+programmer must remember to add vm.shutdown().
+
+A nice solution is context managers:
+
+  with VM(binary) as vm:
+      ...
+  # vm is guaranteed to be shut down here
+
+Cc: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: 20170824072202.26818-2-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit d792bc3811f22a22a46c7d9a725fd29029f54095)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/qemu.py | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/qemu.py b/scripts/qemu.py
+index 880e3e8..4d8ee10 100644
+--- a/scripts/qemu.py
++++ b/scripts/qemu.py
+@@ -21,7 +21,14 @@ import qmp.qmp
+ 
+ 
+ class QEMUMachine(object):
+-    '''A QEMU VM'''
++    '''A QEMU VM
++
++    Use this object as a context manager to ensure the QEMU process terminates::
++
++        with VM(binary) as vm:
++            ...
++        # vm is guaranteed to be shut down here
++    '''
+ 
+     def __init__(self, binary, args=[], wrapper=[], name=None, test_dir="/var/tmp",
+                  monitor_address=None, socket_scm_helper=None, debug=False):
+@@ -40,6 +47,13 @@ class QEMUMachine(object):
+         self._socket_scm_helper = socket_scm_helper
+         self._debug = debug
+ 
++    def __enter__(self):
++        return self
++
++    def __exit__(self, exc_type, exc_val, exc_tb):
++        self.shutdown()
++        return False
++
+     # This can be used to add an unused monitor instance.
+     def add_monitor_telnet(self, ip, port):
+         args = 'tcp:%s:%d,server,nowait,telnet' % (ip, port)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qom-provide-root-container-for-internal-objs.patch b/SOURCES/kvm-qom-provide-root-container-for-internal-objs.patch
new file mode 100644
index 0000000..82aeff5
--- /dev/null
+++ b/SOURCES/kvm-qom-provide-root-container-for-internal-objs.patch
@@ -0,0 +1,86 @@
+From f105da1e0b15cdded39ad0a96501aace13e3bd6b Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 22 Dec 2017 11:08:44 +0100
+Subject: [PATCH 26/42] qom: provide root container for internal objs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171222110900.24813-5-stefanha@redhat.com>
+Patchwork-id: 78486
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 04/20] qom: provide root container for internal objs
+Bugzilla: 1519721
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Peter Xu <peterx@redhat.com>
+
+We have object_get_objects_root() to keep user created objects, however
+no place for objects that will be used internally.  Create such a
+container for internal objects.
+
+CC: Andreas Färber <afaerber@suse.de>
+CC: Markus Armbruster <armbru@redhat.com>
+CC: Paolo Bonzini <pbonzini@redhat.com>
+Suggested-by: Daniel P. Berrange <berrange@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Message-id: 20170928025958.1420-2-peterx@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 7c47c4ead75d0b733ee8f2f51fd1de0644cc1308)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/qom/object.h | 11 +++++++++++
+ qom/object.c         | 11 +++++++++++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/include/qom/object.h b/include/qom/object.h
+index 1b82899..dde5086 100644
+--- a/include/qom/object.h
++++ b/include/qom/object.h
+@@ -1214,6 +1214,17 @@ Object *object_get_root(void);
+ Object *object_get_objects_root(void);
+ 
+ /**
++ * object_get_internal_root:
++ *
++ * Get the container object that holds internally used object
++ * instances.  Any object which is put into this container must not be
++ * user visible, and it will not be exposed in the QOM tree.
++ *
++ * Returns: the internal object container
++ */
++Object *object_get_internal_root(void);
++
++/**
+  * object_get_canonical_path_component:
+  *
+  * Returns: The final component in the object's canonical path.  The canonical
+diff --git a/qom/object.c b/qom/object.c
+index fe6e744..4e4b2f7 100644
+--- a/qom/object.c
++++ b/qom/object.c
+@@ -1370,6 +1370,17 @@ Object *object_get_objects_root(void)
+     return container_get(object_get_root(), "/objects");
+ }
+ 
++Object *object_get_internal_root(void)
++{
++    static Object *internal_root;
++
++    if (!internal_root) {
++        internal_root = object_new("container");
++    }
++
++    return internal_root;
++}
++
+ static void object_get_child_property(Object *obj, Visitor *v,
+                                       const char *name, void *opaque,
+                                       Error **errp)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-redhat-add-CONFIG_RHV-flag.patch b/SOURCES/kvm-redhat-add-CONFIG_RHV-flag.patch
new file mode 100644
index 0000000..365d2b2
--- /dev/null
+++ b/SOURCES/kvm-redhat-add-CONFIG_RHV-flag.patch
@@ -0,0 +1,85 @@
+From 4506913c42c58ef5a667779596af1c4bd1b11102 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Fri, 6 Oct 2017 16:04:07 +0200
+Subject: [PATCH 04/69] redhat: add CONFIG_RHV flag
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171006160407.18609-1-lvivier@redhat.com>
+Patchwork-id: 76906
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v3] redhat: add CONFIG_RHV flag
+Bugzilla: 1498865
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+We need to know if the binaries we build are for qemu-kvm-rhev
+or qemu-kvm-ma.
+
+Add an option to configure to select the target:
+--rhel-target=rhv for qemu-kvm-rhev or
+--rhel-target=rhel for qemu-kvm-ma.
+
+If RHEL target is rhv, the CONFIG_RHV macro is defined.
+By default, configure selects "rhv" target.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ configure                     | 9 +++++++++
+ redhat/Makefile               | 2 +-
+ redhat/Makefile.local         | 1 +
+ redhat/build_configure.sh     | 9 +++++++++
+ redhat/qemu-kvm.spec.template | 5 +++++
+ 5 files changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index 457b2ff..0da6821 100755
+--- a/configure
++++ b/configure
+@@ -407,6 +407,7 @@ jemalloc="no"
+ replication="yes"
+ vxhs=""
+ vtd="yes"
++rhel_target="rhv"
+ 
+ supported_cpu="no"
+ supported_os="no"
+@@ -1301,6 +1302,8 @@ for opt do
+   ;;
+   --enable-vtd) vtd="yes"
+   ;;
++  --rhel-target=*) rhel_target="$optarg"
++  ;;
+   *)
+       echo "ERROR: unknown option $opt"
+       echo "Try '$0 --help' for more information"
+@@ -1469,6 +1472,7 @@ Advanced options (experts only):
+                            xen pv domain builder
+   --enable-debug-stack-usage
+                            track the maximum stack usage of stacks created by qemu_alloc_stack
++  --rhel-target            set RHEL target (rhv or rhel)
+ 
+ Optional features, enabled with --enable-FEATURE and
+ disabled with --disable-FEATURE, default is enabled if available:
+@@ -5395,6 +5399,7 @@ echo "avx2 optimization $avx2_opt"
+ echo "replication support $replication"
+ echo "VxHS block device $vxhs"
+ echo "VT-d emulation    $vtd"
++echo "RHEL target       $rhel_target"
+ 
+ if test "$sdl_too_old" = "yes"; then
+ echo "-> Your SDL version is too old - please upgrade to have SDL support"
+@@ -6064,6 +6069,10 @@ if test "$vtd" = "yes" ; then
+   echo "CONFIG_VTD=y" >> $config_host_mak
+ fi
+ 
++if test "$rhel_target" = "rhv" ; then
++  echo "CONFIG_RHV=y" >> $config_host_mak
++fi
++
+ if test "$tcg_interpreter" = "yes"; then
+   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
+ elif test "$ARCH" = "sparc64" ; then
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-redhat-define-HW_COMPAT_RHEL7_4.patch b/SOURCES/kvm-redhat-define-HW_COMPAT_RHEL7_4.patch
new file mode 100644
index 0000000..114e46d
--- /dev/null
+++ b/SOURCES/kvm-redhat-define-HW_COMPAT_RHEL7_4.patch
@@ -0,0 +1,51 @@
+From ea157600dac6db592419ad9a8562ad86a8103627 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Mon, 9 Oct 2017 14:23:15 +0200
+Subject: [PATCH 06/69] redhat: define HW_COMPAT_RHEL7_4
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171009142318.6262-2-lvivier@redhat.com>
+Patchwork-id: 77033
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/4] redhat: define HW_COMPAT_RHEL7_4
+Bugzilla: 1478478
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/hw/compat.h | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/include/hw/compat.h b/include/hw/compat.h
+index aa616e3..85c6cbe 100644
+--- a/include/hw/compat.h
++++ b/include/hw/compat.h
+@@ -413,4 +413,23 @@
+         .value    = "off",\
+     },
+ 
++/* Mostly like HW_COMPAT_2_9 except
++ * x-mtu-bypass-backend has already been
++ * backported to RHEL7.4
++ */
++#define HW_COMPAT_RHEL7_4 \
++    { /* HW_COMPAT_RHEL7_4 */ \
++        .driver   = "pci-bridge",\
++        .property = "shpc",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_4 */ \
++        .driver   = "intel-iommu",\
++        .property = "pt",\
++        .value    = "off",\
++    },{ /* HW_COMPAT_RHEL7_4 */ \
++        .driver   = "pcie-root-port",\
++        .property = "x-migrate-msix",\
++        .value    = "false",\
++    },
++
+ #endif /* HW_COMPAT_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-redhat-define-pseries-rhel7.5.0-machine-type.patch b/SOURCES/kvm-redhat-define-pseries-rhel7.5.0-machine-type.patch
new file mode 100644
index 0000000..98030db
--- /dev/null
+++ b/SOURCES/kvm-redhat-define-pseries-rhel7.5.0-machine-type.patch
@@ -0,0 +1,85 @@
+From 86ef5cd189077ab6a1a3b55ed844408c1ba8f75a Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Mon, 9 Oct 2017 14:23:16 +0200
+Subject: [PATCH 07/69] redhat: define pseries-rhel7.5.0 machine type
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171009142318.6262-3-lvivier@redhat.com>
+Patchwork-id: 77034
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/4] redhat: define pseries-rhel7.5.0 machine type
+Bugzilla: 1478478
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+As we don't support migration from PEGAS 1.0, pseries-rhel7.4.0alt is removed
+(replaced) in this patch.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 30b2c5b..cb317f8 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3946,32 +3946,47 @@ DEFINE_SPAPR_MACHINE(2_1, "2.1", false);
+ #endif
+ 
+ /*
+- * pseries-rhel7.4.0alt
++ * pseries-rhel7.5.0
+  */
+-static void spapr_machine_rhel740alt_instance_options(MachineState *machine)
++
++static void spapr_machine_rhel750_instance_options(MachineState *machine)
+ {
+ }
+ 
+-static void spapr_machine_rhel740alt_class_options(MachineClass *mc)
++static void spapr_machine_rhel750_class_options(MachineClass *mc)
+ {
+     /* Defaults for the latest behaviour inherited from the base class */
+ }
+ 
+-DEFINE_SPAPR_MACHINE(rhel740alt, "rhel7.4.0alt", true);
+-
++DEFINE_SPAPR_MACHINE(rhel750, "rhel7.5.0", true);
+ 
+ /*
+  * pseries-rhel7.4.0
++ * like SPAPR_COMPAT_2_9
+  */
+ 
++#define SPAPR_COMPAT_RHEL7_4                                           \
++    HW_COMPAT_RHEL7_4                                                  \
++    {                                                                  \
++        .driver = TYPE_POWERPC_CPU,                                    \
++        .property = "pre-2.10-migration",                              \
++        .value    = "on",                                              \
++    },                                                                 \
++
+ static void spapr_machine_rhel740_instance_options(MachineState *machine)
+ {
+-    spapr_machine_rhel740alt_instance_options(machine);
++    spapr_machine_rhel750_instance_options(machine);
+ }
+ 
+ static void spapr_machine_rhel740_class_options(MachineClass *mc)
+ {
+-    spapr_machine_rhel740alt_class_options(mc);
++    sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
++
++    spapr_machine_rhel750_class_options(mc);
++    SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_4);
++    mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
++    smc->pre_2_10_has_unused_icps = true;
++    smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
+ }
+ 
+ DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-redhat-fix-HW_COMPAT_RHEL7_3.patch b/SOURCES/kvm-redhat-fix-HW_COMPAT_RHEL7_3.patch
new file mode 100644
index 0000000..077104b
--- /dev/null
+++ b/SOURCES/kvm-redhat-fix-HW_COMPAT_RHEL7_3.patch
@@ -0,0 +1,56 @@
+From 58702e8dbb2b2abc09b737d55d633228329d7256 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Thu, 5 Oct 2017 08:16:15 +0200
+Subject: [PATCH 09/34] redhat: fix HW_COMPAT_RHEL7_3
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171005081615.20677-1-lvivier@redhat.com>
+Patchwork-id: 76810
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] redhat: fix HW_COMPAT_RHEL7_3
+Bugzilla: 1498754
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+BZ:   https://bugzilla.redhat.com/show_bug.cgi?id=1498754
+BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14179622
+Upstream-status: downstream only
+
+x-mtu-bypass-backend has been added to HW_COMPAT_2_1 instead of
+HW_COMPAT_RHEL7_3. Fix that.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/hw/compat.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/hw/compat.h b/include/hw/compat.h
+index 56cefc9..aa616e3 100644
+--- a/include/hw/compat.h
++++ b/include/hw/compat.h
+@@ -227,10 +227,6 @@
+         .driver   = "virtio-pci",\
+         .property = "virtio-pci-bus-master-bug-migration",\
+         .value    = "on",\
+-    },{ /* HW_COMPAT_RHEL7_3 */ \
+-        .driver   = "virtio-net-device",\
+-        .property = "x-mtu-bypass-backend",\
+-        .value    = "off",\
+     },
+ 
+ /* Mostly like HW_COMPAT_2_1 but:
+@@ -411,6 +407,10 @@
+         .driver   = "e1000e",\
+         .property = "__redhat_e1000e_7_3_intr_state",\
+         .value    = "on",\
++    },{ /* HW_COMPAT_RHEL7_3 */ \
++        .driver   = "virtio-net-device",\
++        .property = "x-mtu-bypass-backend",\
++        .value    = "off",\
+     },
+ 
+ #endif /* HW_COMPAT_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-redhat-globally-limit-the-maximum-number-of-CPUs.patch b/SOURCES/kvm-redhat-globally-limit-the-maximum-number-of-CPUs.patch
new file mode 100644
index 0000000..4a288ed
--- /dev/null
+++ b/SOURCES/kvm-redhat-globally-limit-the-maximum-number-of-CPUs.patch
@@ -0,0 +1,77 @@
+From bb722e9effd08ea9d64091914c6f09d061017cad Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 9 Jan 2018 10:32:52 +0100
+Subject: [PATCH 02/12] redhat: globally limit the maximum number of CPUs
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20180109103253.24517-2-david@redhat.com>
+Patchwork-id: 78531
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH v2 1/2] redhat: globally limit the maximum number of CPUs
+Bugzilla: 1527449
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+
+Upstream-status: n/a
+
+For RHEL, we support 240, for RHV up to 384 VCPUs. Let's limit this
+globally instead of fixing up all machines. This way, we can easily
+change (increase) the product specific levels later.
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ vl.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/vl.c b/vl.c
+index bef5ae3..90b542f 100644
+--- a/vl.c
++++ b/vl.c
+@@ -135,6 +135,12 @@ int main(int argc, char **argv)
+ #define MAX_VIRTIO_CONSOLES 1
+ #define MAX_SCLP_CONSOLES 1
+ 
++#if defined(CONFIG_RHV)
++#define RHEL_MAX_CPUS 384
++#else
++#define RHEL_MAX_CPUS 240
++#endif
++
+ static const char *data_dir[16];
+ static int data_dir_idx;
+ const char *bios_name = NULL;
+@@ -1501,6 +1507,20 @@ MachineClass *find_default_machine(void)
+     return mc;
+ }
+ 
++/* Maximum number of CPUs limited for Red Hat Enterprise Linux */
++static void limit_max_cpus_in_machines(void)
++{
++    GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
++
++    for (el = machines; el; el = el->next) {
++        MachineClass *mc = el->data;
++
++        if (mc->max_cpus > RHEL_MAX_CPUS) {
++            mc->max_cpus = RHEL_MAX_CPUS;
++        }
++    }
++}
++
+ MachineInfoList *qmp_query_machines(Error **errp)
+ {
+     GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
+@@ -4130,6 +4150,9 @@ int main(int argc, char **argv, char **envp)
+ 
+     replay_configure(icount_opts);
+ 
++    /* Maximum number of CPUs limited for Red Hat Enterprise Linux */
++    limit_max_cpus_in_machines();
++
+     machine_class = select_machine();
+ 
+     set_memory_options(&ram_slots, &maxram_size, machine_class);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-redhat-remove-manual-max_cpus-limitations-for-ppc.patch b/SOURCES/kvm-redhat-remove-manual-max_cpus-limitations-for-ppc.patch
new file mode 100644
index 0000000..ea010eb
--- /dev/null
+++ b/SOURCES/kvm-redhat-remove-manual-max_cpus-limitations-for-ppc.patch
@@ -0,0 +1,73 @@
+From 92fef14623387db071a79f64fa7996ce8ea9040e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 9 Jan 2018 10:32:53 +0100
+Subject: [PATCH 03/12] redhat: remove manual max_cpus limitations for ppc
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20180109103253.24517-3-david@redhat.com>
+Patchwork-id: 78532
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH v2 2/2] redhat: remove manual max_cpus limitations for ppc
+Bugzilla: 1527449
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+
+Upstream-status: n/a
+
+We now globally limit the number of VCPUs, depending on release type
+(RHEL vs. RHV). Especially, there is no way one can specify more than
+max_cpus VCPUs for a VM.
+
+This allows us the restore the ppc max_cpus limitation to the upstream
+default and minimize the ppc hack in kvm-all.c.
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ accel/kvm/kvm-all.c | 10 ----------
+ hw/ppc/spapr.c      |  3 +--
+ 2 files changed, 1 insertion(+), 12 deletions(-)
+
+diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
+index 94c4968..158fe66 100644
+--- a/accel/kvm/kvm-all.c
++++ b/accel/kvm/kvm-all.c
+@@ -1629,21 +1629,11 @@ static int kvm_init(MachineState *ms)
+ 
+ #ifdef HOST_PPC64
+     /*
+-     * RHEL hack:
+-     *
+      * On POWER, the kernel advertises a soft limit based on the
+      * number of CPU threads on the host.  We want to allow exceeding
+      * this for testing purposes, so we don't want to set hard limit
+      * to soft limit as on x86.
+-     *
+-     * However the POWER hard limit advertised by the kernel is 2048
+-     * (== NR_CPUS) but we only want to allow up to the number of
+-     * vCPUs we actually test, so we force the hard limit to 384
+      */
+-    hard_vcpus_limit = 384;
+-    if (soft_vcpus_limit > hard_vcpus_limit) {
+-        soft_vcpus_limit = hard_vcpus_limit;
+-    }
+ #else
+     /* RHEL doesn't support nr_vcpus > soft_vcpus_limit */
+     hard_vcpus_limit = soft_vcpus_limit;
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index d320b6c..d7fac62 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3586,8 +3586,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     mc->init = ppc_spapr_init;
+     mc->reset = ppc_spapr_reset;
+     mc->block_default_type = IF_SCSI;
+-    /* RHEL: set to max # of supported vcpus */
+-    mc->max_cpus = 384;
++    mc->max_cpus = 1024;
+     mc->no_parallel = 1;
+     mc->default_boot_order = "";
+     mc->default_ram_size = 512 * M_BYTE;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-ccw-Fix-alignment-for-CCW1.patch b/SOURCES/kvm-s390-ccw-Fix-alignment-for-CCW1.patch
new file mode 100644
index 0000000..d3bbccf
--- /dev/null
+++ b/SOURCES/kvm-s390-ccw-Fix-alignment-for-CCW1.patch
@@ -0,0 +1,51 @@
+From 5ddb3b822086c04493be468cc27e356cf174307d Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Wed, 22 Nov 2017 10:43:30 +0100
+Subject: [PATCH 13/15] s390-ccw: Fix alignment for CCW1
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1511347411-16226-3-git-send-email-thuth@redhat.com>
+Patchwork-id: 77775
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 2/3] s390-ccw: Fix alignment for CCW1
+Bugzilla: 1514352
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Farhan Ali <alifm@linux.vnet.ibm.com>
+
+The commit 198c0d1f9df8c4 s390x/css: check ccw address validity
+exposes an alignment issue in ccw bios.
+
+According to PoP the CCW must be doubleword aligned. Let's fix
+this in the bios.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Farhan Ali <alifm@linux.vnet.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reviewed-by: Eric Farman <farman@linux.vnet.ibm.com>
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <3ed8b810b6592daee6a775037ce21f850e40647d.1503667215.git.alifm@linux.vnet.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 3a1e4561ad63b303b092387ae006bd41468ece63)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ pc-bios/s390-ccw/cio.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
+index f5b4549..55eaeee 100644
+--- a/pc-bios/s390-ccw/cio.h
++++ b/pc-bios/s390-ccw/cio.h
+@@ -133,7 +133,7 @@ struct ccw1 {
+     __u8 flags;
+     __u16 count;
+     __u32 cda;
+-} __attribute__ ((packed));
++} __attribute__ ((packed, aligned(8)));
+ 
+ #define CCW_FLAG_DC              0x80
+ #define CCW_FLAG_CC              0x40
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-ais-for-2.10-stable-disable-ais-facility.patch b/SOURCES/kvm-s390x-ais-for-2.10-stable-disable-ais-facility.patch
new file mode 100644
index 0000000..4b20d6c
--- /dev/null
+++ b/SOURCES/kvm-s390x-ais-for-2.10-stable-disable-ais-facility.patch
@@ -0,0 +1,54 @@
+From 49a0dc9e670b7f67713a7f9115028a4a29fbd03b Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Thu, 5 Oct 2017 12:04:05 +0200
+Subject: [PATCH 11/34] s390x/ais: for 2.10 stable: disable ais facility
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20171005120406.16642-2-cohuck@redhat.com>
+Patchwork-id: 76818
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 1/2] s390x/ais: for 2.10 stable: disable ais facility
+Bugzilla: 1494548
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+The migration interface for ais was introduced with kernel 4.13
+but the capability itself had been active since 4.12. As migration
+support is considered necessary lets disable ais in the 2.10
+stable version. A proper fix and re-enablement will be done
+for qemu 2.11.
+
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20170921140834.14233-2-borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 3f2d07b3b01ea61126b382633ab4006320923048)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/s390x/kvm.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index c4c5791..eb0dbb3 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -308,8 +308,13 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+         }
+     }
+ 
+-    /* Try to enable AIS facility */
+-    kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0);
++    /*
++     * The migration interface for ais was introduced with kernel 4.13
++     * but the capability itself had been active since 4.12. As migration
++     * support is considered necessary let's disable ais in the 2.10
++     * machine.
++     */
++    /* kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0); */
+ 
+     qemu_mutex_init(&qemu_sigp_mutex);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-cpumodel-Disable-unsupported-CPU-models.patch b/SOURCES/kvm-s390x-cpumodel-Disable-unsupported-CPU-models.patch
new file mode 100644
index 0000000..311921c
--- /dev/null
+++ b/SOURCES/kvm-s390x-cpumodel-Disable-unsupported-CPU-models.patch
@@ -0,0 +1,70 @@
+From d5959fcefcda5639e99793f21688ba071bc2886a Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Fri, 10 Nov 2017 14:49:04 +0100
+Subject: [PATCH 7/7] s390x/cpumodel: Disable unsupported CPU models
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171110144904.7026-3-david@redhat.com>
+Patchwork-id: 77648
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH v3 2/2] s390x/cpumodel: Disable unsupported CPU models
+Bugzilla: 1504138
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1504138
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14527097
+Upstream-status: RHEL-only
+
+We will only be supporting CPU models >= HW generation 11 (including
+z196, z12, z13, z14).
+
+As completely removing CPU models is tricky (mainly due to TCG), we
+simply disallow to instantiate them with KVM.
+
+In addition, report via query-cpu-definitions, that these models are
+not runnable under kvm.
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/s390x/cpu_models.c | 3 +++
+ target/s390x/kvm.c        | 8 ++++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
+index e055852..d8f7bed 100644
+--- a/target/s390x/cpu_models.c
++++ b/target/s390x/cpu_models.c
+@@ -360,6 +360,9 @@ static void check_unavailable_features(const S390CPUModel *max_model,
+         (max_model->def->gen == model->def->gen &&
+          max_model->def->ec_ga < model->def->ec_ga)) {
+         list_add_feat("type", unavailable);
++    } else if (model->def->gen < 11 && kvm_enabled()) {
++        /* Older CPU models are not supported on Red Hat Enterprise Linux */
++        list_add_feat("type", unavailable);
+     }
+ 
+     /* detect missing features if any to properly report them */
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index eb0dbb3..3589e6e 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -2712,6 +2712,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
+         error_setg(errp, "KVM doesn't support CPU models");
+         return;
+     }
++
++    /* Older CPU models are not supported on Red Hat Enterprise Linux */
++    if (model->def->gen < 11) {
++        error_setg(errp, "KVM: Unsupported CPU model specified: %s",
++                   MACHINE(qdev_get_machine())->cpu_model);
++        return;
++    }
++
+     prop.cpuid = s390_cpuid_from_cpu_model(model);
+     prop.ibc = s390_ibc_from_cpu_model(model);
+     /* configure cpu features indicated via STFL(e) */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-cpumodel-remove-ais-from-z14-default-model-als.patch b/SOURCES/kvm-s390x-cpumodel-remove-ais-from-z14-default-model-als.patch
new file mode 100644
index 0000000..418435b
--- /dev/null
+++ b/SOURCES/kvm-s390x-cpumodel-remove-ais-from-z14-default-model-als.patch
@@ -0,0 +1,46 @@
+From 7aaf777448ba232fc0dc136e1ed775f86e0e8036 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Thu, 5 Oct 2017 12:04:06 +0200
+Subject: [PATCH 12/34] s390x/cpumodel: remove ais from z14 default model->
+ also for 2.10.1
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20171005120406.16642-3-cohuck@redhat.com>
+Patchwork-id: 76819
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH 2/2] s390x/cpumodel: remove ais from z14 default model-> also for 2.10.1
+Bugzilla: 1494548
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+We disabled ais for 2.10, so let's also remove it from the z14
+default model.
+
+Fixes: 3f2d07b3b01e ("s390x/ais: for 2.10 stable: disable ais facility")
+CC: qemu-stable@nongnu.org
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20170927072030.35737-2-borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 9dacc908462693719d84ec594e839434959cf6f1)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/s390x/gen-features.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
+index c8dc104..68e6c31 100644
+--- a/target/s390x/gen-features.c
++++ b/target/s390x/gen-features.c
+@@ -527,7 +527,6 @@ static uint16_t default_GEN13_GA1[] = {
+ #define default_GEN13_GA2 EmptyFeat
+ 
+ static uint16_t default_GEN14_GA1[] = {
+-    S390_FEAT_ADAPTER_INT_SUPPRESSION,
+     S390_FEAT_INSTRUCTION_EXEC_PROT,
+     S390_FEAT_GUARDED_STORAGE,
+     S390_FEAT_VECTOR_PACKED_DECIMAL,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-css-fix-css-migration-compat-handling.patch b/SOURCES/kvm-s390x-css-fix-css-migration-compat-handling.patch
new file mode 100644
index 0000000..eb200a9
--- /dev/null
+++ b/SOURCES/kvm-s390x-css-fix-css-migration-compat-handling.patch
@@ -0,0 +1,73 @@
+From c08eeabcb588c0cd8f9952e273fa6cdaea71d25c Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 15:50:33 +0200
+Subject: [PATCH 30/34] s390x/css: fix css migration compat handling
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507564234-19627-2-git-send-email-thuth@redhat.com>
+Patchwork-id: 77038
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 1/2] s390x/css: fix css migration compat handling
+Bugzilla: 1473292
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Halil Pasic <pasic@linux.vnet.ibm.com>
+
+Commit e996583eb3 ("s390x/css: activate ChannelSubSys migration",
+2017-07-11) was supposed to enable css migration for virtio-ccw
+machines starting 2.10, but it ended up effectively enabling it
+only for 2.10 as the registration of the appropriate VMStateDescription
+happens in ccw_machine_2_10_instance_options which does not get
+called for machines more recent than 2_10.
+
+Let us move the corresponding chunk of code (which conditionally enables
+the migration based on the value of the corresponding class property) to
+ccw_init, which is called for each virtio-ccw machine instance.
+
+Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reported-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <20171004110109.16525-1-pasic@linux.vnet.ibm.com>
+Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 489c909f097a387eb6913c89cf1851750397110c)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/s390x/s390-virtio-ccw.c
+	(contextual conflict since we do not have commit with id
+	70d8d9a0c9bc599d8ae99dd65ff8535adb2acdfc in downstream yet)
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+---
+ hw/s390x/s390-virtio-ccw.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index 1c7af39..1aec58c 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -156,6 +156,9 @@ static void ccw_init(MachineState *machine)
+         ret = css_create_css_image(VIRTUAL_CSSID, true);
+     }
+     assert(ret == 0);
++    if (css_migration_enabled()) {
++        css_register_vmstate();
++    }
+ 
+     /* Create VirtIO network adapters */
+     s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
+@@ -508,9 +511,6 @@ bool css_migration_enabled(void)
+ 
+ static void ccw_machine_2_10_instance_options(MachineState *machine)
+ {
+-    if (css_migration_enabled()) {
+-        css_register_vmstate();
+-    }
+ }
+ 
+ static void ccw_machine_2_10_class_options(MachineClass *mc)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-ipl-The-s390-ipl-device-is-not-hot-pluggable.patch b/SOURCES/kvm-s390x-ipl-The-s390-ipl-device-is-not-hot-pluggable.patch
new file mode 100644
index 0000000..697bf47
--- /dev/null
+++ b/SOURCES/kvm-s390x-ipl-The-s390-ipl-device-is-not-hot-pluggable.patch
@@ -0,0 +1,45 @@
+From 456a0426e0db531e9545042fb20ecdb1d470f8ea Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:44 +0200
+Subject: [PATCH 25/34] s390x/ipl: The s390-ipl device is not hot-pluggable
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-9-git-send-email-thuth@redhat.com>
+Patchwork-id: 77025
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 08/12] s390x/ipl: The s390-ipl device is not hot-pluggable
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The s390-ipl device can not be created by the user, since it is meant only
+to  be instantiated once internally to load the ROMs and kernel. If the user
+tries to do a "device_add s390-ipl" via the monitor later, QEMU aborts with
+a "ROM images must be loaded at startup" error message.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1502861458-30270-1-git-send-email-thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 0d4fa4996fc5ee56ea7d072e272b8e69948460a5)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/ipl.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
+index cc36003..0d06fc1 100644
+--- a/hw/s390x/ipl.c
++++ b/hw/s390x/ipl.c
+@@ -442,6 +442,8 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data)
+     dc->reset = s390_ipl_reset;
+     dc->vmsd = &vmstate_ipl;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
++    /* Reason: Loads the ROMs and thus can only be used one time - internally */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo s390_ipl_info = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-kvm-Handle-bpb-feature.patch b/SOURCES/kvm-s390x-kvm-Handle-bpb-feature.patch
new file mode 100644
index 0000000..0f2bd5a
--- /dev/null
+++ b/SOURCES/kvm-s390x-kvm-Handle-bpb-feature.patch
@@ -0,0 +1,178 @@
+From 89628ec85c86fee920a518330759891dd0c01921 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 23 Jan 2018 19:12:45 +0100
+Subject: [PATCH 3/8] s390x/kvm: Handle bpb feature
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1516734766-12075-3-git-send-email-thuth@redhat.com>
+Patchwork-id: 78701
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 2/3] s390x/kvm: Handle bpb feature
+Bugzilla: 1535606
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+We need to handle the bpb control on reset and migration. Normally
+stfle.82 is transparent (and the normal guest part works without
+hypervisor activity). To prevent any issues we require full
+host kernel support for this feature.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20180118085628.40798-3-borntraeger@de.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+[CH: 'Branch Prediction Blocking' -> 'Branch prediction blocking']
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit b073c87517d4d348c7bac0f0b35e8e83e6354d82)
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/s390x/cpu.c              |  1 +
+ target/s390x/cpu.h              |  1 +
+ target/s390x/cpu_features.c     |  1 +
+ target/s390x/cpu_features_def.h |  1 +
+ target/s390x/gen-features.c     |  1 +
+ target/s390x/kvm.c              | 14 ++++++++++++++
+ target/s390x/machine.c          | 17 +++++++++++++++++
+ 7 files changed, 36 insertions(+)
+
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index 489bc25..8bd463c 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -78,6 +78,7 @@ static void s390_cpu_reset(CPUState *s)
+     CPUS390XState *env = &cpu->env;
+ 
+     env->pfault_token = -1UL;
++    env->bpbc = false;
+     scc->parent_reset(s);
+     cpu->env.sigp_order = 0;
+     s390_cpu_set_state(CPU_STATE_STOPPED, cpu);
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 29fdd5d..ce1f933 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -96,6 +96,7 @@ typedef struct CPUS390XState {
+ 
+     uint32_t fpc;          /* floating-point control register */
+     uint32_t cc_op;
++    bool bpbc;             /* branch prediction blocking */
+ 
+     float_status fpu_status; /* passed to softfloat lib */
+ 
+diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
+index 1d3a036..d39efb0 100644
+--- a/target/s390x/cpu_features.c
++++ b/target/s390x/cpu_features.c
+@@ -89,6 +89,7 @@ static const S390FeatDef s390_features[] = {
+     FEAT_INIT("msa4-base", S390_FEAT_TYPE_STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)"),
+     FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
+     FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
++    FEAT_INIT("bpb", S390_FEAT_TYPE_STFL, 82, "Branch prediction blocking"),
+     FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
+     FEAT_INIT("iep", S390_FEAT_TYPE_STFL, 130, "Instruction-execution-protection facility"),
+     FEAT_INIT("sea_esop2", S390_FEAT_TYPE_STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2"),
+diff --git a/target/s390x/cpu_features_def.h b/target/s390x/cpu_features_def.h
+index 4b6d4e9..4487cfd 100644
+--- a/target/s390x/cpu_features_def.h
++++ b/target/s390x/cpu_features_def.h
+@@ -80,6 +80,7 @@ typedef enum {
+     S390_FEAT_MSA_EXT_4,
+     S390_FEAT_EDAT_2,
+     S390_FEAT_DFP_PACKED_CONVERSION,
++    S390_FEAT_BPB,
+     S390_FEAT_VECTOR,
+     S390_FEAT_INSTRUCTION_EXEC_PROT,
+     S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
+diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
+index 68e6c31..13a6291 100644
+--- a/target/s390x/gen-features.c
++++ b/target/s390x/gen-features.c
+@@ -352,6 +352,7 @@ static uint16_t base_GEN14_GA1[] = {
+  * support these features yet.
+  */
+ static uint16_t full_GEN7_GA1[] = {
++    S390_FEAT_BPB,
+     S390_FEAT_SIE_F2,
+     S390_FEAT_SIE_SKEY,
+     S390_FEAT_SIE_GPERE,
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 3589e6e..871f441 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -488,6 +488,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
+         cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GSCB;
+     }
+ 
++    if (can_sync_regs(cs, KVM_SYNC_BPBC)) {
++        cs->kvm_run->s.regs.bpbc = env->bpbc;
++        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_BPBC;
++    }
++
+     /* Finally the prefix */
+     if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
+         cs->kvm_run->s.regs.prefix = env->psa;
+@@ -598,6 +603,10 @@ int kvm_arch_get_registers(CPUState *cs)
+         memcpy(env->gscb, cs->kvm_run->s.regs.gscb, 32);
+     }
+ 
++    if (can_sync_regs(cs, KVM_SYNC_BPBC)) {
++        env->bpbc = cs->kvm_run->s.regs.bpbc;
++    }
++
+     /* pfault parameters */
+     if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
+         env->pfault_token = cs->kvm_run->s.regs.pft;
+@@ -2666,6 +2675,11 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
+         clear_bit(S390_FEAT_CMM_NT, model->features);
+     }
+ 
++    /* bpb needs kernel support for migration, VSIE and reset */
++    if (!kvm_check_extension(kvm_state, KVM_CAP_S390_BPB)) {
++        clear_bit(S390_FEAT_BPB, model->features);
++    }
++
+     /* We emulate a zPCI bus and AEN, therefore we don't need HW support */
+     set_bit(S390_FEAT_ZPCI, model->features);
+     set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features);
+diff --git a/target/s390x/machine.c b/target/s390x/machine.c
+index 2dcadfd..f24088b 100644
+--- a/target/s390x/machine.c
++++ b/target/s390x/machine.c
+@@ -190,6 +190,22 @@ const VMStateDescription vmstate_gscb = {
+         }
+ };
+ 
++static bool bpbc_needed(void *opaque)
++{
++    return s390_has_feat(S390_FEAT_BPB);
++}
++
++const VMStateDescription vmstate_bpbc = {
++    .name = "cpu/bpbc",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .needed = bpbc_needed,
++    .fields = (VMStateField[]) {
++        VMSTATE_BOOL(env.bpbc, S390CPU),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
+ const VMStateDescription vmstate_s390_cpu = {
+     .name = "cpu",
+     .post_load = cpu_post_load,
+@@ -224,6 +240,7 @@ const VMStateDescription vmstate_s390_cpu = {
+         &vmstate_riccb,
+         &vmstate_exval,
+         &vmstate_gscb,
++        &vmstate_bpbc,
+         NULL
+     },
+ };
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-kvm-provide-stfle.81.patch b/SOURCES/kvm-s390x-kvm-provide-stfle.81.patch
new file mode 100644
index 0000000..96ccef4
--- /dev/null
+++ b/SOURCES/kvm-s390x-kvm-provide-stfle.81.patch
@@ -0,0 +1,74 @@
+From 775d414bd144e3562456e2caa5b246f5ef41a5fd Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 23 Jan 2018 19:12:46 +0100
+Subject: [PATCH 4/8] s390x/kvm: provide stfle.81
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1516734766-12075-4-git-send-email-thuth@redhat.com>
+Patchwork-id: 78702
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 3/3] s390x/kvm: provide stfle.81
+Bugzilla: 1535606
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+stfle.81 (ppa15) is a transparent facility that can be passed to the
+guest without the need to implement hypervisor support. As this feature
+can be provided by firmware we add it to all full models.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20180118085628.40798-4-borntraeger@de.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 9f0d13f4f1de3cf9b70435cc4e87a301ee12471f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/s390x/cpu_features.c     | 1 +
+ target/s390x/cpu_features_def.h | 1 +
+ target/s390x/gen-features.c     | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
+index d39efb0..5ecb2bc 100644
+--- a/target/s390x/cpu_features.c
++++ b/target/s390x/cpu_features.c
+@@ -89,6 +89,7 @@ static const S390FeatDef s390_features[] = {
+     FEAT_INIT("msa4-base", S390_FEAT_TYPE_STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)"),
+     FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
+     FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
++    FEAT_INIT("ppa15", S390_FEAT_TYPE_STFL, 81, "PPA15 is installed"),
+     FEAT_INIT("bpb", S390_FEAT_TYPE_STFL, 82, "Branch prediction blocking"),
+     FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
+     FEAT_INIT("iep", S390_FEAT_TYPE_STFL, 130, "Instruction-execution-protection facility"),
+diff --git a/target/s390x/cpu_features_def.h b/target/s390x/cpu_features_def.h
+index 4487cfd..4d93087 100644
+--- a/target/s390x/cpu_features_def.h
++++ b/target/s390x/cpu_features_def.h
+@@ -80,6 +80,7 @@ typedef enum {
+     S390_FEAT_MSA_EXT_4,
+     S390_FEAT_EDAT_2,
+     S390_FEAT_DFP_PACKED_CONVERSION,
++    S390_FEAT_PPA15,
+     S390_FEAT_BPB,
+     S390_FEAT_VECTOR,
+     S390_FEAT_INSTRUCTION_EXEC_PROT,
+diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
+index 13a6291..e6b4152 100644
+--- a/target/s390x/gen-features.c
++++ b/target/s390x/gen-features.c
+@@ -352,6 +352,7 @@ static uint16_t base_GEN14_GA1[] = {
+  * support these features yet.
+  */
+ static uint16_t full_GEN7_GA1[] = {
++    S390_FEAT_PPA15,
+     S390_FEAT_BPB,
+     S390_FEAT_SIE_F2,
+     S390_FEAT_SIE_SKEY,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-print-CPU-definitions-in-sorted-order.patch b/SOURCES/kvm-s390x-print-CPU-definitions-in-sorted-order.patch
new file mode 100644
index 0000000..281f64c
--- /dev/null
+++ b/SOURCES/kvm-s390x-print-CPU-definitions-in-sorted-order.patch
@@ -0,0 +1,121 @@
+From a009d0254cdfd6deb532ef654a3f2811cb8b9c15 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Fri, 10 Nov 2017 14:49:03 +0100
+Subject: [PATCH 6/7] s390x: print CPU definitions in sorted order
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171110144904.7026-2-david@redhat.com>
+Patchwork-id: 77647
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH v3 1/2] s390x: print CPU definitions in sorted order
+Bugzilla: 1504138
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1504138
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14527097
+Upstream-status: 99aa6bf29b87052d9603c5bf5c23d0db960f30ce
+
+Other architectures provide nicely sorted lists, let's do it similarly on
+s390x.
+
+While at it, clean up the code we have to touch either way.
+
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20170913132417.24384-16-david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 99aa6bf29b87052d9603c5bf5c23d0db960f30ce)
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/s390x/cpu_models.c | 56 ++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 41 insertions(+), 15 deletions(-)
+
+diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
+index fa1338f..e055852 100644
+--- a/target/s390x/cpu_models.c
++++ b/target/s390x/cpu_models.c
+@@ -267,16 +267,11 @@ const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
+     return last_compatible;
+ }
+ 
+-struct S390PrintCpuListInfo {
+-    FILE *f;
+-    fprintf_function print;
+-};
+-
+-static void print_cpu_model_list(ObjectClass *klass, void *opaque)
++static void s390_print_cpu_model_list_entry(gpointer data, gpointer user_data)
+ {
+-    struct S390PrintCpuListInfo *info = opaque;
+-    S390CPUClass *scc = S390_CPU_CLASS(klass);
+-    char *name = g_strdup(object_class_get_name(klass));
++    CPUListState *s = user_data;
++    const S390CPUClass *scc = S390_CPU_CLASS((ObjectClass *)data);
++    char *name = g_strdup(object_class_get_name((ObjectClass *)data));
+     const char *details = "";
+ 
+     if (scc->is_static) {
+@@ -287,21 +282,52 @@ static void print_cpu_model_list(ObjectClass *klass, void *opaque)
+ 
+     /* strip off the -s390-cpu */
+     g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
+-    (*info->print)(info->f, "s390 %-15s %-35s %s\n", name, scc->desc,
+-                   details);
++    (*s->cpu_fprintf)(s->file, "s390 %-15s %-35s %s\n", name, scc->desc,
++                      details);
+     g_free(name);
+ }
+ 
++static gint s390_cpu_list_compare(gconstpointer a, gconstpointer b)
++{
++    const S390CPUClass *cc_a = S390_CPU_CLASS((ObjectClass *)a);
++    const S390CPUClass *cc_b = S390_CPU_CLASS((ObjectClass *)b);
++    const char *name_a = object_class_get_name((ObjectClass *)a);
++    const char *name_b = object_class_get_name((ObjectClass *)b);
++
++    /* move qemu and host to the top of the list, qemu first, host second */
++    if (name_a[0] == 'q') {
++        return -1;
++    } else if (name_b[0] == 'q') {
++        return 1;
++    } else if (name_a[0] == 'h') {
++        return -1;
++    } else if (name_b[0] == 'h') {
++        return 1;
++    }
++
++    /* keep the same order we have in our table (sorted by release date) */
++    if (cc_a->cpu_def != cc_b->cpu_def) {
++        return cc_a->cpu_def - cc_b->cpu_def;
++    }
++
++    /* exact same definition - list base model first */
++    return cc_a->is_static ? -1 : 1;
++}
++
+ void s390_cpu_list(FILE *f, fprintf_function print)
+ {
+-    struct S390PrintCpuListInfo info = {
+-        .f = f,
+-        .print = print,
++    CPUListState s = {
++        .file = f,
++        .cpu_fprintf = print,
+     };
+     S390FeatGroup group;
+     S390Feat feat;
++    GSList *list;
+ 
+-    object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info);
++    list = object_class_get_list(TYPE_S390_CPU, false);
++    list = g_slist_sort(list, s390_cpu_list_compare);
++    g_slist_foreach(list, s390_print_cpu_model_list_entry, &s);
++    g_slist_free(list);
+ 
+     (*print)(f, "\nRecognized feature flags:\n");
+     for (feat = 0; feat < S390_FEAT_MAX; feat++) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-s390-skeys-Mark-the-storage-key-devices-with-u.patch b/SOURCES/kvm-s390x-s390-skeys-Mark-the-storage-key-devices-with-u.patch
new file mode 100644
index 0000000..068318d
--- /dev/null
+++ b/SOURCES/kvm-s390x-s390-skeys-Mark-the-storage-key-devices-with-u.patch
@@ -0,0 +1,79 @@
+From b830658def8c36d5449e0b704e2f0cb26a593c1e Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:42 +0200
+Subject: [PATCH 23/34] s390x/s390-skeys: Mark the storage key devices with
+ user_creatable = false
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-7-git-send-email-thuth@redhat.com>
+Patchwork-id: 77024
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 06/12] s390x/s390-skeys: Mark the storage key devices with user_creatable = false
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+QEMU currently aborts if the user tries to create a skey device:
+
+$ s390x-softmmu/qemu-system-s390x -nographic -device s390-skeys-qemu
+qemu-system-s390x: hw/s390x/s390-skeys.c:30: s390_get_skeys_device:
+ Assertion `ss' failed.
+Aborted (core dumped)
+
+The storage key devices are only meant to be instantiated one time,
+internally. They can not be used by the user, so mark them with
+user_creatable = false.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1503569328-22197-1-git-send-email-thuth@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 574ee06de9c4fe63c90be90dc9c747fc9382bb2b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/s390-skeys-kvm.c | 4 ++++
+ hw/s390x/s390-skeys.c     | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/hw/s390x/s390-skeys-kvm.c b/hw/s390x/s390-skeys-kvm.c
+index 131da56..dc54ed8 100644
+--- a/hw/s390x/s390-skeys-kvm.c
++++ b/hw/s390x/s390-skeys-kvm.c
+@@ -54,10 +54,14 @@ static int kvm_s390_skeys_set(S390SKeysState *ss, uint64_t start_gfn,
+ static void kvm_s390_skeys_class_init(ObjectClass *oc, void *data)
+ {
+     S390SKeysClass *skeyclass = S390_SKEYS_CLASS(oc);
++    DeviceClass *dc = DEVICE_CLASS(oc);
+ 
+     skeyclass->skeys_enabled = kvm_s390_skeys_enabled;
+     skeyclass->get_skeys = kvm_s390_skeys_get;
+     skeyclass->set_skeys = kvm_s390_skeys_set;
++
++    /* Reason: Internal device (only one skeys device for the whole memory) */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo kvm_s390_skeys_info = {
+diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
+index c0de3b0..53ad5d3 100644
+--- a/hw/s390x/s390-skeys.c
++++ b/hw/s390x/s390-skeys.c
+@@ -229,10 +229,14 @@ static int qemu_s390_skeys_get(S390SKeysState *ss, uint64_t start_gfn,
+ static void qemu_s390_skeys_class_init(ObjectClass *oc, void *data)
+ {
+     S390SKeysClass *skeyclass = S390_SKEYS_CLASS(oc);
++    DeviceClass *dc = DEVICE_CLASS(oc);
+ 
+     skeyclass->skeys_enabled = qemu_s390_skeys_enabled;
+     skeyclass->get_skeys = qemu_s390_skeys_get;
+     skeyclass->set_skeys = qemu_s390_skeys_set;
++
++    /* Reason: Internal device (only one skeys device for the whole memory) */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo qemu_s390_skeys_info = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-s390-stattrib-Mark-the-storage-attribute-as-no.patch b/SOURCES/kvm-s390x-s390-stattrib-Mark-the-storage-attribute-as-no.patch
new file mode 100644
index 0000000..07a7598
--- /dev/null
+++ b/SOURCES/kvm-s390x-s390-stattrib-Mark-the-storage-attribute-as-no.patch
@@ -0,0 +1,79 @@
+From 69504b264f7272d31814d928ffbd9d01661ec62a Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:41 +0200
+Subject: [PATCH 22/34] s390x/s390-stattrib: Mark the storage attribute as not
+ user_creatable
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-6-git-send-email-thuth@redhat.com>
+Patchwork-id: 77022
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 05/12] s390x/s390-stattrib: Mark the storage attribute as not user_creatable
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The storage attribute devices are only meant to be instantiated one
+time, internally. They can not be used by the user, so mark them with
+user_creatable = false.
+
+Suggested-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1503576029-24264-1-git-send-email-thuth@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 3ea6d20e0baacb4a1211ed0ea57db14e2fc927ce)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/s390-stattrib-kvm.c | 4 ++++
+ hw/s390x/s390-stattrib.c     | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c
+index ff3f89f..bc0274d 100644
+--- a/hw/s390x/s390-stattrib-kvm.c
++++ b/hw/s390x/s390-stattrib-kvm.c
+@@ -163,6 +163,7 @@ static int kvm_s390_stattrib_get_active(S390StAttribState *sa)
+ static void kvm_s390_stattrib_class_init(ObjectClass *oc, void *data)
+ {
+     S390StAttribClass *sac = S390_STATTRIB_CLASS(oc);
++    DeviceClass *dc = DEVICE_CLASS(oc);
+ 
+     sac->get_stattr = kvm_s390_stattrib_get_stattr;
+     sac->peek_stattr = kvm_s390_stattrib_peek_stattr;
+@@ -171,6 +172,9 @@ static void kvm_s390_stattrib_class_init(ObjectClass *oc, void *data)
+     sac->get_dirtycount = kvm_s390_stattrib_get_dirtycount;
+     sac->synchronize = kvm_s390_stattrib_synchronize;
+     sac->get_active = kvm_s390_stattrib_get_active;
++
++    /* Reason: Can only be instantiated one time (internally) */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo kvm_s390_stattrib_info = {
+diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c
+index d14923f..f75548e 100644
+--- a/hw/s390x/s390-stattrib.c
++++ b/hw/s390x/s390-stattrib.c
+@@ -306,6 +306,7 @@ static int qemu_s390_get_active(S390StAttribState *sa)
+ static void qemu_s390_stattrib_class_init(ObjectClass *oc, void *data)
+ {
+     S390StAttribClass *sa_cl = S390_STATTRIB_CLASS(oc);
++    DeviceClass *dc = DEVICE_CLASS(oc);
+ 
+     sa_cl->synchronize = qemu_s390_synchronize_stub;
+     sa_cl->get_stattr = qemu_s390_get_stattr_stub;
+@@ -314,6 +315,9 @@ static void qemu_s390_stattrib_class_init(ObjectClass *oc, void *data)
+     sa_cl->set_migrationmode = qemu_s390_set_migrationmode_stub;
+     sa_cl->get_dirtycount = qemu_s390_get_dirtycount_stub;
+     sa_cl->get_active = qemu_s390_get_active;
++
++    /* Reason: Can only be instantiated one time (internally) */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo qemu_s390_stattrib_info = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-sclp-Mark-the-sclp-device-with-user_creatable-.patch b/SOURCES/kvm-s390x-sclp-Mark-the-sclp-device-with-user_creatable-.patch
new file mode 100644
index 0000000..b12727f
--- /dev/null
+++ b/SOURCES/kvm-s390x-sclp-Mark-the-sclp-device-with-user_creatable-.patch
@@ -0,0 +1,58 @@
+From 26c80458360dfd14a97a7f5823ad578ebcdffd87 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:47 +0200
+Subject: [PATCH 28/34] s390x/sclp: Mark the sclp device with user_creatable =
+ false
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-12-git-send-email-thuth@redhat.com>
+Patchwork-id: 77029
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 11/12] s390x/sclp: Mark the sclp device with user_creatable = false
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The "sclp" device is just an internal device that can not be instantiated
+by the users. If they try to use it, they only get a simple error message:
+
+$ qemu-system-s390x -nographic -device sclp
+qemu-system-s390x: Option '-device s390-sclp-event-facility' cannot be
+handled by this machine
+
+Since sclp_init() tries to create a TYPE_SCLP_EVENT_FACILITY which is
+a non-pluggable sysbus device, there is really no way that the "sclp"
+device can be used by the user, so let's set the user_creatable = false
+accordingly.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1507125199-22562-1-git-send-email-thuth@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Reviewed-by: Farhan Ali <alifm@linux.vnet.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit e6cb60bf158fe7ea4505d760fdbb7abe4dbf4362)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/sclp.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
+index 9253dbb..b94ce0c 100644
+--- a/hw/s390x/sclp.c
++++ b/hw/s390x/sclp.c
+@@ -584,6 +584,11 @@ static void sclp_class_init(ObjectClass *oc, void *data)
+     dc->realize = sclp_realize;
+     dc->hotpluggable = false;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
++    /*
++     * Reason: Creates TYPE_SCLP_EVENT_FACILITY in sclp_init
++     * which is a non-pluggable sysbus device
++     */
++    dc->user_creatable = false;
+ 
+     sc->read_SCP_info = read_SCP_info;
+     sc->read_storage_element0_info = read_storage_element0_info;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-sclp-mark-sclp-cpu-hotplug-as-non-usercreatabl.patch b/SOURCES/kvm-s390x-sclp-mark-sclp-cpu-hotplug-as-non-usercreatabl.patch
new file mode 100644
index 0000000..2710dda
--- /dev/null
+++ b/SOURCES/kvm-s390x-sclp-mark-sclp-cpu-hotplug-as-non-usercreatabl.patch
@@ -0,0 +1,53 @@
+From 3ad6366bd5d0bea256b37b0e8cdef6ff5ac2e4e2 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:46 +0200
+Subject: [PATCH 27/34] s390x/sclp: mark sclp-cpu-hotplug as non-usercreatable
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-11-git-send-email-thuth@redhat.com>
+Patchwork-id: 77028
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 10/12] s390x/sclp: mark sclp-cpu-hotplug as non-usercreatable
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Cornelia Huck <cohuck@redhat.com>
+
+A TYPE_SCLP_CPU_HOTPLUG device for handling cpu hotplug events
+is already created by the sclp event facility. Adding a second
+TYPE_SCLP_CPU_HOTPLUG device via -device sclp-cpu-hotplug creates
+an ambiguity in raise_irq_cpu_hotplug(), leading to a crash once
+a cpu is hotplugged.
+
+To fix this, disallow creating a sclp-cpu-hotplug device manually.
+
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 7aa4d85d2962a072931657bee964113727ebf0c8)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/s390x/sclpcpu.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/s390x/sclpcpu.c b/hw/s390x/sclpcpu.c
+index b1f3ef8..fa17cc5 100644
+--- a/hw/s390x/sclpcpu.c
++++ b/hw/s390x/sclpcpu.c
+@@ -83,6 +83,12 @@ static void cpu_class_init(ObjectClass *oc, void *data)
+     k->get_receive_mask = receive_mask;
+     k->read_event_data = read_event_data;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
++    /*
++     * Reason: raise_irq_cpu_hotplug() depends on an unique
++     * TYPE_SCLP_CPU_HOTPLUG device, which is already created
++     * by the sclp event facility
++     */
++    dc->user_creatable = false;
+ }
+ 
+ static const TypeInfo sclp_cpu_info = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x.conf b/SOURCES/kvm-s390x.conf
new file mode 100644
index 0000000..949f6d1
--- /dev/null
+++ b/SOURCES/kvm-s390x.conf
@@ -0,0 +1,7 @@
+# Setting "modprobe kvm nested=1" only enables Nested Virtualization until
+# the next reboot or module reload. Uncomment the option below to enable
+# the feature permanently.
+#
+# User changes in this file are preserved across upgrades.
+#
+#options kvm nested=1
diff --git a/SOURCES/kvm-scripts-dump-guest-memory.py-add-vmcoreinfo.patch b/SOURCES/kvm-scripts-dump-guest-memory.py-add-vmcoreinfo.patch
new file mode 100644
index 0000000..fe58e14
--- /dev/null
+++ b/SOURCES/kvm-scripts-dump-guest-memory.py-add-vmcoreinfo.patch
@@ -0,0 +1,134 @@
+From 7d60c93dbdf3568c9b96cf6bc61af49966e1a06f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:09 +0100
+Subject: [PATCH 11/21] scripts/dump-guest-memory.py: add vmcoreinfo
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-8-marcandre.lureau@redhat.com>
+Patchwork-id: 77929
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 7/9] scripts/dump-guest-memory.py: add vmcoreinfo
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Add a vmcoreinfo ELF note in the dump if vmcoreinfo device has the
+memory location details.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit d23bfa91b7789534d16ede6cb7d925bfac3f3c4c)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/dump-guest-memory.py | 61 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+
+diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
+index f7c6635..69dd5ef 100644
+--- a/scripts/dump-guest-memory.py
++++ b/scripts/dump-guest-memory.py
+@@ -14,6 +14,7 @@ the COPYING file in the top-level directory.
+ """
+ 
+ import ctypes
++import struct
+ 
+ UINTPTR_T = gdb.lookup_type("uintptr_t")
+ 
+@@ -45,6 +46,17 @@ EM_S390 = 22
+ EM_AARCH = 183
+ EM_X86_64 = 62
+ 
++VMCOREINFO_FORMAT_ELF = 1
++
++def le16_to_cpu(val):
++    return struct.unpack("<H", struct.pack("=H", val))[0]
++
++def le32_to_cpu(val):
++    return struct.unpack("<I", struct.pack("=I", val))[0]
++
++def le64_to_cpu(val):
++    return struct.unpack("<Q", struct.pack("=Q", val))[0]
++
+ class ELF(object):
+     """Representation of a ELF file."""
+ 
+@@ -120,6 +132,25 @@ class ELF(object):
+         self.segments[0].p_filesz += ctypes.sizeof(note)
+         self.segments[0].p_memsz += ctypes.sizeof(note)
+ 
++
++    def add_vmcoreinfo_note(self, vmcoreinfo):
++        """Adds a vmcoreinfo note to the ELF dump."""
++        # compute the header size, and copy that many bytes from the note
++        header = get_arch_note(self.endianness, 0, 0)
++        ctypes.memmove(ctypes.pointer(header),
++                       vmcoreinfo, ctypes.sizeof(header))
++        if header.n_descsz > 1 << 20:
++            print('warning: invalid vmcoreinfo size')
++            return
++        # now get the full note
++        note = get_arch_note(self.endianness,
++                             header.n_namesz - 1, header.n_descsz)
++        ctypes.memmove(ctypes.pointer(note), vmcoreinfo, ctypes.sizeof(note))
++
++        self.notes.append(note)
++        self.segments[0].p_filesz += ctypes.sizeof(note)
++        self.segments[0].p_memsz += ctypes.sizeof(note)
++
+     def add_segment(self, p_type, p_paddr, p_size):
+         """Adds a segment to the elf."""
+ 
+@@ -505,6 +536,35 @@ shape and this command should mostly work."""
+                 cur += chunk_size
+                 left -= chunk_size
+ 
++    def phys_memory_read(self, addr, size):
++        qemu_core = gdb.inferiors()[0]
++        for block in self.guest_phys_blocks:
++            if block["target_start"] <= addr \
++               and addr + size <= block["target_end"]:
++                haddr = block["host_addr"] + (addr - block["target_start"])
++                return qemu_core.read_memory(haddr, size)
++        return None
++
++    def add_vmcoreinfo(self):
++        if not gdb.parse_and_eval("vmcoreinfo_find()") \
++           or not gdb.parse_and_eval("vmcoreinfo_find()->has_vmcoreinfo"):
++            return
++
++        fmt = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.guest_format")
++        addr = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.paddr")
++        size = gdb.parse_and_eval("vmcoreinfo_find()->vmcoreinfo.size")
++
++        fmt = le16_to_cpu(fmt)
++        addr = le64_to_cpu(addr)
++        size = le32_to_cpu(size)
++
++        if fmt != VMCOREINFO_FORMAT_ELF:
++            return
++
++        vmcoreinfo = self.phys_memory_read(addr, size)
++        if vmcoreinfo:
++            self.elf.add_vmcoreinfo_note(vmcoreinfo.tobytes())
++
+     def invoke(self, args, from_tty):
+         """Handles command invocation from gdb."""
+ 
+@@ -518,6 +578,7 @@ shape and this command should mostly work."""
+ 
+         self.elf = ELF(argv[1])
+         self.guest_phys_blocks = get_guest_phys_blocks()
++        self.add_vmcoreinfo()
+ 
+         with open(argv[0], "wb") as vmcore:
+             self.dump_init(vmcore)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-Fix-onboard-HBAs-to-pick-up-drive-if-scsi.patch b/SOURCES/kvm-scsi-Fix-onboard-HBAs-to-pick-up-drive-if-scsi.patch
new file mode 100644
index 0000000..7615297
--- /dev/null
+++ b/SOURCES/kvm-scsi-Fix-onboard-HBAs-to-pick-up-drive-if-scsi.patch
@@ -0,0 +1,73 @@
+From 8198d8d36fed85743c4d2b26aa1670f5bc3a9793 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Tue, 28 Nov 2017 13:24:17 +0100
+Subject: [PATCH 16/21] scsi: Fix onboard HBAs to pick up -drive if=scsi
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <20171128132417.18247-2-armbru@redhat.com>
+Patchwork-id: 77934
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 1/1] scsi: Fix onboard HBAs to pick up -drive if=scsi
+Bugzilla: 1497740
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+Downstream commit 7977e6031 "scsi: Disable deprecated implicit SCSI
+HBA creation more cleanly" regressed -drive if=scsi and its sugared
+forms like -cdrom with onboard HBAs.  Instead of creating SCSI devices
+connected to the onboard HBA, we reject these options like this:
+
+    $ qemu-kvm -cdrom r7.iso
+    qemu-kvm: -cdrom r7.iso: machine type does not support if=scsi,bus=0,unit=2
+
+The culprit is scsi_bus_legacy_handle_cmdline(): commit 7977e6031
+accidentally neutered it for the non-deprecated case (onboard SCSI
+HBA) in addition to the deprecated case (non-onboard SCSI HBA with
+legacy magic).  Fix by narrowing the neutering to the deprecated case.
+
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-bus.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 309daaa..404686a 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -265,8 +265,6 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
+ 
+ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
+ {
+-#if 0 /* Disabled for Red Hat Enterprise Linux */
+-
+     Location loc;
+     DriveInfo *dinfo;
+     int unit;
+@@ -279,6 +277,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
+         }
+         qemu_opts_loc_restore(dinfo->opts);
+         if (deprecated) {
++#if 0 /* Disabled for Red Hat Enterprise Linux */
+             /* Handling -drive not claimed by machine initialization */
+             if (blk_get_attached_dev(blk_by_legacy_dinfo(dinfo))) {
+                 continue;       /* claimed */
+@@ -288,12 +287,14 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
+                             " machine type",
+                             bus->busnr, unit);
+             }
++#else
++            continue;
++#endif
+         }
+         scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo),
+                                   unit, false, -1, NULL, &error_fatal);
+     }
+     loc_pop(&loc);
+-#endif
+ }
+ 
+ #if 0 /* Disabled for Red Hat Enterprise Linux */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-Improve-scsi_sense_to_errno.patch b/SOURCES/kvm-scsi-Improve-scsi_sense_to_errno.patch
new file mode 100644
index 0000000..30d1be7
--- /dev/null
+++ b/SOURCES/kvm-scsi-Improve-scsi_sense_to_errno.patch
@@ -0,0 +1,74 @@
+From bc3855000036c3abe2a440d3cb65a9fbd90745fb Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:41 +0100
+Subject: [PATCH 15/36] scsi: Improve scsi_sense_to_errno
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-6-pbonzini@redhat.com>
+Patchwork-id: 78077
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 05/17] scsi: Improve scsi_sense_to_errno
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Fam Zheng <famz@redhat.com>
+
+Tweak the errno mapping to return more accurate/appropriate values.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-Id: <20170821141008.19383-3-famz@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 5efa3c04483d408a03ff5f018842501a2048a51b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/scsi.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/util/scsi.c b/util/scsi.c
+index a671079..472eb5b 100644
+--- a/util/scsi.c
++++ b/util/scsi.c
+@@ -18,13 +18,16 @@
+ int scsi_sense_to_errno(int key, int asc, int ascq)
+ {
+     switch (key) {
+-    case 0x02: /* NOT READY */
+-        return EBUSY;
+-    case 0x07: /* DATA PROTECTION */
+-        return EACCES;
++    case 0x00: /* NO SENSE */
++    case 0x01: /* RECOVERED ERROR */
++    case 0x06: /* UNIT ATTENTION */
++        /* These sense keys are not errors */
++        return 0;
+     case 0x0b: /* COMMAND ABORTED */
+         return ECANCELED;
++    case 0x02: /* NOT READY */
+     case 0x05: /* ILLEGAL REQUEST */
++    case 0x07: /* DATA PROTECTION */
+         /* Parse ASCQ */
+         break;
+     default:
+@@ -37,6 +40,7 @@ int scsi_sense_to_errno(int key, int asc, int ascq)
+     case 0x2600: /* INVALID FIELD IN PARAMETER LIST */
+         return EINVAL;
+     case 0x2100: /* LBA OUT OF RANGE */
++    case 0x2707: /* SPACE ALLOC FAILED */
+         return ENOSPC;
+     case 0x2500: /* LOGICAL UNIT NOT SUPPORTED */
+         return ENOTSUP;
+@@ -46,6 +50,10 @@ int scsi_sense_to_errno(int key, int asc, int ascq)
+         return ENOMEDIUM;
+     case 0x2700: /* WRITE PROTECTED */
+         return EACCES;
++    case 0x0401: /* NOT READY, IN PROGRESS OF BECOMING READY */
++        return EAGAIN;
++    case 0x0402: /* NOT READY, INITIALIZING COMMAND REQUIRED */
++        return ENOTCONN;
+     default:
+         return EIO;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-Introduce-scsi_sense_buf_to_errno.patch b/SOURCES/kvm-scsi-Introduce-scsi_sense_buf_to_errno.patch
new file mode 100644
index 0000000..17986f2
--- /dev/null
+++ b/SOURCES/kvm-scsi-Introduce-scsi_sense_buf_to_errno.patch
@@ -0,0 +1,81 @@
+From f635140407bf6d024045ad18e7a1f8f802690b36 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:42 +0100
+Subject: [PATCH 16/36] scsi: Introduce scsi_sense_buf_to_errno
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-7-pbonzini@redhat.com>
+Patchwork-id: 78082
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 06/17] scsi: Introduce scsi_sense_buf_to_errno
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Fam Zheng <famz@redhat.com>
+
+This recognizes the "fixed" and "descriptor" format sense data, extracts
+the sense key/asc/ascq fields then converts them to an errno.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-Id: <20170821141008.19383-4-famz@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit a485b23425c755867d6caa6ab590be4e0473e35a)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/scsi/scsi.h |  1 +
+ util/scsi.c         | 30 ++++++++++++++++++++++++++++++
+ 2 files changed, 31 insertions(+)
+
+diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
+index f894ace..fe33038 100644
+--- a/include/scsi/scsi.h
++++ b/include/scsi/scsi.h
+@@ -15,5 +15,6 @@
+ #define QEMU_SCSI_H
+ 
+ int scsi_sense_to_errno(int key, int asc, int ascq);
++int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
+ 
+ #endif
+diff --git a/util/scsi.c b/util/scsi.c
+index 472eb5b..472293d 100644
+--- a/util/scsi.c
++++ b/util/scsi.c
+@@ -58,3 +58,33 @@ int scsi_sense_to_errno(int key, int asc, int ascq)
+         return EIO;
+     }
+ }
++
++int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size)
++{
++    int key, asc, ascq;
++    if (sense_size < 1) {
++        return EIO;
++    }
++    switch (sense[0]) {
++    case 0x70: /* Fixed format sense data. */
++        if (sense_size < 14) {
++            return EIO;
++        }
++        key = sense[2] & 0xF;
++        asc = sense[12];
++        ascq = sense[13];
++        break;
++    case 0x72: /* Descriptor format sense data. */
++        if (sense_size < 4) {
++            return EIO;
++        }
++        key = sense[1] & 0xF;
++        asc = sense[2];
++        ascq = sense[3];
++        break;
++    default:
++        return EIO;
++        break;
++    }
++    return scsi_sense_to_errno(key, asc, ascq);
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-Refactor-scsi-sense-interpreting-code.patch b/SOURCES/kvm-scsi-Refactor-scsi-sense-interpreting-code.patch
new file mode 100644
index 0000000..a607b02
--- /dev/null
+++ b/SOURCES/kvm-scsi-Refactor-scsi-sense-interpreting-code.patch
@@ -0,0 +1,207 @@
+From 4f71eecd159d2ab9e66e1f6115a0490676f76e8e Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:40 +0100
+Subject: [PATCH 14/36] scsi: Refactor scsi sense interpreting code
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-5-pbonzini@redhat.com>
+Patchwork-id: 78073
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 04/17] scsi: Refactor scsi sense interpreting code
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Fam Zheng <famz@redhat.com>
+
+So that it can be reused outside of iscsi.c.
+
+Also update MAINTAINERS to include the new files in SCSI section.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-Id: <20170821141008.19383-2-famz@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 2875135807771a0d07ba1c878c20b757ed7adffb)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ MAINTAINERS         |  2 ++
+ block/iscsi.c       | 45 ++++-----------------------------------------
+ include/scsi/scsi.h | 19 +++++++++++++++++++
+ util/Makefile.objs  |  1 +
+ util/scsi.c         | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 78 insertions(+), 41 deletions(-)
+ create mode 100644 include/scsi/scsi.h
+ create mode 100644 util/scsi.c
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index ccee28b..2a4e503 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -969,7 +969,9 @@ SCSI
+ M: Paolo Bonzini <pbonzini@redhat.com>
+ S: Supported
+ F: include/hw/scsi/*
++F: include/scsi/*
+ F: hw/scsi/*
++F: util/scsi*
+ F: tests/virtio-scsi-test.c
+ T: git git://github.com/bonzini/qemu.git scsi-next
+ 
+diff --git a/block/iscsi.c b/block/iscsi.c
+index d557c99..4bed63c 100644
+--- a/block/iscsi.c
++++ b/block/iscsi.c
+@@ -40,6 +40,7 @@
+ #include "qmp-commands.h"
+ #include "qapi/qmp/qstring.h"
+ #include "crypto/secret.h"
++#include "scsi/scsi.h"
+ 
+ #include <iscsi/iscsi.h>
+ #include <iscsi/scsi-lowlevel.h>
+@@ -209,47 +210,9 @@ static inline unsigned exp_random(double mean)
+ 
+ static int iscsi_translate_sense(struct scsi_sense *sense)
+ {
+-    int ret;
+-
+-    switch (sense->key) {
+-    case SCSI_SENSE_NOT_READY:
+-        return -EBUSY;
+-    case SCSI_SENSE_DATA_PROTECTION:
+-        return -EACCES;
+-    case SCSI_SENSE_COMMAND_ABORTED:
+-        return -ECANCELED;
+-    case SCSI_SENSE_ILLEGAL_REQUEST:
+-        /* Parse ASCQ */
+-        break;
+-    default:
+-        return -EIO;
+-    }
+-    switch (sense->ascq) {
+-    case SCSI_SENSE_ASCQ_PARAMETER_LIST_LENGTH_ERROR:
+-    case SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE:
+-    case SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB:
+-    case SCSI_SENSE_ASCQ_INVALID_FIELD_IN_PARAMETER_LIST:
+-        ret = -EINVAL;
+-        break;
+-    case SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE:
+-        ret = -ENOSPC;
+-        break;
+-    case SCSI_SENSE_ASCQ_LOGICAL_UNIT_NOT_SUPPORTED:
+-        ret = -ENOTSUP;
+-        break;
+-    case SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT:
+-    case SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED:
+-    case SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN:
+-        ret = -ENOMEDIUM;
+-        break;
+-    case SCSI_SENSE_ASCQ_WRITE_PROTECTED:
+-        ret = -EACCES;
+-        break;
+-    default:
+-        ret = -EIO;
+-        break;
+-    }
+-    return ret;
++    return - scsi_sense_to_errno(sense->key,
++                                 (sense->ascq & 0xFF00) >> 8,
++                                 sense->ascq & 0xFF);
+ }
+ 
+ /* Called (via iscsi_service) with QemuMutex held.  */
+diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
+new file mode 100644
+index 0000000..f894ace
+--- /dev/null
++++ b/include/scsi/scsi.h
+@@ -0,0 +1,19 @@
++/*
++ *  SCSI helpers
++ *
++ *  Copyright 2017 Red Hat, Inc.
++ *
++ *  Authors:
++ *   Fam Zheng <famz@redhat.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2 of the License, or (at your option)
++ * any later version.
++ */
++#ifndef QEMU_SCSI_H
++#define QEMU_SCSI_H
++
++int scsi_sense_to_errno(int key, int asc, int ascq);
++
++#endif
+diff --git a/util/Makefile.objs b/util/Makefile.objs
+index 50a55ec..c9e6c49 100644
+--- a/util/Makefile.objs
++++ b/util/Makefile.objs
+@@ -45,3 +45,4 @@ util-obj-y += qht.o
+ util-obj-y += range.o
+ util-obj-y += stats64.o
+ util-obj-y += systemd.o
++util-obj-y += scsi.o
+diff --git a/util/scsi.c b/util/scsi.c
+new file mode 100644
+index 0000000..a671079
+--- /dev/null
++++ b/util/scsi.c
+@@ -0,0 +1,52 @@
++/*
++ *  SCSI helpers
++ *
++ *  Copyright 2017 Red Hat, Inc.
++ *
++ *  Authors:
++ *   Fam Zheng <famz@redhat.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2 of the License, or (at your option)
++ * any later version.
++ */
++
++#include "qemu/osdep.h"
++#include "scsi/scsi.h"
++
++int scsi_sense_to_errno(int key, int asc, int ascq)
++{
++    switch (key) {
++    case 0x02: /* NOT READY */
++        return EBUSY;
++    case 0x07: /* DATA PROTECTION */
++        return EACCES;
++    case 0x0b: /* COMMAND ABORTED */
++        return ECANCELED;
++    case 0x05: /* ILLEGAL REQUEST */
++        /* Parse ASCQ */
++        break;
++    default:
++        return EIO;
++    }
++    switch ((asc << 8) | ascq) {
++    case 0x1a00: /* PARAMETER LIST LENGTH ERROR */
++    case 0x2000: /* INVALID OPERATION CODE */
++    case 0x2400: /* INVALID FIELD IN CDB */
++    case 0x2600: /* INVALID FIELD IN PARAMETER LIST */
++        return EINVAL;
++    case 0x2100: /* LBA OUT OF RANGE */
++        return ENOSPC;
++    case 0x2500: /* LOGICAL UNIT NOT SUPPORTED */
++        return ENOTSUP;
++    case 0x3a00: /* MEDIUM NOT PRESENT */
++    case 0x3a01: /* MEDIUM NOT PRESENT TRAY CLOSED */
++    case 0x3a02: /* MEDIUM NOT PRESENT TRAY OPEN */
++        return ENOMEDIUM;
++    case 0x2700: /* WRITE PROTECTED */
++        return EACCES;
++    default:
++        return EIO;
++    }
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-add-multipath-support-to-qemu-pr-helper.patch b/SOURCES/kvm-scsi-add-multipath-support-to-qemu-pr-helper.patch
new file mode 100644
index 0000000..7780492
--- /dev/null
+++ b/SOURCES/kvm-scsi-add-multipath-support-to-qemu-pr-helper.patch
@@ -0,0 +1,675 @@
+From d9ebb2728bc92d055f178f1c45f82979c542a9aa Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:50 +0100
+Subject: [PATCH 24/36] scsi: add multipath support to qemu-pr-helper
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-15-pbonzini@redhat.com>
+Patchwork-id: 78083
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 14/17] scsi: add multipath support to qemu-pr-helper
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Proper support of persistent reservation for multipath devices requires
+communication with the multipath daemon, so that the reservation is
+registered and applied when a path comes up.  The device mapper
+utilities provide a library to do so; this patch makes qemu-pr-helper.c
+detect multipath devices and, when one is found, delegate the operation
+to libmpathpersist.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit fe8fc5ae5c808e037fa4746cbfeb3c07ffe0af81)
+
+[RHEL: do not use {0} because GCC does not like it; will be changed
+ upstream, but squash it in here so that all commits compile - Paolo]
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ Makefile              |   3 +
+ configure             |  46 +++++++
+ docs/pr-manager.rst   |  27 ++++
+ include/scsi/utils.h  |   4 +
+ scsi/qemu-pr-helper.c | 346 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ scsi/utils.c          |  10 ++
+ 6 files changed, 433 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 3e76953..ae48405 100644
+--- a/Makefile
++++ b/Makefile
+@@ -387,6 +387,9 @@ fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal
+ fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
+ 
+ scsi/qemu-pr-helper$(EXESUF): scsi/qemu-pr-helper.o scsi/utils.o $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
++ifdef CONFIG_MPATH
++scsi/qemu-pr-helper$(EXESUF): LIBS += -ludev -lmultipath -lmpathpersist
++endif
+ 
+ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
+ 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"GEN","$@")
+diff --git a/configure b/configure
+index 2df1b42..97ee507 100755
+--- a/configure
++++ b/configure
+@@ -291,6 +291,7 @@ pixman=""
+ sdl=""
+ sdlabi=""
+ virtfs=""
++mpath=""
+ vnc="yes"
+ sparse="no"
+ vde=""
+@@ -956,6 +957,10 @@ for opt do
+   ;;
+   --enable-virtfs) virtfs="yes"
+   ;;
++  --disable-mpath) mpath="no"
++  ;;
++  --enable-mpath) mpath="yes"
++  ;;
+   --disable-vnc) vnc="no"
+   ;;
+   --enable-vnc) vnc="yes"
+@@ -1510,6 +1515,7 @@ disabled with --disable-FEATURE, default is enabled if available:
+   vnc-png         PNG compression for VNC server
+   cocoa           Cocoa UI (Mac OS X only)
+   virtfs          VirtFS
++  mpath           Multipath persistent reservation passthrough
+   xen             xen backend driver support
+   xen-pci-passthrough
+   brlapi          BrlAPI (Braile)
+@@ -3358,6 +3364,30 @@ else
+ fi
+ 
+ ##########################################
++# libmpathpersist probe
++
++if test "$mpath" != "no" ; then
++  cat > $TMPC <<EOF
++#include <libudev.h>
++#include <mpath_persist.h>
++unsigned mpath_mx_alloc_len = 1024;
++int logsink;
++int main(void) {
++    struct udev *udev = udev_new();
++    mpath_lib_init(udev);
++    return 0;
++}
++EOF
++  if compile_prog "" "-ludev -lmultipath -lmpathpersist" ; then
++    mpathpersist=yes
++  else
++    mpathpersist=no
++  fi
++else
++  mpathpersist=no
++fi
++
++##########################################
+ # libcap probe
+ 
+ if test "$cap" != "no" ; then
+@@ -5075,12 +5105,24 @@ if test "$softmmu" = yes ; then
+       fi
+       virtfs=no
+     fi
++    if test "$mpath" != no && test "$mpathpersist" = yes ; then
++      mpath=yes
++    else
++      if test "$mpath" = yes; then
++        error_exit "Multipath requires libmpathpersist devel"
++      fi
++      mpath=no
++    fi
+     tools="$tools scsi/qemu-pr-helper\$(EXESUF)"
+   else
+     if test "$virtfs" = yes; then
+       error_exit "VirtFS is supported only on Linux"
+     fi
+     virtfs=no
++    if test "$mpath" = yes; then
++      error_exit "Multipath is supported only on Linux"
++    fi
++    mpath=no
+   fi
+ fi
+ 
+@@ -5327,6 +5369,7 @@ echo "Audio drivers     $audio_drv_list"
+ echo "Block whitelist (rw) $block_drv_rw_whitelist"
+ echo "Block whitelist (ro) $block_drv_ro_whitelist"
+ echo "VirtFS support    $virtfs"
++echo "Multipath support $mpath"
+ echo "VNC support       $vnc"
+ if test "$vnc" = "yes" ; then
+     echo "VNC SASL support  $vnc_sasl"
+@@ -5777,6 +5820,9 @@ fi
+ if test "$virtfs" = "yes" ; then
+   echo "CONFIG_VIRTFS=y" >> $config_host_mak
+ fi
++if test "$mpath" = "yes" ; then
++  echo "CONFIG_MPATH=y" >> $config_host_mak
++fi
+ if test "$vhost_scsi" = "yes" ; then
+   echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
+ fi
+diff --git a/docs/pr-manager.rst b/docs/pr-manager.rst
+index 7107e59..9b1de19 100644
+--- a/docs/pr-manager.rst
++++ b/docs/pr-manager.rst
+@@ -60,6 +60,7 @@ system service and supports the following option:
+ 
+ -d, --daemon              run in the background
+ -q, --quiet               decrease verbosity
++-v, --verbose             increase verbosity
+ -f, --pidfile=path        PID file when running as a daemon
+ -k, --socket=path         path to the socket
+ -T, --trace=trace-opts    tracing options
+@@ -82,3 +83,29 @@ its operation.  To do this, add the following options:
+ 
+ -u, --user=user           user to drop privileges to
+ -g, --group=group         group to drop privileges to
++
++---------------------------------------------
++Multipath devices and persistent reservations
++---------------------------------------------
++
++Proper support of persistent reservation for multipath devices requires
++communication with the multipath daemon, so that the reservation is
++registered and applied when a path is newly discovered or becomes online
++again.  :command:`qemu-pr-helper` can do this if the ``libmpathpersist``
++library was available on the system at build time.
++
++As of August 2017, a reservation key must be specified in ``multipath.conf``
++for ``multipathd`` to check for persistent reservation for newly
++discovered paths or reinstated paths.  The attribute can be added
++to the ``defaults`` section or the ``multipaths`` section; for example::
++
++    multipaths {
++        multipath {
++            wwid   XXXXXXXXXXXXXXXX
++            alias      yellow
++            reservation_key  0x123abc
++        }
++    }
++
++Linking :program:`qemu-pr-helper` to ``libmpathpersist`` does not impede
++its usage on regular SCSI devices.
+diff --git a/include/scsi/utils.h b/include/scsi/utils.h
+index d301b31..00a4bdb 100644
+--- a/include/scsi/utils.h
++++ b/include/scsi/utils.h
+@@ -72,10 +72,14 @@ extern const struct SCSISense sense_code_IO_ERROR;
+ extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
+ /* Command aborted, Logical Unit failure */
+ extern const struct SCSISense sense_code_LUN_FAILURE;
++/* Command aborted, LUN Communication failure */
++extern const struct SCSISense sense_code_LUN_COMM_FAILURE;
+ /* Command aborted, Overlapped Commands Attempted */
+ extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
+ /* LUN not ready, Capacity data has changed */
+ extern const struct SCSISense sense_code_CAPACITY_CHANGED;
++/* Unit attention, SCSI bus reset */
++extern const struct SCSISense sense_code_SCSI_BUS_RESET;
+ /* LUN not ready, Medium not present */
+ extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
+ /* Unit attention, Power on, reset or bus device reset occurred */
+diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
+index f46266f..42bc2cf 100644
+--- a/scsi/qemu-pr-helper.c
++++ b/scsi/qemu-pr-helper.c
+@@ -30,6 +30,12 @@
+ #include <pwd.h>
+ #include <grp.h>
+ 
++#ifdef CONFIG_MPATH
++#include <libudev.h>
++#include <mpath_cmd.h>
++#include <mpath_persist.h>
++#endif
++
+ #include "qapi/error.h"
+ #include "qemu-common.h"
+ #include "qemu/cutils.h"
+@@ -60,6 +66,7 @@ static enum { RUNNING, TERMINATE, TERMINATING } state;
+ static QIOChannelSocket *server_ioc;
+ static int server_watch;
+ static int num_active_sockets = 1;
++static int noisy;
+ static int verbose;
+ 
+ #ifdef CONFIG_LIBCAP
+@@ -204,9 +211,316 @@ static int do_sgio(int fd, const uint8_t *cdb, uint8_t *sense,
+     return r;
+ }
+ 
++/* Device mapper interface */
++
++#ifdef CONFIG_MPATH
++#define CONTROL_PATH "/dev/mapper/control"
++
++typedef struct DMData {
++    struct dm_ioctl dm;
++    uint8_t data[1024];
++} DMData;
++
++static int control_fd;
++
++static void *dm_ioctl(int ioc, struct dm_ioctl *dm)
++{
++    static DMData d;
++    memcpy(&d.dm, dm, sizeof(d.dm));
++    QEMU_BUILD_BUG_ON(sizeof(d.data) < sizeof(struct dm_target_spec));
++
++    d.dm.version[0] = DM_VERSION_MAJOR;
++    d.dm.version[1] = 0;
++    d.dm.version[2] = 0;
++    d.dm.data_size = 1024;
++    d.dm.data_start = offsetof(DMData, data);
++    if (ioctl(control_fd, ioc, &d) < 0) {
++        return NULL;
++    }
++    memcpy(dm, &d.dm, sizeof(d.dm));
++    return &d.data;
++}
++
++static void *dm_dev_ioctl(int fd, int ioc, struct dm_ioctl *dm)
++{
++    struct stat st;
++    int r;
++
++    r = fstat(fd, &st);
++    if (r < 0) {
++        perror("fstat");
++        exit(1);
++    }
++
++    dm->dev = st.st_rdev;
++    return dm_ioctl(ioc, dm);
++}
++
++static void dm_init(void)
++{
++    control_fd = open(CONTROL_PATH, O_RDWR);
++    if (control_fd < 0) {
++        perror("Cannot open " CONTROL_PATH);
++        exit(1);
++    }
++    struct dm_ioctl dm = {};
++    if (!dm_ioctl(DM_VERSION, &dm)) {
++        perror("ioctl");
++        exit(1);
++    }
++    if (dm.version[0] != DM_VERSION_MAJOR) {
++        fprintf(stderr, "Unsupported device mapper interface");
++        exit(1);
++    }
++}
++
++/* Variables required by libmultipath and libmpathpersist.  */
++QEMU_BUILD_BUG_ON(PR_HELPER_DATA_SIZE > MPATH_MAX_PARAM_LEN);
++unsigned mpath_mx_alloc_len = PR_HELPER_DATA_SIZE;
++int logsink;
++
++static void multipath_pr_init(void)
++{
++    static struct udev *udev;
++
++    udev = udev_new();
++    mpath_lib_init(udev);
++}
++
++static int is_mpath(int fd)
++{
++    struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG };
++    struct dm_target_spec *tgt;
++
++    tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm);
++    if (!tgt) {
++        if (errno == ENXIO) {
++            return 0;
++        }
++        perror("ioctl");
++        exit(EXIT_FAILURE);
++    }
++    return !strncmp(tgt->target_type, "multipath", DM_MAX_TYPE_NAME);
++}
++
++static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
++{
++    switch (r) {
++    case MPATH_PR_SUCCESS:
++        return GOOD;
++    case MPATH_PR_SENSE_NOT_READY:
++    case MPATH_PR_SENSE_MEDIUM_ERROR:
++    case MPATH_PR_SENSE_HARDWARE_ERROR:
++    case MPATH_PR_SENSE_ABORTED_COMMAND:
++        {
++            /* libmpathpersist ate the exact sense.  Try to find it by
++             * issuing TEST UNIT READY.
++             */
++            uint8_t cdb[6] = { TEST_UNIT_READY };
++            int sz = 0;
++            return do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
++        }
++
++    case MPATH_PR_SENSE_UNIT_ATTENTION:
++        /* Congratulations libmpathpersist, you ruined the Unit Attention...
++         * Return a heavyweight one.
++         */
++        scsi_build_sense(sense, SENSE_CODE(SCSI_BUS_RESET));
++        return CHECK_CONDITION;
++    case MPATH_PR_SENSE_INVALID_OP:
++        /* Only one valid sense.  */
++        scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
++        return CHECK_CONDITION;
++    case MPATH_PR_ILLEGAL_REQ:
++        /* Guess.  */
++        scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
++        return CHECK_CONDITION;
++    case MPATH_PR_NO_SENSE:
++        scsi_build_sense(sense, SENSE_CODE(NO_SENSE));
++        return CHECK_CONDITION;
++
++    case MPATH_PR_RESERV_CONFLICT:
++        return RESERVATION_CONFLICT;
++
++    case MPATH_PR_OTHER:
++    default:
++        scsi_build_sense(sense, SENSE_CODE(LUN_COMM_FAILURE));
++        return CHECK_CONDITION;
++    }
++}
++
++static int multipath_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
++                           uint8_t *data, int sz)
++{
++    int rq_servact = cdb[1];
++    struct prin_resp resp;
++    size_t written;
++    int r;
++
++    switch (rq_servact) {
++    case MPATH_PRIN_RKEY_SA:
++    case MPATH_PRIN_RRES_SA:
++    case MPATH_PRIN_RCAP_SA:
++        break;
++    case MPATH_PRIN_RFSTAT_SA:
++        /* Nobody implements it anyway, so bail out. */
++    default:
++        /* Cannot parse any other output.  */
++        scsi_build_sense(sense, SENSE_CODE(INVALID_FIELD));
++        return CHECK_CONDITION;
++    }
++
++    r = mpath_persistent_reserve_in(fd, rq_servact, &resp, noisy, verbose);
++    if (r == MPATH_PR_SUCCESS) {
++        switch (rq_servact) {
++        case MPATH_PRIN_RKEY_SA:
++        case MPATH_PRIN_RRES_SA: {
++            struct prin_readdescr *out = &resp.prin_descriptor.prin_readkeys;
++            assert(sz >= 8);
++            written = MIN(out->additional_length + 8, sz);
++            stl_be_p(&data[0], out->prgeneration);
++            stl_be_p(&data[4], out->additional_length);
++            memcpy(&data[8], out->key_list, written - 8);
++            break;
++        }
++        case MPATH_PRIN_RCAP_SA: {
++            struct prin_capdescr *out = &resp.prin_descriptor.prin_readcap;
++            assert(sz >= 6);
++            written = 6;
++            stw_be_p(&data[0], out->length);
++            data[2] = out->flags[0];
++            data[3] = out->flags[1];
++            stw_be_p(&data[4], out->pr_type_mask);
++            break;
++        }
++        default:
++            scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
++            return CHECK_CONDITION;
++        }
++        assert(written <= sz);
++        memset(data + written, 0, sz - written);
++    }
++
++    return mpath_reconstruct_sense(fd, r, sense);
++}
++
++static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
++                            const uint8_t *param, int sz)
++{
++    int rq_servact = cdb[1];
++    int rq_scope = cdb[2] >> 4;
++    int rq_type = cdb[2] & 0xf;
++    struct prout_param_descriptor paramp;
++    char transportids[PR_HELPER_DATA_SIZE];
++    int r;
++
++    switch (rq_servact) {
++    case MPATH_PROUT_REG_SA:
++    case MPATH_PROUT_RES_SA:
++    case MPATH_PROUT_REL_SA:
++    case MPATH_PROUT_CLEAR_SA:
++    case MPATH_PROUT_PREE_SA:
++    case MPATH_PROUT_PREE_AB_SA:
++    case MPATH_PROUT_REG_IGN_SA:
++        break;
++    case MPATH_PROUT_REG_MOV_SA:
++        /* Not supported by struct prout_param_descriptor.  */
++    default:
++        /* Cannot parse any other input.  */
++        scsi_build_sense(sense, SENSE_CODE(INVALID_FIELD));
++        return CHECK_CONDITION;
++    }
++
++    /* Convert input data, especially transport IDs, to the structs
++     * used by libmpathpersist (which, of course, will immediately
++     * do the opposite).
++     */
++    memset(&paramp, 0, sizeof(paramp));
++    memcpy(&paramp.key, &param[0], 8);
++    memcpy(&paramp.sa_key, &param[8], 8);
++    paramp.sa_flags = param[10];
++    if (sz > PR_OUT_FIXED_PARAM_SIZE) {
++        size_t transportid_len;
++        int i, j;
++        if (sz < PR_OUT_FIXED_PARAM_SIZE + 4) {
++            scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM_LEN));
++            return CHECK_CONDITION;
++        }
++        transportid_len = ldl_be_p(&param[24]) + PR_OUT_FIXED_PARAM_SIZE + 4;
++        if (transportid_len > sz) {
++            scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
++            return CHECK_CONDITION;
++        }
++        for (i = PR_OUT_FIXED_PARAM_SIZE + 4, j = 0; i < transportid_len; ) {
++            struct transportid *id = (struct transportid *) &transportids[j];
++            int len;
++
++            id->format_code = param[i] & 0xc0;
++            id->protocol_id = param[i] & 0x0f;
++            switch (param[i] & 0xcf) {
++            case 0:
++                /* FC transport.  */
++                if (i + 24 > transportid_len) {
++                    goto illegal_req;
++                }
++                memcpy(id->n_port_name, &param[i + 8], 8);
++                j += offsetof(struct transportid, n_port_name[8]);
++                i += 24;
++                break;
++            case 3:
++            case 0x43:
++                /* iSCSI transport.  */
++                len = lduw_be_p(&param[i + 2]);
++                if (len > 252 || (len & 3) || i + len + 4 > transportid_len) {
++                    /* For format code 00, the standard says the maximum is 223
++                     * plus the NUL terminator.  For format code 01 there is no
++                     * maximum length, but libmpathpersist ignores the first
++                     * byte of id->iscsi_name so our maximum is 252.
++                     */
++                    goto illegal_req;
++                }
++                if (memchr(&param[i + 4], 0, len) == NULL) {
++                    goto illegal_req;
++                }
++                memcpy(id->iscsi_name, &param[i + 2], len + 2);
++                j += offsetof(struct transportid, iscsi_name[len + 2]);
++                i += len + 4;
++                break;
++            case 6:
++                /* SAS transport.  */
++                if (i + 24 > transportid_len) {
++                    goto illegal_req;
++                }
++                memcpy(id->sas_address, &param[i + 4], 8);
++                j += offsetof(struct transportid, sas_address[8]);
++                i += 24;
++                break;
++            default:
++            illegal_req:
++                scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
++                return CHECK_CONDITION;
++            }
++
++            paramp.trnptid_list[paramp.num_transportid++] = id;
++        }
++    }
++
++    r = mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type,
++                                     &paramp, noisy, verbose);
++    return mpath_reconstruct_sense(fd, r, sense);
++}
++#endif
++
+ static int do_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
+                     uint8_t *data, int *resp_sz)
+ {
++#ifdef CONFIG_MPATH
++    if (is_mpath(fd)) {
++        /* multipath_pr_in fills the whole input buffer.  */
++        return multipath_pr_in(fd, cdb, sense, data, *resp_sz);
++    }
++#endif
++
+     return do_sgio(fd, cdb, sense, data, resp_sz,
+                    SG_DXFER_FROM_DEV);
+ }
+@@ -214,7 +528,14 @@ static int do_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
+ static int do_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
+                      const uint8_t *param, int sz)
+ {
+-    int resp_sz = sz;
++    int resp_sz;
++#ifdef CONFIG_MPATH
++    if (is_mpath(fd)) {
++        return multipath_pr_out(fd, cdb, sense, param, sz);
++    }
++#endif
++
++    resp_sz = sz;
+     return do_sgio(fd, cdb, sense, (uint8_t *)param, &resp_sz,
+                    SG_DXFER_TO_DEV);
+ }
+@@ -525,6 +846,14 @@ static int drop_privileges(void)
+         return -1;
+     }
+ 
++#ifdef CONFIG_MPATH
++    /* For /dev/mapper/control ioctls */
++    if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
++                     CAP_SYS_ADMIN) < 0) {
++        return -1;
++    }
++#endif
++
+     /* Change user/group id, retaining the capabilities.  Because file descriptors
+      * are passed via SCM_RIGHTS, we don't need supplementary groups (and in
+      * fact the helper can run as "nobody").
+@@ -541,7 +870,7 @@ static int drop_privileges(void)
+ 
+ int main(int argc, char **argv)
+ {
+-    const char *sopt = "hVk:fdT:u:g:q";
++    const char *sopt = "hVk:fdT:u:g:vq";
+     struct option lopt[] = {
+         { "help", no_argument, NULL, 'h' },
+         { "version", no_argument, NULL, 'V' },
+@@ -551,10 +880,12 @@ int main(int argc, char **argv)
+         { "trace", required_argument, NULL, 'T' },
+         { "user", required_argument, NULL, 'u' },
+         { "group", required_argument, NULL, 'g' },
++        { "verbose", no_argument, NULL, 'v' },
+         { "quiet", no_argument, NULL, 'q' },
+         { NULL, 0, NULL, 0 }
+     };
+     int opt_ind = 0;
++    int loglevel = 1;
+     int quiet = 0;
+     int ch;
+     Error *local_err = NULL;
+@@ -631,6 +962,9 @@ int main(int argc, char **argv)
+         case 'q':
+             quiet = 1;
+             break;
++        case 'v':
++            ++loglevel;
++            break;
+         case 'T':
+             g_free(trace_file);
+             trace_file = trace_opt_parse(optarg);
+@@ -650,7 +984,8 @@ int main(int argc, char **argv)
+     }
+ 
+     /* set verbosity */
+-    verbose = !quiet;
++    noisy = !quiet && (loglevel >= 3);
++    verbose = quiet ? 0 : MIN(loglevel, 3);
+ 
+     if (!trace_init_backends()) {
+         exit(EXIT_FAILURE);
+@@ -658,6 +993,11 @@ int main(int argc, char **argv)
+     trace_init_file(trace_file);
+     qemu_set_log(LOG_TRACE);
+ 
++#ifdef CONFIG_MPATH
++    dm_init();
++    multipath_pr_init();
++#endif
++
+     socket_activation = check_socket_activation();
+     if (socket_activation == 0) {
+         SocketAddress saddr;
+diff --git a/scsi/utils.c b/scsi/utils.c
+index fab60bd..5684951 100644
+--- a/scsi/utils.c
++++ b/scsi/utils.c
+@@ -206,6 +206,11 @@ const struct SCSISense sense_code_OVERLAPPED_COMMANDS = {
+     .key = ABORTED_COMMAND, .asc = 0x4e, .ascq = 0x00
+ };
+ 
++/* Command aborted, LUN Communication Failure */
++const struct SCSISense sense_code_LUN_COMM_FAILURE = {
++    .key = ABORTED_COMMAND, .asc = 0x08, .ascq = 0x00
++};
++
+ /* Unit attention, Capacity data has changed */
+ const struct SCSISense sense_code_CAPACITY_CHANGED = {
+     .key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
+@@ -216,6 +221,11 @@ const struct SCSISense sense_code_RESET = {
+     .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
+ };
+ 
++/* Unit attention, SCSI bus reset */
++const struct SCSISense sense_code_SCSI_BUS_RESET = {
++    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x02
++};
++
+ /* Unit attention, No medium */
+ const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = {
+     .key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-add-persistent-reservation-manager-using-qemu-p.patch b/SOURCES/kvm-scsi-add-persistent-reservation-manager-using-qemu-p.patch
new file mode 100644
index 0000000..b9e6cf6
--- /dev/null
+++ b/SOURCES/kvm-scsi-add-persistent-reservation-manager-using-qemu-p.patch
@@ -0,0 +1,346 @@
+From 65c8aa05dcaaad802c92a55c9352305c3de39de0 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:51 +0100
+Subject: [PATCH 25/36] scsi: add persistent reservation manager using
+ qemu-pr-helper
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-16-pbonzini@redhat.com>
+Patchwork-id: 78084
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 15/17] scsi: add persistent reservation manager using qemu-pr-helper
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+This adds a concrete subclass of pr-manager that talks to qemu-pr-helper.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 9bad2a6b9d0aeb2dcf91a07652cc63bbb6e73141)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scsi/Makefile.objs       |   2 +-
+ scsi/pr-manager-helper.c | 302 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 303 insertions(+), 1 deletion(-)
+ create mode 100644 scsi/pr-manager-helper.c
+
+diff --git a/scsi/Makefile.objs b/scsi/Makefile.objs
+index 5496d2a..4d25e47 100644
+--- a/scsi/Makefile.objs
++++ b/scsi/Makefile.objs
+@@ -1,3 +1,3 @@
+ block-obj-y += utils.o
+ 
+-block-obj-$(CONFIG_LINUX) += pr-manager.o
++block-obj-$(CONFIG_LINUX) += pr-manager.o pr-manager-helper.o
+diff --git a/scsi/pr-manager-helper.c b/scsi/pr-manager-helper.c
+new file mode 100644
+index 0000000..82ff6b6
+--- /dev/null
++++ b/scsi/pr-manager-helper.c
+@@ -0,0 +1,302 @@
++/*
++ * Persistent reservation manager that talks to qemu-pr-helper
++ *
++ * Copyright (c) 2017 Red Hat, Inc.
++ *
++ * Author: Paolo Bonzini <pbonzini@redhat.com>
++ *
++ * This code is licensed under the LGPL v2.1 or later.
++ *
++ */
++
++#include "qemu/osdep.h"
++#include "qapi/error.h"
++#include "scsi/constants.h"
++#include "scsi/pr-manager.h"
++#include "scsi/utils.h"
++#include "io/channel.h"
++#include "io/channel-socket.h"
++#include "pr-helper.h"
++
++#include <scsi/sg.h>
++
++#define PR_MAX_RECONNECT_ATTEMPTS 5
++
++#define TYPE_PR_MANAGER_HELPER "pr-manager-helper"
++
++#define PR_MANAGER_HELPER(obj) \
++     OBJECT_CHECK(PRManagerHelper, (obj), \
++                  TYPE_PR_MANAGER_HELPER)
++
++typedef struct PRManagerHelper {
++    /* <private> */
++    PRManager parent;
++
++    char *path;
++
++    QemuMutex lock;
++    QIOChannel *ioc;
++} PRManagerHelper;
++
++/* Called with lock held.  */
++static int pr_manager_helper_read(PRManagerHelper *pr_mgr,
++                                  void *buf, int sz, Error **errp)
++{
++    ssize_t r = qio_channel_read_all(pr_mgr->ioc, buf, sz, errp);
++
++    if (r < 0) {
++        object_unref(OBJECT(pr_mgr->ioc));
++        pr_mgr->ioc = NULL;
++        return -EINVAL;
++    }
++
++    return 0;
++}
++
++/* Called with lock held.  */
++static int pr_manager_helper_write(PRManagerHelper *pr_mgr,
++                                   int fd,
++                                   const void *buf, int sz, Error **errp)
++{
++    size_t nfds = (fd != -1);
++    while (sz > 0) {
++        struct iovec iov;
++        ssize_t n_written;
++
++        iov.iov_base = (void *)buf;
++        iov.iov_len = sz;
++        n_written = qio_channel_writev_full(QIO_CHANNEL(pr_mgr->ioc), &iov, 1,
++                                            nfds ? &fd : NULL, nfds, errp);
++
++        if (n_written <= 0) {
++            assert(n_written != QIO_CHANNEL_ERR_BLOCK);
++            object_unref(OBJECT(pr_mgr->ioc));
++            return n_written < 0 ? -EINVAL : 0;
++        }
++
++        nfds = 0;
++        buf += n_written;
++        sz -= n_written;
++    }
++
++    return 0;
++}
++
++/* Called with lock held.  */
++static int pr_manager_helper_initialize(PRManagerHelper *pr_mgr,
++                                        Error **errp)
++{
++    char *path = g_strdup(pr_mgr->path);
++    SocketAddress saddr = {
++        .type = SOCKET_ADDRESS_TYPE_UNIX,
++        .u.q_unix.path = path
++    };
++    QIOChannelSocket *sioc = qio_channel_socket_new();
++    Error *local_err = NULL;
++
++    uint32_t flags;
++    int r;
++
++    assert(!pr_mgr->ioc);
++    qio_channel_set_name(QIO_CHANNEL(sioc), "pr-manager-helper");
++    qio_channel_socket_connect_sync(sioc,
++                                    &saddr,
++                                    &local_err);
++    g_free(path);
++    if (local_err) {
++        object_unref(OBJECT(sioc));
++        error_propagate(errp, local_err);
++        return -ENOTCONN;
++    }
++
++    qio_channel_set_delay(QIO_CHANNEL(sioc), false);
++    pr_mgr->ioc = QIO_CHANNEL(sioc);
++
++    /* A simple feature negotation protocol, even though there is
++     * no optional feature right now.
++     */
++    r = pr_manager_helper_read(pr_mgr, &flags, sizeof(flags), errp);
++    if (r < 0) {
++        goto out_close;
++    }
++
++    flags = 0;
++    r = pr_manager_helper_write(pr_mgr, -1, &flags, sizeof(flags), errp);
++    if (r < 0) {
++        goto out_close;
++    }
++
++    return 0;
++
++out_close:
++    object_unref(OBJECT(pr_mgr->ioc));
++    pr_mgr->ioc = NULL;
++    return r;
++}
++
++static int pr_manager_helper_run(PRManager *p,
++                                 int fd, struct sg_io_hdr *io_hdr)
++{
++    PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(p);
++
++    uint32_t len;
++    PRHelperResponse resp;
++    int ret;
++    int expected_dir;
++    int attempts;
++    uint8_t cdb[PR_HELPER_CDB_SIZE] = { 0 };
++
++    if (!io_hdr->cmd_len || io_hdr->cmd_len > PR_HELPER_CDB_SIZE) {
++        return -EINVAL;
++    }
++
++    memcpy(cdb, io_hdr->cmdp, io_hdr->cmd_len);
++    assert(cdb[0] == PERSISTENT_RESERVE_OUT || cdb[0] == PERSISTENT_RESERVE_IN);
++    expected_dir =
++        (cdb[0] == PERSISTENT_RESERVE_OUT ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV);
++    if (io_hdr->dxfer_direction != expected_dir) {
++        return -EINVAL;
++    }
++
++    len = scsi_cdb_xfer(cdb);
++    if (io_hdr->dxfer_len < len || len > PR_HELPER_DATA_SIZE) {
++        return -EINVAL;
++    }
++
++    qemu_mutex_lock(&pr_mgr->lock);
++
++    /* Try to reconnect while sending the CDB.  */
++    for (attempts = 0; attempts < PR_MAX_RECONNECT_ATTEMPTS; attempts++) {
++        if (!pr_mgr->ioc) {
++            ret = pr_manager_helper_initialize(pr_mgr, NULL);
++            if (ret < 0) {
++                qemu_mutex_unlock(&pr_mgr->lock);
++                g_usleep(G_USEC_PER_SEC);
++                qemu_mutex_lock(&pr_mgr->lock);
++                continue;
++            }
++        }
++
++        ret = pr_manager_helper_write(pr_mgr, fd, cdb, ARRAY_SIZE(cdb), NULL);
++        if (ret >= 0) {
++            break;
++        }
++    }
++    if (ret < 0) {
++        goto out;
++    }
++
++    /* After sending the CDB, any communications failure causes the
++     * command to fail.  The failure is transient, retrying the command
++     * will invoke pr_manager_helper_initialize again.
++     */
++    if (expected_dir == SG_DXFER_TO_DEV) {
++        io_hdr->resid = io_hdr->dxfer_len - len;
++        ret = pr_manager_helper_write(pr_mgr, -1, io_hdr->dxferp, len, NULL);
++        if (ret < 0) {
++            goto out;
++        }
++    }
++    ret = pr_manager_helper_read(pr_mgr, &resp, sizeof(resp), NULL);
++    if (ret < 0) {
++        goto out;
++    }
++
++    resp.result = be32_to_cpu(resp.result);
++    resp.sz = be32_to_cpu(resp.sz);
++    if (io_hdr->dxfer_direction == SG_DXFER_FROM_DEV) {
++        assert(resp.sz <= io_hdr->dxfer_len);
++        ret = pr_manager_helper_read(pr_mgr, io_hdr->dxferp, resp.sz, NULL);
++        if (ret < 0) {
++            goto out;
++        }
++        io_hdr->resid = io_hdr->dxfer_len - resp.sz;
++    } else {
++        assert(resp.sz == 0);
++    }
++
++    io_hdr->status = resp.result;
++    if (resp.result == CHECK_CONDITION) {
++        io_hdr->driver_status = SG_ERR_DRIVER_SENSE;
++        io_hdr->sb_len_wr = MIN(io_hdr->mx_sb_len, PR_HELPER_SENSE_SIZE);
++        memcpy(io_hdr->sbp, resp.sense, io_hdr->sb_len_wr);
++    }
++
++out:
++    if (ret < 0) {
++        int sense_len = scsi_build_sense(io_hdr->sbp,
++                                         SENSE_CODE(LUN_COMM_FAILURE));
++        io_hdr->driver_status = SG_ERR_DRIVER_SENSE;
++        io_hdr->sb_len_wr = MIN(io_hdr->mx_sb_len, sense_len);
++        io_hdr->status = CHECK_CONDITION;
++    }
++    qemu_mutex_unlock(&pr_mgr->lock);
++    return ret;
++}
++
++static void pr_manager_helper_complete(UserCreatable *uc, Error **errp)
++{
++    PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(uc);
++
++    qemu_mutex_lock(&pr_mgr->lock);
++    pr_manager_helper_initialize(pr_mgr, errp);
++    qemu_mutex_unlock(&pr_mgr->lock);
++}
++
++static char *get_path(Object *obj, Error **errp)
++{
++    PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(obj);
++
++    return g_strdup(pr_mgr->path);
++}
++
++static void set_path(Object *obj, const char *str, Error **errp)
++{
++    PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(obj);
++
++    g_free(pr_mgr->path);
++    pr_mgr->path = g_strdup(str);
++}
++
++static void pr_manager_helper_instance_finalize(Object *obj)
++{
++    PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(obj);
++
++    object_unref(OBJECT(pr_mgr->ioc));
++    qemu_mutex_destroy(&pr_mgr->lock);
++}
++
++static void pr_manager_helper_instance_init(Object *obj)
++{
++    PRManagerHelper *pr_mgr = PR_MANAGER_HELPER(obj);
++
++    qemu_mutex_init(&pr_mgr->lock);
++}
++
++static void pr_manager_helper_class_init(ObjectClass *klass,
++                                         void *class_data G_GNUC_UNUSED)
++{
++    PRManagerClass *prmgr_klass = PR_MANAGER_CLASS(klass);
++    UserCreatableClass *uc_klass = USER_CREATABLE_CLASS(klass);
++
++    object_class_property_add_str(klass, "path", get_path, set_path,
++                                  &error_abort);
++    uc_klass->complete = pr_manager_helper_complete;
++    prmgr_klass->run = pr_manager_helper_run;
++}
++
++static const TypeInfo pr_manager_helper_info = {
++    .parent = TYPE_PR_MANAGER,
++    .name = TYPE_PR_MANAGER_HELPER,
++    .instance_size = sizeof(PRManagerHelper),
++    .instance_init = pr_manager_helper_instance_init,
++    .instance_finalize = pr_manager_helper_instance_finalize,
++    .class_init = pr_manager_helper_class_init,
++};
++
++static void pr_manager_helper_register_types(void)
++{
++    type_register_static(&pr_manager_helper_info);
++}
++
++type_init(pr_manager_helper_register_types);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-block-Add-share-rw-option.patch b/SOURCES/kvm-scsi-block-Add-share-rw-option.patch
new file mode 100644
index 0000000..0be10b5
--- /dev/null
+++ b/SOURCES/kvm-scsi-block-Add-share-rw-option.patch
@@ -0,0 +1,44 @@
+From cd8403ec12e9ee21ebe61894e3a57e806c190956 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Wed, 17 Jan 2018 06:08:33 +0100
+Subject: [PATCH 03/21] scsi-block: Add share-rw option
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20180117060834.17481-2-famz@redhat.com>
+Patchwork-id: 78653
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/2] scsi-block: Add share-rw option
+Bugzilla: 1518482
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+Scsi-block doesn't use the DEFINE_BLOCK_PROPERTIES() macro so it didn't
+gain the share-rw back when it was added to all other storage devices.
+This option is meaningful here, and need to be used when attaching a
+shared storage to guest.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-Id: <20171205071928.30242-1-famz@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 07488549f884a658689370b9ef878dc50eced83e)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-disk.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
+index 8a63377..c676355 100644
+--- a/hw/scsi/scsi-disk.c
++++ b/hw/scsi/scsi-disk.c
+@@ -2992,6 +2992,7 @@ static const TypeInfo scsi_cd_info = {
+ #ifdef __linux__
+ 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_END_OF_LIST(),
+ };
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-build-qemu-pr-helper.patch b/SOURCES/kvm-scsi-build-qemu-pr-helper.patch
new file mode 100644
index 0000000..f175fe5
--- /dev/null
+++ b/SOURCES/kvm-scsi-build-qemu-pr-helper.patch
@@ -0,0 +1,1024 @@
+From c3ce9144a1f76102f51bef7909eac5b2ba4bd777 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:49 +0100
+Subject: [PATCH 23/36] scsi: build qemu-pr-helper
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-14-pbonzini@redhat.com>
+Patchwork-id: 78089
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 13/17] scsi: build qemu-pr-helper
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Introduce a privileged helper to run persistent reservation commands.
+This lets virtual machines send persistent reservations without using
+CAP_SYS_RAWIO or out-of-tree patches.  The helper uses Unix permissions
+and SCM_RIGHTS to restrict access to processes that can access its socket
+and prove that they have an open file descriptor for a raw SCSI device.
+
+The next patch will also correct the usage of persistent reservations
+with multipath devices.
+
+It would also be possible to support for Linux's IOC_PR_* ioctls in
+the future, to support NVMe devices.  For now, however, only SCSI is
+supported.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit b855f8d175a0a26c9798cbc5962bb8c0d9538231)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ Makefile                   |   4 +-
+ configure                  |  14 +-
+ docs/interop/pr-helper.rst |  83 +++++
+ docs/pr-manager.rst        |  33 ++
+ scsi/pr-helper.h           |  41 +++
+ scsi/qemu-pr-helper.c      | 735 +++++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 905 insertions(+), 5 deletions(-)
+ create mode 100644 docs/interop/pr-helper.rst
+ create mode 100644 scsi/pr-helper.h
+ create mode 100644 scsi/qemu-pr-helper.c
+
+diff --git a/Makefile b/Makefile
+index 1a773a8..3e76953 100644
+--- a/Makefile
++++ b/Makefile
+@@ -386,6 +386,8 @@ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
+ fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o $(COMMON_LDADDS)
+ fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
+ 
++scsi/qemu-pr-helper$(EXESUF): scsi/qemu-pr-helper.o scsi/utils.o $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
++
+ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
+ 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"GEN","$@")
+ 
+@@ -493,7 +495,7 @@ clean:
+ 	rm -f *.msi
+ 	find . \( -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
+ 	rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
+-	rm -f fsdev/*.pod
++	rm -f fsdev/*.pod scsi/*.pod
+ 	rm -f qemu-img-cmds.h
+ 	rm -f ui/shader/*-vert.h ui/shader/*-frag.h
+ 	@# May not be present in GENERATED_FILES
+diff --git a/configure b/configure
+index 644e52d..2df1b42 100755
+--- a/configure
++++ b/configure
+@@ -5065,16 +5065,22 @@ if test "$want_tools" = "yes" ; then
+   fi
+ fi
+ if test "$softmmu" = yes ; then
+-  if test "$virtfs" != no ; then
+-    if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
++  if test "$linux" = yes; then
++    if test "$virtfs" != no && test "$cap" = yes && test "$attr" = yes ; then
+       virtfs=yes
+       tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
+     else
+       if test "$virtfs" = yes; then
+-        error_exit "VirtFS is supported only on Linux and requires libcap devel and libattr devel"
++        error_exit "VirtFS requires libcap devel and libattr devel"
+       fi
+       virtfs=no
+     fi
++    tools="$tools scsi/qemu-pr-helper\$(EXESUF)"
++  else
++    if test "$virtfs" = yes; then
++      error_exit "VirtFS is supported only on Linux"
++    fi
++    virtfs=no
+   fi
+ fi
+ 
+@@ -6562,7 +6568,7 @@ fi
+ 
+ # build tree in object directory in case the source is not in the current directory
+ DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
+-DIRS="$DIRS docs docs/interop fsdev"
++DIRS="$DIRS docs docs/interop fsdev scsi"
+ DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
+ DIRS="$DIRS roms/seabios roms/vgabios"
+ DIRS="$DIRS qapi-generated"
+diff --git a/docs/interop/pr-helper.rst b/docs/interop/pr-helper.rst
+new file mode 100644
+index 0000000..9f76d5b
+--- /dev/null
++++ b/docs/interop/pr-helper.rst
+@@ -0,0 +1,83 @@
++..
++
++======================================
++Persistent reservation helper protocol
++======================================
++
++QEMU's SCSI passthrough devices, ``scsi-block`` and ``scsi-generic``,
++can delegate implementation of persistent reservations to an external
++(and typically privileged) program.  Persistent Reservations allow
++restricting access to block devices to specific initiators in a shared
++storage setup.
++
++For a more detailed reference please refer the the SCSI Primary
++Commands standard, specifically the section on Reservations and the
++"PERSISTENT RESERVE IN" and "PERSISTENT RESERVE OUT" commands.
++
++This document describes the socket protocol used between QEMU's
++``pr-manager-helper`` object and the external program.
++
++.. contents::
++
++Connection and initialization
++-----------------------------
++
++All data transmitted on the socket is big-endian.
++
++After connecting to the helper program's socket, the helper starts a simple
++feature negotiation process by writing four bytes corresponding to
++the features it exposes (``supported_features``).  QEMU reads it,
++then writes four bytes corresponding to the desired features of the
++helper program (``requested_features``).
++
++If a bit is 1 in ``requested_features`` and 0 in ``supported_features``,
++the corresponding feature is not supported by the helper and the connection
++is closed.  On the other hand, it is acceptable for a bit to be 0 in
++``requested_features`` and 1 in ``supported_features``; in this case,
++the helper will not enable the feature.
++
++Right now no feature is defined, so the two parties always write four
++zero bytes.
++
++Command format
++--------------
++
++It is invalid to send multiple commands concurrently on the same
++socket.  It is however possible to connect multiple sockets to the
++helper and send multiple commands to the helper for one or more
++file descriptors.
++
++A command consists of a request and a response.  A request consists
++of a 16-byte SCSI CDB.  A file descriptor must be passed to the helper
++together with the SCSI CDB using ancillary data.
++
++The CDB has the following limitations:
++
++- the command (stored in the first byte) must be one of 0x5E
++  (PERSISTENT RESERVE IN) or 0x5F (PERSISTENT RESERVE OUT).
++
++- the allocation length (stored in bytes 7-8 of the CDB for PERSISTENT
++  RESERVE IN) or parameter list length (stored in bytes 5-8 of the CDB
++  for PERSISTENT RESERVE OUT) is limited to 8 KiB.
++
++For PERSISTENT RESERVE OUT, the parameter list is sent right after the
++CDB.  The length of the parameter list is taken from the CDB itself.
++
++The helper's reply has the following structure:
++
++- 4 bytes for the SCSI status
++
++- 4 bytes for the payload size (nonzero only for PERSISTENT RESERVE IN
++  and only if the SCSI status is 0x00, i.e. GOOD)
++
++- 96 bytes for the SCSI sense data
++
++- if the size is nonzero, the payload follows
++
++The sense data is always sent to keep the protocol simple, even though
++it is only valid if the SCSI status is CHECK CONDITION (0x02).
++
++The payload size is always less than or equal to the allocation length
++specified in the CDB for the PERSISTENT RESERVE IN command.
++
++If the protocol is violated, the helper closes the socket.
+diff --git a/docs/pr-manager.rst b/docs/pr-manager.rst
+index b6089fb..7107e59 100644
+--- a/docs/pr-manager.rst
++++ b/docs/pr-manager.rst
+@@ -49,3 +49,36 @@ Alternatively, using ``-blockdev``::
+           -object pr-manager-helper,id=helper0,path=/var/run/qemu-pr-helper.sock
+           -blockdev node-name=hd,driver=raw,file.driver=host_device,file.filename=/dev/sdb,file.pr-manager=helper0
+           -device scsi-block,drive=hd
++
++----------------------------------
++Invoking :program:`qemu-pr-helper`
++----------------------------------
++
++QEMU provides an implementation of the persistent reservation helper,
++called :program:`qemu-pr-helper`.  The helper should be started as a
++system service and supports the following option:
++
++-d, --daemon              run in the background
++-q, --quiet               decrease verbosity
++-f, --pidfile=path        PID file when running as a daemon
++-k, --socket=path         path to the socket
++-T, --trace=trace-opts    tracing options
++
++By default, the socket and PID file are placed in the runtime state
++directory, for example :file:`/var/run/qemu-pr-helper.sock` and
++:file:`/var/run/qemu-pr-helper.pid`.  The PID file is not created
++unless :option:`-d` is passed too.
++
++:program:`qemu-pr-helper` can also use the systemd socket activation
++protocol.  In this case, the systemd socket unit should specify a
++Unix stream socket, like this::
++
++    [Socket]
++    ListenStream=/var/run/qemu-pr-helper.sock
++
++After connecting to the socket, :program:`qemu-pr-helper`` can optionally drop
++root privileges, except for those capabilities that are needed for
++its operation.  To do this, add the following options:
++
++-u, --user=user           user to drop privileges to
++-g, --group=group         group to drop privileges to
+diff --git a/scsi/pr-helper.h b/scsi/pr-helper.h
+new file mode 100644
+index 0000000..96c50a9
+--- /dev/null
++++ b/scsi/pr-helper.h
+@@ -0,0 +1,41 @@
++/* Definitions for QEMU's persistent reservation helper daemon
++ *
++ * Copyright (C) 2017 Red Hat, Inc.
++ *
++ * Author:
++ *   Paolo Bonzini <pbonzini@redhat.com>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
++ * IN THE SOFTWARE.
++ */
++#ifndef QEMU_PR_HELPER_H
++#define QEMU_PR_HELPER_H 1
++
++#include <stdint.h>
++
++#define PR_HELPER_CDB_SIZE     16
++#define PR_HELPER_SENSE_SIZE   96
++#define PR_HELPER_DATA_SIZE    8192
++
++typedef struct PRHelperResponse {
++    int32_t result;
++    int32_t sz;
++    uint8_t sense[PR_HELPER_SENSE_SIZE];
++} PRHelperResponse;
++
++#endif
+diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
+new file mode 100644
+index 0000000..f46266f
+--- /dev/null
++++ b/scsi/qemu-pr-helper.c
+@@ -0,0 +1,735 @@
++/*
++ * Privileged helper to handle persistent reservation commands for QEMU
++ *
++ * Copyright (C) 2017 Red Hat, Inc. <pbonzini@redhat.com>
++ *
++ * Author: Paolo Bonzini <pbonzini@redhat.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; under version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "qemu/osdep.h"
++#include <getopt.h>
++#include <sys/ioctl.h>
++#include <linux/dm-ioctl.h>
++#include <scsi/sg.h>
++
++#ifdef CONFIG_LIBCAP
++#include <cap-ng.h>
++#endif
++#include <pwd.h>
++#include <grp.h>
++
++#include "qapi/error.h"
++#include "qemu-common.h"
++#include "qemu/cutils.h"
++#include "qemu/main-loop.h"
++#include "qemu/error-report.h"
++#include "qemu/config-file.h"
++#include "qemu/bswap.h"
++#include "qemu/log.h"
++#include "qemu/systemd.h"
++#include "qapi/util.h"
++#include "qapi/qmp/qstring.h"
++#include "io/channel-socket.h"
++#include "trace/control.h"
++#include "qemu-version.h"
++
++#include "block/aio.h"
++#include "block/thread-pool.h"
++
++#include "scsi/constants.h"
++#include "scsi/utils.h"
++#include "pr-helper.h"
++
++#define PR_OUT_FIXED_PARAM_SIZE 24
++
++static char *socket_path;
++static char *pidfile;
++static enum { RUNNING, TERMINATE, TERMINATING } state;
++static QIOChannelSocket *server_ioc;
++static int server_watch;
++static int num_active_sockets = 1;
++static int verbose;
++
++#ifdef CONFIG_LIBCAP
++static int uid = -1;
++static int gid = -1;
++#endif
++
++static void usage(const char *name)
++{
++    (printf) (
++"Usage: %s [OPTIONS] FILE\n"
++"Persistent Reservation helper program for QEMU\n"
++"\n"
++"  -h, --help                display this help and exit\n"
++"  -V, --version             output version information and exit\n"
++"\n"
++"  -d, --daemon              run in the background\n"
++"  -f, --pidfile=PATH        PID file when running as a daemon\n"
++"                            (default '%s')\n"
++"  -k, --socket=PATH         path to the unix socket\n"
++"                            (default '%s')\n"
++"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
++"                            specify tracing options\n"
++#ifdef CONFIG_LIBCAP
++"  -u, --user=USER           user to drop privileges to\n"
++"  -g, --group=GROUP         group to drop privileges to\n"
++#endif
++"\n"
++QEMU_HELP_BOTTOM "\n"
++    , name, pidfile, socket_path);
++}
++
++static void version(const char *name)
++{
++    printf(
++"%s " QEMU_VERSION QEMU_PKGVERSION "\n"
++"Written by Paolo Bonzini.\n"
++"\n"
++QEMU_COPYRIGHT "\n"
++"This is free software; see the source for copying conditions.  There is NO\n"
++"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
++    , name);
++}
++
++static void write_pidfile(void)
++{
++    int pidfd;
++    char pidstr[32];
++
++    pidfd = qemu_open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
++    if (pidfd == -1) {
++        error_report("Cannot open pid file, %s", strerror(errno));
++        exit(EXIT_FAILURE);
++    }
++
++    if (lockf(pidfd, F_TLOCK, 0)) {
++        error_report("Cannot lock pid file, %s", strerror(errno));
++        goto fail;
++    }
++    if (ftruncate(pidfd, 0)) {
++        error_report("Failed to truncate pid file");
++        goto fail;
++    }
++
++    snprintf(pidstr, sizeof(pidstr), "%d\n", getpid());
++    if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
++        error_report("Failed to write pid file");
++        goto fail;
++    }
++    return;
++
++fail:
++    unlink(pidfile);
++    close(pidfd);
++    exit(EXIT_FAILURE);
++}
++
++/* SG_IO support */
++
++typedef struct PRHelperSGIOData {
++    int fd;
++    const uint8_t *cdb;
++    uint8_t *sense;
++    uint8_t *buf;
++    int sz;              /* input/output */
++    int dir;
++} PRHelperSGIOData;
++
++static int do_sgio_worker(void *opaque)
++{
++    PRHelperSGIOData *data = opaque;
++    struct sg_io_hdr io_hdr;
++    int ret;
++    int status;
++    SCSISense sense_code;
++
++    memset(data->sense, 0, PR_HELPER_SENSE_SIZE);
++    memset(&io_hdr, 0, sizeof(io_hdr));
++    io_hdr.interface_id = 'S';
++    io_hdr.cmd_len = PR_HELPER_CDB_SIZE;
++    io_hdr.cmdp = (uint8_t *)data->cdb;
++    io_hdr.sbp = data->sense;
++    io_hdr.mx_sb_len = PR_HELPER_SENSE_SIZE;
++    io_hdr.timeout = 1;
++    io_hdr.dxfer_direction = data->dir;
++    io_hdr.dxferp = (char *)data->buf;
++    io_hdr.dxfer_len = data->sz;
++    ret = ioctl(data->fd, SG_IO, &io_hdr);
++    status = sg_io_sense_from_errno(ret < 0 ? errno : 0, &io_hdr,
++                                    &sense_code);
++    if (status == GOOD) {
++        data->sz -= io_hdr.resid;
++    } else {
++        data->sz = 0;
++    }
++
++    if (status == CHECK_CONDITION &&
++        !(io_hdr.driver_status & SG_ERR_DRIVER_SENSE)) {
++        scsi_build_sense(data->sense, sense_code);
++    }
++
++    return status;
++}
++
++static int do_sgio(int fd, const uint8_t *cdb, uint8_t *sense,
++                    uint8_t *buf, int *sz, int dir)
++{
++    ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
++    int r;
++
++    PRHelperSGIOData data = {
++        .fd = fd,
++        .cdb = cdb,
++        .sense = sense,
++        .buf = buf,
++        .sz = *sz,
++        .dir = dir,
++    };
++
++    r = thread_pool_submit_co(pool, do_sgio_worker, &data);
++    *sz = data.sz;
++    return r;
++}
++
++static int do_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
++                    uint8_t *data, int *resp_sz)
++{
++    return do_sgio(fd, cdb, sense, data, resp_sz,
++                   SG_DXFER_FROM_DEV);
++}
++
++static int do_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
++                     const uint8_t *param, int sz)
++{
++    int resp_sz = sz;
++    return do_sgio(fd, cdb, sense, (uint8_t *)param, &resp_sz,
++                   SG_DXFER_TO_DEV);
++}
++
++/* Client */
++
++typedef struct PRHelperClient {
++    QIOChannelSocket *ioc;
++    Coroutine *co;
++    int fd;
++    uint8_t data[PR_HELPER_DATA_SIZE];
++} PRHelperClient;
++
++typedef struct PRHelperRequest {
++    int fd;
++    size_t sz;
++    uint8_t cdb[PR_HELPER_CDB_SIZE];
++} PRHelperRequest;
++
++static int coroutine_fn prh_read(PRHelperClient *client, void *buf, int sz,
++                                 Error **errp)
++{
++    int ret = 0;
++
++    while (sz > 0) {
++        int *fds = NULL;
++        size_t nfds = 0;
++        int i;
++        struct iovec iov;
++        ssize_t n_read;
++
++        iov.iov_base = buf;
++        iov.iov_len = sz;
++        n_read = qio_channel_readv_full(QIO_CHANNEL(client->ioc), &iov, 1,
++                                        &fds, &nfds, errp);
++
++        if (n_read == QIO_CHANNEL_ERR_BLOCK) {
++            qio_channel_yield(QIO_CHANNEL(client->ioc), G_IO_IN);
++            continue;
++        }
++        if (n_read <= 0) {
++            ret = n_read ? n_read : -1;
++            goto err;
++        }
++
++        /* Stash one file descriptor per request.  */
++        if (nfds) {
++            bool too_many = false;
++            for (i = 0; i < nfds; i++) {
++                if (client->fd == -1) {
++                    client->fd = fds[i];
++                } else {
++                    close(fds[i]);
++                    too_many = true;
++                }
++            }
++            g_free(fds);
++            if (too_many) {
++                ret = -1;
++                goto err;
++            }
++        }
++
++        buf += n_read;
++        sz -= n_read;
++    }
++
++    return 0;
++
++err:
++    if (client->fd != -1) {
++        close(client->fd);
++        client->fd = -1;
++    }
++    return ret;
++}
++
++static int coroutine_fn prh_read_request(PRHelperClient *client,
++                                         PRHelperRequest *req,
++                                         PRHelperResponse *resp, Error **errp)
++{
++    uint32_t sz;
++
++    if (prh_read(client, req->cdb, sizeof(req->cdb), NULL) < 0) {
++        return -1;
++    }
++
++    if (client->fd == -1) {
++        error_setg(errp, "No file descriptor in request.");
++        return -1;
++    }
++
++    if (req->cdb[0] != PERSISTENT_RESERVE_OUT &&
++        req->cdb[0] != PERSISTENT_RESERVE_IN) {
++        error_setg(errp, "Invalid CDB, closing socket.");
++        goto out_close;
++    }
++
++    sz = scsi_cdb_xfer(req->cdb);
++    if (sz > sizeof(client->data)) {
++        goto out_close;
++    }
++
++    if (req->cdb[0] == PERSISTENT_RESERVE_OUT) {
++        if (qio_channel_read_all(QIO_CHANNEL(client->ioc),
++                                 (char *)client->data, sz,
++                                 errp) < 0) {
++            goto out_close;
++        }
++        if ((fcntl(client->fd, F_GETFL) & O_ACCMODE) == O_RDONLY) {
++            scsi_build_sense(resp->sense, SENSE_CODE(INVALID_OPCODE));
++            sz = 0;
++        } else if (sz < PR_OUT_FIXED_PARAM_SIZE) {
++            /* Illegal request, Parameter list length error.  This isn't fatal;
++             * we have read the data, send an error without closing the socket.
++             */
++            scsi_build_sense(resp->sense, SENSE_CODE(INVALID_PARAM_LEN));
++            sz = 0;
++        }
++        if (sz == 0) {
++            resp->result = CHECK_CONDITION;
++            close(client->fd);
++            client->fd = -1;
++        }
++    }
++
++    req->fd = client->fd;
++    req->sz = sz;
++    client->fd = -1;
++    return sz;
++
++out_close:
++    close(client->fd);
++    client->fd = -1;
++    return -1;
++}
++
++static int coroutine_fn prh_write_response(PRHelperClient *client,
++                                           PRHelperRequest *req,
++                                           PRHelperResponse *resp, Error **errp)
++{
++    ssize_t r;
++    size_t sz;
++
++    if (req->cdb[0] == PERSISTENT_RESERVE_IN && resp->result == GOOD) {
++        assert(resp->sz <= req->sz && resp->sz <= sizeof(client->data));
++    } else {
++        assert(resp->sz == 0);
++    }
++
++    sz = resp->sz;
++
++    resp->result = cpu_to_be32(resp->result);
++    resp->sz = cpu_to_be32(resp->sz);
++    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
++                              (char *) resp, sizeof(*resp), errp);
++    if (r < 0) {
++        return r;
++    }
++
++    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
++                              (char *) client->data,
++                              sz, errp);
++    return r < 0 ? r : 0;
++}
++
++static void coroutine_fn prh_co_entry(void *opaque)
++{
++    PRHelperClient *client = opaque;
++    Error *local_err = NULL;
++    uint32_t flags;
++    int r;
++
++    qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
++                             false, NULL);
++    qio_channel_attach_aio_context(QIO_CHANNEL(client->ioc),
++                                   qemu_get_aio_context());
++
++    /* A very simple negotiation for future extensibility.  No features
++     * are defined so write 0.
++     */
++    flags = cpu_to_be32(0);
++    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
++                             (char *) &flags, sizeof(flags), NULL);
++    if (r < 0) {
++        goto out;
++    }
++
++    r = qio_channel_read_all(QIO_CHANNEL(client->ioc),
++                             (char *) &flags, sizeof(flags), NULL);
++    if (be32_to_cpu(flags) != 0 || r < 0) {
++        goto out;
++    }
++
++    while (atomic_read(&state) == RUNNING) {
++        PRHelperRequest req;
++        PRHelperResponse resp;
++        int sz;
++
++        sz = prh_read_request(client, &req, &resp, &local_err);
++        if (sz < 0) {
++            break;
++        }
++
++        if (sz > 0) {
++            num_active_sockets++;
++            if (req.cdb[0] == PERSISTENT_RESERVE_OUT) {
++                r = do_pr_out(req.fd, req.cdb, resp.sense,
++                              client->data, sz);
++                resp.sz = 0;
++            } else {
++                resp.sz = sizeof(client->data);
++                r = do_pr_in(req.fd, req.cdb, resp.sense,
++                             client->data, &resp.sz);
++                resp.sz = MIN(resp.sz, sz);
++            }
++            num_active_sockets--;
++            close(req.fd);
++            if (r == -1) {
++                break;
++            }
++            resp.result = r;
++        }
++
++        if (prh_write_response(client, &req, &resp, &local_err) < 0) {
++            break;
++        }
++    }
++
++    if (local_err) {
++        if (verbose == 0) {
++            error_free(local_err);
++        } else {
++            error_report_err(local_err);
++        }
++    }
++
++out:
++    qio_channel_detach_aio_context(QIO_CHANNEL(client->ioc));
++    object_unref(OBJECT(client->ioc));
++    g_free(client);
++}
++
++static gboolean accept_client(QIOChannel *ioc, GIOCondition cond, gpointer opaque)
++{
++    QIOChannelSocket *cioc;
++    PRHelperClient *prh;
++
++    cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
++                                     NULL);
++    if (!cioc) {
++        return TRUE;
++    }
++
++    prh = g_new(PRHelperClient, 1);
++    prh->ioc = cioc;
++    prh->fd = -1;
++    prh->co = qemu_coroutine_create(prh_co_entry, prh);
++    qemu_coroutine_enter(prh->co);
++
++    return TRUE;
++}
++
++
++/*
++ * Check socket parameters compatibility when socket activation is used.
++ */
++static const char *socket_activation_validate_opts(void)
++{
++    if (socket_path != NULL) {
++        return "Unix socket can't be set when using socket activation";
++    }
++
++    return NULL;
++}
++
++static void compute_default_paths(void)
++{
++    if (!socket_path) {
++        socket_path = qemu_get_local_state_pathname("run/qemu-pr-helper.sock");
++    }
++}
++
++static void termsig_handler(int signum)
++{
++    atomic_cmpxchg(&state, RUNNING, TERMINATE);
++    qemu_notify_event();
++}
++
++static void close_server_socket(void)
++{
++    assert(server_ioc);
++
++    g_source_remove(server_watch);
++    server_watch = -1;
++    object_unref(OBJECT(server_ioc));
++    num_active_sockets--;
++}
++
++#ifdef CONFIG_LIBCAP
++static int drop_privileges(void)
++{
++    /* clear all capabilities */
++    capng_clear(CAPNG_SELECT_BOTH);
++
++    if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
++                     CAP_SYS_RAWIO) < 0) {
++        return -1;
++    }
++
++    /* Change user/group id, retaining the capabilities.  Because file descriptors
++     * are passed via SCM_RIGHTS, we don't need supplementary groups (and in
++     * fact the helper can run as "nobody").
++     */
++    if (capng_change_id(uid != -1 ? uid : getuid(),
++                        gid != -1 ? gid : getgid(),
++                        CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) {
++        return -1;
++    }
++
++    return 0;
++}
++#endif
++
++int main(int argc, char **argv)
++{
++    const char *sopt = "hVk:fdT:u:g:q";
++    struct option lopt[] = {
++        { "help", no_argument, NULL, 'h' },
++        { "version", no_argument, NULL, 'V' },
++        { "socket", required_argument, NULL, 'k' },
++        { "pidfile", no_argument, NULL, 'f' },
++        { "daemon", no_argument, NULL, 'd' },
++        { "trace", required_argument, NULL, 'T' },
++        { "user", required_argument, NULL, 'u' },
++        { "group", required_argument, NULL, 'g' },
++        { "quiet", no_argument, NULL, 'q' },
++        { NULL, 0, NULL, 0 }
++    };
++    int opt_ind = 0;
++    int quiet = 0;
++    int ch;
++    Error *local_err = NULL;
++    char *trace_file = NULL;
++    bool daemonize = false;
++    unsigned socket_activation;
++
++    struct sigaction sa_sigterm;
++    memset(&sa_sigterm, 0, sizeof(sa_sigterm));
++    sa_sigterm.sa_handler = termsig_handler;
++    sigaction(SIGTERM, &sa_sigterm, NULL);
++    sigaction(SIGINT, &sa_sigterm, NULL);
++    sigaction(SIGHUP, &sa_sigterm, NULL);
++
++    signal(SIGPIPE, SIG_IGN);
++
++    module_call_init(MODULE_INIT_TRACE);
++    module_call_init(MODULE_INIT_QOM);
++    qemu_add_opts(&qemu_trace_opts);
++    qemu_init_exec_dir(argv[0]);
++
++    pidfile = qemu_get_local_state_pathname("run/qemu-pr-helper.pid");
++
++    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
++        switch (ch) {
++        case 'k':
++            socket_path = optarg;
++            if (socket_path[0] != '/') {
++                error_report("socket path must be absolute");
++                exit(EXIT_FAILURE);
++            }
++            break;
++        case 'f':
++            pidfile = optarg;
++            break;
++#ifdef CONFIG_LIBCAP
++        case 'u': {
++            unsigned long res;
++            struct passwd *userinfo = getpwnam(optarg);
++            if (userinfo) {
++                uid = userinfo->pw_uid;
++            } else if (qemu_strtoul(optarg, NULL, 10, &res) == 0 &&
++                       (uid_t)res == res) {
++                uid = res;
++            } else {
++                error_report("invalid user '%s'", optarg);
++                exit(EXIT_FAILURE);
++            }
++            break;
++        }
++        case 'g': {
++            unsigned long res;
++            struct group *groupinfo = getgrnam(optarg);
++            if (groupinfo) {
++                gid = groupinfo->gr_gid;
++            } else if (qemu_strtoul(optarg, NULL, 10, &res) == 0 &&
++                       (gid_t)res == res) {
++                gid = res;
++            } else {
++                error_report("invalid group '%s'", optarg);
++                exit(EXIT_FAILURE);
++            }
++            break;
++        }
++#else
++        case 'u':
++        case 'g':
++            error_report("-%c not supported by this %s", ch, argv[0]);
++            exit(1);
++#endif
++        case 'd':
++            daemonize = true;
++            break;
++        case 'q':
++            quiet = 1;
++            break;
++        case 'T':
++            g_free(trace_file);
++            trace_file = trace_opt_parse(optarg);
++            break;
++        case 'V':
++            version(argv[0]);
++            exit(EXIT_SUCCESS);
++            break;
++        case 'h':
++            usage(argv[0]);
++            exit(EXIT_SUCCESS);
++            break;
++        case '?':
++            error_report("Try `%s --help' for more information.", argv[0]);
++            exit(EXIT_FAILURE);
++        }
++    }
++
++    /* set verbosity */
++    verbose = !quiet;
++
++    if (!trace_init_backends()) {
++        exit(EXIT_FAILURE);
++    }
++    trace_init_file(trace_file);
++    qemu_set_log(LOG_TRACE);
++
++    socket_activation = check_socket_activation();
++    if (socket_activation == 0) {
++        SocketAddress saddr;
++        compute_default_paths();
++        saddr = (SocketAddress){
++            .type = SOCKET_ADDRESS_TYPE_UNIX,
++            .u.q_unix.path = g_strdup(socket_path)
++        };
++        server_ioc = qio_channel_socket_new();
++        if (qio_channel_socket_listen_sync(server_ioc, &saddr, &local_err) < 0) {
++            object_unref(OBJECT(server_ioc));
++            error_report_err(local_err);
++            return 1;
++        }
++        g_free(saddr.u.q_unix.path);
++    } else {
++        /* Using socket activation - check user didn't use -p etc. */
++        const char *err_msg = socket_activation_validate_opts();
++        if (err_msg != NULL) {
++            error_report("%s", err_msg);
++            exit(EXIT_FAILURE);
++        }
++
++        /* Can only listen on a single socket.  */
++        if (socket_activation > 1) {
++            error_report("%s does not support socket activation with LISTEN_FDS > 1",
++                         argv[0]);
++            exit(EXIT_FAILURE);
++        }
++        server_ioc = qio_channel_socket_new_fd(FIRST_SOCKET_ACTIVATION_FD,
++                                               &local_err);
++        if (server_ioc == NULL) {
++            error_report("Failed to use socket activation: %s",
++                         error_get_pretty(local_err));
++            exit(EXIT_FAILURE);
++        }
++        socket_path = NULL;
++    }
++
++    if (qemu_init_main_loop(&local_err)) {
++        error_report_err(local_err);
++        exit(EXIT_FAILURE);
++    }
++
++    server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc),
++                                         G_IO_IN,
++                                         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);
++        }
++        write_pidfile();
++    }
++
++    state = RUNNING;
++    do {
++        main_loop_wait(false);
++        if (state == TERMINATE) {
++            state = TERMINATING;
++            close_server_socket();
++        }
++    } while (num_active_sockets > 0);
++
++    exit(EXIT_SUCCESS);
++}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-bus-correct-responses-for-INQUIRY-and-REQUEST-S.patch b/SOURCES/kvm-scsi-bus-correct-responses-for-INQUIRY-and-REQUEST-S.patch
new file mode 100644
index 0000000..2eb1c37
--- /dev/null
+++ b/SOURCES/kvm-scsi-bus-correct-responses-for-INQUIRY-and-REQUEST-S.patch
@@ -0,0 +1,84 @@
+From 23f2b51d8b3d7734718eb2f9b109cb9090f1484e Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:39 +0100
+Subject: [PATCH 13/36] scsi-bus: correct responses for INQUIRY and REQUEST
+ SENSE
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-4-pbonzini@redhat.com>
+Patchwork-id: 78085
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 03/17] scsi-bus: correct responses for INQUIRY and REQUEST SENSE
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Hannes Reinecke <hare@suse.de>
+
+According to SPC-3 INQUIRY and REQUEST SENSE should return GOOD
+even on unsupported LUNS.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Message-Id: <1503049022-14749-1-git-send-email-hare@suse.de>
+Reported-by: Laszlo Ersek <lersek@redhat.com>
+Fixes: ded6ddc5a7b95217557fa360913d1213e12d4a6d
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit b07fbce6349c7b84642e7ed56c7a1ac3c1caca61)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-bus.c | 29 +++++++++++++++++++++++++----
+ 1 file changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 404686a..55aa5a7 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -524,8 +524,10 @@ static size_t scsi_sense_len(SCSIRequest *req)
+ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
+ {
+     SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
++    int fixed_sense = (req->cmd.buf[1] & 1) == 0;
+ 
+-    if (req->lun != 0) {
++    if (req->lun != 0 &&
++        buf[0] != INQUIRY && buf[0] != REQUEST_SENSE) {
+         scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
+         scsi_req_complete(req, CHECK_CONDITION);
+         return 0;
+@@ -543,9 +545,28 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
+         break;
+     case REQUEST_SENSE:
+         scsi_target_alloc_buf(&r->req, scsi_sense_len(req));
+-        r->len = scsi_device_get_sense(r->req.dev, r->buf,
+-                                       MIN(req->cmd.xfer, r->buf_len),
+-                                       (req->cmd.buf[1] & 1) == 0);
++        if (req->lun != 0) {
++            const struct SCSISense sense = SENSE_CODE(LUN_NOT_SUPPORTED);
++
++            if (fixed_sense) {
++                r->buf[0] = 0x70;
++                r->buf[2] = sense.key;
++                r->buf[10] = 10;
++                r->buf[12] = sense.asc;
++                r->buf[13] = sense.ascq;
++                r->len = MIN(req->cmd.xfer, SCSI_SENSE_LEN);
++            } else {
++                r->buf[0] = 0x72;
++                r->buf[1] = sense.key;
++                r->buf[2] = sense.asc;
++                r->buf[3] = sense.ascq;
++                r->len = 8;
++            }
++        } else {
++            r->len = scsi_device_get_sense(r->req.dev, r->buf,
++                                           MIN(req->cmd.xfer, r->buf_len),
++                                           fixed_sense);
++        }
+         if (r->req.dev->sense_is_ua) {
+             scsi_device_unit_attention_reported(req->dev);
+             r->req.dev->sense_len = 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-disk-release-AioContext-in-unaligned-WRITE-SAME.patch b/SOURCES/kvm-scsi-disk-release-AioContext-in-unaligned-WRITE-SAME.patch
new file mode 100644
index 0000000..10c93f9
--- /dev/null
+++ b/SOURCES/kvm-scsi-disk-release-AioContext-in-unaligned-WRITE-SAME.patch
@@ -0,0 +1,54 @@
+From 81bdf75b893c852a9daae615b4ab41106eb364db Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Thu, 18 Jan 2018 12:12:04 +0100
+Subject: [PATCH 06/21] scsi-disk: release AioContext in unaligned WRITE SAME
+ case
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20180118121204.17287-2-stefanha@redhat.com>
+Patchwork-id: 78663
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] scsi-disk: release AioContext in unaligned WRITE SAME case
+Bugzilla: 1526423
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+scsi_write_same_complete() can retry the write if the request was
+unaligned.  Make sure to release the AioContext when that code path is
+taken!
+
+This patch fixes a hang when QEMU terminates after an unaligned WRITE
+SAME request has been processed with dataplane.  The hang occurs because
+iothread_stop_all() cannot acquire the AioContext lock that was leaked
+by the IOThread in scsi_write_same_complete().
+
+Fixes: b9e413dd37 ("block: explicitly acquire aiocontext in aio callbacks that need it").
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reported-by: Cong Li <coli@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20180104142502.15175-1-stefanha@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 24355b79bdaf6ab12f7c610b032fc35ec045cd55)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-disk.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
+index c676355..25cbd7b 100644
+--- a/hw/scsi/scsi-disk.c
++++ b/hw/scsi/scsi-disk.c
+@@ -1747,6 +1747,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
+                                        data->sector << BDRV_SECTOR_BITS,
+                                        &data->qiov, 0,
+                                        scsi_write_same_complete, data);
++        aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
+         return;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-disk-support-reporting-of-rotation-rate.patch b/SOURCES/kvm-scsi-disk-support-reporting-of-rotation-rate.patch
new file mode 100644
index 0000000..90ef5bc
--- /dev/null
+++ b/SOURCES/kvm-scsi-disk-support-reporting-of-rotation-rate.patch
@@ -0,0 +1,100 @@
+From 23c1feb875805a4c324c51c3916b249da0edbe02 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 29 Nov 2017 14:26:04 +0100
+Subject: [PATCH 18/21] scsi-disk: support reporting of rotation rate
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171129142606.15965-2-berrange@redhat.com>
+Patchwork-id: 77961
+O-Subject: [PATCH RHV-7.5 qemu-kvm-rhev 1/3] scsi-disk: support reporting of rotation rate
+Bugzilla: 1498042
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+The Linux kernel will query the SCSI "Block device characteristics"
+VPD to determine the rotations per minute of the disk. If this has
+the value 1, it is taken to be an SSD and so Linux sets the
+'rotational' flag to 0 for the I/O queue and will stop using that
+disk as a source of random entropy. Other operating systems may
+also take into account rotation rate when setting up default
+behaviour.
+
+Mgmt apps should be able to set the rotation rate for virtualized
+block devices, based on characteristics of the host storage in use,
+so that the guest OS gets sensible behaviour out of the box. This
+patch thus adds a 'rotation-rate' parameter for 'scsi-hd' and
+'scsi-block' device types. For the latter, this parameter will be
+ignored unless the host device has TYPE_DISK.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Message-Id: <20171004114008.14849-2-berrange@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 070f80095ad5b1143b50d2faffd2b1a84292e00d)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-disk.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
+index 5f1e5e8..21d6b4e 100644
+--- a/hw/scsi/scsi-disk.c
++++ b/hw/scsi/scsi-disk.c
+@@ -104,6 +104,14 @@ typedef struct SCSIDiskState
+     char *product;
+     bool tray_open;
+     bool tray_locked;
++    /*
++     * 0x0000        - rotation rate not reported
++     * 0x0001        - non-rotating medium (SSD)
++     * 0x0002-0x0400 - reserved
++     * 0x0401-0xffe  - rotations per minute
++     * 0xffff        - reserved
++     */
++    uint16_t rotation_rate;
+ } SCSIDiskState;
+ 
+ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed);
+@@ -597,6 +605,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
+             outbuf[buflen++] = 0x83; // device identification
+             if (s->qdev.type == TYPE_DISK) {
+                 outbuf[buflen++] = 0xb0; // block limits
++                outbuf[buflen++] = 0xb1; /* block device characteristics */
+                 outbuf[buflen++] = 0xb2; // thin provisioning
+             }
+             break;
+@@ -739,6 +748,15 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
+             outbuf[43] = max_io_sectors & 0xff;
+             break;
+         }
++        case 0xb1: /* block device characteristics */
++        {
++            buflen = 8;
++            outbuf[4] = (s->rotation_rate >> 8) & 0xff;
++            outbuf[5] = s->rotation_rate & 0xff;
++            outbuf[6] = 0;
++            outbuf[7] = 0;
++            break;
++        }
+         case 0xb2: /* thin provisioning */
+         {
+             buflen = 8;
+@@ -2903,6 +2921,7 @@ static Property scsi_hd_properties[] = {
+                        DEFAULT_MAX_UNMAP_SIZE),
+     DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
+                        DEFAULT_MAX_IO_SIZE),
++    DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
+     DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+@@ -2973,6 +2992,7 @@ static const TypeInfo scsi_cd_info = {
+ #ifdef __linux__
+ static Property scsi_block_properties[] = {
+     DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
++    DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-file-posix-add-support-for-persistent-reservati.patch b/SOURCES/kvm-scsi-file-posix-add-support-for-persistent-reservati.patch
new file mode 100644
index 0000000..30f3912
--- /dev/null
+++ b/SOURCES/kvm-scsi-file-posix-add-support-for-persistent-reservati.patch
@@ -0,0 +1,451 @@
+From f9b538c808178d27af2d4726a8f4b36a305b072b Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:48 +0100
+Subject: [PATCH 22/36] scsi, file-posix: add support for persistent
+ reservation management
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-13-pbonzini@redhat.com>
+Patchwork-id: 78087
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 12/17] scsi, file-posix: add support for persistent reservation management
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+It is a common requirement for virtual machine to send persistent
+reservations, but this currently requires either running QEMU with
+CAP_SYS_RAWIO, or using out-of-tree patches that let an unprivileged
+QEMU bypass Linux's filter on SG_IO commands.
+
+As an alternative mechanism, the next patches will introduce a
+privileged helper to run persistent reservation commands without
+expanding QEMU's attack surface unnecessarily.
+
+The helper is invoked through a "pr-manager" QOM object, to which
+file-posix.c passes SG_IO requests for PERSISTENT RESERVE OUT and
+PERSISTENT RESERVE IN commands.  For example:
+
+  $ qemu-system-x86_64
+      -device virtio-scsi \
+      -object pr-manager-helper,id=helper0,path=/var/run/qemu-pr-helper.sock
+      -drive if=none,id=hd,driver=raw,file.filename=/dev/sdb,file.pr-manager=helper0
+      -device scsi-block,drive=hd
+
+or:
+
+  $ qemu-system-x86_64
+      -device virtio-scsi \
+      -object pr-manager-helper,id=helper0,path=/var/run/qemu-pr-helper.sock
+      -blockdev node-name=hd,driver=raw,file.driver=host_device,file.filename=/dev/sdb,file.pr-manager=helper0
+      -device scsi-block,drive=hd
+
+Multiple pr-manager implementations are conceivable and possible, though
+only one is implemented right now.  For example, a pr-manager could:
+
+- talk directly to the multipath daemon from a privileged QEMU
+  (i.e. QEMU links to libmpathpersist); this makes reservation work
+  properly with multipath, but still requires CAP_SYS_RAWIO
+
+- use the Linux IOC_PR_* ioctls (they require CAP_SYS_ADMIN though)
+
+- more interestingly, implement reservations directly in QEMU
+  through file system locks or a shared database (e.g. sqlite)
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 7c9e527659c67d4d7b41d9504f93d2d7ee482488)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ Makefile.objs             |   1 +
+ block/file-posix.c        |  30 +++++++++++++
+ docs/pr-manager.rst       |  51 ++++++++++++++++++++++
+ include/scsi/pr-manager.h |  56 ++++++++++++++++++++++++
+ qapi/block-core.json      |   4 ++
+ scsi/Makefile.objs        |   2 +
+ scsi/pr-manager.c         | 109 ++++++++++++++++++++++++++++++++++++++++++++++
+ scsi/trace-events         |   3 ++
+ vl.c                      |   3 +-
+ 9 files changed, 258 insertions(+), 1 deletion(-)
+ create mode 100644 docs/pr-manager.rst
+ create mode 100644 include/scsi/pr-manager.h
+ create mode 100644 scsi/pr-manager.c
+ create mode 100644 scsi/trace-events
+
+diff --git a/Makefile.objs b/Makefile.objs
+index f68aa3b..64bebd0 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -168,6 +168,7 @@ trace-events-subdirs += qapi
+ trace-events-subdirs += accel/tcg
+ trace-events-subdirs += accel/kvm
+ trace-events-subdirs += nbd
++trace-events-subdirs += scsi
+ 
+ trace-events-files = $(SRC_PATH)/trace-events $(trace-events-subdirs:%=$(SRC_PATH)/%/trace-events)
+ 
+diff --git a/block/file-posix.c b/block/file-posix.c
+index cb3bfce..9cacf06 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -34,6 +34,9 @@
+ #include "qapi/util.h"
+ #include "qapi/qmp/qstring.h"
+ 
++#include "scsi/pr-manager.h"
++#include "scsi/constants.h"
++
+ #if defined(__APPLE__) && (__MACH__)
+ #include <paths.h>
+ #include <sys/param.h>
+@@ -156,6 +159,8 @@ typedef struct BDRVRawState {
+     bool page_cache_inconsistent:1;
+     bool has_fallocate;
+     bool needs_alignment;
++
++    PRManager *pr_mgr;
+ } BDRVRawState;
+ 
+ typedef struct BDRVRawReopenState {
+@@ -403,6 +408,11 @@ static QemuOptsList raw_runtime_opts = {
+             .type = QEMU_OPT_STRING,
+             .help = "file locking mode (on/off/auto, default: auto)",
+         },
++        {
++            .name = "pr-manager",
++            .type = QEMU_OPT_STRING,
++            .help = "id of persistent reservation manager object (default: none)",
++        },
+         { /* end of list */ }
+     },
+ };
+@@ -414,6 +424,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
+     QemuOpts *opts;
+     Error *local_err = NULL;
+     const char *filename = NULL;
++    const char *str;
+     BlockdevAioOptions aio, aio_default;
+     int fd, ret;
+     struct stat st;
+@@ -475,6 +486,16 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
+         abort();
+     }
+ 
++    str = qemu_opt_get(opts, "pr-manager");
++    if (str) {
++        s->pr_mgr = pr_manager_lookup(str, &local_err);
++        if (local_err) {
++            error_propagate(errp, local_err);
++            ret = -EINVAL;
++            goto fail;
++        }
++    }
++
+     s->open_flags = open_flags;
+     raw_parse_flags(bdrv_flags, &s->open_flags);
+ 
+@@ -2597,6 +2618,15 @@ static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
+     if (fd_open(bs) < 0)
+         return NULL;
+ 
++    if (req == SG_IO && s->pr_mgr) {
++        struct sg_io_hdr *io_hdr = buf;
++        if (io_hdr->cmdp[0] == PERSISTENT_RESERVE_OUT ||
++            io_hdr->cmdp[0] == PERSISTENT_RESERVE_IN) {
++            return pr_manager_execute(s->pr_mgr, bdrv_get_aio_context(bs),
++                                      s->fd, io_hdr, cb, opaque);
++        }
++    }
++
+     acb = g_new(RawPosixAIOData, 1);
+     acb->bs = bs;
+     acb->aio_type = QEMU_AIO_IOCTL;
+diff --git a/docs/pr-manager.rst b/docs/pr-manager.rst
+new file mode 100644
+index 0000000..b6089fb
+--- /dev/null
++++ b/docs/pr-manager.rst
+@@ -0,0 +1,51 @@
++======================================
++Persistent reservation managers
++======================================
++
++SCSI persistent Reservations allow restricting access to block devices
++to specific initiators in a shared storage setup.  When implementing
++clustering of virtual machines, it is a common requirement for virtual
++machines to send persistent reservation SCSI commands.  However,
++the operating system restricts sending these commands to unprivileged
++programs because incorrect usage can disrupt regular operation of the
++storage fabric.
++
++For this reason, QEMU's SCSI passthrough devices, ``scsi-block``
++and ``scsi-generic`` (both are only available on Linux) can delegate
++implementation of persistent reservations to a separate object,
++the "persistent reservation manager".  Only PERSISTENT RESERVE OUT and
++PERSISTENT RESERVE IN commands are passed to the persistent reservation
++manager object; other commands are processed by QEMU as usual.
++
++-----------------------------------------
++Defining a persistent reservation manager
++-----------------------------------------
++
++A persistent reservation manager is an instance of a subclass of the
++"pr-manager" QOM class.
++
++Right now only one subclass is defined, ``pr-manager-helper``, which
++forwards the commands to an external privileged helper program
++over Unix sockets.  The helper program only allows sending persistent
++reservation commands to devices for which QEMU has a file descriptor,
++so that QEMU will not be able to effect persistent reservations
++unless it has access to both the socket and the device.
++
++``pr-manager-helper`` has a single string property, ``path``, which
++accepts the path to the helper program's Unix socket.  For example,
++the following command line defines a ``pr-manager-helper`` object and
++attaches it to a SCSI passthrough device::
++
++      $ qemu-system-x86_64
++          -device virtio-scsi \
++          -object pr-manager-helper,id=helper0,path=/var/run/qemu-pr-helper.sock
++          -drive if=none,id=hd,driver=raw,file.filename=/dev/sdb,file.pr-manager=helper0
++          -device scsi-block,drive=hd
++
++Alternatively, using ``-blockdev``::
++
++      $ qemu-system-x86_64
++          -device virtio-scsi \
++          -object pr-manager-helper,id=helper0,path=/var/run/qemu-pr-helper.sock
++          -blockdev node-name=hd,driver=raw,file.driver=host_device,file.filename=/dev/sdb,file.pr-manager=helper0
++          -device scsi-block,drive=hd
+diff --git a/include/scsi/pr-manager.h b/include/scsi/pr-manager.h
+new file mode 100644
+index 0000000..b2b37d6
+--- /dev/null
++++ b/include/scsi/pr-manager.h
+@@ -0,0 +1,56 @@
++#ifndef PR_MANAGER_H
++#define PR_MANAGER_H
++
++#include "qom/object.h"
++#include "qapi/qmp/qdict.h"
++#include "qapi/visitor.h"
++#include "qom/object_interfaces.h"
++#include "block/aio.h"
++
++#define TYPE_PR_MANAGER "pr-manager"
++
++#define PR_MANAGER_CLASS(klass) \
++     OBJECT_CLASS_CHECK(PRManagerClass, (klass), TYPE_PR_MANAGER)
++#define PR_MANAGER_GET_CLASS(obj) \
++     OBJECT_GET_CLASS(PRManagerClass, (obj), TYPE_PR_MANAGER)
++#define PR_MANAGER(obj) \
++     OBJECT_CHECK(PRManager, (obj), TYPE_PR_MANAGER)
++
++struct sg_io_hdr;
++
++typedef struct PRManager {
++    /* <private> */
++    Object parent;
++} PRManager;
++
++/**
++ * PRManagerClass:
++ * @parent_class: the base class
++ * @run: callback invoked in thread pool context
++ */
++typedef struct PRManagerClass {
++    /* <private> */
++    ObjectClass parent_class;
++
++    /* <public> */
++    int (*run)(PRManager *pr_mgr, int fd, struct sg_io_hdr *hdr);
++} PRManagerClass;
++
++BlockAIOCB *pr_manager_execute(PRManager *pr_mgr,
++                               AioContext *ctx, int fd,
++                               struct sg_io_hdr *hdr,
++                               BlockCompletionFunc *complete,
++                               void *opaque);
++
++#ifdef CONFIG_LINUX
++PRManager *pr_manager_lookup(const char *id, Error **errp);
++#else
++static inline PRManager *pr_manager_lookup(const char *id, Error **errp)
++{
++    /* The classes do not exist at all!  */
++    error_setg(errp, "No persistent reservation manager with id '%s'", id);
++    return NULL;
++}
++#endif
++
++#endif
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index 8f5f105..15fc08f 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -2191,6 +2191,9 @@
+ # Driver specific block device options for the file backend.
+ #
+ # @filename:    path to the image file
++# @pr-manager:  the id for the object that will handle persistent reservations
++#               for this device (default: none, forward the commands via SG_IO;
++#               since 2.11)
+ # @aio:         AIO backend (default: threads) (since: 2.8)
+ # @locking:     whether to enable file locking. If set to 'auto', only enable
+ #               when Open File Descriptor (OFD) locking API is available
+@@ -2200,6 +2203,7 @@
+ ##
+ { 'struct': 'BlockdevOptionsFile',
+   'data': { 'filename': 'str',
++            '*pr-manager': 'str',
+             '*locking': 'OnOffAuto',
+             '*aio': 'BlockdevAioOptions' } }
+ 
+diff --git a/scsi/Makefile.objs b/scsi/Makefile.objs
+index 31b82a5..5496d2a 100644
+--- a/scsi/Makefile.objs
++++ b/scsi/Makefile.objs
+@@ -1 +1,3 @@
+ block-obj-y += utils.o
++
++block-obj-$(CONFIG_LINUX) += pr-manager.o
+diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c
+new file mode 100644
+index 0000000..87c45db
+--- /dev/null
++++ b/scsi/pr-manager.c
+@@ -0,0 +1,109 @@
++/*
++ * Persistent reservation manager abstract class
++ *
++ * Copyright (c) 2017 Red Hat, Inc.
++ *
++ * Author: Paolo Bonzini <pbonzini@redhat.com>
++ *
++ * This code is licensed under the LGPL.
++ *
++ */
++
++#include "qemu/osdep.h"
++#include <scsi/sg.h>
++
++#include "qapi/error.h"
++#include "block/aio.h"
++#include "block/thread-pool.h"
++#include "scsi/pr-manager.h"
++#include "trace.h"
++
++typedef struct PRManagerData {
++    PRManager *pr_mgr;
++    struct sg_io_hdr *hdr;
++    int fd;
++} PRManagerData;
++
++static int pr_manager_worker(void *opaque)
++{
++    PRManagerData *data = opaque;
++    PRManager *pr_mgr = data->pr_mgr;
++    PRManagerClass *pr_mgr_class =
++        PR_MANAGER_GET_CLASS(pr_mgr);
++    struct sg_io_hdr *hdr = data->hdr;
++    int fd = data->fd;
++    int r;
++
++    g_free(data);
++    trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
++
++    /* The reference was taken in pr_manager_execute.  */
++    r = pr_mgr_class->run(pr_mgr, fd, hdr);
++    object_unref(OBJECT(pr_mgr));
++    return r;
++}
++
++
++BlockAIOCB *pr_manager_execute(PRManager *pr_mgr,
++                               AioContext *ctx, int fd,
++                               struct sg_io_hdr *hdr,
++                               BlockCompletionFunc *complete,
++                               void *opaque)
++{
++    PRManagerData *data = g_new(PRManagerData, 1);
++    ThreadPool *pool = aio_get_thread_pool(ctx);
++
++    trace_pr_manager_execute(fd, hdr->cmdp[0], hdr->cmdp[1], opaque);
++    data->pr_mgr = pr_mgr;
++    data->fd = fd;
++    data->hdr = hdr;
++
++    /* The matching object_unref is in pr_manager_worker.  */
++    object_ref(OBJECT(pr_mgr));
++    return thread_pool_submit_aio(pool, pr_manager_worker,
++                                  data, complete, opaque);
++}
++
++static const TypeInfo pr_manager_info = {
++    .parent = TYPE_OBJECT,
++    .name = TYPE_PR_MANAGER,
++    .class_size = sizeof(PRManagerClass),
++    .abstract = true,
++    .interfaces = (InterfaceInfo[]) {
++        { TYPE_USER_CREATABLE },
++        { }
++    }
++};
++
++PRManager *pr_manager_lookup(const char *id, Error **errp)
++{
++    Object *obj;
++    PRManager *pr_mgr;
++
++    obj = object_resolve_path_component(object_get_objects_root(), id);
++    if (!obj) {
++        error_setg(errp, "No persistent reservation manager with id '%s'", id);
++        return NULL;
++    }
++
++    pr_mgr = (PRManager *)
++        object_dynamic_cast(obj,
++                            TYPE_PR_MANAGER);
++    if (!pr_mgr) {
++        error_setg(errp,
++                   "Object with id '%s' is not a persistent reservation manager",
++                   id);
++        return NULL;
++    }
++
++    return pr_mgr;
++}
++
++static void
++pr_manager_register_types(void)
++{
++    type_register_static(&pr_manager_info);
++}
++
++
++type_init(pr_manager_register_types);
+diff --git a/scsi/trace-events b/scsi/trace-events
+new file mode 100644
+index 0000000..45f5b6e
+--- /dev/null
++++ b/scsi/trace-events
+@@ -0,0 +1,3 @@
++# scsi/pr-manager.c
++pr_manager_execute(int fd, int cmd, int sa, void *opaque) "fd=%d cmd=0x%02x service action=0x%02x opaque=%p"
++pr_manager_run(int fd, int cmd, int sa) "fd=%d cmd=0x%02x service action=0x%02x"
+diff --git a/vl.c b/vl.c
+index 55949e6..bef5ae3 100644
+--- a/vl.c
++++ b/vl.c
+@@ -2820,7 +2820,8 @@ static int machine_set_property(void *opaque,
+  */
+ static bool object_create_initial(const char *type)
+ {
+-    if (g_str_equal(type, "rng-egd")) {
++    if (g_str_equal(type, "rng-egd") ||
++        g_str_has_prefix(type, "pr-manager-")) {
+         return false;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-generic-Add-share-rw-option.patch b/SOURCES/kvm-scsi-generic-Add-share-rw-option.patch
new file mode 100644
index 0000000..8f8b1c8
--- /dev/null
+++ b/SOURCES/kvm-scsi-generic-Add-share-rw-option.patch
@@ -0,0 +1,70 @@
+From 7d6eed4b197081fa324e42f7624d6ab0a27bab6d Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Wed, 17 Jan 2018 06:08:34 +0100
+Subject: [PATCH 04/21] scsi-generic: Add share-rw option
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20180117060834.17481-3-famz@redhat.com>
+Patchwork-id: 78652
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/2] scsi-generic: Add share-rw option
+Bugzilla: 1518482
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+Add the property to the device model, then parse it by calling
+blkconf_apply_backend_options().
+
+In addition to blk_set_perm(), the called function also handles error
+options and wce. For error options we've already checked that the
+default values are used, for wce we don't have the option either so it
+is always the default (true). In other words there is no change of
+behavior in these regards.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-Id: <20171205151553.7834-1-famz@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit d9bcd6f7f23a13ea627d8edb85c0706525da0b75)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-generic.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
+index bd0d9ff..ba70c0d 100644
+--- a/hw/scsi/scsi-generic.c
++++ b/hw/scsi/scsi-generic.c
+@@ -482,6 +482,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
+     int rc;
+     int sg_version;
+     struct sg_scsi_id scsiid;
++    Error *local_err = NULL;
+ 
+     if (!s->conf.blk) {
+         error_setg(errp, "drive property not set");
+@@ -515,6 +516,13 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
+         error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
+         return;
+     }
++    blkconf_apply_backend_options(&s->conf,
++                                  blk_is_read_only(s->conf.blk),
++                                  true, &local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        return;
++    }
+ 
+     /* define device state */
+     s->type = scsiid.scsi_type;
+@@ -565,6 +573,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
+ 
+ static Property scsi_generic_properties[] = {
+     DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
++    DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
+     DEFINE_PROP_END_OF_LIST(),
+ };
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-introduce-scsi_build_sense.patch b/SOURCES/kvm-scsi-introduce-scsi_build_sense.patch
new file mode 100644
index 0000000..ebb3f11
--- /dev/null
+++ b/SOURCES/kvm-scsi-introduce-scsi_build_sense.patch
@@ -0,0 +1,88 @@
+From 671df2c5697b3509eb8a9e16e3b2ccc51f9719d7 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:45 +0100
+Subject: [PATCH 19/36] scsi: introduce scsi_build_sense
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-10-pbonzini@redhat.com>
+Patchwork-id: 78078
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 09/17] scsi: introduce scsi_build_sense
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Move more knowledge of sense data format out of hw/scsi/scsi-bus.c
+for reusability.
+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit a3760467c6b0ff5d1ff952fdc8cec69c65e19499)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-bus.c   |  8 +-------
+ include/scsi/utils.h |  2 ++
+ scsi/utils.c         | 11 +++++++++++
+ 3 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 635cdf6..f77e576 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -826,13 +826,7 @@ void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
+ {
+     trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag,
+                                sense.key, sense.asc, sense.ascq);
+-    memset(req->sense, 0, 18);
+-    req->sense[0] = 0x70;
+-    req->sense[2] = sense.key;
+-    req->sense[7] = 10;
+-    req->sense[12] = sense.asc;
+-    req->sense[13] = sense.ascq;
+-    req->sense_len = 18;
++    req->sense_len = scsi_build_sense(req->sense, sense);
+ }
+ 
+ static void scsi_req_enqueue_internal(SCSIRequest *req)
+diff --git a/include/scsi/utils.h b/include/scsi/utils.h
+index 90bf4dc..b49392d 100644
+--- a/include/scsi/utils.h
++++ b/include/scsi/utils.h
+@@ -30,6 +30,8 @@ typedef struct SCSISense {
+     uint8_t ascq;
+ } SCSISense;
+ 
++int scsi_build_sense(uint8_t *buf, SCSISense sense);
++
+ /*
+  * Predefined sense codes
+  */
+diff --git a/scsi/utils.c b/scsi/utils.c
+index 2327e06..89d9167 100644
+--- a/scsi/utils.c
++++ b/scsi/utils.c
+@@ -96,6 +96,17 @@ int scsi_cdb_length(uint8_t *buf)
+     return cdb_len;
+ }
+ 
++int scsi_build_sense(uint8_t *buf, SCSISense sense)
++{
++    memset(buf, 0, 18);
++    buf[0] = 0x70;
++    buf[2] = sense.key;
++    buf[7] = 10;
++    buf[12] = sense.asc;
++    buf[13] = sense.ascq;
++    return 18;
++}
++
+ /*
+  * Predefined sense codes
+  */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-introduce-sg_io_sense_from_errno.patch b/SOURCES/kvm-scsi-introduce-sg_io_sense_from_errno.patch
new file mode 100644
index 0000000..3c55e1c
--- /dev/null
+++ b/SOURCES/kvm-scsi-introduce-sg_io_sense_from_errno.patch
@@ -0,0 +1,148 @@
+From b1aa9df721c90e02c917eba8f753fa50d3c1e952 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:46 +0100
+Subject: [PATCH 20/36] scsi: introduce sg_io_sense_from_errno
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-11-pbonzini@redhat.com>
+Patchwork-id: 78080
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 10/17] scsi: introduce sg_io_sense_from_errno
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Move more knowledge of SG_IO out of hw/scsi/scsi-generic.c, for
+reusability.
+
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 1ead6b4e242e59711976cdf2502dd5c7cd5d340a)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-generic.c | 40 +++++++---------------------------------
+ include/scsi/utils.h   |  3 +++
+ scsi/utils.c           | 35 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
+index 7a8f500..04c687e 100644
+--- a/hw/scsi/scsi-generic.c
++++ b/hw/scsi/scsi-generic.c
+@@ -81,6 +81,7 @@ static void scsi_free_request(SCSIRequest *req)
+ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
+ {
+     int status;
++    SCSISense sense;
+ 
+     assert(r->req.aiocb == NULL);
+ 
+@@ -88,42 +89,15 @@ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
+         scsi_req_cancel_complete(&r->req);
+         goto done;
+     }
+-    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
+-        r->req.sense_len = r->io_header.sb_len_wr;
+-    }
+-
+-    if (ret != 0) {
+-        switch (ret) {
+-        case -EDOM:
+-            status = TASK_SET_FULL;
+-            break;
+-        case -ENOMEM:
+-            status = CHECK_CONDITION;
+-            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
+-            break;
+-        default:
+-            status = CHECK_CONDITION;
+-            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
+-            break;
+-        }
+-    } else {
+-        if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
+-            r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
+-            r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
+-            (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
+-            status = BUSY;
+-            BADF("Driver Timeout\n");
+-        } else if (r->io_header.host_status) {
+-            status = CHECK_CONDITION;
+-            scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
+-        } else if (r->io_header.status) {
+-            status = r->io_header.status;
+-        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
+-            status = CHECK_CONDITION;
++    status = sg_io_sense_from_errno(-ret, &r->io_header, &sense);
++    if (status == CHECK_CONDITION) {
++        if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
++            r->req.sense_len = r->io_header.sb_len_wr;
+         } else {
+-            status = GOOD;
++            scsi_req_build_sense(&r->req, sense);
+         }
+     }
++
+     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
+             r, r->req.tag, status);
+ 
+diff --git a/include/scsi/utils.h b/include/scsi/utils.h
+index b49392d..d301b31 100644
+--- a/include/scsi/utils.h
++++ b/include/scsi/utils.h
+@@ -116,6 +116,9 @@ int scsi_cdb_length(uint8_t *buf);
+ #define SG_ERR_DID_TIME_OUT    0x03
+ 
+ #define SG_ERR_DRIVER_SENSE    0x08
++
++int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr,
++                           SCSISense *sense);
+ #endif
+ 
+ #endif
+diff --git a/scsi/utils.c b/scsi/utils.c
+index 89d9167..6ee9f40 100644
+--- a/scsi/utils.c
++++ b/scsi/utils.c
+@@ -501,3 +501,38 @@ const char *scsi_command_name(uint8_t cmd)
+     }
+     return names[cmd];
+ }
++
++#ifdef CONFIG_LINUX
++int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr,
++                           SCSISense *sense)
++{
++    if (errno_value != 0) {
++        switch (errno_value) {
++        case EDOM:
++            return TASK_SET_FULL;
++        case ENOMEM:
++            *sense = SENSE_CODE(TARGET_FAILURE);
++            return CHECK_CONDITION;
++        default:
++            *sense = SENSE_CODE(IO_ERROR);
++            return CHECK_CONDITION;
++        }
++    } else {
++        if (io_hdr->host_status == SG_ERR_DID_NO_CONNECT ||
++            io_hdr->host_status == SG_ERR_DID_BUS_BUSY ||
++            io_hdr->host_status == SG_ERR_DID_TIME_OUT ||
++            (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT)) {
++            return BUSY;
++        } else if (io_hdr->host_status) {
++            *sense = SENSE_CODE(I_T_NEXUS_LOSS);
++            return CHECK_CONDITION;
++        } else if (io_hdr->status) {
++            return io_hdr->status;
++        } else if (io_hdr->driver_status & SG_ERR_DRIVER_SENSE) {
++            return CHECK_CONDITION;
++        } else {
++            return GOOD;
++        }
++    }
++}
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-move-block-scsi.h-to-include-scsi-constants.h.patch b/SOURCES/kvm-scsi-move-block-scsi.h-to-include-scsi-constants.h.patch
new file mode 100644
index 0000000..560469b
--- /dev/null
+++ b/SOURCES/kvm-scsi-move-block-scsi.h-to-include-scsi-constants.h.patch
@@ -0,0 +1,899 @@
+From a97cc2e8341bf5d50e9282946bcdf26b43ebc34c Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:47 +0100
+Subject: [PATCH 21/36] scsi: move block/scsi.h to include/scsi/constants.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-12-pbonzini@redhat.com>
+Patchwork-id: 78086
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 11/17] scsi: move block/scsi.h to include/scsi/constants.h
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+Complete the transition by renaming this header, which was
+shared by block/iscsi.c and the SCSI emulation code.
+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 08e2c9f19ce791b3a0fb6adbf962ab4902ec5a7b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/iscsi.c                   |   2 +-
+ hw/block/virtio-blk.c           |   2 +-
+ hw/scsi/megasas.c               |   2 +-
+ hw/scsi/mptendian.c             |   2 +-
+ hw/scsi/mptsas.c                |   2 +-
+ hw/scsi/scsi-bus.c              |   2 +-
+ hw/scsi/scsi-disk.c             |   2 +-
+ hw/scsi/scsi-generic.c          |   2 +-
+ hw/scsi/spapr_vscsi.c           |   2 +-
+ hw/scsi/virtio-scsi-dataplane.c |   2 +-
+ hw/scsi/virtio-scsi.c           |   2 +-
+ hw/scsi/vmw_pvscsi.c            |   2 +-
+ hw/usb/dev-uas.c                |   2 +-
+ include/block/scsi.h            | 314 ----------------------------------------
+ include/hw/ide/internal.h       |   2 +-
+ include/scsi/constants.h        | 314 ++++++++++++++++++++++++++++++++++++++++
+ scsi/utils.c                    |   2 +-
+ tests/virtio-scsi-test.c        |   2 +-
+ 18 files changed, 330 insertions(+), 330 deletions(-)
+ delete mode 100644 include/block/scsi.h
+ create mode 100644 include/scsi/constants.h
+
+diff --git a/block/iscsi.c b/block/iscsi.c
+index 40adc3c..c4586be 100644
+--- a/block/iscsi.c
++++ b/block/iscsi.c
+@@ -34,7 +34,7 @@
+ #include "qemu/bitops.h"
+ #include "qemu/bitmap.h"
+ #include "block/block_int.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "qemu/iov.h"
+ #include "qemu/uuid.h"
+ #include "qmp-commands.h"
+diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
+index a16ac75..05d1440 100644
+--- a/hw/block/virtio-blk.c
++++ b/hw/block/virtio-blk.c
+@@ -22,7 +22,7 @@
+ #include "sysemu/blockdev.h"
+ #include "hw/virtio/virtio-blk.h"
+ #include "dataplane/virtio-blk.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #ifdef __linux__
+ # include <scsi/sg.h>
+ #endif
+diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
+index 4ae10e3..d5eae62 100644
+--- a/hw/scsi/megasas.c
++++ b/hw/scsi/megasas.c
+@@ -27,7 +27,7 @@
+ #include "hw/pci/msix.h"
+ #include "qemu/iov.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "trace.h"
+ #include "qapi/error.h"
+ #include "mfi.h"
+diff --git a/hw/scsi/mptendian.c b/hw/scsi/mptendian.c
+index b7fe2a2..3415229 100644
+--- a/hw/scsi/mptendian.c
++++ b/hw/scsi/mptendian.c
+@@ -28,7 +28,7 @@
+ #include "hw/pci/msi.h"
+ #include "qemu/iov.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "trace.h"
+ 
+ #include "mptsas.h"
+diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
+index f807dc6..2f2c1b1 100644
+--- a/hw/scsi/mptsas.c
++++ b/hw/scsi/mptsas.c
+@@ -30,7 +30,7 @@
+ #include "hw/pci/msi.h"
+ #include "qemu/iov.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "trace.h"
+ #include "qapi/error.h"
+ #include "mptsas.h"
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index f77e576..97c9525 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -3,7 +3,7 @@
+ #include "qapi/error.h"
+ #include "qemu/error-report.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "hw/qdev.h"
+ #include "sysemu/block-backend.h"
+ #include "sysemu/blockdev.h"
+diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
+index b7714e3..8a63377 100644
+--- a/hw/scsi/scsi-disk.c
++++ b/hw/scsi/scsi-disk.c
+@@ -32,7 +32,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
+ #include "qapi/error.h"
+ #include "qemu/error-report.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "sysemu/sysemu.h"
+ #include "sysemu/block-backend.h"
+ #include "sysemu/blockdev.h"
+diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
+index 04c687e..bd0d9ff 100644
+--- a/hw/scsi/scsi-generic.c
++++ b/hw/scsi/scsi-generic.c
+@@ -34,7 +34,7 @@ do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
+ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
+ 
+ #include <scsi/sg.h>
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ 
+ #ifndef MAX_UINT
+ #define MAX_UINT ((unsigned int)-1)
+diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
+index 92a3de3..5a7ca06 100644
+--- a/hw/scsi/spapr_vscsi.c
++++ b/hw/scsi/spapr_vscsi.c
+@@ -36,7 +36,7 @@
+ #include "cpu.h"
+ #include "hw/hw.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "srp.h"
+ #include "hw/qdev.h"
+ #include "hw/ppc/spapr.h"
+diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
+index 944ea4e..add4b3f 100644
+--- a/hw/scsi/virtio-scsi-dataplane.c
++++ b/hw/scsi/virtio-scsi-dataplane.c
+@@ -17,7 +17,7 @@
+ #include "qemu/error-report.h"
+ #include "sysemu/block-backend.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "hw/virtio/virtio-bus.h"
+ #include "hw/virtio/virtio-access.h"
+ 
+diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
+index 2635c38..1591283 100644
+--- a/hw/scsi/virtio-scsi.c
++++ b/hw/scsi/virtio-scsi.c
+@@ -21,7 +21,7 @@
+ #include "qemu/iov.h"
+ #include "sysemu/block-backend.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "hw/virtio/virtio-bus.h"
+ #include "hw/virtio/virtio-access.h"
+ 
+diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
+index d185393..d6b315f 100644
+--- a/hw/scsi/vmw_pvscsi.c
++++ b/hw/scsi/vmw_pvscsi.c
+@@ -28,7 +28,7 @@
+ #include "qemu/osdep.h"
+ #include "qapi/error.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "hw/pci/msi.h"
+ #include "vmw_pvscsi.h"
+ #include "trace.h"
+diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
+index fffc424..c218b53 100644
+--- a/hw/usb/dev-uas.c
++++ b/hw/usb/dev-uas.c
+@@ -19,7 +19,7 @@
+ #include "hw/usb.h"
+ #include "hw/usb/desc.h"
+ #include "hw/scsi/scsi.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ 
+ /* --------------------------------------------------------------------- */
+ 
+diff --git a/include/block/scsi.h b/include/block/scsi.h
+deleted file mode 100644
+index a141dd7..0000000
+--- a/include/block/scsi.h
++++ /dev/null
+@@ -1,314 +0,0 @@
+-/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+-*/
+-
+-/*
+- * This header file contains public constants and structures used by
+- * the scsi code for linux.
+- */
+-
+-#ifndef BLOCK_SCSI_H
+-#define BLOCK_SCSI_H
+-
+-/*
+- *      SCSI opcodes
+- */
+-
+-#define TEST_UNIT_READY       0x00
+-#define REWIND                0x01
+-#define REQUEST_SENSE         0x03
+-#define FORMAT_UNIT           0x04
+-#define READ_BLOCK_LIMITS     0x05
+-#define INITIALIZE_ELEMENT_STATUS 0x07
+-#define REASSIGN_BLOCKS       0x07
+-#define READ_6                0x08
+-#define WRITE_6               0x0a
+-#define SET_CAPACITY          0x0b
+-#define READ_REVERSE          0x0f
+-#define WRITE_FILEMARKS       0x10
+-#define SPACE                 0x11
+-#define INQUIRY               0x12
+-#define RECOVER_BUFFERED_DATA 0x14
+-#define MODE_SELECT           0x15
+-#define RESERVE               0x16
+-#define RELEASE               0x17
+-#define COPY                  0x18
+-#define ERASE                 0x19
+-#define MODE_SENSE            0x1a
+-#define LOAD_UNLOAD           0x1b
+-#define SCAN                  0x1b
+-#define START_STOP            0x1b
+-#define RECEIVE_DIAGNOSTIC    0x1c
+-#define SEND_DIAGNOSTIC       0x1d
+-#define ALLOW_MEDIUM_REMOVAL  0x1e
+-#define SET_WINDOW            0x24
+-#define READ_CAPACITY_10      0x25
+-#define GET_WINDOW            0x25
+-#define READ_10               0x28
+-#define WRITE_10              0x2a
+-#define SEND                  0x2a
+-#define SEEK_10               0x2b
+-#define LOCATE_10             0x2b
+-#define POSITION_TO_ELEMENT   0x2b
+-#define WRITE_VERIFY_10       0x2e
+-#define VERIFY_10             0x2f
+-#define SEARCH_HIGH           0x30
+-#define SEARCH_EQUAL          0x31
+-#define OBJECT_POSITION       0x31
+-#define SEARCH_LOW            0x32
+-#define SET_LIMITS            0x33
+-#define PRE_FETCH             0x34
+-#define READ_POSITION         0x34
+-#define GET_DATA_BUFFER_STATUS 0x34
+-#define SYNCHRONIZE_CACHE     0x35
+-#define LOCK_UNLOCK_CACHE     0x36
+-#define INITIALIZE_ELEMENT_STATUS_WITH_RANGE 0x37
+-#define READ_DEFECT_DATA      0x37
+-#define MEDIUM_SCAN           0x38
+-#define COMPARE               0x39
+-#define COPY_VERIFY           0x3a
+-#define WRITE_BUFFER          0x3b
+-#define READ_BUFFER           0x3c
+-#define UPDATE_BLOCK          0x3d
+-#define READ_LONG_10          0x3e
+-#define WRITE_LONG_10         0x3f
+-#define CHANGE_DEFINITION     0x40
+-#define WRITE_SAME_10         0x41
+-#define UNMAP                 0x42
+-#define READ_TOC              0x43
+-#define REPORT_DENSITY_SUPPORT 0x44
+-#define GET_CONFIGURATION     0x46
+-#define SANITIZE              0x48
+-#define GET_EVENT_STATUS_NOTIFICATION 0x4a
+-#define LOG_SELECT            0x4c
+-#define LOG_SENSE             0x4d
+-#define READ_DISC_INFORMATION 0x51
+-#define RESERVE_TRACK         0x53
+-#define MODE_SELECT_10        0x55
+-#define RESERVE_10            0x56
+-#define RELEASE_10            0x57
+-#define MODE_SENSE_10         0x5a
+-#define SEND_CUE_SHEET        0x5d
+-#define PERSISTENT_RESERVE_IN 0x5e
+-#define PERSISTENT_RESERVE_OUT 0x5f
+-#define VARLENGTH_CDB         0x7f
+-#define WRITE_FILEMARKS_16    0x80
+-#define READ_REVERSE_16       0x81
+-#define ALLOW_OVERWRITE       0x82
+-#define EXTENDED_COPY         0x83
+-#define ATA_PASSTHROUGH_16    0x85
+-#define ACCESS_CONTROL_IN     0x86
+-#define ACCESS_CONTROL_OUT    0x87
+-#define READ_16               0x88
+-#define COMPARE_AND_WRITE     0x89
+-#define WRITE_16              0x8a
+-#define WRITE_VERIFY_16       0x8e
+-#define VERIFY_16             0x8f
+-#define PRE_FETCH_16          0x90
+-#define SPACE_16              0x91
+-#define SYNCHRONIZE_CACHE_16  0x91
+-#define LOCATE_16             0x92
+-#define WRITE_SAME_16         0x93
+-#define ERASE_16              0x93
+-#define SERVICE_ACTION_IN_16  0x9e
+-#define WRITE_LONG_16         0x9f
+-#define REPORT_LUNS           0xa0
+-#define ATA_PASSTHROUGH_12    0xa1
+-#define MAINTENANCE_IN        0xa3
+-#define MAINTENANCE_OUT       0xa4
+-#define MOVE_MEDIUM           0xa5
+-#define EXCHANGE_MEDIUM       0xa6
+-#define SET_READ_AHEAD        0xa7
+-#define READ_12               0xa8
+-#define WRITE_12              0xaa
+-#define SERVICE_ACTION_IN_12  0xab
+-#define ERASE_12              0xac
+-#define READ_DVD_STRUCTURE    0xad
+-#define WRITE_VERIFY_12       0xae
+-#define VERIFY_12             0xaf
+-#define SEARCH_HIGH_12        0xb0
+-#define SEARCH_EQUAL_12       0xb1
+-#define SEARCH_LOW_12         0xb2
+-#define READ_ELEMENT_STATUS   0xb8
+-#define SEND_VOLUME_TAG       0xb6
+-#define READ_DEFECT_DATA_12   0xb7
+-#define SET_CD_SPEED          0xbb
+-#define MECHANISM_STATUS      0xbd
+-#define READ_CD               0xbe
+-#define SEND_DVD_STRUCTURE    0xbf
+-
+-/*
+- * SERVICE ACTION IN subcodes
+- */
+-#define SAI_READ_CAPACITY_16  0x10
+-
+-/*
+- * READ POSITION service action codes
+- */
+-#define SHORT_FORM_BLOCK_ID  0x00
+-#define SHORT_FORM_VENDOR_SPECIFIC 0x01
+-#define LONG_FORM            0x06
+-#define EXTENDED_FORM        0x08
+-
+-/*
+- *  SAM Status codes
+- */
+-
+-#define GOOD                 0x00
+-#define CHECK_CONDITION      0x02
+-#define CONDITION_GOOD       0x04
+-#define BUSY                 0x08
+-#define INTERMEDIATE_GOOD    0x10
+-#define INTERMEDIATE_C_GOOD  0x14
+-#define RESERVATION_CONFLICT 0x18
+-#define COMMAND_TERMINATED   0x22
+-#define TASK_SET_FULL        0x28
+-#define ACA_ACTIVE           0x30
+-#define TASK_ABORTED         0x40
+-
+-#define STATUS_MASK          0x3e
+-
+-/*
+- *  SENSE KEYS
+- */
+-
+-#define NO_SENSE            0x00
+-#define RECOVERED_ERROR     0x01
+-#define NOT_READY           0x02
+-#define MEDIUM_ERROR        0x03
+-#define HARDWARE_ERROR      0x04
+-#define ILLEGAL_REQUEST     0x05
+-#define UNIT_ATTENTION      0x06
+-#define DATA_PROTECT        0x07
+-#define BLANK_CHECK         0x08
+-#define COPY_ABORTED        0x0a
+-#define ABORTED_COMMAND     0x0b
+-#define VOLUME_OVERFLOW     0x0d
+-#define MISCOMPARE          0x0e
+-
+-
+-/*
+- *  DEVICE TYPES
+- */
+-
+-#define TYPE_DISK           0x00
+-#define TYPE_TAPE           0x01
+-#define TYPE_PRINTER        0x02
+-#define TYPE_PROCESSOR      0x03    /* HP scanners use this */
+-#define TYPE_WORM           0x04    /* Treated as ROM by our system */
+-#define TYPE_ROM            0x05
+-#define TYPE_SCANNER        0x06
+-#define TYPE_MOD            0x07    /* Magneto-optical disk -
+-				     * - treated as TYPE_DISK */
+-#define TYPE_MEDIUM_CHANGER 0x08
+-#define TYPE_STORAGE_ARRAY  0x0c    /* Storage array device */
+-#define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
+-#define TYPE_RBC            0x0e    /* Simplified Direct-Access Device */
+-#define TYPE_OSD            0x11    /* Object-storage Device */
+-#define TYPE_WLUN           0x1e    /* Well known LUN */
+-#define TYPE_NOT_PRESENT    0x1f
+-#define TYPE_INACTIVE       0x20
+-#define TYPE_NO_LUN         0x7f
+-
+-/* Mode page codes for mode sense/set */
+-#define MODE_PAGE_R_W_ERROR                   0x01
+-#define MODE_PAGE_HD_GEOMETRY                 0x04
+-#define MODE_PAGE_FLEXIBLE_DISK_GEOMETRY      0x05
+-#define MODE_PAGE_CACHING                     0x08
+-#define MODE_PAGE_AUDIO_CTL                   0x0e
+-#define MODE_PAGE_POWER                       0x1a
+-#define MODE_PAGE_FAULT_FAIL                  0x1c
+-#define MODE_PAGE_TO_PROTECT                  0x1d
+-#define MODE_PAGE_CAPABILITIES                0x2a
+-#define MODE_PAGE_ALLS                        0x3f
+-/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
+- * of MODE_PAGE_SENSE_POWER */
+-#define MODE_PAGE_CDROM                       0x0d
+-
+-/* Event notification classes for GET EVENT STATUS NOTIFICATION */
+-#define GESN_NO_EVENTS                0
+-#define GESN_OPERATIONAL_CHANGE       1
+-#define GESN_POWER_MANAGEMENT         2
+-#define GESN_EXTERNAL_REQUEST         3
+-#define GESN_MEDIA                    4
+-#define GESN_MULTIPLE_HOSTS           5
+-#define GESN_DEVICE_BUSY              6
+-
+-/* Event codes for MEDIA event status notification */
+-#define MEC_NO_CHANGE                 0
+-#define MEC_EJECT_REQUESTED           1
+-#define MEC_NEW_MEDIA                 2
+-#define MEC_MEDIA_REMOVAL             3 /* only for media changers */
+-#define MEC_MEDIA_CHANGED             4 /* only for media changers */
+-#define MEC_BG_FORMAT_COMPLETED       5 /* MRW or DVD+RW b/g format completed */
+-#define MEC_BG_FORMAT_RESTARTED       6 /* MRW or DVD+RW b/g format restarted */
+-
+-#define MS_TRAY_OPEN                  1
+-#define MS_MEDIA_PRESENT              2
+-
+-/*
+- * Based on values from <linux/cdrom.h> but extending CD_MINS
+- * to the maximum common size allowed by the Orange's Book ATIP
+- *
+- * 90 and 99 min CDs are also available but using them as the
+- * upper limit reduces the effectiveness of the heuristic to
+- * detect DVDs burned to less than 25% of their maximum capacity
+- */
+-
+-/* Some generally useful CD-ROM information */
+-#define CD_MINS                       80 /* max. minutes per CD */
+-#define CD_SECS                       60 /* seconds per minute */
+-#define CD_FRAMES                     75 /* frames per second */
+-#define CD_FRAMESIZE                2048 /* bytes per frame, "cooked" mode */
+-#define CD_MAX_BYTES       (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE)
+-#define CD_MAX_SECTORS     (CD_MAX_BYTES / 512)
+-
+-/*
+- * The MMC values are not IDE specific and might need to be moved
+- * to a common header if they are also needed for the SCSI emulation
+- */
+-
+-/* Profile list from MMC-6 revision 1 table 91 */
+-#define MMC_PROFILE_NONE                0x0000
+-#define MMC_PROFILE_CD_ROM              0x0008
+-#define MMC_PROFILE_CD_R                0x0009
+-#define MMC_PROFILE_CD_RW               0x000A
+-#define MMC_PROFILE_DVD_ROM             0x0010
+-#define MMC_PROFILE_DVD_R_SR            0x0011
+-#define MMC_PROFILE_DVD_RAM             0x0012
+-#define MMC_PROFILE_DVD_RW_RO           0x0013
+-#define MMC_PROFILE_DVD_RW_SR           0x0014
+-#define MMC_PROFILE_DVD_R_DL_SR         0x0015
+-#define MMC_PROFILE_DVD_R_DL_JR         0x0016
+-#define MMC_PROFILE_DVD_RW_DL           0x0017
+-#define MMC_PROFILE_DVD_DDR             0x0018
+-#define MMC_PROFILE_DVD_PLUS_RW         0x001A
+-#define MMC_PROFILE_DVD_PLUS_R          0x001B
+-#define MMC_PROFILE_DVD_PLUS_RW_DL      0x002A
+-#define MMC_PROFILE_DVD_PLUS_R_DL       0x002B
+-#define MMC_PROFILE_BD_ROM              0x0040
+-#define MMC_PROFILE_BD_R_SRM            0x0041
+-#define MMC_PROFILE_BD_R_RRM            0x0042
+-#define MMC_PROFILE_BD_RE               0x0043
+-#define MMC_PROFILE_HDDVD_ROM           0x0050
+-#define MMC_PROFILE_HDDVD_R             0x0051
+-#define MMC_PROFILE_HDDVD_RAM           0x0052
+-#define MMC_PROFILE_HDDVD_RW            0x0053
+-#define MMC_PROFILE_HDDVD_R_DL          0x0058
+-#define MMC_PROFILE_HDDVD_RW_DL         0x005A
+-#define MMC_PROFILE_INVALID             0xFFFF
+-
+-#endif
+diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
+index f1aca72..41cd42d 100644
+--- a/include/hw/ide/internal.h
++++ b/include/hw/ide/internal.h
+@@ -11,7 +11,7 @@
+ #include "sysemu/dma.h"
+ #include "sysemu/sysemu.h"
+ #include "hw/block/block.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ 
+ /* debug IDE devices */
+ //#define DEBUG_IDE
+diff --git a/include/scsi/constants.h b/include/scsi/constants.h
+new file mode 100644
+index 0000000..a141dd7
+--- /dev/null
++++ b/include/scsi/constants.h
+@@ -0,0 +1,314 @@
++/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with this library; if not, see <http://www.gnu.org/licenses/>.
++*/
++
++/*
++ * This header file contains public constants and structures used by
++ * the scsi code for linux.
++ */
++
++#ifndef BLOCK_SCSI_H
++#define BLOCK_SCSI_H
++
++/*
++ *      SCSI opcodes
++ */
++
++#define TEST_UNIT_READY       0x00
++#define REWIND                0x01
++#define REQUEST_SENSE         0x03
++#define FORMAT_UNIT           0x04
++#define READ_BLOCK_LIMITS     0x05
++#define INITIALIZE_ELEMENT_STATUS 0x07
++#define REASSIGN_BLOCKS       0x07
++#define READ_6                0x08
++#define WRITE_6               0x0a
++#define SET_CAPACITY          0x0b
++#define READ_REVERSE          0x0f
++#define WRITE_FILEMARKS       0x10
++#define SPACE                 0x11
++#define INQUIRY               0x12
++#define RECOVER_BUFFERED_DATA 0x14
++#define MODE_SELECT           0x15
++#define RESERVE               0x16
++#define RELEASE               0x17
++#define COPY                  0x18
++#define ERASE                 0x19
++#define MODE_SENSE            0x1a
++#define LOAD_UNLOAD           0x1b
++#define SCAN                  0x1b
++#define START_STOP            0x1b
++#define RECEIVE_DIAGNOSTIC    0x1c
++#define SEND_DIAGNOSTIC       0x1d
++#define ALLOW_MEDIUM_REMOVAL  0x1e
++#define SET_WINDOW            0x24
++#define READ_CAPACITY_10      0x25
++#define GET_WINDOW            0x25
++#define READ_10               0x28
++#define WRITE_10              0x2a
++#define SEND                  0x2a
++#define SEEK_10               0x2b
++#define LOCATE_10             0x2b
++#define POSITION_TO_ELEMENT   0x2b
++#define WRITE_VERIFY_10       0x2e
++#define VERIFY_10             0x2f
++#define SEARCH_HIGH           0x30
++#define SEARCH_EQUAL          0x31
++#define OBJECT_POSITION       0x31
++#define SEARCH_LOW            0x32
++#define SET_LIMITS            0x33
++#define PRE_FETCH             0x34
++#define READ_POSITION         0x34
++#define GET_DATA_BUFFER_STATUS 0x34
++#define SYNCHRONIZE_CACHE     0x35
++#define LOCK_UNLOCK_CACHE     0x36
++#define INITIALIZE_ELEMENT_STATUS_WITH_RANGE 0x37
++#define READ_DEFECT_DATA      0x37
++#define MEDIUM_SCAN           0x38
++#define COMPARE               0x39
++#define COPY_VERIFY           0x3a
++#define WRITE_BUFFER          0x3b
++#define READ_BUFFER           0x3c
++#define UPDATE_BLOCK          0x3d
++#define READ_LONG_10          0x3e
++#define WRITE_LONG_10         0x3f
++#define CHANGE_DEFINITION     0x40
++#define WRITE_SAME_10         0x41
++#define UNMAP                 0x42
++#define READ_TOC              0x43
++#define REPORT_DENSITY_SUPPORT 0x44
++#define GET_CONFIGURATION     0x46
++#define SANITIZE              0x48
++#define GET_EVENT_STATUS_NOTIFICATION 0x4a
++#define LOG_SELECT            0x4c
++#define LOG_SENSE             0x4d
++#define READ_DISC_INFORMATION 0x51
++#define RESERVE_TRACK         0x53
++#define MODE_SELECT_10        0x55
++#define RESERVE_10            0x56
++#define RELEASE_10            0x57
++#define MODE_SENSE_10         0x5a
++#define SEND_CUE_SHEET        0x5d
++#define PERSISTENT_RESERVE_IN 0x5e
++#define PERSISTENT_RESERVE_OUT 0x5f
++#define VARLENGTH_CDB         0x7f
++#define WRITE_FILEMARKS_16    0x80
++#define READ_REVERSE_16       0x81
++#define ALLOW_OVERWRITE       0x82
++#define EXTENDED_COPY         0x83
++#define ATA_PASSTHROUGH_16    0x85
++#define ACCESS_CONTROL_IN     0x86
++#define ACCESS_CONTROL_OUT    0x87
++#define READ_16               0x88
++#define COMPARE_AND_WRITE     0x89
++#define WRITE_16              0x8a
++#define WRITE_VERIFY_16       0x8e
++#define VERIFY_16             0x8f
++#define PRE_FETCH_16          0x90
++#define SPACE_16              0x91
++#define SYNCHRONIZE_CACHE_16  0x91
++#define LOCATE_16             0x92
++#define WRITE_SAME_16         0x93
++#define ERASE_16              0x93
++#define SERVICE_ACTION_IN_16  0x9e
++#define WRITE_LONG_16         0x9f
++#define REPORT_LUNS           0xa0
++#define ATA_PASSTHROUGH_12    0xa1
++#define MAINTENANCE_IN        0xa3
++#define MAINTENANCE_OUT       0xa4
++#define MOVE_MEDIUM           0xa5
++#define EXCHANGE_MEDIUM       0xa6
++#define SET_READ_AHEAD        0xa7
++#define READ_12               0xa8
++#define WRITE_12              0xaa
++#define SERVICE_ACTION_IN_12  0xab
++#define ERASE_12              0xac
++#define READ_DVD_STRUCTURE    0xad
++#define WRITE_VERIFY_12       0xae
++#define VERIFY_12             0xaf
++#define SEARCH_HIGH_12        0xb0
++#define SEARCH_EQUAL_12       0xb1
++#define SEARCH_LOW_12         0xb2
++#define READ_ELEMENT_STATUS   0xb8
++#define SEND_VOLUME_TAG       0xb6
++#define READ_DEFECT_DATA_12   0xb7
++#define SET_CD_SPEED          0xbb
++#define MECHANISM_STATUS      0xbd
++#define READ_CD               0xbe
++#define SEND_DVD_STRUCTURE    0xbf
++
++/*
++ * SERVICE ACTION IN subcodes
++ */
++#define SAI_READ_CAPACITY_16  0x10
++
++/*
++ * READ POSITION service action codes
++ */
++#define SHORT_FORM_BLOCK_ID  0x00
++#define SHORT_FORM_VENDOR_SPECIFIC 0x01
++#define LONG_FORM            0x06
++#define EXTENDED_FORM        0x08
++
++/*
++ *  SAM Status codes
++ */
++
++#define GOOD                 0x00
++#define CHECK_CONDITION      0x02
++#define CONDITION_GOOD       0x04
++#define BUSY                 0x08
++#define INTERMEDIATE_GOOD    0x10
++#define INTERMEDIATE_C_GOOD  0x14
++#define RESERVATION_CONFLICT 0x18
++#define COMMAND_TERMINATED   0x22
++#define TASK_SET_FULL        0x28
++#define ACA_ACTIVE           0x30
++#define TASK_ABORTED         0x40
++
++#define STATUS_MASK          0x3e
++
++/*
++ *  SENSE KEYS
++ */
++
++#define NO_SENSE            0x00
++#define RECOVERED_ERROR     0x01
++#define NOT_READY           0x02
++#define MEDIUM_ERROR        0x03
++#define HARDWARE_ERROR      0x04
++#define ILLEGAL_REQUEST     0x05
++#define UNIT_ATTENTION      0x06
++#define DATA_PROTECT        0x07
++#define BLANK_CHECK         0x08
++#define COPY_ABORTED        0x0a
++#define ABORTED_COMMAND     0x0b
++#define VOLUME_OVERFLOW     0x0d
++#define MISCOMPARE          0x0e
++
++
++/*
++ *  DEVICE TYPES
++ */
++
++#define TYPE_DISK           0x00
++#define TYPE_TAPE           0x01
++#define TYPE_PRINTER        0x02
++#define TYPE_PROCESSOR      0x03    /* HP scanners use this */
++#define TYPE_WORM           0x04    /* Treated as ROM by our system */
++#define TYPE_ROM            0x05
++#define TYPE_SCANNER        0x06
++#define TYPE_MOD            0x07    /* Magneto-optical disk -
++				     * - treated as TYPE_DISK */
++#define TYPE_MEDIUM_CHANGER 0x08
++#define TYPE_STORAGE_ARRAY  0x0c    /* Storage array device */
++#define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
++#define TYPE_RBC            0x0e    /* Simplified Direct-Access Device */
++#define TYPE_OSD            0x11    /* Object-storage Device */
++#define TYPE_WLUN           0x1e    /* Well known LUN */
++#define TYPE_NOT_PRESENT    0x1f
++#define TYPE_INACTIVE       0x20
++#define TYPE_NO_LUN         0x7f
++
++/* Mode page codes for mode sense/set */
++#define MODE_PAGE_R_W_ERROR                   0x01
++#define MODE_PAGE_HD_GEOMETRY                 0x04
++#define MODE_PAGE_FLEXIBLE_DISK_GEOMETRY      0x05
++#define MODE_PAGE_CACHING                     0x08
++#define MODE_PAGE_AUDIO_CTL                   0x0e
++#define MODE_PAGE_POWER                       0x1a
++#define MODE_PAGE_FAULT_FAIL                  0x1c
++#define MODE_PAGE_TO_PROTECT                  0x1d
++#define MODE_PAGE_CAPABILITIES                0x2a
++#define MODE_PAGE_ALLS                        0x3f
++/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
++ * of MODE_PAGE_SENSE_POWER */
++#define MODE_PAGE_CDROM                       0x0d
++
++/* Event notification classes for GET EVENT STATUS NOTIFICATION */
++#define GESN_NO_EVENTS                0
++#define GESN_OPERATIONAL_CHANGE       1
++#define GESN_POWER_MANAGEMENT         2
++#define GESN_EXTERNAL_REQUEST         3
++#define GESN_MEDIA                    4
++#define GESN_MULTIPLE_HOSTS           5
++#define GESN_DEVICE_BUSY              6
++
++/* Event codes for MEDIA event status notification */
++#define MEC_NO_CHANGE                 0
++#define MEC_EJECT_REQUESTED           1
++#define MEC_NEW_MEDIA                 2
++#define MEC_MEDIA_REMOVAL             3 /* only for media changers */
++#define MEC_MEDIA_CHANGED             4 /* only for media changers */
++#define MEC_BG_FORMAT_COMPLETED       5 /* MRW or DVD+RW b/g format completed */
++#define MEC_BG_FORMAT_RESTARTED       6 /* MRW or DVD+RW b/g format restarted */
++
++#define MS_TRAY_OPEN                  1
++#define MS_MEDIA_PRESENT              2
++
++/*
++ * Based on values from <linux/cdrom.h> but extending CD_MINS
++ * to the maximum common size allowed by the Orange's Book ATIP
++ *
++ * 90 and 99 min CDs are also available but using them as the
++ * upper limit reduces the effectiveness of the heuristic to
++ * detect DVDs burned to less than 25% of their maximum capacity
++ */
++
++/* Some generally useful CD-ROM information */
++#define CD_MINS                       80 /* max. minutes per CD */
++#define CD_SECS                       60 /* seconds per minute */
++#define CD_FRAMES                     75 /* frames per second */
++#define CD_FRAMESIZE                2048 /* bytes per frame, "cooked" mode */
++#define CD_MAX_BYTES       (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE)
++#define CD_MAX_SECTORS     (CD_MAX_BYTES / 512)
++
++/*
++ * The MMC values are not IDE specific and might need to be moved
++ * to a common header if they are also needed for the SCSI emulation
++ */
++
++/* Profile list from MMC-6 revision 1 table 91 */
++#define MMC_PROFILE_NONE                0x0000
++#define MMC_PROFILE_CD_ROM              0x0008
++#define MMC_PROFILE_CD_R                0x0009
++#define MMC_PROFILE_CD_RW               0x000A
++#define MMC_PROFILE_DVD_ROM             0x0010
++#define MMC_PROFILE_DVD_R_SR            0x0011
++#define MMC_PROFILE_DVD_RAM             0x0012
++#define MMC_PROFILE_DVD_RW_RO           0x0013
++#define MMC_PROFILE_DVD_RW_SR           0x0014
++#define MMC_PROFILE_DVD_R_DL_SR         0x0015
++#define MMC_PROFILE_DVD_R_DL_JR         0x0016
++#define MMC_PROFILE_DVD_RW_DL           0x0017
++#define MMC_PROFILE_DVD_DDR             0x0018
++#define MMC_PROFILE_DVD_PLUS_RW         0x001A
++#define MMC_PROFILE_DVD_PLUS_R          0x001B
++#define MMC_PROFILE_DVD_PLUS_RW_DL      0x002A
++#define MMC_PROFILE_DVD_PLUS_R_DL       0x002B
++#define MMC_PROFILE_BD_ROM              0x0040
++#define MMC_PROFILE_BD_R_SRM            0x0041
++#define MMC_PROFILE_BD_R_RRM            0x0042
++#define MMC_PROFILE_BD_RE               0x0043
++#define MMC_PROFILE_HDDVD_ROM           0x0050
++#define MMC_PROFILE_HDDVD_R             0x0051
++#define MMC_PROFILE_HDDVD_RAM           0x0052
++#define MMC_PROFILE_HDDVD_RW            0x0053
++#define MMC_PROFILE_HDDVD_R_DL          0x0058
++#define MMC_PROFILE_HDDVD_RW_DL         0x005A
++#define MMC_PROFILE_INVALID             0xFFFF
++
++#endif
+diff --git a/scsi/utils.c b/scsi/utils.c
+index 6ee9f40..fab60bd 100644
+--- a/scsi/utils.c
++++ b/scsi/utils.c
+@@ -14,7 +14,7 @@
+  */
+ 
+ #include "qemu/osdep.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "scsi/utils.h"
+ #include "qemu/bswap.h"
+ 
+diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
+index 87a3b6e..082d323 100644
+--- a/tests/virtio-scsi-test.c
++++ b/tests/virtio-scsi-test.c
+@@ -10,7 +10,7 @@
+ 
+ #include "qemu/osdep.h"
+ #include "libqtest.h"
+-#include "block/scsi.h"
++#include "scsi/constants.h"
+ #include "libqos/libqos-pc.h"
+ #include "libqos/libqos-spapr.h"
+ #include "libqos/virtio.h"
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-move-non-emulation-specific-code-to-scsi.patch b/SOURCES/kvm-scsi-move-non-emulation-specific-code-to-scsi.patch
new file mode 100644
index 0000000..7fbf795
--- /dev/null
+++ b/SOURCES/kvm-scsi-move-non-emulation-specific-code-to-scsi.patch
@@ -0,0 +1,1445 @@
+From a5ba8413e64d791d33b24a0ad7475d223e5607b6 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:44 +0100
+Subject: [PATCH 18/36] scsi: move non-emulation specific code to scsi/
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-9-pbonzini@redhat.com>
+Patchwork-id: 78081
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 08/17] scsi: move non-emulation specific code to scsi/
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+util/scsi.c includes some SCSI code that is shared by block/iscsi.c and
+hw/scsi, but the introduction of the persistent reservation helper
+will add many more instances of this.  There is also include/block/scsi.h,
+which actually is not part of the core block layer.
+
+The persistent reservation manager will also need a home.  A scsi/
+directory provides one for both the aforementioned shared code and
+the PR manager code.
+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit e5b5728cd330f533e02e483af8973ad7ffccce8b)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ MAINTAINERS            |   7 +
+ Makefile.objs          |   2 +-
+ block/iscsi.c          |   6 +-
+ hw/scsi/scsi-bus.c     | 397 ---------------------------------------
+ hw/scsi/scsi-generic.c |   8 -
+ include/block/scsi.h   |   2 -
+ include/hw/scsi/scsi.h |  94 +---------
+ include/scsi/scsi.h    |  20 --
+ include/scsi/utils.h   | 119 ++++++++++++
+ scsi/Makefile.objs     |   1 +
+ scsi/utils.c           | 492 +++++++++++++++++++++++++++++++++++++++++++++++++
+ util/Makefile.objs     |   1 -
+ util/scsi.c            |  90 ---------
+ 13 files changed, 626 insertions(+), 613 deletions(-)
+ delete mode 100644 include/scsi/scsi.h
+ create mode 100644 include/scsi/utils.h
+ create mode 100644 scsi/Makefile.objs
+ create mode 100644 scsi/utils.c
+ delete mode 100644 util/scsi.c
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 2a4e503..074da8c 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1215,6 +1215,13 @@ F: migration/block*
+ F: include/block/aio.h
+ T: git git://github.com/stefanha/qemu.git block
+ 
++Block SCSI subsystem
++M: Paolo Bonzini <pbonzini@redhat.com>
++L: qemu-block@nongnu.org
++S: Supported
++F: include/scsi/*
++F: scsi/*
++
+ Block Jobs
+ M: Jeff Cody <jcody@redhat.com>
+ L: qemu-block@nongnu.org
+diff --git a/Makefile.objs b/Makefile.objs
+index 24a4ea0..f68aa3b 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -11,7 +11,7 @@ chardev-obj-y = chardev/
+ 
+ block-obj-y += nbd/
+ block-obj-y += block.o blockjob.o
+-block-obj-y += block/
++block-obj-y += block/ scsi/
+ block-obj-y += qemu-io-cmds.o
+ block-obj-$(CONFIG_REPLICATION) += replication.o
+ 
+diff --git a/block/iscsi.c b/block/iscsi.c
+index 4bed63c..40adc3c 100644
+--- a/block/iscsi.c
++++ b/block/iscsi.c
+@@ -40,10 +40,14 @@
+ #include "qmp-commands.h"
+ #include "qapi/qmp/qstring.h"
+ #include "crypto/secret.h"
+-#include "scsi/scsi.h"
++#include "scsi/utils.h"
+ 
++/* Conflict between scsi/utils.h and libiscsi! :( */
++#define SCSI_XFER_NONE ISCSI_XFER_NONE
+ #include <iscsi/iscsi.h>
+ #include <iscsi/scsi-lowlevel.h>
++#undef SCSI_XFER_NONE
++QEMU_BUILD_BUG_ON((int)SCSI_XFER_NONE != (int)ISCSI_XFER_NONE);
+ 
+ #ifdef __linux__
+ #include <scsi/sg.h>
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 256610a..635cdf6 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -964,36 +964,6 @@ static int ata_passthrough_16_xfer(SCSIDevice *dev, uint8_t *buf)
+     return xfer * unit;
+ }
+ 
+-uint32_t scsi_data_cdb_xfer(uint8_t *buf)
+-{
+-    if ((buf[0] >> 5) == 0 && buf[4] == 0) {
+-        return 256;
+-    } else {
+-        return scsi_cdb_xfer(buf);
+-    }
+-}
+-
+-uint32_t scsi_cdb_xfer(uint8_t *buf)
+-{
+-    switch (buf[0] >> 5) {
+-    case 0:
+-        return buf[4];
+-        break;
+-    case 1:
+-    case 2:
+-        return lduw_be_p(&buf[7]);
+-        break;
+-    case 4:
+-        return ldl_be_p(&buf[10]) & 0xffffffffULL;
+-        break;
+-    case 5:
+-        return ldl_be_p(&buf[6]) & 0xffffffffULL;
+-        break;
+-    default:
+-        return -1;
+-    }
+-}
+-
+ static int scsi_req_xfer(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
+ {
+     cmd->xfer = scsi_cdb_xfer(buf);
+@@ -1306,53 +1276,6 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
+     }
+ }
+ 
+-static uint64_t scsi_cmd_lba(SCSICommand *cmd)
+-{
+-    uint8_t *buf = cmd->buf;
+-    uint64_t lba;
+-
+-    switch (buf[0] >> 5) {
+-    case 0:
+-        lba = ldl_be_p(&buf[0]) & 0x1fffff;
+-        break;
+-    case 1:
+-    case 2:
+-    case 5:
+-        lba = ldl_be_p(&buf[2]) & 0xffffffffULL;
+-        break;
+-    case 4:
+-        lba = ldq_be_p(&buf[2]);
+-        break;
+-    default:
+-        lba = -1;
+-
+-    }
+-    return lba;
+-}
+-
+-int scsi_cdb_length(uint8_t *buf) {
+-    int cdb_len;
+-
+-    switch (buf[0] >> 5) {
+-    case 0:
+-        cdb_len = 6;
+-        break;
+-    case 1:
+-    case 2:
+-        cdb_len = 10;
+-        break;
+-    case 4:
+-        cdb_len = 16;
+-        break;
+-    case 5:
+-        cdb_len = 12;
+-        break;
+-    default:
+-        cdb_len = -1;
+-    }
+-    return cdb_len;
+-}
+-
+ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
+ {
+     int rc;
+@@ -1399,326 +1322,6 @@ void scsi_device_report_change(SCSIDevice *dev, SCSISense sense)
+     }
+ }
+ 
+-/*
+- * Predefined sense codes
+- */
+-
+-/* No sense data available */
+-const struct SCSISense sense_code_NO_SENSE = {
+-    .key = NO_SENSE , .asc = 0x00 , .ascq = 0x00
+-};
+-
+-/* LUN not ready, Manual intervention required */
+-const struct SCSISense sense_code_LUN_NOT_READY = {
+-    .key = NOT_READY, .asc = 0x04, .ascq = 0x03
+-};
+-
+-/* LUN not ready, Medium not present */
+-const struct SCSISense sense_code_NO_MEDIUM = {
+-    .key = NOT_READY, .asc = 0x3a, .ascq = 0x00
+-};
+-
+-/* LUN not ready, medium removal prevented */
+-const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED = {
+-    .key = NOT_READY, .asc = 0x53, .ascq = 0x02
+-};
+-
+-/* Hardware error, internal target failure */
+-const struct SCSISense sense_code_TARGET_FAILURE = {
+-    .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00
+-};
+-
+-/* Illegal request, invalid command operation code */
+-const struct SCSISense sense_code_INVALID_OPCODE = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x20, .ascq = 0x00
+-};
+-
+-/* Illegal request, LBA out of range */
+-const struct SCSISense sense_code_LBA_OUT_OF_RANGE = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x21, .ascq = 0x00
+-};
+-
+-/* Illegal request, Invalid field in CDB */
+-const struct SCSISense sense_code_INVALID_FIELD = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x24, .ascq = 0x00
+-};
+-
+-/* Illegal request, Invalid field in parameter list */
+-const struct SCSISense sense_code_INVALID_PARAM = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x26, .ascq = 0x00
+-};
+-
+-/* Illegal request, Parameter list length error */
+-const struct SCSISense sense_code_INVALID_PARAM_LEN = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x1a, .ascq = 0x00
+-};
+-
+-/* Illegal request, LUN not supported */
+-const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
+-};
+-
+-/* Illegal request, Saving parameters not supported */
+-const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x39, .ascq = 0x00
+-};
+-
+-/* Illegal request, Incompatible medium installed */
+-const struct SCSISense sense_code_INCOMPATIBLE_FORMAT = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00
+-};
+-
+-/* Illegal request, medium removal prevented */
+-const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x02
+-};
+-
+-/* Illegal request, Invalid Transfer Tag */
+-const struct SCSISense sense_code_INVALID_TAG = {
+-    .key = ILLEGAL_REQUEST, .asc = 0x4b, .ascq = 0x01
+-};
+-
+-/* Command aborted, I/O process terminated */
+-const struct SCSISense sense_code_IO_ERROR = {
+-    .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
+-};
+-
+-/* Command aborted, I_T Nexus loss occurred */
+-const struct SCSISense sense_code_I_T_NEXUS_LOSS = {
+-    .key = ABORTED_COMMAND, .asc = 0x29, .ascq = 0x07
+-};
+-
+-/* Command aborted, Logical Unit failure */
+-const struct SCSISense sense_code_LUN_FAILURE = {
+-    .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
+-};
+-
+-/* Command aborted, Overlapped Commands Attempted */
+-const struct SCSISense sense_code_OVERLAPPED_COMMANDS = {
+-    .key = ABORTED_COMMAND, .asc = 0x4e, .ascq = 0x00
+-};
+-
+-/* Unit attention, Capacity data has changed */
+-const struct SCSISense sense_code_CAPACITY_CHANGED = {
+-    .key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
+-};
+-
+-/* Unit attention, Power on, reset or bus device reset occurred */
+-const struct SCSISense sense_code_RESET = {
+-    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
+-};
+-
+-/* Unit attention, No medium */
+-const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = {
+-    .key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00
+-};
+-
+-/* Unit attention, Medium may have changed */
+-const struct SCSISense sense_code_MEDIUM_CHANGED = {
+-    .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
+-};
+-
+-/* Unit attention, Reported LUNs data has changed */
+-const struct SCSISense sense_code_REPORTED_LUNS_CHANGED = {
+-    .key = UNIT_ATTENTION, .asc = 0x3f, .ascq = 0x0e
+-};
+-
+-/* Unit attention, Device internal reset */
+-const struct SCSISense sense_code_DEVICE_INTERNAL_RESET = {
+-    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x04
+-};
+-
+-/* Data Protection, Write Protected */
+-const struct SCSISense sense_code_WRITE_PROTECTED = {
+-    .key = DATA_PROTECT, .asc = 0x27, .ascq = 0x00
+-};
+-
+-/* Data Protection, Space Allocation Failed Write Protect */
+-const struct SCSISense sense_code_SPACE_ALLOC_FAILED = {
+-    .key = DATA_PROTECT, .asc = 0x27, .ascq = 0x07
+-};
+-
+-/*
+- * scsi_convert_sense
+- *
+- * Convert between fixed and descriptor sense buffers
+- */
+-int scsi_convert_sense(uint8_t *in_buf, int in_len,
+-                       uint8_t *buf, int len, bool fixed)
+-{
+-    bool fixed_in;
+-    SCSISense sense;
+-    if (!fixed && len < 8) {
+-        return 0;
+-    }
+-
+-    if (in_len == 0) {
+-        sense.key = NO_SENSE;
+-        sense.asc = 0;
+-        sense.ascq = 0;
+-    } else {
+-        fixed_in = (in_buf[0] & 2) == 0;
+-
+-        if (fixed == fixed_in) {
+-            memcpy(buf, in_buf, MIN(len, in_len));
+-            return MIN(len, in_len);
+-        }
+-
+-        if (fixed_in) {
+-            sense.key = in_buf[2];
+-            sense.asc = in_buf[12];
+-            sense.ascq = in_buf[13];
+-        } else {
+-            sense.key = in_buf[1];
+-            sense.asc = in_buf[2];
+-            sense.ascq = in_buf[3];
+-        }
+-    }
+-
+-    memset(buf, 0, len);
+-    if (fixed) {
+-        /* Return fixed format sense buffer */
+-        buf[0] = 0x70;
+-        buf[2] = sense.key;
+-        buf[7] = 10;
+-        buf[12] = sense.asc;
+-        buf[13] = sense.ascq;
+-        return MIN(len, SCSI_SENSE_LEN);
+-    } else {
+-        /* Return descriptor format sense buffer */
+-        buf[0] = 0x72;
+-        buf[1] = sense.key;
+-        buf[2] = sense.asc;
+-        buf[3] = sense.ascq;
+-        return 8;
+-    }
+-}
+-
+-const char *scsi_command_name(uint8_t cmd)
+-{
+-    static const char *names[] = {
+-        [ TEST_UNIT_READY          ] = "TEST_UNIT_READY",
+-        [ REWIND                   ] = "REWIND",
+-        [ REQUEST_SENSE            ] = "REQUEST_SENSE",
+-        [ FORMAT_UNIT              ] = "FORMAT_UNIT",
+-        [ READ_BLOCK_LIMITS        ] = "READ_BLOCK_LIMITS",
+-        [ REASSIGN_BLOCKS          ] = "REASSIGN_BLOCKS/INITIALIZE ELEMENT STATUS",
+-        /* LOAD_UNLOAD and INITIALIZE_ELEMENT_STATUS use the same operation code */
+-        [ READ_6                   ] = "READ_6",
+-        [ WRITE_6                  ] = "WRITE_6",
+-        [ SET_CAPACITY             ] = "SET_CAPACITY",
+-        [ READ_REVERSE             ] = "READ_REVERSE",
+-        [ WRITE_FILEMARKS          ] = "WRITE_FILEMARKS",
+-        [ SPACE                    ] = "SPACE",
+-        [ INQUIRY                  ] = "INQUIRY",
+-        [ RECOVER_BUFFERED_DATA    ] = "RECOVER_BUFFERED_DATA",
+-        [ MAINTENANCE_IN           ] = "MAINTENANCE_IN",
+-        [ MAINTENANCE_OUT          ] = "MAINTENANCE_OUT",
+-        [ MODE_SELECT              ] = "MODE_SELECT",
+-        [ RESERVE                  ] = "RESERVE",
+-        [ RELEASE                  ] = "RELEASE",
+-        [ COPY                     ] = "COPY",
+-        [ ERASE                    ] = "ERASE",
+-        [ MODE_SENSE               ] = "MODE_SENSE",
+-        [ START_STOP               ] = "START_STOP/LOAD_UNLOAD",
+-        /* LOAD_UNLOAD and START_STOP use the same operation code */
+-        [ RECEIVE_DIAGNOSTIC       ] = "RECEIVE_DIAGNOSTIC",
+-        [ SEND_DIAGNOSTIC          ] = "SEND_DIAGNOSTIC",
+-        [ ALLOW_MEDIUM_REMOVAL     ] = "ALLOW_MEDIUM_REMOVAL",
+-        [ READ_CAPACITY_10         ] = "READ_CAPACITY_10",
+-        [ READ_10                  ] = "READ_10",
+-        [ WRITE_10                 ] = "WRITE_10",
+-        [ SEEK_10                  ] = "SEEK_10/POSITION_TO_ELEMENT",
+-        /* SEEK_10 and POSITION_TO_ELEMENT use the same operation code */
+-        [ WRITE_VERIFY_10          ] = "WRITE_VERIFY_10",
+-        [ VERIFY_10                ] = "VERIFY_10",
+-        [ SEARCH_HIGH              ] = "SEARCH_HIGH",
+-        [ SEARCH_EQUAL             ] = "SEARCH_EQUAL",
+-        [ SEARCH_LOW               ] = "SEARCH_LOW",
+-        [ SET_LIMITS               ] = "SET_LIMITS",
+-        [ PRE_FETCH                ] = "PRE_FETCH/READ_POSITION",
+-        /* READ_POSITION and PRE_FETCH use the same operation code */
+-        [ SYNCHRONIZE_CACHE        ] = "SYNCHRONIZE_CACHE",
+-        [ LOCK_UNLOCK_CACHE        ] = "LOCK_UNLOCK_CACHE",
+-        [ READ_DEFECT_DATA         ] = "READ_DEFECT_DATA/INITIALIZE_ELEMENT_STATUS_WITH_RANGE",
+-        /* READ_DEFECT_DATA and INITIALIZE_ELEMENT_STATUS_WITH_RANGE use the same operation code */
+-        [ MEDIUM_SCAN              ] = "MEDIUM_SCAN",
+-        [ COMPARE                  ] = "COMPARE",
+-        [ COPY_VERIFY              ] = "COPY_VERIFY",
+-        [ WRITE_BUFFER             ] = "WRITE_BUFFER",
+-        [ READ_BUFFER              ] = "READ_BUFFER",
+-        [ UPDATE_BLOCK             ] = "UPDATE_BLOCK",
+-        [ READ_LONG_10             ] = "READ_LONG_10",
+-        [ WRITE_LONG_10            ] = "WRITE_LONG_10",
+-        [ CHANGE_DEFINITION        ] = "CHANGE_DEFINITION",
+-        [ WRITE_SAME_10            ] = "WRITE_SAME_10",
+-        [ UNMAP                    ] = "UNMAP",
+-        [ READ_TOC                 ] = "READ_TOC",
+-        [ REPORT_DENSITY_SUPPORT   ] = "REPORT_DENSITY_SUPPORT",
+-        [ SANITIZE                 ] = "SANITIZE",
+-        [ GET_CONFIGURATION        ] = "GET_CONFIGURATION",
+-        [ LOG_SELECT               ] = "LOG_SELECT",
+-        [ LOG_SENSE                ] = "LOG_SENSE",
+-        [ MODE_SELECT_10           ] = "MODE_SELECT_10",
+-        [ RESERVE_10               ] = "RESERVE_10",
+-        [ RELEASE_10               ] = "RELEASE_10",
+-        [ MODE_SENSE_10            ] = "MODE_SENSE_10",
+-        [ PERSISTENT_RESERVE_IN    ] = "PERSISTENT_RESERVE_IN",
+-        [ PERSISTENT_RESERVE_OUT   ] = "PERSISTENT_RESERVE_OUT",
+-        [ WRITE_FILEMARKS_16       ] = "WRITE_FILEMARKS_16",
+-        [ EXTENDED_COPY            ] = "EXTENDED_COPY",
+-        [ ATA_PASSTHROUGH_16       ] = "ATA_PASSTHROUGH_16",
+-        [ ACCESS_CONTROL_IN        ] = "ACCESS_CONTROL_IN",
+-        [ ACCESS_CONTROL_OUT       ] = "ACCESS_CONTROL_OUT",
+-        [ READ_16                  ] = "READ_16",
+-        [ COMPARE_AND_WRITE        ] = "COMPARE_AND_WRITE",
+-        [ WRITE_16                 ] = "WRITE_16",
+-        [ WRITE_VERIFY_16          ] = "WRITE_VERIFY_16",
+-        [ VERIFY_16                ] = "VERIFY_16",
+-        [ PRE_FETCH_16             ] = "PRE_FETCH_16",
+-        [ SYNCHRONIZE_CACHE_16     ] = "SPACE_16/SYNCHRONIZE_CACHE_16",
+-        /* SPACE_16 and SYNCHRONIZE_CACHE_16 use the same operation code */
+-        [ LOCATE_16                ] = "LOCATE_16",
+-        [ WRITE_SAME_16            ] = "ERASE_16/WRITE_SAME_16",
+-        /* ERASE_16 and WRITE_SAME_16 use the same operation code */
+-        [ SERVICE_ACTION_IN_16     ] = "SERVICE_ACTION_IN_16",
+-        [ WRITE_LONG_16            ] = "WRITE_LONG_16",
+-        [ REPORT_LUNS              ] = "REPORT_LUNS",
+-        [ ATA_PASSTHROUGH_12       ] = "BLANK/ATA_PASSTHROUGH_12",
+-        [ MOVE_MEDIUM              ] = "MOVE_MEDIUM",
+-        [ EXCHANGE_MEDIUM          ] = "EXCHANGE MEDIUM",
+-        [ READ_12                  ] = "READ_12",
+-        [ WRITE_12                 ] = "WRITE_12",
+-        [ ERASE_12                 ] = "ERASE_12/GET_PERFORMANCE",
+-        /* ERASE_12 and GET_PERFORMANCE use the same operation code */
+-        [ SERVICE_ACTION_IN_12     ] = "SERVICE_ACTION_IN_12",
+-        [ WRITE_VERIFY_12          ] = "WRITE_VERIFY_12",
+-        [ VERIFY_12                ] = "VERIFY_12",
+-        [ SEARCH_HIGH_12           ] = "SEARCH_HIGH_12",
+-        [ SEARCH_EQUAL_12          ] = "SEARCH_EQUAL_12",
+-        [ SEARCH_LOW_12            ] = "SEARCH_LOW_12",
+-        [ READ_ELEMENT_STATUS      ] = "READ_ELEMENT_STATUS",
+-        [ SEND_VOLUME_TAG          ] = "SEND_VOLUME_TAG/SET_STREAMING",
+-        /* SEND_VOLUME_TAG and SET_STREAMING use the same operation code */
+-        [ READ_CD                  ] = "READ_CD",
+-        [ READ_DEFECT_DATA_12      ] = "READ_DEFECT_DATA_12",
+-        [ READ_DVD_STRUCTURE       ] = "READ_DVD_STRUCTURE",
+-        [ RESERVE_TRACK            ] = "RESERVE_TRACK",
+-        [ SEND_CUE_SHEET           ] = "SEND_CUE_SHEET",
+-        [ SEND_DVD_STRUCTURE       ] = "SEND_DVD_STRUCTURE",
+-        [ SET_CD_SPEED             ] = "SET_CD_SPEED",
+-        [ SET_READ_AHEAD           ] = "SET_READ_AHEAD",
+-        [ ALLOW_OVERWRITE          ] = "ALLOW_OVERWRITE",
+-        [ MECHANISM_STATUS         ] = "MECHANISM_STATUS",
+-        [ GET_EVENT_STATUS_NOTIFICATION ] = "GET_EVENT_STATUS_NOTIFICATION",
+-        [ READ_DISC_INFORMATION    ] = "READ_DISC_INFORMATION",
+-    };
+-
+-    if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL)
+-        return "*UNKNOWN*";
+-    return names[cmd];
+-}
+-
+ SCSIRequest *scsi_req_ref(SCSIRequest *req)
+ {
+     assert(req->refcount > 0);
+diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
+index 7e1cbab..7a8f500 100644
+--- a/hw/scsi/scsi-generic.c
++++ b/hw/scsi/scsi-generic.c
+@@ -36,14 +36,6 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
+ #include <scsi/sg.h>
+ #include "block/scsi.h"
+ 
+-#define SG_ERR_DRIVER_TIMEOUT  0x06
+-#define SG_ERR_DRIVER_SENSE    0x08
+-
+-#define SG_ERR_DID_OK          0x00
+-#define SG_ERR_DID_NO_CONNECT  0x01
+-#define SG_ERR_DID_BUS_BUSY    0x02
+-#define SG_ERR_DID_TIME_OUT    0x03
+-
+ #ifndef MAX_UINT
+ #define MAX_UINT ((unsigned int)-1)
+ #endif
+diff --git a/include/block/scsi.h b/include/block/scsi.h
+index cdf0a58..a141dd7 100644
+--- a/include/block/scsi.h
++++ b/include/block/scsi.h
+@@ -150,8 +150,6 @@
+ #define READ_CD               0xbe
+ #define SEND_DVD_STRUCTURE    0xbf
+ 
+-const char *scsi_command_name(uint8_t cmd);
+-
+ /*
+  * SERVICE ACTION IN subcodes
+  */
+diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
+index 6ef67fb..23a8ee6 100644
+--- a/include/hw/scsi/scsi.h
++++ b/include/hw/scsi/scsi.h
+@@ -4,45 +4,20 @@
+ #include "hw/qdev.h"
+ #include "hw/block/block.h"
+ #include "sysemu/sysemu.h"
++#include "scsi/utils.h"
+ #include "qemu/notify.h"
+ 
+ #define MAX_SCSI_DEVS	255
+ 
+-#define SCSI_CMD_BUF_SIZE      16
+-#define SCSI_SENSE_LEN         18
+-#define SCSI_SENSE_LEN_SCANNER 32
+-#define SCSI_INQUIRY_LEN       36
+-
+ typedef struct SCSIBus SCSIBus;
+ typedef struct SCSIBusInfo SCSIBusInfo;
+-typedef struct SCSICommand SCSICommand;
+ typedef struct SCSIDevice SCSIDevice;
+ typedef struct SCSIRequest SCSIRequest;
+ typedef struct SCSIReqOps SCSIReqOps;
+ 
+-enum SCSIXferMode {
+-    SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
+-    SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
+-    SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
+-};
+-
+-typedef struct SCSISense {
+-    uint8_t key;
+-    uint8_t asc;
+-    uint8_t ascq;
+-} SCSISense;
+-
+ #define SCSI_SENSE_BUF_SIZE_OLD 96
+ #define SCSI_SENSE_BUF_SIZE 252
+ 
+-struct SCSICommand {
+-    uint8_t buf[SCSI_CMD_BUF_SIZE];
+-    int len;
+-    size_t xfer;
+-    uint64_t lba;
+-    enum SCSIXferMode mode;
+-};
+-
+ struct SCSIRequest {
+     SCSIBus           *bus;
+     SCSIDevice        *dev;
+@@ -180,73 +155,6 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
+ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated);
+ void scsi_legacy_handle_cmdline(void);
+ 
+-/*
+- * Predefined sense codes
+- */
+-
+-/* No sense data available */
+-extern const struct SCSISense sense_code_NO_SENSE;
+-/* LUN not ready, Manual intervention required */
+-extern const struct SCSISense sense_code_LUN_NOT_READY;
+-/* LUN not ready, Medium not present */
+-extern const struct SCSISense sense_code_NO_MEDIUM;
+-/* LUN not ready, medium removal prevented */
+-extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
+-/* Hardware error, internal target failure */
+-extern const struct SCSISense sense_code_TARGET_FAILURE;
+-/* Illegal request, invalid command operation code */
+-extern const struct SCSISense sense_code_INVALID_OPCODE;
+-/* Illegal request, LBA out of range */
+-extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
+-/* Illegal request, Invalid field in CDB */
+-extern const struct SCSISense sense_code_INVALID_FIELD;
+-/* Illegal request, Invalid field in parameter list */
+-extern const struct SCSISense sense_code_INVALID_PARAM;
+-/* Illegal request, Parameter list length error */
+-extern const struct SCSISense sense_code_INVALID_PARAM_LEN;
+-/* Illegal request, LUN not supported */
+-extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
+-/* Illegal request, Saving parameters not supported */
+-extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
+-/* Illegal request, Incompatible format */
+-extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
+-/* Illegal request, medium removal prevented */
+-extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
+-/* Illegal request, Invalid Transfer Tag */
+-extern const struct SCSISense sense_code_INVALID_TAG;
+-/* Command aborted, I/O process terminated */
+-extern const struct SCSISense sense_code_IO_ERROR;
+-/* Command aborted, I_T Nexus loss occurred */
+-extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
+-/* Command aborted, Logical Unit failure */
+-extern const struct SCSISense sense_code_LUN_FAILURE;
+-/* Command aborted, Overlapped Commands Attempted */
+-extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
+-/* LUN not ready, Capacity data has changed */
+-extern const struct SCSISense sense_code_CAPACITY_CHANGED;
+-/* LUN not ready, Medium not present */
+-extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
+-/* Unit attention, Power on, reset or bus device reset occurred */
+-extern const struct SCSISense sense_code_RESET;
+-/* Unit attention, Medium may have changed*/
+-extern const struct SCSISense sense_code_MEDIUM_CHANGED;
+-/* Unit attention, Reported LUNs data has changed */
+-extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
+-/* Unit attention, Device internal reset */
+-extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
+-/* Data Protection, Write Protected */
+-extern const struct SCSISense sense_code_WRITE_PROTECTED;
+-/* Data Protection, Space Allocation Failed Write Protect */
+-extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
+-
+-#define SENSE_CODE(x) sense_code_ ## x
+-
+-uint32_t scsi_data_cdb_xfer(uint8_t *buf);
+-uint32_t scsi_cdb_xfer(uint8_t *buf);
+-int scsi_cdb_length(uint8_t *buf);
+-int scsi_convert_sense(uint8_t *in_buf, int in_len,
+-                       uint8_t *buf, int len, bool fixed);
+-
+ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
+                             uint32_t tag, uint32_t lun, void *hba_private);
+ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
+diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
+deleted file mode 100644
+index fe33038..0000000
+--- a/include/scsi/scsi.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-/*
+- *  SCSI helpers
+- *
+- *  Copyright 2017 Red Hat, Inc.
+- *
+- *  Authors:
+- *   Fam Zheng <famz@redhat.com>
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the Free
+- * Software Foundation; either version 2 of the License, or (at your option)
+- * any later version.
+- */
+-#ifndef QEMU_SCSI_H
+-#define QEMU_SCSI_H
+-
+-int scsi_sense_to_errno(int key, int asc, int ascq);
+-int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
+-
+-#endif
+diff --git a/include/scsi/utils.h b/include/scsi/utils.h
+new file mode 100644
+index 0000000..90bf4dc
+--- /dev/null
++++ b/include/scsi/utils.h
+@@ -0,0 +1,119 @@
++#ifndef SCSI_UTILS_H
++#define SCSI_UTILS_H 1
++
++#ifdef CONFIG_LINUX
++#include <scsi/sg.h>
++#endif
++
++#define SCSI_CMD_BUF_SIZE      16
++#define SCSI_SENSE_LEN         18
++#define SCSI_SENSE_LEN_SCANNER 32
++#define SCSI_INQUIRY_LEN       36
++
++enum SCSIXferMode {
++    SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
++    SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
++    SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
++};
++
++typedef struct SCSICommand {
++    uint8_t buf[SCSI_CMD_BUF_SIZE];
++    int len;
++    size_t xfer;
++    uint64_t lba;
++    enum SCSIXferMode mode;
++} SCSICommand;
++
++typedef struct SCSISense {
++    uint8_t key;
++    uint8_t asc;
++    uint8_t ascq;
++} SCSISense;
++
++/*
++ * Predefined sense codes
++ */
++
++/* No sense data available */
++extern const struct SCSISense sense_code_NO_SENSE;
++/* LUN not ready, Manual intervention required */
++extern const struct SCSISense sense_code_LUN_NOT_READY;
++/* LUN not ready, Medium not present */
++extern const struct SCSISense sense_code_NO_MEDIUM;
++/* LUN not ready, medium removal prevented */
++extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
++/* Hardware error, internal target failure */
++extern const struct SCSISense sense_code_TARGET_FAILURE;
++/* Illegal request, invalid command operation code */
++extern const struct SCSISense sense_code_INVALID_OPCODE;
++/* Illegal request, LBA out of range */
++extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
++/* Illegal request, Invalid field in CDB */
++extern const struct SCSISense sense_code_INVALID_FIELD;
++/* Illegal request, Invalid field in parameter list */
++extern const struct SCSISense sense_code_INVALID_PARAM;
++/* Illegal request, Parameter list length error */
++extern const struct SCSISense sense_code_INVALID_PARAM_LEN;
++/* Illegal request, LUN not supported */
++extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
++/* Illegal request, Saving parameters not supported */
++extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
++/* Illegal request, Incompatible format */
++extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
++/* Illegal request, medium removal prevented */
++extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
++/* Illegal request, Invalid Transfer Tag */
++extern const struct SCSISense sense_code_INVALID_TAG;
++/* Command aborted, I/O process terminated */
++extern const struct SCSISense sense_code_IO_ERROR;
++/* Command aborted, I_T Nexus loss occurred */
++extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
++/* Command aborted, Logical Unit failure */
++extern const struct SCSISense sense_code_LUN_FAILURE;
++/* Command aborted, Overlapped Commands Attempted */
++extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
++/* LUN not ready, Capacity data has changed */
++extern const struct SCSISense sense_code_CAPACITY_CHANGED;
++/* LUN not ready, Medium not present */
++extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
++/* Unit attention, Power on, reset or bus device reset occurred */
++extern const struct SCSISense sense_code_RESET;
++/* Unit attention, Medium may have changed*/
++extern const struct SCSISense sense_code_MEDIUM_CHANGED;
++/* Unit attention, Reported LUNs data has changed */
++extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
++/* Unit attention, Device internal reset */
++extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
++/* Data Protection, Write Protected */
++extern const struct SCSISense sense_code_WRITE_PROTECTED;
++/* Data Protection, Space Allocation Failed Write Protect */
++extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
++
++#define SENSE_CODE(x) sense_code_ ## x
++
++int scsi_sense_to_errno(int key, int asc, int ascq);
++int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
++
++int scsi_convert_sense(uint8_t *in_buf, int in_len,
++                       uint8_t *buf, int len, bool fixed);
++const char *scsi_command_name(uint8_t cmd);
++
++uint64_t scsi_cmd_lba(SCSICommand *cmd);
++uint32_t scsi_data_cdb_xfer(uint8_t *buf);
++uint32_t scsi_cdb_xfer(uint8_t *buf);
++int scsi_cdb_length(uint8_t *buf);
++
++/* Linux SG_IO interface.  */
++#ifdef CONFIG_LINUX
++#define SG_ERR_DRIVER_TIMEOUT  0x06
++#define SG_ERR_DRIVER_SENSE    0x08
++
++#define SG_ERR_DID_OK          0x00
++#define SG_ERR_DID_NO_CONNECT  0x01
++#define SG_ERR_DID_BUS_BUSY    0x02
++#define SG_ERR_DID_TIME_OUT    0x03
++
++#define SG_ERR_DRIVER_SENSE    0x08
++#endif
++
++#endif
+diff --git a/scsi/Makefile.objs b/scsi/Makefile.objs
+new file mode 100644
+index 0000000..31b82a5
+--- /dev/null
++++ b/scsi/Makefile.objs
+@@ -0,0 +1 @@
++block-obj-y += utils.o
+diff --git a/scsi/utils.c b/scsi/utils.c
+new file mode 100644
+index 0000000..2327e06
+--- /dev/null
++++ b/scsi/utils.c
+@@ -0,0 +1,492 @@
++/*
++ *  SCSI helpers
++ *
++ *  Copyright 2017 Red Hat, Inc.
++ *
++ *  Authors:
++ *   Fam Zheng <famz@redhat.com>
++ *   Paolo Bonzini <pbonzini@redhat.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2 of the License, or (at your option)
++ * any later version.
++ */
++
++#include "qemu/osdep.h"
++#include "block/scsi.h"
++#include "scsi/utils.h"
++#include "qemu/bswap.h"
++
++uint32_t scsi_data_cdb_xfer(uint8_t *buf)
++{
++    if ((buf[0] >> 5) == 0 && buf[4] == 0) {
++        return 256;
++    } else {
++        return scsi_cdb_xfer(buf);
++    }
++}
++
++uint32_t scsi_cdb_xfer(uint8_t *buf)
++{
++    switch (buf[0] >> 5) {
++    case 0:
++        return buf[4];
++        break;
++    case 1:
++    case 2:
++        return lduw_be_p(&buf[7]);
++        break;
++    case 4:
++        return ldl_be_p(&buf[10]) & 0xffffffffULL;
++        break;
++    case 5:
++        return ldl_be_p(&buf[6]) & 0xffffffffULL;
++        break;
++    default:
++        return -1;
++    }
++}
++
++uint64_t scsi_cmd_lba(SCSICommand *cmd)
++{
++    uint8_t *buf = cmd->buf;
++    uint64_t lba;
++
++    switch (buf[0] >> 5) {
++    case 0:
++        lba = ldl_be_p(&buf[0]) & 0x1fffff;
++        break;
++    case 1:
++    case 2:
++    case 5:
++        lba = ldl_be_p(&buf[2]) & 0xffffffffULL;
++        break;
++    case 4:
++        lba = ldq_be_p(&buf[2]);
++        break;
++    default:
++        lba = -1;
++
++    }
++    return lba;
++}
++
++int scsi_cdb_length(uint8_t *buf)
++{
++    int cdb_len;
++
++    switch (buf[0] >> 5) {
++    case 0:
++        cdb_len = 6;
++        break;
++    case 1:
++    case 2:
++        cdb_len = 10;
++        break;
++    case 4:
++        cdb_len = 16;
++        break;
++    case 5:
++        cdb_len = 12;
++        break;
++    default:
++        cdb_len = -1;
++    }
++    return cdb_len;
++}
++
++/*
++ * Predefined sense codes
++ */
++
++/* No sense data available */
++const struct SCSISense sense_code_NO_SENSE = {
++    .key = NO_SENSE , .asc = 0x00 , .ascq = 0x00
++};
++
++/* LUN not ready, Manual intervention required */
++const struct SCSISense sense_code_LUN_NOT_READY = {
++    .key = NOT_READY, .asc = 0x04, .ascq = 0x03
++};
++
++/* LUN not ready, Medium not present */
++const struct SCSISense sense_code_NO_MEDIUM = {
++    .key = NOT_READY, .asc = 0x3a, .ascq = 0x00
++};
++
++/* LUN not ready, medium removal prevented */
++const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED = {
++    .key = NOT_READY, .asc = 0x53, .ascq = 0x02
++};
++
++/* Hardware error, internal target failure */
++const struct SCSISense sense_code_TARGET_FAILURE = {
++    .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00
++};
++
++/* Illegal request, invalid command operation code */
++const struct SCSISense sense_code_INVALID_OPCODE = {
++    .key = ILLEGAL_REQUEST, .asc = 0x20, .ascq = 0x00
++};
++
++/* Illegal request, LBA out of range */
++const struct SCSISense sense_code_LBA_OUT_OF_RANGE = {
++    .key = ILLEGAL_REQUEST, .asc = 0x21, .ascq = 0x00
++};
++
++/* Illegal request, Invalid field in CDB */
++const struct SCSISense sense_code_INVALID_FIELD = {
++    .key = ILLEGAL_REQUEST, .asc = 0x24, .ascq = 0x00
++};
++
++/* Illegal request, Invalid field in parameter list */
++const struct SCSISense sense_code_INVALID_PARAM = {
++    .key = ILLEGAL_REQUEST, .asc = 0x26, .ascq = 0x00
++};
++
++/* Illegal request, Parameter list length error */
++const struct SCSISense sense_code_INVALID_PARAM_LEN = {
++    .key = ILLEGAL_REQUEST, .asc = 0x1a, .ascq = 0x00
++};
++
++/* Illegal request, LUN not supported */
++const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
++    .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
++};
++
++/* Illegal request, Saving parameters not supported */
++const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED = {
++    .key = ILLEGAL_REQUEST, .asc = 0x39, .ascq = 0x00
++};
++
++/* Illegal request, Incompatible medium installed */
++const struct SCSISense sense_code_INCOMPATIBLE_FORMAT = {
++    .key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00
++};
++
++/* Illegal request, medium removal prevented */
++const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED = {
++    .key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x02
++};
++
++/* Illegal request, Invalid Transfer Tag */
++const struct SCSISense sense_code_INVALID_TAG = {
++    .key = ILLEGAL_REQUEST, .asc = 0x4b, .ascq = 0x01
++};
++
++/* Command aborted, I/O process terminated */
++const struct SCSISense sense_code_IO_ERROR = {
++    .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
++};
++
++/* Command aborted, I_T Nexus loss occurred */
++const struct SCSISense sense_code_I_T_NEXUS_LOSS = {
++    .key = ABORTED_COMMAND, .asc = 0x29, .ascq = 0x07
++};
++
++/* Command aborted, Logical Unit failure */
++const struct SCSISense sense_code_LUN_FAILURE = {
++    .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
++};
++
++/* Command aborted, Overlapped Commands Attempted */
++const struct SCSISense sense_code_OVERLAPPED_COMMANDS = {
++    .key = ABORTED_COMMAND, .asc = 0x4e, .ascq = 0x00
++};
++
++/* Unit attention, Capacity data has changed */
++const struct SCSISense sense_code_CAPACITY_CHANGED = {
++    .key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
++};
++
++/* Unit attention, Power on, reset or bus device reset occurred */
++const struct SCSISense sense_code_RESET = {
++    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
++};
++
++/* Unit attention, No medium */
++const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = {
++    .key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00
++};
++
++/* Unit attention, Medium may have changed */
++const struct SCSISense sense_code_MEDIUM_CHANGED = {
++    .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
++};
++
++/* Unit attention, Reported LUNs data has changed */
++const struct SCSISense sense_code_REPORTED_LUNS_CHANGED = {
++    .key = UNIT_ATTENTION, .asc = 0x3f, .ascq = 0x0e
++};
++
++/* Unit attention, Device internal reset */
++const struct SCSISense sense_code_DEVICE_INTERNAL_RESET = {
++    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x04
++};
++
++/* Data Protection, Write Protected */
++const struct SCSISense sense_code_WRITE_PROTECTED = {
++    .key = DATA_PROTECT, .asc = 0x27, .ascq = 0x00
++};
++
++/* Data Protection, Space Allocation Failed Write Protect */
++const struct SCSISense sense_code_SPACE_ALLOC_FAILED = {
++    .key = DATA_PROTECT, .asc = 0x27, .ascq = 0x07
++};
++
++/*
++ * scsi_convert_sense
++ *
++ * Convert between fixed and descriptor sense buffers
++ */
++int scsi_convert_sense(uint8_t *in_buf, int in_len,
++                       uint8_t *buf, int len, bool fixed)
++{
++    bool fixed_in;
++    SCSISense sense;
++    if (!fixed && len < 8) {
++        return 0;
++    }
++
++    if (in_len == 0) {
++        sense.key = NO_SENSE;
++        sense.asc = 0;
++        sense.ascq = 0;
++    } else {
++        fixed_in = (in_buf[0] & 2) == 0;
++
++        if (fixed == fixed_in) {
++            memcpy(buf, in_buf, MIN(len, in_len));
++            return MIN(len, in_len);
++        }
++
++        if (fixed_in) {
++            sense.key = in_buf[2];
++            sense.asc = in_buf[12];
++            sense.ascq = in_buf[13];
++        } else {
++            sense.key = in_buf[1];
++            sense.asc = in_buf[2];
++            sense.ascq = in_buf[3];
++        }
++    }
++
++    memset(buf, 0, len);
++    if (fixed) {
++        /* Return fixed format sense buffer */
++        buf[0] = 0x70;
++        buf[2] = sense.key;
++        buf[7] = 10;
++        buf[12] = sense.asc;
++        buf[13] = sense.ascq;
++        return MIN(len, SCSI_SENSE_LEN);
++    } else {
++        /* Return descriptor format sense buffer */
++        buf[0] = 0x72;
++        buf[1] = sense.key;
++        buf[2] = sense.asc;
++        buf[3] = sense.ascq;
++        return 8;
++    }
++}
++
++int scsi_sense_to_errno(int key, int asc, int ascq)
++{
++    switch (key) {
++    case 0x00: /* NO SENSE */
++    case 0x01: /* RECOVERED ERROR */
++    case 0x06: /* UNIT ATTENTION */
++        /* These sense keys are not errors */
++        return 0;
++    case 0x0b: /* COMMAND ABORTED */
++        return ECANCELED;
++    case 0x02: /* NOT READY */
++    case 0x05: /* ILLEGAL REQUEST */
++    case 0x07: /* DATA PROTECTION */
++        /* Parse ASCQ */
++        break;
++    default:
++        return EIO;
++    }
++    switch ((asc << 8) | ascq) {
++    case 0x1a00: /* PARAMETER LIST LENGTH ERROR */
++    case 0x2000: /* INVALID OPERATION CODE */
++    case 0x2400: /* INVALID FIELD IN CDB */
++    case 0x2600: /* INVALID FIELD IN PARAMETER LIST */
++        return EINVAL;
++    case 0x2100: /* LBA OUT OF RANGE */
++    case 0x2707: /* SPACE ALLOC FAILED */
++        return ENOSPC;
++    case 0x2500: /* LOGICAL UNIT NOT SUPPORTED */
++        return ENOTSUP;
++    case 0x3a00: /* MEDIUM NOT PRESENT */
++    case 0x3a01: /* MEDIUM NOT PRESENT TRAY CLOSED */
++    case 0x3a02: /* MEDIUM NOT PRESENT TRAY OPEN */
++        return ENOMEDIUM;
++    case 0x2700: /* WRITE PROTECTED */
++        return EACCES;
++    case 0x0401: /* NOT READY, IN PROGRESS OF BECOMING READY */
++        return EAGAIN;
++    case 0x0402: /* NOT READY, INITIALIZING COMMAND REQUIRED */
++        return ENOTCONN;
++    default:
++        return EIO;
++    }
++}
++
++int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size)
++{
++    int key, asc, ascq;
++    if (sense_size < 1) {
++        return EIO;
++    }
++    switch (sense[0]) {
++    case 0x70: /* Fixed format sense data. */
++        if (sense_size < 14) {
++            return EIO;
++        }
++        key = sense[2] & 0xF;
++        asc = sense[12];
++        ascq = sense[13];
++        break;
++    case 0x72: /* Descriptor format sense data. */
++        if (sense_size < 4) {
++            return EIO;
++        }
++        key = sense[1] & 0xF;
++        asc = sense[2];
++        ascq = sense[3];
++        break;
++    default:
++        return EIO;
++        break;
++    }
++    return scsi_sense_to_errno(key, asc, ascq);
++}
++
++const char *scsi_command_name(uint8_t cmd)
++{
++    static const char *names[] = {
++        [ TEST_UNIT_READY          ] = "TEST_UNIT_READY",
++        [ REWIND                   ] = "REWIND",
++        [ REQUEST_SENSE            ] = "REQUEST_SENSE",
++        [ FORMAT_UNIT              ] = "FORMAT_UNIT",
++        [ READ_BLOCK_LIMITS        ] = "READ_BLOCK_LIMITS",
++        [ REASSIGN_BLOCKS          ] = "REASSIGN_BLOCKS/INITIALIZE ELEMENT STATUS",
++        /* LOAD_UNLOAD and INITIALIZE_ELEMENT_STATUS use the same operation code */
++        [ READ_6                   ] = "READ_6",
++        [ WRITE_6                  ] = "WRITE_6",
++        [ SET_CAPACITY             ] = "SET_CAPACITY",
++        [ READ_REVERSE             ] = "READ_REVERSE",
++        [ WRITE_FILEMARKS          ] = "WRITE_FILEMARKS",
++        [ SPACE                    ] = "SPACE",
++        [ INQUIRY                  ] = "INQUIRY",
++        [ RECOVER_BUFFERED_DATA    ] = "RECOVER_BUFFERED_DATA",
++        [ MAINTENANCE_IN           ] = "MAINTENANCE_IN",
++        [ MAINTENANCE_OUT          ] = "MAINTENANCE_OUT",
++        [ MODE_SELECT              ] = "MODE_SELECT",
++        [ RESERVE                  ] = "RESERVE",
++        [ RELEASE                  ] = "RELEASE",
++        [ COPY                     ] = "COPY",
++        [ ERASE                    ] = "ERASE",
++        [ MODE_SENSE               ] = "MODE_SENSE",
++        [ START_STOP               ] = "START_STOP/LOAD_UNLOAD",
++        /* LOAD_UNLOAD and START_STOP use the same operation code */
++        [ RECEIVE_DIAGNOSTIC       ] = "RECEIVE_DIAGNOSTIC",
++        [ SEND_DIAGNOSTIC          ] = "SEND_DIAGNOSTIC",
++        [ ALLOW_MEDIUM_REMOVAL     ] = "ALLOW_MEDIUM_REMOVAL",
++        [ READ_CAPACITY_10         ] = "READ_CAPACITY_10",
++        [ READ_10                  ] = "READ_10",
++        [ WRITE_10                 ] = "WRITE_10",
++        [ SEEK_10                  ] = "SEEK_10/POSITION_TO_ELEMENT",
++        /* SEEK_10 and POSITION_TO_ELEMENT use the same operation code */
++        [ WRITE_VERIFY_10          ] = "WRITE_VERIFY_10",
++        [ VERIFY_10                ] = "VERIFY_10",
++        [ SEARCH_HIGH              ] = "SEARCH_HIGH",
++        [ SEARCH_EQUAL             ] = "SEARCH_EQUAL",
++        [ SEARCH_LOW               ] = "SEARCH_LOW",
++        [ SET_LIMITS               ] = "SET_LIMITS",
++        [ PRE_FETCH                ] = "PRE_FETCH/READ_POSITION",
++        /* READ_POSITION and PRE_FETCH use the same operation code */
++        [ SYNCHRONIZE_CACHE        ] = "SYNCHRONIZE_CACHE",
++        [ LOCK_UNLOCK_CACHE        ] = "LOCK_UNLOCK_CACHE",
++        [ READ_DEFECT_DATA         ] = "READ_DEFECT_DATA/INITIALIZE_ELEMENT_STATUS_WITH_RANGE",
++        /* READ_DEFECT_DATA and INITIALIZE_ELEMENT_STATUS_WITH_RANGE use the same operation code */
++        [ MEDIUM_SCAN              ] = "MEDIUM_SCAN",
++        [ COMPARE                  ] = "COMPARE",
++        [ COPY_VERIFY              ] = "COPY_VERIFY",
++        [ WRITE_BUFFER             ] = "WRITE_BUFFER",
++        [ READ_BUFFER              ] = "READ_BUFFER",
++        [ UPDATE_BLOCK             ] = "UPDATE_BLOCK",
++        [ READ_LONG_10             ] = "READ_LONG_10",
++        [ WRITE_LONG_10            ] = "WRITE_LONG_10",
++        [ CHANGE_DEFINITION        ] = "CHANGE_DEFINITION",
++        [ WRITE_SAME_10            ] = "WRITE_SAME_10",
++        [ UNMAP                    ] = "UNMAP",
++        [ READ_TOC                 ] = "READ_TOC",
++        [ REPORT_DENSITY_SUPPORT   ] = "REPORT_DENSITY_SUPPORT",
++        [ SANITIZE                 ] = "SANITIZE",
++        [ GET_CONFIGURATION        ] = "GET_CONFIGURATION",
++        [ LOG_SELECT               ] = "LOG_SELECT",
++        [ LOG_SENSE                ] = "LOG_SENSE",
++        [ MODE_SELECT_10           ] = "MODE_SELECT_10",
++        [ RESERVE_10               ] = "RESERVE_10",
++        [ RELEASE_10               ] = "RELEASE_10",
++        [ MODE_SENSE_10            ] = "MODE_SENSE_10",
++        [ PERSISTENT_RESERVE_IN    ] = "PERSISTENT_RESERVE_IN",
++        [ PERSISTENT_RESERVE_OUT   ] = "PERSISTENT_RESERVE_OUT",
++        [ WRITE_FILEMARKS_16       ] = "WRITE_FILEMARKS_16",
++        [ EXTENDED_COPY            ] = "EXTENDED_COPY",
++        [ ATA_PASSTHROUGH_16       ] = "ATA_PASSTHROUGH_16",
++        [ ACCESS_CONTROL_IN        ] = "ACCESS_CONTROL_IN",
++        [ ACCESS_CONTROL_OUT       ] = "ACCESS_CONTROL_OUT",
++        [ READ_16                  ] = "READ_16",
++        [ COMPARE_AND_WRITE        ] = "COMPARE_AND_WRITE",
++        [ WRITE_16                 ] = "WRITE_16",
++        [ WRITE_VERIFY_16          ] = "WRITE_VERIFY_16",
++        [ VERIFY_16                ] = "VERIFY_16",
++        [ PRE_FETCH_16             ] = "PRE_FETCH_16",
++        [ SYNCHRONIZE_CACHE_16     ] = "SPACE_16/SYNCHRONIZE_CACHE_16",
++        /* SPACE_16 and SYNCHRONIZE_CACHE_16 use the same operation code */
++        [ LOCATE_16                ] = "LOCATE_16",
++        [ WRITE_SAME_16            ] = "ERASE_16/WRITE_SAME_16",
++        /* ERASE_16 and WRITE_SAME_16 use the same operation code */
++        [ SERVICE_ACTION_IN_16     ] = "SERVICE_ACTION_IN_16",
++        [ WRITE_LONG_16            ] = "WRITE_LONG_16",
++        [ REPORT_LUNS              ] = "REPORT_LUNS",
++        [ ATA_PASSTHROUGH_12       ] = "BLANK/ATA_PASSTHROUGH_12",
++        [ MOVE_MEDIUM              ] = "MOVE_MEDIUM",
++        [ EXCHANGE_MEDIUM          ] = "EXCHANGE MEDIUM",
++        [ READ_12                  ] = "READ_12",
++        [ WRITE_12                 ] = "WRITE_12",
++        [ ERASE_12                 ] = "ERASE_12/GET_PERFORMANCE",
++        /* ERASE_12 and GET_PERFORMANCE use the same operation code */
++        [ SERVICE_ACTION_IN_12     ] = "SERVICE_ACTION_IN_12",
++        [ WRITE_VERIFY_12          ] = "WRITE_VERIFY_12",
++        [ VERIFY_12                ] = "VERIFY_12",
++        [ SEARCH_HIGH_12           ] = "SEARCH_HIGH_12",
++        [ SEARCH_EQUAL_12          ] = "SEARCH_EQUAL_12",
++        [ SEARCH_LOW_12            ] = "SEARCH_LOW_12",
++        [ READ_ELEMENT_STATUS      ] = "READ_ELEMENT_STATUS",
++        [ SEND_VOLUME_TAG          ] = "SEND_VOLUME_TAG/SET_STREAMING",
++        /* SEND_VOLUME_TAG and SET_STREAMING use the same operation code */
++        [ READ_CD                  ] = "READ_CD",
++        [ READ_DEFECT_DATA_12      ] = "READ_DEFECT_DATA_12",
++        [ READ_DVD_STRUCTURE       ] = "READ_DVD_STRUCTURE",
++        [ RESERVE_TRACK            ] = "RESERVE_TRACK",
++        [ SEND_CUE_SHEET           ] = "SEND_CUE_SHEET",
++        [ SEND_DVD_STRUCTURE       ] = "SEND_DVD_STRUCTURE",
++        [ SET_CD_SPEED             ] = "SET_CD_SPEED",
++        [ SET_READ_AHEAD           ] = "SET_READ_AHEAD",
++        [ ALLOW_OVERWRITE          ] = "ALLOW_OVERWRITE",
++        [ MECHANISM_STATUS         ] = "MECHANISM_STATUS",
++        [ GET_EVENT_STATUS_NOTIFICATION ] = "GET_EVENT_STATUS_NOTIFICATION",
++        [ READ_DISC_INFORMATION    ] = "READ_DISC_INFORMATION",
++    };
++
++    if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL) {
++        return "*UNKNOWN*";
++    }
++    return names[cmd];
++}
+diff --git a/util/Makefile.objs b/util/Makefile.objs
+index c9e6c49..50a55ec 100644
+--- a/util/Makefile.objs
++++ b/util/Makefile.objs
+@@ -45,4 +45,3 @@ util-obj-y += qht.o
+ util-obj-y += range.o
+ util-obj-y += stats64.o
+ util-obj-y += systemd.o
+-util-obj-y += scsi.o
+diff --git a/util/scsi.c b/util/scsi.c
+deleted file mode 100644
+index 472293d..0000000
+--- a/util/scsi.c
++++ /dev/null
+@@ -1,90 +0,0 @@
+-/*
+- *  SCSI helpers
+- *
+- *  Copyright 2017 Red Hat, Inc.
+- *
+- *  Authors:
+- *   Fam Zheng <famz@redhat.com>
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the Free
+- * Software Foundation; either version 2 of the License, or (at your option)
+- * any later version.
+- */
+-
+-#include "qemu/osdep.h"
+-#include "scsi/scsi.h"
+-
+-int scsi_sense_to_errno(int key, int asc, int ascq)
+-{
+-    switch (key) {
+-    case 0x00: /* NO SENSE */
+-    case 0x01: /* RECOVERED ERROR */
+-    case 0x06: /* UNIT ATTENTION */
+-        /* These sense keys are not errors */
+-        return 0;
+-    case 0x0b: /* COMMAND ABORTED */
+-        return ECANCELED;
+-    case 0x02: /* NOT READY */
+-    case 0x05: /* ILLEGAL REQUEST */
+-    case 0x07: /* DATA PROTECTION */
+-        /* Parse ASCQ */
+-        break;
+-    default:
+-        return EIO;
+-    }
+-    switch ((asc << 8) | ascq) {
+-    case 0x1a00: /* PARAMETER LIST LENGTH ERROR */
+-    case 0x2000: /* INVALID OPERATION CODE */
+-    case 0x2400: /* INVALID FIELD IN CDB */
+-    case 0x2600: /* INVALID FIELD IN PARAMETER LIST */
+-        return EINVAL;
+-    case 0x2100: /* LBA OUT OF RANGE */
+-    case 0x2707: /* SPACE ALLOC FAILED */
+-        return ENOSPC;
+-    case 0x2500: /* LOGICAL UNIT NOT SUPPORTED */
+-        return ENOTSUP;
+-    case 0x3a00: /* MEDIUM NOT PRESENT */
+-    case 0x3a01: /* MEDIUM NOT PRESENT TRAY CLOSED */
+-    case 0x3a02: /* MEDIUM NOT PRESENT TRAY OPEN */
+-        return ENOMEDIUM;
+-    case 0x2700: /* WRITE PROTECTED */
+-        return EACCES;
+-    case 0x0401: /* NOT READY, IN PROGRESS OF BECOMING READY */
+-        return EAGAIN;
+-    case 0x0402: /* NOT READY, INITIALIZING COMMAND REQUIRED */
+-        return ENOTCONN;
+-    default:
+-        return EIO;
+-    }
+-}
+-
+-int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size)
+-{
+-    int key, asc, ascq;
+-    if (sense_size < 1) {
+-        return EIO;
+-    }
+-    switch (sense[0]) {
+-    case 0x70: /* Fixed format sense data. */
+-        if (sense_size < 14) {
+-            return EIO;
+-        }
+-        key = sense[2] & 0xF;
+-        asc = sense[12];
+-        ascq = sense[13];
+-        break;
+-    case 0x72: /* Descriptor format sense data. */
+-        if (sense_size < 4) {
+-            return EIO;
+-        }
+-        key = sense[1] & 0xF;
+-        asc = sense[2];
+-        ascq = sense[3];
+-        break;
+-    default:
+-        return EIO;
+-        break;
+-    }
+-    return scsi_sense_to_errno(key, asc, ascq);
+-}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-scsi-rename-scsi_build_sense-to-scsi_convert_sense.patch b/SOURCES/kvm-scsi-rename-scsi_build_sense-to-scsi_convert_sense.patch
new file mode 100644
index 0000000..539a71f
--- /dev/null
+++ b/SOURCES/kvm-scsi-rename-scsi_build_sense-to-scsi_convert_sense.patch
@@ -0,0 +1,103 @@
+From ddae0e4b41b8bdf17934bce837558bb8eeecb2ea Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 2 Dec 2017 12:19:43 +0100
+Subject: [PATCH 17/36] scsi: rename scsi_build_sense to scsi_convert_sense
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20171202121953.13317-8-pbonzini@redhat.com>
+Patchwork-id: 78079
+O-Subject: [RHEL7.4 qemu-kvm-rhev PATCH 07/17] scsi: rename scsi_build_sense to scsi_convert_sense
+Bugzilla: 1464908
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+After introducing the scsi/ subdirectory, there will be a scsi_build_sense
+function that is the same as scsi_req_build_sense but without needing
+a SCSIRequest.  The existing scsi_build_sense function gets in the way,
+remove it.
+
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 37b6045c455275af37f0433b05b0dad123e14daf)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/scsi/scsi-bus.c     | 10 +++++-----
+ hw/scsi/scsi-disk.c    |  4 ++--
+ include/hw/scsi/scsi.h |  4 ++--
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 55aa5a7..256610a 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -798,7 +798,7 @@ int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
+         return 0;
+     }
+ 
+-    ret = scsi_build_sense(req->sense, req->sense_len, buf, len, true);
++    ret = scsi_convert_sense(req->sense, req->sense_len, buf, len, true);
+ 
+     /*
+      * FIXME: clearing unit attention conditions upon autosense should be done
+@@ -819,7 +819,7 @@ int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
+ 
+ int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
+ {
+-    return scsi_build_sense(dev->sense, dev->sense_len, buf, len, fixed);
++    return scsi_convert_sense(dev->sense, dev->sense_len, buf, len, fixed);
+ }
+ 
+ void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
+@@ -1539,12 +1539,12 @@ const struct SCSISense sense_code_SPACE_ALLOC_FAILED = {
+ };
+ 
+ /*
+- * scsi_build_sense
++ * scsi_convert_sense
+  *
+  * Convert between fixed and descriptor sense buffers
+  */
+-int scsi_build_sense(uint8_t *in_buf, int in_len,
+-                     uint8_t *buf, int len, bool fixed)
++int scsi_convert_sense(uint8_t *in_buf, int in_len,
++                       uint8_t *buf, int len, bool fixed)
+ {
+     bool fixed_in;
+     SCSISense sense;
+diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
+index 21d6b4e..b7714e3 100644
+--- a/hw/scsi/scsi-disk.c
++++ b/hw/scsi/scsi-disk.c
+@@ -1996,8 +1996,8 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
+         break;
+     case REQUEST_SENSE:
+         /* Just return "NO SENSE".  */
+-        buflen = scsi_build_sense(NULL, 0, outbuf, r->buflen,
+-                                  (req->cmd.buf[1] & 1) == 0);
++        buflen = scsi_convert_sense(NULL, 0, outbuf, r->buflen,
++                                    (req->cmd.buf[1] & 1) == 0);
+         if (buflen < 0) {
+             goto illegal_request;
+         }
+diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
+index 6b85786..6ef67fb 100644
+--- a/include/hw/scsi/scsi.h
++++ b/include/hw/scsi/scsi.h
+@@ -244,8 +244,8 @@ extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
+ uint32_t scsi_data_cdb_xfer(uint8_t *buf);
+ uint32_t scsi_cdb_xfer(uint8_t *buf);
+ int scsi_cdb_length(uint8_t *buf);
+-int scsi_build_sense(uint8_t *in_buf, int in_len,
+-                     uint8_t *buf, int len, bool fixed);
++int scsi_convert_sense(uint8_t *in_buf, int in_len,
++                       uint8_t *buf, int len, bool fixed);
+ 
+ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
+                             uint32_t tag, uint32_t lun, void *hba_private);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-serial-always-transmit-send-receive-buffers-on-migra.patch b/SOURCES/kvm-serial-always-transmit-send-receive-buffers-on-migra.patch
new file mode 100644
index 0000000..05a68c7
--- /dev/null
+++ b/SOURCES/kvm-serial-always-transmit-send-receive-buffers-on-migra.patch
@@ -0,0 +1,93 @@
+From b1163e497bdb3d6f04593940b6ec7842ec35c8ff Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 11 Jan 2018 13:56:44 +0100
+Subject: [PATCH 01/21] serial: always transmit send/receive buffers on
+ migration
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20180111135644.16253-1-pbonzini@redhat.com>
+Patchwork-id: 78551
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH v2] serial: always transmit send/receive buffers on migration
+Bugzilla: 1459945
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+When subsections were added in qemu 2.3, they were all disabled
+for machine types that require pre-2.3 compatibility.  The commit
+message says "disabling these subsections on older machine types should
+leave it no worse than existing qemu", but actually migrating from
+new QEMU to new QEMU (but with old machine type) will detect an
+inconsistent migration state and fail the migration:
+
+   qemu-system-x86_64: inconsistent state in serial device (tsr not empty, tsr_retry=0
+   qemu-system-x86_64: Failed to load serial:state
+   qemu-system-x86_64: error while loading state for instance 0x0 of device 'serial'
+
+In fact, this shows that migration from new source to old destination
+might have also eaten the data in the FIFO or transmit/receive buffers.
+
+It's actually pretty easy to trigger the failure by connecting a console
+to a hung-up reader (not a *disconnected* reader!).  The fix is to
+handle the subsections the same as we did in the qemu-kvm BZ1452067.
+The data registers are migrated, which may indeed cause some more migrations
+to fail to old qemu-kvm-rhev, but it will fix migration to new qemu-kvm-rhev.
+Some subsections are still keyed on migrate_pre_2_2; from the commit message
+of downstream commit 7d2e8f9662feb64c0b15b6fd53e06e3c56921f27:
+
+    thr_ipending can be reconstructed fairly
+    reliably by serial_post_load.  The others are features that are
+    unlikely to be used in RHEL, respectively receive timeout (Linux
+    does not even have the UART_IIR_CTI symbol in the driver) and
+    physical serial ports connected to a modem
+
+I consider this okay because nobody has yet complained about it for
+qemu-kvm.  It's also safer because the failure avoids serial data loss
+on migration.  This is consistent with the intended use of subsections.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/char/serial.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/hw/char/serial.c b/hw/char/serial.c
+index fe4f41d..d82f7eb 100644
+--- a/hw/char/serial.c
++++ b/hw/char/serial.c
+@@ -720,10 +720,6 @@ static const VMStateDescription vmstate_serial_thr_ipending = {
+ static bool serial_tsr_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
+-    if (migrate_pre_2_2) {
+-        return false;
+-    }
+-
+     return s->tsr_retry != 0;
+ }
+ 
+@@ -743,10 +739,6 @@ static const VMStateDescription vmstate_serial_tsr = {
+ static bool serial_recv_fifo_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
+-    if (migrate_pre_2_2) {
+-        return false;
+-    }
+-
+     return !fifo8_is_empty(&s->recv_fifo);
+ 
+ }
+@@ -765,10 +757,6 @@ static const VMStateDescription vmstate_serial_recv_fifo = {
+ static bool serial_xmit_fifo_needed(void *opaque)
+ {
+     SerialState *s = (SerialState *)opaque;
+-    if (migrate_pre_2_2) {
+-        return false;
+-    }
+-
+     return !fifo8_is_empty(&s->xmit_fifo);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-setup b/SOURCES/kvm-setup
new file mode 100644
index 0000000..abbd587
--- /dev/null
+++ b/SOURCES/kvm-setup
@@ -0,0 +1,40 @@
+#! /bin/bash
+
+kvm_setup_powerpc () {
+    if grep '^platform[[:space:]]*:[[:space:]]*PowerNV' /proc/cpuinfo > /dev/null; then
+	# PowerNV platform, which is KVM HV capable
+
+	if [ -z "$SUBCORES" ]; then
+	    SUBCORES=1
+	fi
+
+	# Step 1. Load the KVM HVmodule
+	if ! modprobe -b kvm_hv; then
+	    return
+	fi
+
+	# On POWER8 a host core can only run threads of a single
+	# guest, meaning that SMT must be disabled on the host in
+	# order to run KVM guests. (Also applieds to POWER7, but we
+	# don't support that).
+	#
+	# POWER9 doesn't have this limitation (though it will for hash
+	# guests on radix host when that's implemented).  So, only set
+	# up subcores and disable SMT for POWER*.
+	if grep '^cpu[[:space:]]*:[[:space:]]*POWER8' /proc/cpuinfo > /dev/null; then
+	    # Step 2. Configure subcore mode
+	    /usr/sbin/ppc64_cpu --subcores-per-core=$SUBCORES
+
+	    # Step 3. Disable SMT (multithreading)
+	    /usr/sbin/ppc64_cpu --smt=off
+	fi
+    fi
+}
+
+case $(uname -m) in
+    ppc64|ppc64le)
+	kvm_setup_powerpc
+	;;
+esac
+
+exit 0
diff --git a/SOURCES/kvm-setup.service b/SOURCES/kvm-setup.service
new file mode 100644
index 0000000..9c4bf97
--- /dev/null
+++ b/SOURCES/kvm-setup.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Perform system configuration to prepare system to run KVM guests
+# Offlining CPUs can cause irqbalance to throw warnings if it's running
+Before=irqbalance.service
+# libvirtd reads CPU topology at startup, so change it before
+Before=libvirtd.service
+
+[Service]
+Type=oneshot
+EnvironmentFile=-/etc/sysconfig/kvm
+ExecStart=/usr/lib/systemd/kvm-setup
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/kvm-slirp-fix-clearing-ifq_so-from-pending-packets.patch b/SOURCES/kvm-slirp-fix-clearing-ifq_so-from-pending-packets.patch
new file mode 100644
index 0000000..77ff6c7
--- /dev/null
+++ b/SOURCES/kvm-slirp-fix-clearing-ifq_so-from-pending-packets.patch
@@ -0,0 +1,93 @@
+From fab160fce838f609b3a395fcef40e4efce5c0fa7 Mon Sep 17 00:00:00 2001
+From: Xiao Wang <jasowang@redhat.com>
+Date: Tue, 28 Nov 2017 03:43:20 +0100
+Subject: [PATCH 14/21] slirp: fix clearing ifq_so from pending packets
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Xiao Wang <jasowang@redhat.com>
+Message-id: <1511840600-52375-1-git-send-email-jasowang@redhat.com>
+Patchwork-id: 77930
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] slirp: fix clearing ifq_so from pending packets
+Bugzilla: 1508750
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: wexu@redhat.com
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+The if_fastq and if_batchq contain not only packets, but queues of packets
+for the same socket. When sofree frees a socket, it thus has to clear ifq_so
+from all the packets from the queues, not only the first.
+
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit 1201d308519f1e915866d7583d5136d03cc1d384)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/socket.c | 39 +++++++++++++++++++++++----------------
+ 1 file changed, 23 insertions(+), 16 deletions(-)
+
+diff --git a/slirp/socket.c b/slirp/socket.c
+index ecec029..cb7b5b6 100644
+--- a/slirp/socket.c
++++ b/slirp/socket.c
+@@ -60,29 +60,36 @@ socreate(Slirp *slirp)
+ }
+ 
+ /*
++ * Remove references to so from the given message queue.
++ */
++static void
++soqfree(struct socket *so, struct quehead *qh)
++{
++    struct mbuf *ifq;
++
++    for (ifq = (struct mbuf *) qh->qh_link;
++             (struct quehead *) ifq != qh;
++             ifq = ifq->ifq_next) {
++        if (ifq->ifq_so == so) {
++            struct mbuf *ifm;
++            ifq->ifq_so = NULL;
++            for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) {
++                ifm->ifq_so = NULL;
++            }
++        }
++    }
++}
++
++/*
+  * remque and free a socket, clobber cache
+  */
+ void
+ sofree(struct socket *so)
+ {
+   Slirp *slirp = so->slirp;
+-  struct mbuf *ifm;
+ 
+-  for (ifm = (struct mbuf *) slirp->if_fastq.qh_link;
+-       (struct quehead *) ifm != &slirp->if_fastq;
+-       ifm = ifm->ifq_next) {
+-    if (ifm->ifq_so == so) {
+-      ifm->ifq_so = NULL;
+-    }
+-  }
+-
+-  for (ifm = (struct mbuf *) slirp->if_batchq.qh_link;
+-       (struct quehead *) ifm != &slirp->if_batchq;
+-       ifm = ifm->ifq_next) {
+-    if (ifm->ifq_so == so) {
+-      ifm->ifq_so = NULL;
+-    }
+-  }
++  soqfree(so, &slirp->if_fastq);
++  soqfree(so, &slirp->if_batchq);
+ 
+   if (so->so_emu==EMU_RSH && so->extra) {
+ 	sofree(so->extra);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-snapshot-tests-Try-loadvm-twice.patch b/SOURCES/kvm-snapshot-tests-Try-loadvm-twice.patch
new file mode 100644
index 0000000..ac75eb3
--- /dev/null
+++ b/SOURCES/kvm-snapshot-tests-Try-loadvm-twice.patch
@@ -0,0 +1,67 @@
+From 5fb5d8c2e07d86138ca30bc27b5e454a6a05329b Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Thu, 2 Nov 2017 15:36:57 +0100
+Subject: [PATCH 4/9] snapshot/tests: Try loadvm twice
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20171102153657.13452-3-dgilbert@redhat.com>
+Patchwork-id: 77483
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 2/2] snapshot/tests: Try loadvm twice
+Bugzilla: 1508799
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+It's legal to loadvm twice, modify the existing save/loadvm test
+to do it twice.
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-Id: <20170825141940.20740-3-dgilbert@redhat.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 04583a9e8fbeb2c5c0607327b853b306aef7465f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ tests/qemu-iotests/068     | 2 +-
+ tests/qemu-iotests/068.out | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
+index cfa0f2a..e7fca6a 100755
+--- a/tests/qemu-iotests/068
++++ b/tests/qemu-iotests/068
+@@ -78,7 +78,7 @@ for extra_args in \
+     # Give qemu some time to boot before saving the VM state
+     { sleep 1; printf "savevm 0\nquit\n"; } | _qemu $extra_args
+     # Now try to continue from that VM state (this should just work)
+-    echo quit | _qemu $extra_args -loadvm 0
++    { sleep 1; printf "loadvm 0\nloadvm 0\nquit\n"; } | _qemu $extra_args -S
+ done
+ 
+ # success, all done
+diff --git a/tests/qemu-iotests/068.out b/tests/qemu-iotests/068.out
+index aa063cf..f07a938 100644
+--- a/tests/qemu-iotests/068.out
++++ b/tests/qemu-iotests/068.out
+@@ -7,6 +7,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
+ (qemu) savevm 0
+ (qemu) quit
+ QEMU X.Y.Z monitor - type 'help' for more information
++(qemu) loadvm 0
++(qemu) loadvm 0
+ (qemu) quit
+ 
+ === Saving and reloading a VM state to/from a qcow2 image (-object iothread,id=iothread0 -set device.hba0.iothread=iothread0) ===
+@@ -16,5 +18,7 @@ QEMU X.Y.Z monitor - type 'help' for more information
+ (qemu) savevm 0
+ (qemu) quit
+ QEMU X.Y.Z monitor - type 'help' for more information
++(qemu) loadvm 0
++(qemu) loadvm 0
+ (qemu) quit
+ *** done
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-sockets-avoid-crash-when-cleaning-up-sockets-for-an-.patch b/SOURCES/kvm-sockets-avoid-crash-when-cleaning-up-sockets-for-an-.patch
new file mode 100644
index 0000000..0f7bd6b
--- /dev/null
+++ b/SOURCES/kvm-sockets-avoid-crash-when-cleaning-up-sockets-for-an-.patch
@@ -0,0 +1,45 @@
+From b76eb750ff4e5a698428465d6b54684d49319e40 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Fri, 8 Dec 2017 14:00:16 +0100
+Subject: [PATCH 21/21] sockets: avoid crash when cleaning up sockets for an
+ invalid FD
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171208140016.29707-1-berrange@redhat.com>
+Patchwork-id: 78275
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH] sockets: avoid crash when cleaning up sockets for an invalid FD
+Bugzilla: 1506218
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+
+If socket_listen_cleanup is passed an invalid FD, then querying the socket
+local address will fail. We must thus be prepared for the returned addr to
+be NULL
+
+Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit 2d7ad7c05e762d5b10a57eba9af1bb6b41700854)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/qemu-sockets.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
+index 1358c81..bca6a06 100644
+--- a/util/qemu-sockets.c
++++ b/util/qemu-sockets.c
+@@ -1190,6 +1190,9 @@ void socket_listen_cleanup(int fd, Error **errp)
+     SocketAddress *addr;
+ 
+     addr = socket_local_address(fd, errp);
++    if (!addr) {
++        return;
++    }
+ 
+     if (addr->type == SOCKET_ADDRESS_TYPE_UNIX
+         && addr->u.q_unix.path) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Adjust-default-VSMT-value-for-better-migration.patch b/SOURCES/kvm-spapr-Adjust-default-VSMT-value-for-better-migration.patch
new file mode 100644
index 0000000..ac92131
--- /dev/null
+++ b/SOURCES/kvm-spapr-Adjust-default-VSMT-value-for-better-migration.patch
@@ -0,0 +1,117 @@
+From 11a953b475cd0c30c661e8ce4cf4518405792b75 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 04:04:58 +0100
+Subject: [PATCH 18/21] spapr: Adjust default VSMT value for better migration
+ compatibility
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119040458.5629-5-dgibson@redhat.com>
+Patchwork-id: 78679
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 4/4] spapr: Adjust default VSMT value for better migration compatibility
+Bugzilla: 1529243
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+fa98fbfc "PC: KVM: Support machine option to set VSMT mode" introduced the
+"vsmt" parameter for the pseries machine type, which controls the spacing
+of the vcpu ids of thread 0 for each virtual core.  This was done to bring
+some consistency and stability to how that was done, while still allowing
+backwards compatibility for migration and otherwise.
+
+The default value we used for vsmt was set to the max of the host's
+advertised default number of threads and the number of vthreads per vcore
+in the guest.  This was done to continue running without extra parameters
+on older KVM versions which don't allow the VSMT value to be changed.
+
+Unfortunately, even that smaller than before leakage of host configuration
+into guest visible configuration still breaks things.  Specifically a guest
+with 4 (or less) vthread/vcore will get a different vsmt value when
+running on a POWER8 (vsmt==8) and POWER9 (vsmt==4) host.  That means the
+vcpu ids don't line up so you can't migrate between them, though you should
+be able to.
+
+Long term we really want to make vsmt == smp_threads for sufficiently
+new machine types.  However, that means that qemu will then require a
+sufficiently recent KVM (one which supports changing VSMT) - that's still
+not widely enough deployed to be really comfortable to do.
+
+In the meantime we need some default that will work as often as
+possible.  This patch changes that default to 8 in all circumstances.
+This does change guest visible behaviour (including for existing
+machine versions) for many cases - just not the most common/important
+case.
+
+Following is case by case justification for why this is still the least
+worst option.  Note that any of the old behaviours can still be duplicated
+after this patch, it's just that it requires manual intervention by
+setting the vsmt property on the command line.
+
+KVM HV on POWER8 host:
+   This is the overwhelmingly common case in production setups, and is
+   unchanged by design.  POWER8 hosts will advertise a default VSMT mode
+   of 8, and > 8 vthreads/vcore isn't permitted
+
+KVM HV on POWER7 host:
+   Will break, but POWER7s allowing KVM were never released to the public.
+
+KVM HV on POWER9 host:
+   Not yet released to the public, breaking this now will reduce other
+   breakage later.
+
+KVM HV on PowerPC 970:
+   Will theoretically break it, but it was barely supported to begin with
+   and already required various user visible hacks to work.  Also so old
+   that I just don't care.
+
+TCG:
+   This is the nastiest one; it means migration of TCG guests (without
+   manual vsmt setting) will break.  Since TCG is rarely used in production
+   I think this is worth it for the other benefits.  It does also remove
+   one more barrier to TCG<->KVM migration which could be interesting for
+   debugging applications.
+
+KVM PR:
+   As with TCG, this will break migration of existing configurations,
+   without adding extra manual vsmt options.  As with TCG, it is rare in
+   production so I think the benefits outweigh breakages.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 8904e5a75005fe579c28806003892d8ae4a27dfa)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 1086b5a..2bb3b61 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -2254,9 +2254,14 @@ static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
+         }
+         /* In this case, spapr->vsmt has been set by the command line */
+     } else {
+-        /* Choose a VSMT mode that may be higher than necessary but is
+-         * likely to be compatible with hosts that don't have VSMT. */
+-        spapr->vsmt = MAX(kvm_smt, smp_threads);
++        /*
++         * Default VSMT value is tricky, because we need it to be as
++         * consistent as possible (for migration), but this requires
++         * changing it for at least some existing cases.  We pick 8 as
++         * the value that we'd get with KVM on POWER8, the
++         * overwhelmingly common case in production systems.
++         */
++        spapr->vsmt = 8;
+     }
+ 
+     /* KVM: If necessary, set the SMT mode: */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Allow-some-cases-where-we-can-t-set-VSMT-mode-.patch b/SOURCES/kvm-spapr-Allow-some-cases-where-we-can-t-set-VSMT-mode-.patch
new file mode 100644
index 0000000..c4842d0
--- /dev/null
+++ b/SOURCES/kvm-spapr-Allow-some-cases-where-we-can-t-set-VSMT-mode-.patch
@@ -0,0 +1,86 @@
+From 689db60fc3f20c8aea0d5f382eb7d4de87e6bb3f Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 04:04:57 +0100
+Subject: [PATCH 17/21] spapr: Allow some cases where we can't set VSMT mode in
+ the kernel
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119040458.5629-4-dgibson@redhat.com>
+Patchwork-id: 78678
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 3/4] spapr: Allow some cases where we can't set VSMT mode in the kernel
+Bugzilla: 1529243
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+At present if we require a vsmt mode that's not equal to the kernel's
+default, and the kernel doesn't let us change it (e.g. because it's an old
+kernel without support) then we always fail.
+
+But in fact we can cope with the kernel having a different vsmt as long as
+  a) it's >= the actual number of vthreads/vcore (so that guest threads
+     that are supposed to be on the same core act like it)
+  b) it's a submultiple of the requested vsmt mode (so that guest threads
+     spaced by the vsmt value will act like they're on different cores)
+
+Allowing this case gives us a bit more freedom to adjust the vsmt behaviour
+without breaking existing cases.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+Tested-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 1f20f2e0ee61d91abff4e86ed1cda1b5244647d3)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 5233366..1086b5a 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -2263,17 +2263,29 @@ static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
+     if (kvm_enabled() && (spapr->vsmt != kvm_smt)) {
+         ret = kvmppc_set_smt_threads(spapr->vsmt);
+         if (ret) {
++            /* Looks like KVM isn't able to change VSMT mode */
+             error_setg(&local_err,
+                        "Failed to set KVM's VSMT mode to %d (errno %d)",
+                        spapr->vsmt, ret);
+-            if (!vsmt_user) {
+-                error_append_hint(&local_err, "On PPC, a VM with %d threads/"
+-                             "core on a host with %d threads/core requires "
+-                             " the use of VSMT mode %d.\n",
+-                             smp_threads, kvm_smt, spapr->vsmt);
++            /* We can live with that if the default one is big enough
++             * for the number of threads, and a submultiple of the one
++             * we want.  In this case we'll waste some vcpu ids, but
++             * behaviour will be correct */
++            if ((kvm_smt >= smp_threads) && ((spapr->vsmt % kvm_smt) == 0)) {
++                warn_report_err(local_err);
++                local_err = NULL;
++                goto out;
++            } else {
++                if (!vsmt_user) {
++                    error_append_hint(&local_err,
++                                      "On PPC, a VM with %d threads/core"
++                                      " on a host with %d threads/core"
++                                      " requires the use of VSMT mode %d.\n",
++                                      smp_threads, kvm_smt, spapr->vsmt);
++                }
++                kvmppc_hint_smt_possible(&local_err);
++                goto out;
+             }
+-            kvmppc_hint_smt_possible(&local_err);
+-            goto out;
+         }
+     }
+     /* else TCG: nothing to do currently */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Capabilities-infrastructure.patch b/SOURCES/kvm-spapr-Capabilities-infrastructure.patch
new file mode 100644
index 0000000..e9e393a
--- /dev/null
+++ b/SOURCES/kvm-spapr-Capabilities-infrastructure.patch
@@ -0,0 +1,365 @@
+From 466322847847d3948eb7699aafcf9afd9ac3fc26 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:36 +0100
+Subject: [PATCH 08/21] spapr: Capabilities infrastructure
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-2-dgibson@redhat.com>
+Patchwork-id: 78668
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/7] spapr: Capabilities infrastructure
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+Because PAPR is a paravirtual environment access to certain CPU (or other)
+facilities can be blocked by the hypervisor.  PAPR provides ways to
+advertise in the device tree whether or not those features are available to
+the guest.
+
+In some places we automatically determine whether to make a feature
+available based on whether our host can support it, in most cases this is
+based on limitations in the available KVM implementation.
+
+Although we correctly advertise this to the guest, it means that host
+factors might make changes to the guest visible environment which is bad:
+as well as generaly reducing reproducibility, it means that a migration
+between different host environments can easily go bad.
+
+We've mostly gotten away with it because the environments considered mature
+enough to be well supported (basically, KVM on POWER8) have had consistent
+feature availability.  But, it's still not right and some limitations on
+POWER9 is going to make it more of an issue in future.
+
+This introduces an infrastructure for defining "sPAPR capabilities".  These
+are set by default based on the machine version, masked by the capabilities
+of the chosen cpu, but can be overriden with machine properties.
+
+The intention is at reset time we verify that the requested capabilities
+can be supported on the host (considering TCG, KVM and/or host cpu
+limitations).  If not we simply fail, rather than silently modifying the
+advertised featureset to the guest.
+
+This does mean that certain configurations that "worked" may now fail, but
+such configurations were already more subtly broken.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 33face6b8981add8eba1f7cdaf4cf6cede415d2e)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr.c
+	include/hw/ppc/spapr.h
+
+Simple contextual conflicts.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/Makefile.objs   |   2 +-
+ hw/ppc/spapr.c         |   7 ++
+ hw/ppc/spapr_caps.c    | 181 +++++++++++++++++++++++++++++++++++++++++++++++++
+ include/hw/ppc/spapr.h |  31 +++++++++
+ 4 files changed, 220 insertions(+), 1 deletion(-)
+ create mode 100644 hw/ppc/spapr_caps.c
+
+diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
+index 856cef5..d4cdbb8 100644
+--- a/hw/ppc/Makefile.objs
++++ b/hw/ppc/Makefile.objs
+@@ -1,7 +1,7 @@
+ # shared objects
+ obj-y += ppc.o ppc_booke.o fdt.o
+ # IBM pSeries (sPAPR)
+-obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
++obj-$(CONFIG_PSERIES) += spapr.o spapr_caps.o spapr_vio.o spapr_events.o
+ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
+ obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o
+ obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index cdc56f3..7a4191d 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1424,6 +1424,8 @@ static void ppc_spapr_reset(void)
+     /* Check for unknown sysbus devices */
+     foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
+ 
++    spapr_caps_reset(spapr);
++
+     first_ppc_cpu = POWERPC_CPU(first_cpu);
+     if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
+         ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
+@@ -2267,6 +2269,8 @@ static void ppc_spapr_init(MachineState *machine)
+     char *filename;
+     Error *resize_hpt_err = NULL;
+ 
++    spapr_caps_validate(spapr, &error_fatal);
++
+     msi_nonbroken = true;
+ 
+     QLIST_INIT(&spapr->phbs);
+@@ -3635,6 +3639,9 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+      */
+     mc->numa_mem_align_shift = 28;
+     smc->has_power9_support = true;
++
++    smc->default_caps = spapr_caps(0);
++    spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+ static const TypeInfo spapr_machine_info = {
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+new file mode 100644
+index 0000000..968ba7b
+--- /dev/null
++++ b/hw/ppc/spapr_caps.c
+@@ -0,0 +1,181 @@
++/*
++ * QEMU PowerPC pSeries Logical Partition capabilities handling
++ *
++ * Copyright (c) 2017 David Gibson, Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++#include "qemu/osdep.h"
++#include "qapi/error.h"
++#include "qapi/visitor.h"
++
++#include "hw/ppc/spapr.h"
++
++typedef struct sPAPRCapabilityInfo {
++    const char *name;
++    const char *description;
++    uint64_t flag;
++
++    /* Make sure the virtual hardware can support this capability */
++    void (*allow)(sPAPRMachineState *spapr, Error **errp);
++
++    /* If possible, tell the virtual hardware not to allow the cap to
++     * be used at all */
++    void (*disallow)(sPAPRMachineState *spapr, Error **errp);
++} sPAPRCapabilityInfo;
++
++static sPAPRCapabilityInfo capability_table[] = {
++};
++
++static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
++                                               CPUState *cs)
++{
++    sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
++    sPAPRCapabilities caps;
++
++    caps = smc->default_caps;
++
++    /* TODO: clamp according to cpu model */
++
++    return caps;
++}
++
++void spapr_caps_reset(sPAPRMachineState *spapr)
++{
++    Error *local_err = NULL;
++    sPAPRCapabilities caps;
++    int i;
++
++    /* First compute the actual set of caps we're running with.. */
++    caps = default_caps_with_cpu(spapr, first_cpu);
++
++    caps.mask |= spapr->forced_caps.mask;
++    caps.mask &= ~spapr->forbidden_caps.mask;
++
++    spapr->effective_caps = caps;
++
++    /* .. then apply those caps to the virtual hardware */
++
++    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
++        sPAPRCapabilityInfo *info = &capability_table[i];
++
++        if (spapr->effective_caps.mask & info->flag) {
++            /* Failure to allow a cap is fatal - if the guest doesn't
++             * have it, we'll be supplying an incorrect environment */
++            if (info->allow) {
++                info->allow(spapr, &error_fatal);
++            }
++        } else {
++            /* Failure to enforce a cap is only a warning.  The guest
++             * shouldn't be using it, since it's not advertised, so it
++             * doesn't get to complain about weird behaviour if it
++             * goes ahead anyway */
++            if (info->disallow) {
++                info->disallow(spapr, &local_err);
++            }
++            if (local_err) {
++                warn_report_err(local_err);
++                local_err = NULL;
++            }
++        }
++    }
++}
++
++static void spapr_cap_get(Object *obj, Visitor *v, const char *name,
++                          void *opaque, Error **errp)
++{
++    sPAPRCapabilityInfo *cap = opaque;
++    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
++    bool value = spapr_has_cap(spapr, cap->flag);
++
++    /* TODO: Could this get called before effective_caps is finalized
++     * in spapr_caps_reset()? */
++
++    visit_type_bool(v, name, &value, errp);
++}
++
++static void spapr_cap_set(Object *obj, Visitor *v, const char *name,
++                          void *opaque, Error **errp)
++{
++    sPAPRCapabilityInfo *cap = opaque;
++    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
++    bool value;
++    Error *local_err = NULL;
++
++    visit_type_bool(v, name, &value, &local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        return;
++    }
++
++    if (value) {
++        spapr->forced_caps.mask |= cap->flag;
++    } else {
++        spapr->forbidden_caps.mask |= cap->flag;
++    }
++}
++
++void spapr_caps_validate(sPAPRMachineState *spapr, Error **errp)
++{
++    uint64_t allcaps = 0;
++    int i;
++
++    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
++        g_assert((allcaps & capability_table[i].flag) == 0);
++        allcaps |= capability_table[i].flag;
++    }
++
++    g_assert((spapr->forced_caps.mask & ~allcaps) == 0);
++    g_assert((spapr->forbidden_caps.mask & ~allcaps) == 0);
++
++    if (spapr->forced_caps.mask & spapr->forbidden_caps.mask) {
++        error_setg(errp, "Some sPAPR capabilities set both on and off");
++        return;
++    }
++
++    /* Check for any caps incompatible with other caps.  Nothing to do
++     * yet */
++}
++
++void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
++{
++    Error *local_err = NULL;
++    ObjectClass *klass = OBJECT_CLASS(smc);
++    int i;
++
++    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
++        sPAPRCapabilityInfo *cap = &capability_table[i];
++        const char *name = g_strdup_printf("cap-%s", cap->name);
++
++        object_class_property_add(klass, name, "bool",
++                                  spapr_cap_get, spapr_cap_set, NULL,
++                                  cap, &local_err);
++        if (local_err) {
++            error_propagate(errp, local_err);
++            return;
++        }
++
++        object_class_property_set_description(klass, name, cap->description,
++                                              &local_err);
++        if (local_err) {
++            error_propagate(errp, local_err);
++            return;
++        }
++    }
++}
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index d9e8e5a..7267151 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -51,6 +51,15 @@ typedef enum {
+ } sPAPRResizeHPT;
+ 
+ /**
++ * Capabilities
++ */
++
++typedef struct sPAPRCapabilities sPAPRCapabilities;
++struct sPAPRCapabilities {
++    uint64_t mask;
++};
++
++/**
+  * sPAPRMachineClass:
+  */
+ struct sPAPRMachineClass {
+@@ -68,6 +77,7 @@ struct sPAPRMachineClass {
+                           hwaddr *mmio32, hwaddr *mmio64,
+                           unsigned n_dma, uint32_t *liobns, Error **errp);
+     sPAPRResizeHPT resize_hpt_default;
++    sPAPRCapabilities default_caps;
+ };
+ 
+ /**
+@@ -129,6 +139,9 @@ struct sPAPRMachineState {
+     MemoryHotplugState hotplug_memory;
+ 
+     const char *icp_type;
++
++    sPAPRCapabilities forced_caps, forbidden_caps;
++    sPAPRCapabilities effective_caps;
+ };
+ 
+ #define H_SUCCESS         0
+@@ -707,4 +720,22 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
+ 
+ #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
+ 
++/*
++ * Handling of optional capabilities
++ */
++static inline sPAPRCapabilities spapr_caps(uint64_t mask)
++{
++    sPAPRCapabilities caps = { mask };
++    return caps;
++}
++
++static inline bool spapr_has_cap(sPAPRMachineState *spapr, uint64_t cap)
++{
++    return !!(spapr->effective_caps.mask & cap);
++}
++
++void spapr_caps_reset(sPAPRMachineState *spapr);
++void spapr_caps_validate(sPAPRMachineState *spapr, Error **errp);
++void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
++
+ #endif /* HW_SPAPR_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Correct-RAM-size-calculation-for-HPT-resizing.patch b/SOURCES/kvm-spapr-Correct-RAM-size-calculation-for-HPT-resizing.patch
new file mode 100644
index 0000000..63d6795
--- /dev/null
+++ b/SOURCES/kvm-spapr-Correct-RAM-size-calculation-for-HPT-resizing.patch
@@ -0,0 +1,80 @@
+From 61cace627e7140a63e27c7b1f949fc3b44ec120c Mon Sep 17 00:00:00 2001
+From: Serhii Popovych <spopovyc@redhat.com>
+Date: Wed, 22 Nov 2017 13:35:31 +0100
+Subject: [PATCH 1/7] spapr: Correct RAM size calculation for HPT resizing
+
+RH-Author: Serhii Popovych <spopovyc@redhat.com>
+Message-id: <1511357731-4779-1-git-send-email-spopovyc@redhat.com>
+Patchwork-id: 77778
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2] spapr: Correct RAM size calculation for HPT resizing
+Bugzilla: 1499647
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+The only thing making this change distinct from one in
+upstream is get_plugged_memory_size() function which
+isn't present in 2.10.x branch and it is a part of new
+QMP interface command which we do not want to introduce
+in downstream.
+
+So assuming that we replace get_plugged_memory_size()
+with direct call to pc_existing_dimms_capacity().
+
+    commit db50f280cf5f714e64ff2b134aae138908f07502
+    Author: David Gibson <david@gibson.dropbear.id.au>
+    Date:   Wed Oct 11 00:16:57 2017 +1100
+
+    spapr: Correct RAM size calculation for HPT resizing
+
+    In order to prevent the guest from forcing the allocation of large amounts
+    of qemu memory (or host kernel memory, in the case of KVM HV), we limit
+    the size of Hashed Page Table (HPT) it is allowed to allocated, based on
+    its RAM size.
+
+    However, the current calculation is not correct: it only adds up the size
+    of plugged memory, ignoring the base memory size.  This patch corrects it.
+
+    While we're there, use get_plugged_memory_size() instead of directly
+    calling pc_existing_dimms_capacity().  The only difference is that it
+    will abort on failure, which is right: a failure here indicates something
+    wrong within qemu.
+
+    Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+    Reviewed-by: Greg Kurz <groug@kaod.org>
+    Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+
+Signed-off-by: Serhii Popovych <spopovyc@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_hcall.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
+index b503299..217358d 100644
+--- a/hw/ppc/spapr_hcall.c
++++ b/hw/ppc/spapr_hcall.c
+@@ -472,7 +472,7 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
+     target_ulong flags = args[0];
+     int shift = args[1];
+     sPAPRPendingHPT *pending = spapr->pending_hpt;
+-    uint64_t current_ram_size = MACHINE(spapr)->ram_size;
++    uint64_t current_ram_size;
+     int rc;
+ 
+     if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) {
+@@ -494,7 +494,8 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
+         return H_PARAMETER;
+     }
+ 
+-    current_ram_size = pc_existing_dimms_capacity(&error_fatal);
++    current_ram_size = MACHINE(spapr)->ram_size +
++                       pc_existing_dimms_capacity(&error_fatal);
+ 
+     /* We only allow the guest to allocate an HPT one order above what
+      * we'd normally give them (to stop a small guest claiming a huge
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Correct-compatibility-mode-setting-for-hotplug.patch b/SOURCES/kvm-spapr-Correct-compatibility-mode-setting-for-hotplug.patch
new file mode 100644
index 0000000..41c367b
--- /dev/null
+++ b/SOURCES/kvm-spapr-Correct-compatibility-mode-setting-for-hotplug.patch
@@ -0,0 +1,91 @@
+From 4d5b8f8fecbbf460f8c2f789784542e2d0e1fd20 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 12 Jan 2018 03:43:33 +0100
+Subject: [PATCH 06/12] spapr: Correct compatibility mode setting for
+ hotplugged CPUs
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180112034333.5242-1-dgibson@redhat.com>
+Patchwork-id: 78556
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] spapr: Correct compatibility mode setting for hotplugged CPUs
+Bugzilla: 1528234
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Serhii Popovych <spopovyc@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+Currently the pseries machine sets the compatibility mode for the
+guest's cpus in two places: 1) at machine reset and 2) after CAS
+negotiation.
+
+This means that if we set or negotiate a compatiblity mode, then
+hotplug a cpu, the hotplugged cpu doesn't get the right mode set and
+will incorrectly have the full native features.
+
+To correct this, we set the compatibility mode on a cpu when it is
+brought online with the 'start-cpu' RTAS call.  Given that we no
+longer need to set the compatibility mode on all CPUs at machine
+reset, so we change that to only set the mode for the boot cpu.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reported-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
+Tested-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
+Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+(cherry picked from commit 51f84465dd985fc21589b2eac1f18658fc9783e9)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr_rtas.c
+
+Minor contextual conflict.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/spapr.c      | 2 +-
+ hw/ppc/spapr_rtas.c | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index e276632..cdc56f3 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1462,7 +1462,7 @@ static void ppc_spapr_reset(void)
+         spapr_ovec_cleanup(spapr->ov5_cas);
+         spapr->ov5_cas = spapr_ovec_new();
+ 
+-        ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal);
++        ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
+     }
+ 
+     fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
+diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
+index 94a2799..93f09a0 100644
+--- a/hw/ppc/spapr_rtas.c
++++ b/hw/ppc/spapr_rtas.c
+@@ -162,6 +162,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
+     if (cpu != NULL) {
+         CPUState *cs = CPU(cpu);
+         CPUPPCState *env = &cpu->env;
++        Error *local_err = NULL;
+ 
+         if (!cs->halted) {
+             rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+@@ -173,6 +174,14 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
+          * new cpu enters */
+         kvm_cpu_synchronize_state(cs);
+ 
++        /* Set compatibility mode to match existing cpus */
++        ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err);
++        if (local_err) {
++            error_report_err(local_err);
++            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
++            return;
++        }
++
+         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
+         env->nip = start;
+         env->gpr[3] = r3;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Handle-Decimal-Floating-Point-DFP-as-an-option.patch b/SOURCES/kvm-spapr-Handle-Decimal-Floating-Point-DFP-as-an-option.patch
new file mode 100644
index 0000000..f24a783
--- /dev/null
+++ b/SOURCES/kvm-spapr-Handle-Decimal-Floating-Point-DFP-as-an-option.patch
@@ -0,0 +1,143 @@
+From 4e2f29e8fef6d8428bed4a5c366e5cafd7b92a41 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:40 +0100
+Subject: [PATCH 12/21] spapr: Handle Decimal Floating Point (DFP) as an
+ optional capability
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-6-dgibson@redhat.com>
+Patchwork-id: 78672
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 5/7] spapr: Handle Decimal Floating Point (DFP) as an optional capability
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+Decimal Floating Point has been available on POWER7 and later (server)
+cpus.  However, it can be disabled on the hypervisor, meaning that it's
+not available to guests.
+
+We currently handle this by conditionally advertising DFP support in the
+device tree depending on whether the guest CPU model supports it - which
+can also depend on what's allowed in the host for -cpu host.  That can lead
+to confusion on migration, since host properties are silently affecting
+guest visible properties.
+
+This patch handles it by treating it as an optional capability for the
+pseries machine type.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 2d1fb9bc8e6e78931d8e1bfeb0ed7a4d223b0480)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr.c
+
+Due to differences between upstream and downstream machine type
+versions.  As CAP_DFP is enabled for all upstream versions, enable it
+for all downsteam as well.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/spapr.c         |  7 ++++---
+ hw/ppc/spapr_caps.c    | 18 ++++++++++++++++++
+ include/hw/ppc/spapr.h |  3 +++
+ 3 files changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 0ef2af9..41cb2fa 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -575,7 +575,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+     /* Advertise DFP (Decimal Floating Point) if available
+      *   0 / no property == no DFP
+      *   1               == DFP available */
+-    if (env->insns_flags2 & PPC2_DFP) {
++    if (spapr_has_cap(spapr, SPAPR_CAP_DFP)) {
+         _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
+     }
+ 
+@@ -3650,7 +3650,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     mc->numa_mem_align_shift = 28;
+     smc->has_power9_support = true;
+ 
+-    smc->default_caps = spapr_caps(SPAPR_CAP_VSX);
++    smc->default_caps = spapr_caps(SPAPR_CAP_VSX | SPAPR_CAP_DFP);
+     spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+@@ -4056,7 +4056,8 @@ static void spapr_machine_rhel740_class_options(MachineClass *mc)
+     smc->has_power9_support = false;
+     smc->pre_2_10_has_unused_icps = true;
+     smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
+-    smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX);
++    smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX
++                                   | SPAPR_CAP_DFP);
+ }
+ 
+ DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false);
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index 9f901fb..2b67ac2 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -70,6 +70,16 @@ static void cap_vsx_allow(sPAPRMachineState *spapr, Error **errp)
+     }
+ }
+ 
++static void cap_dfp_allow(sPAPRMachineState *spapr, Error **errp)
++{
++    PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
++    CPUPPCState *env = &cpu->env;
++
++    if (!(env->insns_flags2 & PPC2_DFP)) {
++        error_setg(errp, "DFP support not available, try cap-dfp=off");
++    }
++}
++
+ static sPAPRCapabilityInfo capability_table[] = {
+     {
+         .name = "htm",
+@@ -85,6 +95,13 @@ static sPAPRCapabilityInfo capability_table[] = {
+         .allow = cap_vsx_allow,
+         /* TODO: add cap_vsx_disallow */
+     },
++    {
++        .name = "dfp",
++        .description = "Allow Decimal Floating Point (DFP)",
++        .flag = SPAPR_CAP_DFP,
++        .allow = cap_dfp_allow,
++        /* TODO: add cap_dfp_disallow */
++    },
+ };
+ 
+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+@@ -104,6 +121,7 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+     if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
+                           0, spapr->max_compat_pvr)) {
+         caps.mask &= ~SPAPR_CAP_VSX;
++        caps.mask &= ~SPAPR_CAP_DFP;
+     }
+ 
+     return caps;
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 36f6816..df767c3 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -62,6 +62,9 @@ typedef enum {
+ /* Vector Scalar Extensions */
+ #define SPAPR_CAP_VSX               0x0000000000000002ULL
+ 
++/* Decimal Floating Point */
++#define SPAPR_CAP_DFP               0x0000000000000004ULL
++
+ typedef struct sPAPRCapabilities sPAPRCapabilities;
+ struct sPAPRCapabilities {
+     uint64_t mask;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Handle-VMX-VSX-presence-as-an-spapr-capability.patch b/SOURCES/kvm-spapr-Handle-VMX-VSX-presence-as-an-spapr-capability.patch
new file mode 100644
index 0000000..9b07a7e
--- /dev/null
+++ b/SOURCES/kvm-spapr-Handle-VMX-VSX-presence-as-an-spapr-capability.patch
@@ -0,0 +1,169 @@
+From 268880a2fee41c5c1929aac996a3292db41233cb Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:39 +0100
+Subject: [PATCH 11/21] spapr: Handle VMX/VSX presence as an spapr capability
+ flag
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-5-dgibson@redhat.com>
+Patchwork-id: 78671
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 4/7] spapr: Handle VMX/VSX presence as an spapr capability flag
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+We currently have some conditionals in the spapr device tree code to decide
+whether or not to advertise the availability of the VMX (aka Altivec) and
+VSX vector extensions to the guest, based on whether the guest cpu has
+those features.
+
+This can lead to confusion and subtle failures on migration, since it makes
+a guest visible change based only on host capabilities.  We now have a
+better mechanism for this, in spapr capabilities flags, which explicitly
+depend on user options rather than host capabilities.
+
+Rework the advertisement of VSX and VMX based on a new VSX capability.  We
+no longer bother with a conditional for VMX support, because every CPU
+that's ever been supported by the pseries machine type supports VMX.
+
+NOTE: Some userspace distributions (e.g. RHEL7.4) already rely on
+availability of VSX in libc, so using cap-vsx=off may lead to a fatal
+SIGILL in init.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 2938664286499c0c30d6e455a7e2e5d3e6c3f63d)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr.c
+
+Because of the difference between upstream and downstream machine type
+versions.  Adjusted the logic to enable CAP_VSX on all downstream
+machine types, as it is for all upstream types.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/spapr.c         | 20 +++++++++++---------
+ hw/ppc/spapr_caps.c    | 25 +++++++++++++++++++++++++
+ include/hw/ppc/spapr.h |  3 +++
+ 3 files changed, 39 insertions(+), 9 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 846b906..0ef2af9 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -560,14 +560,16 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+                           segs, sizeof(segs))));
+     }
+ 
+-    /* Advertise VMX/VSX (vector extensions) if available
+-     *   0 / no property == no vector extensions
++    /* Advertise VSX (vector extensions) if available
+      *   1               == VMX / Altivec available
+-     *   2               == VSX available */
+-    if (env->insns_flags & PPC_ALTIVEC) {
+-        uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
+-
+-        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
++     *   2               == VSX available
++     *
++     * Only CPUs for which we create core types in spapr_cpu_core.c
++     * are possible, and all of those have VMX */
++    if (spapr_has_cap(spapr, SPAPR_CAP_VSX)) {
++        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
++    } else {
++        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
+     }
+ 
+     /* Advertise DFP (Decimal Floating Point) if available
+@@ -3648,7 +3650,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     mc->numa_mem_align_shift = 28;
+     smc->has_power9_support = true;
+ 
+-    smc->default_caps = spapr_caps(0);
++    smc->default_caps = spapr_caps(SPAPR_CAP_VSX);
+     spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+@@ -4054,7 +4056,7 @@ static void spapr_machine_rhel740_class_options(MachineClass *mc)
+     smc->has_power9_support = false;
+     smc->pre_2_10_has_unused_icps = true;
+     smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
+-    smc->default_caps = spapr_caps(SPAPR_CAP_HTM);
++    smc->default_caps = spapr_caps(SPAPR_CAP_HTM | SPAPR_CAP_VSX);
+ }
+ 
+ DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false);
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index 2bdc202..9f901fb 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -57,6 +57,19 @@ static void cap_htm_allow(sPAPRMachineState *spapr, Error **errp)
+     }
+ }
+ 
++static void cap_vsx_allow(sPAPRMachineState *spapr, Error **errp)
++{
++    PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
++    CPUPPCState *env = &cpu->env;
++
++    /* Allowable CPUs in spapr_cpu_core.c should already have gotten
++     * rid of anything that doesn't do VMX */
++    g_assert(env->insns_flags & PPC_ALTIVEC);
++    if (!(env->insns_flags2 & PPC2_VSX)) {
++        error_setg(errp, "VSX support not available, try cap-vsx=off");
++    }
++}
++
+ static sPAPRCapabilityInfo capability_table[] = {
+     {
+         .name = "htm",
+@@ -65,6 +78,13 @@ static sPAPRCapabilityInfo capability_table[] = {
+         .allow = cap_htm_allow,
+         /* TODO: add cap_htm_disallow */
+     },
++    {
++        .name = "vsx",
++        .description = "Allow Vector Scalar Extensions (VSX)",
++        .flag = SPAPR_CAP_VSX,
++        .allow = cap_vsx_allow,
++        /* TODO: add cap_vsx_disallow */
++    },
+ };
+ 
+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+@@ -81,6 +101,11 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+         caps.mask &= ~SPAPR_CAP_HTM;
+     }
+ 
++    if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
++                          0, spapr->max_compat_pvr)) {
++        caps.mask &= ~SPAPR_CAP_VSX;
++    }
++
+     return caps;
+ }
+ 
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index f32967a..36f6816 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -59,6 +59,9 @@ typedef enum {
+ /* Hardware Transactional Memory */
+ #define SPAPR_CAP_HTM               0x0000000000000001ULL
+ 
++/* Vector Scalar Extensions */
++#define SPAPR_CAP_VSX               0x0000000000000002ULL
++
+ typedef struct sPAPRCapabilities sPAPRCapabilities;
+ struct sPAPRCapabilities {
+     uint64_t mask;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Implement-bug-in-spapr-vty-device-to-be-compat.patch b/SOURCES/kvm-spapr-Implement-bug-in-spapr-vty-device-to-be-compat.patch
new file mode 100644
index 0000000..8f0afb6
--- /dev/null
+++ b/SOURCES/kvm-spapr-Implement-bug-in-spapr-vty-device-to-be-compat.patch
@@ -0,0 +1,78 @@
+From ea460580ae8d4910bddac476b25eb31c04b4e54c Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Mon, 27 Nov 2017 04:56:27 +0100
+Subject: [PATCH 5/7] spapr: Implement bug in spapr-vty device to be compatible
+ with PowerVM
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171127045627.20341-1-dgibson@redhat.com>
+Patchwork-id: 77896
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] spapr: Implement bug in spapr-vty device to be compatible with PowerVM
+Bugzilla: 1495090
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+The spapr-vty device implements the PAPR defined virtual console,
+which is also implemented by IBM's proprietary PowerVM hypervisor.
+
+PowerVM's implementation has a bug where it inserts an extra \0 after
+every \r going to the guest.  Because of that Linux's guest side
+driver has a workaround which strips \0 characters that appear
+immediately after a \r.
+
+That means that when running under qemu, sending a binary stream from
+host to guest via spapr-vty which happens to include a \r\0 sequence
+will get corrupted by that workaround.
+
+To deal with that, this patch duplicates PowerVM's bug, inserting an
+extra \0 after each \r.  Ugly, but the best option available.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit 6c3bc244d3cbdc5545504fda4fae0238ec36a3c0)
+
+Testing: Verified that when transferring a file (raw) through
+         spapr-vty device, '\r\0' sequences are no longer mangled.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/char/spapr_vty.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
+index 0fa416c..6748334 100644
+--- a/hw/char/spapr_vty.c
++++ b/hw/char/spapr_vty.c
+@@ -58,6 +58,24 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
+ 
+     while ((n < max) && (dev->out != dev->in)) {
+         buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
++
++        /* PowerVM's vty implementation has a bug where it inserts a
++         * \0 after every \r going to the guest.  Existing guests have
++         * a workaround for this which removes every \0 immediately
++         * following a \r, so here we make ourselves bug-for-bug
++         * compatible, so that the guest won't drop a real \0-after-\r
++         * that happens to occur in a binary stream. */
++        if (buf[n - 1] == '\r') {
++            if (n < max) {
++                buf[n++] = '\0';
++            } else {
++                /* No room for the extra \0, roll back and try again
++                 * next time */
++                dev->out--;
++                n--;
++                break;
++            }
++        }
+     }
+ 
+     qemu_chr_fe_accept_input(&dev->chardev);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Remove-unnecessary-options-field-from-sPAPRCap.patch b/SOURCES/kvm-spapr-Remove-unnecessary-options-field-from-sPAPRCap.patch
new file mode 100644
index 0000000..91d81b1
--- /dev/null
+++ b/SOURCES/kvm-spapr-Remove-unnecessary-options-field-from-sPAPRCap.patch
@@ -0,0 +1,83 @@
+From 146d96d35b69fea9311b15de60eb85a076ec2e14 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:42 +0100
+Subject: [PATCH 14/21] spapr: Remove unnecessary 'options' field from
+ sPAPRCapabilityInfo
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-8-dgibson@redhat.com>
+Patchwork-id: 78673
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 7/7] spapr: Remove unnecessary 'options' field from sPAPRCapabilityInfo
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+The options field here is intended to list the available values for the
+capability.  It's not used yet, because the existing capabilities are
+boolean.
+
+We're going to add capabilities that aren't, but in that case the info on
+the possible values can be folded into the .description field.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 895d5cd620d358c2623c639a150d9320d581b4f8)
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_caps.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index f95a785..d5c9ce7 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -35,7 +35,6 @@
+ typedef struct sPAPRCapabilityInfo {
+     const char *name;
+     const char *description;
+-    const char *options;                        /* valid capability values */
+     int index;
+ 
+     /* Getter and Setter Function Pointers */
+@@ -126,7 +125,6 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+     [SPAPR_CAP_HTM] = {
+         .name = "htm",
+         .description = "Allow Hardware Transactional Memory (HTM)",
+-        .options = "",
+         .index = SPAPR_CAP_HTM,
+         .get = spapr_cap_get_bool,
+         .set = spapr_cap_set_bool,
+@@ -136,7 +134,6 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+     [SPAPR_CAP_VSX] = {
+         .name = "vsx",
+         .description = "Allow Vector Scalar Extensions (VSX)",
+-        .options = "",
+         .index = SPAPR_CAP_VSX,
+         .get = spapr_cap_get_bool,
+         .set = spapr_cap_set_bool,
+@@ -146,7 +143,6 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+     [SPAPR_CAP_DFP] = {
+         .name = "dfp",
+         .description = "Allow Decimal Floating Point (DFP)",
+-        .options = "",
+         .index = SPAPR_CAP_DFP,
+         .get = spapr_cap_get_bool,
+         .set = spapr_cap_set_bool,
+@@ -338,7 +334,7 @@ void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
+             return;
+         }
+ 
+-        desc = g_strdup_printf("%s%s", cap->description, cap->options);
++        desc = g_strdup_printf("%s", cap->description);
+         object_class_property_set_description(klass, name, desc, &local_err);
+         g_free(desc);
+         if (local_err) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Treat-Hardware-Transactional-Memory-HTM-as-an-.patch b/SOURCES/kvm-spapr-Treat-Hardware-Transactional-Memory-HTM-as-an-.patch
new file mode 100644
index 0000000..1c092af
--- /dev/null
+++ b/SOURCES/kvm-spapr-Treat-Hardware-Transactional-Memory-HTM-as-an-.patch
@@ -0,0 +1,193 @@
+From 423e8d79df3ef4548d74854a8feeee84cd5e159c Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:37 +0100
+Subject: [PATCH 09/21] spapr: Treat Hardware Transactional Memory (HTM) as an
+ optional capability
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-3-dgibson@redhat.com>
+Patchwork-id: 78670
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 2/7] spapr: Treat Hardware Transactional Memory (HTM) as an optional capability
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+This adds an spapr capability bit for Hardware Transactional Memory.  It is
+enabled by default for pseries-2.11 and earlier machine types. with POWER8
+or later CPUs (as it must be, since earlier qemu versions would implicitly
+allow it).  However it is disabled by default for the latest pseries-2.12
+machine type.
+
+This means that with the latest machine type, HTM will not be available,
+regardless of CPU, unless it is explicitly enabled on the command line.
+That change is made on the basis that:
+
+ * This way running with -M pseries,accel=tcg will start with whatever cpu
+   and will provide the same guest visible model as with accel=kvm.
+     - More specifically, this means existing make check tests don't have
+       to be modified to use cap-htm=off in order to run with TCG
+
+ * We hope to add a new "HTM without suspend" feature in the not too
+   distant future which could work on both POWER8 and POWER9 cpus, and
+   could be enabled by default.
+
+ * Best guesses suggest that future POWER cpus may well only support the
+   HTM-without-suspend model, not the (frankly, horribly overcomplicated)
+   POWER8 style HTM with suspend.
+
+ * Anecdotal evidence suggests problems with HTM being enabled when it
+   wasn't wanted are more common than being missing when it was.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit ee76a09fc72cfbfab2bb5529320ef7e460adffd8)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr.c
+
+Conflicts due to replacement of upstream machine types with downstream
+ones.  Omitted original logic since it affects the 2.11 machine type
+which isn't in downstream (even in comments).  Replaced with logic to
+enable HTM capability only for pseries-rhel7.4.0 and earlier machine
+types.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/spapr.c         | 13 ++++++++-----
+ hw/ppc/spapr_caps.c    | 29 ++++++++++++++++++++++++++++-
+ include/hw/ppc/spapr.h |  3 +++
+ 3 files changed, 39 insertions(+), 6 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 7a4191d..2068a1f 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -253,7 +253,9 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
+ }
+ 
+ /* Populate the "ibm,pa-features" property */
+-static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
++static void spapr_populate_pa_features(sPAPRMachineState *spapr,
++                                       PowerPCCPU *cpu,
++                                       void *fdt, int offset,
+                                        bool legacy_guest)
+ {
+     CPUPPCState *env = &cpu->env;
+@@ -318,7 +320,7 @@ static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
+          */
+         pa_features[3] |= 0x20;
+     }
+-    if (kvmppc_has_cap_htm() && pa_size > 24) {
++    if (spapr_has_cap(spapr, SPAPR_CAP_HTM) && pa_size > 24) {
+         pa_features[24] |= 0x80;    /* Transactional memory support */
+     }
+     if (legacy_guest && pa_size > 40) {
+@@ -385,8 +387,8 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
+             return ret;
+         }
+ 
+-        spapr_populate_pa_features(cpu, fdt, offset,
+-                                         spapr->cas_legacy_guest_workaround);
++        spapr_populate_pa_features(spapr, cpu, fdt, offset,
++                                   spapr->cas_legacy_guest_workaround);
+     }
+     return ret;
+ }
+@@ -582,7 +584,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+                           page_sizes_prop, page_sizes_prop_size)));
+     }
+ 
+-    spapr_populate_pa_features(cpu, fdt, offset, false);
++    spapr_populate_pa_features(spapr, cpu, fdt, offset, false);
+ 
+     _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
+                            cs->cpu_index / vcpus_per_socket)));
+@@ -4046,6 +4048,7 @@ static void spapr_machine_rhel740_class_options(MachineClass *mc)
+     smc->has_power9_support = false;
+     smc->pre_2_10_has_unused_icps = true;
+     smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
++    smc->default_caps = spapr_caps(SPAPR_CAP_HTM);
+ }
+ 
+ DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false);
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index 968ba7b..3b35b91 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -24,6 +24,10 @@
+ #include "qemu/osdep.h"
+ #include "qapi/error.h"
+ #include "qapi/visitor.h"
++#include "sysemu/hw_accel.h"
++#include "target/ppc/cpu.h"
++#include "cpu-models.h"
++#include "kvm_ppc.h"
+ 
+ #include "hw/ppc/spapr.h"
+ 
+@@ -40,18 +44,41 @@ typedef struct sPAPRCapabilityInfo {
+     void (*disallow)(sPAPRMachineState *spapr, Error **errp);
+ } sPAPRCapabilityInfo;
+ 
++static void cap_htm_allow(sPAPRMachineState *spapr, Error **errp)
++{
++    if (tcg_enabled()) {
++        error_setg(errp,
++                   "No Transactional Memory support in TCG, try cap-htm=off");
++    } else if (kvm_enabled() && !kvmppc_has_cap_htm()) {
++        error_setg(errp,
++"KVM implementation does not support Transactional Memory, try cap-htm=off"
++            );
++    }
++}
++
+ static sPAPRCapabilityInfo capability_table[] = {
++    {
++        .name = "htm",
++        .description = "Allow Hardware Transactional Memory (HTM)",
++        .flag = SPAPR_CAP_HTM,
++        .allow = cap_htm_allow,
++        /* TODO: add cap_htm_disallow */
++    },
+ };
+ 
+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+                                                CPUState *cs)
+ {
+     sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
++    PowerPCCPU *cpu = POWERPC_CPU(cs);
+     sPAPRCapabilities caps;
+ 
+     caps = smc->default_caps;
+ 
+-    /* TODO: clamp according to cpu model */
++    if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07,
++                          0, spapr->max_compat_pvr)) {
++        caps.mask &= ~SPAPR_CAP_HTM;
++    }
+ 
+     return caps;
+ }
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 7267151..77dc3fb 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -54,6 +54,9 @@ typedef enum {
+  * Capabilities
+  */
+ 
++/* Hardware Transactional Memory */
++#define SPAPR_CAP_HTM               0x0000000000000001ULL
++
+ typedef struct sPAPRCapabilities sPAPRCapabilities;
+ struct sPAPRCapabilities {
+     uint64_t mask;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-Validate-capabilities-on-migration.patch b/SOURCES/kvm-spapr-Validate-capabilities-on-migration.patch
new file mode 100644
index 0000000..0132d15
--- /dev/null
+++ b/SOURCES/kvm-spapr-Validate-capabilities-on-migration.patch
@@ -0,0 +1,240 @@
+From a6549068139448cfd38e4b1e602fbaba5ed32a97 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 02:34:38 +0100
+Subject: [PATCH 10/21] spapr: Validate capabilities on migration
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119023442.28577-4-dgibson@redhat.com>
+Patchwork-id: 78669
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 3/7] spapr: Validate capabilities on migration
+Bugzilla: 1523414
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+Now that the "pseries" machine type implements optional capabilities (well,
+one so far) there's the possibility of having different capabilities
+available at either end of a migration.  Although arguably a user error,
+it would be nice to catch this situation and fail as gracefully as we can.
+
+This adds code to migrate the capabilities flags.  These aren't pulled
+directly into the destination's configuration since what the user has
+specified on the destination command line should take precedence.  However,
+they are checked against the destination capabilities.
+
+If the source was using a capability which is absent on the destination,
+we fail the migration, since that could easily cause a guest crash or other
+bad behaviour.  If the source lacked a capability which is present on the
+destination we warn, but allow the migration to proceed.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+(cherry picked from commit be85537d654565e35e359a74b46fc08b7956525c)
+
+Adjusted because we don't have 44b1ff31 "migration: pre_save return
+int" downstream, which means spapr_caps_pre_save() needs a different
+type.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c         |  6 ++++
+ hw/ppc/spapr_caps.c    | 95 ++++++++++++++++++++++++++++++++++++++++++++++++--
+ include/hw/ppc/spapr.h |  6 ++++
+ 3 files changed, 104 insertions(+), 3 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 2068a1f..846b906 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1547,6 +1547,11 @@ static int spapr_post_load(void *opaque, int version_id)
+     sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+     int err = 0;
+ 
++    err = spapr_caps_post_migration(spapr);
++    if (err) {
++        return err;
++    }
++
+     if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
+         CPUState *cs;
+         CPU_FOREACH(cs) {
+@@ -1713,6 +1718,7 @@ static const VMStateDescription vmstate_spapr = {
+         &vmstate_spapr_ov5_cas,
+         &vmstate_spapr_patb_entry,
+         &vmstate_spapr_pending_events,
++        &vmstate_spapr_caps,
+         NULL
+     }
+ };
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index 3b35b91..2bdc202 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -22,6 +22,7 @@
+  * THE SOFTWARE.
+  */
+ #include "qemu/osdep.h"
++#include "qemu/error-report.h"
+ #include "qapi/error.h"
+ #include "qapi/visitor.h"
+ #include "sysemu/hw_accel.h"
+@@ -83,6 +84,92 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+     return caps;
+ }
+ 
++static bool spapr_caps_needed(void *opaque)
++{
++    sPAPRMachineState *spapr = opaque;
++
++    return (spapr->forced_caps.mask != 0) || (spapr->forbidden_caps.mask != 0);
++}
++
++/* This has to be called from the top-level spapr post_load, not the
++ * caps specific one.  Otherwise it wouldn't be called when the source
++ * caps are all defaults, which could still conflict with overridden
++ * caps on the destination */
++int spapr_caps_post_migration(sPAPRMachineState *spapr)
++{
++    uint64_t allcaps = 0;
++    int i;
++    bool ok = true;
++    sPAPRCapabilities dstcaps = spapr->effective_caps;
++    sPAPRCapabilities srccaps;
++
++    srccaps = default_caps_with_cpu(spapr, first_cpu);
++    srccaps.mask |= spapr->mig_forced_caps.mask;
++    srccaps.mask &= ~spapr->mig_forbidden_caps.mask;
++
++    for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
++        sPAPRCapabilityInfo *info = &capability_table[i];
++
++        allcaps |= info->flag;
++
++        if ((srccaps.mask & info->flag) && !(dstcaps.mask & info->flag)) {
++            error_report("cap-%s=on in incoming stream, but off in destination",
++                         info->name);
++            ok = false;
++        }
++
++        if (!(srccaps.mask & info->flag) && (dstcaps.mask & info->flag)) {
++            warn_report("cap-%s=off in incoming stream, but on in destination",
++                         info->name);
++        }
++    }
++
++    if (spapr->mig_forced_caps.mask & ~allcaps) {
++        error_report(
++            "Unknown capabilities 0x%"PRIx64" enabled in incoming stream",
++            spapr->mig_forced_caps.mask & ~allcaps);
++        ok = false;
++    }
++    if (spapr->mig_forbidden_caps.mask & ~allcaps) {
++        warn_report(
++            "Unknown capabilities 0x%"PRIx64" disabled in incoming stream",
++            spapr->mig_forbidden_caps.mask & ~allcaps);
++    }
++
++    return ok ? 0 : -EINVAL;
++}
++
++static void spapr_caps_pre_save(void *opaque)
++{
++    sPAPRMachineState *spapr = opaque;
++
++    spapr->mig_forced_caps = spapr->forced_caps;
++    spapr->mig_forbidden_caps = spapr->forbidden_caps;
++}
++
++static int spapr_caps_pre_load(void *opaque)
++{
++    sPAPRMachineState *spapr = opaque;
++
++    spapr->mig_forced_caps = spapr_caps(0);
++    spapr->mig_forbidden_caps = spapr_caps(0);
++    return 0;
++}
++
++const VMStateDescription vmstate_spapr_caps = {
++    .name = "spapr/caps",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .needed = spapr_caps_needed,
++    .pre_save = spapr_caps_pre_save,
++    .pre_load = spapr_caps_pre_load,
++    .fields = (VMStateField[]) {
++        VMSTATE_UINT64(mig_forced_caps.mask, sPAPRMachineState),
++        VMSTATE_UINT64(mig_forbidden_caps.mask, sPAPRMachineState),
++        VMSTATE_END_OF_LIST()
++    },
++};
++
+ void spapr_caps_reset(sPAPRMachineState *spapr)
+ {
+     Error *local_err = NULL;
+@@ -92,6 +179,11 @@ void spapr_caps_reset(sPAPRMachineState *spapr)
+     /* First compute the actual set of caps we're running with.. */
+     caps = default_caps_with_cpu(spapr, first_cpu);
+ 
++    /* Remove unnecessary forced/forbidden bits (this will help us
++     * with migration) */
++    spapr->forced_caps.mask &= ~caps.mask;
++    spapr->forbidden_caps.mask &= caps.mask;
++
+     caps.mask |= spapr->forced_caps.mask;
+     caps.mask &= ~spapr->forbidden_caps.mask;
+ 
+@@ -175,9 +267,6 @@ void spapr_caps_validate(sPAPRMachineState *spapr, Error **errp)
+         error_setg(errp, "Some sPAPR capabilities set both on and off");
+         return;
+     }
+-
+-    /* Check for any caps incompatible with other caps.  Nothing to do
+-     * yet */
+ }
+ 
+ void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 77dc3fb..f32967a 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -54,6 +54,8 @@ typedef enum {
+  * Capabilities
+  */
+ 
++/* These bits go in the migration stream, so they can't be reassigned */
++
+ /* Hardware Transactional Memory */
+ #define SPAPR_CAP_HTM               0x0000000000000001ULL
+ 
+@@ -144,6 +146,7 @@ struct sPAPRMachineState {
+     const char *icp_type;
+ 
+     sPAPRCapabilities forced_caps, forbidden_caps;
++    sPAPRCapabilities mig_forced_caps, mig_forbidden_caps;
+     sPAPRCapabilities effective_caps;
+ };
+ 
+@@ -726,6 +729,8 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
+ /*
+  * Handling of optional capabilities
+  */
++extern const VMStateDescription vmstate_spapr_caps;
++
+ static inline sPAPRCapabilities spapr_caps(uint64_t mask)
+ {
+     sPAPRCapabilities caps = { mask };
+@@ -740,5 +745,6 @@ static inline bool spapr_has_cap(sPAPRMachineState *spapr, uint64_t cap)
+ void spapr_caps_reset(sPAPRMachineState *spapr);
+ void spapr_caps_validate(sPAPRMachineState *spapr, Error **errp);
+ void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
++int spapr_caps_post_migration(sPAPRMachineState *spapr);
+ 
+ #endif /* HW_SPAPR_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-add-missing-break-in-h_get_cpu_characteristics.patch b/SOURCES/kvm-spapr-add-missing-break-in-h_get_cpu_characteristics.patch
new file mode 100644
index 0000000..5ebab62
--- /dev/null
+++ b/SOURCES/kvm-spapr-add-missing-break-in-h_get_cpu_characteristics.patch
@@ -0,0 +1,51 @@
+From 72c1a30661e94a58a347dd6341dd8cabdc23d2dc Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:30 +0100
+Subject: [PATCH 13/15] spapr: add missing break in h_get_cpu_characteristics()
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-10-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78985
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 9/9] spapr: add missing break in h_get_cpu_characteristics()
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+Detected by Coverity (CID 1385702). This fixes the recently added hypercall
+to let guests properly apply Spectre and Meltdown workarounds.
+
+Fixes: c59704b25473 "target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS"
+Reported-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit fa86f59234919b479b7e8da6b0dc2dad894a5eac)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_hcall.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
+index 21247cd..d3f811a 100644
+--- a/hw/ppc/spapr_hcall.c
++++ b/hw/ppc/spapr_hcall.c
+@@ -1672,6 +1672,7 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
+     switch (safe_indirect_branch) {
+     case SPAPR_CAP_FIXED:
+         characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
++        break;
+     default: /* broken */
+         assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
+         break;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-disable-cpu-hot-remove.patch b/SOURCES/kvm-spapr-disable-cpu-hot-remove.patch
new file mode 100644
index 0000000..146c090
--- /dev/null
+++ b/SOURCES/kvm-spapr-disable-cpu-hot-remove.patch
@@ -0,0 +1,60 @@
+From 3d76fc1a1b8041c952d398140832460f16b7eade Mon Sep 17 00:00:00 2001
+From: Igor Mammedov <imammedo@redhat.com>
+Date: Thu, 19 Oct 2017 15:28:13 +0200
+Subject: [PATCH 68/69] spapr: disable cpu hot-remove
+
+RH-Author: Igor Mammedov <imammedo@redhat.com>
+Message-id: <1508426893-172020-1-git-send-email-imammedo@redhat.com>
+Patchwork-id: 77378
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH v2] spapr: disable cpu hot-remove
+Bugzilla: 1499320
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1499320
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14301295
+Upstream: RHEL-only
+
+Rebase to 2.10 brought in cpu hot-remove with it, disable it
+for qemu-kvm-ma variant of QEMU where it hasn't been supported.
+Use CONFIG_RHV to switch unplug off only for qemu-kvm-ma and
+not to affect RHEV variant built from the same source code.
+
+Signed-off-by: Igor Mammedov <imammedo@redhat.com>
+---
+v2:
+  - use CONFIG_RHV to not break RHEV build
+
+Thanks to Laszlo for hints to use CONFIG_RHV!
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 3c598fd..5fe7769 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3148,6 +3148,7 @@ static
+ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
+                                Error **errp)
+ {
++#if defined(CONFIG_RHV)
+     int index;
+     sPAPRDRConnector *drc;
+     CPUCore *cc = CPU_CORE(dev);
+@@ -3169,6 +3170,9 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
+     spapr_drc_detach(drc);
+ 
+     spapr_hotplug_req_remove_by_index(drc);
++#else
++    error_setg(errp, "this feature or command is not currently supported");
++#endif /* CONFIG_RHV */
+ }
+ 
+ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-disable-memory-hotplug.patch b/SOURCES/kvm-spapr-disable-memory-hotplug.patch
new file mode 100644
index 0000000..7b28b71
--- /dev/null
+++ b/SOURCES/kvm-spapr-disable-memory-hotplug.patch
@@ -0,0 +1,79 @@
+From 437d5386e39a7955bf7a08c3af4d34ac74d677a2 Mon Sep 17 00:00:00 2001
+From: Igor Mammedov <imammedo@redhat.com>
+Date: Wed, 31 Jan 2018 10:44:31 +0100
+Subject: [PATCH 8/8] spapr: disable memory hotplug
+
+RH-Author: Igor Mammedov <imammedo@redhat.com>
+Message-id: <1517395471-44118-1-git-send-email-imammedo@redhat.com>
+Patchwork-id: 78748
+O-Subject: [RHV7.5 qemu-kvm-ma PATCH v3] spapr: disable memory hotplug
+Bugzilla: 1535952
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1535952
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=15146188
+Upstream: RHEL-only
+
+Disable memory hotplug for qemu-kvm-ma variant of QEMU where
+shouldn't be supported.
+Use CONFIG_RHV to switch feature off only for qemu-kvm-ma and
+not to affect RHEV variant built from the same source code.
+
+PS:
+Disable only (un)plug entry points from device_add/del and
+leave the rest of hotplug hw intact so that -ma machine
+could be migrated to -rhev.
+Note: backward migration would be broken if source -rhev
+machine used pc-dimm devices (either with -device/device_add)
+
+Signed-off-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 4f1ab14..6c4c088 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -2992,6 +2992,9 @@ out:
+ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+                                   Error **errp)
+ {
++#if !defined(CONFIG_RHV)
++    error_setg(errp, "Memory hotplug not supported for this machine");
++#else
+     PCDIMMDevice *dimm = PC_DIMM(dev);
+     PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
+     MemoryRegion *mr;
+@@ -3019,6 +3022,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ 
+ out:
+     g_free(mem_dev);
++#endif
+ }
+ 
+ struct sPAPRDIMMState {
+@@ -3132,6 +3136,9 @@ void spapr_lmb_release(DeviceState *dev)
+ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
+                                         DeviceState *dev, Error **errp)
+ {
++#if !defined(CONFIG_RHV)
++    error_setg(errp, "Memory hot unplug not supported for this machine");
++#else
+     sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
+     Error *local_err = NULL;
+     PCDIMMDevice *dimm = PC_DIMM(dev);
+@@ -3186,6 +3193,7 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
+                                               nr_lmbs, spapr_drc_index(drc));
+ out:
+     error_propagate(errp, local_err);
++#endif
+ }
+ 
+ static void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-don-t-initialize-PATB-entry-if-max-cpu-compat-.patch b/SOURCES/kvm-spapr-don-t-initialize-PATB-entry-if-max-cpu-compat-.patch
new file mode 100644
index 0000000..5ad7b3e
--- /dev/null
+++ b/SOURCES/kvm-spapr-don-t-initialize-PATB-entry-if-max-cpu-compat-.patch
@@ -0,0 +1,79 @@
+From 19ab0de29b4a853622fbccccf957f6a2c44466f3 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Tue, 19 Dec 2017 10:42:36 +0100
+Subject: [PATCH 01/42] spapr: don't initialize PATB entry if max-cpu-compat <
+ power9
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171219104236.22556-1-lvivier@redhat.com>
+Patchwork-id: 78413
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] spapr: don't initialize PATB entry if max-cpu-compat < power9
+Bugzilla: 1525866
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+BZ:     https://bugzilla.redhat.com/show_bug.cgi?id=1525866
+BREW:   https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14815605
+        s390x build is broken (binutils is missing), build only the others
+Tested: I tested this patch with upstream QEMU.
+        As it is difficult to have a P9 host in beaker to check migration
+        to P8 host, I didn't re-test it with downstream build
+        (but I have asked QE to do)
+
+if KVM is enabled and KVM capabilities MMU radix is available,
+the partition table entry (patb_entry) for the radix mode is
+initialized by default in ppc_spapr_reset().
+
+It's a problem if we want to migrate the guest to a POWER8 host
+while the kernel is not started to set the value to the one
+expected for a POWER8 CPU.
+
+The "-machine max-cpu-compat=power8" should allow to migrate
+a POWER9 KVM host to a POWER8 KVM host, but because patb_entry
+is set, the destination QEMU tries to enable radix mode on the
+POWER8 host. This fails and cancels the migration:
+
+    Process table config unsupported by the host
+    error while loading state for instance 0x0 of device 'spapr'
+    load of migration failed: Invalid argument
+
+This patch doesn't set the PATB entry if the user provides
+a CPU compatibility mode that doesn't support radix mode.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 1481fe5fcfeb7fcf3c1ebb9d8c0432e3e0188ccf)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index af7a3bb..d320b6c 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1424,7 +1424,10 @@ static void ppc_spapr_reset(void)
+     /* Check for unknown sysbus devices */
+     foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
+ 
+-    if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
++    first_ppc_cpu = POWERPC_CPU(first_cpu);
++    if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
++        ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
++                         spapr->max_compat_pvr)) {
+         /* If using KVM with radix mode available, VCPUs can be started
+          * without a HPT because KVM will start them in radix mode.
+          * Set the GR bit in PATB so that we know there is no HPT. */
+@@ -1483,7 +1486,6 @@ static void ppc_spapr_reset(void)
+     g_free(fdt);
+ 
+     /* Set up the entry state */
+-    first_ppc_cpu = POWERPC_CPU(first_cpu);
+     first_ppc_cpu->env.gpr[3] = fdt_addr;
+     first_ppc_cpu->env.gpr[5] = 0;
+     first_cpu->halted = 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-fix-CAS-generated-reset.patch b/SOURCES/kvm-spapr-fix-CAS-generated-reset.patch
new file mode 100644
index 0000000..a221208
--- /dev/null
+++ b/SOURCES/kvm-spapr-fix-CAS-generated-reset.patch
@@ -0,0 +1,63 @@
+From bc0dcb3a78edf2eb8df0509d4862bb9ff36c4332 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Wed, 4 Oct 2017 05:40:14 +0200
+Subject: [PATCH 07/34] spapr: fix CAS-generated reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171004054014.14159-5-dgibson@redhat.com>
+Patchwork-id: 76802
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 4/4] spapr: fix CAS-generated reset
+Bugzilla: 1448344
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Cédric Le Goater <clg@kaod.org>
+
+The OV5_MMU_RADIX_300 requires special handling in the CAS negotiation
+process. It is cleared from the option vector of the guest before
+evaluating the changes and re-added later. But, when testing for a
+possible CAS reset :
+
+    spapr->cas_reboot = spapr_ovec_diff(ov5_updates,
+                                        ov5_cas_old, spapr->ov5_cas);
+
+the bit OV5_MMU_RADIX_300 will each time be seen as removed from the
+previous OV5 set, hence generating a reset loop.
+
+Fix this problem by also clearing the same bit in the ov5_cas_old set.
+
+Signed-off-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 30bf9ed1684da582e47ae004f8f3cf14fd6f39dd)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_hcall.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
+index 07b3da8..92f1e21 100644
+--- a/hw/ppc/spapr_hcall.c
++++ b/hw/ppc/spapr_hcall.c
+@@ -1575,6 +1575,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
+      * to worry about this for now.
+      */
+     ov5_cas_old = spapr_ovec_clone(spapr->ov5_cas);
++
++    /* also clear the radix/hash bit from the current ov5_cas bits to
++     * be in sync with the newly ov5 bits. Else the radix bit will be
++     * seen as being removed and this will generate a reset loop
++     */
++    spapr_ovec_clear(ov5_cas_old, OV5_MMU_RADIX_300);
++
+     /* full range of negotiated ov5 capabilities */
+     spapr_ovec_intersect(spapr->ov5_cas, spapr->ov5, ov5_guest);
+     spapr_ovec_cleanup(ov5_guest);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-fix-device-tree-properties-when-using-compatib.patch b/SOURCES/kvm-spapr-fix-device-tree-properties-when-using-compatib.patch
new file mode 100644
index 0000000..ed719f7
--- /dev/null
+++ b/SOURCES/kvm-spapr-fix-device-tree-properties-when-using-compatib.patch
@@ -0,0 +1,164 @@
+From 384d7ebbde836477e00c19dbe5f68ece3e0fad1e Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Mon, 22 Jan 2018 16:48:48 +0100
+Subject: [PATCH 21/21] spapr: fix device tree properties when using
+ compatibility mode
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20180122164848.20486-1-lvivier@redhat.com>
+Patchwork-id: 78694
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2] spapr: fix device tree properties when using compatibility mode
+Bugzilla: 1535752
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+Commit 51f84465dd98 changed the compatility mode setting logic:
+- machine reset only sets compatibility mode for the boot CPU
+- compatibility mode is set for other CPUs when they are put online
+  by the guest with the "start-cpu" RTAS call
+
+This causes a regression for machines started with max-compat-cpu:
+the device tree nodes related to secondary CPU cores contain wrong
+"cpu-version" and "ibm,pa-features" values, as shown below.
+
+Guest started on a POWER8 host with:
+     -smp cores=2 -machine pseries,max-cpu-compat=compat7
+
+                        ibm,pa-features = [18 00 f6 3f c7 c0 80 f0 80 00
+ 00 00 00 00 00 00 00 00 80 00 80 00 80 00 00 00];
+                        cpu-version = <0x4d0200>;
+
+                               ^^^
+                        second CPU core
+
+                        ibm,pa-features = <0x600f63f 0xc70080c0>;
+                        cpu-version = <0xf000003>;
+
+                               ^^^
+                          boot CPU core
+
+The second core is advertised in raw POWER8 mode. This happens because
+CAS assumes all CPUs to have the same compatibility mode. Since the
+boot CPU already has the requested compatibility mode, the CAS code
+does not set it for the secondary one, and exposes the bogus device
+tree properties in in the CAS response to the guest.
+
+A similar situation is observed when hot-plugging a CPU core. The
+related device tree properties are generated and exposed to guest
+with the "ibm,configure-connector" RTAS before "start-cpu" is called.
+The CPU core is advertised to the guest in raw mode as well.
+
+It both cases, it boils down to the fact that "start-cpu" happens too
+late. This can be fixed globally by propagating the compatibility mode
+of the boot CPU to the other CPUs during reset.  For this to work, the
+compatibility mode of the boot CPU must be set before the machine code
+actually resets all CPUs.
+
+It is not needed to set the compatibility mode in "start-cpu" anymore,
+so the code is dropped.
+
+Fixes: 51f84465dd98
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 9012a53f067a78022947e18050b145c34a3dc599)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr_rtas.c
+because of missing commit:
+9a94ee5bb1 "spapr/rtas: disable the decrementer interrupt when a "
+            CPU is unplugged"
+---
+ hw/ppc/spapr.c          | 18 +++++++++---------
+ hw/ppc/spapr_cpu_core.c |  7 +++++++
+ hw/ppc/spapr_rtas.c     |  9 ---------
+ 3 files changed, 16 insertions(+), 18 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 2bb3b61..4f1ab14 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1442,6 +1442,15 @@ static void ppc_spapr_reset(void)
+         spapr_setup_hpt_and_vrma(spapr);
+     }
+ 
++    /* if this reset wasn't generated by CAS, we should reset our
++     * negotiated options and start from scratch */
++    if (!spapr->cas_reboot) {
++        spapr_ovec_cleanup(spapr->ov5_cas);
++        spapr->ov5_cas = spapr_ovec_new();
++
++        ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
++    }
++
+     qemu_devices_reset();
+ 
+     /* DRC reset may cause a device to be unplugged. This will cause troubles
+@@ -1462,15 +1471,6 @@ static void ppc_spapr_reset(void)
+     rtas_addr = rtas_limit - RTAS_MAX_SIZE;
+     fdt_addr = rtas_addr - FDT_MAX_SIZE;
+ 
+-    /* if this reset wasn't generated by CAS, we should reset our
+-     * negotiated options and start from scratch */
+-    if (!spapr->cas_reboot) {
+-        spapr_ovec_cleanup(spapr->ov5_cas);
+-        spapr->ov5_cas = spapr_ovec_new();
+-
+-        ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
+-    }
+-
+     fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
+ 
+     spapr_load_rtas(spapr, fdt, rtas_addr);
+diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
+index 30c15d5..fbabe49 100644
+--- a/hw/ppc/spapr_cpu_core.c
++++ b/hw/ppc/spapr_cpu_core.c
+@@ -101,6 +101,13 @@ static void spapr_cpu_reset(void *opaque)
+             exit(1);
+         }
+     }
++
++    /* Set compatibility mode to match the boot CPU, which was either set
++     * by the machine reset code or by CAS. This should never fail.
++     */
++    if (cs != first_cpu) {
++        ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort);
++    }
+ }
+ 
+ static void spapr_cpu_destroy(PowerPCCPU *cpu)
+diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
+index 93f09a0..94a2799 100644
+--- a/hw/ppc/spapr_rtas.c
++++ b/hw/ppc/spapr_rtas.c
+@@ -162,7 +162,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
+     if (cpu != NULL) {
+         CPUState *cs = CPU(cpu);
+         CPUPPCState *env = &cpu->env;
+-        Error *local_err = NULL;
+ 
+         if (!cs->halted) {
+             rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+@@ -174,14 +173,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
+          * new cpu enters */
+         kvm_cpu_synchronize_state(cs);
+ 
+-        /* Set compatibility mode to match existing cpus */
+-        ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err);
+-        if (local_err) {
+-            error_report_err(local_err);
+-            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+-            return;
+-        }
+-
+         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
+         env->nip = start;
+         env->gpr[3] = r3;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-reset-DRCs-after-devices.patch b/SOURCES/kvm-spapr-reset-DRCs-after-devices.patch
new file mode 100644
index 0000000..e9aa272
--- /dev/null
+++ b/SOURCES/kvm-spapr-reset-DRCs-after-devices.patch
@@ -0,0 +1,126 @@
+From 4dcd885d5308e34fb4550c20fc7ffc050e014c91 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Mon, 27 Nov 2017 09:03:20 +0100
+Subject: [PATCH 6/7] spapr: reset DRCs after devices
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171127090320.32307-1-lvivier@redhat.com>
+Patchwork-id: 77902
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] spapr: reset DRCs after devices
+Bugzilla: 1516145
+RH-Acked-by: Serhii Popovych <spopovyc@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+A DRC with a pending unplug request releases its associated device at
+machine reset time.
+
+In the case of LMB, when all DRCs for a DIMM device have been reset,
+the DIMM gets unplugged, causing guest memory to disappear. This may
+be very confusing for anything still using this memory.
+
+This is exactly what happens with vhost backends, and QEMU aborts
+with:
+
+qemu-system-ppc64: used ring relocated for ring 2
+qemu-system-ppc64: qemu/hw/virtio/vhost.c:649: vhost_commit: Assertion
+ `r >= 0' failed.
+
+The issue is that each DRC registers a QEMU reset handler, and we
+don't control the order in which these handlers are called (ie,
+a LMB DRC will unplug a DIMM before the virtio device using the
+memory on this DIMM could stop its vhost backend).
+
+To avoid such situations, let's reset DRCs after all devices
+have been reset.
+
+Reported-by: Mallesh N. Koti <mallesh@linux.vnet.ibm.com>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
+Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 82512483940c756e2db1bd67ea91b02bc29c5e01)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c     | 21 +++++++++++++++++++++
+ hw/ppc/spapr_drc.c |  7 -------
+ 2 files changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 2065f09..6c64c55 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1394,6 +1394,19 @@ static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
+     }
+ }
+ 
++static int spapr_reset_drcs(Object *child, void *opaque)
++{
++    sPAPRDRConnector *drc =
++        (sPAPRDRConnector *) object_dynamic_cast(child,
++                                                 TYPE_SPAPR_DR_CONNECTOR);
++
++    if (drc) {
++        spapr_drc_reset(drc);
++    }
++
++    return 0;
++}
++
+ static void ppc_spapr_reset(void)
+ {
+     MachineState *machine = MACHINE(qdev_get_machine());
+@@ -1417,6 +1430,14 @@ static void ppc_spapr_reset(void)
+     }
+ 
+     qemu_devices_reset();
++
++    /* DRC reset may cause a device to be unplugged. This will cause troubles
++     * if this device is used by another device (eg, a running vhost backend
++     * will crash QEMU if the DIMM holding the vring goes away). To avoid such
++     * situations, we reset DRCs after all devices have been reset.
++     */
++    object_child_foreach_recursive(object_get_root(), spapr_reset_drcs, NULL);
++
+     spapr_clear_pending_events(spapr);
+ 
+     /*
+diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
+index 85c999d..7d33e4c 100644
+--- a/hw/ppc/spapr_drc.c
++++ b/hw/ppc/spapr_drc.c
+@@ -455,11 +455,6 @@ void spapr_drc_reset(sPAPRDRConnector *drc)
+     }
+ }
+ 
+-static void drc_reset(void *opaque)
+-{
+-    spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
+-}
+-
+ bool spapr_drc_needed(void *opaque)
+ {
+     sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
+@@ -517,7 +512,6 @@ static void realize(DeviceState *d, Error **errp)
+     }
+     vmstate_register(DEVICE(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
+                      drc);
+-    qemu_register_reset(drc_reset, drc);
+     trace_spapr_drc_realize_complete(spapr_drc_index(drc));
+ }
+ 
+@@ -528,7 +522,6 @@ static void unrealize(DeviceState *d, Error **errp)
+     char name[256];
+ 
+     trace_spapr_drc_unrealize(spapr_drc_index(drc));
+-    qemu_unregister_reset(drc_reset, drc);
+     vmstate_unregister(DEVICE(drc), &vmstate_spapr_drc, drc);
+     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
+     snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-spapr-set-vsmt-to-MAX-8-smp_threads.patch b/SOURCES/kvm-spapr-set-vsmt-to-MAX-8-smp_threads.patch
new file mode 100644
index 0000000..5101c2a
--- /dev/null
+++ b/SOURCES/kvm-spapr-set-vsmt-to-MAX-8-smp_threads.patch
@@ -0,0 +1,47 @@
+From 779370f8d1cf47e46b39b210a43d24804e551071 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Mon, 12 Feb 2018 12:04:49 +0100
+Subject: [PATCH 04/15] spapr: set vsmt to MAX(8, smp_threads)
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20180212120449.20810-1-lvivier@redhat.com>
+Patchwork-id: 78978
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] spapr: set vsmt to MAX(8, smp_threads)
+Bugzilla: 1542421
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Serhii Popovych <spopovyc@redhat.com>
+
+We ignore silently the value of smp_threads when we set
+the default VSMT value, and if smp_threads is greater than VSMT
+kernel is going into trouble later.
+
+Fixes: 8904e5a750
+("spapr: Adjust default VSMT value for better migration compatibility")
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 4ad64cbd0c3f9df15be5f7d1c920285551e802ca)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 6c4c088..2b991d8 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -2261,7 +2261,7 @@ static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
+          * the value that we'd get with KVM on POWER8, the
+          * overwhelmingly common case in production systems.
+          */
+-        spapr->vsmt = 8;
++        spapr->vsmt = MAX(8, smp_threads);
+     }
+ 
+     /* KVM: If necessary, set the SMT mode: */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-add-support-for-SPEC_CTRL-MSR.patch b/SOURCES/kvm-target-i386-add-support-for-SPEC_CTRL-MSR.patch
new file mode 100644
index 0000000..9b6d63b
--- /dev/null
+++ b/SOURCES/kvm-target-i386-add-support-for-SPEC_CTRL-MSR.patch
@@ -0,0 +1,143 @@
+From f0fac2e6c70510f7a5c5c572831b1a851a29fc07 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Wed, 13 Dec 2017 15:47:36 -0200
+Subject: [PATCH 1/3] target-i386: add support for SPEC_CTRL MSR
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171213174738.20852-2-ehabkost@redhat.com>
+Patchwork-id: n/a
+O-Subject: [CONFIDENTIAL][RHEL-7.5 qemu-kvm-rhev PATCH v2 1/3] target-i386: cpu:
+add new CPUID bits for indirect branch predictor restrictions
+Bugzilla: CVE-2017-5715
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/cpu.h     |  3 +++
+ target/i386/kvm.c     | 14 ++++++++++++++
+ target/i386/machine.c | 20 ++++++++++++++++++++
+ 3 files changed, 37 insertions(+)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index fd73888..4dfb859 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -335,6 +335,7 @@
+ #define MSR_IA32_APICBASE_BASE          (0xfffffU<<12)
+ #define MSR_IA32_FEATURE_CONTROL        0x0000003a
+ #define MSR_TSC_ADJUST                  0x0000003b
++#define MSR_IA32_SPEC_CTRL              0x48
+ #define MSR_IA32_TSCDEADLINE            0x6e0
+ 
+ #define FEATURE_CONTROL_LOCKED                    (1<<0)
+@@ -1082,6 +1083,8 @@ typedef struct CPUX86State {
+ 
+     uint32_t pkru;
+ 
++    uint64_t spec_ctrl;
++
+     /* End of state preserved by INIT (dummy marker).  */
+     struct {} end_init_save;
+ 
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index ee4e91f..3f59629 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -91,6 +91,7 @@ static bool has_msr_hv_synic;
+ static bool has_msr_hv_stimer;
+ static bool has_msr_hv_frequencies;
+ static bool has_msr_xss;
++static bool has_msr_spec_ctrl;
+ 
+ static bool has_msr_architectural_pmu;
+ static uint32_t num_architectural_pmu_counters;
+@@ -1145,6 +1146,9 @@ static int kvm_get_supported_msrs(KVMState *s)
+                 case HV_X64_MSR_TSC_FREQUENCY:
+                     has_msr_hv_frequencies = true;
+                     break;
++                case MSR_IA32_SPEC_CTRL:
++                    has_msr_spec_ctrl = true;
++                    break;
+                 }
+             }
+         }
+@@ -1627,6 +1631,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+     if (has_msr_xss) {
+         kvm_msr_entry_add(cpu, MSR_IA32_XSS, env->xss);
+     }
++    if (has_msr_spec_ctrl) {
++        kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, env->spec_ctrl);
++    }
+ #ifdef TARGET_X86_64
+     if (lm_capable_kernel) {
+         kvm_msr_entry_add(cpu, MSR_CSTAR, env->cstar);
+@@ -1635,6 +1642,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+         kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
+     }
+ #endif
++
+     /*
+      * The following MSRs have side effects on the guest or are too heavy
+      * for normal writeback. Limit them to reset or full state updates.
+@@ -2000,6 +2008,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+     if (has_msr_xss) {
+         kvm_msr_entry_add(cpu, MSR_IA32_XSS, 0);
+     }
++    if (has_msr_spec_ctrl) {
++        kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, 0);
++    }
+ 
+ 
+     if (!env->tsc_valid) {
+@@ -2349,6 +2360,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+                 env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
+             }
+             break;
++        case MSR_IA32_SPEC_CTRL:
++            env->spec_ctrl = msrs[i].data;
++            break;
+         }
+     }
+ 
+diff --git a/target/i386/machine.c b/target/i386/machine.c
+index 6156626..0212270 100644
+--- a/target/i386/machine.c
++++ b/target/i386/machine.c
+@@ -838,6 +838,25 @@ static const VMStateDescription vmstate_xsave ={
+     }
+ };
+ 
++static bool spec_ctrl_needed(void *opaque)
++{
++    X86CPU *cpu = opaque;
++    CPUX86State *env = &cpu->env;
++
++    return env->spec_ctrl != 0;
++}
++
++static const VMStateDescription vmstate_spec_ctrl = {
++    .name = "cpu/spec_ctrl",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .needed = spec_ctrl_needed,
++    .fields = (VMStateField[]){
++        VMSTATE_UINT64(env.spec_ctrl, X86CPU),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
+ VMStateDescription vmstate_x86_cpu = {
+     .name = "cpu",
+     .version_id = 12,
+@@ -956,6 +975,7 @@ VMStateDescription vmstate_x86_cpu = {
+ #ifdef TARGET_X86_64
+         &vmstate_pkru,
+ #endif
++        &vmstate_spec_ctrl,
+         &vmstate_mcg_ext_ctl,
+         &vmstate_xsave,
+         NULL
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-cpu-Add-new-EPYC-CPU-model.patch b/SOURCES/kvm-target-i386-cpu-Add-new-EPYC-CPU-model.patch
new file mode 100644
index 0000000..a2e38df
--- /dev/null
+++ b/SOURCES/kvm-target-i386-cpu-Add-new-EPYC-CPU-model.patch
@@ -0,0 +1,96 @@
+From 89afbdab86f84025f4611fc5e26ba7014216689d Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Thu, 5 Oct 2017 22:09:12 +0200
+Subject: [PATCH 03/69] target-i386/cpu: Add new EPYC CPU model
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171005220912.11421-1-ehabkost@redhat.com>
+Patchwork-id: 76830
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] target-i386/cpu: Add new EPYC CPU model
+Bugzilla: 1445834
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Bandan Das <bsd@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Brijesh Singh <brijesh.singh@amd.com>
+
+Add a new base CPU model called 'EPYC' to model processors from AMD EPYC
+family (which includes EPYC 76xx,75xx,74xx, 73xx and 72xx).
+
+The following features bits have been added/removed compare to Opteron_G5
+
+Added: monitor, movbe, rdrand, mmxext, ffxsr, rdtscp, cr8legacy, osvw,
+       fsgsbase, bmi1, avx2, smep, bmi2, rdseed, adx, smap, clfshopt, sha
+       xsaveopt, xsavec, xgetbv1, arat
+
+Removed: xop, fma4, tbm
+
+Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
+Message-Id: <20170815170051.127257-1-brijesh.singh@amd.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 2e2efc7dbe2b0adc1200b5aa286cdbed729f6751)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/cpu.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 670d121..1cae8fe 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1547,6 +1547,50 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .xlevel = 0x8000001A,
+         .model_id = "AMD Opteron 63xx class CPU",
+     },
++    {
++        .name = "EPYC",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_AMD,
++        .family = 23,
++        .model = 1,
++        .stepping = 2,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
++            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
++            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
++            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
++            CPUID_VME | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
++            CPUID_EXT_XSAVE | CPUID_EXT_AES |  CPUID_EXT_POPCNT |
++            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
++            CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
++            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
++            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
++            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
++            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
++            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
++            CPUID_7_0_EBX_SHA_NI,
++        /* Missing: XSAVES (not supported by some Linux versions,
++         * including v4.1 to v4.12).
++         * KVM doesn't yet expose any XSAVES state save component.
++         */
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
++            CPUID_XSAVE_XGETBV1,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x8000000A,
++        .model_id = "AMD EPYC Processor",
++    },
+ };
+ 
+ typedef struct PropValue {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-cpu-add-new-CPU-models-for-indirect-bran.patch b/SOURCES/kvm-target-i386-cpu-add-new-CPU-models-for-indirect-bran.patch
new file mode 100644
index 0000000..94e54db
--- /dev/null
+++ b/SOURCES/kvm-target-i386-cpu-add-new-CPU-models-for-indirect-bran.patch
@@ -0,0 +1,932 @@
+From 052aaec83e84cc99a03e023eaaf58d289e0d5d05 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Wed, 13 Dec 2017 15:47:38 -0200
+Subject: [PATCH 3/3] target-i386: cpu: add new CPU models for indirect branch
+ predictor restrictions
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171213174738.20852-4-ehabkost@redhat.com>
+Patchwork-id: n/a
+O-Subject: [CONFIDENTIAL][RHEL-7.5 qemu-kvm-rhev PATCH v2 3/3] target-i386: cpu: add
+ new CPU models for indirect branch predictor restrictions
+Bugzilla: CVE-2017-5715
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+To ensure the New CPU models won't introduce any unexpected
+changes except for the spec-ctrl feature (even if people are
+running older machine-types), copy all compat_props entries for
+existing CPU models to their *-IBRS versions.
+
+The only entries that are not being copied are the ones touching
+"(min-)level" and "(min-)xlevel" because it's an expected result
+of the CPU model change (otherwise the spec-ctrl feature would
+remain unavailable to the guest).
+
+The entries that had to be copied can be found using:
+  $ git grep -E 'Nehalem|Westmere|SandyBridge|IvyBridge|Haswell-noTSX|Haswell|Broadwell-noTSX|Broadwell|Skylake-Client|Skylake-Server|EPYC'
+
+Note that the upstream-only PC_COMPAT_* macros are not being
+touched as they are not used by the RHEL machine-types
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>.
+---
+ hw/i386/pc_piix.c    | 100 ++++++++++++
+ include/hw/i386/pc.h |  75 +++++++++
+ target/i386/cpu.c    | 425 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ target/i386/cpu.h    |   3 +
+ 4 files changed, 602 insertions(+), 1 deletion(-)
+
+diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
+index c10e462..7a205c4 100644
+--- a/hw/i386/pc_piix.c
++++ b/hw/i386/pc_piix.c
+@@ -1444,96 +1444,191 @@ DEFINE_PC_MACHINE(rhel700, "pc-i440fx-rhel7.0.0", pc_init_rhel700,
+             .property = "x2apic",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "x2apic",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "x2apic",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "pclmulqdq",\
+             .value = "off",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "pclmulqdq",\
++            .value = "off",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "fxsr",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "fxsr",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "mmx",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "mmx",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "pat",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "pat",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "cmov",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "cmov",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "pge",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "pge",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "apic",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "apic",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "cx8",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "cx8",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "mce",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "mce",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "pae",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "pae",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "msr",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "msr",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "tsc",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "tsc",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "pse",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "pse",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "de",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "de",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Westmere" "-" TYPE_X86_CPU,\
+             .property = "fpu",\
+             .value = "on",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++            .property = "fpu",\
++            .value = "on",\
++        },\
+         {\
+             .driver = "Broadwell" "-" TYPE_X86_CPU,\
+             .property = "rdtscp",\
+             .value = "off",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\
++            .property = "rdtscp",\
++            .value = "off",\
++        },\
+         {\
+             .driver = "Broadwell" "-" TYPE_X86_CPU,\
+             .property = "smap",\
+             .value = "off",\
+         },\
++        { /* PC_RHEL6_6_COMPAT (copied from the entry above) */ \
++            .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\
++            .property = "smap",\
++            .value = "off",\
++        },\
+         {\
+             .driver = TYPE_X86_CPU,\
+             .property = "rdtscp",\
+@@ -1752,6 +1847,11 @@ DEFINE_PC_MACHINE(rhel640, "rhel6.4.0", pc_init_rhel640,
+             .driver = "SandyBridge" "-" TYPE_X86_CPU,\
+             .property = "tsc-deadline",\
+             .value = "off",\
++        },\
++        { /* PC_RHEL6_3_COMPAT (copied from the entry above) */ \
++            .driver = "SandyBridge-IBRS" "-" TYPE_X86_CPU,\
++            .property = "tsc-deadline",\
++            .value = "off",\
+         },
+ 
+ static void pc_compat_rhel630(MachineState *machine)
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index f9b7998..d1b1320 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -1118,21 +1118,41 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+             .property = "abm",\
+             .value    = "off",\
+         },\
++        { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \
++            .driver   = "Haswell-IBRS" "-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
+         { /* PC_RHEL7_2_COMPAT */ \
+             .driver   = "Haswell-noTSX-" TYPE_X86_CPU,\
+             .property = "abm",\
+             .value    = "off",\
+         },\
++        { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \
++            .driver   = "Haswell-noTSX-IBRS" "-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
+         { /* PC_RHEL7_2_COMPAT */ \
+             .driver   = "Broadwell-" TYPE_X86_CPU,\
+             .property = "abm",\
+             .value    = "off",\
+         },\
++        { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \
++            .driver   = "Broadwell-IBRS" "-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
+         { /* PC_RHEL7_2_COMPAT */ \
+             .driver   = "Broadwell-noTSX-" TYPE_X86_CPU,\
+             .property = "abm",\
+             .value    = "off",\
+         },\
++        { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \
++            .driver   = "Broadwell-noTSX-IBRS" "-" TYPE_X86_CPU,\
++            .property = "abm",\
++            .value    = "off",\
++        },\
+         { /* PC_RHEL7_2_COMPAT */ \
+             .driver   = "host" "-" TYPE_X86_CPU,\
+             .property = "host-cache-info",\
+@@ -1198,26 +1218,51 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+ 		.property = "vme",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Westmere" "-" TYPE_X86_CPU,\
+ 		.property = "vme",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "SandyBridge" "-" TYPE_X86_CPU,\
+ 		.property = "vme",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "SandyBridge-IBRS" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Haswell" "-" TYPE_X86_CPU,\
+ 		.property = "vme",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Broadwell" "-" TYPE_X86_CPU,\
+ 		.property = "vme",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\
++		.property = "vme",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Opteron_G1" "-" TYPE_X86_CPU,\
+ 		.property = "vme",\
+@@ -1248,21 +1293,41 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+ 		.property = "f16c",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\
++		.property = "f16c",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Haswell" "-" TYPE_X86_CPU,\
+ 		.property = "rdrand",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\
++		.property = "rdrand",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Broadwell" "-" TYPE_X86_CPU,\
+ 		.property = "f16c",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\
++		.property = "f16c",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "Broadwell" "-" TYPE_X86_CPU,\
+ 		.property = "rdrand",\
+ 		.value = "off",\
+ 	},\
++	{ /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \
++		.driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\
++		.property = "rdrand",\
++		.value = "off",\
++	},\
+ 	{\
+ 		.driver = "coreduo" "-" TYPE_X86_CPU,\
+ 		.property = "vmx",\
+@@ -1431,11 +1496,21 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+ 		.property = "x2apic",\
+ 		.value = "on",\
+ 	},\
++	{ /* PC_RHEL7_0_COMPAT (copied from the entry above) */ \
++		.driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
+ 	{\
+ 		.driver = "Westmere" "-" TYPE_X86_CPU,\
+ 		.property = "x2apic",\
+ 		.value = "on",\
+ 	},\
++	{ /* PC_RHEL7_0_COMPAT (copied from the entry above) */ \
++		.driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\
++		.property = "x2apic",\
++		.value = "on",\
++	},\
+ 	{\
+ 		.driver = "Opteron_G1" "-" TYPE_X86_CPU,\
+ 		.property = "x2apic",\
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 364e52e..da5a266 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1102,6 +1102,31 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
+     },
+     {
++        .name = "Nehalem-IBRS",
++        .level = 11,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 26,
++        .stepping = 3,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)",
++    },
++    {
+         .name = "Westmere",
+         .level = 11,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1128,6 +1153,34 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
+     },
+     {
++        .name = "Westmere-IBRS",
++        .level = 11,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 44,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)",
++    },
++    {
+         .name = "SandyBridge",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1159,6 +1212,39 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Xeon E312xx (Sandy Bridge)",
+     },
+     {
++        .name = "SandyBridge-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 42,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
++            CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
++            CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)",
++    },
++    {
+         .name = "IvyBridge",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1193,6 +1279,42 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
+     },
+     {
++        .name = "IvyBridge-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 58,
++        .stepping = 9,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
++            CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
++            CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_ERMS,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)",
++    },
++    {
+         .name = "Haswell-noTSX",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1227,7 +1349,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_6_EAX_ARAT,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Haswell, no TSX)",
+-    },    {
++    },
++    {
++        .name = "Haswell-noTSX-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 60,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Core Processor (Haswell, no TSX, IBRS)",
++    },
++    {
+         .name = "Haswell",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1265,6 +1426,45 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Core Processor (Haswell)",
+     },
+     {
++        .name = "Haswell-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 60,
++        .stepping = 4,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RTM,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Core Processor (Haswell, IBRS)",
++    },
++    {
+         .name = "Broadwell-noTSX",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1303,6 +1503,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Core Processor (Broadwell, no TSX)",
+     },
+     {
++        .name = "Broadwell-noTSX-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 61,
++        .stepping = 2,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
++            CPUID_7_0_EBX_SMAP,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Core Processor (Broadwell, no TSX, IBRS)",
++    },
++    {
+         .name = "Broadwell",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1341,6 +1581,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Core Processor (Broadwell)",
+     },
+     {
++        .name = "Broadwell-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 61,
++        .stepping = 2,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
++            CPUID_7_0_EBX_SMAP,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Core Processor (Broadwell, IBRS)",
++    },
++    {
+         .name = "Skylake-Client",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1386,6 +1666,53 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Core Processor (Skylake)",
+     },
+     {
++        .name = "Skylake-Client-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 94,
++        .stepping = 3,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
++            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
++        /* Missing: XSAVES (not supported by some Linux versions,
++         * including v4.1 to v4.12).
++         * KVM doesn't yet expose any XSAVES state save component,
++         * and the only one defined in Skylake (processor tracing)
++         * probably will block migration anyway.
++         */
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
++            CPUID_XSAVE_XGETBV1,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Core Processor (Skylake, IBRS)",
++    },
++    {
+         .name = "Skylake-Server",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1434,6 +1761,56 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "Intel Xeon Processor (Skylake)",
+     },
+     {
++        .name = "Skylake-Server-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 85,
++        .stepping = 4,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
++            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
++            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
++            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
++            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
++            CPUID_7_0_EBX_AVX512VL,
++        /* Missing: XSAVES (not supported by some Linux versions,
++         * including v4.1 to v4.12).
++         * KVM doesn't yet expose any XSAVES state save component,
++         * and the only one defined in Skylake (processor tracing)
++         * probably will block migration anyway.
++         */
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
++            CPUID_XSAVE_XGETBV1,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Xeon Processor (Skylake, IBRS)",
++    },
++    {
+         .name = "Opteron_G1",
+         .level = 5,
+         .vendor = CPUID_VENDOR_AMD,
+@@ -1607,6 +1984,52 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .xlevel = 0x8000000A,
+         .model_id = "AMD EPYC Processor",
+     },
++    {
++        .name = "EPYC-IBPB",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_AMD,
++        .family = 23,
++        .model = 1,
++        .stepping = 2,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
++            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
++            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
++            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
++            CPUID_VME | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
++            CPUID_EXT_XSAVE | CPUID_EXT_AES |  CPUID_EXT_POPCNT |
++            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
++            CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
++            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
++            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
++            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
++        .features[FEAT_8000_0008_EBX] =
++            CPUID_8000_0008_EBX_IBPB,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
++            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
++            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
++            CPUID_7_0_EBX_SHA_NI,
++        /* Missing: XSAVES (not supported by some Linux versions,
++         * including v4.1 to v4.12).
++         * KVM doesn't yet expose any XSAVES state save component.
++         */
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
++            CPUID_XSAVE_XGETBV1,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x8000000A,
++        .model_id = "AMD EPYC Processor (with IBPB)",
++    },
+ };
+ 
+ typedef struct PropValue {
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index f2686d5..eb77e85 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -643,6 +643,9 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
+ 
+ #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */
+ #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */
++#define CPUID_7_0_EDX_SPEC_CTRL     (1U << 26) /* Indirect Branch - Restrict Speculation */
++
++#define CPUID_8000_0008_EBX_IBPB    (1U << 12) /* Indirect Branch Prediction Barrier */
+ 
+ #define CPUID_XSAVE_XSAVEOPT   (1U << 0)
+ #define CPUID_XSAVE_XSAVEC     (1U << 1)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-cpu-add-new-CPUID-bits-for-indirect-bran.patch b/SOURCES/kvm-target-i386-cpu-add-new-CPUID-bits-for-indirect-bran.patch
new file mode 100644
index 0000000..ad28567
--- /dev/null
+++ b/SOURCES/kvm-target-i386-cpu-add-new-CPUID-bits-for-indirect-bran.patch
@@ -0,0 +1,91 @@
+From bc88b0d69c0e81626e5c246cae83e499bfa3dccb Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Wed, 13 Dec 2017 15:47:37 -0200
+Subject: [PATCH 2/3] target-i386: cpu: add new CPUID bits for indirect branch
+ predictor restrictions
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171213174738.20852-3-ehabkost@redhat.com>
+Patchwork-id: n/a
+O-Subject: [CONFIDENTIAL][RHEL-7.5 qemu-kvm-rhev PATCH v2 2/3] target-i386: add
+ support for SPEC_CTRL MSR
+Bugzilla: CVE-2017-5715
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/cpu.c | 23 ++++++++++++++++++++---
+ target/i386/cpu.h |  1 +
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index c2dee60..364e52e 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -456,8 +456,8 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL, NULL,
+-            NULL, NULL, NULL, NULL,
+-            NULL, NULL, NULL, NULL,
++            NULL, NULL, "spec-ctrl", "stibp",
++            NULL, "arch-facilities", NULL, NULL,
+         },
+         .cpuid_eax = 7,
+         .cpuid_needs_ecx = true, .cpuid_ecx = 0,
+@@ -480,6 +480,22 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         .tcg_features = TCG_APM_FEATURES,
+         .unmigratable_flags = CPUID_APM_INVTSC,
+     },
++    [FEAT_8000_0008_EBX] = {
++        .feat_names = {
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            "ibpb", NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .cpuid_eax = 0x80000008,
++        .cpuid_reg = R_EBX,
++        .tcg_features = 0,
++        .unmigratable_flags = 0,
++    },
+     [FEAT_XSAVE] = {
+         .feat_names = {
+             "xsaveopt", "xsavec", "xgetbv1", "xsaves",
+@@ -3122,7 +3138,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+         } else {
+             *eax = cpu->phys_bits;
+         }
+-        *ebx = 0;
++        *ebx = env->features[FEAT_8000_0008_EBX];
+         *ecx = 0;
+         *edx = 0;
+         if (cs->nr_cores * cs->nr_threads > 1) {
+@@ -3578,6 +3594,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+         x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
+         x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
+         x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX);
++        x86_cpu_adjust_feat_level(cpu, FEAT_8000_0008_EBX);
+         x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
+         x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
+         x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 4dfb859..f2686d5 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -454,6 +454,7 @@ typedef enum FeatureWord {
+     FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
+     FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+     FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
++    FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */
+     FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
+     FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
+     FEAT_HYPERV_EAX,    /* CPUID[4000_0003].EAX */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-sanitize-x86-MSR_PAT-loaded-from-another.patch b/SOURCES/kvm-target-i386-sanitize-x86-MSR_PAT-loaded-from-another.patch
new file mode 100644
index 0000000..32fa560
--- /dev/null
+++ b/SOURCES/kvm-target-i386-sanitize-x86-MSR_PAT-loaded-from-another.patch
@@ -0,0 +1,77 @@
+From 7705b73dcfd0a9391bb93b9e26695ecb6dc51139 Mon Sep 17 00:00:00 2001
+From: Wei Huang <wei@redhat.com>
+Date: Wed, 17 Jan 2018 22:13:23 +0100
+Subject: [PATCH 05/21] target-i386: sanitize x86 MSR_PAT loaded from another
+ source
+
+RH-Author: Wei Huang <wei@redhat.com>
+Message-id: <20180117221323.1008-1-wei@redhat.com>
+Patchwork-id: 78659
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] target-i386: sanitize x86 MSR_PAT loaded from another source
+Bugzilla: 1529461
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+The RHEL 7 downstream commit a94f33258 honors guest VM's writes of MSR_PAT
+for SVM machines. But this cause a problem when an x86 VM is migrated from
+an old host, such as RHEL 6.9. This is because older system doesn't save
+the guest's PAT field during migration; Instead 0x0 is saved and migrated.
+At the destination, it will use 0x0 as guest PAT because of a94f33258.
+This causes the guest VM's performance to drop significatly.
+
+This patch solves the problem by sanitizing the PAT field. If it is zero,
+we use the default MSR_PAT value (0x0007040600070406ULL) to prevent
+performance drop. This solution should work with different types of
+(old or new) VM sources.
+
+Signed-off-by: Wei Huang <wei@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/i386/cpu.c     | 2 +-
+ target/i386/cpu.h     | 1 +
+ target/i386/machine.c | 3 +++
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index da5a266..81d0b75 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3678,7 +3678,7 @@ static void x86_cpu_reset(CPUState *s)
+     /* All units are in INIT state.  */
+     env->xstate_bv = 0;
+ 
+-    env->pat = 0x0007040600070406ULL;
++    env->pat = MSR_PAT_DEFAULT;
+     env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
+ 
+     memset(env->dr, 0, sizeof(env->dr));
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index eb77e85..e04579d 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -385,6 +385,7 @@
+ #define MSR_MTRRfix4K_F8000             0x26f
+ 
+ #define MSR_PAT                         0x277
++#define MSR_PAT_DEFAULT                 0x0007040600070406ULL
+ 
+ #define MSR_MTRRdefType                 0x2ff
+ 
+diff --git a/target/i386/machine.c b/target/i386/machine.c
+index 0212270..9f6ba9a 100644
+--- a/target/i386/machine.c
++++ b/target/i386/machine.c
+@@ -274,6 +274,9 @@ static int cpu_post_load(void *opaque, int version_id)
+     env->hflags &= ~HF_CPL_MASK;
+     env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
+ 
++    if (!(env->pat))
++        env->pat = MSR_PAT_DEFAULT;
++
+     env->fpstt = (env->fpus_vmstate >> 11) & 7;
+     env->fpus = env->fpus_vmstate & ~0x3800;
+     env->fptag_vmstate ^= 0xff;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-Add-POWER9-DD2.0-model-information.patch b/SOURCES/kvm-target-ppc-Add-POWER9-DD2.0-model-information.patch
new file mode 100644
index 0000000..9ff88d0
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-Add-POWER9-DD2.0-model-information.patch
@@ -0,0 +1,117 @@
+From f862178a20240a06504e35d11953982fcf769789 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Fri, 8 Dec 2017 14:48:39 +0100
+Subject: [PATCH 1/6] target/ppc: Add POWER9 DD2.0 model information
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20171208144839.6655-1-lvivier@redhat.com>
+Patchwork-id: 78276
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] target/ppc: Add POWER9 DD2.0 model information
+Bugzilla: 1523235
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+Tested: /usr/libexec/qemu-kvm -device help 2>&1|grep -i "power9"
+        name "POWER9_v1.0-spapr-cpu-core"
+        name "POWER9_v2.0-spapr-cpu-core"
+        /usr/libexec/qemu-kvm -cpu help 2>&1|grep -i "power9"
+        PowerPC POWER9_v1.0      PVR 004e0100
+        PowerPC POWER9_v2.0      PVR 004e1200
+        PowerPC POWER9           (alias for preferred POWER9 CPU)
+
+At the moment the only POWER9 model which is listed in qemu is v1.0 (aka
+"DD1").  This is a very early (read, buggy) version which will never be
+released to the public - it was included in qemu only for the convenience
+of those doing bringup on the early silicon.  For bonus points, we actually
+had its PVR incorrect in the table (0x004e0000 instead of 0x004e0100).  We
+also never actually implemented the differences in behaviour (read, bugs)
+that marked DD1 in qemu.
+
+Now that we know the PVR for the substantially better v2.0 (DD2) chip,
+include it and make it the default POWER9 in qemu.  For the time being we
+leave the DD1 definition in place for the poor souls (read, me) who still
+need to work with DD1 hardware.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 1ed9c8af501f8d1bdf5a8725a038527be059f54d)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr_cpu_core.c
+	target/ppc/cpu-models.c
+
+with downstream only commit:
+
+  0e72e616b2 Enable/disable devices for RHEL 7
+
+introducing "#if .. #endif" in the CPU list
+
+And missing upstream commit:
+
+  c5354f5 ppc: make cpu_model translation to type consistent
+
+changing all the CPU names to lower-case and then doing
+case-insensitive matching. I've chosen to not backport this one
+because it changes the behaviour of the interface (vs upstream 2.10).
+---
+ hw/ppc/spapr_cpu_core.c | 1 +
+ target/ppc/cpu-models.c | 6 ++++--
+ target/ppc/cpu-models.h | 1 +
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
+index 400ab56..30c15d5 100644
+--- a/hw/ppc/spapr_cpu_core.c
++++ b/hw/ppc/spapr_cpu_core.c
+@@ -308,6 +308,7 @@ static const char *spapr_core_models[] = {
+     "POWER8NVL_v1.0",
+     /* POWER9 */
+     "POWER9_v1.0",
++    "POWER9_v2.0",
+ };
+ 
+ static Property spapr_cpu_core_properties[] = {
+diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
+index 08a1f59..975aa07 100644
+--- a/target/ppc/cpu-models.c
++++ b/target/ppc/cpu-models.c
+@@ -1150,8 +1150,10 @@
+                 "PowerPC 970 v2.2")
+ #endif
+ 
+-    POWERPC_DEF("POWER9_v1.0",   CPU_POWERPC_POWER9_BASE,            POWER9,
++    POWERPC_DEF("POWER9_v1.0",   CPU_POWERPC_POWER9_DD1,             POWER9,
+                 "POWER9 v1.0")
++    POWERPC_DEF("POWER9_v2.0",   CPU_POWERPC_POWER9_DD20,            POWER9,
++                "POWER9 v2.0")
+ 
+ #if 0  /* Disabled for Red Hat Enterprise Linux */
+     POWERPC_DEF("970fx_v1.0",    CPU_POWERPC_970FX_v10,              970,
+@@ -1403,7 +1405,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
+     { "POWER8E", "POWER8E_v2.1" },
+     { "POWER8", "POWER8_v2.0" },
+     { "POWER8NVL", "POWER8NVL_v1.0" },
+-    { "POWER9", "POWER9_v1.0" },
++    { "POWER9", "POWER9_v2.0" },
+ #if 0  /* Disabled for Red Hat Enterprise Linux */
+     { "970", "970_v2.2" },
+     { "970fx", "970fx_v3.1" },
+diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
+index b563c45..fc1b1d2 100644
+--- a/target/ppc/cpu-models.h
++++ b/target/ppc/cpu-models.h
+@@ -562,6 +562,7 @@ enum {
+     CPU_POWERPC_POWER8NVL_v10      = 0x004C0100,
+     CPU_POWERPC_POWER9_BASE        = 0x004E0000,
+     CPU_POWERPC_POWER9_DD1         = 0x004E0100,
++    CPU_POWERPC_POWER9_DD20        = 0x004E1200,
+     CPU_POWERPC_970_v22            = 0x00390202,
+     CPU_POWERPC_970FX_v10          = 0x00391100,
+     CPU_POWERPC_970FX_v20          = 0x003C0200,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-Clarify-compat-mode-max_threads-value.patch b/SOURCES/kvm-target-ppc-Clarify-compat-mode-max_threads-value.patch
new file mode 100644
index 0000000..8ec069a
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-Clarify-compat-mode-max_threads-value.patch
@@ -0,0 +1,162 @@
+From b25ff3cd5a8b561f58b0245115d61cde0572cbdc Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Fri, 19 Jan 2018 04:04:56 +0100
+Subject: [PATCH 16/21] target/ppc: Clarify compat mode max_threads value
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20180119040458.5629-3-dgibson@redhat.com>
+Patchwork-id: 78676
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 2/4] target/ppc: Clarify compat mode max_threads value
+Bugzilla: 1529243
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: David Gibson <david@gibson.dropbear.id.au>
+
+We recently had some discussions that were sidetracked for a while, because
+nearly everyone misapprehended the purpose of the 'max_threads' field in
+the compatiblity modes table.  It's all about guest expectations, not host
+expectations or support (that's handled elsewhere).
+
+In an attempt to avoid a repeat of that confusion, rename the field to
+'max_vthreads' and add an explanatory comment.
+
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com>
+(cherry picked from commit abbc124753896f72e3715813ea20dd1924202ff0)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/ppc/spapr.c
+
+Contextual conflict.
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+---
+ hw/ppc/spapr.c      |  4 ++--
+ target/ppc/compat.c | 25 +++++++++++++++++--------
+ target/ppc/cpu.h    |  2 +-
+ 3 files changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 66227c3..5233366 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -345,7 +345,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
+         PowerPCCPU *cpu = POWERPC_CPU(cs);
+         DeviceClass *dc = DEVICE_GET_CLASS(cs);
+         int index = ppc_get_vcpu_dt_id(cpu);
+-        int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
++        int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
+ 
+         if ((index % smt) != 0) {
+             continue;
+@@ -506,7 +506,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+     size_t page_sizes_prop_size;
+     uint32_t vcpus_per_socket = smp_threads * smp_cores;
+     uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
+-    int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
++    int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
+     sPAPRDRConnector *drc;
+     int drc_index;
+     uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];
+diff --git a/target/ppc/compat.c b/target/ppc/compat.c
+index 94ff14a..33658fb 100644
+--- a/target/ppc/compat.c
++++ b/target/ppc/compat.c
+@@ -32,7 +32,16 @@ typedef struct {
+     uint32_t pvr;
+     uint64_t pcr;
+     uint64_t pcr_level;
+-    int max_threads;
++
++    /*
++     * Maximum allowed virtual threads per virtual core
++     *
++     * This is to stop older guests getting confused by seeing more
++     * threads than they think the cpu can support.  Usually it's
++     * equal to the number of threads supported on bare metal
++     * hardware, but not always (see POWER9).
++     */
++    int max_vthreads;
+ } CompatInfo;
+ 
+ static const CompatInfo compat_table[] = {
+@@ -45,28 +54,28 @@ static const CompatInfo compat_table[] = {
+         .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
+                PCR_COMPAT_2_05 | PCR_TM_DIS | PCR_VSX_DIS,
+         .pcr_level = PCR_COMPAT_2_05,
+-        .max_threads = 2,
++        .max_vthreads = 2,
+     },
+     { /* POWER7, ISA2.06 */
+         .name = "power7",
+         .pvr = CPU_POWERPC_LOGICAL_2_06,
+         .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS,
+         .pcr_level = PCR_COMPAT_2_06,
+-        .max_threads = 4,
++        .max_vthreads = 4,
+     },
+     {
+         .name = "power7+",
+         .pvr = CPU_POWERPC_LOGICAL_2_06_PLUS,
+         .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS,
+         .pcr_level = PCR_COMPAT_2_06,
+-        .max_threads = 4,
++        .max_vthreads = 4,
+     },
+     { /* POWER8, ISA2.07 */
+         .name = "power8",
+         .pvr = CPU_POWERPC_LOGICAL_2_07,
+         .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07,
+         .pcr_level = PCR_COMPAT_2_07,
+-        .max_threads = 8,
++        .max_vthreads = 8,
+     },
+     { /* POWER9, ISA3.00 */
+         .name = "power9",
+@@ -80,7 +89,7 @@ static const CompatInfo compat_table[] = {
+          * confusing if half of the threads disappear from the guest
+          * if it announces it's POWER9 aware at CAS time.
+          */
+-        .max_threads = 8,
++        .max_vthreads = 8,
+     },
+ };
+ 
+@@ -203,14 +212,14 @@ void ppc_set_compat_all(uint32_t compat_pvr, Error **errp)
+     }
+ }
+ 
+-int ppc_compat_max_threads(PowerPCCPU *cpu)
++int ppc_compat_max_vthreads(PowerPCCPU *cpu)
+ {
+     const CompatInfo *compat = compat_by_pvr(cpu->compat_pvr);
+     int n_threads = CPU(cpu)->nr_threads;
+ 
+     if (cpu->compat_pvr) {
+         g_assert(compat);
+-        n_threads = MIN(n_threads, compat->max_threads);
++        n_threads = MIN(n_threads, compat->max_vthreads);
+     }
+ 
+     return n_threads;
+diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
+index 6c770a2..9b107e4 100644
+--- a/target/ppc/cpu.h
++++ b/target/ppc/cpu.h
+@@ -1374,7 +1374,7 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp);
+ #if !defined(CONFIG_USER_ONLY)
+ void ppc_set_compat_all(uint32_t compat_pvr, Error **errp);
+ #endif
+-int ppc_compat_max_threads(PowerPCCPU *cpu);
++int ppc_compat_max_vthreads(PowerPCCPU *cpu);
+ void ppc_compat_add_property(Object *obj, const char *name,
+                              uint32_t *compat_pvr, const char *basedesc,
+                              Error **errp);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-Fix-setting-of-cpu-compat_pvr-on-incoming.patch b/SOURCES/kvm-target-ppc-Fix-setting-of-cpu-compat_pvr-on-incoming.patch
new file mode 100644
index 0000000..ad5934a
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-Fix-setting-of-cpu-compat_pvr-on-incoming.patch
@@ -0,0 +1,63 @@
+From ae27b925a8cda59917f47b834492fc77d341d898 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 5 Dec 2017 05:55:19 +0100
+Subject: [PATCH 14/21] target/ppc: Fix setting of cpu->compat_pvr on incoming
+ migration
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1512453319-16676-3-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78133
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 2/2] target/ppc: Fix setting of cpu->compat_pvr on incoming migration
+Bugzilla: 1517051
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+cpu->compat_pvr is used to store the current compat mode of the cpu.
+
+On the receiving side during incoming migration we check compatibility
+with the compat mode by calling ppc_set_compat(). However we fail to set
+the compat mode with the hypervisor since the "new" compat mode doesn't
+differ from the current (due to a "cpu->compat_pvr != compat_pvr" check).
+This means that kvm runs the vcpus without a compat mode, which is the
+incorrect behaviour. The implication being that a compatibility mode
+will never be in effect after migration.
+
+To fix this so that the compat mode is correctly set with the
+hypervisor, store the desired compat mode and reset cpu->compat_pvr to
+zero before calling ppc_set_compat().
+
+Fixes: 5dfaa532 ("ppc: fix ppc_set_compat() with KVM PR")
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit e07cc1929515cfb808b5c2fcc60c079e6be110cf)
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/ppc/machine.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/target/ppc/machine.c b/target/ppc/machine.c
+index e36b710..760be64d 100644
+--- a/target/ppc/machine.c
++++ b/target/ppc/machine.c
+@@ -235,9 +235,11 @@ static int cpu_post_load(void *opaque, int version_id)
+ 
+ #if defined(TARGET_PPC64)
+     if (cpu->compat_pvr) {
++        uint32_t compat_pvr = cpu->compat_pvr;
+         Error *local_err = NULL;
+ 
+-        ppc_set_compat(cpu, cpu->compat_pvr, &local_err);
++        cpu->compat_pvr = 0;
++        ppc_set_compat(cpu, compat_pvr, &local_err);
+         if (local_err) {
+             error_report_err(local_err);
+             return -1;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-Move-setting-of-patb_entry-on-hash-table-.patch b/SOURCES/kvm-target-ppc-Move-setting-of-patb_entry-on-hash-table-.patch
new file mode 100644
index 0000000..29876ca
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-Move-setting-of-patb_entry-on-hash-table-.patch
@@ -0,0 +1,67 @@
+From 57adfa908abbf97d98a19724447565731f3f825f Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 5 Dec 2017 05:55:18 +0100
+Subject: [PATCH 13/21] target/ppc: Move setting of patb_entry on hash table
+ init
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1512453319-16676-2-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78134
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 1/2] target/ppc: Move setting of patb_entry on hash table init
+Bugzilla: 1517051
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+The patb_entry is used to store the location of the process table in
+guest memory. The msb is also used to indicate the mmu mode of the
+guest, that is patb_entry & 1 << 63 ? radix_mode : hash_mode.
+
+Currently we set this to zero in spapr_setup_hpt_and_vrma() since if
+this function gets called then we know we're hash. However some code
+paths, such as setting up the hpt on incoming migration of a hash guest,
+call spapr_reallocate_hpt() directly bypassing this higher level
+function. Since we assume radix if the host is capable this results in
+the msb in patb_entry being left set so in spapr_post_load() we call
+kvmppc_configure_v3_mmu() and tell the host we're radix which as
+expected means addresses cannot be translated once we actually run the cpu.
+
+To fix this move the zeroing of patb_entry into spapr_reallocate_hpt().
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit ee4d9ecc3675af1e68a9c00a8b338641898d613e)
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 8623996..e3dce84 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1356,6 +1356,8 @@ void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
+             DIRTY_HPTE(HPTE(spapr->htab, i));
+         }
+     }
++    /* We're setting up a hash table, so that means we're not radix */
++    spapr->patb_entry = 0;
+ }
+ 
+ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
+@@ -1375,8 +1377,6 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
+         spapr->rma_size = kvmppc_rma_size(spapr_node0_size(),
+                                           spapr->htab_shift);
+     }
+-    /* We're setting up a hash table, so that means we're not radix */
+-    spapr->patb_entry = 0;
+ }
+ 
+ static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-Update-setting-of-cpu-features-to-account.patch b/SOURCES/kvm-target-ppc-Update-setting-of-cpu-features-to-account.patch
new file mode 100644
index 0000000..996a12e
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-Update-setting-of-cpu-features-to-account.patch
@@ -0,0 +1,168 @@
+From ba38a0071969c6a428cf165e31ec0e91b7167af8 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Fri, 24 Nov 2017 00:58:17 +0100
+Subject: [PATCH 12/15] target/ppc: Update setting of cpu features to account
+ for compat modes
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1511485097-25676-3-git-send-email-sursingh@redhat.com>
+Patchwork-id: 77847
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 2/2] target/ppc: Update setting of cpu features to account for compat modes
+Bugzilla: 1396120
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+The device tree nodes ibm,arch-vec-5-platform-support and ibm,pa-features
+are used to communicate features of the cpu to the guest operating
+system. The properties of each of these are determined based on the
+selected cpu model and the availability of hypervisor features.
+Currently the compatibility mode of the cpu is not taken into account.
+
+The ibm,arch-vec-5-platform-support node is used to communicate the
+level of support for various ISAv3 processor features to the guest
+before CAS to inform the guests' request. The available mmu mode should
+only be hash unless the cpu is a POWER9 which is not in a prePOWER9
+compat mode, in which case the available modes depend on the
+accelerator and the hypervisor capabilities.
+
+The ibm,pa-featues node is used to communicate the level of cpu support
+for various features to the guest os. This should only contain features
+relevant to the operating mode of the processor, that is the selected
+cpu model taking into account any compat mode. This means that the
+compat mode should be taken into account when choosing the properties of
+ibm,pa-features and they should match the compat mode selected, or the
+cpu model selected if no compat mode.
+
+Update the setting of these cpu features in the device tree as described
+above to properly take into account any compat mode. We use the
+ppc_check_compat function which takes into account the current processor
+model and the cpu compat mode.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 7abd43baec0649002d32bbb1380e936bec6f5867)
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c | 43 +++++++++++++++++++++----------------------
+ 1 file changed, 21 insertions(+), 22 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 42028ef..96df3a7 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -44,6 +44,7 @@
+ #include "migration/register.h"
+ #include "mmu-hash64.h"
+ #include "mmu-book3s-v3.h"
++#include "cpu-models.h"
+ #include "qom/cpu.h"
+ 
+ #include "hw/boards.h"
+@@ -252,9 +253,10 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
+ }
+ 
+ /* Populate the "ibm,pa-features" property */
+-static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset,
+-                                      bool legacy_guest)
++static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
++                                       bool legacy_guest)
+ {
++    CPUPPCState *env = &cpu->env;
+     uint8_t pa_features_206[] = { 6, 0,
+         0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
+     uint8_t pa_features_207[] = { 24, 0,
+@@ -287,23 +289,22 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset,
+         /* 60: NM atomic, 62: RNG */
+         0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
+     };
+-    uint8_t *pa_features;
++    uint8_t *pa_features = NULL;
+     size_t pa_size;
+ 
+-    switch (POWERPC_MMU_VER(env->mmu_model)) {
+-    case POWERPC_MMU_VER_2_06:
++    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06, 0, cpu->compat_pvr)) {
+         pa_features = pa_features_206;
+         pa_size = sizeof(pa_features_206);
+-        break;
+-    case POWERPC_MMU_VER_2_07:
++    }
++    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07, 0, cpu->compat_pvr)) {
+         pa_features = pa_features_207;
+         pa_size = sizeof(pa_features_207);
+-        break;
+-    case POWERPC_MMU_VER_3_00:
++    }
++    if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, cpu->compat_pvr)) {
+         pa_features = pa_features_300;
+         pa_size = sizeof(pa_features_300);
+-        break;
+-    default:
++    }
++    if (!pa_features) {
+         return;
+     }
+ 
+@@ -340,7 +341,6 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
+ 
+     CPU_FOREACH(cs) {
+         PowerPCCPU *cpu = POWERPC_CPU(cs);
+-        CPUPPCState *env = &cpu->env;
+         DeviceClass *dc = DEVICE_GET_CLASS(cs);
+         int index = ppc_get_vcpu_dt_id(cpu);
+         int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
+@@ -385,7 +385,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
+             return ret;
+         }
+ 
+-        spapr_populate_pa_features(env, fdt, offset,
++        spapr_populate_pa_features(cpu, fdt, offset,
+                                          spapr->cas_legacy_guest_workaround);
+     }
+     return ret;
+@@ -582,7 +582,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+                           page_sizes_prop, page_sizes_prop_size)));
+     }
+ 
+-    spapr_populate_pa_features(env, fdt, offset, false);
++    spapr_populate_pa_features(cpu, fdt, offset, false);
+ 
+     _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
+                            cs->cpu_index / vcpus_per_socket)));
+@@ -945,7 +945,11 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
+         26, 0x40, /* Radix options: GTSE == yes. */
+     };
+ 
+-    if (kvm_enabled()) {
++    if (!ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
++                          first_ppc_cpu->compat_pvr)) {
++        /* If we're in a pre POWER9 compat mode then the guest should do hash */
++        val[3] = 0x00; /* Hash */
++    } else if (kvm_enabled()) {
+         if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
+             val[3] = 0x80; /* OV5_MMU_BOTH */
+         } else if (kvmppc_has_cap_mmu_radix()) {
+@@ -954,13 +958,8 @@ static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
+             val[3] = 0x00; /* Hash */
+         }
+     } else {
+-        if (first_ppc_cpu->env.mmu_model & POWERPC_MMU_V3) {
+-            /* V3 MMU supports both hash and radix (with dynamic switching) */
+-            val[3] = 0xC0;
+-        } else {
+-            /* Otherwise we can only do hash */
+-            val[3] = 0x00;
+-        }
++        /* V3 MMU supports both hash and radix in tcg (with dynamic switching) */
++        val[3] = 0xC0;
+     }
+     _FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support",
+                      val, sizeof(val)));
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-correct-htab-shift-for-hash-on-radix.patch b/SOURCES/kvm-target-ppc-correct-htab-shift-for-hash-on-radix.patch
new file mode 100644
index 0000000..2b162e9
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-correct-htab-shift-for-hash-on-radix.patch
@@ -0,0 +1,78 @@
+From c1ed391fd7e14e16387f8d5e320b13157851db9a Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Fri, 24 Nov 2017 00:58:16 +0100
+Subject: [PATCH 11/15] target/ppc: correct htab shift for hash on radix
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1511485097-25676-2-git-send-email-sursingh@redhat.com>
+Patchwork-id: 77845
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 1/2] target/ppc: correct htab shift for hash on radix
+Bugzilla: 1396120
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Sam Bobroff <sam.bobroff@au1.ibm.com>
+
+KVM HV will soon support running a guest in hash mode on a POWER9 host
+running in radix mode (see [1]), however the guest currently fails to
+boot.
+
+This is because the "htab_shift" value (the size of the MMU's hash
+table) is added to the device tree before KVM has had a chance to
+change it. If the host is in hash mode, KVM does not need to change it
+and so the problem is not seen, but when the host is in radix mode a
+change is required and we see a problem.
+
+To fix this, move the call spapr_setup_hpt_and_vrma() (where
+htab_shift could be changed) up a little so that it's called before
+spapr_h_cas_compose_response() (where htab_shift is added to the
+device tree).
+
+Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
+
+[1] See http://www.spinics.net/lists/kvm-ppc/msg13057.html
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+
+(cherry picked from commit e05fba5004676cd0fa7c47b623cb0a14ad1feed8)
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_hcall.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
+index 92f1e21..b503299 100644
+--- a/hw/ppc/spapr_hcall.c
++++ b/hw/ppc/spapr_hcall.c
+@@ -1609,6 +1609,12 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
+     spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
+                                                           OV1_PPC_3_00);
+     if (!spapr->cas_reboot) {
++        /* If ppc_spapr_reset() did not set up a HPT but one is necessary
++         * (because the guest isn't going to use radix) then set it up here. */
++        if ((spapr->patb_entry & PATBE1_GR) && !guest_radix) {
++            /* legacy hash or new hash: */
++            spapr_setup_hpt_and_vrma(spapr);
++        }
+         spapr->cas_reboot =
+             (spapr_h_cas_compose_response(spapr, args[1], args[2],
+                                           ov5_updates) != 0);
+@@ -1617,13 +1623,6 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
+ 
+     if (spapr->cas_reboot) {
+         qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+-    } else {
+-        /* If ppc_spapr_reset() did not set up a HPT but one is necessary
+-         * (because the guest isn't going to use radix) then set it up here. */
+-        if ((spapr->patb_entry & PATBE1_GR) && !guest_radix) {
+-            /* legacy hash or new hash: */
+-            spapr_setup_hpt_and_vrma(spapr);
+-        }
+     }
+ 
+     return H_SUCCESS;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-introduce-the-PPC_BIT-macro.patch b/SOURCES/kvm-target-ppc-introduce-the-PPC_BIT-macro.patch
new file mode 100644
index 0000000..53cef0e
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-introduce-the-PPC_BIT-macro.patch
@@ -0,0 +1,190 @@
+From 6c787760c9ce1b5101c29e43de38d8e1974be482 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:28 +0100
+Subject: [PATCH 11/15] target/ppc: introduce the PPC_BIT() macro
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-8-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78989
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 7/9] target/ppc: introduce the PPC_BIT() macro
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Cédric Le Goater <clg@kaod.org>
+
+and use them in a couple of obvious places. Other macros will be used
+in the model of the XIVE interrupt controller.
+
+Signed-off-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 2a83f9976efa9a85e8ceb9d1035a68f25c321334)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ target/ppc/cpu.h | 105 +++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 56 insertions(+), 49 deletions(-)
+
+diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
+index 9b107e4..7453250 100644
+--- a/target/ppc/cpu.h
++++ b/target/ppc/cpu.h
+@@ -87,6 +87,13 @@
+ #define PPC_ELF_MACHINE     EM_PPC
+ #endif
+ 
++#define PPC_BIT(bit)            (0x8000000000000000UL >> (bit))
++#define PPC_BIT32(bit)          (0x80000000UL >> (bit))
++#define PPC_BIT8(bit)           (0x80UL >> (bit))
++#define PPC_BITMASK(bs, be)     ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
++#define PPC_BITMASK32(bs, be)   ((PPC_BIT32(bs) - PPC_BIT32(be)) | \
++                                 PPC_BIT32(bs))
++
+ /*****************************************************************************/
+ /* Exception vectors definitions                                             */
+ enum {
+@@ -371,10 +378,10 @@ struct ppc_slb_t {
+ #define MSR_LE   0  /* Little-endian mode                           1 hflags */
+ 
+ /* LPCR bits */
+-#define LPCR_VPM0         (1ull << (63 - 0))
+-#define LPCR_VPM1         (1ull << (63 - 1))
+-#define LPCR_ISL          (1ull << (63 - 2))
+-#define LPCR_KBV          (1ull << (63 - 3))
++#define LPCR_VPM0         PPC_BIT(0)
++#define LPCR_VPM1         PPC_BIT(1)
++#define LPCR_ISL          PPC_BIT(2)
++#define LPCR_KBV          PPC_BIT(3)
+ #define LPCR_DPFD_SHIFT   (63 - 11)
+ #define LPCR_DPFD         (0x7ull << LPCR_DPFD_SHIFT)
+ #define LPCR_VRMASD_SHIFT (63 - 16)
+@@ -382,41 +389,41 @@ struct ppc_slb_t {
+ /* P9: Power-saving mode Exit Cause Enable (Upper Section) Mask */
+ #define LPCR_PECE_U_SHIFT (63 - 19)
+ #define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
+-#define LPCR_HVEE         (1ull << (63 - 17)) /* Hypervisor Virt Exit Enable */
++#define LPCR_HVEE         PPC_BIT(17) /* Hypervisor Virt Exit Enable */
+ #define LPCR_RMLS_SHIFT   (63 - 37)
+ #define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
+-#define LPCR_ILE          (1ull << (63 - 38))
++#define LPCR_ILE          PPC_BIT(38)
+ #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
+ #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
+-#define LPCR_UPRT         (1ull << (63 - 41)) /* Use Process Table */
+-#define LPCR_EVIRT        (1ull << (63 - 42)) /* Enhanced Virtualisation */
+-#define LPCR_ONL          (1ull << (63 - 45))
+-#define LPCR_LD           (1ull << (63 - 46)) /* Large Decrementer */
+-#define LPCR_P7_PECE0     (1ull << (63 - 49))
+-#define LPCR_P7_PECE1     (1ull << (63 - 50))
+-#define LPCR_P7_PECE2     (1ull << (63 - 51))
+-#define LPCR_P8_PECE0     (1ull << (63 - 47))
+-#define LPCR_P8_PECE1     (1ull << (63 - 48))
+-#define LPCR_P8_PECE2     (1ull << (63 - 49))
+-#define LPCR_P8_PECE3     (1ull << (63 - 50))
+-#define LPCR_P8_PECE4     (1ull << (63 - 51))
++#define LPCR_UPRT         PPC_BIT(41) /* Use Process Table */
++#define LPCR_EVIRT        PPC_BIT(42) /* Enhanced Virtualisation */
++#define LPCR_ONL          PPC_BIT(45)
++#define LPCR_LD           PPC_BIT(46) /* Large Decrementer */
++#define LPCR_P7_PECE0     PPC_BIT(49)
++#define LPCR_P7_PECE1     PPC_BIT(50)
++#define LPCR_P7_PECE2     PPC_BIT(51)
++#define LPCR_P8_PECE0     PPC_BIT(47)
++#define LPCR_P8_PECE1     PPC_BIT(48)
++#define LPCR_P8_PECE2     PPC_BIT(49)
++#define LPCR_P8_PECE3     PPC_BIT(50)
++#define LPCR_P8_PECE4     PPC_BIT(51)
+ /* P9: Power-saving mode Exit Cause Enable (Lower Section) Mask */
+ #define LPCR_PECE_L_SHIFT (63 - 51)
+ #define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
+-#define LPCR_PDEE         (1ull << (63 - 47)) /* Privileged Doorbell Exit EN */
+-#define LPCR_HDEE         (1ull << (63 - 48)) /* Hyperv Doorbell Exit Enable */
+-#define LPCR_EEE          (1ull << (63 - 49)) /* External Exit Enable        */
+-#define LPCR_DEE          (1ull << (63 - 50)) /* Decrementer Exit Enable     */
+-#define LPCR_OEE          (1ull << (63 - 51)) /* Other Exit Enable           */
+-#define LPCR_MER          (1ull << (63 - 52))
+-#define LPCR_GTSE         (1ull << (63 - 53)) /* Guest Translation Shootdown */
+-#define LPCR_TC           (1ull << (63 - 54))
+-#define LPCR_HEIC         (1ull << (63 - 59)) /* HV Extern Interrupt Control */
+-#define LPCR_LPES0        (1ull << (63 - 60))
+-#define LPCR_LPES1        (1ull << (63 - 61))
+-#define LPCR_RMI          (1ull << (63 - 62))
+-#define LPCR_HVICE        (1ull << (63 - 62)) /* HV Virtualisation Int Enable */
+-#define LPCR_HDICE        (1ull << (63 - 63))
++#define LPCR_PDEE         PPC_BIT(47) /* Privileged Doorbell Exit EN */
++#define LPCR_HDEE         PPC_BIT(48) /* Hyperv Doorbell Exit Enable */
++#define LPCR_EEE          PPC_BIT(49) /* External Exit Enable        */
++#define LPCR_DEE          PPC_BIT(50) /* Decrementer Exit Enable     */
++#define LPCR_OEE          PPC_BIT(51) /* Other Exit Enable           */
++#define LPCR_MER          PPC_BIT(52)
++#define LPCR_GTSE         PPC_BIT(53) /* Guest Translation Shootdown */
++#define LPCR_TC           PPC_BIT(54)
++#define LPCR_HEIC         PPC_BIT(59) /* HV Extern Interrupt Control */
++#define LPCR_LPES0        PPC_BIT(60)
++#define LPCR_LPES1        PPC_BIT(61)
++#define LPCR_RMI          PPC_BIT(62)
++#define LPCR_HVICE        PPC_BIT(62) /* HV Virtualisation Int Enable */
++#define LPCR_HDICE        PPC_BIT(63)
+ 
+ #define msr_sf   ((env->msr >> MSR_SF)   & 1)
+ #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
+@@ -507,22 +514,22 @@ struct ppc_slb_t {
+ #define FSCR_IC_TAR         8
+ 
+ /* Exception state register bits definition                                  */
+-#define ESR_PIL   (1 << (63 - 36)) /* Illegal Instruction                    */
+-#define ESR_PPR   (1 << (63 - 37)) /* Privileged Instruction                 */
+-#define ESR_PTR   (1 << (63 - 38)) /* Trap                                   */
+-#define ESR_FP    (1 << (63 - 39)) /* Floating-Point Operation               */
+-#define ESR_ST    (1 << (63 - 40)) /* Store Operation                        */
+-#define ESR_AP    (1 << (63 - 44)) /* Auxiliary Processor Operation          */
+-#define ESR_PUO   (1 << (63 - 45)) /* Unimplemented Operation                */
+-#define ESR_BO    (1 << (63 - 46)) /* Byte Ordering                          */
+-#define ESR_PIE   (1 << (63 - 47)) /* Imprecise exception                    */
+-#define ESR_DATA  (1 << (63 - 53)) /* Data Access (Embedded page table)      */
+-#define ESR_TLBI  (1 << (63 - 54)) /* TLB Ineligible (Embedded page table)   */
+-#define ESR_PT    (1 << (63 - 55)) /* Page Table (Embedded page table)       */
+-#define ESR_SPV   (1 << (63 - 56)) /* SPE/VMX operation                      */
+-#define ESR_EPID  (1 << (63 - 57)) /* External Process ID operation          */
+-#define ESR_VLEMI (1 << (63 - 58)) /* VLE operation                          */
+-#define ESR_MIF   (1 << (63 - 62)) /* Misaligned instruction (VLE)           */
++#define ESR_PIL   PPC_BIT(36) /* Illegal Instruction                    */
++#define ESR_PPR   PPC_BIT(37) /* Privileged Instruction                 */
++#define ESR_PTR   PPC_BIT(38) /* Trap                                   */
++#define ESR_FP    PPC_BIT(39) /* Floating-Point Operation               */
++#define ESR_ST    PPC_BIT(40) /* Store Operation                        */
++#define ESR_AP    PPC_BIT(44) /* Auxiliary Processor Operation          */
++#define ESR_PUO   PPC_BIT(45) /* Unimplemented Operation                */
++#define ESR_BO    PPC_BIT(46) /* Byte Ordering                          */
++#define ESR_PIE   PPC_BIT(47) /* Imprecise exception                    */
++#define ESR_DATA  PPC_BIT(53) /* Data Access (Embedded page table)      */
++#define ESR_TLBI  PPC_BIT(54) /* TLB Ineligible (Embedded page table)   */
++#define ESR_PT    PPC_BIT(55) /* Page Table (Embedded page table)       */
++#define ESR_SPV   PPC_BIT(56) /* SPE/VMX operation                      */
++#define ESR_EPID  PPC_BIT(57) /* External Process ID operation          */
++#define ESR_VLEMI PPC_BIT(58) /* VLE operation                          */
++#define ESR_MIF   PPC_BIT(62) /* Misaligned instruction (VLE)           */
+ 
+ /* Transaction EXception And Summary Register bits                           */
+ #define TEXASR_FAILURE_PERSISTENT                (63 - 7)
+@@ -1990,7 +1997,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
+ #define HID0_DEEPNAP        (1 << 24)           /* pre-2.06 */
+ #define HID0_DOZE           (1 << 23)           /* pre-2.06 */
+ #define HID0_NAP            (1 << 22)           /* pre-2.06 */
+-#define HID0_HILE           (1ull << (63 - 19)) /* POWER8 */
++#define HID0_HILE           PPC_BIT(19) /* POWER8 */
+ 
+ /*****************************************************************************/
+ /* PowerPC Instructions types definitions                                    */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-kvm-Add-cap_ppc_safe_-cache-bounds_check-.patch b/SOURCES/kvm-target-ppc-kvm-Add-cap_ppc_safe_-cache-bounds_check-.patch
new file mode 100644
index 0000000..1103492
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-kvm-Add-cap_ppc_safe_-cache-bounds_check-.patch
@@ -0,0 +1,203 @@
+From e8388e92e3bb6dbdd69ada6d7939e06e15875eeb Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:23 +0100
+Subject: [PATCH 06/15] target/ppc/kvm: Add
+ cap_ppc_safe_[cache/bounds_check/indirect_branch]
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-3-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78984
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 2/9] target/ppc/kvm: Add cap_ppc_safe_[cache/bounds_check/indirect_branch]
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+Add three new kvm capabilities used to represent the level of host support
+for three corresponding workarounds.
+
+Host support for each of the capabilities is queried through the
+new ioctl KVM_PPC_GET_CPU_CHAR which returns four uint64 quantities. The
+first two, character and behaviour, represent the available
+characteristics of the cpu and the behaviour of the cpu respectively.
+The second two, c_mask and b_mask, represent the mask of known bits for
+the character and beheviour dwords respectively.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+[dwg: Correct some compile errors due to name change in final kernel
+ patch version]
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+
+(cherry picked from commit 8acc2ae5e91681ceda3ff4cf946ebf163f6012e9)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	target/ppc/kvm.c
+
+Minor massage required due to lack of commit downstream:
+2e9c10eb (ppc: spapr: use generic cpu_model parsing)
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+---
+ include/hw/ppc/spapr.h | 12 +++++++++++
+ target/ppc/kvm.c       | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ target/ppc/kvm_ppc.h   | 18 ++++++++++++++++
+ 3 files changed, 88 insertions(+)
+
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 7156a70..6090f3d 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -297,6 +297,18 @@ struct sPAPRMachineState {
+ #define H_DABRX_KERNEL     (1ULL<<(63-62))
+ #define H_DABRX_USER       (1ULL<<(63-63))
+ 
++/* Values for KVM_PPC_GET_CPU_CHAR & H_GET_CPU_CHARACTERISTICS */
++#define H_CPU_CHAR_SPEC_BAR_ORI31               PPC_BIT(0)
++#define H_CPU_CHAR_BCCTRL_SERIALISED            PPC_BIT(1)
++#define H_CPU_CHAR_L1D_FLUSH_ORI30              PPC_BIT(2)
++#define H_CPU_CHAR_L1D_FLUSH_TRIG2              PPC_BIT(3)
++#define H_CPU_CHAR_L1D_THREAD_PRIV              PPC_BIT(4)
++#define H_CPU_CHAR_HON_BRANCH_HINTS             PPC_BIT(5)
++#define H_CPU_CHAR_THR_RECONF_TRIG              PPC_BIT(6)
++#define H_CPU_BEHAV_FAVOUR_SECURITY             PPC_BIT(0)
++#define H_CPU_BEHAV_L1D_FLUSH_PR                PPC_BIT(1)
++#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR           PPC_BIT(2)
++
+ /* Each control block has to be on a 4K boundary */
+ #define H_CB_ALIGNMENT     4096
+ 
+diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
+index ce7e2ec..7a7bc3b 100644
+--- a/target/ppc/kvm.c
++++ b/target/ppc/kvm.c
+@@ -92,6 +92,9 @@ static int cap_mmu_radix;
+ static int cap_mmu_hash_v3;
+ static int cap_resize_hpt;
+ static int cap_ppc_pvr_compat;
++static int cap_ppc_safe_cache;
++static int cap_ppc_safe_bounds_check;
++static int cap_ppc_safe_indirect_branch;
+ 
+ static uint32_t debug_inst_opcode;
+ 
+@@ -124,6 +127,7 @@ static bool kvmppc_is_pr(KVMState *ks)
+ }
+ 
+ static int kvm_ppc_register_host_cpu_type(void);
++static void kvmppc_get_cpu_characteristics(KVMState *s);
+ 
+ int kvm_arch_init(MachineState *ms, KVMState *s)
+ {
+@@ -150,6 +154,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
+     cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
+     cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
++    kvmppc_get_cpu_characteristics(s);
+     /*
+      * Note: setting it to false because there is not such capability
+      * in KVM at this moment.
+@@ -2473,6 +2478,59 @@ bool kvmppc_has_cap_mmu_hash_v3(void)
+     return cap_mmu_hash_v3;
+ }
+ 
++static void kvmppc_get_cpu_characteristics(KVMState *s)
++{
++    struct kvm_ppc_cpu_char c;
++    int ret;
++
++    /* Assume broken */
++    cap_ppc_safe_cache = 0;
++    cap_ppc_safe_bounds_check = 0;
++    cap_ppc_safe_indirect_branch = 0;
++
++    ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR);
++    if (!ret) {
++        return;
++    }
++    ret = kvm_vm_ioctl(s, KVM_PPC_GET_CPU_CHAR, &c);
++    if (ret < 0) {
++        return;
++    }
++    /* Parse and set cap_ppc_safe_cache */
++    if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
++        cap_ppc_safe_cache = 2;
++    } else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
++               (c.character & c.character_mask
++                & (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
++        cap_ppc_safe_cache = 1;
++    }
++    /* Parse and set cap_ppc_safe_bounds_check */
++    if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
++        cap_ppc_safe_bounds_check = 2;
++    } else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
++        cap_ppc_safe_bounds_check = 1;
++    }
++    /* Parse and set cap_ppc_safe_indirect_branch */
++    if (c.character & H_CPU_CHAR_BCCTRL_SERIALISED) {
++        cap_ppc_safe_indirect_branch = 2;
++    }
++}
++
++int kvmppc_get_cap_safe_cache(void)
++{
++    return cap_ppc_safe_cache;
++}
++
++int kvmppc_get_cap_safe_bounds_check(void)
++{
++    return cap_ppc_safe_bounds_check;
++}
++
++int kvmppc_get_cap_safe_indirect_branch(void)
++{
++    return cap_ppc_safe_indirect_branch;
++}
++
+ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
+ {
+     uint32_t host_pvr = mfpvr();
+diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
+index e6711fc..9da92a9 100644
+--- a/target/ppc/kvm_ppc.h
++++ b/target/ppc/kvm_ppc.h
+@@ -62,6 +62,9 @@ bool kvmppc_has_cap_fixup_hcalls(void);
+ bool kvmppc_has_cap_htm(void);
+ bool kvmppc_has_cap_mmu_radix(void);
+ bool kvmppc_has_cap_mmu_hash_v3(void);
++int kvmppc_get_cap_safe_cache(void);
++int kvmppc_get_cap_safe_bounds_check(void);
++int kvmppc_get_cap_safe_indirect_branch(void);
+ int kvmppc_enable_hwrng(void);
+ int kvmppc_put_books_sregs(PowerPCCPU *cpu);
+ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
+@@ -299,6 +302,21 @@ static inline bool kvmppc_has_cap_mmu_hash_v3(void)
+     return false;
+ }
+ 
++static inline int kvmppc_get_cap_safe_cache(void)
++{
++    return 0;
++}
++
++static inline int kvmppc_get_cap_safe_bounds_check(void)
++{
++    return 0;
++}
++
++static inline int kvmppc_get_cap_safe_indirect_branch(void)
++{
++    return 0;
++}
++
+ static inline int kvmppc_enable_hwrng(void)
+ {
+     return -1;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-spapr-Add-H-Call-H_GET_CPU_CHARACTERISTIC.patch b/SOURCES/kvm-target-ppc-spapr-Add-H-Call-H_GET_CPU_CHARACTERISTIC.patch
new file mode 100644
index 0000000..3323c48
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-spapr-Add-H-Call-H_GET_CPU_CHARACTERISTIC.patch
@@ -0,0 +1,128 @@
+From d47dcee27b473fd94b4afdb21433d735ff9e51cd Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:29 +0100
+Subject: [PATCH 12/15] target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-9-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78986
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 8/9] target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+The new H-Call H_GET_CPU_CHARACTERISTICS is used by the guest to query
+behaviours and available characteristics of the cpu.
+
+Implement the handler for this new H-Call which formulates its response
+based on the setting of the spapr_caps cap-cfpc, cap-sbbc and cap-ibs.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit c59704b254734182c3202e0c261589ea2ccf485e)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_hcall.c   | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/hw/ppc/spapr.h |  1 +
+ 2 files changed, 59 insertions(+)
+
+diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
+index 217358d..21247cd 100644
+--- a/hw/ppc/spapr_hcall.c
++++ b/hw/ppc/spapr_hcall.c
+@@ -1629,6 +1629,60 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
+     return H_SUCCESS;
+ }
+ 
++static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
++                                              sPAPRMachineState *spapr,
++                                              target_ulong opcode,
++                                              target_ulong *args)
++{
++    uint64_t characteristics = H_CPU_CHAR_HON_BRANCH_HINTS &
++                               ~H_CPU_CHAR_THR_RECONF_TRIG;
++    uint64_t behaviour = H_CPU_BEHAV_FAVOUR_SECURITY;
++    uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
++    uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
++    uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
++
++    switch (safe_cache) {
++    case SPAPR_CAP_WORKAROUND:
++        characteristics |= H_CPU_CHAR_L1D_FLUSH_ORI30;
++        characteristics |= H_CPU_CHAR_L1D_FLUSH_TRIG2;
++        characteristics |= H_CPU_CHAR_L1D_THREAD_PRIV;
++        behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
++        break;
++    case SPAPR_CAP_FIXED:
++        break;
++    default: /* broken */
++        assert(safe_cache == SPAPR_CAP_BROKEN);
++        behaviour |= H_CPU_BEHAV_L1D_FLUSH_PR;
++        break;
++    }
++
++    switch (safe_bounds_check) {
++    case SPAPR_CAP_WORKAROUND:
++        characteristics |= H_CPU_CHAR_SPEC_BAR_ORI31;
++        behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
++        break;
++    case SPAPR_CAP_FIXED:
++        break;
++    default: /* broken */
++        assert(safe_bounds_check == SPAPR_CAP_BROKEN);
++        behaviour |= H_CPU_BEHAV_BNDS_CHK_SPEC_BAR;
++        break;
++    }
++
++    switch (safe_indirect_branch) {
++    case SPAPR_CAP_FIXED:
++        characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
++    default: /* broken */
++        assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
++        break;
++    }
++
++    args[0] = characteristics;
++    args[1] = behaviour;
++
++    return H_SUCCESS;
++}
++
+ static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
+ static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
+ 
+@@ -1708,6 +1762,10 @@ static void hypercall_register_types(void)
+     spapr_register_hypercall(H_INVALIDATE_PID, h_invalidate_pid);
+     spapr_register_hypercall(H_REGISTER_PROC_TBL, h_register_process_table);
+ 
++    /* hcall-get-cpu-characteristics */
++    spapr_register_hypercall(H_GET_CPU_CHARACTERISTICS,
++                             h_get_cpu_characteristics);
++
+     /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate
+      * here between the "CI" and the "CACHE" variants, they will use whatever
+      * mapping attributes qemu is using. When using KVM, the kernel will
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index f7f01f3..375b2ba 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -406,6 +406,7 @@ struct sPAPRMachineState {
+ #define H_GET_HCA_INFO          0x1B8
+ #define H_GET_PERF_COUNT        0x1BC
+ #define H_MANAGE_TRACE          0x1C0
++#define H_GET_CPU_CHARACTERISTICS 0x1C8
+ #define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
+ #define H_QUERY_INT_STATE       0x1E4
+ #define H_POLL_PENDING          0x1D8
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-spapr_caps-Add-macro-to-generate-spapr_ca.patch b/SOURCES/kvm-target-ppc-spapr_caps-Add-macro-to-generate-spapr_ca.patch
new file mode 100644
index 0000000..6a24397
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-spapr_caps-Add-macro-to-generate-spapr_ca.patch
@@ -0,0 +1,133 @@
+From 1f48270b951f370528fc7f9e6e76b25ed422ac77 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:22 +0100
+Subject: [PATCH 05/15] target/ppc/spapr_caps: Add macro to generate spapr_caps
+ migration vmstate
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-2-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78983
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 1/9] target/ppc/spapr_caps: Add macro to generate spapr_caps migration vmstate
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+The vmstate description and the contained needed function for migration
+of spapr_caps is the same for each cap, with the name of the cap
+substituted. As such introduce a macro to allow for easier generation of
+these.
+
+Convert the three existing spapr_caps (htm, vsx, and dfp) to use this
+macro.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 1f63ebaa91f73f469c8f107dbd266cabdbea3a40)
+
+Conflicts: None
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_caps.c | 78 +++++++++++++++++------------------------------------
+ 1 file changed, 24 insertions(+), 54 deletions(-)
+
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index d5c9ce7..5d52969 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -228,62 +228,32 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr)
+     return ok ? 0 : -EINVAL;
+ }
+ 
+-static bool spapr_cap_htm_needed(void *opaque)
+-{
+-    sPAPRMachineState *spapr = opaque;
+-
+-    return spapr->cmd_line_caps[SPAPR_CAP_HTM] &&
+-           (spapr->eff.caps[SPAPR_CAP_HTM] != spapr->def.caps[SPAPR_CAP_HTM]);
+-}
+-
+-const VMStateDescription vmstate_spapr_cap_htm = {
+-    .name = "spapr/cap/htm",
+-    .version_id = 1,
+-    .minimum_version_id = 1,
+-    .needed = spapr_cap_htm_needed,
+-    .fields = (VMStateField[]) {
+-        VMSTATE_UINT8(mig.caps[SPAPR_CAP_HTM], sPAPRMachineState),
+-        VMSTATE_END_OF_LIST()
+-    },
+-};
+-
+-static bool spapr_cap_vsx_needed(void *opaque)
+-{
+-    sPAPRMachineState *spapr = opaque;
+-
+-    return spapr->cmd_line_caps[SPAPR_CAP_VSX] &&
+-           (spapr->eff.caps[SPAPR_CAP_VSX] != spapr->def.caps[SPAPR_CAP_VSX]);
++/* Used to generate the migration field and needed function for a spapr cap */
++#define SPAPR_CAP_MIG_STATE(cap, ccap)                  \
++static bool spapr_cap_##cap##_needed(void *opaque)      \
++{                                                       \
++    sPAPRMachineState *spapr = opaque;                  \
++                                                        \
++    return spapr->cmd_line_caps[SPAPR_CAP_##ccap] &&    \
++           (spapr->eff.caps[SPAPR_CAP_##ccap] !=        \
++            spapr->def.caps[SPAPR_CAP_##ccap]);         \
++}                                                       \
++                                                        \
++const VMStateDescription vmstate_spapr_cap_##cap = {    \
++    .name = "spapr/cap/" #cap,                          \
++    .version_id = 1,                                    \
++    .minimum_version_id = 1,                            \
++    .needed = spapr_cap_##cap##_needed,                 \
++    .fields = (VMStateField[]) {                        \
++        VMSTATE_UINT8(mig.caps[SPAPR_CAP_##ccap],       \
++                      sPAPRMachineState),               \
++        VMSTATE_END_OF_LIST()                           \
++    },                                                  \
+ }
+ 
+-const VMStateDescription vmstate_spapr_cap_vsx = {
+-    .name = "spapr/cap/vsx",
+-    .version_id = 1,
+-    .minimum_version_id = 1,
+-    .needed = spapr_cap_vsx_needed,
+-    .fields = (VMStateField[]) {
+-        VMSTATE_UINT8(mig.caps[SPAPR_CAP_VSX], sPAPRMachineState),
+-        VMSTATE_END_OF_LIST()
+-    },
+-};
+-
+-static bool spapr_cap_dfp_needed(void *opaque)
+-{
+-    sPAPRMachineState *spapr = opaque;
+-
+-    return spapr->cmd_line_caps[SPAPR_CAP_DFP] &&
+-           (spapr->eff.caps[SPAPR_CAP_DFP] != spapr->def.caps[SPAPR_CAP_DFP]);
+-}
+-
+-const VMStateDescription vmstate_spapr_cap_dfp = {
+-    .name = "spapr/cap/dfp",
+-    .version_id = 1,
+-    .minimum_version_id = 1,
+-    .needed = spapr_cap_dfp_needed,
+-    .fields = (VMStateField[]) {
+-        VMSTATE_UINT8(mig.caps[SPAPR_CAP_DFP], sPAPRMachineState),
+-        VMSTATE_END_OF_LIST()
+-    },
+-};
++SPAPR_CAP_MIG_STATE(htm, HTM);
++SPAPR_CAP_MIG_STATE(vsx, VSX);
++SPAPR_CAP_MIG_STATE(dfp, DFP);
+ 
+ void spapr_caps_reset(sPAPRMachineState *spapr)
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_boun.patch b/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_boun.patch
new file mode 100644
index 0000000..e881dbe
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_boun.patch
@@ -0,0 +1,130 @@
+From 410393e052e3e3e26e3d7fc5b9f806c182f10508 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:26 +0100
+Subject: [PATCH 09/15] target/ppc/spapr_caps: Add new tristate cap
+ safe_bounds_check
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-6-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78982
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 5/9] target/ppc/spapr_caps: Add new tristate cap safe_bounds_check
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+Add new tristate cap cap-sbbc to represent the speculation barrier
+bounds checking capability.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 09114fd8179977e4157b36aab2e3d68eaf08adca)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c         |  2 ++
+ hw/ppc/spapr_caps.c    | 21 +++++++++++++++++++++
+ include/hw/ppc/spapr.h |  5 ++++-
+ 3 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 31a5460..2dae180 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1743,6 +1743,7 @@ static const VMStateDescription vmstate_spapr = {
+         &vmstate_spapr_cap_vsx,
+         &vmstate_spapr_cap_dfp,
+         &vmstate_spapr_cap_cfpc,
++        &vmstate_spapr_cap_sbbc,
+         NULL
+     }
+ };
+@@ -3699,6 +3700,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
+     smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
+     smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
++    smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
+     spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index d53da63..ce1f74f 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -191,6 +191,17 @@ static void cap_safe_cache_apply(sPAPRMachineState *spapr, uint8_t val,
+     }
+ }
+ 
++static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
++                                        Error **errp)
++{
++    if (tcg_enabled() && val) {
++        /* TODO - for now only allow broken for TCG */
++        error_setg(errp, "Requested safe bounds check capability level not supported by tcg, try a different value for cap-sbbc");
++    } else if (kvm_enabled() && (val > kvmppc_get_cap_safe_bounds_check())) {
++        error_setg(errp, "Requested safe bounds check capability level not supported by kvm, try a different value for cap-sbbc");
++    }
++}
++
+ #define VALUE_DESC_TRISTATE     " (broken, workaround, fixed)"
+ 
+ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+@@ -230,6 +241,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+         .type = "string",
+         .apply = cap_safe_cache_apply,
+     },
++    [SPAPR_CAP_SBBC] = {
++        .name = "sbbc",
++        .description = "Speculation Barrier Bounds Checking" VALUE_DESC_TRISTATE,
++        .index = SPAPR_CAP_SBBC,
++        .get = spapr_cap_get_tristate,
++        .set = spapr_cap_set_tristate,
++        .type = "string",
++        .apply = cap_safe_bounds_check_apply,
++    },
+ };
+ 
+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+@@ -336,6 +356,7 @@ SPAPR_CAP_MIG_STATE(htm, HTM);
+ SPAPR_CAP_MIG_STATE(vsx, VSX);
+ SPAPR_CAP_MIG_STATE(dfp, DFP);
+ SPAPR_CAP_MIG_STATE(cfpc, CFPC);
++SPAPR_CAP_MIG_STATE(sbbc, SBBC);
+ 
+ void spapr_caps_reset(sPAPRMachineState *spapr)
+ {
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 442b35b..38a8e72 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -62,8 +62,10 @@ typedef enum {
+ #define SPAPR_CAP_DFP                   0x02
+ /* Cache Flush on Privilege Change */
+ #define SPAPR_CAP_CFPC                  0x03
++/* Speculation Barrier Bounds Checking */
++#define SPAPR_CAP_SBBC                  0x04
+ /* Num Caps */
+-#define SPAPR_CAP_NUM                   (SPAPR_CAP_CFPC + 1)
++#define SPAPR_CAP_NUM                   (SPAPR_CAP_SBBC + 1)
+ 
+ /*
+  * Capability Values
+@@ -765,6 +767,7 @@ extern const VMStateDescription vmstate_spapr_cap_htm;
+ extern const VMStateDescription vmstate_spapr_cap_vsx;
+ extern const VMStateDescription vmstate_spapr_cap_dfp;
+ extern const VMStateDescription vmstate_spapr_cap_cfpc;
++extern const VMStateDescription vmstate_spapr_cap_sbbc;
+ 
+ static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_cach.patch b/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_cach.patch
new file mode 100644
index 0000000..e8deabf
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_cach.patch
@@ -0,0 +1,158 @@
+From bbf51e75c92f870d0637cbb3025fc3f4da9d40f2 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:25 +0100
+Subject: [PATCH 08/15] target/ppc/spapr_caps: Add new tristate cap safe_cache
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-5-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78987
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 4/9] target/ppc/spapr_caps: Add new tristate cap safe_cache
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+Add new tristate cap cap-cfpc to represent the cache flush on privilege
+change capability.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 8f38eaf8f9dd194c9961cf76c675724930ce4570)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c         |  2 ++
+ hw/ppc/spapr_caps.c    | 36 ++++++++++++++++++++++++++----------
+ include/hw/ppc/spapr.h |  5 ++++-
+ 3 files changed, 32 insertions(+), 11 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 2b991d8..31a5460 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1742,6 +1742,7 @@ static const VMStateDescription vmstate_spapr = {
+         &vmstate_spapr_cap_htm,
+         &vmstate_spapr_cap_vsx,
+         &vmstate_spapr_cap_dfp,
++        &vmstate_spapr_cap_cfpc,
+         NULL
+     }
+ };
+@@ -3697,6 +3698,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
+     smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
+     smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
++    smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
+     spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index d6f82b1..d53da63 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -73,11 +73,8 @@ static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
+     spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF;
+ }
+ 
+-static void __attribute__ ((unused)) spapr_cap_get_tristate(Object *obj,
+-                                                            Visitor *v,
+-                                                            const char *name,
+-                                                            void *opaque,
+-                                                            Error **errp)
++static void spapr_cap_get_tristate(Object *obj, Visitor *v, const char *name,
++                                   void *opaque, Error **errp)
+ {
+     sPAPRCapabilityInfo *cap = opaque;
+     sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+@@ -103,11 +100,8 @@ static void __attribute__ ((unused)) spapr_cap_get_tristate(Object *obj,
+     g_free(val);
+ }
+ 
+-static void __attribute__ ((unused)) spapr_cap_set_tristate(Object *obj,
+-                                                            Visitor *v,
+-                                                            const char *name,
+-                                                            void *opaque,
+-                                                            Error **errp)
++static void spapr_cap_set_tristate(Object *obj, Visitor *v, const char *name,
++                                   void *opaque, Error **errp)
+ {
+     sPAPRCapabilityInfo *cap = opaque;
+     sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+@@ -186,6 +180,18 @@ static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+     }
+ }
+ 
++static void cap_safe_cache_apply(sPAPRMachineState *spapr, uint8_t val,
++                                 Error **errp)
++{
++    if (tcg_enabled() && val) {
++        /* TODO - for now only allow broken for TCG */
++        error_setg(errp, "Requested safe cache capability level not supported by tcg, try a different value for cap-cfpc");
++    } else if (kvm_enabled() && (val > kvmppc_get_cap_safe_cache())) {
++        error_setg(errp, "Requested safe cache capability level not supported by kvm, try a different value for cap-cfpc");
++    }
++}
++
++#define VALUE_DESC_TRISTATE     " (broken, workaround, fixed)"
+ 
+ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+     [SPAPR_CAP_HTM] = {
+@@ -215,6 +221,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+         .type = "bool",
+         .apply = cap_dfp_apply,
+     },
++    [SPAPR_CAP_CFPC] = {
++        .name = "cfpc",
++        .description = "Cache Flush on Privilege Change" VALUE_DESC_TRISTATE,
++        .index = SPAPR_CAP_CFPC,
++        .get = spapr_cap_get_tristate,
++        .set = spapr_cap_set_tristate,
++        .type = "string",
++        .apply = cap_safe_cache_apply,
++    },
+ };
+ 
+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+@@ -320,6 +335,7 @@ const VMStateDescription vmstate_spapr_cap_##cap = {    \
+ SPAPR_CAP_MIG_STATE(htm, HTM);
+ SPAPR_CAP_MIG_STATE(vsx, VSX);
+ SPAPR_CAP_MIG_STATE(dfp, DFP);
++SPAPR_CAP_MIG_STATE(cfpc, CFPC);
+ 
+ void spapr_caps_reset(sPAPRMachineState *spapr)
+ {
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index abe0011..442b35b 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -60,8 +60,10 @@ typedef enum {
+ #define SPAPR_CAP_VSX                   0x01
+ /* Decimal Floating Point */
+ #define SPAPR_CAP_DFP                   0x02
++/* Cache Flush on Privilege Change */
++#define SPAPR_CAP_CFPC                  0x03
+ /* Num Caps */
+-#define SPAPR_CAP_NUM                   (SPAPR_CAP_DFP + 1)
++#define SPAPR_CAP_NUM                   (SPAPR_CAP_CFPC + 1)
+ 
+ /*
+  * Capability Values
+@@ -762,6 +764,7 @@ int spapr_caps_pre_save(void *opaque);
+ extern const VMStateDescription vmstate_spapr_cap_htm;
+ extern const VMStateDescription vmstate_spapr_cap_vsx;
+ extern const VMStateDescription vmstate_spapr_cap_dfp;
++extern const VMStateDescription vmstate_spapr_cap_cfpc;
+ 
+ static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_indi.patch b/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_indi.patch
new file mode 100644
index 0000000..298e1d5
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_indi.patch
@@ -0,0 +1,130 @@
+From 29fa2de37ac3bbd6087d7350d1923fb8143bd365 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:27 +0100
+Subject: [PATCH 10/15] target/ppc/spapr_caps: Add new tristate cap
+ safe_indirect_branch
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-7-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78990
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 6/9] target/ppc/spapr_caps: Add new tristate cap safe_indirect_branch
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+Add new tristate cap cap-ibs to represent the indirect branch
+serialisation capability.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 4be8d4e7d935fc8919d61f53a0f0fb7230052bb3)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr.c         |  2 ++
+ hw/ppc/spapr_caps.c    | 21 +++++++++++++++++++++
+ include/hw/ppc/spapr.h |  5 ++++-
+ 3 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 2dae180..c71ffac 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -1744,6 +1744,7 @@ static const VMStateDescription vmstate_spapr = {
+         &vmstate_spapr_cap_dfp,
+         &vmstate_spapr_cap_cfpc,
+         &vmstate_spapr_cap_sbbc,
++        &vmstate_spapr_cap_ibs,
+         NULL
+     }
+ };
+@@ -3701,6 +3702,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
+     smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
+     smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
+     smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
++    smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
+     spapr_caps_add_properties(smc, &error_abort);
+ }
+ 
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index ce1f74f..62efdae 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -202,6 +202,17 @@ static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
+     }
+ }
+ 
++static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
++                                           uint8_t val, Error **errp)
++{
++    if (tcg_enabled() && val) {
++        /* TODO - for now only allow broken for TCG */
++        error_setg(errp, "Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
++    } else if (kvm_enabled() && (val > kvmppc_get_cap_safe_indirect_branch())) {
++        error_setg(errp, "Requested safe indirect branch capability level not supported by kvm, try a different value for cap-ibs");
++    }
++}
++
+ #define VALUE_DESC_TRISTATE     " (broken, workaround, fixed)"
+ 
+ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+@@ -250,6 +261,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+         .type = "string",
+         .apply = cap_safe_bounds_check_apply,
+     },
++    [SPAPR_CAP_IBS] = {
++        .name = "ibs",
++        .description = "Indirect Branch Serialisation" VALUE_DESC_TRISTATE,
++        .index = SPAPR_CAP_IBS,
++        .get = spapr_cap_get_tristate,
++        .set = spapr_cap_set_tristate,
++        .type = "string",
++        .apply = cap_safe_indirect_branch_apply,
++    },
+ };
+ 
+ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+@@ -357,6 +377,7 @@ SPAPR_CAP_MIG_STATE(vsx, VSX);
+ SPAPR_CAP_MIG_STATE(dfp, DFP);
+ SPAPR_CAP_MIG_STATE(cfpc, CFPC);
+ SPAPR_CAP_MIG_STATE(sbbc, SBBC);
++SPAPR_CAP_MIG_STATE(ibs, IBS);
+ 
+ void spapr_caps_reset(sPAPRMachineState *spapr)
+ {
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 38a8e72..f7f01f3 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -64,8 +64,10 @@ typedef enum {
+ #define SPAPR_CAP_CFPC                  0x03
+ /* Speculation Barrier Bounds Checking */
+ #define SPAPR_CAP_SBBC                  0x04
++/* Indirect Branch Serialisation */
++#define SPAPR_CAP_IBS                   0x05
+ /* Num Caps */
+-#define SPAPR_CAP_NUM                   (SPAPR_CAP_SBBC + 1)
++#define SPAPR_CAP_NUM                   (SPAPR_CAP_IBS + 1)
+ 
+ /*
+  * Capability Values
+@@ -768,6 +770,7 @@ extern const VMStateDescription vmstate_spapr_cap_vsx;
+ extern const VMStateDescription vmstate_spapr_cap_dfp;
+ extern const VMStateDescription vmstate_spapr_cap_cfpc;
+ extern const VMStateDescription vmstate_spapr_cap_sbbc;
++extern const VMStateDescription vmstate_spapr_cap_ibs;
+ 
+ static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
+ {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-ppc-spapr_caps-Add-support-for-tristate-spapr.patch b/SOURCES/kvm-target-ppc-spapr_caps-Add-support-for-tristate-spapr.patch
new file mode 100644
index 0000000..c3259d0
--- /dev/null
+++ b/SOURCES/kvm-target-ppc-spapr_caps-Add-support-for-tristate-spapr.patch
@@ -0,0 +1,135 @@
+From ea039b07c94712a8ffb92b0a6e515f7c354d2219 Mon Sep 17 00:00:00 2001
+From: Suraj Jitindar Singh <sursingh@redhat.com>
+Date: Tue, 13 Feb 2018 04:12:24 +0100
+Subject: [PATCH 07/15] target/ppc/spapr_caps: Add support for tristate
+ spapr_capabilities
+
+RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
+Message-id: <1518495150-24134-4-git-send-email-sursingh@redhat.com>
+Patchwork-id: 78991
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 3/9] target/ppc/spapr_caps: Add support for tristate spapr_capabilities
+Bugzilla: 1532050
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+
+spapr_caps are used to represent the level of support for various
+capabilities related to the spapr machine type. Currently there is
+only support for boolean capabilities.
+
+Add support for tristate capabilities by implementing their get/set
+functions. These capabilities can have the values 0, 1 or 2
+corresponding to broken, workaround and fixed.
+
+Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 6898aed77f4636c3e77af9c12631f583f22cb5db)
+
+Conflicts: none
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
+
+Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/ppc/spapr_caps.c    | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/hw/ppc/spapr.h |  4 +++
+ 2 files changed, 70 insertions(+)
+
+diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
+index 5d52969..d6f82b1 100644
+--- a/hw/ppc/spapr_caps.c
++++ b/hw/ppc/spapr_caps.c
+@@ -73,6 +73,72 @@ static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
+     spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF;
+ }
+ 
++static void __attribute__ ((unused)) spapr_cap_get_tristate(Object *obj,
++                                                            Visitor *v,
++                                                            const char *name,
++                                                            void *opaque,
++                                                            Error **errp)
++{
++    sPAPRCapabilityInfo *cap = opaque;
++    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
++    char *val = NULL;
++    uint8_t value = spapr_get_cap(spapr, cap->index);
++
++    switch (value) {
++    case SPAPR_CAP_BROKEN:
++        val = g_strdup("broken");
++        break;
++    case SPAPR_CAP_WORKAROUND:
++        val = g_strdup("workaround");
++        break;
++    case SPAPR_CAP_FIXED:
++        val = g_strdup("fixed");
++        break;
++    default:
++        error_setg(errp, "Invalid value (%d) for cap-%s", value, cap->name);
++        return;
++    }
++
++    visit_type_str(v, name, &val, errp);
++    g_free(val);
++}
++
++static void __attribute__ ((unused)) spapr_cap_set_tristate(Object *obj,
++                                                            Visitor *v,
++                                                            const char *name,
++                                                            void *opaque,
++                                                            Error **errp)
++{
++    sPAPRCapabilityInfo *cap = opaque;
++    sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
++    char *val;
++    Error *local_err = NULL;
++    uint8_t value;
++
++    visit_type_str(v, name, &val, &local_err);
++    if (local_err) {
++        error_propagate(errp, local_err);
++        return;
++    }
++
++    if (!strcasecmp(val, "broken")) {
++        value = SPAPR_CAP_BROKEN;
++    } else if (!strcasecmp(val, "workaround")) {
++        value = SPAPR_CAP_WORKAROUND;
++    } else if (!strcasecmp(val, "fixed")) {
++        value = SPAPR_CAP_FIXED;
++    } else {
++        error_setg(errp, "Invalid capability mode \"%s\" for cap-%s", val,
++                   cap->name);
++        goto out;
++    }
++
++    spapr->cmd_line_caps[cap->index] = true;
++    spapr->eff.caps[cap->index] = value;
++out:
++    g_free(val);
++}
++
+ static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+ {
+     if (!val) {
+diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
+index 6090f3d..abe0011 100644
+--- a/include/hw/ppc/spapr.h
++++ b/include/hw/ppc/spapr.h
+@@ -69,6 +69,10 @@ typedef enum {
+ /* Bool Caps */
+ #define SPAPR_CAP_OFF                   0x00
+ #define SPAPR_CAP_ON                    0x01
++/* Broken | Workaround | Fixed Caps */
++#define SPAPR_CAP_BROKEN                0x00
++#define SPAPR_CAP_WORKAROUND            0x01
++#define SPAPR_CAP_FIXED                 0x02
+ 
+ typedef struct sPAPRCapabilities sPAPRCapabilities;
+ struct sPAPRCapabilities {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-throttle-groups-drain-before-detaching-ThrottleState.patch b/SOURCES/kvm-throttle-groups-drain-before-detaching-ThrottleState.patch
new file mode 100644
index 0000000..966dcd1
--- /dev/null
+++ b/SOURCES/kvm-throttle-groups-drain-before-detaching-ThrottleState.patch
@@ -0,0 +1,82 @@
+From 9e1beaad709ba68a82a54738ad7b50cac69861cc Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:04 +0100
+Subject: [PATCH 05/15] throttle-groups: drain before detaching ThrottleState
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-6-stefanha@redhat.com>
+Patchwork-id: 77740
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 5/9] throttle-groups: drain before detaching ThrottleState
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+I/O requests hang after stop/cont commands at least since QEMU 2.10.0
+with -drive iops=100:
+
+  (guest)$ dd if=/dev/zero of=/dev/vdb oflag=direct count=1000
+  (qemu) stop
+  (qemu) cont
+  ...I/O is stuck...
+
+This happens because blk_set_aio_context() detaches the ThrottleState
+while requests may still be in flight:
+
+  if (tgm->throttle_state) {
+      throttle_group_detach_aio_context(tgm);
+      throttle_group_attach_aio_context(tgm, new_context);
+  }
+
+This patch encloses the detach/attach calls in a drained region so no
+I/O request is left hanging.  Also add assertions so we don't make the
+same mistake again in the future.
+
+Reported-by: Yongxue Hong <yhong@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Message-id: 20171110151934.16883-1-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit dc868fb03b9b829ed9d2ecdae0fcc12f3fe19b4f)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/block-backend.c   | 2 ++
+ block/throttle-groups.c | 6 ++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index bfb3e84..520f2b2 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -1771,8 +1771,10 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
+ 
+     if (bs) {
+         if (tgm->throttle_state) {
++            bdrv_drained_begin(bs);
+             throttle_group_detach_aio_context(tgm);
+             throttle_group_attach_aio_context(tgm, new_context);
++            bdrv_drained_end(bs);
+         }
+         bdrv_set_aio_context(bs, new_context);
+     }
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index 7749cf0..44cc1e6 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -568,6 +568,12 @@ void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
+ void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
+ {
+     ThrottleTimers *tt = &tgm->throttle_timers;
++
++    /* Requests must have been drained */
++    assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
++    assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
++    assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
++
+     throttle_timers_detach_aio_context(tt);
+     tgm->aio_context = NULL;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-throttle-groups-forget-timer-and-schedule-next-TGM-o.patch b/SOURCES/kvm-throttle-groups-forget-timer-and-schedule-next-TGM-o.patch
new file mode 100644
index 0000000..73cbad5
--- /dev/null
+++ b/SOURCES/kvm-throttle-groups-forget-timer-and-schedule-next-TGM-o.patch
@@ -0,0 +1,74 @@
+From ae4ca7d9cfb0033cf39971f1c59e9a20a80c9bee Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 17 Nov 2017 11:19:08 +0100
+Subject: [PATCH 09/15] throttle-groups: forget timer and schedule next TGM on
+ detach
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171117111908.8815-10-stefanha@redhat.com>
+Patchwork-id: 77744
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 9/9] throttle-groups: forget timer and schedule next TGM on detach
+Bugzilla: 1492295
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+tg->any_timer_armed[] must be cleared when detaching pending timers from
+the AioContext.  Failure to do so leads to hung I/O because it looks
+like there are still timers pending when in fact they have been removed.
+
+Other ThrottleGroupMembers might have requests pending too so it's
+necessary to schedule the next TGM so it can set a timer.
+
+This patch fixes hung I/O when QEMU is launched with drives that are in
+the same throttling group:
+
+  (guest)$ dd if=/dev/zero of=/dev/vdb oflag=direct bs=512 &
+  (guest)$ dd if=/dev/zero of=/dev/vdc oflag=direct bs=512 &
+  (qemu) stop
+  (qemu) cont
+  ...I/O is stuck...
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: 20171116112150.27607-1-stefanha@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 341e0b5658681f46680024cdbfc998717d85cc35)
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ block/throttle-groups.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/block/throttle-groups.c b/block/throttle-groups.c
+index 44cc1e6..35c22ac 100644
+--- a/block/throttle-groups.c
++++ b/block/throttle-groups.c
+@@ -567,13 +567,25 @@ void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
+ 
+ void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
+ {
++    ThrottleGroup *tg = container_of(tgm->throttle_state, ThrottleGroup, ts);
+     ThrottleTimers *tt = &tgm->throttle_timers;
++    int i;
+ 
+     /* Requests must have been drained */
+     assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
+     assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
+     assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
+ 
++    /* Kick off next ThrottleGroupMember, if necessary */
++    qemu_mutex_lock(&tg->lock);
++    for (i = 0; i < 2; i++) {
++        if (timer_pending(tt->timers[i])) {
++            tg->any_timer_armed[i] = false;
++            schedule_next_request(tgm, i);
++        }
++    }
++    qemu_mutex_unlock(&tg->lock);
++
+     throttle_timers_detach_aio_context(tt);
+     tgm->aio_context = NULL;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-Total-column.patch b/SOURCES/kvm-tools-kvm_stat-add-Total-column.patch
new file mode 100644
index 0000000..f8015ce
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-Total-column.patch
@@ -0,0 +1,76 @@
+From 4f80c9081b411684efbd2e3caff57e7a261d71e7 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:43 +0200
+Subject: [PATCH 38/69] tools/kvm_stat: add '%Total' column
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-18-david@redhat.com>
+Patchwork-id: 77328
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 17/39] tools/kvm_stat: add '%Total' column
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git e55fe3ccccc1efb8f20c99728c8863424ae9ee4a
+
+commit e55fe3ccccc1efb8f20c99728c8863424ae9ee4a
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:16 2017 +0100
+
+    tools/kvm_stat: add '%Total' column
+
+    Add column '%Total' next to 'Total' for easier comparison of numbers between
+    hosts.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index f8c48f8..8f74ed8 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -973,7 +973,9 @@ class Tui(object):
+         self.screen.addstr(2, 1, 'Event')
+         self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
+                            len('Total'), 'Total')
+-        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
++        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 7 -
++                           len('%Total'), '%Total')
++        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 7 + 8 -
+                            len('Current'), 'Current')
+         self.screen.addstr(4, 1, 'Collecting data...')
+         self.screen.refresh()
+@@ -989,6 +991,9 @@ class Tui(object):
+                 return (-stats[x][1], -stats[x][0])
+             else:
+                 return (0, -stats[x][0])
++        total = 0.
++        for val in stats.values():
++            total += val[0]
+         for key in sorted(stats.keys(), key=sortkey):
+ 
+             if row >= self.screen.getmaxyx()[0]:
+@@ -1001,6 +1006,8 @@ class Tui(object):
+             col += LABEL_WIDTH
+             self.screen.addstr(row, col, '%10d' % (values[0],))
+             col += NUMBER_WIDTH
++            self.screen.addstr(row, col, '%7.1f' % (values[0] * 100 / total,))
++            col += 7
+             if values[1] is not None:
+                 self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
+             row += 1
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-f-help-to-get-the-available-event.patch b/SOURCES/kvm-tools-kvm_stat-add-f-help-to-get-the-available-event.patch
new file mode 100644
index 0000000..8c2464b
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-f-help-to-get-the-available-event.patch
@@ -0,0 +1,77 @@
+From 592b801e5cc13422eedf2bc81bb27c12e2da3d9e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:16:05 +0200
+Subject: [PATCH 60/69] tools/kvm_stat: add '-f help' to get the available
+ event list
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-40-david@redhat.com>
+Patchwork-id: 77345
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 39/39] tools/kvm_stat: add '-f help' to get the available event list
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 67fbcd62f54d4503e3dc63b68af1c6757b74e050
+
+commit 67fbcd62f54d4503e3dc63b68af1c6757b74e050
+Author: Lin Ma <lma@suse.com>
+Date:   Tue Jul 25 19:05:54 2017 +0800
+
+    tools/kvm_stat: add '-f help' to get the available event list
+
+    Signed-off-by: Lin Ma <lma@suse.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 5704044..32283d8 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -474,7 +474,7 @@ class Provider(object):
+     @staticmethod
+     def is_field_wanted(fields_filter, field):
+         """Indicate whether field is valid according to fields_filter."""
+-        if not fields_filter:
++        if not fields_filter or fields_filter == "help":
+             return True
+         return re.match(fields_filter, field) is not None
+ 
+@@ -1496,7 +1496,8 @@ Press any other key to refresh statistics immediately.
+                          action='store',
+                          default=DEFAULT_REGEX,
+                          dest='fields',
+-                         help='fields to display (regex)',
++                         help='''fields to display (regex)
++                                 "-f help" for a list of available events''',
+                          )
+     optparser.add_option('-p', '--pid',
+                          action='store',
+@@ -1559,6 +1560,17 @@ def main():
+ 
+     stats = Stats(options)
+ 
++    if options.fields == "help":
++        event_list = "\n"
++        s = stats.get()
++        for key in s.keys():
++            if key.find('(') != -1:
++                key = key[0:key.find('(')]
++            if event_list.find('\n' + key + '\n') == -1:
++                event_list += key + '\n'
++        sys.stdout.write(event_list)
++        return ""
++
+     if options.log:
+         log(stats)
+     elif not options.once:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-interactive-command-c.patch b/SOURCES/kvm-tools-kvm_stat-add-interactive-command-c.patch
new file mode 100644
index 0000000..4f909e0
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-interactive-command-c.patch
@@ -0,0 +1,121 @@
+From 38362f9d75028cdcd58b6facb605f71f2a22a9be Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:41 +0200
+Subject: [PATCH 36/69] tools/kvm_stat: add interactive command 'c'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-16-david@redhat.com>
+Patchwork-id: 77325
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 15/39] tools/kvm_stat: add interactive command 'c'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 4443084fa0cf85f91d357c8917b90504b784d925
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 4443084fa0cf85f91d357c8917b90504b784d925
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:14 2017 +0100
+
+    tools/kvm_stat: add interactive command 'c'
+
+    Provide a real simple way to erase any active filter.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 16 ++++++++++++----
+ scripts/kvm/kvm_stat.texi |  3 +++
+ 2 files changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index f263312..676a92a 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -861,6 +861,7 @@ DELAY_INITIAL = 0.25
+ DELAY_REGULAR = 3.0
+ MAX_GUEST_NAME_LEN = 48
+ MAX_REGEX_LEN = 44
++DEFAULT_REGEX = r'^[^\(]*$'
+ 
+ 
+ class Tui(object):
+@@ -907,9 +908,9 @@ class Tui(object):
+     def update_drilldown(self):
+         """Sets or removes a filter that only allows fields without braces."""
+         if not self.stats.fields_filter:
+-            self.stats.fields_filter = r'^[^\(]*$'
++            self.stats.fields_filter = DEFAULT_REGEX
+ 
+-        elif self.stats.fields_filter == r'^[^\(]*$':
++        elif self.stats.fields_filter == DEFAULT_REGEX:
+             self.stats.fields_filter = None
+ 
+     def update_pid(self, pid):
+@@ -931,7 +932,8 @@ class Tui(object):
+                                .format(pid, gname), curses.A_BOLD)
+         else:
+             self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
+-        if self.stats.fields_filter and self.stats.fields_filter != '^[^\(]*$':
++        if self.stats.fields_filter and self.stats.fields_filter \
++           != DEFAULT_REGEX:
+             regex = self.stats.fields_filter
+             if len(regex) > MAX_REGEX_LEN:
+                 regex = regex[:MAX_REGEX_LEN] + '...'
+@@ -991,7 +993,7 @@ class Tui(object):
+             regex = self.screen.getstr()
+             curses.noecho()
+             if len(regex) == 0:
+-                self.stats.fields_filter = r'^[^\(]*$'
++                self.stats.fields_filter = DEFAULT_REGEX
+                 self.refresh_header()
+                 return
+             try:
+@@ -1101,6 +1103,11 @@ class Tui(object):
+                     sleeptime = DELAY_INITIAL
+                 if char == 'q':
+                     break
++                if char == 'c':
++                    self.stats.fields_filter = DEFAULT_REGEX
++                    self.refresh_header(0)
++                    self.update_pid(0)
++                    sleeptime = DELAY_INITIAL
+                 if char == 'f':
+                     self.show_filter_selection()
+                     sleeptime = DELAY_INITIAL
+@@ -1177,6 +1184,7 @@ Requirements:
+   the large number of files that are possibly opened.
+ 
+ Interactive Commands:
++   c     clear filter
+    f     filter by regular expression
+    g     filter by guest name
+    p     filter by PID
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index a8c1071..203d61d 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -24,6 +24,9 @@ Use batch and logging modes for scripting purposes.
+ While running in regular (interactive) mode, use any of the following keys:
+ 
+ @table @key
++@item c
++@kindex c
++clear filter
+ @item f
+ @kindex f
+ filter by regular expression
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-interactive-command-r.patch b/SOURCES/kvm-tools-kvm_stat-add-interactive-command-r.patch
new file mode 100644
index 0000000..5351a8a
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-interactive-command-r.patch
@@ -0,0 +1,225 @@
+From 243d90a041dca861bb85bc71df863578a8f839bd Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:42 +0200
+Subject: [PATCH 37/69] tools/kvm_stat: add interactive command 'r'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-17-david@redhat.com>
+Patchwork-id: 77326
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 16/39] tools/kvm_stat: add interactive command 'r'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 9f114a03c6854f49065dd036c17e1b4bb947f842
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 9f114a03c6854f49065dd036c17e1b4bb947f842
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:15 2017 +0100
+
+    tools/kvm_stat: add interactive command 'r'
+
+    Provide an interactive command to reset the tracepoint statistics.
+    Requires some extra work for debugfs, as the counters cannot be reset.
+
+    On the up side, this offers us the opportunity to have debugfs values
+    reset on startup and whenever a filter is modified, becoming consistent
+    with the tracepoint provider. As a bonus, 'kvmstat -dt' will now provide
+    useful output, instead of mixing values in totally different orders of
+    magnitude.
+    Furthermore, we avoid unnecessary resets when any of the filters is
+    "changed" interactively to the previous value.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Acked-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 65 +++++++++++++++++++++++++++++++++++++----------
+ scripts/kvm/kvm_stat.texi |  3 +++
+ 2 files changed, 54 insertions(+), 14 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 676a92a..f8c48f8 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -716,15 +716,23 @@ class TracepointProvider(object):
+                     ret[name] += val
+         return ret
+ 
++    def reset(self):
++        """Reset all field counters"""
++        for group in self.group_leaders:
++            for event in group.events:
++                event.reset()
++
+ 
+ class DebugfsProvider(object):
+     """Provides data from the files that KVM creates in the kvm debugfs
+     folder."""
+     def __init__(self):
+         self._fields = self.get_available_fields()
++        self._baseline = {}
+         self._pid = 0
+         self.do_read = True
+         self.paths = []
++        self.reset()
+ 
+     def get_available_fields(self):
+         """"Returns a list of available fields.
+@@ -741,6 +749,7 @@ class DebugfsProvider(object):
+     @fields.setter
+     def fields(self, fields):
+         self._fields = fields
++        self.reset()
+ 
+     @property
+     def pid(self):
+@@ -758,10 +767,11 @@ class DebugfsProvider(object):
+             self.paths = filter(lambda x: "{}-".format(pid) in x, vms)
+ 
+         else:
+-            self.paths = ['']
++            self.paths = []
+             self.do_read = True
++        self.reset()
+ 
+-    def read(self):
++    def read(self, reset=0):
+         """Returns a dict with format:'file name / field -> current value'."""
+         results = {}
+ 
+@@ -769,10 +779,22 @@ class DebugfsProvider(object):
+         if not self.do_read:
+             return results
+ 
+-        for path in self.paths:
++        paths = self.paths
++        if self._pid == 0:
++            paths = []
++            for entry in os.walk(PATH_DEBUGFS_KVM):
++                for dir in entry[1]:
++                    paths.append(dir)
++        for path in paths:
+             for field in self._fields:
+-                results[field] = results.get(field, 0) \
+-                                 + self.read_field(field, path)
++                value = self.read_field(field, path)
++                key = path + field
++                if reset:
++                    self._baseline[key] = value
++                if self._baseline.get(key, -1) == -1:
++                    self._baseline[key] = value
++                results[field] = (results.get(field, 0) + value -
++                                  self._baseline.get(key, 0))
+ 
+         return results
+ 
+@@ -786,6 +808,11 @@ class DebugfsProvider(object):
+         except IOError:
+             return 0
+ 
++    def reset(self):
++        """Reset field counters"""
++        self._baseline = {}
++        self.read(1)
++
+ 
+ class Stats(object):
+     """Manages the data providers and the data they provide.
+@@ -822,14 +849,20 @@ class Stats(object):
+         for provider in self.providers:
+             provider.pid = self._pid_filter
+ 
++    def reset(self):
++        self.values = {}
++        for provider in self.providers:
++            provider.reset()
++
+     @property
+     def fields_filter(self):
+         return self._fields_filter
+ 
+     @fields_filter.setter
+     def fields_filter(self, fields_filter):
+-        self._fields_filter = fields_filter
+-        self.update_provider_filters()
++        if fields_filter != self._fields_filter:
++            self._fields_filter = fields_filter
++            self.update_provider_filters()
+ 
+     @property
+     def pid_filter(self):
+@@ -837,9 +870,10 @@ class Stats(object):
+ 
+     @pid_filter.setter
+     def pid_filter(self, pid):
+-        self._pid_filter = pid
+-        self.values = {}
+-        self.update_provider_pid()
++        if pid != self._pid_filter:
++            self._pid_filter = pid
++            self.values = {}
++            self.update_provider_pid()
+ 
+     def get(self):
+         """Returns a dict with field -> (value, delta to last value) of all
+@@ -847,11 +881,9 @@ class Stats(object):
+         for provider in self.providers:
+             new = provider.read()
+             for key in provider.fields:
+-                oldval = self.values.get(key, (0, 0))
++                oldval = self.values.get(key, (0, 0))[0]
+                 newval = new.get(key, 0)
+-                newdelta = None
+-                if oldval is not None:
+-                    newdelta = newval - oldval[0]
++                newdelta = newval - oldval
+                 self.values[key] = (newval, newdelta)
+         return self.values
+ 
+@@ -1117,6 +1149,10 @@ class Tui(object):
+                 if char == 'p':
+                     self.show_vm_selection_by_pid()
+                     sleeptime = DELAY_INITIAL
++                if char == 'r':
++                    self.refresh_header()
++                    self.stats.reset()
++                    sleeptime = DELAY_INITIAL
+             except KeyboardInterrupt:
+                 break
+             except curses.error:
+@@ -1190,6 +1226,7 @@ Interactive Commands:
+    p     filter by PID
+    q     quit
+    x     toggle reporting of stats for individual child trace events
++   r     reset stats
+ Press any other key to refresh statistics immediately.
+ """
+ 
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index 203d61d..c0cb7bc 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -39,6 +39,9 @@ filter by PID
+ @item q
+ @kindex q
+ quit
++@item r
++@kindex r
++reset stats
+ @item x
+ @kindex x
+ toggle reporting of stats for child trace events
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-new-command-line-switch-i.patch b/SOURCES/kvm-tools-kvm_stat-add-new-command-line-switch-i.patch
new file mode 100644
index 0000000..fefaafe
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-new-command-line-switch-i.patch
@@ -0,0 +1,149 @@
+From 72f660ddfca081d8a3124e30b0d55f2be06965bc Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:16:02 +0200
+Subject: [PATCH 57/69] tools/kvm_stat: add new command line switch '-i'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-37-david@redhat.com>
+Patchwork-id: 77348
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 36/39] tools/kvm_stat: add new command line switch '-i'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git ab7ef193fab628fc5da6fd4f4672ffd0d1bb53df
+
+Convertion of documentation (for man page generation) to texi.
+
+commit ab7ef193fab628fc5da6fd4f4672ffd0d1bb53df
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Sun Jun 25 21:34:15 2017 +0200
+
+    tools/kvm_stat: add new command line switch '-i'
+
+    It might be handy to display the full history of event stats to compare
+    the current event distribution against any available historic data.
+    Since we have that available for debugfs, we offer a respective command
+    line option to display what's available.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 34 ++++++++++++++++++++++++++++++----
+ scripts/kvm/kvm_stat.texi |  2 ++
+ 2 files changed, 32 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 39476e5..4065b29 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -681,12 +681,14 @@ class TracepointProvider(Provider):
+ class DebugfsProvider(Provider):
+     """Provides data from the files that KVM creates in the kvm debugfs
+     folder."""
+-    def __init__(self, pid, fields_filter):
++    def __init__(self, pid, fields_filter, include_past):
+         self.update_fields(fields_filter)
+         self._baseline = {}
+         self.do_read = True
+         self.paths = []
+         self.pid = pid
++        if include_past:
++            self.restore()
+ 
+     def get_available_fields(self):
+         """"Returns a list of available fields.
+@@ -730,7 +732,14 @@ class DebugfsProvider(Provider):
+         self.reset()
+ 
+     def read(self, reset=0):
+-        """Returns a dict with format:'file name / field -> current value'."""
++        """Returns a dict with format:'file name / field -> current value'.
++
++        Parameter 'reset':
++          0   plain read
++          1   reset field counts to 0
++          2   restore the original field counts
++
++        """
+         results = {}
+ 
+         # If no debugfs filtering support is available, then don't read.
+@@ -747,8 +756,10 @@ class DebugfsProvider(Provider):
+             for field in self._fields:
+                 value = self.read_field(field, path)
+                 key = path + field
+-                if reset:
++                if reset == 1:
+                     self._baseline[key] = value
++                if reset == 2:
++                    self._baseline[key] = 0
+                 if self._baseline.get(key, -1) == -1:
+                     self._baseline[key] = value
+                 results[field] = (results.get(field, 0) + value -
+@@ -771,6 +782,11 @@ class DebugfsProvider(Provider):
+         self._baseline = {}
+         self.read(1)
+ 
++    def restore(self):
++        """Reset field counters"""
++        self._baseline = {}
++        self.read(2)
++
+ 
+ class Stats(object):
+     """Manages the data providers and the data they provide.
+@@ -791,7 +807,8 @@ class Stats(object):
+         providers = []
+ 
+         if options.debugfs:
+-            providers.append(DebugfsProvider(options.pid, options.fields))
++            providers.append(DebugfsProvider(options.pid, options.fields,
++                                             options.dbgfs_include_past))
+         if options.tracepoints or not providers:
+             providers.append(TracepointProvider(options.pid, options.fields))
+ 
+@@ -1270,6 +1287,8 @@ class Tui(object):
+                     sleeptime = self._delay_initial
+                 if char == 'x':
+                     self.update_drilldown()
++                    # prevents display of current values on next refresh
++                    self.stats.get()
+             except KeyboardInterrupt:
+                 break
+             except curses.error:
+@@ -1381,6 +1400,13 @@ Press any other key to refresh statistics immediately.
+                          dest='once',
+                          help='run in batch mode for one second',
+                          )
++    optparser.add_option('-i', '--debugfs-include-past',
++                         action='store_true',
++                         default=False,
++                         dest='dbgfs_include_past',
++                         help='include all available data on past events for '
++                              'debugfs',
++                         )
+     optparser.add_option('-l', '--log',
+                          action='store_true',
+                          default=False,
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index 68d5024..b0e282a 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -73,6 +73,8 @@ Press any other key to refresh statistics immediately.
+   retrieve statistics from debugfs
+ @item -p, --pid=@var{pid}
+   limit statistics to one virtual machine (pid)
++@item -i, --debugfs-include-past
++  include all available data on past events for debugfs
+ @item -g, --guest=@var{guest_name}
+   limit statistics to one virtual machine (guest name)
+ @item -f, --fields=@var{fields}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-b.patch b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-b.patch
new file mode 100644
index 0000000..b27d3e1
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-b.patch
@@ -0,0 +1,240 @@
+From 17165a0bc8b8496f52f9273fe4466797f3a6726e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:16:03 +0200
+Subject: [PATCH 58/69] tools/kvm_stat: add new interactive command 'b'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-38-david@redhat.com>
+Patchwork-id: 77344
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 37/39] tools/kvm_stat: add new interactive command 'b'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 5c1954d25d1b9e857be2a4c77437312075875589
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 5c1954d25d1b9e857be2a4c77437312075875589
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Sun Jun 25 21:34:16 2017 +0200
+
+    tools/kvm_stat: add new interactive command 'b'
+
+    Toggle display total number of events by guest (debugfs only).
+    When switching to display of events by guest, field filters remain
+    active. I.e. the number of events per guest reported considers only
+    events matching the filters. Likewise with pid/guest filtering.
+    Note that when switching to display of events by guest, DebugfsProvider
+    remains to collect data for events as it did before, but the read()
+    method summarizes the values by pid.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 87 +++++++++++++++++++++++++++++++++++++++++------
+ scripts/kvm/kvm_stat.texi |  3 ++
+ 2 files changed, 80 insertions(+), 10 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 4065b29..dd8f00c 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -662,7 +662,7 @@ class TracepointProvider(Provider):
+         self.setup_traces()
+         self.fields = self._fields
+ 
+-    def read(self):
++    def read(self, by_guest=0):
+         """Returns 'event name: current value' for all enabled events."""
+         ret = defaultdict(int)
+         for group in self.group_leaders:
+@@ -731,7 +731,7 @@ class DebugfsProvider(Provider):
+             self.do_read = True
+         self.reset()
+ 
+-    def read(self, reset=0):
++    def read(self, reset=0, by_guest=0):
+         """Returns a dict with format:'file name / field -> current value'.
+ 
+         Parameter 'reset':
+@@ -762,8 +762,16 @@ class DebugfsProvider(Provider):
+                     self._baseline[key] = 0
+                 if self._baseline.get(key, -1) == -1:
+                     self._baseline[key] = value
+-                results[field] = (results.get(field, 0) + value -
+-                                  self._baseline.get(key, 0))
++                increment = (results.get(field, 0) + value -
++                             self._baseline.get(key, 0))
++                if by_guest:
++                    pid = key.split('-')[0]
++                    if pid in results:
++                        results[pid] += increment
++                    else:
++                        results[pid] = increment
++                else:
++                    results[field] = increment
+ 
+         return results
+ 
+@@ -849,18 +857,44 @@ class Stats(object):
+             for provider in self.providers:
+                 provider.pid = self._pid_filter
+ 
+-    def get(self):
++    def get(self, by_guest=0):
+         """Returns a dict with field -> (value, delta to last value) of all
+         provider data."""
+         for provider in self.providers:
+-            new = provider.read()
+-            for key in provider.fields:
++            new = provider.read(by_guest=by_guest)
++            for key in new if by_guest else provider.fields:
+                 oldval = self.values.get(key, (0, 0))[0]
+                 newval = new.get(key, 0)
+                 newdelta = newval - oldval
+                 self.values[key] = (newval, newdelta)
+         return self.values
+ 
++    def toggle_display_guests(self, to_pid):
++        """Toggle between collection of stats by individual event and by
++        guest pid
++
++        Events reported by DebugfsProvider change when switching to/from
++        reading by guest values. Hence we have to remove the excess event
++        names from self.values.
++
++        """
++        if any(isinstance(ins, TracepointProvider) for ins in self.providers):
++            return 1
++        if to_pid:
++            for provider in self.providers:
++                if isinstance(provider, DebugfsProvider):
++                    for key in provider.fields:
++                        if key in self.values.keys():
++                            del self.values[key]
++        else:
++            oldvals = self.values.copy()
++            for key in oldvals:
++                if key.isdigit():
++                    del self.values[key]
++        # Update oldval (see get())
++        self.get(to_pid)
++        return 0
++
+ DELAY_DEFAULT = 3.0
+ MAX_GUEST_NAME_LEN = 48
+ MAX_REGEX_LEN = 44
+@@ -876,6 +910,7 @@ class Tui(object):
+         self._delay_initial = 0.25
+         self._delay_regular = DELAY_DEFAULT
+         self._sorting = SORT_DEFAULT
++        self._display_guests = 0
+ 
+     def __enter__(self):
+         """Initialises curses for later use.  Based on curses.wrapper
+@@ -1024,8 +1059,12 @@ class Tui(object):
+             if len(regex) > MAX_REGEX_LEN:
+                 regex = regex[:MAX_REGEX_LEN] + '...'
+             self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
++        if self._display_guests:
++            col_name = 'Guest Name'
++        else:
++            col_name = 'Event'
+         self.screen.addstr(2, 1, '%-40s %10s%7s %8s' %
+-                           ('Event', 'Total', '%Total', 'CurAvg/s'),
++                           (col_name, 'Total', '%Total', 'CurAvg/s'),
+                            curses.A_STANDOUT)
+         self.screen.addstr(4, 1, 'Collecting data...')
+         self.screen.refresh()
+@@ -1034,7 +1073,7 @@ class Tui(object):
+         row = 3
+         self.screen.move(row, 0)
+         self.screen.clrtobot()
+-        stats = self.stats.get()
++        stats = self.stats.get(self._display_guests)
+ 
+         def sortCurAvg(x):
+             # sort by current events if available
+@@ -1062,6 +1101,8 @@ class Tui(object):
+                 break
+             if values[0] is not None:
+                 cur = int(round(values[1] / sleeptime)) if values[1] else ''
++                if self._display_guests:
++                    key = self.get_gname_from_pid(key)
+                 self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' %
+                                    (key, values[0], values[0] * 100 / total,
+                                     cur))
+@@ -1070,9 +1111,26 @@ class Tui(object):
+             self.screen.addstr(4, 1, 'No matching events reported yet')
+         self.screen.refresh()
+ 
++    def show_msg(self, text):
++        """Display message centered text and exit on key press"""
++        hint = 'Press any key to continue'
++        curses.cbreak()
++        self.screen.erase()
++        (x, term_width) = self.screen.getmaxyx()
++        row = 2
++        for line in text:
++            start = (term_width - len(line)) / 2
++            self.screen.addstr(row, start, line)
++            row += 1
++        self.screen.addstr(row + 1, (term_width - len(hint)) / 2, hint,
++                           curses.A_STANDOUT)
++        self.screen.getkey()
++
+     def show_help_interactive(self):
+         """Display help with list of interactive commands"""
+-        msg = ('   c     clear filter',
++        msg = ('   b     toggle events by guests (debugfs only, honors'
++               ' filters)',
++               '   c     clear filter',
+                '   f     filter by regular expression',
+                '   g     filter by guest name',
+                '   h     display interactive commands reference',
+@@ -1253,6 +1311,14 @@ class Tui(object):
+             sleeptime = self._delay_regular
+             try:
+                 char = self.screen.getkey()
++                if char == 'b':
++                    self._display_guests = not self._display_guests
++                    if self.stats.toggle_display_guests(self._display_guests):
++                        self.show_msg(['Command not available with tracepoints'
++                                       ' enabled', 'Restart with debugfs only '
++                                       '(see option \'-d\') and try again!'])
++                        self._display_guests = not self._display_guests
++                    self.refresh_header()
+                 if char == 'c':
+                     self.stats.fields_filter = DEFAULT_REGEX
+                     self.refresh_header(0)
+@@ -1356,6 +1422,7 @@ Requirements:
+   the large number of files that are possibly opened.
+ 
+ Interactive Commands:
++   b     toggle events by guests (debugfs only, honors filters)
+    c     clear filter
+    f     filter by regular expression
+    g     filter by guest name
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index b0e282a..5d964f6 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -24,6 +24,9 @@ Use batch and logging modes for scripting purposes.
+ While running in regular (interactive) mode, use any of the following keys:
+ 
+ @table @key
++@item b
++@kindex b
++toggle events by guests (debugfs only, honors filters)
+ @item c
+ @kindex c
+ clear filter
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-h.patch b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-h.patch
new file mode 100644
index 0000000..5d3b241
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-h.patch
@@ -0,0 +1,134 @@
+From 95b5c46145b2ac79dd4b0f5621baec07e488ff3e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:57 +0200
+Subject: [PATCH 52/69] tools/kvm_stat: add new interactive command 'h'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-32-david@redhat.com>
+Patchwork-id: 77339
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 31/39] tools/kvm_stat: add new interactive command 'h'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 1fdea7b2893045e5258a13937c3d78c425fd7aa0
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 1fdea7b2893045e5258a13937c3d78c425fd7aa0
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:38 2017 +0200
+
+    tools/kvm_stat: add new interactive command 'h'
+
+    Display interactive commands reference on 'h'.
+    While at it, sort interactive commands alphabetically in various places.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 37 ++++++++++++++++++++++++++++++++-----
+ scripts/kvm/kvm_stat.texi |  3 +++
+ 2 files changed, 35 insertions(+), 5 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index a9e7ea6..6838de3 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1018,6 +1018,30 @@ class Tui(object):
+             self.screen.addstr(4, 1, 'No matching events reported yet')
+         self.screen.refresh()
+ 
++    def show_help_interactive(self):
++        """Display help with list of interactive commands"""
++        msg = ('   c     clear filter',
++               '   f     filter by regular expression',
++               '   g     filter by guest name',
++               '   h     display interactive commands reference',
++               '   p     filter by PID',
++               '   q     quit',
++               '   r     reset stats',
++               '   x     toggle reporting of stats for individual child trace'
++               ' events',
++               'Any other key refreshes statistics immediately')
++        curses.cbreak()
++        self.screen.erase()
++        self.screen.addstr(0, 0, "Interactive commands reference",
++                           curses.A_BOLD)
++        self.screen.addstr(2, 0, "Press any key to exit", curses.A_STANDOUT)
++        row = 4
++        for line in msg:
++            self.screen.addstr(row, 0, line)
++            row += 1
++        self.screen.getkey()
++        self.refresh_header()
++
+     def show_filter_selection(self):
+         """Draws filter selection mask.
+ 
+@@ -1142,10 +1166,6 @@ class Tui(object):
+             sleeptime = DELAY_REGULAR
+             try:
+                 char = self.screen.getkey()
+-                if char == 'x':
+-                    self.update_drilldown()
+-                if char == 'q':
+-                    break
+                 if char == 'c':
+                     self.stats.fields_filter = DEFAULT_REGEX
+                     self.refresh_header(0)
+@@ -1160,13 +1180,19 @@ class Tui(object):
+                     self.show_vm_selection_by_guest_name()
+                     curses.curs_set(0)
+                     sleeptime = DELAY_INITIAL
++                if char == 'h':
++                    self.show_help_interactive()
+                 if char == 'p':
+                     curses.curs_set(1)
+                     self.show_vm_selection_by_pid()
+                     curses.curs_set(0)
+                     sleeptime = DELAY_INITIAL
++                if char == 'q':
++                    break
+                 if char == 'r':
+                     self.stats.reset()
++                if char == 'x':
++                    self.update_drilldown()
+             except KeyboardInterrupt:
+                 break
+             except curses.error:
+@@ -1237,10 +1263,11 @@ Interactive Commands:
+    c     clear filter
+    f     filter by regular expression
+    g     filter by guest name
++   h     display interactive commands reference
+    p     filter by PID
+    q     quit
+-   x     toggle reporting of stats for individual child trace events
+    r     reset stats
++   x     toggle reporting of stats for individual child trace events
+ Press any other key to refresh statistics immediately.
+ """
+ 
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index c0cb7bc..4dfcd8f 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -33,6 +33,9 @@ filter by regular expression
+ @item g
+ @kindex g
+ filter by guest name
++@item h
++@kindex h
++display interactive commands reference
+ @item p
+ @kindex p
+ filter by PID
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-o.patch b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-o.patch
new file mode 100644
index 0000000..399e5ee
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-o.patch
@@ -0,0 +1,125 @@
+From 55f7ed9b2ccc2761e353d14680fe5d1ea8bc11be Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:59 +0200
+Subject: [PATCH 54/69] tools/kvm_stat: add new interactive command 'o'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-34-david@redhat.com>
+Patchwork-id: 77347
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 33/39] tools/kvm_stat: add new interactive command 'o'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 6667ae8f395099257afca0963838d2dc50a18da7
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 6667ae8f395099257afca0963838d2dc50a18da7
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:41 2017 +0200
+
+    tools/kvm_stat: add new interactive command 'o'
+
+    Add new interactive command 'o' to toggle sorting by 'CurAvg/s' (default)
+    and 'Total' columns.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 17 ++++++++++++++++-
+ scripts/kvm/kvm_stat.texi |  3 +++
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 1276b88..cf7aa28 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -848,6 +848,7 @@ DELAY_DEFAULT = 3.0
+ MAX_GUEST_NAME_LEN = 48
+ MAX_REGEX_LEN = 44
+ DEFAULT_REGEX = r'^[^\(]*$'
++SORT_DEFAULT = 0
+ 
+ 
+ class Tui(object):
+@@ -857,6 +858,7 @@ class Tui(object):
+         self.screen = None
+         self._delay_initial = 0.25
+         self._delay_regular = DELAY_DEFAULT
++        self._sorting = SORT_DEFAULT
+ 
+     def __enter__(self):
+         """Initialises curses for later use.  Based on curses.wrapper
+@@ -994,14 +996,23 @@ class Tui(object):
+         self.screen.clrtobot()
+         stats = self.stats.get()
+ 
+-        def sortkey(x):
++        def sortCurAvg(x):
++            # sort by current events if available
+             if stats[x][1]:
+                 return (-stats[x][1], -stats[x][0])
+             else:
+                 return (0, -stats[x][0])
++
++        def sortTotal(x):
++            # sort by totals
++            return (0, -stats[x][0])
+         total = 0.
+         for val in stats.values():
+             total += val[0]
++        if self._sorting == SORT_DEFAULT:
++            sortkey = sortCurAvg
++        else:
++            sortkey = sortTotal
+         for key in sorted(stats.keys(), key=sortkey):
+ 
+             if row >= self.screen.getmaxyx()[0]:
+@@ -1025,6 +1036,7 @@ class Tui(object):
+                '   f     filter by regular expression',
+                '   g     filter by guest name',
+                '   h     display interactive commands reference',
++               '   o     toggle sorting order (Total vs CurAvg/s)',
+                '   p     filter by PID',
+                '   q     quit',
+                '   r     reset stats',
+@@ -1215,6 +1227,8 @@ class Tui(object):
+                     sleeptime = self._delay_initial
+                 if char == 'h':
+                     self.show_help_interactive()
++                if char == 'o':
++                    self._sorting = not self._sorting
+                 if char == 'p':
+                     curses.curs_set(1)
+                     self.show_vm_selection_by_pid()
+@@ -1302,6 +1316,7 @@ Interactive Commands:
+    f     filter by regular expression
+    g     filter by guest name
+    h     display interactive commands reference
++   o     toggle sorting order (Total vs CurAvg/s)
+    p     filter by PID
+    q     quit
+    r     reset stats
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index f0066ff..68d5024 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -36,6 +36,9 @@ filter by guest name
+ @item h
+ @kindex h
+ display interactive commands reference
++@item o
++@kindex o
++toggle sorting order (Total vs CurAvg/s)
+ @item p
+ @kindex p
+ filter by PID
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-s.patch b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-s.patch
new file mode 100644
index 0000000..3e06a56
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-new-interactive-command-s.patch
@@ -0,0 +1,187 @@
+From 25c56e3212fa11d526544b402f4f19234cf991e8 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:58 +0200
+Subject: [PATCH 53/69] tools/kvm_stat: add new interactive command 's'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-33-david@redhat.com>
+Patchwork-id: 77336
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 32/39] tools/kvm_stat: add new interactive command 's'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 64eefad2cdbf2d7c76e24d0b67e19efdbe1c97a9
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 64eefad2cdbf2d7c76e24d0b67e19efdbe1c97a9
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:39 2017 +0200
+
+    tools/kvm_stat: add new interactive command 's'
+
+    Add new command 's' to modify the update interval. Limited to a maximum of
+    25.5 sec and a minimum of 0.1 sec, since curses cannot handle longer
+    and shorter delays respectively.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 55 ++++++++++++++++++++++++++++++++++++++++-------
+ scripts/kvm/kvm_stat.texi |  3 +++
+ 2 files changed, 50 insertions(+), 8 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 6838de3..1276b88 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -844,8 +844,7 @@ class Stats(object):
+                 self.values[key] = (newval, newdelta)
+         return self.values
+ 
+-DELAY_INITIAL = 0.25
+-DELAY_REGULAR = 3.0
++DELAY_DEFAULT = 3.0
+ MAX_GUEST_NAME_LEN = 48
+ MAX_REGEX_LEN = 44
+ DEFAULT_REGEX = r'^[^\(]*$'
+@@ -856,6 +855,8 @@ class Tui(object):
+     def __init__(self, stats):
+         self.stats = stats
+         self.screen = None
++        self._delay_initial = 0.25
++        self._delay_regular = DELAY_DEFAULT
+ 
+     def __enter__(self):
+         """Initialises curses for later use.  Based on curses.wrapper
+@@ -1027,6 +1028,7 @@ class Tui(object):
+                '   p     filter by PID',
+                '   q     quit',
+                '   r     reset stats',
++               '   s     set update interval',
+                '   x     toggle reporting of stats for individual child trace'
+                ' events',
+                'Any other key refreshes statistics immediately')
+@@ -1106,10 +1108,41 @@ class Tui(object):
+                 self.refresh_header(pid)
+                 self.update_pid(pid)
+                 break
+-
+             except ValueError:
+                 msg = '"' + str(pid) + '": Not a valid pid'
+ 
++    def show_set_update_interval(self):
++        """Draws update interval selection mask."""
++        msg = ''
++        while True:
++            self.screen.erase()
++            self.screen.addstr(0, 0, 'Set update interval (defaults to %fs).' %
++                               DELAY_DEFAULT, curses.A_BOLD)
++            self.screen.addstr(4, 0, msg)
++            self.screen.addstr(2, 0, 'Change delay from %.1fs to ' %
++                               self._delay_regular)
++            curses.echo()
++            val = self.screen.getstr()
++            curses.noecho()
++
++            try:
++                if len(val) > 0:
++                    delay = float(val)
++                    if delay < 0.1:
++                        msg = '"' + str(val) + '": Value must be >=0.1'
++                        continue
++                    if delay > 25.5:
++                        msg = '"' + str(val) + '": Value must be <=25.5'
++                        continue
++                else:
++                    delay = DELAY_DEFAULT
++                self._delay_regular = delay
++                break
++
++            except ValueError:
++                msg = '"' + str(val) + '": Invalid value'
++        self.refresh_header()
++
+     def show_vm_selection_by_guest_name(self):
+         """Draws guest selection mask.
+ 
+@@ -1156,14 +1189,14 @@ class Tui(object):
+ 
+     def show_stats(self):
+         """Refreshes the screen and processes user input."""
+-        sleeptime = DELAY_INITIAL
++        sleeptime = self._delay_initial
+         self.refresh_header()
+         start = 0.0  # result based on init value never appears on screen
+         while True:
+             self.refresh_body(time.time() - start)
+             curses.halfdelay(int(sleeptime * 10))
+             start = time.time()
+-            sleeptime = DELAY_REGULAR
++            sleeptime = self._delay_regular
+             try:
+                 char = self.screen.getkey()
+                 if char == 'c':
+@@ -1174,23 +1207,28 @@ class Tui(object):
+                     curses.curs_set(1)
+                     self.show_filter_selection()
+                     curses.curs_set(0)
+-                    sleeptime = DELAY_INITIAL
++                    sleeptime = self._delay_initial
+                 if char == 'g':
+                     curses.curs_set(1)
+                     self.show_vm_selection_by_guest_name()
+                     curses.curs_set(0)
+-                    sleeptime = DELAY_INITIAL
++                    sleeptime = self._delay_initial
+                 if char == 'h':
+                     self.show_help_interactive()
+                 if char == 'p':
+                     curses.curs_set(1)
+                     self.show_vm_selection_by_pid()
+                     curses.curs_set(0)
+-                    sleeptime = DELAY_INITIAL
++                    sleeptime = self._delay_initial
+                 if char == 'q':
+                     break
+                 if char == 'r':
+                     self.stats.reset()
++                if char == 's':
++                    curses.curs_set(1)
++                    self.show_set_update_interval()
++                    curses.curs_set(0)
++                    sleeptime = self._delay_initial
+                 if char == 'x':
+                     self.update_drilldown()
+             except KeyboardInterrupt:
+@@ -1267,6 +1305,7 @@ Interactive Commands:
+    p     filter by PID
+    q     quit
+    r     reset stats
++   s     set update interval
+    x     toggle reporting of stats for individual child trace events
+ Press any other key to refresh statistics immediately.
+ """
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index 4dfcd8f..f0066ff 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -45,6 +45,9 @@ quit
+ @item r
+ @kindex r
+ reset stats
++@item s
++@kindex s
++set update interval
+ @item x
+ @kindex x
+ toggle reporting of stats for child trace events
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-add-option-guest.patch b/SOURCES/kvm-tools-kvm_stat-add-option-guest.patch
new file mode 100644
index 0000000..fd2b980
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-add-option-guest.patch
@@ -0,0 +1,239 @@
+From 8b7b31fc24968fc62be018b9932ea94263e1b586 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:40 +0200
+Subject: [PATCH 35/69] tools/kvm_stat: add option '--guest'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-15-david@redhat.com>
+Patchwork-id: 77323
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 14/39] tools/kvm_stat: add option '--guest'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git f9ff1087354e5e063b96a291360a8de84bea0bed
+
+Convertion of documentation (for man page generation) to texi.
+
+commit f9ff1087354e5e063b96a291360a8de84bea0bed
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:13 2017 +0100
+
+    tools/kvm_stat: add option '--guest'
+
+    Add a new option '-g'/'--guest' to select a particular process by providing
+    the QEMU guest name.
+    Notes:
+    - The logic to figure out the pid corresponding to the guest name might look
+      scary, but works pretty reliably in practice; in the unlikely event that it
+      returns add'l flukes, it will bail out and hint at using '-p' instead, no
+      harm done.
+    - Mixing '-g' and '-p' is possible, and the final instance specified on the
+      command line is the significant one. This is consistent with current
+      behavior for '-p' which, if specified multiple times, also regards the final
+      instance as the significant one.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      | 101 +++++++++++++++++++++++++++++++++++++++++++++-
+ scripts/kvm/kvm_stat.texi |   5 +++
+ 2 files changed, 104 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index f2a868b..f263312 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -30,6 +30,7 @@ import fcntl
+ import resource
+ import struct
+ import re
++import subprocess
+ from collections import defaultdict
+ 
+ VMX_EXIT_REASONS = {
+@@ -320,6 +321,30 @@ def parse_int_list(list_string):
+     return integers
+ 
+ 
++def get_pid_from_gname(gname):
++    """Fuzzy function to convert guest name to QEMU process pid.
++
++    Returns a list of potential pids, can be empty if no match found.
++    Throws an exception on processing errors.
++
++    """
++    pids = []
++    try:
++        child = subprocess.Popen(['ps', '-A', '--format', 'pid,args'],
++                                 stdout=subprocess.PIPE)
++    except:
++        raise Exception
++    for line in child.stdout:
++        line = line.lstrip().split(' ', 1)
++        # perform a sanity check before calling the more expensive
++        # function to possibly extract the guest name
++        if ' -name ' in line[1] and gname == get_gname_from_pid(line[0]):
++            pids.append(int(line[0]))
++    child.stdout.close()
++
++    return pids
++
++
+ def get_gname_from_pid(pid):
+     """Returns the guest name for a QEMU process pid.
+ 
+@@ -977,7 +1002,7 @@ class Tui(object):
+             except re.error:
+                 continue
+ 
+-    def show_vm_selection(self):
++    def show_vm_selection_by_pid(self):
+         """Draws PID selection mask.
+ 
+         Asks for a pid until a valid pid or 0 has been entered.
+@@ -1016,6 +1041,50 @@ class Tui(object):
+                 msg = '"' + str(pid) + '": Not a valid pid'
+                 continue
+ 
++    def show_vm_selection_by_guest_name(self):
++        """Draws guest selection mask.
++
++        Asks for a guest name until a valid guest name or '' is entered.
++
++        """
++        msg = ''
++        while True:
++            self.screen.erase()
++            self.screen.addstr(0, 0,
++                               'Show statistics for specific guest.',
++                               curses.A_BOLD)
++            self.screen.addstr(1, 0,
++                               'This might limit the shown data to the trace '
++                               'statistics.')
++            self.screen.addstr(5, 0, msg)
++            curses.echo()
++            self.screen.addstr(3, 0, "Guest [ENTER or guest]: ")
++            gname = self.screen.getstr()
++            curses.noecho()
++
++            if not gname:
++                self.refresh_header(0)
++                self.update_pid(0)
++                break
++            else:
++                pids = []
++                try:
++                    pids = get_pid_from_gname(gname)
++                except:
++                    msg = '"' + gname + '": Internal error while searching, ' \
++                          'use pid filter instead'
++                    continue
++                if len(pids) == 0:
++                    msg = '"' + gname + '": Not an active guest'
++                    continue
++                if len(pids) > 1:
++                    msg = '"' + gname + '": Multiple matches found, use pid ' \
++                          'filter instead'
++                    continue
++                self.refresh_header(pids[0])
++                self.update_pid(pids[0])
++                break
++
+     def show_stats(self):
+         """Refreshes the screen and processes user input."""
+         sleeptime = DELAY_INITIAL
+@@ -1035,8 +1104,11 @@ class Tui(object):
+                 if char == 'f':
+                     self.show_filter_selection()
+                     sleeptime = DELAY_INITIAL
++                if char == 'g':
++                    self.show_vm_selection_by_guest_name()
++                    sleeptime = DELAY_INITIAL
+                 if char == 'p':
+-                    self.show_vm_selection()
++                    self.show_vm_selection_by_pid()
+                     sleeptime = DELAY_INITIAL
+             except KeyboardInterrupt:
+                 break
+@@ -1106,6 +1178,7 @@ Requirements:
+ 
+ Interactive Commands:
+    f     filter by regular expression
++   g     filter by guest name
+    p     filter by PID
+    q     quit
+    x     toggle reporting of stats for individual child trace events
+@@ -1119,6 +1192,22 @@ Press any other key to refresh statistics immediately.
+             else:
+                 return ""
+ 
++    def cb_guest_to_pid(option, opt, val, parser):
++        try:
++            pids = get_pid_from_gname(val)
++        except:
++            raise optparse.OptionValueError('Error while searching for guest '
++                                            '"{}", use "-p" to specify a pid '
++                                            'instead'.format(val))
++        if len(pids) == 0:
++            raise optparse.OptionValueError('No guest by the name "{}" '
++                                            'found'.format(val))
++        if len(pids) > 1:
++            raise optparse.OptionValueError('Multiple processes found (pids: '
++                                            '{}) - use "-p" to specify a pid '
++                                            'instead'.format(" ".join(pids)))
++        parser.values.pid = pids[0]
++
+     optparser = optparse.OptionParser(description=description_text,
+                                       formatter=PlainHelpFormatter())
+     optparser.add_option('-1', '--once', '--batch',
+@@ -1158,6 +1247,14 @@ Press any other key to refresh statistics immediately.
+                          dest='pid',
+                          help='restrict statistics to pid',
+                          )
++    optparser.add_option('-g', '--guest',
++                         action='callback',
++                         type='string',
++                         dest='pid',
++                         metavar='GUEST',
++                         help='restrict statistics to guest by name',
++                         callback=cb_guest_to_pid,
++                         )
+     (options, _) = optparser.parse_args(sys.argv)
+     return options
+ 
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index 3519cf9..a8c1071 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -27,6 +27,9 @@ While running in regular (interactive) mode, use any of the following keys:
+ @item f
+ @kindex f
+ filter by regular expression
++@item g
++@kindex g
++filter by guest name
+ @item p
+ @kindex p
+ filter by PID
+@@ -55,6 +58,8 @@ Press any other key to refresh statistics immediately.
+   retrieve statistics from debugfs
+ @item -p, --pid=@var{pid}
+   limit statistics to one virtual machine (pid)
++@item -g, --guest=@var{guest_name}
++  limit statistics to one virtual machine (guest name)
+ @item -f, --fields=@var{fields}
+   fields to display (regex)
+ @item -h, --help
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-catch-curses-exceptions-only.patch b/SOURCES/kvm-tools-kvm_stat-catch-curses-exceptions-only.patch
new file mode 100644
index 0000000..08b4920
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-catch-curses-exceptions-only.patch
@@ -0,0 +1,57 @@
+From 98cf56caaacda1b1f3ef8b571fe601fe0acdd8bf Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:28 +0200
+Subject: [PATCH 23/69] tools/kvm_stat: catch curses exceptions only
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-3-david@redhat.com>
+Patchwork-id: 77311
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 02/39] tools/kvm_stat: catch curses exceptions only
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 9fc0adfc427a5e3f95f8db8dafabe1eaa3720f4a
+
+commit 9fc0adfc427a5e3f95f8db8dafabe1eaa3720f4a
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:01 2017 +0100
+
+    tools/kvm_stat: catch curses exceptions only
+
+    The previous version was catching all exceptions, including SIGINT.
+    We only want to catch the curses exceptions here.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Reviewed-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 8cc83a3..ef47ad7 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -809,7 +809,7 @@ class Tui(object):
+         # return from C start_color() is ignorable.
+         try:
+             curses.start_color()
+-        except:
++        except curses.error:
+             pass
+ 
+         # Hide cursor in extra statement as some monochrome terminals
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-display-guest-list-in-pid-guest-sele2.patch b/SOURCES/kvm-tools-kvm_stat-display-guest-list-in-pid-guest-sele2.patch
new file mode 100644
index 0000000..16adf5c
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-display-guest-list-in-pid-guest-sele2.patch
@@ -0,0 +1,53 @@
+From 554fa10df52cbb50ef39ee5eb4ac324610b240ea Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:16:01 +0200
+Subject: [PATCH 56/69] tools/kvm_stat: display guest list in pid/guest
+ selection screens
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-36-david@redhat.com>
+Patchwork-id: 77342
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 35/39] tools/kvm_stat: display guest list in pid/guest selection screens
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 61f381bb7e1a8e9250aa32b3963a7a5c4b92cbf5
+
+commit 61f381bb7e1a8e9250aa32b3963a7a5c4b92cbf5
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Sun Jun 25 21:34:14 2017 +0200
+
+    tools/kvm_stat: fix error on interactive command 'g'
+
+    Fix an instance where print_all_gnames() is called without the mandatory
+    argument, resulting in a stack trace.
+    To reproduce, simply press 'g' in interactive mode.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 2cf5176..39476e5 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1195,7 +1195,7 @@ class Tui(object):
+                                'This might limit the shown data to the trace '
+                                'statistics.')
+             self.screen.addstr(5, 0, msg)
+-            self.print_all_gnames()
++            self.print_all_gnames(7)
+             curses.echo()
+             self.screen.addstr(3, 0, "Guest [ENTER or guest]: ")
+             gname = self.screen.getstr()
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-display-guest-list-in-pid-guest-selec.patch b/SOURCES/kvm-tools-kvm_stat-display-guest-list-in-pid-guest-selec.patch
new file mode 100644
index 0000000..67fa011
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-display-guest-list-in-pid-guest-selec.patch
@@ -0,0 +1,125 @@
+From 53a1267b00b7e981a5f67b9d241da6008004d002 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:16:00 +0200
+Subject: [PATCH 55/69] tools/kvm_stat: display guest list in pid/guest
+ selection screens
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-35-david@redhat.com>
+Patchwork-id: 77338
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 34/39] tools/kvm_stat: display guest list in pid/guest selection screens
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 865279c53ca9d88718d974bb014b2c6ce259ac75
+
+commit 865279c53ca9d88718d974bb014b2c6ce259ac75
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:43 2017 +0200
+
+    tools/kvm_stat: display guest list in pid/guest selection screens
+
+    Display a (possibly inaccurate) list of all running guests. Note that we
+    leave a bit of extra room above the list for potential error messages.
+    Furthermore, we deliberately do not reject pids or guest names that are
+    not in our list, as we cannot rule out that our fuzzy approach might be
+    in error somehow.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 49 +++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 37 insertions(+), 12 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index cf7aa28..2cf5176 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -894,15 +894,9 @@ class Tui(object):
+             curses.nocbreak()
+             curses.endwin()
+ 
+-    @staticmethod
+-    def get_pid_from_gname(gname):
+-        """Fuzzy function to convert guest name to QEMU process pid.
+-
+-        Returns a list of potential pids, can be empty if no match found.
+-        Throws an exception on processing errors.
+-
+-        """
+-        pids = []
++    def get_all_gnames(self):
++        """Returns a list of (pid, gname) tuples of all running guests"""
++        res = []
+         try:
+             child = subprocess.Popen(['ps', '-A', '--format', 'pid,args'],
+                                      stdout=subprocess.PIPE)
+@@ -912,11 +906,40 @@ class Tui(object):
+             line = line.lstrip().split(' ', 1)
+             # perform a sanity check before calling the more expensive
+             # function to possibly extract the guest name
+-            if (' -name ' in line[1] and
+-                    gname == self.get_gname_from_pid(line[0])):
+-                pids.append(int(line[0]))
++            if ' -name ' in line[1]:
++                res.append((line[0], self.get_gname_from_pid(line[0])))
+         child.stdout.close()
+ 
++        return res
++
++    def print_all_gnames(self, row):
++        """Print a list of all running guests along with their pids."""
++        self.screen.addstr(row, 2, '%8s  %-60s' %
++                           ('Pid', 'Guest Name (fuzzy list, might be '
++                            'inaccurate!)'),
++                           curses.A_UNDERLINE)
++        row += 1
++        try:
++            for line in self.get_all_gnames():
++                self.screen.addstr(row, 2, '%8s  %-60s' % (line[0], line[1]))
++                row += 1
++                if row >= self.screen.getmaxyx()[0]:
++                    break
++        except Exception:
++            self.screen.addstr(row + 1, 2, 'Not available')
++
++    def get_pid_from_gname(self, gname):
++        """Fuzzy function to convert guest name to QEMU process pid.
++
++        Returns a list of potential pids, can be empty if no match found.
++        Throws an exception on processing errors.
++
++        """
++        pids = []
++        for line in self.get_all_gnames():
++            if gname == line[1]:
++                pids.append(int(line[0]))
++
+         return pids
+ 
+     @staticmethod
+@@ -1102,6 +1125,7 @@ class Tui(object):
+                                'This might limit the shown data to the trace '
+                                'statistics.')
+             self.screen.addstr(5, 0, msg)
++            self.print_all_gnames(7)
+ 
+             curses.echo()
+             self.screen.addstr(3, 0, "Pid [0 or pid]: ")
+@@ -1171,6 +1195,7 @@ class Tui(object):
+                                'This might limit the shown data to the trace '
+                                'statistics.')
+             self.screen.addstr(5, 0, msg)
++            self.print_all_gnames()
+             curses.echo()
+             self.screen.addstr(3, 0, "Guest [ENTER or guest]: ")
+             gname = self.screen.getstr()
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-display-guest-name-when-using-pid-fil.patch b/SOURCES/kvm-tools-kvm_stat-display-guest-name-when-using-pid-fil.patch
new file mode 100644
index 0000000..434ccef
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-display-guest-name-when-using-pid-fil.patch
@@ -0,0 +1,110 @@
+From 3e1d2fc34c6ff536cfcc2787a98e579ff31550b1 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:35 +0200
+Subject: [PATCH 30/69] tools/kvm_stat: display guest name when using pid
+ filter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-10-david@redhat.com>
+Patchwork-id: 77317
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 09/39] tools/kvm_stat: display guest name when using pid filter
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git a24e85f6a69f09a9d09a86110a6bb168c60610ef
+
+commit a24e85f6a69f09a9d09a86110a6bb168c60610ef
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:08 2017 +0100
+
+    tools/kvm_stat: display guest name when using pid filter
+
+    When running kvm_stat with option '-p' to filter per process, display
+    the QEMU guest name next to the pid, if available.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-By: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 41 +++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 39 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index aca8508..95ffa9a 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -320,6 +320,37 @@ def parse_int_list(list_string):
+     return integers
+ 
+ 
++def get_gname_from_pid(pid):
++    """Returns the guest name for a QEMU process pid.
++
++    Extracts the guest name from the QEMU comma line by processing the '-name'
++    option. Will also handle names specified out of sequence.
++
++    """
++    name = ''
++    try:
++        line = open('/proc/{}/cmdline'.format(pid), 'rb').read().split('\0')
++        parms = line[line.index('-name') + 1].split(',')
++        while '' in parms:
++            # commas are escaped (i.e. ',,'), hence e.g. 'foo,bar' results in
++            # ['foo', '', 'bar'], which we revert here
++            idx = parms.index('')
++            parms[idx - 1] += ',' + parms[idx + 1]
++            del parms[idx:idx+2]
++        # the '-name' switch allows for two ways to specify the guest name,
++        # where the plain name overrides the name specified via 'guest='
++        for arg in parms:
++            if '=' not in arg:
++                name = arg
++                break
++            if arg[:6] == 'guest=':
++                name = arg[6:]
++    except (ValueError, IOError, IndexError):
++        pass
++
++    return name
++
++
+ def get_online_cpus():
+     """Returns a list of cpu id integers."""
+     with open('/sys/devices/system/cpu/online') as cpu_list:
+@@ -803,6 +834,7 @@ LABEL_WIDTH = 40
+ NUMBER_WIDTH = 10
+ DELAY_INITIAL = 0.25
+ DELAY_REGULAR = 3.0
++MAX_GUEST_NAME_LEN = 48
+ 
+ 
+ class Tui(object):
+@@ -863,9 +895,14 @@ class Tui(object):
+         if pid is None:
+             pid = self.stats.pid_filter
+         self.screen.erase()
++        gname = get_gname_from_pid(pid)
++        if gname:
++            gname = ('({})'.format(gname[:MAX_GUEST_NAME_LEN] + '...'
++                                   if len(gname) > MAX_GUEST_NAME_LEN
++                                   else gname))
+         if pid > 0:
+-            self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
+-                               .format(pid), curses.A_BOLD)
++            self.screen.addstr(0, 0, 'kvm statistics - pid {0} {1}'
++                               .format(pid, gname), curses.A_BOLD)
+         else:
+             self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
+         self.screen.addstr(2, 1, 'Event')
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-display-message-indicating-lack-of-ev.patch b/SOURCES/kvm-tools-kvm_stat-display-message-indicating-lack-of-ev.patch
new file mode 100644
index 0000000..afea904
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-display-message-indicating-lack-of-ev.patch
@@ -0,0 +1,52 @@
+From 6b557dc235257a9d4e69532f79007a9a4de854c6 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:54 +0200
+Subject: [PATCH 49/69] tools/kvm_stat: display message indicating lack of
+ events
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-29-david@redhat.com>
+Patchwork-id: 77340
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 28/39] tools/kvm_stat: display message indicating lack of events
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 5725393764a342b6a5420fdd10184984ca08b5f6
+
+commit 5725393764a342b6a5420fdd10184984ca08b5f6
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:35 2017 +0200
+
+    tools/kvm_stat: display message indicating lack of events
+
+    Give users some indication on the reason why no data is displayed on the
+    screen yet.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 53dcd40..790fbce 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1013,6 +1013,8 @@ class Tui(object):
+                                    (key, values[0], values[0] * 100 / total,
+                                     cur))
+             row += 1
++        if row == 3:
++            self.screen.addstr(4, 1, 'No matching events reported yet')
+         self.screen.refresh()
+ 
+     def show_filter_selection(self):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-display-regex-when-set-to-non-default.patch b/SOURCES/kvm-tools-kvm_stat-display-regex-when-set-to-non-default.patch
new file mode 100644
index 0000000..013af6d
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-display-regex-when-set-to-non-default.patch
@@ -0,0 +1,66 @@
+From a0c6451760d3bae225d4cd4e152d862c6e76673e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:38 +0200
+Subject: [PATCH 33/69] tools/kvm_stat: display regex when set to non-default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-13-david@redhat.com>
+Patchwork-id: 77319
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 12/39] tools/kvm_stat: display regex when set to non-default
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 72187dfa8e2686b748ad7485d0ca59ba993ba526
+
+commit 72187dfa8e2686b748ad7485d0ca59ba993ba526
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:11 2017 +0100
+
+    tools/kvm_stat: display regex when set to non-default
+
+    If a user defines a regex filter through the interactive command, display
+    the active regex in the header's second line.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index ced0cb9..af70717 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -835,6 +835,7 @@ NUMBER_WIDTH = 10
+ DELAY_INITIAL = 0.25
+ DELAY_REGULAR = 3.0
+ MAX_GUEST_NAME_LEN = 48
++MAX_REGEX_LEN = 44
+ 
+ 
+ class Tui(object):
+@@ -905,6 +906,11 @@ class Tui(object):
+                                .format(pid, gname), curses.A_BOLD)
+         else:
+             self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
++        if self.stats.fields_filter and self.stats.fields_filter != '^[^\(]*$':
++            regex = self.stats.fields_filter
++            if len(regex) > MAX_REGEX_LEN:
++                regex = regex[:MAX_REGEX_LEN] + '...'
++            self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
+         self.screen.addstr(2, 1, 'Event')
+         self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
+                            len('Total'), 'Total')
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-document-list-of-interactive-commands.patch b/SOURCES/kvm-tools-kvm_stat-document-list-of-interactive-commands.patch
new file mode 100644
index 0000000..823ffef
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-document-list-of-interactive-commands.patch
@@ -0,0 +1,99 @@
+From 2ef292f12dbc13c450bdac0ec48c293ce6a1a7fe Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:34 +0200
+Subject: [PATCH 29/69] tools/kvm_stat: document list of interactive commands
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-9-david@redhat.com>
+Patchwork-id: 77315
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 08/39] tools/kvm_stat: document list of interactive commands
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 1eaa2f9022d55a8d7249c42def8dc4b0d682e142
+
+Convertion of documentation (for man page generation) to texi.
+
+commit 1eaa2f9022d55a8d7249c42def8dc4b0d682e142
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:07 2017 +0100
+
+    tools/kvm_stat: document list of interactive commands
+
+    Apart from the source code, there does not seem to be a place that documents
+    the interactive capabilities of kvm_stat yet.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat      |  7 +++++++
+ scripts/kvm/kvm_stat.texi | 24 ++++++++++++++++++++++++
+ 2 files changed, 31 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 3e60d93..aca8508 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1052,6 +1052,13 @@ Requirements:
+   CAP_SYS_ADMIN and perf events are used.
+ - CAP_SYS_RESOURCE if the hard limit is not high enough to allow
+   the large number of files that are possibly opened.
++
++Interactive Commands:
++   f     filter by regular expression
++   p     filter by PID
++   q     quit
++   x     toggle reporting of stats for individual child trace events
++Press any other key to refresh statistics immediately.
+ """
+ 
+     class PlainHelpFormatter(optparse.IndentedHelpFormatter):
+diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
+index 4faf1a6..3519cf9 100644
+--- a/scripts/kvm/kvm_stat.texi
++++ b/scripts/kvm/kvm_stat.texi
+@@ -17,8 +17,32 @@ The set of KVM kernel module trace events may be specific to the kernel version
+ or architecture.  It is best to check the KVM kernel module source code for the
+ meaning of events.
+ 
++Use batch and logging modes for scripting purposes.
++
++@section Interactive Commands
++
++While running in regular (interactive) mode, use any of the following keys:
++
++@table @key
++@item f
++@kindex f
++filter by regular expression
++@item p
++@kindex p
++filter by PID
++@item q
++@kindex q
++quit
++@item x
++@kindex x
++toggle reporting of stats for child trace events
++@end table
++
++Press any other key to refresh statistics immediately.
++
+ @c man end
+ 
++
+ @c man begin OPTIONS
+ @table @option
+ @item -1, --once, --batch
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-fix-command-line-option-g.patch b/SOURCES/kvm-tools-kvm_stat-fix-command-line-option-g.patch
new file mode 100644
index 0000000..6dd8952
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-fix-command-line-option-g.patch
@@ -0,0 +1,85 @@
+From 283aa25f757053d99515887348cdc49e873e577c Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Mon, 8 Jan 2018 21:26:31 +0100
+Subject: [PATCH 01/12] tools/kvm_stat: fix command line option '-g'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20180108212631.29046-1-david@redhat.com>
+Patchwork-id: 78528
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] tools/kvm_stat: fix command line option '-g'
+Bugzilla: 1529676
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+commit 19e8e54f4309eaa438237aa1973fe40c331903d4 (HEAD)
+Author: Stefan Raspl <stefan.raspl@de.ibm.com>
+Date:   Mon Dec 11 12:25:19 2017 +0100
+
+    tools/kvm_stat: fix command line option '-g'
+
+    Specifying a guest via '-g foo' always results in an error:
+      $ kvm_stat -g foo
+      Usage: kvm_stat [options]
+
+      kvm_stat: error: Error while searching for guest "foo", use "-p" to
+      specify a pid instead
+
+    Reason is that Tui.get_pid_from_gname() is not static, as it is supposed
+    to be.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 32283d8..c74a9a0 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -946,7 +946,8 @@ class Tui(object):
+             curses.nocbreak()
+             curses.endwin()
+ 
+-    def get_all_gnames(self):
++    @staticmethod
++    def get_all_gnames():
+         """Returns a list of (pid, gname) tuples of all running guests"""
+         res = []
+         try:
+@@ -959,7 +960,7 @@ class Tui(object):
+             # perform a sanity check before calling the more expensive
+             # function to possibly extract the guest name
+             if ' -name ' in line[1]:
+-                res.append((line[0], self.get_gname_from_pid(line[0])))
++                res.append((line[0], Tui.get_gname_from_pid(line[0])))
+         child.stdout.close()
+ 
+         return res
+@@ -980,7 +981,8 @@ class Tui(object):
+         except Exception:
+             self.screen.addstr(row + 1, 2, 'Not available')
+ 
+-    def get_pid_from_gname(self, gname):
++    @staticmethod
++    def get_pid_from_gname(gname):
+         """Fuzzy function to convert guest name to QEMU process pid.
+ 
+         Returns a list of potential pids, can be empty if no match found.
+@@ -988,7 +990,7 @@ class Tui(object):
+ 
+         """
+         pids = []
+-        for line in self.get_all_gnames():
++        for line in Tui.get_all_gnames():
+             if gname == line[1]:
+                 pids.append(int(line[0]))
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-fix-event-counts-display-for-interrup.patch b/SOURCES/kvm-tools-kvm_stat-fix-event-counts-display-for-interrup.patch
new file mode 100644
index 0000000..f7f4849
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-fix-event-counts-display-for-interrup.patch
@@ -0,0 +1,69 @@
+From 7bc419ee18fb59acbd0bf2fc5d31b25b32bc28ea Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:45 +0200
+Subject: [PATCH 40/69] tools/kvm_stat: fix event counts display for
+ interrupted intervals
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-20-david@redhat.com>
+Patchwork-id: 77330
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 19/39] tools/kvm_stat: fix event counts display for interrupted intervals
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 124c2fc9fdf5fb1d9cea4707d7e5471e317ba3bf
+
+commit 124c2fc9fdf5fb1d9cea4707d7e5471e317ba3bf
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:26 2017 +0200
+
+    tools/kvm_stat: fix event counts display for interrupted intervals
+
+    When an update interval is interrupted via key press (e.g. space), the
+    'Current' column value is calculated using the full interval length
+    instead of the elapsed time, which leads to lower than actual numbers.
+    Furthermore, the value should be rounded, not truncated.
+    This is fixed by using the actual elapsed time for the calculation.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 904eb62..b571584 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1009,7 +1009,8 @@ class Tui(object):
+             self.screen.addstr(row, col, '%7.1f' % (values[0] * 100 / total,))
+             col += 7
+             if values[1] is not None:
+-                self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
++                self.screen.addstr(row, col, '%8d' %
++                                   round(values[1] / sleeptime))
+             row += 1
+         self.screen.refresh()
+ 
+@@ -1130,9 +1131,11 @@ class Tui(object):
+         """Refreshes the screen and processes user input."""
+         sleeptime = DELAY_INITIAL
+         self.refresh_header()
++        start = 0.0  # result based on init value never appears on screen
+         while True:
+-            self.refresh_body(sleeptime)
++            self.refresh_body(time.time() - start)
+             curses.halfdelay(int(sleeptime * 10))
++            start = time.time()
+             sleeptime = DELAY_REGULAR
+             try:
+                 char = self.screen.getkey()
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-fix-misc-glitches.patch b/SOURCES/kvm-tools-kvm_stat-fix-misc-glitches.patch
new file mode 100644
index 0000000..c194fea
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-fix-misc-glitches.patch
@@ -0,0 +1,127 @@
+From 8654f68785c5ddddfd92b8fd2b0e550481e3099c Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:30 +0200
+Subject: [PATCH 25/69] tools/kvm_stat: fix misc glitches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-5-david@redhat.com>
+Patchwork-id: 77313
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 04/39] tools/kvm_stat: fix misc glitches
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git e0ba38765c1d1d670246d6f6c518594aa8e62587
+
+commit e0ba38765c1d1d670246d6f6c518594aa8e62587
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:03 2017 +0100
+
+    tools/kvm_stat: fix misc glitches
+
+    Addresses
+    - eliminate extra import
+    - missing variable initialization
+    - type redefinition from int to float
+    - passing of int type argument instead of string
+    - a couple of PEP8-reported indentation/formatting glitches
+    - remove unused variable drilldown in class Tui
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 14536c0..231186a 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -31,7 +31,6 @@ import resource
+ import struct
+ import re
+ from collections import defaultdict
+-from time import sleep
+ 
+ VMX_EXIT_REASONS = {
+     'EXCEPTION_NMI':        0,
+@@ -657,6 +656,7 @@ class DebugfsProvider(object):
+         self._fields = self.get_available_fields()
+         self._pid = 0
+         self.do_read = True
++        self.paths = []
+ 
+     def get_available_fields(self):
+         """"Returns a list of available fields.
+@@ -794,7 +794,6 @@ class Tui(object):
+     def __init__(self, stats):
+         self.stats = stats
+         self.screen = None
+-        self.drilldown = False
+         self.update_drilldown()
+ 
+     def __enter__(self):
+@@ -950,11 +949,10 @@ class Tui(object):
+         while True:
+             self.refresh(sleeptime)
+             curses.halfdelay(int(sleeptime * 10))
+-            sleeptime = 3
++            sleeptime = 3.0
+             try:
+                 char = self.screen.getkey()
+                 if char == 'x':
+-                    self.drilldown = not self.drilldown
+                     self.update_drilldown()
+                 if char == 'q':
+                     break
+@@ -1064,12 +1062,12 @@ Requirements:
+                          help='fields to display (regex)',
+                          )
+     optparser.add_option('-p', '--pid',
+-                        action='store',
+-                        default=0,
+-                        type=int,
+-                        dest='pid',
+-                        help='restrict statistics to pid',
+-                        )
++                         action='store',
++                         default=0,
++                         type='int',
++                         dest='pid',
++                         help='restrict statistics to pid',
++                         )
+     (options, _) = optparser.parse_args(sys.argv)
+     return options
+ 
+@@ -1099,8 +1097,8 @@ def check_access(options):
+                          "Also ensure, that the kvm modules are loaded.\n")
+         sys.exit(1)
+ 
+-    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints
+-                                                     or not options.debugfs):
++    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints or
++                                                     not options.debugfs):
+         sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
+                          "when using the option -t (default).\n"
+                          "If it is enabled, make {0} readable by the "
+@@ -1111,7 +1109,7 @@ def check_access(options):
+ 
+         sys.stderr.write("Falling back to debugfs statistics!\n")
+         options.debugfs = True
+-        sleep(5)
++        time.sleep(5)
+ 
+     return options
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-fix-trace-setup-glitch-on-field-updat.patch b/SOURCES/kvm-tools-kvm_stat-fix-trace-setup-glitch-on-field-updat.patch
new file mode 100644
index 0000000..8a4e4c0
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-fix-trace-setup-glitch-on-field-updat.patch
@@ -0,0 +1,80 @@
+From d4525d7460d6d129d3a6e4b94a125afb6a06e6ca Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:31 +0200
+Subject: [PATCH 26/69] tools/kvm_stat: fix trace setup glitch on field updates
+ in TracepointProvider
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-6-david@redhat.com>
+Patchwork-id: 77316
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 05/39] tools/kvm_stat: fix trace setup glitch on field updates in TracepointProvider
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git a183606937489ab5ada2215aa8211374a6b26bd3
+
+commit a183606937489ab5ada2215aa8211374a6b26bd3
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:04 2017 +0100
+
+    tools/kvm_stat: fix trace setup glitch on field updates in TracepointProvider
+
+    Updating the fields of the TracepointProvider does not propagate changes to the
+    tracepoints. This shows when a pid filter is enabled, whereby subsequent
+    extensions of the fields of the Tracepoint provider (e.g. by toggling
+    drilldown) will not modify the tracepoints as required.
+    To reproduce, select a specific process via interactive command 'p', and
+    enable drilldown via 'x' - none of the fields with the braces will appear
+    although they should.
+    The fix will always leave all available fields in the TracepointProvider
+    enabled.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Based-on-text-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 231186a..6207843 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -550,6 +550,7 @@ class TracepointProvider(object):
+     def setup_traces(self):
+         """Creates all event and group objects needed to be able to retrieve
+         data."""
++        fields = self.get_available_fields()
+         if self._pid > 0:
+             # Fetch list of all threads of the monitored pid, as qemu
+             # starts a thread for each vcpu.
+@@ -560,7 +561,7 @@ class TracepointProvider(object):
+ 
+         # The constant is needed as a buffer for python libs, std
+         # streams and other files that the script opens.
+-        newlim = len(groupids) * len(self._fields) + 50
++        newlim = len(groupids) * len(fields) + 50
+         try:
+             softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)
+ 
+@@ -576,7 +577,7 @@ class TracepointProvider(object):
+ 
+         for groupid in groupids:
+             group = Group()
+-            for name in self._fields:
++            for name in fields:
+                 tracepoint = name
+                 tracefilter = None
+                 match = re.match(r'(.*)\((.*)\)', name)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-fix-typo.patch b/SOURCES/kvm-tools-kvm_stat-fix-typo.patch
new file mode 100644
index 0000000..f5bea9f
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-fix-typo.patch
@@ -0,0 +1,48 @@
+From e21fb4a96edba8dfc5edada51d15e604444d9cf9 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:44 +0200
+Subject: [PATCH 39/69] tools/kvm_stat: fix typo
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-19-david@redhat.com>
+Patchwork-id: 77324
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 18/39] tools/kvm_stat: fix typo
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 773bffeeb2f1fca7739516d0a5a814dd14a5cc83
+
+commit 773bffeeb2f1fca7739516d0a5a814dd14a5cc83
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:25 2017 +0200
+
+    tools/kvm_stat: fix typo
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 8f74ed8..904eb62 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -929,7 +929,7 @@ class Tui(object):
+         return self
+ 
+     def __exit__(self, *exception):
+-        """Resets the terminal to its normal state.  Based on curses.wrappre
++        """Resets the terminal to its normal state.  Based on curses.wrapper
+            implementation from the Python standard library."""
+         if self.screen:
+             self.screen.keypad(0)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-fix-undue-use-of-initial-sleeptime.patch b/SOURCES/kvm-tools-kvm_stat-fix-undue-use-of-initial-sleeptime.patch
new file mode 100644
index 0000000..3ea2f6c
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-fix-undue-use-of-initial-sleeptime.patch
@@ -0,0 +1,66 @@
+From d54183dd4ba5e326ebe193815338b9824d5fef56 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:46 +0200
+Subject: [PATCH 41/69] tools/kvm_stat: fix undue use of initial sleeptime
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-21-david@redhat.com>
+Patchwork-id: 77331
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 20/39] tools/kvm_stat: fix undue use of initial sleeptime
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 81468d73b6eb0ed251e7c77f2cc44c0f4edb4d36
+
+commit 81468d73b6eb0ed251e7c77f2cc44c0f4edb4d36
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:27 2017 +0200
+
+    tools/kvm_stat: fix undue use of initial sleeptime
+
+    We should not use the initial sleeptime for any key press that does not
+    switch to a different screen, as that introduces an unaesthetic flicker due
+    to two updates in quick succession.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index b571584..6e29e5b 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1142,14 +1142,12 @@ class Tui(object):
+                 if char == 'x':
+                     self.refresh_header()
+                     self.update_drilldown()
+-                    sleeptime = DELAY_INITIAL
+                 if char == 'q':
+                     break
+                 if char == 'c':
+                     self.stats.fields_filter = DEFAULT_REGEX
+                     self.refresh_header(0)
+                     self.update_pid(0)
+-                    sleeptime = DELAY_INITIAL
+                 if char == 'f':
+                     self.show_filter_selection()
+                     sleeptime = DELAY_INITIAL
+@@ -1162,7 +1160,6 @@ class Tui(object):
+                 if char == 'r':
+                     self.refresh_header()
+                     self.stats.reset()
+-                    sleeptime = DELAY_INITIAL
+             except KeyboardInterrupt:
+                 break
+             except curses.error:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-full-PEP8-compliance.patch b/SOURCES/kvm-tools-kvm_stat-full-PEP8-compliance.patch
new file mode 100644
index 0000000..85c742a
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-full-PEP8-compliance.patch
@@ -0,0 +1,212 @@
+From 5f41d9716a2f46f18ee4bf02c9875f1ae0ba53ee Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:32 +0200
+Subject: [PATCH 27/69] tools/kvm_stat: full PEP8 compliance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-7-david@redhat.com>
+Patchwork-id: 77312
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 06/39] tools/kvm_stat: full PEP8 compliance
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 692c7f6deb553dde2531102cd10ac17ab61438e4
+
+commit 692c7f6deb553dde2531102cd10ac17ab61438e4
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:05 2017 +0100
+
+    tools/kvm_stat: full PEP8 compliance
+
+    Provides all missing empty lines as required for full PEP compliance.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 6207843..5c4f248 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -224,6 +224,7 @@ IOCTL_NUMBERS = {
+     'RESET':       0x00002403,
+ }
+ 
++
+ class Arch(object):
+     """Encapsulates global architecture specific data.
+ 
+@@ -254,12 +255,14 @@ class Arch(object):
+                     return ArchX86(SVM_EXIT_REASONS)
+                 return
+ 
++
+ class ArchX86(Arch):
+     def __init__(self, exit_reasons):
+         self.sc_perf_evt_open = 298
+         self.ioctl_numbers = IOCTL_NUMBERS
+         self.exit_reasons = exit_reasons
+ 
++
+ class ArchPPC(Arch):
+     def __init__(self):
+         self.sc_perf_evt_open = 319
+@@ -274,12 +277,14 @@ class ArchPPC(Arch):
+         self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
+         self.exit_reasons = {}
+ 
++
+ class ArchA64(Arch):
+     def __init__(self):
+         self.sc_perf_evt_open = 241
+         self.ioctl_numbers = IOCTL_NUMBERS
+         self.exit_reasons = AARCH64_EXIT_REASONS
+ 
++
+ class ArchS390(Arch):
+     def __init__(self):
+         self.sc_perf_evt_open = 331
+@@ -341,6 +346,7 @@ def get_filters():
+ libc = ctypes.CDLL('libc.so.6', use_errno=True)
+ syscall = libc.syscall
+ 
++
+ class perf_event_attr(ctypes.Structure):
+     """Struct that holds the necessary data to set up a trace event.
+ 
+@@ -369,6 +375,7 @@ class perf_event_attr(ctypes.Structure):
+         self.size = ctypes.sizeof(self)
+         self.read_format = PERF_FORMAT_GROUP
+ 
++
+ def perf_event_open(attr, pid, cpu, group_fd, flags):
+     """Wrapper for the sys_perf_evt_open() syscall.
+ 
+@@ -394,6 +401,7 @@ PERF_FORMAT_GROUP = 1 << 3
+ PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
+ PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'
+ 
++
+ class Group(object):
+     """Represents a perf event group."""
+ 
+@@ -426,6 +434,7 @@ class Group(object):
+                         struct.unpack(read_format,
+                                       os.read(self.events[0].fd, length))))
+ 
++
+ class Event(object):
+     """Represents a performance event and manages its life cycle."""
+     def __init__(self, name, group, trace_cpu, trace_pid, trace_point,
+@@ -509,6 +518,7 @@ class Event(object):
+         """Resets the count of the trace event in the kernel."""
+         fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
+ 
++
+ class TracepointProvider(object):
+     """Data provider for the stats class.
+ 
+@@ -650,6 +660,7 @@ class TracepointProvider(object):
+                     ret[name] += val
+         return ret
+ 
++
+ class DebugfsProvider(object):
+     """Provides data from the files that KVM creates in the kvm debugfs
+     folder."""
+@@ -719,6 +730,7 @@ class DebugfsProvider(object):
+         except IOError:
+             return 0
+ 
++
+ class Stats(object):
+     """Manages the data providers and the data they provide.
+ 
+@@ -790,6 +802,7 @@ class Stats(object):
+ LABEL_WIDTH = 40
+ NUMBER_WIDTH = 10
+ 
++
+ class Tui(object):
+     """Instruments curses to draw a nice text ui."""
+     def __init__(self, stats):
+@@ -859,6 +872,7 @@ class Tui(object):
+                            len('Current'), 'Current')
+         row = 3
+         stats = self.stats.get()
++
+         def sortkey(x):
+             if stats[x][1]:
+                 return (-stats[x][1], -stats[x][0])
+@@ -966,6 +980,7 @@ class Tui(object):
+             except curses.error:
+                 continue
+ 
++
+ def batch(stats):
+     """Prints statistics in a key, value format."""
+     try:
+@@ -978,13 +993,16 @@ def batch(stats):
+     except KeyboardInterrupt:
+         pass
+ 
++
+ def log(stats):
+     """Prints statistics as reiterating key block, multiple value blocks."""
+     keys = sorted(stats.get().iterkeys())
++
+     def banner():
+         for k in keys:
+             print '%s' % k,
+         print
++
+     def statline():
+         s = stats.get()
+         for k in keys:
+@@ -1002,6 +1020,7 @@ def log(stats):
+         except KeyboardInterrupt:
+             break
+ 
++
+ def get_options():
+     """Returns processed program arguments."""
+     description_text = """
+@@ -1072,6 +1091,7 @@ Requirements:
+     (options, _) = optparser.parse_args(sys.argv)
+     return options
+ 
++
+ def get_providers(options):
+     """Returns a list of data providers depending on the passed options."""
+     providers = []
+@@ -1085,6 +1105,7 @@ def get_providers(options):
+ 
+     return providers
+ 
++
+ def check_access(options):
+     """Exits if the current user can't access all needed directories."""
+     if not os.path.exists('/sys/kernel/debug'):
+@@ -1114,6 +1135,7 @@ def check_access(options):
+ 
+     return options
+ 
++
+ def main():
+     options = get_options()
+     options = check_access(options)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-handle-SIGINT-in-log-and-batch-modes.patch b/SOURCES/kvm-tools-kvm_stat-handle-SIGINT-in-log-and-batch-modes.patch
new file mode 100644
index 0000000..d4fc4ea
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-handle-SIGINT-in-log-and-batch-modes.patch
@@ -0,0 +1,88 @@
+From dada85e20a716597bb06c8684eca7a17a2eb8c5e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:29 +0200
+Subject: [PATCH 24/69] tools/kvm_stat: handle SIGINT in log and batch modes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-4-david@redhat.com>
+Patchwork-id: 77318
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 03/39] tools/kvm_stat: handle SIGINT in log and batch modes
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git dadf1e7839243474b691ca4258bfd2a59e628a5e
+
+commit dadf1e7839243474b691ca4258bfd2a59e628a5e
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:02 2017 +0100
+
+    tools/kvm_stat: handle SIGINT in log and batch modes
+
+    SIGINT causes ugly unhandled exceptions in log and batch mode, which we
+    prevent by catching the exceptions accordingly.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index ef47ad7..14536c0 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -969,12 +969,15 @@ class Tui(object):
+ 
+ def batch(stats):
+     """Prints statistics in a key, value format."""
+-    s = stats.get()
+-    time.sleep(1)
+-    s = stats.get()
+-    for key in sorted(s.keys()):
+-        values = s[key]
+-        print '%-42s%10d%10d' % (key, values[0], values[1])
++    try:
++        s = stats.get()
++        time.sleep(1)
++        s = stats.get()
++        for key in sorted(s.keys()):
++            values = s[key]
++            print '%-42s%10d%10d' % (key, values[0], values[1])
++    except KeyboardInterrupt:
++        pass
+ 
+ def log(stats):
+     """Prints statistics as reiterating key block, multiple value blocks."""
+@@ -991,11 +994,14 @@ def log(stats):
+     line = 0
+     banner_repeat = 20
+     while True:
+-        time.sleep(1)
+-        if line % banner_repeat == 0:
+-            banner()
+-        statline()
+-        line += 1
++        try:
++            time.sleep(1)
++            if line % banner_repeat == 0:
++                banner()
++            statline()
++            line += 1
++        except KeyboardInterrupt:
++            break
+ 
+ def get_options():
+     """Returns processed program arguments."""
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-hide-cursor.patch b/SOURCES/kvm-tools-kvm_stat-hide-cursor.patch
new file mode 100644
index 0000000..6ae9e06
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-hide-cursor.patch
@@ -0,0 +1,62 @@
+From beffa30342dc667526c274e71f135c9863a56e61 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:27 +0200
+Subject: [PATCH 22/69] tools/kvm_stat: hide cursor
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-2-david@redhat.com>
+Patchwork-id: 77309
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 01/39] tools/kvm_stat: hide cursor
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git a0b4e6a0325e325d91901342dd436d917da0ddd6
+
+commit a0b4e6a0325e325d91901342dd436d917da0ddd6
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:00 2017 +0100
+
+    tools/kvm_stat: hide cursor
+
+    When running kvm_stat in interactive mode, the cursor appears at the lower
+    left corner, which looks a bit distracting.
+    This patch hides the cursor by turning it invisible.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-By: Sascha Silbe <silbe@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 581278c..8cc83a3 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -812,6 +812,13 @@ class Tui(object):
+         except:
+             pass
+ 
++        # Hide cursor in extra statement as some monochrome terminals
++        # might support hiding but not colors.
++        try:
++            curses.curs_set(0)
++        except curses.error:
++            pass
++
+         curses.use_default_colors()
+         return self
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-make-heading-look-a-bit-more-like-top.patch b/SOURCES/kvm-tools-kvm_stat-make-heading-look-a-bit-more-like-top.patch
new file mode 100644
index 0000000..5674c24
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-make-heading-look-a-bit-more-like-top.patch
@@ -0,0 +1,51 @@
+From 7f50a8be62efbab70573a4dc1ca3afb14f66960a Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:55 +0200
+Subject: [PATCH 50/69] tools/kvm_stat: make heading look a bit more like 'top'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-30-david@redhat.com>
+Patchwork-id: 77343
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 29/39] tools/kvm_stat: make heading look a bit more like 'top'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git f6d753102a2469ae4ce08ef3e34d170ec583fb50
+
+commit f6d753102a2469ae4ce08ef3e34d170ec583fb50
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:36 2017 +0200
+
+    tools/kvm_stat: make heading look a bit more like 'top'
+
+    Print header in standout font just like the 'top' command does.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 790fbce..35147e4 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -982,7 +982,8 @@ class Tui(object):
+                 regex = regex[:MAX_REGEX_LEN] + '...'
+             self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
+         self.screen.addstr(2, 1, '%-40s %10s%7s %7s' %
+-                           ('Event', 'Total', '%Total', 'Current'))
++                           ('Event', 'Total', '%Total', 'Current'),
++                           curses.A_STANDOUT)
+         self.screen.addstr(4, 1, 'Collecting data...')
+         self.screen.refresh()
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-move-functions-to-corresponding-class.patch b/SOURCES/kvm-tools-kvm_stat-move-functions-to-corresponding-class.patch
new file mode 100644
index 0000000..13e3cbf
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-move-functions-to-corresponding-class.patch
@@ -0,0 +1,516 @@
+From 1dbc0659acce676594060b331eb4d854d26eed0c Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:52 +0200
+Subject: [PATCH 47/69] tools/kvm_stat: move functions to corresponding classes
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-27-david@redhat.com>
+Patchwork-id: 77334
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 26/39] tools/kvm_stat: move functions to corresponding classes
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 099a2dfc674e3333bd4ff5e5b106ccd788aa46d7
+
+commit 099a2dfc674e3333bd4ff5e5b106ccd788aa46d7
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:33 2017 +0200
+
+    tools/kvm_stat: move functions to corresponding classes
+
+    Quite a few of the functions are used only in a single class. Moving
+    functions accordingly to improve the overall structure.
+    Furthermore, introduce a base class for the providers, which might also
+    come handy for future extensions.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 327 ++++++++++++++++++++++++++-------------------------
+ 1 file changed, 165 insertions(+), 162 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index b8522d2..f81ed20 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -295,121 +295,6 @@ class ArchS390(Arch):
+ ARCH = Arch.get_arch()
+ 
+ 
+-def is_field_wanted(fields_filter, field):
+-    """Indicate whether field is valid according to fields_filter."""
+-    if not fields_filter:
+-        return True
+-    return re.match(fields_filter, field) is not None
+-
+-
+-def walkdir(path):
+-    """Returns os.walk() data for specified directory.
+-
+-    As it is only a wrapper it returns the same 3-tuple of (dirpath,
+-    dirnames, filenames).
+-    """
+-    return next(os.walk(path))
+-
+-
+-def parse_int_list(list_string):
+-    """Returns an int list from a string of comma separated integers and
+-    integer ranges."""
+-    integers = []
+-    members = list_string.split(',')
+-
+-    for member in members:
+-        if '-' not in member:
+-            integers.append(int(member))
+-        else:
+-            int_range = member.split('-')
+-            integers.extend(range(int(int_range[0]),
+-                                  int(int_range[1]) + 1))
+-
+-    return integers
+-
+-
+-def get_pid_from_gname(gname):
+-    """Fuzzy function to convert guest name to QEMU process pid.
+-
+-    Returns a list of potential pids, can be empty if no match found.
+-    Throws an exception on processing errors.
+-
+-    """
+-    pids = []
+-    try:
+-        child = subprocess.Popen(['ps', '-A', '--format', 'pid,args'],
+-                                 stdout=subprocess.PIPE)
+-    except:
+-        raise Exception
+-    for line in child.stdout:
+-        line = line.lstrip().split(' ', 1)
+-        # perform a sanity check before calling the more expensive
+-        # function to possibly extract the guest name
+-        if ' -name ' in line[1] and gname == get_gname_from_pid(line[0]):
+-            pids.append(int(line[0]))
+-    child.stdout.close()
+-
+-    return pids
+-
+-
+-def get_gname_from_pid(pid):
+-    """Returns the guest name for a QEMU process pid.
+-
+-    Extracts the guest name from the QEMU comma line by processing the '-name'
+-    option. Will also handle names specified out of sequence.
+-
+-    """
+-    name = ''
+-    try:
+-        line = open('/proc/{}/cmdline'.format(pid), 'rb').read().split('\0')
+-        parms = line[line.index('-name') + 1].split(',')
+-        while '' in parms:
+-            # commas are escaped (i.e. ',,'), hence e.g. 'foo,bar' results in
+-            # ['foo', '', 'bar'], which we revert here
+-            idx = parms.index('')
+-            parms[idx - 1] += ',' + parms[idx + 1]
+-            del parms[idx:idx+2]
+-        # the '-name' switch allows for two ways to specify the guest name,
+-        # where the plain name overrides the name specified via 'guest='
+-        for arg in parms:
+-            if '=' not in arg:
+-                name = arg
+-                break
+-            if arg[:6] == 'guest=':
+-                name = arg[6:]
+-    except (ValueError, IOError, IndexError):
+-        pass
+-
+-    return name
+-
+-
+-def get_online_cpus():
+-    """Returns a list of cpu id integers."""
+-    with open('/sys/devices/system/cpu/online') as cpu_list:
+-        cpu_string = cpu_list.readline()
+-        return parse_int_list(cpu_string)
+-
+-
+-def get_filters():
+-    """Returns a dict of trace events, their filter ids and
+-    the values that can be filtered.
+-
+-    Trace events can be filtered for special values by setting a
+-    filter string via an ioctl. The string normally has the format
+-    identifier==value. For each filter a new event will be created, to
+-    be able to distinguish the events.
+-
+-    """
+-    filters = {}
+-    filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
+-    if ARCH.exit_reasons:
+-        filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
+-    return filters
+-
+-libc = ctypes.CDLL('libc.so.6', use_errno=True)
+-syscall = libc.syscall
+-
+-
+ class perf_event_attr(ctypes.Structure):
+     """Struct that holds the necessary data to set up a trace event.
+ 
+@@ -439,25 +324,6 @@ class perf_event_attr(ctypes.Structure):
+         self.read_format = PERF_FORMAT_GROUP
+ 
+ 
+-def perf_event_open(attr, pid, cpu, group_fd, flags):
+-    """Wrapper for the sys_perf_evt_open() syscall.
+-
+-    Used to set up performance events, returns a file descriptor or -1
+-    on error.
+-
+-    Attributes are:
+-    - syscall number
+-    - struct perf_event_attr *
+-    - pid or -1 to monitor all pids
+-    - cpu number or -1 to monitor all cpus
+-    - The file descriptor of the group leader or -1 to create a group.
+-    - flags
+-
+-    """
+-    return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
+-                   ctypes.c_int(pid), ctypes.c_int(cpu),
+-                   ctypes.c_int(group_fd), ctypes.c_long(flags))
+-
+ PERF_TYPE_TRACEPOINT = 2
+ PERF_FORMAT_GROUP = 1 << 3
+ 
+@@ -502,6 +368,8 @@ class Event(object):
+     """Represents a performance event and manages its life cycle."""
+     def __init__(self, name, group, trace_cpu, trace_pid, trace_point,
+                  trace_filter, trace_set='kvm'):
++        self.libc = ctypes.CDLL('libc.so.6', use_errno=True)
++        self.syscall = self.libc.syscall
+         self.name = name
+         self.fd = None
+         self.setup_event(group, trace_cpu, trace_pid, trace_point,
+@@ -518,6 +386,25 @@ class Event(object):
+         if self.fd:
+             os.close(self.fd)
+ 
++    def perf_event_open(self, attr, pid, cpu, group_fd, flags):
++        """Wrapper for the sys_perf_evt_open() syscall.
++
++        Used to set up performance events, returns a file descriptor or -1
++        on error.
++
++        Attributes are:
++        - syscall number
++        - struct perf_event_attr *
++        - pid or -1 to monitor all pids
++        - cpu number or -1 to monitor all cpus
++        - The file descriptor of the group leader or -1 to create a group.
++        - flags
++
++        """
++        return self.syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
++                            ctypes.c_int(pid), ctypes.c_int(cpu),
++                            ctypes.c_int(group_fd), ctypes.c_long(flags))
++
+     def setup_event_attribute(self, trace_set, trace_point):
+         """Returns an initialized ctype perf_event_attr struct."""
+ 
+@@ -546,8 +433,8 @@ class Event(object):
+         if group.events:
+             group_leader = group.events[0].fd
+ 
+-        fd = perf_event_open(event_attr, trace_pid,
+-                             trace_cpu, group_leader, 0)
++        fd = self.perf_event_open(event_attr, trace_pid,
++                                  trace_cpu, group_leader, 0)
+         if fd == -1:
+             err = ctypes.get_errno()
+             raise OSError(err, os.strerror(err),
+@@ -582,7 +469,26 @@ class Event(object):
+         fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
+ 
+ 
+-class TracepointProvider(object):
++class Provider(object):
++    """Encapsulates functionalities used by all providers."""
++    @staticmethod
++    def is_field_wanted(fields_filter, field):
++        """Indicate whether field is valid according to fields_filter."""
++        if not fields_filter:
++            return True
++        return re.match(fields_filter, field) is not None
++
++    @staticmethod
++    def walkdir(path):
++        """Returns os.walk() data for specified directory.
++
++        As it is only a wrapper it returns the same 3-tuple of (dirpath,
++        dirnames, filenames).
++        """
++        return next(os.walk(path))
++
++
++class TracepointProvider(Provider):
+     """Data provider for the stats class.
+ 
+     Manages the events/groups from which it acquires its data.
+@@ -590,10 +496,27 @@ class TracepointProvider(object):
+     """
+     def __init__(self, pid, fields_filter):
+         self.group_leaders = []
+-        self.filters = get_filters()
++        self.filters = self.get_filters()
+         self.update_fields(fields_filter)
+         self.pid = pid
+ 
++    @staticmethod
++    def get_filters():
++        """Returns a dict of trace events, their filter ids and
++        the values that can be filtered.
++
++        Trace events can be filtered for special values by setting a
++        filter string via an ioctl. The string normally has the format
++        identifier==value. For each filter a new event will be created, to
++        be able to distinguish the events.
++
++        """
++        filters = {}
++        filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
++        if ARCH.exit_reasons:
++            filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
++        return filters
++
+     def get_available_fields(self):
+         """Returns a list of available event's of format 'event name(filter
+         name)'.
+@@ -610,7 +533,7 @@ class TracepointProvider(object):
+ 
+         """
+         path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
+-        fields = walkdir(path)[1]
++        fields = self.walkdir(path)[1]
+         extra = []
+         for field in fields:
+             if field in self.filters:
+@@ -623,7 +546,30 @@ class TracepointProvider(object):
+     def update_fields(self, fields_filter):
+         """Refresh fields, applying fields_filter"""
+         self._fields = [field for field in self.get_available_fields()
+-                        if is_field_wanted(fields_filter, field)]
++                        if self.is_field_wanted(fields_filter, field)]
++
++    @staticmethod
++    def get_online_cpus():
++        """Returns a list of cpu id integers."""
++        def parse_int_list(list_string):
++            """Returns an int list from a string of comma separated integers and
++            integer ranges."""
++            integers = []
++            members = list_string.split(',')
++
++            for member in members:
++                if '-' not in member:
++                    integers.append(int(member))
++                else:
++                    int_range = member.split('-')
++                    integers.extend(range(int(int_range[0]),
++                                          int(int_range[1]) + 1))
++
++            return integers
++
++        with open('/sys/devices/system/cpu/online') as cpu_list:
++            cpu_string = cpu_list.readline()
++            return parse_int_list(cpu_string)
+ 
+     def setup_traces(self):
+         """Creates all event and group objects needed to be able to retrieve
+@@ -633,9 +579,9 @@ class TracepointProvider(object):
+             # Fetch list of all threads of the monitored pid, as qemu
+             # starts a thread for each vcpu.
+             path = os.path.join('/proc', str(self._pid), 'task')
+-            groupids = walkdir(path)[1]
++            groupids = self.walkdir(path)[1]
+         else:
+-            groupids = get_online_cpus()
++            groupids = self.get_online_cpus()
+ 
+         # The constant is needed as a buffer for python libs, std
+         # streams and other files that the script opens.
+@@ -732,7 +678,7 @@ class TracepointProvider(object):
+                 event.reset()
+ 
+ 
+-class DebugfsProvider(object):
++class DebugfsProvider(Provider):
+     """Provides data from the files that KVM creates in the kvm debugfs
+     folder."""
+     def __init__(self, pid, fields_filter):
+@@ -748,12 +694,12 @@ class DebugfsProvider(object):
+         The fields are all available KVM debugfs files
+ 
+         """
+-        return walkdir(PATH_DEBUGFS_KVM)[2]
++        return self.walkdir(PATH_DEBUGFS_KVM)[2]
+ 
+     def update_fields(self, fields_filter):
+         """Refresh fields, applying fields_filter"""
+         self._fields = [field for field in self.get_available_fields()
+-                        if is_field_wanted(fields_filter, field)]
++                        if self.is_field_wanted(fields_filter, field)]
+ 
+     @property
+     def fields(self):
+@@ -772,7 +718,7 @@ class DebugfsProvider(object):
+     def pid(self, pid):
+         self._pid = pid
+         if pid != 0:
+-            vms = walkdir(PATH_DEBUGFS_KVM)[1]
++            vms = self.walkdir(PATH_DEBUGFS_KVM)[1]
+             if len(vms) == 0:
+                 self.do_read = False
+ 
+@@ -834,11 +780,23 @@ class Stats(object):
+ 
+     """
+     def __init__(self, options):
+-        self.providers = get_providers(options)
++        self.providers = self.get_providers(options)
+         self._pid_filter = options.pid
+         self._fields_filter = options.fields
+         self.values = {}
+ 
++    @staticmethod
++    def get_providers(options):
++        """Returns a list of data providers depending on the passed options."""
++        providers = []
++
++        if options.debugfs:
++            providers.append(DebugfsProvider(options.pid, options.fields))
++        if options.tracepoints or not providers:
++            providers.append(TracepointProvider(options.pid, options.fields))
++
++        return providers
++
+     def update_provider_filters(self):
+         """Propagates fields filters to providers."""
+         # As we reset the counters when updating the fields we can
+@@ -933,6 +891,63 @@ class Tui(object):
+             curses.nocbreak()
+             curses.endwin()
+ 
++    @staticmethod
++    def get_pid_from_gname(gname):
++        """Fuzzy function to convert guest name to QEMU process pid.
++
++        Returns a list of potential pids, can be empty if no match found.
++        Throws an exception on processing errors.
++
++        """
++        pids = []
++        try:
++            child = subprocess.Popen(['ps', '-A', '--format', 'pid,args'],
++                                     stdout=subprocess.PIPE)
++        except:
++            raise Exception
++        for line in child.stdout:
++            line = line.lstrip().split(' ', 1)
++            # perform a sanity check before calling the more expensive
++            # function to possibly extract the guest name
++            if (' -name ' in line[1] and
++                    gname == self.get_gname_from_pid(line[0])):
++                pids.append(int(line[0]))
++        child.stdout.close()
++
++        return pids
++
++    @staticmethod
++    def get_gname_from_pid(pid):
++        """Returns the guest name for a QEMU process pid.
++
++        Extracts the guest name from the QEMU comma line by processing the
++        '-name' option. Will also handle names specified out of sequence.
++
++        """
++        name = ''
++        try:
++            line = open('/proc/{}/cmdline'
++                        .format(pid), 'rb').read().split('\0')
++            parms = line[line.index('-name') + 1].split(',')
++            while '' in parms:
++                # commas are escaped (i.e. ',,'), hence e.g. 'foo,bar' results
++                # in # ['foo', '', 'bar'], which we revert here
++                idx = parms.index('')
++                parms[idx - 1] += ',' + parms[idx + 1]
++                del parms[idx:idx+2]
++            # the '-name' switch allows for two ways to specify the guest name,
++            # where the plain name overrides the name specified via 'guest='
++            for arg in parms:
++                if '=' not in arg:
++                    name = arg
++                    break
++                if arg[:6] == 'guest=':
++                    name = arg[6:]
++        except (ValueError, IOError, IndexError):
++            pass
++
++        return name
++
+     def update_drilldown(self):
+         """Sets or removes a filter that only allows fields without braces."""
+         if not self.stats.fields_filter:
+@@ -950,7 +965,7 @@ class Tui(object):
+         if pid is None:
+             pid = self.stats.pid_filter
+         self.screen.erase()
+-        gname = get_gname_from_pid(pid)
++        gname = self.get_gname_from_pid(pid)
+         if gname:
+             gname = ('({})'.format(gname[:MAX_GUEST_NAME_LEN] + '...'
+                                    if len(gname) > MAX_GUEST_NAME_LEN
+@@ -1096,7 +1111,7 @@ class Tui(object):
+             else:
+                 pids = []
+                 try:
+-                    pids = get_pid_from_gname(gname)
++                    pids = self.get_pid_from_gname(gname)
+                 except:
+                     msg = '"' + gname + '": Internal error while searching, ' \
+                           'use pid filter instead'
+@@ -1229,7 +1244,7 @@ Press any other key to refresh statistics immediately.
+ 
+     def cb_guest_to_pid(option, opt, val, parser):
+         try:
+-            pids = get_pid_from_gname(val)
++            pids = Tui.get_pid_from_gname(val)
+         except:
+             raise optparse.OptionValueError('Error while searching for guest '
+                                             '"{}", use "-p" to specify a pid '
+@@ -1294,18 +1309,6 @@ Press any other key to refresh statistics immediately.
+     return options
+ 
+ 
+-def get_providers(options):
+-    """Returns a list of data providers depending on the passed options."""
+-    providers = []
+-
+-    if options.debugfs:
+-        providers.append(DebugfsProvider(options.pid, options.fields))
+-    if options.tracepoints or not providers:
+-        providers.append(TracepointProvider(options.pid, options.fields))
+-
+-    return providers
+-
+-
+ def check_access(options):
+     """Exits if the current user can't access all needed directories."""
+     if not os.path.exists('/sys/kernel/debug'):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-print-error-messages-on-faulty-pid-fi.patch b/SOURCES/kvm-tools-kvm_stat-print-error-messages-on-faulty-pid-fi.patch
new file mode 100644
index 0000000..57c415a
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-print-error-messages-on-faulty-pid-fi.patch
@@ -0,0 +1,79 @@
+From 05cc1c1aab959dde7801cabe184c5f4b287835b6 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:37 +0200
+Subject: [PATCH 32/69] tools/kvm_stat: print error messages on faulty pid
+ filter input
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-12-david@redhat.com>
+Patchwork-id: 77321
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 11/39] tools/kvm_stat: print error messages on faulty pid filter input
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 0152c20f0400498774ae56067f8076cef312abc7
+
+commit 0152c20f0400498774ae56067f8076cef312abc7
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:10 2017 +0100
+
+    tools/kvm_stat: print error messages on faulty pid filter input
+
+    Print helpful messages in case users enter invalid input or invalid pids in
+    the interactive pid filter dialogue.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 9e9eb98..ced0cb9 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -976,6 +976,7 @@ class Tui(object):
+         Asks for a pid until a valid pid or 0 has been entered.
+ 
+         """
++        msg = ''
+         while True:
+             self.screen.erase()
+             self.screen.addstr(0, 0,
+@@ -984,6 +985,7 @@ class Tui(object):
+             self.screen.addstr(1, 0,
+                                'This might limit the shown data to the trace '
+                                'statistics.')
++            self.screen.addstr(5, 0, msg)
+ 
+             curses.echo()
+             self.screen.addstr(3, 0, "Pid [0 or pid]: ")
+@@ -995,6 +997,7 @@ class Tui(object):
+                     pid = int(pid)
+                     if pid != 0 and not os.path.isdir(os.path.join('/proc/',
+                                                                    str(pid))):
++                        msg = '"' + str(pid) + '": Not a running process'
+                         continue
+                 else:
+                     pid = 0
+@@ -1003,6 +1006,7 @@ class Tui(object):
+                 break
+ 
+             except ValueError:
++                msg = '"' + str(pid) + '": Not a valid pid'
+                 continue
+ 
+     def show_stats(self):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-reduce-perceived-idle-time-on-filter-.patch b/SOURCES/kvm-tools-kvm_stat-reduce-perceived-idle-time-on-filter-.patch
new file mode 100644
index 0000000..3ca2a8b
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-reduce-perceived-idle-time-on-filter-.patch
@@ -0,0 +1,161 @@
+From 5bf653923c85a01b85fe801b3a752938424ce659 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:33 +0200
+Subject: [PATCH 28/69] tools/kvm_stat: reduce perceived idle time on filter
+ updates
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-8-david@redhat.com>
+Patchwork-id: 77314
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 07/39] tools/kvm_stat: reduce perceived idle time on filter updates
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 184b2d23b057b35fba7fd4049962a897ef0e3f9d
+
+commit 184b2d23b057b35fba7fd4049962a897ef0e3f9d
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:06 2017 +0100
+
+    tools/kvm_stat: reduce perceived idle time on filter updates
+
+    Whenever a user adds a filter, we
+    * redraw the header immediately for a snappy response
+    * print a message indicating to the user that we're busy while the
+      noticeable delay induced by updating all of the stats objects takes place
+    * update the statistics ASAP (i.e. after 0.25s instead of 3s) to be
+      consistent with behavior on startup
+    To do so, we split the Tui's refresh() method to allow for drawing header
+    and stats separately, and trigger a header refresh whenever we are about
+    to do something that takes a while - like updating filters.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 48 ++++++++++++++++++++++++++++++------------------
+ 1 file changed, 30 insertions(+), 18 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 5c4f248..3e60d93 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -801,6 +801,8 @@ class Stats(object):
+ 
+ LABEL_WIDTH = 40
+ NUMBER_WIDTH = 10
++DELAY_INITIAL = 0.25
++DELAY_REGULAR = 3.0
+ 
+ 
+ class Tui(object):
+@@ -856,13 +858,14 @@ class Tui(object):
+         """Propagates pid selection to stats object."""
+         self.stats.pid_filter = pid
+ 
+-    def refresh(self, sleeptime):
+-        """Refreshes on-screen data."""
++    def refresh_header(self, pid=None):
++        """Refreshes the header."""
++        if pid is None:
++            pid = self.stats.pid_filter
+         self.screen.erase()
+-        if self.stats.pid_filter > 0:
++        if pid > 0:
+             self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
+-                               .format(self.stats.pid_filter),
+-                               curses.A_BOLD)
++                               .format(pid), curses.A_BOLD)
+         else:
+             self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
+         self.screen.addstr(2, 1, 'Event')
+@@ -870,7 +873,13 @@ class Tui(object):
+                            len('Total'), 'Total')
+         self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
+                            len('Current'), 'Current')
++        self.screen.addstr(4, 1, 'Collecting data...')
++        self.screen.refresh()
++
++    def refresh_body(self, sleeptime):
+         row = 3
++        self.screen.move(row, 0)
++        self.screen.clrtobot()
+         stats = self.stats.get()
+ 
+         def sortkey(x):
+@@ -914,10 +923,12 @@ class Tui(object):
+             regex = self.screen.getstr()
+             curses.noecho()
+             if len(regex) == 0:
++                self.refresh_header()
+                 return
+             try:
+                 re.compile(regex)
+                 self.stats.fields_filter = regex
++                self.refresh_header()
+                 return
+             except re.error:
+                 continue
+@@ -944,37 +955,38 @@ class Tui(object):
+ 
+             try:
+                 pid = int(pid)
+-
+-                if pid == 0:
+-                    self.update_pid(pid)
+-                    break
+-                else:
+-                    if not os.path.isdir(os.path.join('/proc/', str(pid))):
+-                        continue
+-                    else:
+-                        self.update_pid(pid)
+-                        break
++                if pid != 0 and not os.path.isdir(os.path.join('/proc/',
++                                                               str(pid))):
++                    continue
++                self.refresh_header(pid)
++                self.update_pid(pid)
++                break
+ 
+             except ValueError:
+                 continue
+ 
+     def show_stats(self):
+         """Refreshes the screen and processes user input."""
+-        sleeptime = 0.25
++        sleeptime = DELAY_INITIAL
++        self.refresh_header()
+         while True:
+-            self.refresh(sleeptime)
++            self.refresh_body(sleeptime)
+             curses.halfdelay(int(sleeptime * 10))
+-            sleeptime = 3.0
++            sleeptime = DELAY_REGULAR
+             try:
+                 char = self.screen.getkey()
+                 if char == 'x':
++                    self.refresh_header()
+                     self.update_drilldown()
++                    sleeptime = DELAY_INITIAL
+                 if char == 'q':
+                     break
+                 if char == 'f':
+                     self.show_filter_selection()
++                    sleeptime = DELAY_INITIAL
+                 if char == 'p':
+                     self.show_vm_selection()
++                    sleeptime = DELAY_INITIAL
+             except KeyboardInterrupt:
+                 break
+             except curses.error:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-remove-extra-statement.patch b/SOURCES/kvm-tools-kvm_stat-remove-extra-statement.patch
new file mode 100644
index 0000000..6d19276
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-remove-extra-statement.patch
@@ -0,0 +1,47 @@
+From 92d06e843c4d105175e2e1961f94ce879f84630f Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:50 +0200
+Subject: [PATCH 45/69] tools/kvm_stat: remove extra statement
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-25-david@redhat.com>
+Patchwork-id: 77332
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 24/39] tools/kvm_stat: remove extra statement
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 5e3823a49c50d70cc6b92808c262a43cf3505f3c
+
+commit 5e3823a49c50d70cc6b92808c262a43cf3505f3c
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:31 2017 +0200
+
+    tools/kvm_stat: remove extra statement
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 1b8626b..e38791d 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1066,7 +1066,6 @@ class Tui(object):
+ 
+             except ValueError:
+                 msg = '"' + str(pid) + '": Not a valid pid'
+-                continue
+ 
+     def show_vm_selection_by_guest_name(self):
+         """Draws guest selection mask.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-remove-pid-filter-on-empty-input.patch b/SOURCES/kvm-tools-kvm_stat-remove-pid-filter-on-empty-input.patch
new file mode 100644
index 0000000..0b9a4d3
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-remove-pid-filter-on-empty-input.patch
@@ -0,0 +1,65 @@
+From 66f2e8203e1d29f8ec656f5e333dbc1f13229f9f Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:36 +0200
+Subject: [PATCH 31/69] tools/kvm_stat: remove pid filter on empty input
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-11-david@redhat.com>
+Patchwork-id: 77320
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 10/39] tools/kvm_stat: remove pid filter on empty input
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git be03ea3b77387db36617d71d60ee182a866fb9cd
+
+commit be03ea3b77387db36617d71d60ee182a866fb9cd
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:09 2017 +0100
+
+    tools/kvm_stat: remove pid filter on empty input
+
+    Improve consistency in the interactive dialogue for pid filtering by
+    removing any filters on empty input (in addition to entering 0).
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 95ffa9a..9e9eb98 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -991,10 +991,13 @@ class Tui(object):
+             curses.noecho()
+ 
+             try:
+-                pid = int(pid)
+-                if pid != 0 and not os.path.isdir(os.path.join('/proc/',
+-                                                               str(pid))):
+-                    continue
++                if len(pid) > 0:
++                    pid = int(pid)
++                    if pid != 0 and not os.path.isdir(os.path.join('/proc/',
++                                                                   str(pid))):
++                        continue
++                else:
++                    pid = 0
+                 self.refresh_header(pid)
+                 self.update_pid(pid)
+                 break
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-remove-regex-filter-on-empty-input.patch b/SOURCES/kvm-tools-kvm_stat-remove-regex-filter-on-empty-input.patch
new file mode 100644
index 0000000..2e71708
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-remove-regex-filter-on-empty-input.patch
@@ -0,0 +1,57 @@
+From 3c7dae7507abb6ebe8c2dd9a4ef76e55135c8acd Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:39 +0200
+Subject: [PATCH 34/69] tools/kvm_stat: remove regex filter on empty input
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-14-david@redhat.com>
+Patchwork-id: 77322
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 13/39] tools/kvm_stat: remove regex filter on empty input
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 645c1728a9d33d78028d93a2ed770f51df0a92c6
+
+commit 645c1728a9d33d78028d93a2ed770f51df0a92c6
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Fri Mar 10 13:40:12 2017 +0100
+
+    tools/kvm_stat: remove regex filter on empty input
+
+    Behavior on empty/0 input for regex and pid filtering was inconsistent, as
+    the former would keep the current filter, while the latter would (naturally)
+    remove any pid filtering.
+    Make things consistent by falling back to the default filter on empty input
+    for the regex filter dialogue.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
+    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index af70717..f2a868b 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -966,6 +966,7 @@ class Tui(object):
+             regex = self.screen.getstr()
+             curses.noecho()
+             if len(regex) == 0:
++                self.stats.fields_filter = r'^[^\(]*$'
+                 self.refresh_header()
+                 return
+             try:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-remove-unnecessary-header-redraws.patch b/SOURCES/kvm-tools-kvm_stat-remove-unnecessary-header-redraws.patch
new file mode 100644
index 0000000..b7bc8a6
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-remove-unnecessary-header-redraws.patch
@@ -0,0 +1,58 @@
+From 6514729674c1054580cd85feca527740f5476813 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:47 +0200
+Subject: [PATCH 42/69] tools/kvm_stat: remove unnecessary header redraws
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-22-david@redhat.com>
+Patchwork-id: 77327
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 21/39] tools/kvm_stat: remove unnecessary header redraws
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 2da9d4aaa7348fc13374d7398c9c7027b0a9e2cb
+
+commit 2da9d4aaa7348fc13374d7398c9c7027b0a9e2cb
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:28 2017 +0200
+
+    tools/kvm_stat: remove unnecessary header redraws
+
+    Certain interactive commands will not modify any information displayed in
+    the header, hence we can skip them.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 6e29e5b..d2526b6 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1140,7 +1140,6 @@ class Tui(object):
+             try:
+                 char = self.screen.getkey()
+                 if char == 'x':
+-                    self.refresh_header()
+                     self.update_drilldown()
+                 if char == 'q':
+                     break
+@@ -1158,7 +1157,6 @@ class Tui(object):
+                     self.show_vm_selection_by_pid()
+                     sleeptime = DELAY_INITIAL
+                 if char == 'r':
+-                    self.refresh_header()
+                     self.stats.reset()
+             except KeyboardInterrupt:
+                 break
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-removed-unused-function.patch b/SOURCES/kvm-tools-kvm_stat-removed-unused-function.patch
new file mode 100644
index 0000000..ffadfb6
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-removed-unused-function.patch
@@ -0,0 +1,52 @@
+From 35c050e4fdf7eca9ede714377dc427203cc9fd1f Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:49 +0200
+Subject: [PATCH 44/69] tools/kvm_stat: removed unused function
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-24-david@redhat.com>
+Patchwork-id: 77337
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 23/39] tools/kvm_stat: simplify line print logic
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 42a947b77b00da8fb1c9b1350eaa85fd3d53bacb
+
+commit 42a947b77b00da8fb1c9b1350eaa85fd3d53bacb
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:30 2017 +0200
+
+    tools/kvm_stat: removed unused function
+
+    Function available_fields() is not used in any place.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index a527b2f..1b8626b 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -671,9 +671,6 @@ class TracepointProvider(object):
+ 
+             self.group_leaders.append(group)
+ 
+-    def available_fields(self):
+-        return self.get_available_fields()
+-
+     @property
+     def fields(self):
+         return self._fields
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-rename-Current-column-to-CurAvg-s.patch b/SOURCES/kvm-tools-kvm_stat-rename-Current-column-to-CurAvg-s.patch
new file mode 100644
index 0000000..1dd883f
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-rename-Current-column-to-CurAvg-s.patch
@@ -0,0 +1,64 @@
+From 8ba2fd89d16cb721110ecff6e95b6eca0a2325f9 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:56 +0200
+Subject: [PATCH 51/69] tools/kvm_stat: rename 'Current' column to 'CurAvg/s'
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-31-david@redhat.com>
+Patchwork-id: 77341
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 30/39] tools/kvm_stat: rename 'Current' column to 'CurAvg/s'
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 38e89c37a1e05e6e16af582b980534abda29a4d9
+
+commit 38e89c37a1e05e6e16af582b980534abda29a4d9
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:37 2017 +0200
+
+    tools/kvm_stat: rename 'Current' column to 'CurAvg/s'
+
+    'Current' can be misleading as it doesn't tell whether this is the amount
+    of events in the last interval or the current average per second.
+    Note that this necessitates widening the respective column by one more
+    character.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index 35147e4..a9e7ea6 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -981,8 +981,8 @@ class Tui(object):
+             if len(regex) > MAX_REGEX_LEN:
+                 regex = regex[:MAX_REGEX_LEN] + '...'
+             self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
+-        self.screen.addstr(2, 1, '%-40s %10s%7s %7s' %
+-                           ('Event', 'Total', '%Total', 'Current'),
++        self.screen.addstr(2, 1, '%-40s %10s%7s %8s' %
++                           ('Event', 'Total', '%Total', 'CurAvg/s'),
+                            curses.A_STANDOUT)
+         self.screen.addstr(4, 1, 'Collecting data...')
+         self.screen.refresh()
+@@ -1010,7 +1010,7 @@ class Tui(object):
+                 break
+             if values[0] is not None:
+                 cur = int(round(values[1] / sleeptime)) if values[1] else ''
+-                self.screen.addstr(row, 1, '%-40s %10d%7.1f %7s' %
++                self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' %
+                                    (key, values[0], values[0] * 100 / total,
+                                     cur))
+             row += 1
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-show-cursor-in-selection-screens.patch b/SOURCES/kvm-tools-kvm_stat-show-cursor-in-selection-screens.patch
new file mode 100644
index 0000000..876869a
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-show-cursor-in-selection-screens.patch
@@ -0,0 +1,62 @@
+From bf53d773722b8790858a6415540c5011bd25fe8c Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:53 +0200
+Subject: [PATCH 48/69] tools/kvm_stat: show cursor in selection screens
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-28-david@redhat.com>
+Patchwork-id: 77335
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 27/39] tools/kvm_stat: show cursor in selection screens
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 62d1b6cc24d0dedde89e6a39aae1711270aee1c9
+
+commit 62d1b6cc24d0dedde89e6a39aae1711270aee1c9
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:34 2017 +0200
+
+    tools/kvm_stat: show cursor in selection screens
+
+    Show the cursor in the interactive screens to specify pid, filter or guest
+    name as an orientation for the user.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index f81ed20..53dcd40 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1148,13 +1148,19 @@ class Tui(object):
+                     self.refresh_header(0)
+                     self.update_pid(0)
+                 if char == 'f':
++                    curses.curs_set(1)
+                     self.show_filter_selection()
++                    curses.curs_set(0)
+                     sleeptime = DELAY_INITIAL
+                 if char == 'g':
++                    curses.curs_set(1)
+                     self.show_vm_selection_by_guest_name()
++                    curses.curs_set(0)
+                     sleeptime = DELAY_INITIAL
+                 if char == 'p':
++                    curses.curs_set(1)
+                     self.show_vm_selection_by_pid()
++                    curses.curs_set(0)
+                     sleeptime = DELAY_INITIAL
+                 if char == 'r':
+                     self.stats.reset()
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-simplify-initializers.patch b/SOURCES/kvm-tools-kvm_stat-simplify-initializers.patch
new file mode 100644
index 0000000..ee8ff2e
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-simplify-initializers.patch
@@ -0,0 +1,227 @@
+From d0ced131bf9b63e3197d5f997e6fe796df69ccec Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:51 +0200
+Subject: [PATCH 46/69] tools/kvm_stat: simplify initializers
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-26-david@redhat.com>
+Patchwork-id: 77333
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 25/39] tools/kvm_stat: simplify initializers
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git c469117df05955901d2950b6130770e526b1dbf4
+
+commit c469117df05955901d2950b6130770e526b1dbf4
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:32 2017 +0200
+
+    tools/kvm_stat: simplify initializers
+
+    Simplify a couple of initialization routines:
+    * TracepointProvider and DebugfsProvider: Pass pid into __init__() instead
+      of switching to the requested value in an extra call after initializing
+      to the default first.
+    * Pass a single options object into Stats.__init__(), delaying options
+      evaluation accordingly, instead of evaluating options first and passing
+      several parts of the options object to Stats.__init__() individually.
+    * Eliminate Stats.update_provider_pid(), since this 2-line function is now
+      used in a single place only.
+    * Remove extra call to update_drilldown() in Tui.__init__() by getting the
+      value of options.fields right initially when parsing options.
+    * Simplify get_providers() logic.
+    * Avoid duplicate fields initialization by handling it once in the
+      providers' __init__() methods.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 74 +++++++++++++++++++++++++---------------------------
+ 1 file changed, 36 insertions(+), 38 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index e38791d..b8522d2 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -295,6 +295,13 @@ class ArchS390(Arch):
+ ARCH = Arch.get_arch()
+ 
+ 
++def is_field_wanted(fields_filter, field):
++    """Indicate whether field is valid according to fields_filter."""
++    if not fields_filter:
++        return True
++    return re.match(fields_filter, field) is not None
++
++
+ def walkdir(path):
+     """Returns os.walk() data for specified directory.
+ 
+@@ -581,11 +588,11 @@ class TracepointProvider(object):
+     Manages the events/groups from which it acquires its data.
+ 
+     """
+-    def __init__(self):
++    def __init__(self, pid, fields_filter):
+         self.group_leaders = []
+         self.filters = get_filters()
+-        self._fields = self.get_available_fields()
+-        self._pid = 0
++        self.update_fields(fields_filter)
++        self.pid = pid
+ 
+     def get_available_fields(self):
+         """Returns a list of available event's of format 'event name(filter
+@@ -613,6 +620,11 @@ class TracepointProvider(object):
+         fields += extra
+         return fields
+ 
++    def update_fields(self, fields_filter):
++        """Refresh fields, applying fields_filter"""
++        self._fields = [field for field in self.get_available_fields()
++                        if is_field_wanted(fields_filter, field)]
++
+     def setup_traces(self):
+         """Creates all event and group objects needed to be able to retrieve
+         data."""
+@@ -723,13 +735,12 @@ class TracepointProvider(object):
+ class DebugfsProvider(object):
+     """Provides data from the files that KVM creates in the kvm debugfs
+     folder."""
+-    def __init__(self):
+-        self._fields = self.get_available_fields()
++    def __init__(self, pid, fields_filter):
++        self.update_fields(fields_filter)
+         self._baseline = {}
+-        self._pid = 0
+         self.do_read = True
+         self.paths = []
+-        self.reset()
++        self.pid = pid
+ 
+     def get_available_fields(self):
+         """"Returns a list of available fields.
+@@ -739,6 +750,11 @@ class DebugfsProvider(object):
+         """
+         return walkdir(PATH_DEBUGFS_KVM)[2]
+ 
++    def update_fields(self, fields_filter):
++        """Refresh fields, applying fields_filter"""
++        self._fields = [field for field in self.get_available_fields()
++                        if is_field_wanted(fields_filter, field)]
++
+     @property
+     def fields(self):
+         return self._fields
+@@ -754,9 +770,8 @@ class DebugfsProvider(object):
+ 
+     @pid.setter
+     def pid(self, pid):
++        self._pid = pid
+         if pid != 0:
+-            self._pid = pid
+-
+             vms = walkdir(PATH_DEBUGFS_KVM)[1]
+             if len(vms) == 0:
+                 self.do_read = False
+@@ -818,33 +833,19 @@ class Stats(object):
+     provider data.
+ 
+     """
+-    def __init__(self, providers, pid, fields=None):
+-        self.providers = providers
+-        self._pid_filter = pid
+-        self._fields_filter = fields
++    def __init__(self, options):
++        self.providers = get_providers(options)
++        self._pid_filter = options.pid
++        self._fields_filter = options.fields
+         self.values = {}
+-        self.update_provider_pid()
+-        self.update_provider_filters()
+ 
+     def update_provider_filters(self):
+         """Propagates fields filters to providers."""
+-        def wanted(key):
+-            if not self._fields_filter:
+-                return True
+-            return re.match(self._fields_filter, key) is not None
+-
+         # As we reset the counters when updating the fields we can
+         # also clear the cache of old values.
+         self.values = {}
+         for provider in self.providers:
+-            provider_fields = [key for key in provider.get_available_fields()
+-                               if wanted(key)]
+-            provider.fields = provider_fields
+-
+-    def update_provider_pid(self):
+-        """Propagates pid filters to providers."""
+-        for provider in self.providers:
+-            provider.pid = self._pid_filter
++            provider.update_fields(self._fields_filter)
+ 
+     def reset(self):
+         self.values = {}
+@@ -870,7 +871,8 @@ class Stats(object):
+         if pid != self._pid_filter:
+             self._pid_filter = pid
+             self.values = {}
+-            self.update_provider_pid()
++            for provider in self.providers:
++                provider.pid = self._pid_filter
+ 
+     def get(self):
+         """Returns a dict with field -> (value, delta to last value) of all
+@@ -896,7 +898,6 @@ class Tui(object):
+     def __init__(self, stats):
+         self.stats = stats
+         self.screen = None
+-        self.update_drilldown()
+ 
+     def __enter__(self):
+         """Initialises curses for later use.  Based on curses.wrapper
+@@ -1270,7 +1271,7 @@ Press any other key to refresh statistics immediately.
+                          )
+     optparser.add_option('-f', '--fields',
+                          action='store',
+-                         default=None,
++                         default=DEFAULT_REGEX,
+                          dest='fields',
+                          help='fields to display (regex)',
+                          )
+@@ -1297,12 +1298,10 @@ def get_providers(options):
+     """Returns a list of data providers depending on the passed options."""
+     providers = []
+ 
+-    if options.tracepoints:
+-        providers.append(TracepointProvider())
+     if options.debugfs:
+-        providers.append(DebugfsProvider())
+-    if len(providers) == 0:
+-        providers.append(TracepointProvider())
++        providers.append(DebugfsProvider(options.pid, options.fields))
++    if options.tracepoints or not providers:
++        providers.append(TracepointProvider(options.pid, options.fields))
+ 
+     return providers
+ 
+@@ -1347,8 +1346,7 @@ def main():
+         sys.stderr.write('Did you use a (unsupported) tid instead of a pid?\n')
+         sys.exit('Specified pid does not exist.')
+ 
+-    providers = get_providers(options)
+-    stats = Stats(providers, options.pid, fields=options.fields)
++    stats = Stats(options)
+ 
+     if options.log:
+         log(stats)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-simplify-line-print-logic.patch b/SOURCES/kvm-tools-kvm_stat-simplify-line-print-logic.patch
new file mode 100644
index 0000000..c0581fa
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-simplify-line-print-logic.patch
@@ -0,0 +1,101 @@
+From c4f941df751961aaf2456dfd4ffe7a7a8c0fda4c Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:15:48 +0200
+Subject: [PATCH 43/69] tools/kvm_stat: simplify line print logic
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-23-david@redhat.com>
+Patchwork-id: 77329
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 22/39] tools/kvm_stat: simplify line print logic
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git 5a7d11f8dc59ddb36e89dca42a2526ea25914def
+
+commit 5a7d11f8dc59ddb36e89dca42a2526ea25914def
+Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
+Date:   Wed Jun 7 21:08:29 2017 +0200
+
+    tools/kvm_stat: simplify line print logic
+
+    Simplify line print logic for header and data lines in interactive mode
+    as previously suggested by Radim.
+    While at it, add a space between the first two columns to avoid the
+    total bleeding into the event name.
+    Furthermore, for column 'Current', differentiate between no events being
+    reported (empty 'Current' column) vs the case where events were reported
+    but the average was rounded down to zero ('0' in 'Current column), for
+    the folks who appreciate the difference.
+    Finally: Only skip events which were not reported at all yet, instead of
+    events that don't have a value in the current interval.
+    Considered using constants for the field widths in the format strings.
+    However, that would make things a bit more complicated, and considering
+    that there are only two places where output happens, I figured it isn't
+    worth the trouble.
+
+    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 26 +++++++-------------------
+ 1 file changed, 7 insertions(+), 19 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index d2526b6..a527b2f 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -887,8 +887,6 @@ class Stats(object):
+                 self.values[key] = (newval, newdelta)
+         return self.values
+ 
+-LABEL_WIDTH = 40
+-NUMBER_WIDTH = 10
+ DELAY_INITIAL = 0.25
+ DELAY_REGULAR = 3.0
+ MAX_GUEST_NAME_LEN = 48
+@@ -970,13 +968,8 @@ class Tui(object):
+             if len(regex) > MAX_REGEX_LEN:
+                 regex = regex[:MAX_REGEX_LEN] + '...'
+             self.screen.addstr(1, 17, 'regex filter: {0}'.format(regex))
+-        self.screen.addstr(2, 1, 'Event')
+-        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
+-                           len('Total'), 'Total')
+-        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 7 -
+-                           len('%Total'), '%Total')
+-        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 7 + 8 -
+-                           len('Current'), 'Current')
++        self.screen.addstr(2, 1, '%-40s %10s%7s %7s' %
++                           ('Event', 'Total', '%Total', 'Current'))
+         self.screen.addstr(4, 1, 'Collecting data...')
+         self.screen.refresh()
+ 
+@@ -1001,16 +994,11 @@ class Tui(object):
+             values = stats[key]
+             if not values[0] and not values[1]:
+                 break
+-            col = 1
+-            self.screen.addstr(row, col, key)
+-            col += LABEL_WIDTH
+-            self.screen.addstr(row, col, '%10d' % (values[0],))
+-            col += NUMBER_WIDTH
+-            self.screen.addstr(row, col, '%7.1f' % (values[0] * 100 / total,))
+-            col += 7
+-            if values[1] is not None:
+-                self.screen.addstr(row, col, '%8d' %
+-                                   round(values[1] / sleeptime))
++            if values[0] is not None:
++                cur = int(round(values[1] / sleeptime)) if values[1] else ''
++                self.screen.addstr(row, 1, '%-40s %10d%7.1f %7s' %
++                                   (key, values[0], values[0] * 100 / total,
++                                    cur))
+             row += 1
+         self.screen.refresh()
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-kvm_stat-use-variables-instead-of-hard-paths-i.patch b/SOURCES/kvm-tools-kvm_stat-use-variables-instead-of-hard-paths-i.patch
new file mode 100644
index 0000000..15bd717
--- /dev/null
+++ b/SOURCES/kvm-tools-kvm_stat-use-variables-instead-of-hard-paths-i.patch
@@ -0,0 +1,63 @@
+From ac6ba9a14be2caa8b3b4cb051138b77521ce4b35 Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Tue, 17 Oct 2017 19:16:04 +0200
+Subject: [PATCH 59/69] tools/kvm_stat: use variables instead of hard paths in
+ help output
+
+RH-Author: David Hildenbrand <david@redhat.com>
+Message-id: <20171017191605.2378-39-david@redhat.com>
+Patchwork-id: 77346
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 38/39] tools/kvm_stat: use variables instead of hard paths in help output
+Bugzilla: 1497137
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Upstream-status: linux.git efcb521943a8df5210f16f312037c2edc3e1449f
+
+commit efcb521943a8df5210f16f312037c2edc3e1449f
+Author: Lin Ma <lma@suse.com>
+Date:   Tue Jul 25 19:05:53 2017 +0800
+
+    tools/kvm_stat: use variables instead of hard paths in help output
+
+    Using variables instead of hard paths makes the requirements information
+    more accurate.
+
+    Signed-off-by: Lin Ma <lma@suse.com>
+    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ scripts/kvm/kvm_stat | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
+index dd8f00c..5704044 100755
+--- a/scripts/kvm/kvm_stat
++++ b/scripts/kvm/kvm_stat
+@@ -1413,8 +1413,8 @@ performance.
+ 
+ Requirements:
+ - Access to:
+-    /sys/kernel/debug/kvm
+-    /sys/kernel/debug/trace/events/*
++    %s
++    %s/events/*
+     /proc/pid/task
+ - /proc/sys/kernel/perf_event_paranoid < 1 if user has no
+   CAP_SYS_ADMIN and perf events are used.
+@@ -1434,7 +1434,7 @@ Interactive Commands:
+    s     set update interval
+    x     toggle reporting of stats for individual child trace events
+ Press any other key to refresh statistics immediately.
+-"""
++""" % (PATH_DEBUGFS_KVM, PATH_DEBUGFS_TRACING)
+ 
+     class PlainHelpFormatter(optparse.IndentedHelpFormatter):
+         def format_description(self, description):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-Always-remove-an-old-VNC-channel-watch-before-add.patch b/SOURCES/kvm-ui-Always-remove-an-old-VNC-channel-watch-before-add.patch
new file mode 100644
index 0000000..546e92c
--- /dev/null
+++ b/SOURCES/kvm-ui-Always-remove-an-old-VNC-channel-watch-before-add.patch
@@ -0,0 +1,93 @@
+From 2c959596e23736aadad5010a8db665b99359b517 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Wed, 20 Dec 2017 17:56:46 +0100
+Subject: [PATCH 06/42] ui: Always remove an old VNC channel watch before
+ adding a new one
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20171220175702.29663-5-berrange@redhat.com>
+Patchwork-id: 78457
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 04/20] ui: Always remove an old VNC channel watch before adding a new one
+Bugzilla: 1518649
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+
+Also set saved handle to zero when removing without adding a new watch.
+
+Signed-off-by: Brandon Carpenter <brandon.carpenter@cypherpath.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
+(cherry picked from commit a75d6f07613af7ec5b016b31b117436e32ce7a5f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc-auth-vencrypt.c | 3 +++
+ ui/vnc-ws.c            | 6 ++++++
+ ui/vnc.c               | 4 ++++
+ 3 files changed, 13 insertions(+)
+
+diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
+index ffaab57..c3eece4 100644
+--- a/ui/vnc-auth-vencrypt.c
++++ b/ui/vnc-auth-vencrypt.c
+@@ -77,6 +77,9 @@ static void vnc_tls_handshake_done(QIOTask *task,
+         vnc_client_error(vs);
+         error_free(err);
+     } else {
++        if (vs->ioc_tag) {
++            g_source_remove(vs->ioc_tag);
++        }
+         vs->ioc_tag = qio_channel_add_watch(
+             vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
+         start_auth_vencrypt_subauth(vs);
+diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
+index f530cd5..eaf3095 100644
+--- a/ui/vnc-ws.c
++++ b/ui/vnc-ws.c
+@@ -36,6 +36,9 @@ static void vncws_tls_handshake_done(QIOTask *task,
+         error_free(err);
+     } else {
+         VNC_DEBUG("TLS handshake complete, starting websocket handshake\n");
++        if (vs->ioc_tag) {
++            g_source_remove(vs->ioc_tag);
++        }
+         vs->ioc_tag = qio_channel_add_watch(
+             QIO_CHANNEL(vs->ioc), G_IO_IN, vncws_handshake_io, vs, NULL);
+     }
+@@ -97,6 +100,9 @@ static void vncws_handshake_done(QIOTask *task,
+     } else {
+         VNC_DEBUG("Websock handshake complete, starting VNC protocol\n");
+         vnc_start_protocol(vs);
++        if (vs->ioc_tag) {
++            g_source_remove(vs->ioc_tag);
++        }
+         vs->ioc_tag = qio_channel_add_watch(
+             vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
+     }
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 5b1e264..4e1d94f 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1121,6 +1121,7 @@ static void vnc_disconnect_start(VncState *vs)
+     vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
+     if (vs->ioc_tag) {
+         g_source_remove(vs->ioc_tag);
++        vs->ioc_tag = 0;
+     }
+     qio_channel_close(vs->ioc, NULL);
+     vs->disconnecting = TRUE;
+@@ -2931,6 +2932,9 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
+     VNC_DEBUG("New client on socket %p\n", vs->sioc);
+     update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
+     qio_channel_set_blocking(vs->ioc, false, NULL);
++    if (vs->ioc_tag) {
++        g_source_remove(vs->ioc_tag);
++    }
+     if (websocket) {
+         vs->websocket = 1;
+         if (vd->tlscreds) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-add-trace-events-related-to-VNC-client-throttling.patch b/SOURCES/kvm-ui-add-trace-events-related-to-VNC-client-throttling.patch
new file mode 100644
index 0000000..5d62e30
--- /dev/null
+++ b/SOURCES/kvm-ui-add-trace-events-related-to-VNC-client-throttling.patch
@@ -0,0 +1,136 @@
+From b4bcc805bc53775069ac656e1ac75c49d5eb6b6a Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:09 +0100
+Subject: [PATCH 15/20] ui: add trace events related to VNC client throttling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-15-berrange@redhat.com>
+Patchwork-id: 78886
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 14/17] ui: add trace events related to VNC client throttling
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+The VNC client throttling is quite subtle so will benefit from having trace
+points available for live debugging.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-13-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 6aa22a29187e1908f5db738d27c64a9efc8d0bfa)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/trace-events |  7 +++++++
+ ui/vnc.c        | 23 +++++++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/ui/trace-events b/ui/trace-events
+index 1a9f126..85f74f9 100644
+--- a/ui/trace-events
++++ b/ui/trace-events
+@@ -35,6 +35,13 @@ vnc_client_connect(void *state, void *ioc) "VNC client connect state=%p ioc=%p"
+ vnc_client_disconnect_start(void *state, void *ioc) "VNC client disconnect start state=%p ioc=%p"
+ vnc_client_disconnect_finish(void *state, void *ioc) "VNC client disconnect finish state=%p ioc=%p"
+ vnc_client_io_wrap(void *state, void *ioc, const char *type) "VNC client I/O wrap state=%p ioc=%p type=%s"
++vnc_client_throttle_threshold(void *state, void *ioc, size_t oldoffset, size_t offset, int client_width, int client_height, int bytes_per_pixel, void *audio_cap) "VNC client throttle threshold state=%p ioc=%p oldoffset=%zu newoffset=%zu width=%d height=%d bpp=%d audio=%p"
++vnc_client_throttle_incremental(void *state, void *ioc, int job_update, size_t offset) "VNC client throttle incremental state=%p ioc=%p job-update=%d offset=%zu"
++vnc_client_throttle_forced(void *state, void *ioc, int job_update, size_t offset) "VNC client throttle forced state=%p ioc=%p job-update=%d offset=%zu"
++vnc_client_throttle_audio(void *state, void *ioc, size_t offset) "VNC client throttle audio state=%p ioc=%p offset=%zu"
++vnc_client_unthrottle_forced(void *state, void *ioc) "VNC client unthrottle forced offset state=%p ioc=%p"
++vnc_client_unthrottle_incremental(void *state, void *ioc, size_t offset) "VNC client unthrottle incremental state=%p ioc=%p offset=%zu"
++vnc_client_output_limit(void *state, void *ioc, size_t offset, size_t threshold) "VNC client output limit state=%p ioc=%p offset=%zu threshold=%zu"
+ vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth init state=%p websock=%d auth=%d subauth=%d"
+ vnc_auth_start(void *state, int method) "VNC client auth start state=%p method=%d"
+ vnc_auth_pass(void *state, int method) "VNC client auth passed state=%p method=%d"
+diff --git a/ui/vnc.c b/ui/vnc.c
+index a7aff91..26f58bc 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1011,6 +1011,12 @@ static void vnc_update_throttle_offset(VncState *vs)
+      */
+     offset = MAX(offset, 1024 * 1024);
+ 
++    if (vs->throttle_output_offset != offset) {
++        trace_vnc_client_throttle_threshold(
++            vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
++            vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
++    }
++
+     vs->throttle_output_offset = offset;
+ }
+ 
+@@ -1028,6 +1034,8 @@ static bool vnc_should_update(VncState *vs)
+             vs->job_update == VNC_STATE_UPDATE_NONE) {
+             return true;
+         }
++        trace_vnc_client_throttle_incremental(
++            vs, vs->ioc, vs->job_update, vs->output.offset);
+         break;
+     case VNC_STATE_UPDATE_FORCE:
+         /* Only allow forced updates if the pending send queue
+@@ -1042,6 +1050,8 @@ static bool vnc_should_update(VncState *vs)
+             vs->job_update == VNC_STATE_UPDATE_NONE) {
+             return true;
+         }
++        trace_vnc_client_throttle_forced(
++            vs, vs->ioc, vs->job_update, vs->force_update_offset);
+         break;
+     }
+     return false;
+@@ -1158,6 +1168,8 @@ static void audio_capture(void *opaque, void *buf, int size)
+         vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
+         vnc_write_u32(vs, size);
+         vnc_write(vs, buf, size);
++    } else {
++        trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
+     }
+     vnc_unlock_output(vs);
+     vnc_flush(vs);
+@@ -1328,6 +1340,7 @@ ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
+  */
+ static ssize_t vnc_client_write_plain(VncState *vs)
+ {
++    size_t offset;
+     ssize_t ret;
+ 
+ #ifdef CONFIG_VNC_SASL
+@@ -1348,11 +1361,19 @@ static ssize_t vnc_client_write_plain(VncState *vs)
+         return 0;
+ 
+     if (ret >= vs->force_update_offset) {
++        if (vs->force_update_offset != 0) {
++            trace_vnc_client_unthrottle_forced(vs, vs->ioc);
++        }
+         vs->force_update_offset = 0;
+     } else {
+         vs->force_update_offset -= ret;
+     }
++    offset = vs->output.offset;
+     buffer_advance(&vs->output, ret);
++    if (offset >= vs->throttle_output_offset &&
++        vs->output.offset < vs->throttle_output_offset) {
++        trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
++    }
+ 
+     if (vs->output.offset == 0) {
+         if (vs->ioc_tag) {
+@@ -1549,6 +1570,8 @@ void vnc_write(VncState *vs, const void *data, size_t len)
+     if (vs->throttle_output_offset != 0 &&
+         vs->output.offset > (vs->throttle_output_offset *
+                              VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
++        trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
++                                      vs->throttle_output_offset);
+         vnc_disconnect_start(vs);
+         return;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-add-tracing-of-VNC-authentication-process.patch b/SOURCES/kvm-ui-add-tracing-of-VNC-authentication-process.patch
new file mode 100644
index 0000000..c762b26
--- /dev/null
+++ b/SOURCES/kvm-ui-add-tracing-of-VNC-authentication-process.patch
@@ -0,0 +1,665 @@
+From d22fb15220016b86cca81f73f27c748f5a5c1183 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:09:57 +0100
+Subject: [PATCH 03/20] ui: add tracing of VNC authentication process
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-3-berrange@redhat.com>
+Patchwork-id: 78881
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 02/17] ui: add tracing of VNC authentication process
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+Trace anything related to authentication in the VNC protocol
+handshake
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Message-id: 20170921121528.23935-3-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 7364dbdabb7824d5bde1e341bb6d928282f01c83)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/trace-events        |  15 +++++++
+ ui/vnc-auth-sasl.c     | 113 ++++++++++++++++++++++---------------------------
+ ui/vnc-auth-vencrypt.c |  21 ++++-----
+ ui/vnc.c               |  36 ++++++++--------
+ 4 files changed, 92 insertions(+), 93 deletions(-)
+
+diff --git a/ui/trace-events b/ui/trace-events
+index e4c02e4..1a9f126 100644
+--- a/ui/trace-events
++++ b/ui/trace-events
+@@ -35,6 +35,21 @@ vnc_client_connect(void *state, void *ioc) "VNC client connect state=%p ioc=%p"
+ vnc_client_disconnect_start(void *state, void *ioc) "VNC client disconnect start state=%p ioc=%p"
+ vnc_client_disconnect_finish(void *state, void *ioc) "VNC client disconnect finish state=%p ioc=%p"
+ vnc_client_io_wrap(void *state, void *ioc, const char *type) "VNC client I/O wrap state=%p ioc=%p type=%s"
++vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth init state=%p websock=%d auth=%d subauth=%d"
++vnc_auth_start(void *state, int method) "VNC client auth start state=%p method=%d"
++vnc_auth_pass(void *state, int method) "VNC client auth passed state=%p method=%d"
++vnc_auth_fail(void *state, int method, const char *message, const char *reason) "VNC client auth failed state=%p method=%d message=%s reason=%s"
++vnc_auth_reject(void *state, int expect, int got) "VNC client auth rejected state=%p method expected=%d got=%d"
++vnc_auth_vencrypt_version(void *state, int major, int minor) "VNC client auth vencrypt version state=%p major=%d minor=%d"
++vnc_auth_vencrypt_subauth(void *state, int auth) "VNC client auth vencrypt subauth state=%p auth=%d"
++vnc_auth_sasl_mech_list(void *state, const char *mechs) "VNC client auth SASL state=%p mechlist=%s"
++vnc_auth_sasl_mech_choose(void *state, const char *mech) "VNC client auth SASL state=%p mech=%s"
++vnc_auth_sasl_start(void *state, const void *clientdata, size_t clientlen, const void *serverdata, size_t severlen, int ret) "VNC client auth SASL start state=%p clientdata=%p clientlen=%zu serverdata=%p serverlen=%zu ret=%d"
++vnc_auth_sasl_step(void *state, const void *clientdata, size_t clientlen, const void *serverdata, size_t severlen, int ret) "VNC client auth SASL step state=%p clientdata=%p clientlen=%zu serverdata=%p serverlen=%zu ret=%d"
++vnc_auth_sasl_ssf(void *state, int ssf) "VNC client auth SASL SSF state=%p size=%d"
++vnc_auth_sasl_username(void *state, const char *name) "VNC client auth SASL user state=%p name=%s"
++vnc_auth_sasl_acl(void *state, int allow) "VNC client auth SASL ACL state=%p allow=%d"
++
+ 
+ # ui/input.c
+ input_event_key_number(int conidx, int number, const char *qcode, bool down) "con %d, key number 0x%x [%s], down %d"
+diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
+index 3ade4a4..23f2828 100644
+--- a/ui/vnc-auth-sasl.c
++++ b/ui/vnc-auth-sasl.c
+@@ -25,6 +25,7 @@
+ #include "qemu/osdep.h"
+ #include "qapi/error.h"
+ #include "vnc.h"
++#include "trace.h"
+ 
+ /* Max amount of data we send/recv for SASL steps to prevent DOS */
+ #define SASL_DATA_MAX_LEN (1024 * 1024)
+@@ -133,27 +134,26 @@ static int vnc_auth_sasl_check_access(VncState *vs)
+ 
+     err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val);
+     if (err != SASL_OK) {
+-        VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n",
+-                  err, sasl_errstring(err, NULL, NULL));
++        trace_vnc_auth_fail(vs, vs->auth, "Cannot fetch SASL username",
++                            sasl_errstring(err, NULL, NULL));
+         return -1;
+     }
+     if (val == NULL) {
+-        VNC_DEBUG("no client username was found, denying access\n");
++        trace_vnc_auth_fail(vs, vs->auth, "No SASL username set", "");
+         return -1;
+     }
+-    VNC_DEBUG("SASL client username %s\n", (const char *)val);
+ 
+     vs->sasl.username = g_strdup((const char*)val);
++    trace_vnc_auth_sasl_username(vs, vs->sasl.username);
+ 
+     if (vs->vd->sasl.acl == NULL) {
+-        VNC_DEBUG("no ACL activated, allowing access\n");
++        trace_vnc_auth_sasl_acl(vs, 1);
+         return 0;
+     }
+ 
+     allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username);
+ 
+-    VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username,
+-              allow ? "allowed" : "denied");
++    trace_vnc_auth_sasl_acl(vs, allow);
+     return allow ? 0 : -1;
+ }
+ 
+@@ -170,7 +170,9 @@ static int vnc_auth_sasl_check_ssf(VncState *vs)
+         return 0;
+ 
+     ssf = *(const int *)val;
+-    VNC_DEBUG("negotiated an SSF of %d\n", ssf);
++
++    trace_vnc_auth_sasl_ssf(vs, ssf);
++
+     if (ssf < 56)
+         return 0; /* 56 is good for Kerberos */
+ 
+@@ -218,33 +220,28 @@ static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t le
+         datalen--; /* Don't count NULL byte when passing to _start() */
+     }
+ 
+-    VNC_DEBUG("Step using SASL Data %p (%d bytes)\n",
+-              clientdata, datalen);
+     err = sasl_server_step(vs->sasl.conn,
+                            clientdata,
+                            datalen,
+                            &serverout,
+                            &serveroutlen);
++    trace_vnc_auth_sasl_step(vs, data, len, serverout, serveroutlen, err);
+     if (err != SASL_OK &&
+         err != SASL_CONTINUE) {
+-        VNC_DEBUG("sasl step failed %d (%s)\n",
+-                  err, sasl_errdetail(vs->sasl.conn));
++        trace_vnc_auth_fail(vs, vs->auth, "Cannot step SASL auth",
++                            sasl_errdetail(vs->sasl.conn));
+         sasl_dispose(&vs->sasl.conn);
+         vs->sasl.conn = NULL;
+         goto authabort;
+     }
+ 
+     if (serveroutlen > SASL_DATA_MAX_LEN) {
+-        VNC_DEBUG("sasl step reply data too long %d\n",
+-                  serveroutlen);
++        trace_vnc_auth_fail(vs, vs->auth, "SASL data too long", "");
+         sasl_dispose(&vs->sasl.conn);
+         vs->sasl.conn = NULL;
+         goto authabort;
+     }
+ 
+-    VNC_DEBUG("SASL return data %d bytes, nil; %d\n",
+-              serveroutlen, serverout ? 0 : 1);
+-
+     if (serveroutlen) {
+         vnc_write_u32(vs, serveroutlen + 1);
+         vnc_write(vs, serverout, serveroutlen + 1);
+@@ -256,22 +253,20 @@ static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t le
+     vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1);
+ 
+     if (err == SASL_CONTINUE) {
+-        VNC_DEBUG("%s", "Authentication must continue\n");
+         /* Wait for step length */
+         vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4);
+     } else {
+         if (!vnc_auth_sasl_check_ssf(vs)) {
+-            VNC_DEBUG("Authentication rejected for weak SSF %p\n", vs->ioc);
++            trace_vnc_auth_fail(vs, vs->auth, "SASL SSF too weak", "");
+             goto authreject;
+         }
+ 
+         /* Check username whitelist ACL */
+         if (vnc_auth_sasl_check_access(vs) < 0) {
+-            VNC_DEBUG("Authentication rejected for ACL %p\n", vs->ioc);
+             goto authreject;
+         }
+ 
+-        VNC_DEBUG("Authentication successful %p\n", vs->ioc);
++        trace_vnc_auth_pass(vs, vs->auth);
+         vnc_write_u32(vs, 0); /* Accept auth */
+         /*
+          * Delay writing in SSF encoded mode until pending output
+@@ -300,9 +295,9 @@ static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t le
+ static int protocol_client_auth_sasl_step_len(VncState *vs, uint8_t *data, size_t len)
+ {
+     uint32_t steplen = read_u32(data, 0);
+-    VNC_DEBUG("Got client step len %d\n", steplen);
++
+     if (steplen > SASL_DATA_MAX_LEN) {
+-        VNC_DEBUG("Too much SASL data %d\n", steplen);
++        trace_vnc_auth_fail(vs, vs->auth, "SASL step len too large", "");
+         vnc_client_error(vs);
+         return -1;
+     }
+@@ -346,33 +341,28 @@ static int protocol_client_auth_sasl_start(VncState *vs, uint8_t *data, size_t l
+         datalen--; /* Don't count NULL byte when passing to _start() */
+     }
+ 
+-    VNC_DEBUG("Start SASL auth with mechanism %s. Data %p (%d bytes)\n",
+-              vs->sasl.mechlist, clientdata, datalen);
+     err = sasl_server_start(vs->sasl.conn,
+                             vs->sasl.mechlist,
+                             clientdata,
+                             datalen,
+                             &serverout,
+                             &serveroutlen);
++    trace_vnc_auth_sasl_start(vs, data, len, serverout, serveroutlen, err);
+     if (err != SASL_OK &&
+         err != SASL_CONTINUE) {
+-        VNC_DEBUG("sasl start failed %d (%s)\n",
+-                  err, sasl_errdetail(vs->sasl.conn));
++        trace_vnc_auth_fail(vs, vs->auth, "Cannot start SASL auth",
++                            sasl_errdetail(vs->sasl.conn));
+         sasl_dispose(&vs->sasl.conn);
+         vs->sasl.conn = NULL;
+         goto authabort;
+     }
+     if (serveroutlen > SASL_DATA_MAX_LEN) {
+-        VNC_DEBUG("sasl start reply data too long %d\n",
+-                  serveroutlen);
++        trace_vnc_auth_fail(vs, vs->auth, "SASL data too long", "");
+         sasl_dispose(&vs->sasl.conn);
+         vs->sasl.conn = NULL;
+         goto authabort;
+     }
+ 
+-    VNC_DEBUG("SASL return data %d bytes, nil; %d\n",
+-              serveroutlen, serverout ? 0 : 1);
+-
+     if (serveroutlen) {
+         vnc_write_u32(vs, serveroutlen + 1);
+         vnc_write(vs, serverout, serveroutlen + 1);
+@@ -384,22 +374,20 @@ static int protocol_client_auth_sasl_start(VncState *vs, uint8_t *data, size_t l
+     vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1);
+ 
+     if (err == SASL_CONTINUE) {
+-        VNC_DEBUG("%s", "Authentication must continue\n");
+         /* Wait for step length */
+         vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4);
+     } else {
+         if (!vnc_auth_sasl_check_ssf(vs)) {
+-            VNC_DEBUG("Authentication rejected for weak SSF %p\n", vs->ioc);
++            trace_vnc_auth_fail(vs, vs->auth, "SASL SSF too weak", "");
+             goto authreject;
+         }
+ 
+         /* Check username whitelist ACL */
+         if (vnc_auth_sasl_check_access(vs) < 0) {
+-            VNC_DEBUG("Authentication rejected for ACL %p\n", vs->ioc);
+             goto authreject;
+         }
+ 
+-        VNC_DEBUG("Authentication successful %p\n", vs->ioc);
++        trace_vnc_auth_pass(vs, vs->auth);
+         vnc_write_u32(vs, 0); /* Accept auth */
+         start_client_init(vs);
+     }
+@@ -422,9 +410,9 @@ static int protocol_client_auth_sasl_start(VncState *vs, uint8_t *data, size_t l
+ static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size_t len)
+ {
+     uint32_t startlen = read_u32(data, 0);
+-    VNC_DEBUG("Got client start len %d\n", startlen);
++
+     if (startlen > SASL_DATA_MAX_LEN) {
+-        VNC_DEBUG("Too much SASL data %d\n", startlen);
++        trace_vnc_auth_fail(vs, vs->auth, "SASL start len too large", "");
+         vnc_client_error(vs);
+         return -1;
+     }
+@@ -439,22 +427,18 @@ static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size
+ static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_t len)
+ {
+     char *mechname = g_strndup((const char *) data, len);
+-    VNC_DEBUG("Got client mechname '%s' check against '%s'\n",
+-              mechname, vs->sasl.mechlist);
++    trace_vnc_auth_sasl_mech_choose(vs, mechname);
+ 
+     if (strncmp(vs->sasl.mechlist, mechname, len) == 0) {
+         if (vs->sasl.mechlist[len] != '\0' &&
+             vs->sasl.mechlist[len] != ',') {
+-            VNC_DEBUG("One %d", vs->sasl.mechlist[len]);
+             goto fail;
+         }
+     } else {
+         char *offset = strstr(vs->sasl.mechlist, mechname);
+-        VNC_DEBUG("Two %p\n", offset);
+         if (!offset) {
+             goto fail;
+         }
+-        VNC_DEBUG("Two '%s'\n", offset);
+         if (offset[-1] != ',' ||
+             (offset[len] != '\0'&&
+              offset[len] != ',')) {
+@@ -465,11 +449,11 @@ static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_
+     g_free(vs->sasl.mechlist);
+     vs->sasl.mechlist = mechname;
+ 
+-    VNC_DEBUG("Validated mechname '%s'\n", mechname);
+     vnc_read_when(vs, protocol_client_auth_sasl_start_len, 4);
+     return 0;
+ 
+  fail:
++    trace_vnc_auth_fail(vs, vs->auth, "Unsupported mechname", mechname);
+     vnc_client_error(vs);
+     g_free(mechname);
+     return -1;
+@@ -478,14 +462,14 @@ static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_
+ static int protocol_client_auth_sasl_mechname_len(VncState *vs, uint8_t *data, size_t len)
+ {
+     uint32_t mechlen = read_u32(data, 0);
+-    VNC_DEBUG("Got client mechname len %d\n", mechlen);
++
+     if (mechlen > 100) {
+-        VNC_DEBUG("Too long SASL mechname data %d\n", mechlen);
++        trace_vnc_auth_fail(vs, vs->auth, "SASL mechname too long", "");
+         vnc_client_error(vs);
+         return -1;
+     }
+     if (mechlen < 1) {
+-        VNC_DEBUG("Too short SASL mechname %d\n", mechlen);
++        trace_vnc_auth_fail(vs, vs->auth, "SASL mechname too short", "");
+         vnc_client_error(vs);
+         return -1;
+     }
+@@ -524,19 +508,22 @@ void start_auth_sasl(VncState *vs)
+     const char *mechlist = NULL;
+     sasl_security_properties_t secprops;
+     int err;
++    Error *local_err = NULL;
+     char *localAddr, *remoteAddr;
+     int mechlistlen;
+ 
+-    VNC_DEBUG("Initialize SASL auth %p\n", vs->ioc);
+-
+     /* Get local & remote client addresses in form  IPADDR;PORT */
+-    localAddr = vnc_socket_ip_addr_string(vs->sioc, true, NULL);
++    localAddr = vnc_socket_ip_addr_string(vs->sioc, true, &local_err);
+     if (!localAddr) {
++        trace_vnc_auth_fail(vs, vs->auth, "Cannot format local IP",
++                            error_get_pretty(local_err));
+         goto authabort;
+     }
+ 
+-    remoteAddr = vnc_socket_ip_addr_string(vs->sioc, false, NULL);
++    remoteAddr = vnc_socket_ip_addr_string(vs->sioc, false, &local_err);
+     if (!remoteAddr) {
++        trace_vnc_auth_fail(vs, vs->auth, "Cannot format remote IP",
++                            error_get_pretty(local_err));
+         g_free(localAddr);
+         goto authabort;
+     }
+@@ -554,8 +541,8 @@ void start_auth_sasl(VncState *vs)
+     localAddr = remoteAddr = NULL;
+ 
+     if (err != SASL_OK) {
+-        VNC_DEBUG("sasl context setup failed %d (%s)",
+-                  err, sasl_errstring(err, NULL, NULL));
++        trace_vnc_auth_fail(vs, vs->auth,  "SASL context setup failed",
++                            sasl_errstring(err, NULL, NULL));
+         vs->sasl.conn = NULL;
+         goto authabort;
+     }
+@@ -570,8 +557,8 @@ void start_auth_sasl(VncState *vs)
+         keysize = qcrypto_tls_session_get_key_size(vs->tls,
+                                                    &local_err);
+         if (keysize < 0) {
+-            VNC_DEBUG("cannot TLS get cipher size: %s\n",
+-                      error_get_pretty(local_err));
++            trace_vnc_auth_fail(vs, vs->auth, "cannot TLS get cipher size",
++                                error_get_pretty(local_err));
+             error_free(local_err);
+             sasl_dispose(&vs->sasl.conn);
+             vs->sasl.conn = NULL;
+@@ -581,8 +568,8 @@ void start_auth_sasl(VncState *vs)
+ 
+         err = sasl_setprop(vs->sasl.conn, SASL_SSF_EXTERNAL, &ssf);
+         if (err != SASL_OK) {
+-            VNC_DEBUG("cannot set SASL external SSF %d (%s)\n",
+-                      err, sasl_errstring(err, NULL, NULL));
++            trace_vnc_auth_fail(vs, vs->auth, "cannot set SASL external SSF",
++                                sasl_errstring(err, NULL, NULL));
+             sasl_dispose(&vs->sasl.conn);
+             vs->sasl.conn = NULL;
+             goto authabort;
+@@ -617,8 +604,8 @@ void start_auth_sasl(VncState *vs)
+ 
+     err = sasl_setprop(vs->sasl.conn, SASL_SEC_PROPS, &secprops);
+     if (err != SASL_OK) {
+-        VNC_DEBUG("cannot set SASL security props %d (%s)\n",
+-                  err, sasl_errstring(err, NULL, NULL));
++        trace_vnc_auth_fail(vs, vs->auth, "cannot set SASL security props",
++                            sasl_errstring(err, NULL, NULL));
+         sasl_dispose(&vs->sasl.conn);
+         vs->sasl.conn = NULL;
+         goto authabort;
+@@ -633,13 +620,13 @@ void start_auth_sasl(VncState *vs)
+                         NULL,
+                         NULL);
+     if (err != SASL_OK) {
+-        VNC_DEBUG("cannot list SASL mechanisms %d (%s)\n",
+-                  err, sasl_errdetail(vs->sasl.conn));
++        trace_vnc_auth_fail(vs, vs->auth, "cannot list SASL mechanisms",
++                            sasl_errdetail(vs->sasl.conn));
+         sasl_dispose(&vs->sasl.conn);
+         vs->sasl.conn = NULL;
+         goto authabort;
+     }
+-    VNC_DEBUG("Available mechanisms for client: '%s'\n", mechlist);
++    trace_vnc_auth_sasl_mech_list(vs, mechlist);
+ 
+     vs->sasl.mechlist = g_strdup(mechlist);
+     mechlistlen = strlen(mechlist);
+@@ -647,12 +634,12 @@ void start_auth_sasl(VncState *vs)
+     vnc_write(vs, mechlist, mechlistlen);
+     vnc_flush(vs);
+ 
+-    VNC_DEBUG("Wait for client mechname length\n");
+     vnc_read_when(vs, protocol_client_auth_sasl_mechname_len, 4);
+ 
+     return;
+ 
+  authabort:
++    error_free(local_err);
+     vnc_client_error(vs);
+ }
+ 
+diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
+index 2a3766a..7833631 100644
+--- a/ui/vnc-auth-vencrypt.c
++++ b/ui/vnc-auth-vencrypt.c
+@@ -35,27 +35,24 @@ static void start_auth_vencrypt_subauth(VncState *vs)
+     switch (vs->subauth) {
+     case VNC_AUTH_VENCRYPT_TLSNONE:
+     case VNC_AUTH_VENCRYPT_X509NONE:
+-       VNC_DEBUG("Accept TLS auth none\n");
+        vnc_write_u32(vs, 0); /* Accept auth completion */
+        start_client_init(vs);
+        break;
+ 
+     case VNC_AUTH_VENCRYPT_TLSVNC:
+     case VNC_AUTH_VENCRYPT_X509VNC:
+-       VNC_DEBUG("Start TLS auth VNC\n");
+        start_auth_vnc(vs);
+        break;
+ 
+ #ifdef CONFIG_VNC_SASL
+     case VNC_AUTH_VENCRYPT_TLSSASL:
+     case VNC_AUTH_VENCRYPT_X509SASL:
+-      VNC_DEBUG("Start TLS auth SASL\n");
+       start_auth_sasl(vs);
+       break;
+ #endif /* CONFIG_VNC_SASL */
+ 
+     default: /* Should not be possible, but just in case */
+-       VNC_DEBUG("Reject subauth %d server bug\n", vs->auth);
++       trace_vnc_auth_fail(vs, vs->auth, "Unhandled VeNCrypt subauth", "");
+        vnc_write_u8(vs, 1);
+        if (vs->minor >= 8) {
+            static const char err[] = "Unsupported authentication type";
+@@ -73,8 +70,8 @@ static void vnc_tls_handshake_done(QIOTask *task,
+     Error *err = NULL;
+ 
+     if (qio_task_propagate_error(task, &err)) {
+-        VNC_DEBUG("Handshake failed %s\n",
+-                  error_get_pretty(err));
++        trace_vnc_auth_fail(vs, vs->auth, "TLS handshake failed",
++                            error_get_pretty(err));
+         vnc_client_error(vs);
+         error_free(err);
+     } else {
+@@ -92,15 +89,15 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
+ {
+     int auth = read_u32(data, 0);
+ 
++    trace_vnc_auth_vencrypt_subauth(vs, auth);
+     if (auth != vs->subauth) {
+-        VNC_DEBUG("Rejecting auth %d\n", auth);
++        trace_vnc_auth_fail(vs, vs->auth, "Unsupported sub-auth version", "");
+         vnc_write_u8(vs, 0); /* Reject auth */
+         vnc_flush(vs);
+         vnc_client_error(vs);
+     } else {
+         Error *err = NULL;
+         QIOChannelTLS *tls;
+-        VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth);
+         vnc_write_u8(vs, 1); /* Accept auth */
+         vnc_flush(vs);
+ 
+@@ -115,14 +112,14 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
+             vs->vd->tlsaclname,
+             &err);
+         if (!tls) {
+-            VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err));
++            trace_vnc_auth_fail(vs, vs->auth, "TLS setup failed",
++                                error_get_pretty(err));
+             error_free(err);
+             vnc_client_error(vs);
+             return 0;
+         }
+ 
+         qio_channel_set_name(QIO_CHANNEL(tls), "vnc-server-tls");
+-        VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
+         object_unref(OBJECT(vs->ioc));
+         vs->ioc = QIO_CHANNEL(tls);
+         trace_vnc_client_io_wrap(vs, vs->ioc, "tls");
+@@ -138,14 +135,14 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
+ 
+ static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
+ {
++    trace_vnc_auth_vencrypt_version(vs, (int)data[0], (int)data[1]);
+     if (data[0] != 0 ||
+         data[1] != 2) {
+-        VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
++        trace_vnc_auth_fail(vs, vs->auth, "Unsupported version", "");
+         vnc_write_u8(vs, 1); /* Reject version */
+         vnc_flush(vs);
+         vnc_client_error(vs);
+     } else {
+-        VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
+         vnc_write_u8(vs, 0); /* Accept version */
+         vnc_write_u8(vs, 1); /* Number of sub-auths */
+         vnc_write_u32(vs, vs->subauth); /* The supported auth */
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 66783ec..1275bba 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -2407,11 +2407,11 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
+     Error *err = NULL;
+ 
+     if (!vs->vd->password) {
+-        VNC_DEBUG("No password configured on server");
++        trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
+         goto reject;
+     }
+     if (vs->vd->expires < now) {
+-        VNC_DEBUG("Password is expired");
++        trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
+         goto reject;
+     }
+ 
+@@ -2428,8 +2428,8 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
+         key, G_N_ELEMENTS(key),
+         &err);
+     if (!cipher) {
+-        VNC_DEBUG("Cannot initialize cipher %s",
+-                  error_get_pretty(err));
++        trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
++                            error_get_pretty(err));
+         error_free(err);
+         goto reject;
+     }
+@@ -2439,18 +2439,18 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
+                                response,
+                                VNC_AUTH_CHALLENGE_SIZE,
+                                &err) < 0) {
+-        VNC_DEBUG("Cannot encrypt challenge %s",
+-                  error_get_pretty(err));
++        trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
++                            error_get_pretty(err));
+         error_free(err);
+         goto reject;
+     }
+ 
+     /* Compare expected vs actual challenge response */
+     if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
+-        VNC_DEBUG("Client challenge response did not match\n");
++        trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
+         goto reject;
+     } else {
+-        VNC_DEBUG("Accepting VNC challenge response\n");
++        trace_vnc_auth_pass(vs, vs->auth);
+         vnc_write_u32(vs, 0); /* Accept auth */
+         vnc_flush(vs);
+ 
+@@ -2489,7 +2489,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
+     /* We only advertise 1 auth scheme at a time, so client
+      * must pick the one we sent. Verify this */
+     if (data[0] != vs->auth) { /* Reject auth */
+-       VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
++       trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
+        vnc_write_u32(vs, 1);
+        if (vs->minor >= 8) {
+            static const char err[] = "Authentication failed";
+@@ -2498,36 +2498,33 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
+        }
+        vnc_client_error(vs);
+     } else { /* Accept requested auth */
+-       VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
++       trace_vnc_auth_start(vs, vs->auth);
+        switch (vs->auth) {
+        case VNC_AUTH_NONE:
+-           VNC_DEBUG("Accept auth none\n");
+            if (vs->minor >= 8) {
+                vnc_write_u32(vs, 0); /* Accept auth completion */
+                vnc_flush(vs);
+            }
++           trace_vnc_auth_pass(vs, vs->auth);
+            start_client_init(vs);
+            break;
+ 
+        case VNC_AUTH_VNC:
+-           VNC_DEBUG("Start VNC auth\n");
+            start_auth_vnc(vs);
+            break;
+ 
+        case VNC_AUTH_VENCRYPT:
+-           VNC_DEBUG("Accept VeNCrypt auth\n");
+            start_auth_vencrypt(vs);
+            break;
+ 
+ #ifdef CONFIG_VNC_SASL
+        case VNC_AUTH_SASL:
+-           VNC_DEBUG("Accept SASL auth\n");
+            start_auth_sasl(vs);
+            break;
+ #endif /* CONFIG_VNC_SASL */
+ 
+        default: /* Should not be possible, but just in case */
+-           VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
++           trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
+            vnc_write_u8(vs, 1);
+            if (vs->minor >= 8) {
+                static const char err[] = "Authentication failed";
+@@ -2572,10 +2569,11 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
+         vs->minor = 3;
+ 
+     if (vs->minor == 3) {
++        trace_vnc_auth_start(vs, vs->auth);
+         if (vs->auth == VNC_AUTH_NONE) {
+-            VNC_DEBUG("Tell client auth none\n");
+             vnc_write_u32(vs, vs->auth);
+             vnc_flush(vs);
++            trace_vnc_auth_pass(vs, vs->auth);
+             start_client_init(vs);
+        } else if (vs->auth == VNC_AUTH_VNC) {
+             VNC_DEBUG("Tell client VNC auth\n");
+@@ -2583,13 +2581,13 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len)
+             vnc_flush(vs);
+             start_auth_vnc(vs);
+        } else {
+-            VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
++            trace_vnc_auth_fail(vs, vs->auth,
++                                "Unsupported auth method for v3.3", "");
+             vnc_write_u32(vs, VNC_AUTH_INVALID);
+             vnc_flush(vs);
+             vnc_client_error(vs);
+        }
+     } else {
+-        VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
+         vnc_write_u8(vs, 1); /* num auth */
+         vnc_write_u8(vs, vs->auth);
+         vnc_read_when(vs, protocol_client_auth, 1);
+@@ -3946,12 +3944,14 @@ void vnc_display_open(const char *id, Error **errp)
+                                sasl, false, errp) < 0) {
+         goto fail;
+     }
++    trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
+ 
+     if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
+                                vd->tlscreds, password,
+                                sasl, true, errp) < 0) {
+         goto fail;
+     }
++    trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
+ 
+ #ifdef CONFIG_VNC_SASL
+     if ((saslErr = sasl_server_init(NULL, "qemu-kvm")) != SASL_OK) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-add-tracing-of-VNC-operations-related-to-QIOChann.patch b/SOURCES/kvm-ui-add-tracing-of-VNC-operations-related-to-QIOChann.patch
new file mode 100644
index 0000000..1d98881
--- /dev/null
+++ b/SOURCES/kvm-ui-add-tracing-of-VNC-operations-related-to-QIOChann.patch
@@ -0,0 +1,163 @@
+From 5707c2b3cc6e0312302642914154689d8afda7a0 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:09:56 +0100
+Subject: [PATCH 02/20] ui: add tracing of VNC operations related to QIOChannel
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-2-berrange@redhat.com>
+Patchwork-id: 78884
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 01/17] ui: add tracing of VNC operations related to QIOChannel
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+Trace anything which opens/closes/wraps a QIOChannel in the
+VNC server.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Message-id: 20170921121528.23935-2-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit ad6374c43e572e6e53020a97e72e9ea525b08334)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/trace-events        |  6 ++++++
+ ui/vnc-auth-vencrypt.c |  2 ++
+ ui/vnc-ws.c            |  6 +++---
+ ui/vnc.c               | 11 ++++++++---
+ 4 files changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/ui/trace-events b/ui/trace-events
+index 34c2213..e4c02e4 100644
+--- a/ui/trace-events
++++ b/ui/trace-events
+@@ -29,6 +29,12 @@ vnc_key_event_ext(bool down, int sym, int keycode, const char *name) "down %d, s
+ vnc_key_event_map(bool down, int sym, int keycode, const char *name) "down %d, sym 0x%x -> keycode 0x%x [%s]"
+ vnc_key_sync_numlock(bool on) "%d"
+ vnc_key_sync_capslock(bool on) "%d"
++vnc_client_eof(void *state, void *ioc) "VNC client EOF state=%p ioc=%p"
++vnc_client_io_error(void *state, void *ioc, const char *msg) "VNC client I/O error state=%p ioc=%p errmsg=%s"
++vnc_client_connect(void *state, void *ioc) "VNC client connect state=%p ioc=%p"
++vnc_client_disconnect_start(void *state, void *ioc) "VNC client disconnect start state=%p ioc=%p"
++vnc_client_disconnect_finish(void *state, void *ioc) "VNC client disconnect finish state=%p ioc=%p"
++vnc_client_io_wrap(void *state, void *ioc, const char *type) "VNC client I/O wrap state=%p ioc=%p type=%s"
+ 
+ # ui/input.c
+ input_event_key_number(int conidx, int number, const char *qcode, bool down) "con %d, key number 0x%x [%s], down %d"
+diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
+index c3eece4..2a3766a 100644
+--- a/ui/vnc-auth-vencrypt.c
++++ b/ui/vnc-auth-vencrypt.c
+@@ -28,6 +28,7 @@
+ #include "vnc.h"
+ #include "qapi/error.h"
+ #include "qemu/main-loop.h"
++#include "trace.h"
+ 
+ static void start_auth_vencrypt_subauth(VncState *vs)
+ {
+@@ -124,6 +125,7 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len
+         VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
+         object_unref(OBJECT(vs->ioc));
+         vs->ioc = QIO_CHANNEL(tls);
++        trace_vnc_client_io_wrap(vs, vs->ioc, "tls");
+         vs->tls = qio_channel_tls_get_session(tls);
+ 
+         qio_channel_tls_handshake(tls,
+diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
+index eaf3095..6ccad22 100644
+--- a/ui/vnc-ws.c
++++ b/ui/vnc-ws.c
+@@ -23,6 +23,7 @@
+ #include "vnc.h"
+ #include "io/channel-websock.h"
+ #include "qemu/bswap.h"
++#include "trace.h"
+ 
+ static void vncws_tls_handshake_done(QIOTask *task,
+                                      gpointer user_data)
+@@ -53,7 +54,6 @@ gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
+     QIOChannelTLS *tls;
+     Error *err = NULL;
+ 
+-    VNC_DEBUG("TLS Websocket connection required\n");
+     if (vs->ioc_tag) {
+         g_source_remove(vs->ioc_tag);
+         vs->ioc_tag = 0;
+@@ -73,9 +73,9 @@ gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
+ 
+     qio_channel_set_name(QIO_CHANNEL(tls), "vnc-ws-server-tls");
+ 
+-    VNC_DEBUG("Start TLS WS handshake process\n");
+     object_unref(OBJECT(vs->ioc));
+     vs->ioc = QIO_CHANNEL(tls);
++    trace_vnc_client_io_wrap(vs, vs->ioc, "tls");
+     vs->tls = qio_channel_tls_get_session(tls);
+ 
+     qio_channel_tls_handshake(tls,
+@@ -116,7 +116,6 @@ gboolean vncws_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
+     VncState *vs = opaque;
+     QIOChannelWebsock *wioc;
+ 
+-    VNC_DEBUG("Websocket negotiate starting\n");
+     if (vs->ioc_tag) {
+         g_source_remove(vs->ioc_tag);
+         vs->ioc_tag = 0;
+@@ -127,6 +126,7 @@ gboolean vncws_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
+ 
+     object_unref(OBJECT(vs->ioc));
+     vs->ioc = QIO_CHANNEL(wioc);
++    trace_vnc_client_io_wrap(vs, vs->ioc, "websock");
+ 
+     qio_channel_websock_handshake(wioc,
+                                   vncws_handshake_done,
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 4e1d94f..66783ec 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1118,6 +1118,7 @@ static void vnc_disconnect_start(VncState *vs)
+     if (vs->disconnecting) {
+         return;
+     }
++    trace_vnc_client_disconnect_start(vs, vs->ioc);
+     vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
+     if (vs->ioc_tag) {
+         g_source_remove(vs->ioc_tag);
+@@ -1131,6 +1132,8 @@ void vnc_disconnect_finish(VncState *vs)
+ {
+     int i;
+ 
++    trace_vnc_client_disconnect_finish(vs, vs->ioc);
++
+     vnc_jobs_join(vs); /* Wait encoding jobs */
+ 
+     vnc_lock_output(vs);
+@@ -1184,11 +1187,12 @@ ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
+ {
+     if (ret <= 0) {
+         if (ret == 0) {
+-            VNC_DEBUG("Closing down client sock: EOF\n");
++            trace_vnc_client_eof(vs, vs->ioc);
+             vnc_disconnect_start(vs);
+         } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
+-            VNC_DEBUG("Closing down client sock: ret %zd (%s)\n",
+-                      ret, errp ? error_get_pretty(*errp) : "Unknown");
++            trace_vnc_client_io_error(vs, vs->ioc,
++                                      errp ? error_get_pretty(*errp) :
++                                      "Unknown");
+             vnc_disconnect_start(vs);
+         }
+ 
+@@ -2885,6 +2889,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
+     bool first_client = QTAILQ_EMPTY(&vd->clients);
+     int i;
+ 
++    trace_vnc_client_connect(vs, sioc);
+     vs->sioc = sioc;
+     object_ref(OBJECT(vs->sioc));
+     vs->ioc = QIO_CHANNEL(sioc);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-avoid-pointless-VNC-updates-if-framebuffer-isn-t-.patch b/SOURCES/kvm-ui-avoid-pointless-VNC-updates-if-framebuffer-isn-t-.patch
new file mode 100644
index 0000000..226d370
--- /dev/null
+++ b/SOURCES/kvm-ui-avoid-pointless-VNC-updates-if-framebuffer-isn-t-.patch
@@ -0,0 +1,54 @@
+From 116f4fa9b500042bf89698a2b319be75f28b9423 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:01 +0100
+Subject: [PATCH 07/20] ui: avoid pointless VNC updates if framebuffer isn't
+ dirty
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-7-berrange@redhat.com>
+Patchwork-id: 78888
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 06/17] ui: avoid pointless VNC updates if framebuffer isn't dirty
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+The vnc_update_client() method checks the 'has_dirty' flag to see if there are
+dirty regions that are pending to send to the client. Regardless of this flag,
+if a forced update is requested, updates must be sent. For unknown reasons
+though, the code also tries to sent updates if audio capture is enabled. This
+makes no sense as audio capture state does not impact framebuffer contents, so
+this check is removed.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-5-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 3541b08475d51bddf8aded36576a0ff5a547a978)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 2a2e47c..e159fe6 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -984,7 +984,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+         return 0;
+     }
+ 
+-    if (!vs->has_dirty && !vs->audio_cap && !vs->force_update) {
++    if (!vs->has_dirty && !vs->force_update) {
+         return 0;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-avoid-sign-extension-using-client-width-height.patch b/SOURCES/kvm-ui-avoid-sign-extension-using-client-width-height.patch
new file mode 100644
index 0000000..2678876
--- /dev/null
+++ b/SOURCES/kvm-ui-avoid-sign-extension-using-client-width-height.patch
@@ -0,0 +1,103 @@
+From 31d7d5079364726d5a048d96e1e368173b83ab80 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:11 +0100
+Subject: [PATCH 17/20] ui: avoid sign extension using client width/height
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-17-berrange@redhat.com>
+Patchwork-id: 78889
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 16/17] ui: avoid sign extension using client width/height
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+Pixman returns a signed int for the image width/height, but the VNC
+protocol only permits a unsigned int16. Effective framebuffer size
+is determined by the guest, limited by the video RAM size, so the
+dimensions are unlikely to exceed the range of an unsigned int16,
+but this is not currently validated.
+
+With the current use of 'int' for client width/height, the calculation
+of offsets in vnc_update_throttle_offset() suffers from integer size
+promotion and sign extension, causing coverity warnings
+
+*** CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
+/ui/vnc.c: 979 in vnc_update_throttle_offset()
+973      * than that the client would already suffering awful audio
+974      * glitches, so dropping samples is no worse really).
+975      */
+976     static void vnc_update_throttle_offset(VncState *vs)
+977     {
+978         size_t offset =
+>>>     CID 1385147:  Integer handling issues  (SIGN_EXTENSION)
+>>>     Suspicious implicit sign extension:
+    "vs->client_pf.bytes_per_pixel" with type "unsigned char" (8 bits,
+    unsigned) is promoted in "vs->client_width * vs->client_height *
+    vs->client_pf.bytes_per_pixel" to type "int" (32 bits, signed), then
+    sign-extended to type "unsigned long" (64 bits, unsigned).  If
+    "vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel"
+    is greater than 0x7FFFFFFF, the upper bits of the result will all be 1.
+979             vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
+
+Change client_width / client_height to be a size_t to avoid sign
+extension and integer promotion. Then validate that dimensions are in
+range wrt the RFB protocol u16 limits.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Message-id: 20180118155254.17053-1-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 4c956bd81e2e16afd19d38d1fdeba6d9faa8a1ae)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 9 +++++++++
+ ui/vnc.h | 4 ++--
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index b303930..fec4f4c 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -672,6 +672,11 @@ static void vnc_desktop_resize(VncState *vs)
+         vs->client_height == pixman_image_get_height(vs->vd->server)) {
+         return;
+     }
++
++    assert(pixman_image_get_width(vs->vd->server) < 65536 &&
++           pixman_image_get_width(vs->vd->server) >= 0);
++    assert(pixman_image_get_height(vs->vd->server) < 65536 &&
++           pixman_image_get_height(vs->vd->server) >= 0);
+     vs->client_width = pixman_image_get_width(vs->vd->server);
+     vs->client_height = pixman_image_get_height(vs->vd->server);
+     vnc_lock_output(vs);
+@@ -2490,6 +2495,10 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
+         return 0;
+     }
+ 
++    assert(pixman_image_get_width(vs->vd->server) < 65536 &&
++           pixman_image_get_width(vs->vd->server) >= 0);
++    assert(pixman_image_get_height(vs->vd->server) < 65536 &&
++           pixman_image_get_height(vs->vd->server) >= 0);
+     vs->client_width = pixman_image_get_width(vs->vd->server);
+     vs->client_height = pixman_image_get_height(vs->vd->server);
+     vnc_write_u16(vs, vs->client_width);
+diff --git a/ui/vnc.h b/ui/vnc.h
+index 0c33a5f..bbda054 100644
+--- a/ui/vnc.h
++++ b/ui/vnc.h
+@@ -278,8 +278,8 @@ struct VncState
+     int last_x;
+     int last_y;
+     uint32_t last_bmask;
+-    int client_width;
+-    int client_height;
++    size_t client_width; /* limited to u16 by RFB proto */
++    size_t client_height; /* limited to u16 by RFB proto */
+     VncShareMode share_mode;
+ 
+     uint32_t vnc_encoding;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-correctly-advance-output-buffer-when-writing-SASL.patch b/SOURCES/kvm-ui-correctly-advance-output-buffer-when-writing-SASL.patch
new file mode 100644
index 0000000..955f5b2
--- /dev/null
+++ b/SOURCES/kvm-ui-correctly-advance-output-buffer-when-writing-SASL.patch
@@ -0,0 +1,66 @@
+From 95d2ea23e72d2df6299fcdaa700f5b31b79de741 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:12 +0100
+Subject: [PATCH 18/20] ui: correctly advance output buffer when writing SASL
+ data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-18-berrange@redhat.com>
+Patchwork-id: 78891
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 17/17] ui: correctly advance output buffer when writing SASL data
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+In this previous commit:
+
+  commit 8f61f1c5a6bc06438a1172efa80bc7606594fa07
+  Author: Daniel P. Berrange <berrange@redhat.com>
+  Date:   Mon Dec 18 19:12:20 2017 +0000
+
+    ui: track how much decoded data we consumed when doing SASL encoding
+
+I attempted to fix a flaw with tracking how much data had actually been
+processed when encoding with SASL. With that flaw, the VNC server could
+mistakenly discard queued data that had not been sent.
+
+The fix was not quite right though, because it merely decremented the
+vs->output.offset value. This is effectively discarding data from the
+end of the pending output buffer. We actually need to discard data from
+the start of the pending output buffer. We also want to free memory that
+is no longer required. The correct way to handle this is to use the
+buffer_advance() helper method instead of directly manipulating the
+offset value.
+
+Reported-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Message-id: 20180201155841.27509-1-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 627ebec208a8809818589e17f4fce55a59420ad2)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc-auth-sasl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
+index 74a5f51..fbccca8 100644
+--- a/ui/vnc-auth-sasl.c
++++ b/ui/vnc-auth-sasl.c
+@@ -84,7 +84,7 @@ size_t vnc_client_write_sasl(VncState *vs)
+         } else {
+             vs->force_update_offset -= vs->sasl.encodedRawLength;
+         }
+-        vs->output.offset -= vs->sasl.encodedRawLength;
++        buffer_advance(&vs->output, vs->sasl.encodedRawLength);
+         vs->sasl.encoded = NULL;
+         vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-correctly-reset-framebuffer-update-state-after-pr.patch b/SOURCES/kvm-ui-correctly-reset-framebuffer-update-state-after-pr.patch
new file mode 100644
index 0000000..915d775
--- /dev/null
+++ b/SOURCES/kvm-ui-correctly-reset-framebuffer-update-state-after-pr.patch
@@ -0,0 +1,62 @@
+From 0165d714e9150595c6bceb0d538018d486d7c519 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:04 +0100
+Subject: [PATCH 10/20] ui: correctly reset framebuffer update state after
+ processing dirty regions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-10-berrange@redhat.com>
+Patchwork-id: 78885
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 09/17] ui: correctly reset framebuffer update state after processing dirty regions
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+According to the RFB protocol, a client sends one or more framebuffer update
+requests to the server. The server can reply with a single framebuffer update
+response, that covers all previously received requests. Once the client has
+read this update from the server, it may send further framebuffer update
+requests to monitor future changes. The client is free to delay sending the
+framebuffer update request if it needs to throttle the amount of data it is
+reading from the server.
+
+The QEMU VNC server, however, has never correctly handled the framebuffer
+update requests. Once QEMU has received an update request, it will continue to
+send client updates forever, even if the client hasn't asked for further
+updates. This prevents the client from throttling back data it gets from the
+server. This change fixes the flawed logic such that after a set of updates are
+sent out, QEMU waits for a further update request before sending more data.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-8-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 728a7ac95484a7ba5e624ccbac4c1326571576b0)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 2320421..3707b87 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1031,7 +1031,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+     }
+ 
+     vnc_job_push(job);
+-    vs->update = VNC_STATE_UPDATE_INCREMENTAL;
++    vs->update = VNC_STATE_UPDATE_NONE;
+     vs->has_dirty = 0;
+     return n;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-fix-VNC-client-throttling-when-audio-capture-is-a.patch b/SOURCES/kvm-ui-fix-VNC-client-throttling-when-audio-capture-is-a.patch
new file mode 100644
index 0000000..e9585b2
--- /dev/null
+++ b/SOURCES/kvm-ui-fix-VNC-client-throttling-when-audio-capture-is-a.patch
@@ -0,0 +1,223 @@
+From e961103621520003d54a8c7eac562c2b9e8436db Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:06 +0100
+Subject: [PATCH 12/20] ui: fix VNC client throttling when audio capture is
+ active
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-12-berrange@redhat.com>
+Patchwork-id: 78883
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 11/17] ui: fix VNC client throttling when audio capture is active
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+The VNC server must throttle data sent to the client to prevent the 'output'
+buffer size growing without bound, if the client stops reading data off the
+socket (either maliciously or due to stalled/slow network connection).
+
+The current throttling is very crude because it simply checks whether the
+output buffer offset is zero. This check must be disabled if audio capture is
+enabled, because when streaming audio the output buffer offset will rarely be
+zero due to queued audio data, and so this would starve framebuffer updates.
+
+As a result, the VNC client can cause QEMU to allocate arbitrary amounts of RAM.
+They can first start something in the guest that triggers lots of framebuffer
+updates eg play a youtube video. Then enable audio capture, and simply never
+read data back from the server. This can easily make QEMU's VNC server send
+buffer consume 100MB of RAM per second, until the OOM killer starts reaping
+processes (hopefully the rogue QEMU process, but it might pick others...).
+
+To address this we make the throttling more intelligent, so we can throttle
+when audio capture is active too. To determine how to throttle incremental
+updates or audio data, we calculate a size threshold. Normally the threshold is
+the approximate number of bytes associated with a single complete framebuffer
+update. ie width * height * bytes per pixel. We'll send incremental updates
+until we hit this threshold, at which point we'll stop sending updates until
+data has been written to the wire, causing the output buffer offset to fall
+back below the threshold.
+
+If audio capture is enabled, we increase the size of the threshold to also
+allow for upto 1 seconds worth of audio data samples. ie nchannels * bytes
+per sample * frequency. This allows the output buffer to have a mixture of
+incremental framebuffer updates and audio data queued, but once the threshold
+is exceeded, audio data will be dropped and incremental updates will be
+throttled.
+
+This unbounded memory growth affects all VNC server configurations supported by
+QEMU, with no workaround possible. The mitigating factor is that it can only be
+triggered by a client that has authenticated with the VNC server, and who is
+able to trigger a large quantity of framebuffer updates or audio samples from
+the guest OS. Mostly they'll just succeed in getting the OOM killer to kill
+their own QEMU process, but its possible other processes can get taken out as
+collateral damage.
+
+This is a more general variant of the similar unbounded memory usage flaw in
+the websockets server, that was previously assigned CVE-2017-15268, and fixed
+in 2.11 by:
+
+  commit a7b20a8efa28e5f22c26c06cd06c2f12bc863493
+  Author: Daniel P. Berrange <berrange@redhat.com>
+  Date:   Mon Oct 9 14:43:42 2017 +0100
+
+    io: monitor encoutput buffer size from websocket GSource
+
+This new general memory usage flaw has been assigned CVE-2017-15124, and is
+partially fixed by this patch.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-10-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit e2b72cb6e0443d90d7ab037858cb6834b6cca852)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
+ ui/vnc.h |  6 ++++++
+ 2 files changed, 70 insertions(+), 8 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 2b04050..e132b74 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -60,6 +60,7 @@ static QTAILQ_HEAD(, VncDisplay) vnc_displays =
+ 
+ static int vnc_cursor_define(VncState *vs);
+ static void vnc_release_modifiers(VncState *vs);
++static void vnc_update_throttle_offset(VncState *vs);
+ 
+ static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
+ {
+@@ -766,6 +767,7 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
+         vnc_set_area_dirty(vs->dirty, vd, 0, 0,
+                            vnc_width(vd),
+                            vnc_height(vd));
++        vnc_update_throttle_offset(vs);
+     }
+ }
+ 
+@@ -961,16 +963,67 @@ static int find_and_clear_dirty_height(VncState *vs,
+     return h;
+ }
+ 
++/*
++ * Figure out how much pending data we should allow in the output
++ * buffer before we throttle incremental display updates, and/or
++ * drop audio samples.
++ *
++ * We allow for equiv of 1 full display's worth of FB updates,
++ * and 1 second of audio samples. If audio backlog was larger
++ * than that the client would already suffering awful audio
++ * glitches, so dropping samples is no worse really).
++ */
++static void vnc_update_throttle_offset(VncState *vs)
++{
++    size_t offset =
++        vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
++
++    if (vs->audio_cap) {
++        int freq = vs->as.freq;
++        /* We don't limit freq when reading settings from client, so
++         * it could be upto MAX_INT in size. 48khz is a sensible
++         * upper bound for trustworthy clients */
++        int bps;
++        if (freq > 48000) {
++            freq = 48000;
++        }
++        switch (vs->as.fmt) {
++        default:
++        case  AUD_FMT_U8:
++        case  AUD_FMT_S8:
++            bps = 1;
++            break;
++        case  AUD_FMT_U16:
++        case  AUD_FMT_S16:
++            bps = 2;
++            break;
++        case  AUD_FMT_U32:
++        case  AUD_FMT_S32:
++            bps = 4;
++            break;
++        }
++        offset += freq * bps * vs->as.nchannels;
++    }
++
++    /* Put a floor of 1MB on offset, so that if we have a large pending
++     * buffer and the display is resized to a small size & back again
++     * we don't suddenly apply a tiny send limit
++     */
++    offset = MAX(offset, 1024 * 1024);
++
++    vs->throttle_output_offset = offset;
++}
++
+ static bool vnc_should_update(VncState *vs)
+ {
+     switch (vs->update) {
+     case VNC_STATE_UPDATE_NONE:
+         break;
+     case VNC_STATE_UPDATE_INCREMENTAL:
+-        /* Only allow incremental updates if the output buffer
+-         * is empty, or if audio capture is enabled.
++        /* Only allow incremental updates if the pending send queue
++         * is less than the permitted threshold
+          */
+-        if (!vs->output.offset || vs->audio_cap) {
++        if (vs->output.offset < vs->throttle_output_offset) {
+             return true;
+         }
+         break;
+@@ -1084,11 +1137,13 @@ static void audio_capture(void *opaque, void *buf, int size)
+     VncState *vs = opaque;
+ 
+     vnc_lock_output(vs);
+-    vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
+-    vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
+-    vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
+-    vnc_write_u32(vs, size);
+-    vnc_write(vs, buf, size);
++    if (vs->output.offset < vs->throttle_output_offset) {
++        vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
++        vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
++        vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
++        vnc_write_u32(vs, size);
++        vnc_write(vs, buf, size);
++    }
+     vnc_unlock_output(vs);
+     vnc_flush(vs);
+ }
+@@ -2288,6 +2343,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
+         break;
+     }
+ 
++    vnc_update_throttle_offset(vs);
+     vnc_read_when(vs, protocol_client_msg, 1);
+     return 0;
+ }
+diff --git a/ui/vnc.h b/ui/vnc.h
+index b9d310e..8fe6959 100644
+--- a/ui/vnc.h
++++ b/ui/vnc.h
+@@ -298,6 +298,12 @@ struct VncState
+ 
+     VncClientInfo *info;
+ 
++    /* We allow multiple incremental updates or audio capture
++     * samples to be queued in output buffer, provided the
++     * buffer size doesn't exceed this threshold. The value
++     * is calculating dynamically based on framebuffer size
++     * and audio sample settings in vnc_update_throttle_offset() */
++    size_t throttle_output_offset;
+     Buffer output;
+     Buffer input;
+     /* current output mode information */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-fix-VNC-client-throttling-when-forced-update-is-r.patch b/SOURCES/kvm-ui-fix-VNC-client-throttling-when-forced-update-is-r.patch
new file mode 100644
index 0000000..79bb35e
--- /dev/null
+++ b/SOURCES/kvm-ui-fix-VNC-client-throttling-when-forced-update-is-r.patch
@@ -0,0 +1,201 @@
+From bf44407132cb0c39e59bb2f7f72bde9a7b085c70 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:07 +0100
+Subject: [PATCH 13/20] ui: fix VNC client throttling when forced update is
+ requested
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-13-berrange@redhat.com>
+Patchwork-id: 78882
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 12/17] ui: fix VNC client throttling when forced update is requested
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+The VNC server must throttle data sent to the client to prevent the 'output'
+buffer size growing without bound, if the client stops reading data off the
+socket (either maliciously or due to stalled/slow network connection).
+
+The current throttling is very crude because it simply checks whether the
+output buffer offset is zero. This check is disabled if the client has requested
+a forced update, because we want to send these as soon as possible.
+
+As a result, the VNC client can cause QEMU to allocate arbitrary amounts of RAM.
+They can first start something in the guest that triggers lots of framebuffer
+updates eg play a youtube video. Then repeatedly send full framebuffer update
+requests, but never read data back from the server. This can easily make QEMU's
+VNC server send buffer consume 100MB of RAM per second, until the OOM killer
+starts reaping processes (hopefully the rogue QEMU process, but it might pick
+others...).
+
+To address this we make the throttling more intelligent, so we can throttle
+full updates. When we get a forced update request, we keep track of exactly how
+much data we put on the output buffer. We will not process a subsequent forced
+update request until this data has been fully sent on the wire. We always allow
+one forced update request to be in flight, regardless of what data is queued
+for incremental updates or audio data. The slight complication is that we do
+not initially know how much data an update will send, as this is done in the
+background by the VNC job thread. So we must track the fact that the job thread
+has an update pending, and not process any further updates until this job is
+has been completed & put data on the output buffer.
+
+This unbounded memory growth affects all VNC server configurations supported by
+QEMU, with no workaround possible. The mitigating factor is that it can only be
+triggered by a client that has authenticated with the VNC server, and who is
+able to trigger a large quantity of framebuffer updates or audio samples from
+the guest OS. Mostly they'll just succeed in getting the OOM killer to kill
+their own QEMU process, but its possible other processes can get taken out as
+collateral damage.
+
+This is a more general variant of the similar unbounded memory usage flaw in
+the websockets server, that was previously assigned CVE-2017-15268, and fixed
+in 2.11 by:
+
+  commit a7b20a8efa28e5f22c26c06cd06c2f12bc863493
+  Author: Daniel P. Berrange <berrange@redhat.com>
+  Date:   Mon Oct 9 14:43:42 2017 +0100
+
+    io: monitor encoutput buffer size from websocket GSource
+
+This new general memory usage flaw has been assigned CVE-2017-15124, and is
+partially fixed by this patch.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-11-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit ada8d2e4369ea49677d8672ac81bce73eefd5b54)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc-auth-sasl.c |  5 +++++
+ ui/vnc-jobs.c      |  5 +++++
+ ui/vnc.c           | 28 ++++++++++++++++++++++++----
+ ui/vnc.h           |  7 +++++++
+ 4 files changed, 41 insertions(+), 4 deletions(-)
+
+diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
+index 761493b..8c1cdde 100644
+--- a/ui/vnc-auth-sasl.c
++++ b/ui/vnc-auth-sasl.c
+@@ -79,6 +79,11 @@ long vnc_client_write_sasl(VncState *vs)
+ 
+     vs->sasl.encodedOffset += ret;
+     if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {
++        if (vs->sasl.encodedRawLength >= vs->force_update_offset) {
++            vs->force_update_offset = 0;
++        } else {
++            vs->force_update_offset -= vs->sasl.encodedRawLength;
++        }
+         vs->output.offset -= vs->sasl.encodedRawLength;
+         vs->sasl.encoded = NULL;
+         vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
+diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
+index f786777..e326679 100644
+--- a/ui/vnc-jobs.c
++++ b/ui/vnc-jobs.c
+@@ -152,6 +152,11 @@ void vnc_jobs_consume_buffer(VncState *vs)
+                 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
+         }
+         buffer_move(&vs->output, &vs->jobs_buffer);
++
++        if (vs->job_update == VNC_STATE_UPDATE_FORCE) {
++            vs->force_update_offset = vs->output.offset;
++        }
++        vs->job_update = VNC_STATE_UPDATE_NONE;
+     }
+     flush = vs->ioc != NULL && vs->abort != true;
+     vnc_unlock_output(vs);
+diff --git a/ui/vnc.c b/ui/vnc.c
+index e132b74..7f2210f 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1021,14 +1021,28 @@ static bool vnc_should_update(VncState *vs)
+         break;
+     case VNC_STATE_UPDATE_INCREMENTAL:
+         /* Only allow incremental updates if the pending send queue
+-         * is less than the permitted threshold
++         * is less than the permitted threshold, and the job worker
++         * is completely idle.
+          */
+-        if (vs->output.offset < vs->throttle_output_offset) {
++        if (vs->output.offset < vs->throttle_output_offset &&
++            vs->job_update == VNC_STATE_UPDATE_NONE) {
+             return true;
+         }
+         break;
+     case VNC_STATE_UPDATE_FORCE:
+-        return true;
++        /* Only allow forced updates if the pending send queue
++         * does not contain a previous forced update, and the
++         * job worker is completely idle.
++         *
++         * Note this means we'll queue a forced update, even if
++         * the output buffer size is otherwise over the throttle
++         * output limit.
++         */
++        if (vs->force_update_offset == 0 &&
++            vs->job_update == VNC_STATE_UPDATE_NONE) {
++            return true;
++        }
++        break;
+     }
+     return false;
+ }
+@@ -1096,8 +1110,9 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+         }
+     }
+ 
+-    vnc_job_push(job);
++    vs->job_update = vs->update;
+     vs->update = VNC_STATE_UPDATE_NONE;
++    vnc_job_push(job);
+     vs->has_dirty = 0;
+     return n;
+ }
+@@ -1332,6 +1347,11 @@ static ssize_t vnc_client_write_plain(VncState *vs)
+     if (!ret)
+         return 0;
+ 
++    if (ret >= vs->force_update_offset) {
++        vs->force_update_offset = 0;
++    } else {
++        vs->force_update_offset -= ret;
++    }
+     buffer_advance(&vs->output, ret);
+ 
+     if (vs->output.offset == 0) {
+diff --git a/ui/vnc.h b/ui/vnc.h
+index 8fe6959..3f4cd4d 100644
+--- a/ui/vnc.h
++++ b/ui/vnc.h
+@@ -271,6 +271,7 @@ struct VncState
+ 
+     VncDisplay *vd;
+     VncStateUpdate update; /* Most recent pending request from client */
++    VncStateUpdate job_update; /* Currently processed by job thread */
+     int has_dirty;
+     uint32_t features;
+     int absolute;
+@@ -298,6 +299,12 @@ struct VncState
+ 
+     VncClientInfo *info;
+ 
++    /* Job thread bottom half has put data for a forced update
++     * into the output buffer. This offset points to the end of
++     * the update data in the output buffer. This lets us determine
++     * when a force update is fully sent to the client, allowing
++     * us to process further forced updates. */
++    size_t force_update_offset;
+     /* We allow multiple incremental updates or audio capture
+      * samples to be queued in output buffer, provided the
+      * buffer size doesn't exceed this threshold. The value
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-fix-dcl-unregister.patch b/SOURCES/kvm-ui-fix-dcl-unregister.patch
new file mode 100644
index 0000000..ae4f07e
--- /dev/null
+++ b/SOURCES/kvm-ui-fix-dcl-unregister.patch
@@ -0,0 +1,48 @@
+From 0632da4d9e2ec1e445840299f1e0fbda7a61bef4 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 12 Jan 2018 13:47:48 +0100
+Subject: [PATCH 07/12] ui: fix dcl unregister
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20180112134748.13701-2-kraxel@redhat.com>
+Patchwork-id: 78568
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] ui: fix dcl unregister
+Bugzilla: 1510809
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+register checks for dcl->ds being NULL, to avoid registering
+the same dcl twice.
+
+Therefore dcl->ds must be cleared on unregister, otherwise
+un-registering and re-registering doesn't work.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1510809
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171109105154.29414-1-kraxel@redhat.com
+(cherry picked from commit 777c5f1e436d334a57b650b6951c13d8d2799df0)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/console.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/ui/console.c b/ui/console.c
+index 2616f9c..6967fd4 100644
+--- a/ui/console.c
++++ b/ui/console.c
+@@ -1489,6 +1489,7 @@ void unregister_displaychangelistener(DisplayChangeListener *dcl)
+         dcl->con->dcls--;
+     }
+     QLIST_REMOVE(dcl, next);
++    dcl->ds = NULL;
+     gui_setup_refresh(ds);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-introduce-enum-to-track-VNC-client-framebuffer-up.patch b/SOURCES/kvm-ui-introduce-enum-to-track-VNC-client-framebuffer-up.patch
new file mode 100644
index 0000000..f04cb75
--- /dev/null
+++ b/SOURCES/kvm-ui-introduce-enum-to-track-VNC-client-framebuffer-up.patch
@@ -0,0 +1,121 @@
+From 408b757578e8d9b96756c3753fb6661cd812d62f Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:03 +0100
+Subject: [PATCH 09/20] ui: introduce enum to track VNC client framebuffer
+ update request state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-9-berrange@redhat.com>
+Patchwork-id: 78879
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 08/17] ui: introduce enum to track VNC client framebuffer update request state
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+Currently the VNC servers tracks whether a client has requested an incremental
+or forced update with two boolean flags. There are only really 3 distinct
+states to track, so create an enum to more accurately reflect permitted states.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-7-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit fef1bbadfb2c3027208eb3d14b43e1bdb51166ca)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 21 +++++++++++----------
+ ui/vnc.h |  9 +++++++--
+ 2 files changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index e159fe6..2320421 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -975,16 +975,17 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+     }
+ 
+     vs->has_dirty += has_dirty;
+-    if (!vs->need_update) {
++    if (vs->update == VNC_STATE_UPDATE_NONE) {
+         return 0;
+     }
+ 
+-    if (vs->output.offset && !vs->audio_cap && !vs->force_update) {
++    if (vs->output.offset && !vs->audio_cap &&
++        vs->update != VNC_STATE_UPDATE_FORCE) {
+         /* kernel send buffers are full -> drop frames to throttle */
+         return 0;
+     }
+ 
+-    if (!vs->has_dirty && !vs->force_update) {
++    if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
+         return 0;
+     }
+ 
+@@ -1030,7 +1031,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+     }
+ 
+     vnc_job_push(job);
+-    vs->force_update = 0;
++    vs->update = VNC_STATE_UPDATE_INCREMENTAL;
+     vs->has_dirty = 0;
+     return n;
+ }
+@@ -1869,14 +1870,14 @@ static void ext_key_event(VncState *vs, int down,
+ static void framebuffer_update_request(VncState *vs, int incremental,
+                                        int x, int y, int w, int h)
+ {
+-    vs->need_update = 1;
+-
+     if (incremental) {
+-        return;
++        if (vs->update != VNC_STATE_UPDATE_FORCE) {
++            vs->update = VNC_STATE_UPDATE_INCREMENTAL;
++        }
++    } else {
++        vs->update = VNC_STATE_UPDATE_FORCE;
++        vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
+     }
+-
+-    vs->force_update = 1;
+-    vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
+ }
+ 
+ static void send_ext_key_event_ack(VncState *vs)
+diff --git a/ui/vnc.h b/ui/vnc.h
+index 694cf32..b9d310e 100644
+--- a/ui/vnc.h
++++ b/ui/vnc.h
+@@ -252,6 +252,12 @@ struct VncJob
+     QTAILQ_ENTRY(VncJob) next;
+ };
+ 
++typedef enum {
++    VNC_STATE_UPDATE_NONE,
++    VNC_STATE_UPDATE_INCREMENTAL,
++    VNC_STATE_UPDATE_FORCE,
++} VncStateUpdate;
++
+ struct VncState
+ {
+     QIOChannelSocket *sioc; /* The underlying socket */
+@@ -264,8 +270,7 @@ struct VncState
+                            * vnc-jobs-async.c */
+ 
+     VncDisplay *vd;
+-    int need_update;
+-    int force_update;
++    VncStateUpdate update; /* Most recent pending request from client */
+     int has_dirty;
+     uint32_t features;
+     int absolute;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-mix-misleading-comments-return-types-of-VNC-I-O-h.patch b/SOURCES/kvm-ui-mix-misleading-comments-return-types-of-VNC-I-O-h.patch
new file mode 100644
index 0000000..bb46077
--- /dev/null
+++ b/SOURCES/kvm-ui-mix-misleading-comments-return-types-of-VNC-I-O-h.patch
@@ -0,0 +1,193 @@
+From a04141c5a3565ac437ff7093f36ddf0fb60acdd5 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:10 +0100
+Subject: [PATCH 16/20] ui: mix misleading comments & return types of VNC I/O
+ helper methods
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-16-berrange@redhat.com>
+Patchwork-id: 78892
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 15/17] ui: mix misleading comments & return types of VNC I/O helper methods
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+While the QIOChannel APIs for reading/writing data return ssize_t, with negative
+value indicating an error, the VNC code passes this return value through the
+vnc_client_io_error() method. This detects the error condition, disconnects the
+client and returns 0 to indicate error. Thus all the VNC helper methods should
+return size_t (unsigned), and misleading comments which refer to the possibility
+of negative return values need fixing.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-14-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 30b80fd5269257f55203b7072c505b4ebaab5115)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc-auth-sasl.c |  8 ++++----
+ ui/vnc-auth-sasl.h |  4 ++--
+ ui/vnc.c           | 29 +++++++++++++++--------------
+ ui/vnc.h           |  6 +++---
+ 4 files changed, 24 insertions(+), 23 deletions(-)
+
+diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
+index 8c1cdde..74a5f51 100644
+--- a/ui/vnc-auth-sasl.c
++++ b/ui/vnc-auth-sasl.c
+@@ -48,9 +48,9 @@ void vnc_sasl_client_cleanup(VncState *vs)
+ }
+ 
+ 
+-long vnc_client_write_sasl(VncState *vs)
++size_t vnc_client_write_sasl(VncState *vs)
+ {
+-    long ret;
++    size_t ret;
+ 
+     VNC_DEBUG("Write SASL: Pending output %p size %zd offset %zd "
+               "Encoded: %p size %d offset %d\n",
+@@ -106,9 +106,9 @@ long vnc_client_write_sasl(VncState *vs)
+ }
+ 
+ 
+-long vnc_client_read_sasl(VncState *vs)
++size_t vnc_client_read_sasl(VncState *vs)
+ {
+-    long ret;
++    size_t ret;
+     uint8_t encoded[4096];
+     const char *decoded;
+     unsigned int decodedLen;
+diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h
+index b9d8de1..2ae224e 100644
+--- a/ui/vnc-auth-sasl.h
++++ b/ui/vnc-auth-sasl.h
+@@ -65,8 +65,8 @@ struct VncDisplaySASL {
+ 
+ void vnc_sasl_client_cleanup(VncState *vs);
+ 
+-long vnc_client_read_sasl(VncState *vs);
+-long vnc_client_write_sasl(VncState *vs);
++size_t vnc_client_read_sasl(VncState *vs);
++size_t vnc_client_write_sasl(VncState *vs);
+ 
+ void start_auth_sasl(VncState *vs);
+ 
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 26f58bc..b303930 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1272,7 +1272,7 @@ void vnc_disconnect_finish(VncState *vs)
+     g_free(vs);
+ }
+ 
+-ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
++size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
+ {
+     if (ret <= 0) {
+         if (ret == 0) {
+@@ -1315,9 +1315,9 @@ void vnc_client_error(VncState *vs)
+  *
+  * Returns the number of bytes written, which may be less than
+  * the requested 'datalen' if the socket would block. Returns
+- * -1 on error, and disconnects the client socket.
++ * 0 on I/O error, and disconnects the client socket.
+  */
+-ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
++size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
+ {
+     Error *err = NULL;
+     ssize_t ret;
+@@ -1335,13 +1335,13 @@ ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
+  * will switch the FD poll() handler back to read monitoring.
+  *
+  * Returns the number of bytes written, which may be less than
+- * the buffered output data if the socket would block. Returns
+- * -1 on error, and disconnects the client socket.
++ * the buffered output data if the socket would block.  Returns
++ * 0 on I/O error, and disconnects the client socket.
+  */
+-static ssize_t vnc_client_write_plain(VncState *vs)
++static size_t vnc_client_write_plain(VncState *vs)
+ {
+     size_t offset;
+-    ssize_t ret;
++    size_t ret;
+ 
+ #ifdef CONFIG_VNC_SASL
+     VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
+@@ -1442,9 +1442,9 @@ void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
+  *
+  * Returns the number of bytes read, which may be less than
+  * the requested 'datalen' if the socket would block. Returns
+- * -1 on error, and disconnects the client socket.
++ * 0 on I/O error or EOF, and disconnects the client socket.
+  */
+-ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
++size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
+ {
+     ssize_t ret;
+     Error *err = NULL;
+@@ -1460,12 +1460,13 @@ ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
+  * when not using any SASL SSF encryption layers. Will read as much
+  * data as possible without blocking.
+  *
+- * Returns the number of bytes read. Returns -1 on error, and
+- * disconnects the client socket.
++ * Returns the number of bytes read, which may be less than
++ * the requested 'datalen' if the socket would block. Returns
++ * 0 on I/O error or EOF, and disconnects the client socket.
+  */
+-static ssize_t vnc_client_read_plain(VncState *vs)
++static size_t vnc_client_read_plain(VncState *vs)
+ {
+-    ssize_t ret;
++    size_t ret;
+     VNC_DEBUG("Read plain %p size %zd offset %zd\n",
+               vs->input.buffer, vs->input.capacity, vs->input.offset);
+     buffer_reserve(&vs->input, 4096);
+@@ -1491,7 +1492,7 @@ static void vnc_jobs_bh(void *opaque)
+  */
+ static int vnc_client_read(VncState *vs)
+ {
+-    ssize_t ret;
++    size_t ret;
+ 
+ #ifdef CONFIG_VNC_SASL
+     if (vs->sasl.conn && vs->sasl.runSSF)
+diff --git a/ui/vnc.h b/ui/vnc.h
+index 3f4cd4d..0c33a5f 100644
+--- a/ui/vnc.h
++++ b/ui/vnc.h
+@@ -524,8 +524,8 @@ gboolean vnc_client_io(QIOChannel *ioc,
+                        GIOCondition condition,
+                        void *opaque);
+ 
+-ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
+-ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
++size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
++size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
+ 
+ /* Protocol I/O functions */
+ void vnc_write(VncState *vs, const void *data, size_t len);
+@@ -544,7 +544,7 @@ uint32_t read_u32(uint8_t *data, size_t offset);
+ 
+ /* Protocol stage functions */
+ void vnc_client_error(VncState *vs);
+-ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp);
++size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp);
+ 
+ void start_client_init(VncState *vs);
+ void start_auth_vnc(VncState *vs);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-place-a-hard-cap-on-VNC-server-output-buffer-size.patch b/SOURCES/kvm-ui-place-a-hard-cap-on-VNC-server-output-buffer-size.patch
new file mode 100644
index 0000000..be78da0
--- /dev/null
+++ b/SOURCES/kvm-ui-place-a-hard-cap-on-VNC-server-output-buffer-size.patch
@@ -0,0 +1,105 @@
+From e3dbec9458073f71290e226ede55734ac4fe7e5d Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:08 +0100
+Subject: [PATCH 14/20] ui: place a hard cap on VNC server output buffer size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-14-berrange@redhat.com>
+Patchwork-id: 78890
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 13/17] ui: place a hard cap on VNC server output buffer size
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+The previous patches fix problems with throttling of forced framebuffer updates
+and audio data capture that would cause the QEMU output buffer size to grow
+without bound. Those fixes are graceful in that once the client catches up with
+reading data from the server, everything continues operating normally.
+
+There is some data which the server sends to the client that is impractical to
+throttle. Specifically there are various pseudo framebuffer update encodings to
+inform the client of things like desktop resizes, pointer changes, audio
+playback start/stop, LED state and so on. These generally only involve sending
+a very small amount of data to the client, but a malicious guest might be able
+to do things that trigger these changes at a very high rate. Throttling them is
+not practical as missed or delayed events would cause broken behaviour for the
+client.
+
+This patch thus takes a more forceful approach of setting an absolute upper
+bound on the amount of data we permit to be present in the output buffer at
+any time. The previous patch set a threshold for throttling the output buffer
+by allowing an amount of data equivalent to one complete framebuffer update and
+one seconds worth of audio data. On top of this it allowed for one further
+forced framebuffer update to be queued.
+
+To be conservative, we thus take that throttling threshold and multiply it by
+5 to form an absolute upper bound. If this bound is hit during vnc_write() we
+forceably disconnect the client, refusing to queue further data. This limit is
+high enough that it should never be hit unless a malicious client is trying to
+exploit the sever, or the network is completely saturated preventing any sending
+of data on the socket.
+
+This completes the fix for CVE-2017-15124 started in the previous patches.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-12-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit f887cf165db20f405cb8805c716bd363aaadf815)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 7f2210f..a7aff91 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -1521,8 +1521,37 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
+ }
+ 
+ 
++/*
++ * Scale factor to apply to vs->throttle_output_offset when checking for
++ * hard limit. Worst case normal usage could be x2, if we have a complete
++ * incremental update and complete forced update in the output buffer.
++ * So x3 should be good enough, but we pick x5 to be conservative and thus
++ * (hopefully) never trigger incorrectly.
++ */
++#define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
++
+ void vnc_write(VncState *vs, const void *data, size_t len)
+ {
++    if (vs->disconnecting) {
++        return;
++    }
++    /* Protection against malicious client/guest to prevent our output
++     * buffer growing without bound if client stops reading data. This
++     * should rarely trigger, because we have earlier throttling code
++     * which stops issuing framebuffer updates and drops audio data
++     * if the throttle_output_offset value is exceeded. So we only reach
++     * this higher level if a huge number of pseudo-encodings get
++     * triggered while data can't be sent on the socket.
++     *
++     * NB throttle_output_offset can be zero during early protocol
++     * handshake, or from the job thread's VncState clone
++     */
++    if (vs->throttle_output_offset != 0 &&
++        vs->output.offset > (vs->throttle_output_offset *
++                             VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
++        vnc_disconnect_start(vs);
++        return;
++    }
+     buffer_reserve(&vs->output, len);
+ 
+     if (vs->ioc != NULL && buffer_empty(&vs->output)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-refactor-code-for-determining-if-an-update-should.patch b/SOURCES/kvm-ui-refactor-code-for-determining-if-an-update-should.patch
new file mode 100644
index 0000000..1500b9c
--- /dev/null
+++ b/SOURCES/kvm-ui-refactor-code-for-determining-if-an-update-should.patch
@@ -0,0 +1,83 @@
+From c13d50cb093c4409dd2db6023fc0f6adfe4927d8 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:05 +0100
+Subject: [PATCH 11/20] ui: refactor code for determining if an update should
+ be sent to the client
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-11-berrange@redhat.com>
+Patchwork-id: 78887
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 10/17] ui: refactor code for determining if an update should be sent to the client
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+The logic for determining if it is possible to send an update to the client
+will become more complicated shortly, so pull it out into a separate method
+for easier extension later.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-9-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 0bad834228b9ee63e4239108d02dcb94568254d0)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 3707b87..2b04050 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -961,6 +961,25 @@ static int find_and_clear_dirty_height(VncState *vs,
+     return h;
+ }
+ 
++static bool vnc_should_update(VncState *vs)
++{
++    switch (vs->update) {
++    case VNC_STATE_UPDATE_NONE:
++        break;
++    case VNC_STATE_UPDATE_INCREMENTAL:
++        /* Only allow incremental updates if the output buffer
++         * is empty, or if audio capture is enabled.
++         */
++        if (!vs->output.offset || vs->audio_cap) {
++            return true;
++        }
++        break;
++    case VNC_STATE_UPDATE_FORCE:
++        return true;
++    }
++    return false;
++}
++
+ static int vnc_update_client(VncState *vs, int has_dirty)
+ {
+     VncDisplay *vd = vs->vd;
+@@ -975,13 +994,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+     }
+ 
+     vs->has_dirty += has_dirty;
+-    if (vs->update == VNC_STATE_UPDATE_NONE) {
+-        return 0;
+-    }
+-
+-    if (vs->output.offset && !vs->audio_cap &&
+-        vs->update != VNC_STATE_UPDATE_FORCE) {
+-        /* kernel send buffers are full -> drop frames to throttle */
++    if (!vnc_should_update(vs)) {
+         return 0;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-remove-redundant-indentation-in-vnc_client_update.patch b/SOURCES/kvm-ui-remove-redundant-indentation-in-vnc_client_update.patch
new file mode 100644
index 0000000..aeb1123
--- /dev/null
+++ b/SOURCES/kvm-ui-remove-redundant-indentation-in-vnc_client_update.patch
@@ -0,0 +1,172 @@
+From aefded16955d95827bab7b8145388b6de872da38 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:00 +0100
+Subject: [PATCH 06/20] ui: remove redundant indentation in vnc_client_update
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-6-berrange@redhat.com>
+Patchwork-id: 78876
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 05/17] ui: remove redundant indentation in vnc_client_update
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+Now that previous dead / unreachable code has been removed, we can simplify
+the indentation in the vnc_client_update method.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-4-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit b939eb89b6f320544a9328fa908d881d0024c1ee)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 112 ++++++++++++++++++++++++++++++++-------------------------------
+ 1 file changed, 57 insertions(+), 55 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 1d2b3a8..2a2e47c 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -963,74 +963,76 @@ static int find_and_clear_dirty_height(VncState *vs,
+ 
+ static int vnc_update_client(VncState *vs, int has_dirty)
+ {
++    VncDisplay *vd = vs->vd;
++    VncJob *job;
++    int y;
++    int height, width;
++    int n = 0;
++
+     if (vs->disconnecting) {
+         vnc_disconnect_finish(vs);
+         return 0;
+     }
+ 
+     vs->has_dirty += has_dirty;
+-    if (vs->need_update) {
+-        VncDisplay *vd = vs->vd;
+-        VncJob *job;
+-        int y;
+-        int height, width;
+-        int n = 0;
+-
+-        if (vs->output.offset && !vs->audio_cap && !vs->force_update)
+-            /* kernel send buffers are full -> drop frames to throttle */
+-            return 0;
++    if (!vs->need_update) {
++        return 0;
++    }
+ 
+-        if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
+-            return 0;
++    if (vs->output.offset && !vs->audio_cap && !vs->force_update) {
++        /* kernel send buffers are full -> drop frames to throttle */
++        return 0;
++    }
+ 
+-        /*
+-         * Send screen updates to the vnc client using the server
+-         * surface and server dirty map.  guest surface updates
+-         * happening in parallel don't disturb us, the next pass will
+-         * send them to the client.
+-         */
+-        job = vnc_job_new(vs);
+-
+-        height = pixman_image_get_height(vd->server);
+-        width = pixman_image_get_width(vd->server);
+-
+-        y = 0;
+-        for (;;) {
+-            int x, h;
+-            unsigned long x2;
+-            unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
+-                                                 height * VNC_DIRTY_BPL(vs),
+-                                                 y * VNC_DIRTY_BPL(vs));
+-            if (offset == height * VNC_DIRTY_BPL(vs)) {
+-                /* no more dirty bits */
++    if (!vs->has_dirty && !vs->audio_cap && !vs->force_update) {
++        return 0;
++    }
++
++    /*
++     * Send screen updates to the vnc client using the server
++     * surface and server dirty map.  guest surface updates
++     * happening in parallel don't disturb us, the next pass will
++     * send them to the client.
++     */
++    job = vnc_job_new(vs);
++
++    height = pixman_image_get_height(vd->server);
++    width = pixman_image_get_width(vd->server);
++
++    y = 0;
++    for (;;) {
++        int x, h;
++        unsigned long x2;
++        unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
++                                             height * VNC_DIRTY_BPL(vs),
++                                             y * VNC_DIRTY_BPL(vs));
++        if (offset == height * VNC_DIRTY_BPL(vs)) {
++            /* no more dirty bits */
++            break;
++        }
++        y = offset / VNC_DIRTY_BPL(vs);
++        x = offset % VNC_DIRTY_BPL(vs);
++        x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
++                                VNC_DIRTY_BPL(vs), x);
++        bitmap_clear(vs->dirty[y], x, x2 - x);
++        h = find_and_clear_dirty_height(vs, y, x, x2, height);
++        x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
++        if (x2 > x) {
++            n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
++                                  (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
++        }
++        if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
++            y += h;
++            if (y == height) {
+                 break;
+             }
+-            y = offset / VNC_DIRTY_BPL(vs);
+-            x = offset % VNC_DIRTY_BPL(vs);
+-            x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
+-                                    VNC_DIRTY_BPL(vs), x);
+-            bitmap_clear(vs->dirty[y], x, x2 - x);
+-            h = find_and_clear_dirty_height(vs, y, x, x2, height);
+-            x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
+-            if (x2 > x) {
+-                n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
+-                                      (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
+-            }
+-            if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
+-                y += h;
+-                if (y == height) {
+-                    break;
+-                }
+-            }
+         }
+-
+-        vnc_job_push(job);
+-        vs->force_update = 0;
+-        vs->has_dirty = 0;
+-        return n;
+     }
+ 
+-    return 0;
++    vnc_job_push(job);
++    vs->force_update = 0;
++    vs->has_dirty = 0;
++    return n;
+ }
+ 
+ /* audio */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-remove-sync-parameter-from-vnc_update_client.patch b/SOURCES/kvm-ui-remove-sync-parameter-from-vnc_update_client.patch
new file mode 100644
index 0000000..2f0e485
--- /dev/null
+++ b/SOURCES/kvm-ui-remove-sync-parameter-from-vnc_update_client.patch
@@ -0,0 +1,86 @@
+From 5f140826bcb807ea47063b0b65d62b8ebc4a2c7f Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:09:58 +0100
+Subject: [PATCH 04/20] ui: remove 'sync' parameter from vnc_update_client
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-4-berrange@redhat.com>
+Patchwork-id: 78878
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 03/17] ui: remove 'sync' parameter from vnc_update_client
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+There is only one caller of vnc_update_client and that always passes false
+for the 'sync' parameter.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-2-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 6af998db05aec9af95a06f84ad94f1b96785e667)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 1275bba..6ed738b 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -596,7 +596,7 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
+    3) resolutions > 1024
+ */
+ 
+-static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
++static int vnc_update_client(VncState *vs, int has_dirty);
+ static void vnc_disconnect_start(VncState *vs);
+ 
+ static void vnc_colordepth(VncState *vs);
+@@ -961,7 +961,7 @@ static int find_and_clear_dirty_height(VncState *vs,
+     return h;
+ }
+ 
+-static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
++static int vnc_update_client(VncState *vs, int has_dirty)
+ {
+     if (vs->disconnecting) {
+         vnc_disconnect_finish(vs);
+@@ -1025,9 +1025,6 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
+         }
+ 
+         vnc_job_push(job);
+-        if (sync) {
+-            vnc_jobs_join(vs);
+-        }
+         vs->force_update = 0;
+         vs->has_dirty = 0;
+         return n;
+@@ -1035,8 +1032,6 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
+ 
+     if (vs->disconnecting) {
+         vnc_disconnect_finish(vs);
+-    } else if (sync) {
+-        vnc_jobs_join(vs);
+     }
+ 
+     return 0;
+@@ -2863,7 +2858,7 @@ static void vnc_refresh(DisplayChangeListener *dcl)
+     vnc_unlock_display(vd);
+ 
+     QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
+-        rects += vnc_update_client(vs, has_dirty, false);
++        rects += vnc_update_client(vs, has_dirty);
+         /* vs might be free()ed here */
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-remove-unreachable-code-in-vnc_update_client.patch b/SOURCES/kvm-ui-remove-unreachable-code-in-vnc_update_client.patch
new file mode 100644
index 0000000..da5cdc0
--- /dev/null
+++ b/SOURCES/kvm-ui-remove-unreachable-code-in-vnc_update_client.patch
@@ -0,0 +1,72 @@
+From 11a0ca31dff62ede8b272420cc527f8e4dd102a7 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:09:59 +0100
+Subject: [PATCH 05/20] ui: remove unreachable code in vnc_update_client
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-5-berrange@redhat.com>
+Patchwork-id: 78875
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 04/17] ui: remove unreachable code in vnc_update_client
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+A previous commit:
+
+  commit 5a8be0f73d6f60ff08746377eb09ca459f39deab
+  Author: Gerd Hoffmann <kraxel@redhat.com>
+  Date:   Wed Jul 13 12:21:20 2016 +0200
+
+    vnc: make sure we finish disconnect
+
+Added a check for vs->disconnecting at the very start of the
+vnc_update_client method. This means that the very next "if"
+statement check for !vs->disconnecting always evaluates true,
+and is thus redundant. This in turn means the vs->disconnecting
+check at the very end of the method never evaluates true, and
+is thus unreachable code.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-3-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit c53df961617736f94731d94b62c2954c261d2bae)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 6ed738b..1d2b3a8 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -969,7 +969,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+     }
+ 
+     vs->has_dirty += has_dirty;
+-    if (vs->need_update && !vs->disconnecting) {
++    if (vs->need_update) {
+         VncDisplay *vd = vs->vd;
+         VncJob *job;
+         int y;
+@@ -1030,10 +1030,6 @@ static int vnc_update_client(VncState *vs, int has_dirty)
+         return n;
+     }
+ 
+-    if (vs->disconnecting) {
+-        vnc_disconnect_finish(vs);
+-    }
+-
+     return 0;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ui-track-how-much-decoded-data-we-consumed-when-doin.patch b/SOURCES/kvm-ui-track-how-much-decoded-data-we-consumed-when-doin.patch
new file mode 100644
index 0000000..f7242d2
--- /dev/null
+++ b/SOURCES/kvm-ui-track-how-much-decoded-data-we-consumed-when-doin.patch
@@ -0,0 +1,84 @@
+From 61e62d3b4e8d0eb3715cbffcec580d5d236421a0 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Mon, 5 Feb 2018 11:10:02 +0100
+Subject: [PATCH 08/20] ui: track how much decoded data we consumed when doing
+ SASL encoding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20180205111012.6210-8-berrange@redhat.com>
+Patchwork-id: 78877
+O-Subject: [RHV-7.5 qemu-kvm-rhev PATCH v2 07/17] ui: track how much decoded data we consumed when doing SASL encoding
+Bugzilla: 1527404
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+When we encode data for writing with SASL, we encode the entire pending output
+buffer. The subsequent write, however, may not be able to send the full encoded
+data in one go though, particularly with a slow network. So we delay setting the
+output buffer offset back to zero until all the SASL encoded data is sent.
+
+Between encoding the data and completing sending of the SASL encoded data,
+however, more data might have been placed on the pending output buffer. So it
+is not valid to set offset back to zero. Instead we must keep track of how much
+data we consumed during encoding and subtract only that amount.
+
+With the current bug we would be throwing away some pending data without having
+sent it at all. By sheer luck this did not previously cause any serious problem
+because appending data to the send buffer is always an atomic action, so we
+only ever throw away complete RFB protocol messages. In the case of frame buffer
+updates we'd catch up fairly quickly, so no obvious problem was visible.
+
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20171218191228.31018-6-berrange@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 8f61f1c5a6bc06438a1172efa80bc7606594fa07)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ ui/vnc-auth-sasl.c | 3 ++-
+ ui/vnc-auth-sasl.h | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
+index 23f2828..761493b 100644
+--- a/ui/vnc-auth-sasl.c
++++ b/ui/vnc-auth-sasl.c
+@@ -67,6 +67,7 @@ long vnc_client_write_sasl(VncState *vs)
+         if (err != SASL_OK)
+             return vnc_client_io_error(vs, -1, NULL);
+ 
++        vs->sasl.encodedRawLength = vs->output.offset;
+         vs->sasl.encodedOffset = 0;
+     }
+ 
+@@ -78,7 +79,7 @@ long vnc_client_write_sasl(VncState *vs)
+ 
+     vs->sasl.encodedOffset += ret;
+     if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {
+-        vs->output.offset = 0;
++        vs->output.offset -= vs->sasl.encodedRawLength;
+         vs->sasl.encoded = NULL;
+         vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
+     }
+diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h
+index cb42745..b9d8de1 100644
+--- a/ui/vnc-auth-sasl.h
++++ b/ui/vnc-auth-sasl.h
+@@ -53,6 +53,7 @@ struct VncStateSASL {
+      */
+     const uint8_t *encoded;
+     unsigned int encodedLength;
++    unsigned int encodedRawLength;
+     unsigned int encodedOffset;
+     char *username;
+     char *mechlist;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-usb-drop-HOST_USB.patch b/SOURCES/kvm-usb-drop-HOST_USB.patch
new file mode 100644
index 0000000..476a2b1
--- /dev/null
+++ b/SOURCES/kvm-usb-drop-HOST_USB.patch
@@ -0,0 +1,73 @@
+From ca6e32bce33eab1000eba5629e28832430896cbd Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:37 +0200
+Subject: [PATCH 18/34] usb: drop HOST_USB
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-2-git-send-email-thuth@redhat.com>
+Patchwork-id: 77016
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 01/12] usb: drop HOST_USB
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+Nowdays we use libusb for usb-host, so we don't have different code
+for linux vs. bsd any more.  So there is little reason to have the
+HOST_USB variable, we can just write things directly into the Makefile
+and avoid a pointless indirection.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-id: 20170908111217.21985-2-kraxel@redhat.com
+(cherry picked from commit 4e5ee5b21c84fe3023a64b5cc2e12a52ab0597c1)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	configure (simple conflict in the context of the removed hunk)
+---
+ configure            | 7 -------
+ hw/usb/Makefile.objs | 6 +++++-
+ 2 files changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/configure b/configure
+index 5cb65d0..457b2ff 100755
+--- a/configure
++++ b/configure
+@@ -5968,13 +5968,6 @@ if test "$live_block_ops" = "yes" ; then
+   echo "CONFIG_LIVE_BLOCK_OPS=y" >> $config_host_mak
+ fi
+ 
+-# USB host support
+-if test "$libusb" = "yes"; then
+-  echo "HOST_USB=libusb legacy" >> $config_host_mak
+-else
+-  echo "HOST_USB=stub" >> $config_host_mak
+-fi
+-
+ # TPM passthrough support?
+ if test "$tpm" = "yes"; then
+   echo 'CONFIG_TPM=$(CONFIG_SOFTMMU)' >> $config_host_mak
+diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
+index 97f1c456..a43ebbc 100644
+--- a/hw/usb/Makefile.objs
++++ b/hw/usb/Makefile.objs
+@@ -38,7 +38,11 @@ endif
+ common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
+ 
+ # usb pass-through
+-common-obj-y += $(patsubst %,host-%.o,$(HOST_USB))
++ifeq ($(CONFIG_LIBUSB),y)
++common-obj-y += host-libusb.o host-legacy.o
++else
++common-obj-y += host-stub.o
++endif
+ 
+ ifeq ($(CONFIG_USB_LIBUSB),y)
+ common-obj-$(CONFIG_XEN) += xen-usb.o
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-usb-fix-host-stub.c-build-race.patch b/SOURCES/kvm-usb-fix-host-stub.c-build-race.patch
new file mode 100644
index 0000000..b7a3f34
--- /dev/null
+++ b/SOURCES/kvm-usb-fix-host-stub.c-build-race.patch
@@ -0,0 +1,41 @@
+From 08426497468ec35d4dadd65df19abc5cfa6cd436 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:40 +0200
+Subject: [PATCH 21/34] usb: fix host-stub.c build race
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-5-git-send-email-thuth@redhat.com>
+Patchwork-id: 77021
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 04/12] usb: fix host-stub.c build race
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+Suggested-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-id: 20171004125210.7817-1-kraxel@redhat.com
+(cherry picked from commit eea6ae20379dca837631d603c3bed03e5128189f)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/usb/Makefile.objs | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
+index 01c18cf..53c4765 100644
+--- a/hw/usb/Makefile.objs
++++ b/hw/usb/Makefile.objs
+@@ -43,6 +43,7 @@ common-obj-y += host-libusb.o host-legacy.o
+ else
+ common-obj-y += host-stub.o
+ endif
++common-obj-$(CONFIG_ALL) += host-stub.o
+ 
+ ifeq ($(CONFIG_USB_LIBUSB),y)
+ common-obj-$(CONFIG_XEN) += xen-usb.o
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-usb-fix-libusb-config-variable-name.patch b/SOURCES/kvm-usb-fix-libusb-config-variable-name.patch
new file mode 100644
index 0000000..b227410
--- /dev/null
+++ b/SOURCES/kvm-usb-fix-libusb-config-variable-name.patch
@@ -0,0 +1,43 @@
+From 6c6a4d0d8f5d83ee57b83a85889426389141498c Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:39 +0200
+Subject: [PATCH 20/34] usb: fix libusb config variable name.
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-4-git-send-email-thuth@redhat.com>
+Patchwork-id: 77023
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 03/12] usb: fix libusb config variable name.
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+Cc: Jan Kiszka <jan.kiszka@siemens.com>
+Fixes: 4e5ee5b21c84fe3023a64b5cc2e12a52ab0597c1
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Tested-by: Jan Kiszka <jan.kiszka@siemens.com>
+Message-id: 20170926063820.30773-1-kraxel@redhat.com
+(cherry picked from commit 275d477a1adb084a47859507b20b05e7d65f8e8d)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/usb/Makefile.objs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
+index 757e365..01c18cf 100644
+--- a/hw/usb/Makefile.objs
++++ b/hw/usb/Makefile.objs
+@@ -38,7 +38,7 @@ endif
+ common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
+ 
+ # usb pass-through
+-ifeq ($(CONFIG_LIBUSB)$(CONFIG_USB),yy)
++ifeq ($(CONFIG_USB_LIBUSB)$(CONFIG_USB),yy)
+ common-obj-y += host-libusb.o host-legacy.o
+ else
+ common-obj-y += host-stub.o
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-usb-only-build-usb-host-with-CONFIG_USB-y.patch b/SOURCES/kvm-usb-only-build-usb-host-with-CONFIG_USB-y.patch
new file mode 100644
index 0000000..b7a6065
--- /dev/null
+++ b/SOURCES/kvm-usb-only-build-usb-host-with-CONFIG_USB-y.patch
@@ -0,0 +1,43 @@
+From fb5cc24e24e0b53f0679e911c959a060c945bdff Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:38 +0200
+Subject: [PATCH 19/34] usb: only build usb-host with CONFIG_USB=y
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-3-git-send-email-thuth@redhat.com>
+Patchwork-id: 77019
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 02/12] usb: only build usb-host with CONFIG_USB=y
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Tested-by: Thomas Huth <thuth@redhat.com>
+Message-id: 20170908111217.21985-3-kraxel@redhat.com
+(cherry picked from commit 2041649f0b04f61869589571ddf5ecd4f0695ea2)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/usb/Makefile.objs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
+index a43ebbc..757e365 100644
+--- a/hw/usb/Makefile.objs
++++ b/hw/usb/Makefile.objs
+@@ -38,7 +38,7 @@ endif
+ common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
+ 
+ # usb pass-through
+-ifeq ($(CONFIG_LIBUSB),y)
++ifeq ($(CONFIG_LIBUSB)$(CONFIG_USB),yy)
+ common-obj-y += host-libusb.o host-legacy.o
+ else
+ common-obj-y += host-stub.o
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-usb-storage-Fix-share-rw-option-parsing.patch b/SOURCES/kvm-usb-storage-Fix-share-rw-option-parsing.patch
new file mode 100644
index 0000000..188a2ea
--- /dev/null
+++ b/SOURCES/kvm-usb-storage-Fix-share-rw-option-parsing.patch
@@ -0,0 +1,102 @@
+From b2e6b34cedd32864edaa28dd7b7f8a8bf9578569 Mon Sep 17 00:00:00 2001
+From: Fam Zheng <famz@redhat.com>
+Date: Mon, 29 Jan 2018 05:38:19 +0100
+Subject: [PATCH 7/8] usb-storage: Fix share-rw option parsing
+
+RH-Author: Fam Zheng <famz@redhat.com>
+Message-id: <20180129053819.14507-1-famz@redhat.com>
+Patchwork-id: 78734
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] usb-storage: Fix share-rw option parsing
+Bugzilla: 1525324
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
+
+Because usb-storage creates an internal scsi device, we should propagate
+options. We already do so for bootindex etc, but failed to take care of
+share-rw. Fix it in an apparent way: add a new parameter to
+scsi_bus_legacy_add_drive and pass in s->conf.share_rw.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Message-id: 20180117005222.4781-1-famz@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 395b95395934785ca86baafd314d0c31b307d16d)
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Conflicts:
+	hw/usb/dev-storage.c
+Contextual conflict. Upstream has cleaned up err parameter in ceff3e1f0
+(hw/block: Use errp directly rather than local_err), which is an
+unrelated code refactoring and has other dependencies.
+---
+ hw/scsi/scsi-bus.c     | 9 ++++++++-
+ hw/usb/dev-storage.c   | 3 ++-
+ include/hw/scsi/scsi.h | 1 +
+ 3 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
+index 97c9525..26148aa 100644
+--- a/hw/scsi/scsi-bus.c
++++ b/hw/scsi/scsi-bus.c
+@@ -224,6 +224,7 @@ static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
+ /* handle legacy '-drive if=scsi,...' cmd line args */
+ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
+                                       int unit, bool removable, int bootindex,
++                                      bool share_rw,
+                                       const char *serial, Error **errp)
+ {
+     const char *driver;
+@@ -254,6 +255,12 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
+         object_unparent(OBJECT(dev));
+         return NULL;
+     }
++    object_property_set_bool(OBJECT(dev), share_rw, "share-rw", &err);
++    if (err != NULL) {
++        error_propagate(errp, err);
++        object_unparent(OBJECT(dev));
++        return NULL;
++    }
+     object_property_set_bool(OBJECT(dev), true, "realized", &err);
+     if (err != NULL) {
+         error_propagate(errp, err);
+@@ -292,7 +299,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated)
+ #endif
+         }
+         scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo),
+-                                  unit, false, -1, NULL, &error_fatal);
++                                  unit, false, -1, false, NULL, &error_fatal);
+     }
+     loc_pop(&loc);
+ }
+diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
+index 8a61ec9..ff18ad5 100644
+--- a/hw/usb/dev-storage.c
++++ b/hw/usb/dev-storage.c
+@@ -635,7 +635,8 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
+     scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+                  &usb_msd_scsi_info_storage, NULL);
+     scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
+-                                         s->conf.bootindex, dev->serial,
++                                         s->conf.bootindex, s->conf.share_rw,
++                                         dev->serial,
+                                          &err);
+     blk_unref(blk);
+     if (!scsi_dev) {
+diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
+index 23a8ee6..802a647 100644
+--- a/include/hw/scsi/scsi.h
++++ b/include/hw/scsi/scsi.h
+@@ -151,6 +151,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
+ 
+ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
+                                       int unit, bool removable, int bootindex,
++                                      bool share_rw,
+                                       const char *serial, Error **errp);
+ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, bool deprecated);
+ void scsi_legacy_handle_cmdline(void);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-util-async-use-atomic_mb_set-in-qemu_bh_cancel.patch b/SOURCES/kvm-util-async-use-atomic_mb_set-in-qemu_bh_cancel.patch
new file mode 100644
index 0000000..cbe5166
--- /dev/null
+++ b/SOURCES/kvm-util-async-use-atomic_mb_set-in-qemu_bh_cancel.patch
@@ -0,0 +1,79 @@
+From 550b4bcc2758e8df86570bc1afb29de34a1694fe Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Mon, 13 Nov 2017 16:29:39 +0100
+Subject: [PATCH 03/30] util/async: use atomic_mb_set in qemu_bh_cancel
+
+RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: <20171113162939.5486-2-stefanha@redhat.com>
+Patchwork-id: 77665
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] util/async: use atomic_mb_set in qemu_bh_cancel
+Bugzilla: 1508886
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Sergio Lopez <slp@redhat.com>
+
+Commit b7a745d added a qemu_bh_cancel call to the completion function
+as an optimization to prevent it from unnecessarily rescheduling itself.
+
+This completion function is scheduled from worker_thread, after setting
+the state of a ThreadPoolElement to THREAD_DONE.
+
+This was considered to be safe, as the completion function restarts the
+loop just after the call to qemu_bh_cancel. But, as this loop lacks a HW
+memory barrier, the read of req->state may actually happen _before_ the
+call, seeing it still as THREAD_QUEUED, and ending the completion
+function without having processed a pending TPE linked at pool->head:
+
+         worker thread             |            I/O thread
+------------------------------------------------------------------------
+                                   | speculatively read req->state
+req->state = THREAD_DONE;          |
+qemu_bh_schedule(p->completion_bh) |
+  bh->scheduled = 1;               |
+                                   | qemu_bh_cancel(p->completion_bh)
+                                   |   bh->scheduled = 0;
+                                   | if (req->state == THREAD_DONE)
+                                   |   // sees THREAD_QUEUED
+
+The source of the misunderstanding was that qemu_bh_cancel is now being
+used by the _consumer_ rather than the producer, and therefore now needs
+to have acquire semantics just like e.g. aio_bh_poll.
+
+In some situations, if there are no other independent requests in the
+same aio context that could eventually trigger the scheduling of the
+completion function, the omitted TPE and all operations pending on it
+will get stuck forever.
+
+[Added Sergio's updated wording about the HW memory barrier.
+--Stefan]
+
+Signed-off-by: Sergio Lopez <slp@redhat.com>
+Message-id: 20171108063447.2842-1-slp@redhat.com
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+(cherry picked from commit ef6dada8b44e1e7c4bec5c1115903af9af415b50)
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/async.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/util/async.c b/util/async.c
+index 355af73..0e1bd87 100644
+--- a/util/async.c
++++ b/util/async.c
+@@ -174,7 +174,7 @@ void qemu_bh_schedule(QEMUBH *bh)
+  */
+ void qemu_bh_cancel(QEMUBH *bh)
+ {
+-    bh->scheduled = 0;
++    atomic_mb_set(&bh->scheduled, 0);
+ }
+ 
+ /* This func is async.The bottom half will do the delete action at the finial
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vfio-Fix-vfio-kvm-group-registration.patch b/SOURCES/kvm-vfio-Fix-vfio-kvm-group-registration.patch
new file mode 100644
index 0000000..3594ab0
--- /dev/null
+++ b/SOURCES/kvm-vfio-Fix-vfio-kvm-group-registration.patch
@@ -0,0 +1,60 @@
+From 8c5380844c8f52663f497609cfb0a833e5f643e0 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Thu, 14 Dec 2017 16:30:06 +0100
+Subject: [PATCH 6/6] vfio: Fix vfio-kvm group registration
+
+RH-Author: Alex Williamson <alex.williamson@redhat.com>
+Message-id: <20171214162725.10938.41443.stgit@gimli.home>
+Patchwork-id: 78402
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] vfio: Fix vfio-kvm group registration
+Bugzilla: 1520294
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Commit 8c37faa475f3 ("vfio-pci, ppc64/spapr: Reorder group-to-container
+attaching") moved registration of groups with the vfio-kvm device from
+vfio_get_group() to vfio_connect_container(), but it missed the case
+where a group is attached to an existing container and takes an early
+exit.  Perhaps this is a less common case on ppc64/spapr, but on x86
+(without viommu) all groups are connected to the same container and
+thus only the first group gets registered with the vfio-kvm device.
+This becomes a problem if we then hot-unplug the devices associated
+with that first group and we end up with KVM being misinformed about
+any vfio connections that might remain.  Fix by including the call to
+vfio_kvm_device_add_group() in this early exit path.
+
+Fixes: 8c37faa475f3 ("vfio-pci, ppc64/spapr: Reorder group-to-container attaching")
+Cc: qemu-stable@nongnu.org # qemu-2.10+
+Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Tested-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Tested-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+(cherry picked from commit 2016986aedb6ea2839662eb5f60630f3e231bd1a)
+---
+
+Testing: hot unplug Intel 82576 PF which is not the first vfio-pci device
+for the VM.  Previous, libvirt log includes:
+
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/vfio/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/vfio/common.c b/hw/vfio/common.c
+index 7b2924c..7007878 100644
+--- a/hw/vfio/common.c
++++ b/hw/vfio/common.c
+@@ -968,6 +968,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
+         if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) {
+             group->container = container;
+             QLIST_INSERT_HEAD(&container->group_list, group, container_next);
++            vfio_kvm_device_add_group(group);
+             return 0;
+         }
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vfio-pci-Add-option-to-disable-GeForce-quirks.patch b/SOURCES/kvm-vfio-pci-Add-option-to-disable-GeForce-quirks.patch
new file mode 100644
index 0000000..a97bc21
--- /dev/null
+++ b/SOURCES/kvm-vfio-pci-Add-option-to-disable-GeForce-quirks.patch
@@ -0,0 +1,107 @@
+From 7047cb9155990dec1ee27b2ce65445a13ef40f00 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Tue, 13 Feb 2018 19:04:41 +0100
+Subject: [PATCH 14/15] vfio/pci: Add option to disable GeForce quirks
+
+RH-Author: Alex Williamson <alex.williamson@redhat.com>
+Message-id: <20180213190441.27565.45691.stgit@gimli.home>
+Patchwork-id: 78998
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH v2 1/2] vfio/pci: Add option to disable GeForce quirks
+Bugzilla: 1508330
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+
+These quirks are necessary for GeForce, but not for Quadro/GRID/Tesla
+assignment.  Leaving them enabled is fully functional and provides the
+most compatibility, but due to the unique NVIDIA MSI ACK behavior[1],
+it also introduces latency in re-triggering the MSI interrupt.  This
+overhead is typically negligible, but has been shown to adversely
+affect some (very) high interrupt rate applications.  This adds the
+vfio-pci device option "x-no-geforce-quirks=" which can be set to
+"on" to disable this additional overhead.
+
+A follow-on optimization for GeForce might be to make use of an
+ioeventfd to allow KVM to trigger an irqfd in the kernel vfio-pci
+driver, avoiding the bounce through userspace to handle this device
+write.
+
+[1] Background: the NVIDIA driver has been observed to issue a write
+to the MMIO mirror of PCI config space in BAR0 in order to allow the
+MSI interrupt for the device to retrigger.  Older reports indicated a
+write of 0xff to the (read-only) MSI capability ID register, while
+more recently a write of 0x0 is observed at config space offset 0x704,
+non-architected, extended config space of the device (BAR0 offset
+0x88704).  Virtualization of this range is only required for GeForce.
+
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+(cherry picked from commit db32d0f43839627f54a1a7f8eee17baa770f52d2)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/vfio/pci-quirks.c | 9 ++++++---
+ hw/vfio/pci.c        | 2 ++
+ hw/vfio/pci.h        | 1 +
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
+index 4199771..e875cca 100644
+--- a/hw/vfio/pci-quirks.c
++++ b/hw/vfio/pci-quirks.c
+@@ -541,7 +541,8 @@ static void vfio_vga_probe_nvidia_3d0_quirk(VFIOPCIDevice *vdev)
+     VFIOQuirk *quirk;
+     VFIONvidia3d0Quirk *data;
+ 
+-    if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||
++    if (vdev->no_geforce_quirks ||
++        !vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||
+         !vdev->bars[1].region.size) {
+         return;
+     }
+@@ -659,7 +660,8 @@ static void vfio_probe_nvidia_bar5_quirk(VFIOPCIDevice *vdev, int nr)
+     VFIONvidiaBAR5Quirk *bar5;
+     VFIOConfigWindowQuirk *window;
+ 
+-    if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||
++    if (vdev->no_geforce_quirks ||
++        !vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||
+         !vdev->vga || nr != 5 || !vdev->bars[5].ioport) {
+         return;
+     }
+@@ -753,7 +755,8 @@ static void vfio_probe_nvidia_bar0_quirk(VFIOPCIDevice *vdev, int nr)
+     VFIOQuirk *quirk;
+     VFIOConfigMirrorQuirk *mirror;
+ 
+-    if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||
++    if (vdev->no_geforce_quirks ||
++        !vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||
+         !vfio_is_vga(vdev) || nr != 0) {
+         return;
+     }
+diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
+index b3a2889..4cfb780 100644
+--- a/hw/vfio/pci.c
++++ b/hw/vfio/pci.c
+@@ -2992,6 +2992,8 @@ static Property vfio_pci_dev_properties[] = {
+     DEFINE_PROP_BOOL("x-no-kvm-intx", VFIOPCIDevice, no_kvm_intx, false),
+     DEFINE_PROP_BOOL("x-no-kvm-msi", VFIOPCIDevice, no_kvm_msi, false),
+     DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
++    DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
++                     no_geforce_quirks, false),
+     DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, vendor_id, PCI_ANY_ID),
+     DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, device_id, PCI_ANY_ID),
+     DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice,
+diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
+index a8366bb..ed9172d 100644
+--- a/hw/vfio/pci.h
++++ b/hw/vfio/pci.h
+@@ -143,6 +143,7 @@ typedef struct VFIOPCIDevice {
+     bool no_kvm_intx;
+     bool no_kvm_msi;
+     bool no_kvm_msix;
++    bool no_geforce_quirks;
+ } VFIOPCIDevice;
+ 
+ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vga-check-the-validation-of-memory-addr-when-draw-te.patch b/SOURCES/kvm-vga-check-the-validation-of-memory-addr-when-draw-te.patch
new file mode 100644
index 0000000..3f783fe
--- /dev/null
+++ b/SOURCES/kvm-vga-check-the-validation-of-memory-addr-when-draw-te.patch
@@ -0,0 +1,69 @@
+From 3b2c6ef26bdde6363ca750008cef962076e2bf0f Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 26 Jan 2018 08:12:43 +0100
+Subject: [PATCH 6/8] vga: check the validation of memory addr when draw text
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20180126081243.19785-2-kraxel@redhat.com>
+Patchwork-id: 78712
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] vga: check the validation of memory addr when draw text
+Bugzilla: 1534682
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+From: linzhecheng <linzhecheng@huawei.com>
+
+Start a vm with qemu-kvm -enable-kvm -vnc :66 -smp 1 -m 1024 -hda
+redhat_5.11.qcow2  -device pcnet -vga cirrus,
+then use VNC client to connect to VM, and excute the code below in guest
+OS will lead to qemu crash:
+
+int main()
+ {
+    iopl(3);
+    srand(time(NULL));
+    int a,b;
+    while(1){
+	a = rand()%0x100;
+	b = 0x3c0 + (rand()%0x20);
+        outb(a,b);
+    }
+    return 0;
+}
+
+The above code is writing the registers of VGA randomly.
+We can write VGA CRT controller registers index 0x0C or 0x0D
+(which is the start address register) to modify the
+the display memory address of the upper left pixel
+or character of the screen. The address may be out of the
+range of vga ram. So we should check the validation of memory address
+when reading or writing it to avoid segfault.
+
+Signed-off-by: linzhecheng <linzhecheng@huawei.com>
+Message-id: 20180111132724.13744-1-linzhecheng@huawei.com
+Fixes: CVE-2018-5683
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 191f59dc17396bb5a8da50f8c59b6e0a430711a4)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/vga.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 06ca3da..b1cdf36 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -1280,6 +1280,9 @@ static void vga_draw_text(VGACommonState *s, int full_update)
+         cx_min = width;
+         cx_max = -1;
+         for(cx = 0; cx < width; cx++) {
++            if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
++                break;
++            }
+             ch_attr = *(uint16_t *)src;
+             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
+                 if (cx < cx_min)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vga-drop-line_offset-variable.patch b/SOURCES/kvm-vga-drop-line_offset-variable.patch
new file mode 100644
index 0000000..e3c01dd
--- /dev/null
+++ b/SOURCES/kvm-vga-drop-line_offset-variable.patch
@@ -0,0 +1,63 @@
+From a66572373f31b1267b85f9e4da23a74b82280d14 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 20 Oct 2017 07:19:23 +0200
+Subject: [PATCH 01/19] vga: drop line_offset variable
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171020071925.9483-3-kraxel@redhat.com>
+Patchwork-id: 77390
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/4] vga: drop line_offset variable
+Bugzilla: 1501301
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 362f811793ff6cb4d209ab61d76cc4f841bb5e46)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/vga.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 497c823..895e95c 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -1464,7 +1464,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+ {
+     DisplaySurface *surface = qemu_console_surface(s->con);
+     int y1, y, update, linesize, y_start, double_scan, mask, depth;
+-    int width, height, shift_control, line_offset, bwidth, bits;
++    int width, height, shift_control, bwidth, bits;
+     ram_addr_t page0, page1;
+     DirtyBitmapSnapshot *snap = NULL;
+     int disp_width, multi_scan, multi_run;
+@@ -1614,7 +1614,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+         s->cursor_invalidate(s);
+     }
+ 
+-    line_offset = s->line_offset;
+ #if 0
+     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
+            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
+@@ -1629,7 +1628,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+ 
+     if (!full_update) {
+         ram_addr_t region_start = addr1;
+-        ram_addr_t region_end = addr1 + line_offset * height;
++        ram_addr_t region_end = addr1 + s->line_offset * height;
+         vga_sync_dirty_bitmap(s);
+         if (s->line_compare < height) {
+             /* split screen mode */
+@@ -1681,7 +1680,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+         if (!multi_run) {
+             mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
+             if ((y1 & mask) == mask)
+-                addr1 += line_offset;
++                addr1 += s->line_offset;
+             y1++;
+             multi_run = multi_scan;
+         } else {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vga-fix-display-update-region-calculation-split-scre.patch b/SOURCES/kvm-vga-fix-display-update-region-calculation-split-scre.patch
new file mode 100644
index 0000000..a1ba09d
--- /dev/null
+++ b/SOURCES/kvm-vga-fix-display-update-region-calculation-split-scre.patch
@@ -0,0 +1,58 @@
+From 5a5e2e2d4f7cc2fd67fa970584f06a29ba69fc3a Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 5 Oct 2017 09:49:33 +0200
+Subject: [PATCH 02/69] vga: fix display update region calculation (split
+ screen)
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171005094933.19435-2-kraxel@redhat.com>
+Patchwork-id: 76816
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] vga: fix display update region calculation (split screen)
+Bugzilla: 1486648
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+vga display update mis-calculated the region for the dirty bitmap
+snapshot in case split screen mode is used.  This can trigger an
+assert in cpu_physical_memory_snapshot_get_dirty().
+
+Impact:  DoS for privileged guest users.
+
+Fixes: CVE-2017-13673
+Fixes: fec5e8c92becad223df9d972770522f64aafdb72
+Cc: P J P <ppandit@redhat.com>
+Reported-by: David Buchanan <d@vidbuchanan.co.uk>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20170828123307.15392-1-kraxel@redhat.com
+(cherry picked from commit e65294157d4b69393b3f819c99f4f647452b48e3)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/vga.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 4c2ee0b..497c823 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -1628,9 +1628,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+     y1 = 0;
+ 
+     if (!full_update) {
++        ram_addr_t region_start = addr1;
++        ram_addr_t region_end = addr1 + line_offset * height;
+         vga_sync_dirty_bitmap(s);
+-        snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
+-                                                      line_offset * height,
++        if (s->line_compare < height) {
++            /* split screen mode */
++            region_start = 0;
++        }
++        snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
++                                                      region_end - region_start,
+                                                       DIRTY_MEMORY_VGA);
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch b/SOURCES/kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch
new file mode 100644
index 0000000..ce3346e
--- /dev/null
+++ b/SOURCES/kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch
@@ -0,0 +1,114 @@
+From cb36a048eaf475d3184e5fbecfa669d5d645f943 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 20 Oct 2017 07:19:24 +0200
+Subject: [PATCH 02/19] vga: handle cirrus vbe mode wraparounds.
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171020071925.9483-4-kraxel@redhat.com>
+Patchwork-id: 77391
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 3/4] vga: handle cirrus vbe mode wraparounds.
+Bugzilla: 1501301
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+Commit "3d90c62548 vga: stop passing pointers to vga_draw_line*
+functions" is incomplete.  It doesn't handle the case that the vga
+rendering code tries to create a shared surface, i.e. a pixman image
+backed by vga video memory.  That can not work in case the guest display
+wraps from end of video memory to the start.  So force shadowing in that
+case.  Also adjust the snapshot region calculation.
+
+Can trigger with cirrus only, when programming vbe modes using the bochs
+api (stdvga, also qxl and virtio-vga in vga compat mode) wrap arounds
+can't happen.
+
+Fixes: CVE-2017-13672
+Fixes: 3d90c6254863693a6b13d918d2b8682e08bbc681
+Cc: P J P <ppandit@redhat.com>
+Reported-by: David Buchanan <d@vidbuchanan.co.uk>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20171010141323.14049-3-kraxel@redhat.com
+(cherry picked from commit 28f77de26a4f9995458ddeb9d34bb06c0193bdc9)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/vga.c | 28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 895e95c..06ca3da 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -1465,13 +1465,13 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+     DisplaySurface *surface = qemu_console_surface(s->con);
+     int y1, y, update, linesize, y_start, double_scan, mask, depth;
+     int width, height, shift_control, bwidth, bits;
+-    ram_addr_t page0, page1;
++    ram_addr_t page0, page1, region_start, region_end;
+     DirtyBitmapSnapshot *snap = NULL;
+     int disp_width, multi_scan, multi_run;
+     uint8_t *d;
+     uint32_t v, addr1, addr;
+     vga_draw_line_func *vga_draw_line = NULL;
+-    bool share_surface;
++    bool share_surface, force_shadow = false;
+     pixman_format_code_t format;
+ #ifdef HOST_WORDS_BIGENDIAN
+     bool byteswap = !s->big_endian_fb;
+@@ -1484,6 +1484,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+     s->get_resolution(s, &width, &height);
+     disp_width = width;
+ 
++    region_start = (s->start_addr * 4);
++    region_end = region_start + s->line_offset * height;
++    if (region_end > s->vbe_size) {
++        /* wraps around (can happen with cirrus vbe modes) */
++        region_start = 0;
++        region_end = s->vbe_size;
++        force_shadow = true;
++    }
++
+     shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;
+     double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);
+     if (shift_control != 1) {
+@@ -1523,7 +1532,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+     format = qemu_default_pixman_format(depth, !byteswap);
+     if (format) {
+         share_surface = dpy_gfx_check_format(s->con, format)
+-            && !s->force_shadow;
++            && !s->force_shadow && !force_shadow;
+     } else {
+         share_surface = false;
+     }
+@@ -1627,8 +1636,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+     y1 = 0;
+ 
+     if (!full_update) {
+-        ram_addr_t region_start = addr1;
+-        ram_addr_t region_end = addr1 + s->line_offset * height;
+         vga_sync_dirty_bitmap(s);
+         if (s->line_compare < height) {
+             /* split screen mode */
+@@ -1651,10 +1658,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+             addr = (addr & ~0x8000) | ((y1 & 2) << 14);
+         }
+         update = full_update;
+-        page0 = addr;
+-        page1 = addr + bwidth - 1;
++        page0 = addr & s->vbe_size_mask;
++        page1 = (addr + bwidth - 1) & s->vbe_size_mask;
+         if (full_update) {
+             update = 1;
++        } else if (page1 < page0) {
++            /* scanline wraps from end of video memory to the start */
++            assert(force_shadow);
++            update = memory_region_snapshot_get_dirty(&s->vram, snap,
++                                                      page0, 0);
++            update |= memory_region_snapshot_get_dirty(&s->vram, snap,
++                                                       page1, 0);
+         } else {
+             update = memory_region_snapshot_get_dirty(&s->vram, snap,
+                                                       page0, page1 - page0);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch b/SOURCES/kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch
new file mode 100644
index 0000000..c35ea02
--- /dev/null
+++ b/SOURCES/kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch
@@ -0,0 +1,508 @@
+From 26b9a8ca080307b0d01799f96f944fb32e1619f0 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 5 Oct 2017 09:11:41 +0200
+Subject: [PATCH 10/34] vga: stop passing pointers to vga_draw_line* functions
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171005091141.30358-2-kraxel@redhat.com>
+Patchwork-id: 76814
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] vga: stop passing pointers to vga_draw_line* functions
+Bugzilla: 1486643
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Instead pass around the address (aka offset into vga memory).
+Add vga_read_* helper functions which apply vbe_size_mask to
+the address, to make sure the address stays within the valid
+range, similar to the cirrus blitter fixes (commits ffaf857778
+and 026aeffcb4).
+
+Impact:  DoS for privileged guest users.  qemu crashes with
+a segfault, when hitting the guard page after vga memory
+allocation, while reading vga memory for display updates.
+
+Fixes: CVE-2017-13672
+Cc: P J P <ppandit@redhat.com>
+Reported-by: David Buchanan <d@vidbuchanan.co.uk>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20170828122906.18993-1-kraxel@redhat.com
+(cherry picked from commit 3d90c6254863693a6b13d918d2b8682e08bbc681)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/vga-helpers.h | 202 ++++++++++++++++++++++++++---------------------
+ hw/display/vga.c         |   5 +-
+ hw/display/vga_int.h     |   1 +
+ 3 files changed, 114 insertions(+), 94 deletions(-)
+
+diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h
+index 94f6de2..5a752b3 100644
+--- a/hw/display/vga-helpers.h
++++ b/hw/display/vga-helpers.h
+@@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
+     } while (--h);
+ }
+ 
++static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
++{
++    return vga->vram_ptr[addr & vga->vbe_size_mask];
++}
++
++static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
++{
++    uint32_t offset = addr & vga->vbe_size_mask & ~1;
++    uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
++    return lduw_le_p(ptr);
++}
++
++static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
++{
++    uint32_t offset = addr & vga->vbe_size_mask & ~1;
++    uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
++    return lduw_be_p(ptr);
++}
++
++static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
++{
++    uint32_t offset = addr & vga->vbe_size_mask & ~3;
++    uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
++    return ldl_le_p(ptr);
++}
++
+ /*
+  * 4 color mode
+  */
+-static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
+-                           const uint8_t *s, int width)
++static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
++                           uint32_t addr, int width)
+ {
+     uint32_t plane_mask, *palette, data, v;
+     int x;
+ 
+-    palette = s1->last_palette;
+-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
++    palette = vga->last_palette;
++    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+     width >>= 3;
+     for(x = 0; x < width; x++) {
+-        data = ((uint32_t *)s)[0];
++        data = vga_read_dword_le(vga, addr);
+         data &= plane_mask;
+         v = expand2[GET_PLANE(data, 0)];
+         v |= expand2[GET_PLANE(data, 2)] << 2;
+@@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
+         ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
+         ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
+         d += 32;
+-        s += 4;
++        addr += 4;
+     }
+ }
+ 
+@@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
+ /*
+  * 4 color mode, dup2 horizontal
+  */
+-static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
+-                             const uint8_t *s, int width)
++static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
++                             uint32_t addr, int width)
+ {
+     uint32_t plane_mask, *palette, data, v;
+     int x;
+ 
+-    palette = s1->last_palette;
+-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
++    palette = vga->last_palette;
++    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+     width >>= 3;
+     for(x = 0; x < width; x++) {
+-        data = ((uint32_t *)s)[0];
++        data = vga_read_dword_le(vga, addr);
+         data &= plane_mask;
+         v = expand2[GET_PLANE(data, 0)];
+         v |= expand2[GET_PLANE(data, 2)] << 2;
+@@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
+         PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
+         PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
+         d += 64;
+-        s += 4;
++        addr += 4;
+     }
+ }
+ 
+ /*
+  * 16 color mode
+  */
+-static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
+-                           const uint8_t *s, int width)
++static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
++                           uint32_t addr, int width)
+ {
+     uint32_t plane_mask, data, v, *palette;
+     int x;
+ 
+-    palette = s1->last_palette;
+-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
++    palette = vga->last_palette;
++    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+     width >>= 3;
+     for(x = 0; x < width; x++) {
+-        data = ((uint32_t *)s)[0];
++        data = vga_read_dword_le(vga, addr);
+         data &= plane_mask;
+         v = expand4[GET_PLANE(data, 0)];
+         v |= expand4[GET_PLANE(data, 1)] << 1;
+@@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
+         ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
+         ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
+         d += 32;
+-        s += 4;
++        addr += 4;
+     }
+ }
+ 
+ /*
+  * 16 color mode, dup2 horizontal
+  */
+-static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
+-                             const uint8_t *s, int width)
++static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
++                             uint32_t addr, int width)
+ {
+     uint32_t plane_mask, data, v, *palette;
+     int x;
+ 
+-    palette = s1->last_palette;
+-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
++    palette = vga->last_palette;
++    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+     width >>= 3;
+     for(x = 0; x < width; x++) {
+-        data = ((uint32_t *)s)[0];
++        data = vga_read_dword_le(vga, addr);
+         data &= plane_mask;
+         v = expand4[GET_PLANE(data, 0)];
+         v |= expand4[GET_PLANE(data, 1)] << 1;
+@@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
+         PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
+         PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
+         d += 64;
+-        s += 4;
++        addr += 4;
+     }
+ }
+ 
+@@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
+  *
+  * XXX: add plane_mask support (never used in standard VGA modes)
+  */
+-static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
+-                             const uint8_t *s, int width)
++static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
++                             uint32_t addr, int width)
+ {
+     uint32_t *palette;
+     int x;
+ 
+-    palette = s1->last_palette;
++    palette = vga->last_palette;
+     width >>= 3;
+     for(x = 0; x < width; x++) {
+-        PUT_PIXEL2(d, 0, palette[s[0]]);
+-        PUT_PIXEL2(d, 1, palette[s[1]]);
+-        PUT_PIXEL2(d, 2, palette[s[2]]);
+-        PUT_PIXEL2(d, 3, palette[s[3]]);
++        PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
++        PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
++        PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
++        PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
+         d += 32;
+-        s += 4;
++        addr += 4;
+     }
+ }
+ 
+@@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
+  *
+  * XXX: add plane_mask support (never used in standard VGA modes)
+  */
+-static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
+-                           const uint8_t *s, int width)
++static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
++                           uint32_t addr, int width)
+ {
+     uint32_t *palette;
+     int x;
+ 
+-    palette = s1->last_palette;
++    palette = vga->last_palette;
+     width >>= 3;
+     for(x = 0; x < width; x++) {
+-        ((uint32_t *)d)[0] = palette[s[0]];
+-        ((uint32_t *)d)[1] = palette[s[1]];
+-        ((uint32_t *)d)[2] = palette[s[2]];
+-        ((uint32_t *)d)[3] = palette[s[3]];
+-        ((uint32_t *)d)[4] = palette[s[4]];
+-        ((uint32_t *)d)[5] = palette[s[5]];
+-        ((uint32_t *)d)[6] = palette[s[6]];
+-        ((uint32_t *)d)[7] = palette[s[7]];
++        ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
++        ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
++        ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
++        ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
++        ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
++        ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
++        ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
++        ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
+         d += 32;
+-        s += 8;
++        addr += 8;
+     }
+ }
+ 
+ /*
+  * 15 bit color
+  */
+-static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+     int w;
+     uint32_t v, r, g, b;
+ 
+     w = width;
+     do {
+-        v = lduw_le_p((void *)s);
++        v = vga_read_word_le(vga, addr);
+         r = (v >> 7) & 0xf8;
+         g = (v >> 2) & 0xf8;
+         b = (v << 3) & 0xf8;
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 2;
++        addr += 2;
+         d += 4;
+     } while (--w != 0);
+ }
+ 
+-static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+     int w;
+     uint32_t v, r, g, b;
+ 
+     w = width;
+     do {
+-        v = lduw_be_p((void *)s);
++        v = vga_read_word_be(vga, addr);
+         r = (v >> 7) & 0xf8;
+         g = (v >> 2) & 0xf8;
+         b = (v << 3) & 0xf8;
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 2;
++        addr += 2;
+         d += 4;
+     } while (--w != 0);
+ }
+@@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
+ /*
+  * 16 bit color
+  */
+-static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+     int w;
+     uint32_t v, r, g, b;
+ 
+     w = width;
+     do {
+-        v = lduw_le_p((void *)s);
++        v = vga_read_word_le(vga, addr);
+         r = (v >> 8) & 0xf8;
+         g = (v >> 3) & 0xfc;
+         b = (v << 3) & 0xf8;
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 2;
++        addr += 2;
+         d += 4;
+     } while (--w != 0);
+ }
+ 
+-static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+     int w;
+     uint32_t v, r, g, b;
+ 
+     w = width;
+     do {
+-        v = lduw_be_p((void *)s);
++        v = vga_read_word_be(vga, addr);
+         r = (v >> 8) & 0xf8;
+         g = (v >> 3) & 0xfc;
+         b = (v << 3) & 0xf8;
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 2;
++        addr += 2;
+         d += 4;
+     } while (--w != 0);
+ }
+@@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
+ /*
+  * 24 bit color
+  */
+-static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+     int w;
+     uint32_t r, g, b;
+ 
+     w = width;
+     do {
+-        b = s[0];
+-        g = s[1];
+-        r = s[2];
++        b = vga_read_byte(vga, addr + 0);
++        g = vga_read_byte(vga, addr + 1);
++        r = vga_read_byte(vga, addr + 2);
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 3;
++        addr += 3;
+         d += 4;
+     } while (--w != 0);
+ }
+ 
+-static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+     int w;
+     uint32_t r, g, b;
+ 
+     w = width;
+     do {
+-        r = s[0];
+-        g = s[1];
+-        b = s[2];
++        r = vga_read_byte(vga, addr + 0);
++        g = vga_read_byte(vga, addr + 1);
++        b = vga_read_byte(vga, addr + 2);
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 3;
++        addr += 3;
+         d += 4;
+     } while (--w != 0);
+ }
+@@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
+ /*
+  * 32 bit color
+  */
+-static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+-#ifndef HOST_WORDS_BIGENDIAN
+-    memcpy(d, s, width * 4);
+-#else
+     int w;
+     uint32_t r, g, b;
+ 
+     w = width;
+     do {
+-        b = s[0];
+-        g = s[1];
+-        r = s[2];
++        b = vga_read_byte(vga, addr + 0);
++        g = vga_read_byte(vga, addr + 1);
++        r = vga_read_byte(vga, addr + 2);
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 4;
++        addr += 4;
+         d += 4;
+     } while (--w != 0);
+-#endif
+ }
+ 
+-static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
+-                               const uint8_t *s, int width)
++static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
++                               uint32_t addr, int width)
+ {
+-#ifdef HOST_WORDS_BIGENDIAN
+-    memcpy(d, s, width * 4);
+-#else
+     int w;
+     uint32_t r, g, b;
+ 
+     w = width;
+     do {
+-        r = s[1];
+-        g = s[2];
+-        b = s[3];
++        r = vga_read_byte(vga, addr + 1);
++        g = vga_read_byte(vga, addr + 2);
++        b = vga_read_byte(vga, addr + 3);
+         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+-        s += 4;
++        addr += 4;
+         d += 4;
+     } while (--w != 0);
+-#endif
+ }
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 63421f9..4c2ee0b 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
+ }
+ 
+ typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
+-                                const uint8_t *s, int width);
++                                uint32_t srcaddr, int width);
+ 
+ #include "vga-helpers.h"
+ 
+@@ -1660,7 +1660,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
+             if (y_start < 0)
+                 y_start = y;
+             if (!(is_buffer_shared(surface))) {
+-                vga_draw_line(s, d, s->vram_ptr + addr, width);
++                vga_draw_line(s, d, addr, width);
+                 if (s->cursor_draw_line)
+                     s->cursor_draw_line(s, d, y);
+             }
+@@ -2164,6 +2164,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
+     if (!s->vbe_size) {
+         s->vbe_size = s->vram_size;
+     }
++    s->vbe_size_mask = s->vbe_size - 1;
+ 
+     s->is_vbe_vmstate = 1;
+     memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
+diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
+index dd6c958..ad34a1f 100644
+--- a/hw/display/vga_int.h
++++ b/hw/display/vga_int.h
+@@ -94,6 +94,7 @@ typedef struct VGACommonState {
+     uint32_t vram_size;
+     uint32_t vram_size_mb; /* property */
+     uint32_t vbe_size;
++    uint32_t vbe_size_mask;
+     uint32_t latch;
+     bool has_chain4_alias;
+     MemoryRegion chain4_alias;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vhost-Release-memory-references-on-cleanup.patch b/SOURCES/kvm-vhost-Release-memory-references-on-cleanup.patch
new file mode 100644
index 0000000..23bf245
--- /dev/null
+++ b/SOURCES/kvm-vhost-Release-memory-references-on-cleanup.patch
@@ -0,0 +1,60 @@
+From f221643835f73976adf07ebe355176b09decb558 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson@redhat.com>
+Date: Mon, 11 Sep 2017 20:43:08 +0200
+Subject: [PATCH 01/34] vhost: Release memory references on cleanup
+
+RH-Author: Alex Williamson <alex.williamson@redhat.com>
+Message-id: <20170911204254.12489.22036.stgit@redhat.home>
+Patchwork-id: 76307
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 1/1] vhost: Release memory references on cleanup
+Bugzilla: 1489670
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+
+vhost registers a MemoryListener where it adds and removes references
+to MemoryRegions as the MemoryRegionSections pass through.  The
+region_add callback is invoked for each existing section when the
+MemoryListener is registered, but unregistering the MemoryListener
+performs no reciprocal region_del callback.  It's therefore the
+owner of the MemoryListener's responsibility to cleanup any persistent
+changes, such as these memory references, after unregistering.
+
+The consequence of this bug is that if we have both a vhost device
+and a vfio device, the vhost device will reference any mmap'd MMIO of
+the vfio device via this MemoryListener.  If the vhost device is then
+removed, those references remain outstanding.  If we then attempt to
+remove the vfio device, it never gets finalized and the only way to
+release the kernel file descriptors is to terminate the QEMU process.
+
+Fixes: dfde4e6e1a86 ("memory: add ref/unref calls")
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: qemu-stable@nongnu.org # v1.6.0+
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit ee4c112846a0f2ac4fe5601918b0a2642ac8e2ed)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/virtio/vhost.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
+index 6eddb09..b737ca9 100644
+--- a/hw/virtio/vhost.c
++++ b/hw/virtio/vhost.c
+@@ -1356,6 +1356,10 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
+     if (hdev->mem) {
+         /* those are only safe after successful init */
+         memory_listener_unregister(&hdev->memory_listener);
++        for (i = 0; i < hdev->n_mem_sections; ++i) {
++            MemoryRegionSection *section = &hdev->mem_sections[i];
++            memory_region_unref(section->mr);
++        }
+         QLIST_REMOVE(hdev, entry);
+     }
+     if (hdev->migration_blocker) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vhost-restore-avail-index-from-vring-used-index-on-d.patch b/SOURCES/kvm-vhost-restore-avail-index-from-vring-used-index-on-d.patch
new file mode 100644
index 0000000..ee714d2
--- /dev/null
+++ b/SOURCES/kvm-vhost-restore-avail-index-from-vring-used-index-on-d.patch
@@ -0,0 +1,63 @@
+From 0166112bf9b190bb38208d507b7af4a6dca81063 Mon Sep 17 00:00:00 2001
+From: Maxime Coquelin <maxime.coquelin@redhat.com>
+Date: Tue, 5 Dec 2017 09:28:39 +0100
+Subject: [PATCH 17/21] vhost: restore avail index from vring used index on
+ disconnection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Maxime Coquelin <maxime.coquelin@redhat.com>
+Message-id: <20171205092839.17597-3-maxime.coquelin@redhat.com>
+Patchwork-id: 78141
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/2] vhost: restore avail index from vring used index on disconnection
+Bugzilla: 1491909
+RH-Acked-by: wexu@redhat.com
+RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Xiao Wang <jasowang@redhat.com>
+
+vhost_virtqueue_stop() gets avail index value from the backend,
+except if the backend is not responding.
+
+It happens when the backend crashes, and in this case, internal
+state of the virtio queue is inconsistent, making packets
+to corrupt the vring state.
+
+With a Linux guest, it results in following error message on
+backend reconnection:
+
+[   22.444905] virtio_net virtio0: output.0:id 0 is not a head!
+[   22.446746] net enp0s3: Unexpected TXQ (0) queue failure: -5
+[   22.476360] net enp0s3: Unexpected TXQ (0) queue failure: -5
+
+Fixes: 283e2c2adcb8 ("net: virtio-net discards TX data after link down")
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 2ae39a113af311cb56a0c35b7f212dafcef15303)
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/virtio/vhost.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
+index b737ca9..76f6e1f 100644
+--- a/hw/virtio/vhost.c
++++ b/hw/virtio/vhost.c
+@@ -1137,6 +1137,10 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
+     r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
+     if (r < 0) {
+         VHOST_OPS_DEBUG("vhost VQ %d ring restore failed: %d", idx, r);
++        /* Connection to the backend is broken, so let's sync internal
++         * last avail idx to the device used idx.
++         */
++        virtio_queue_restore_last_avail_idx(vdev, idx);
+     } else {
+         virtio_queue_set_last_avail_idx(vdev, idx, state.num);
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-Add-queue-interface-to-restore-avail-index-fr.patch b/SOURCES/kvm-virtio-Add-queue-interface-to-restore-avail-index-fr.patch
new file mode 100644
index 0000000..bef39f8
--- /dev/null
+++ b/SOURCES/kvm-virtio-Add-queue-interface-to-restore-avail-index-fr.patch
@@ -0,0 +1,74 @@
+From 257d8d98076717288519d312f1690c453bb74776 Mon Sep 17 00:00:00 2001
+From: Maxime Coquelin <maxime.coquelin@redhat.com>
+Date: Tue, 5 Dec 2017 09:28:38 +0100
+Subject: [PATCH 16/21] virtio: Add queue interface to restore avail index from
+ vring used index
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Maxime Coquelin <maxime.coquelin@redhat.com>
+Message-id: <20171205092839.17597-2-maxime.coquelin@redhat.com>
+Patchwork-id: 78140
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/2] virtio: Add queue interface to restore avail index from vring used index
+Bugzilla: 1491909
+RH-Acked-by: wexu@redhat.com
+RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Xiao Wang <jasowang@redhat.com>
+
+In case of backend crash, it is not possible to restore internal
+avail index from the backend value as vhost_get_vring_base
+callback fails.
+
+This patch provides a new interface to restore internal avail index
+from the vring used index, as done by some vhost-user backend on
+reconnection.
+
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 2d4ba6cc741df15df6fbb4feaa706a02e103083a)
+Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/virtio/virtio.c         | 10 ++++++++++
+ include/hw/virtio/virtio.h |  1 +
+ 2 files changed, 11 insertions(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index e7a2bc2..58ecf75 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -2329,6 +2329,16 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
+     vdev->vq[n].shadow_avail_idx = idx;
+ }
+ 
++void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n)
++{
++    rcu_read_lock();
++    if (vdev->vq[n].vring.desc) {
++        vdev->vq[n].last_avail_idx = vring_used_idx(&vdev->vq[n]);
++        vdev->vq[n].shadow_avail_idx = vdev->vq[n].last_avail_idx;
++    }
++    rcu_read_unlock();
++}
++
+ void virtio_queue_update_used_idx(VirtIODevice *vdev, int n)
+ {
+     rcu_read_lock();
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index 5faa359..912310c 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -273,6 +273,7 @@ hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n);
+ hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n);
+ uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
+ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx);
++void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n);
+ void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
+ void virtio_queue_update_used_idx(VirtIODevice *vdev, int n);
+ VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-gpu-disallow-vIOMMU.patch b/SOURCES/kvm-virtio-gpu-disallow-vIOMMU.patch
new file mode 100644
index 0000000..f2f442c
--- /dev/null
+++ b/SOURCES/kvm-virtio-gpu-disallow-vIOMMU.patch
@@ -0,0 +1,77 @@
+From 5ce65934798e5c87e465f30ad08f24b76429ee7c Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Tue, 6 Feb 2018 08:21:19 +0100
+Subject: [PATCH 20/20] virtio-gpu: disallow vIOMMU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20180206082119.9246-1-peterx@redhat.com>
+Patchwork-id: 78903
+O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH] virtio-gpu: disallow vIOMMU
+Bugzilla: 1540182
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+virtio-gpu has special code path that bypassed vIOMMU protection.  So
+for now let's disable iommu_platform for the device until we fully
+support that (if needed).
+
+After the patch, both virtio-vga and virtio-gpu won't allow to boot with
+iommu_platform parameter set.
+
+CC: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-id: 20180131040401.3550-1-peterx@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 34e304e97576a9e17680c868c00ff524a981007b)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/virtio-gpu-pci.c | 8 +++++++-
+ hw/display/virtio-gpu.c     | 5 +++++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
+index ef92c4a..3519dc8 100644
+--- a/hw/display/virtio-gpu-pci.c
++++ b/hw/display/virtio-gpu-pci.c
+@@ -28,10 +28,16 @@ static void virtio_gpu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+     VirtIOGPU *g = &vgpu->vdev;
+     DeviceState *vdev = DEVICE(&vgpu->vdev);
+     int i;
++    Error *local_error = NULL;
+ 
+     qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+     virtio_pci_force_virtio_1(vpci_dev);
+-    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
++    object_property_set_bool(OBJECT(vdev), true, "realized", &local_error);
++
++    if (local_error) {
++        error_propagate(errp, local_error);
++        return;
++    }
+ 
+     for (i = 0; i < g->conf.max_outputs; i++) {
+         object_property_set_link(OBJECT(g->scanout[i].con),
+diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
+index 4e66535..db53e0b 100644
+--- a/hw/display/virtio-gpu.c
++++ b/hw/display/virtio-gpu.c
+@@ -1109,6 +1109,11 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
+     Error *local_err = NULL;
+     int i;
+ 
++    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
++        error_setg(errp, "virtio-gpu does not support vIOMMU yet");
++        return;
++    }
++
+     if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) {
+         error_setg(errp, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS);
+         return;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-gpu-don-t-clear-QemuUIInfo-information-on-res.patch b/SOURCES/kvm-virtio-gpu-don-t-clear-QemuUIInfo-information-on-res.patch
new file mode 100644
index 0000000..c39ecf9
--- /dev/null
+++ b/SOURCES/kvm-virtio-gpu-don-t-clear-QemuUIInfo-information-on-res.patch
@@ -0,0 +1,66 @@
+From 778b752e1808475fe4c2086e5e0c523bff7b30b9 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 5 Oct 2017 08:39:50 +0200
+Subject: [PATCH 01/69] virtio-gpu: don't clear QemuUIInfo information on reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20171005083950.12662-2-kraxel@redhat.com>
+Patchwork-id: 76812
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 1/1] virtio-gpu: don't clear QemuUIInfo information on reset
+Bugzilla: 1460595
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Don't reset window layout information (passed via virtio_gpu_ui_info) on
+device reset, so the user interface window layout will be kept intact
+over reboots.  The head size and position was commented out already, so
+this patch just drops the dead code.  Additionally the enabled head mask
+must be kept so multihead setups work properly too.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1460595
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20170906142058.2460-1-kraxel@redhat.com
+(cherry picked from commit 79d16c21a565927943486b26789caa62413ff371)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/display/virtio-gpu.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
+index 6aae147..4e66535 100644
+--- a/hw/display/virtio-gpu.c
++++ b/hw/display/virtio-gpu.c
+@@ -1195,17 +1195,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
+         virtio_gpu_resource_destroy(g, res);
+     }
+     for (i = 0; i < g->conf.max_outputs; i++) {
+-#if 0
+-        g->req_state[i].x = 0;
+-        g->req_state[i].y = 0;
+-        if (i == 0) {
+-            g->req_state[0].width = 1024;
+-            g->req_state[0].height = 768;
+-        } else {
+-            g->req_state[i].width = 0;
+-            g->req_state[i].height = 0;
+-        }
+-#endif
+         g->scanout[i].resource_id = 0;
+         g->scanout[i].width = 0;
+         g->scanout[i].height = 0;
+@@ -1213,7 +1202,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
+         g->scanout[i].y = 0;
+         g->scanout[i].ds = NULL;
+     }
+-    g->enabled_output_bitmask = 1;
+ 
+ #ifdef CONFIG_VIRGL
+     if (g->use_virgl_renderer) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-net-don-t-touch-virtqueue-if-vm-is-stopped.patch b/SOURCES/kvm-virtio-net-don-t-touch-virtqueue-if-vm-is-stopped.patch
new file mode 100644
index 0000000..03533e5
--- /dev/null
+++ b/SOURCES/kvm-virtio-net-don-t-touch-virtqueue-if-vm-is-stopped.patch
@@ -0,0 +1,59 @@
+From d7c69df61c216de014aca9d1eafc94ddb81ce5bb Mon Sep 17 00:00:00 2001
+From: Xiao Wang <jasowang@redhat.com>
+Date: Wed, 29 Nov 2017 07:39:51 +0100
+Subject: [PATCH 17/21] virtio-net: don't touch virtqueue if vm is stopped
+
+RH-Author: Xiao Wang <jasowang@redhat.com>
+Message-id: <1511941191-30204-1-git-send-email-jasowang@redhat.com>
+Patchwork-id: 77949
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] virtio-net: don't touch virtqueue if vm is stopped
+Bugzilla: 1506151
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
+RH-Acked-by: wexu@redhat.com
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1506151
+Brew Build: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=14645237
+Test status: Tested by myself
+
+Guest state should not be touched if VM is stopped, unfortunately we
+didn't check running state and tried to drain tx queue unconditionally
+in virtio_net_set_status(). A crash was then noticed as a migration
+destination when user type quit after virtqueue state is loaded but
+before region cache is initialized. In this case,
+virtio_net_drop_tx_queue_data() tries to access the uninitialized
+region cache.
+
+Fix this by only dropping tx queue data when vm is running.
+
+Fixes: 283e2c2adcb80 ("net: virtio-net discards TX data after link down")
+Cc: Yuri Benditovich <yuri.benditovich@daynix.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Stefan Hajnoczi <stefanha@redhat.com>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+(cherry picked from commit 70e53e6e4da3db4b2c31981191753a7e974936d0)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/net/virtio-net.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 148071a..fbc5e1b 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -288,7 +288,8 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
+                 qemu_bh_cancel(q->tx_bh);
+             }
+             if ((n->status & VIRTIO_NET_S_LINK_UP) == 0 &&
+-                (queue_status & VIRTIO_CONFIG_S_DRIVER_OK)) {
++                (queue_status & VIRTIO_CONFIG_S_DRIVER_OK) &&
++                vdev->vm_running) {
+                 /* if tx is waiting we are likely have some packets in tx queue
+                  * and disabled notification */
+                 q->tx_waiting = 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-pci-Replace-modern_as-with-direct-access-to-m.patch b/SOURCES/kvm-virtio-pci-Replace-modern_as-with-direct-access-to-m.patch
new file mode 100644
index 0000000..59f8f4e
--- /dev/null
+++ b/SOURCES/kvm-virtio-pci-Replace-modern_as-with-direct-access-to-m.patch
@@ -0,0 +1,240 @@
+From ff5e61b600d9a130faad32ceda3cd212dcb387d4 Mon Sep 17 00:00:00 2001
+From: David Gibson <dgibson@redhat.com>
+Date: Thu, 16 Nov 2017 03:07:11 +0100
+Subject: [PATCH 07/30] virtio-pci: Replace modern_as with direct access to
+ modern_bar
+
+RH-Author: David Gibson <dgibson@redhat.com>
+Message-id: <20171116030732.8560-2-dgibson@redhat.com>
+Patchwork-id: 77689
+O-Subject: [PATCH 01/22] virtio-pci: Replace modern_as with direct access to modern_bar
+Bugzilla: 1481593
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+The modern bar is accessed now via yet another address space created just
+for that purpose and it does not really need FlatView and dispatch tree
+as it has a single memory region so it is just a waste of memory. Things
+get even worse when there are dozens or hundreds of virtio-pci devices -
+since these address spaces are global, changing any of them triggers
+rebuilding all address spaces.
+
+This replaces indirect accesses to the modern BAR with a simple lookup
+and direct calls to memory_region_dispatch_read/write.
+
+This is expected to save lots of memory at boot time after applying:
+[Qemu-devel] [PULL 00/32] Misc changes for 2017-09-22
+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit a93c8d828af186d9a6a1c915a1be8ba22fb89849)
+
+Signed-off-by: David Gibson <dgibson@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/virtio/virtio-pci.c | 75 +++++++++++++++++++++++++++++---------------------
+ hw/virtio/virtio-pci.h | 17 +++++++-----
+ 2 files changed, 54 insertions(+), 38 deletions(-)
+
+diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
+index 6e497c8..4b041bb 100644
+--- a/hw/virtio/virtio-pci.c
++++ b/hw/virtio/virtio-pci.c
+@@ -545,6 +545,24 @@ static const MemoryRegionOps virtio_pci_config_ops = {
+     .endianness = DEVICE_LITTLE_ENDIAN,
+ };
+ 
++static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
++                                                 hwaddr *off, int len)
++{
++    int i;
++    VirtIOPCIRegion *reg;
++
++    for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
++        reg = &proxy->regs[i];
++        if (*off >= reg->offset &&
++            *off + len <= reg->offset + reg->size) {
++            *off -= reg->offset;
++            return &reg->mr;
++        }
++    }
++
++    return NULL;
++}
++
+ /* Below are generic functions to do memcpy from/to an address space,
+  * without byteswaps, with input validation.
+  *
+@@ -558,63 +576,72 @@ static const MemoryRegionOps virtio_pci_config_ops = {
+  * Note: host pointer must be aligned.
+  */
+ static
+-void virtio_address_space_write(AddressSpace *as, hwaddr addr,
++void virtio_address_space_write(VirtIOPCIProxy *proxy, hwaddr addr,
+                                 const uint8_t *buf, int len)
+ {
+-    uint32_t val;
++    uint64_t val;
++    MemoryRegion *mr;
+ 
+     /* address_space_* APIs assume an aligned address.
+      * As address is under guest control, handle illegal values.
+      */
+     addr &= ~(len - 1);
+ 
++    mr = virtio_address_space_lookup(proxy, &addr, len);
++    if (!mr) {
++        return;
++    }
++
+     /* Make sure caller aligned buf properly */
+     assert(!(((uintptr_t)buf) & (len - 1)));
+ 
+     switch (len) {
+     case 1:
+         val = pci_get_byte(buf);
+-        address_space_stb(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
+         break;
+     case 2:
+-        val = pci_get_word(buf);
+-        address_space_stw_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
++        val = cpu_to_le16(pci_get_word(buf));
+         break;
+     case 4:
+-        val = pci_get_long(buf);
+-        address_space_stl_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
++        val = cpu_to_le32(pci_get_long(buf));
+         break;
+     default:
+         /* As length is under guest control, handle illegal values. */
+-        break;
++        return;
+     }
++    memory_region_dispatch_write(mr, addr, val, len, MEMTXATTRS_UNSPECIFIED);
+ }
+ 
+ static void
+-virtio_address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
++virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr addr,
++                          uint8_t *buf, int len)
+ {
+-    uint32_t val;
++    uint64_t val;
++    MemoryRegion *mr;
+ 
+     /* address_space_* APIs assume an aligned address.
+      * As address is under guest control, handle illegal values.
+      */
+     addr &= ~(len - 1);
+ 
++    mr = virtio_address_space_lookup(proxy, &addr, len);
++    if (!mr) {
++        return;
++    }
++
+     /* Make sure caller aligned buf properly */
+     assert(!(((uintptr_t)buf) & (len - 1)));
+ 
++    memory_region_dispatch_read(mr, addr, &val, len, MEMTXATTRS_UNSPECIFIED);
+     switch (len) {
+     case 1:
+-        val = address_space_ldub(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
+         pci_set_byte(buf, val);
+         break;
+     case 2:
+-        val = address_space_lduw_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
+-        pci_set_word(buf, val);
++        pci_set_word(buf, le16_to_cpu(val));
+         break;
+     case 4:
+-        val = address_space_ldl_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
+-        pci_set_long(buf, val);
++        pci_set_long(buf, le32_to_cpu(val));
+         break;
+     default:
+         /* As length is under guest control, handle illegal values. */
+@@ -650,8 +677,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
+ 
+         if (len == 1 || len == 2 || len == 4) {
+             assert(len <= sizeof cfg->pci_cfg_data);
+-            virtio_address_space_write(&proxy->modern_as, off,
+-                                       cfg->pci_cfg_data, len);
++            virtio_address_space_write(proxy, off, cfg->pci_cfg_data, len);
+         }
+     }
+ }
+@@ -675,8 +701,7 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
+ 
+         if (len == 1 || len == 2 || len == 4) {
+             assert(len <= sizeof cfg->pci_cfg_data);
+-            virtio_address_space_read(&proxy->modern_as, off,
+-                                      cfg->pci_cfg_data, len);
++            virtio_address_space_read(proxy, off, cfg->pci_cfg_data, len);
+         }
+     }
+ 
+@@ -1783,15 +1808,6 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
+                        /* PCI BAR regions must be powers of 2 */
+                        pow2ceil(proxy->notify.offset + proxy->notify.size));
+ 
+-    memory_region_init_alias(&proxy->modern_cfg,
+-                             OBJECT(proxy),
+-                             "virtio-pci-cfg",
+-                             &proxy->modern_bar,
+-                             0,
+-                             memory_region_size(&proxy->modern_bar));
+-
+-    address_space_init(&proxy->modern_as, &proxy->modern_cfg, "virtio-pci-cfg-as");
+-
+     if (proxy->disable_legacy == ON_OFF_AUTO_AUTO) {
+         proxy->disable_legacy = pcie_port ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+     }
+@@ -1860,10 +1876,7 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
+ 
+ static void virtio_pci_exit(PCIDevice *pci_dev)
+ {
+-    VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
+-
+     msix_uninit_exclusive_bar(pci_dev);
+-    address_space_destroy(&proxy->modern_as);
+ }
+ 
+ static void virtio_pci_reset(DeviceState *qdev)
+diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
+index 69f5959..12d3a90 100644
+--- a/hw/virtio/virtio-pci.h
++++ b/hw/virtio/virtio-pci.h
+@@ -155,15 +155,18 @@ typedef struct VirtIOPCIQueue {
+ struct VirtIOPCIProxy {
+     PCIDevice pci_dev;
+     MemoryRegion bar;
+-    VirtIOPCIRegion common;
+-    VirtIOPCIRegion isr;
+-    VirtIOPCIRegion device;
+-    VirtIOPCIRegion notify;
+-    VirtIOPCIRegion notify_pio;
++    union {
++        struct {
++            VirtIOPCIRegion common;
++            VirtIOPCIRegion isr;
++            VirtIOPCIRegion device;
++            VirtIOPCIRegion notify;
++            VirtIOPCIRegion notify_pio;
++        };
++        VirtIOPCIRegion regs[5];
++    };
+     MemoryRegion modern_bar;
+     MemoryRegion io_bar;
+-    MemoryRegion modern_cfg;
+-    AddressSpace modern_as;
+     uint32_t legacy_io_bar_idx;
+     uint32_t msix_bar_idx;
+     uint32_t modern_io_bar_idx;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vl-Clean-up-user-creatable-objects-when-exiting.patch b/SOURCES/kvm-vl-Clean-up-user-creatable-objects-when-exiting.patch
new file mode 100644
index 0000000..527d3f7
--- /dev/null
+++ b/SOURCES/kvm-vl-Clean-up-user-creatable-objects-when-exiting.patch
@@ -0,0 +1,82 @@
+From 8f6dfc8d04aa713a8a6f1856a5c2fa68100ecd77 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Thu, 19 Oct 2017 01:34:51 +0200
+Subject: [PATCH 62/69] vl: Clean up user-creatable objects when exiting
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171019013453.21449-3-ehabkost@redhat.com>
+Patchwork-id: 77368
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/4] vl: Clean up user-creatable objects when exiting
+Bugzilla: 1460848
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+Delete all user-creatable objects in /objects when exiting QEMU, so they
+can perform cleanup actions.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20170824192315.5897-2-ehabkost@redhat.com>
+Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Tested-by: Zack Cornelius <zack.cornelius@kove.net>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 9d5139e543e8579aacd324193680c64fd1463d89)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/qom/object_interfaces.h | 8 ++++++++
+ qom/object_interfaces.c         | 5 +++++
+ vl.c                            | 1 +
+ 3 files changed, 14 insertions(+)
+
+diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
+index fdd7603..3f5f206 100644
+--- a/include/qom/object_interfaces.h
++++ b/include/qom/object_interfaces.h
+@@ -148,4 +148,12 @@ int user_creatable_add_opts_foreach(void *opaque,
+  */
+ void user_creatable_del(const char *id, Error **errp);
+ 
++/**
++ * user_creatable_cleanup:
++ *
++ * Delete all user-creatable objects and the user-creatable
++ * objects container.
++ */
++void user_creatable_cleanup(void);
++
+ #endif
+diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
+index ff27e06..dbf8878 100644
+--- a/qom/object_interfaces.c
++++ b/qom/object_interfaces.c
+@@ -193,6 +193,11 @@ void user_creatable_del(const char *id, Error **errp)
+     object_unparent(obj);
+ }
+ 
++void user_creatable_cleanup(void)
++{
++    object_unparent(object_get_objects_root());
++}
++
+ static void register_types(void)
+ {
+     static const TypeInfo uc_interface_info = {
+diff --git a/vl.c b/vl.c
+index 18b837c..55949e6 100644
+--- a/vl.c
++++ b/vl.c
+@@ -4814,6 +4814,7 @@ int main(int argc, char **argv, char **envp)
+     audio_cleanup();
+     monitor_cleanup();
+     qemu_chr_cleanup();
++    user_creatable_cleanup();
+     /* TODO: unref root container, check all devices are ok */
+ 
+     return 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vl-exit-if-maxcpus-is-negative.patch b/SOURCES/kvm-vl-exit-if-maxcpus-is-negative.patch
new file mode 100644
index 0000000..cc4fc7b
--- /dev/null
+++ b/SOURCES/kvm-vl-exit-if-maxcpus-is-negative.patch
@@ -0,0 +1,95 @@
+From 72c9f52facf418294ce72056d771591debb2a2f0 Mon Sep 17 00:00:00 2001
+From: Sam Bobroff <sbobroff@redhat.com>
+Date: Fri, 13 Oct 2017 00:56:26 +0200
+Subject: [PATCH 33/34] vl: exit if maxcpus is negative
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Sam Bobroff <sbobroff@redhat.com>
+Message-id: <1507856186-31186-1-git-send-email-sbobroff@redhat.com>
+Patchwork-id: 77221
+O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH] vl: exit if maxcpus is negative
+Bugzilla: 1491743
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+
+---Steps to Reproduce---
+
+When passed a negative number to 'maxcpus' parameter, Qemu aborts
+with a core dump.
+
+Run the following command with maxcpus argument as negative number
+
+ppc64-softmmu/qemu-system-ppc64 --nographic -vga none -machine
+pseries,accel=kvm,kvm-type=HV -m size=200g -device virtio-blk-pci,
+drive=rootdisk -drive file=/home/images/pegas-1.0-ppc64le.qcow2,
+if=none,cache=none,id=rootdisk,format=qcow2 -monitor telnet
+:127.0.0.1:1234,server,nowait -net nic,model=virtio -net
+user -redir tcp:2000::22 -device nec-usb-xhci -smp 8,cores=1,
+threads=1,maxcpus=-12
+
+(process:12149): GLib-ERROR **: gmem.c:130: failed to allocate
+ 18446744073709550568 bytes
+
+Trace/breakpoint trap
+
+Reported-by: R.Nageswara Sastry <rnsastry@linux.vnet.ibm.com>
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Message-Id: <1504511031-26834-1-git-send-email-s1seetee@linux.vnet.ibm.com>
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+(cherry picked from commit c0dd10991903c552811d8cbe9231055b1b3a7ebd)
+
+Testing: Run qemu-kvm with "-smp maxcpus=-1".
+Signed-off-by: Sam Bobroff <sbobroff@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/sysemu/sysemu.h | 2 +-
+ vl.c                    | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
+index 54fdc4f..d6a9cd7 100644
+--- a/include/sysemu/sysemu.h
++++ b/include/sysemu/sysemu.h
+@@ -115,7 +115,7 @@ extern int win2k_install_hack;
+ extern int alt_grab;
+ extern int ctrl_grab;
+ extern int smp_cpus;
+-extern int max_cpus;
++extern unsigned int max_cpus;
+ extern int cursor_hide;
+ extern int graphic_rotate;
+ extern int no_quit;
+diff --git a/vl.c b/vl.c
+index 183b7f7..18b837c 100644
+--- a/vl.c
++++ b/vl.c
+@@ -164,7 +164,7 @@ Chardev *sclp_hds[MAX_SCLP_CONSOLES];
+ int win2k_install_hack = 0;
+ int singlestep = 0;
+ int smp_cpus = 1;
+-int max_cpus = 1;
++unsigned int max_cpus = 1;
+ int smp_cores = 1;
+ int smp_threads = 1;
+ int acpi_enabled = 1;
+@@ -4244,8 +4244,8 @@ int main(int argc, char **argv, char **envp)
+ 
+     machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
+     if (max_cpus > machine_class->max_cpus) {
+-        error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
+-                     "supported by machine '%s' (%d)", max_cpus,
++        error_report("Invalid SMP CPUs %d. The max CPUs "
++                     "supported by machine '%s' is %d", max_cpus,
+                      machine_class->name, machine_class->max_cpus);
+         exit(1);
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vmcoreinfo-put-it-in-the-misc-device-category.patch b/SOURCES/kvm-vmcoreinfo-put-it-in-the-misc-device-category.patch
new file mode 100644
index 0000000..cb30535
--- /dev/null
+++ b/SOURCES/kvm-vmcoreinfo-put-it-in-the-misc-device-category.patch
@@ -0,0 +1,43 @@
+From a65cfbc7d09d1c55d80e6d70a45f163e89437ccf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 27 Nov 2017 22:51:10 +0100
+Subject: [PATCH 12/21] vmcoreinfo: put it in the 'misc' device category
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20171127225111.24518-9-marcandre.lureau@redhat.com>
+Patchwork-id: 77927
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 8/9] vmcoreinfo: put it in the 'misc' device category
+Bugzilla: 1398633
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit b948bb55dac527ae6b0c5e6dc69d00866a3a6fee)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/misc/vmcoreinfo.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c
+index a618e12..31db57a 100644
+--- a/hw/misc/vmcoreinfo.c
++++ b/hw/misc/vmcoreinfo.c
+@@ -79,6 +79,7 @@ static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data)
+     dc->vmsd = &vmstate_vmcoreinfo;
+     dc->realize = vmcoreinfo_realize;
+     dc->hotpluggable = false;
++    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ }
+ 
+ static const TypeInfo vmcoreinfo_device_info = {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-watchdog-wdt_diag288-Mark-diag288-watchdog-as-non-ho.patch b/SOURCES/kvm-watchdog-wdt_diag288-Mark-diag288-watchdog-as-non-ho.patch
new file mode 100644
index 0000000..590c0e7
--- /dev/null
+++ b/SOURCES/kvm-watchdog-wdt_diag288-Mark-diag288-watchdog-as-non-ho.patch
@@ -0,0 +1,55 @@
+From 6471fec6246b152ac4ddfb8c13d80c5054e5792f Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 9 Oct 2017 12:32:43 +0200
+Subject: [PATCH 24/34] watchdog/wdt_diag288: Mark diag288 watchdog as
+ non-hotpluggable
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <1507552368-9245-8-git-send-email-thuth@redhat.com>
+Patchwork-id: 77027
+O-Subject: [RHEL-7.5 qemu-kvm-ma PATCH 07/12] watchdog/wdt_diag288: Mark diag288 watchdog as non-hotpluggable
+Bugzilla: 1492033
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+
+QEMU currently aborts when the user tries to hot-unplug a diag288
+device:
+
+$ qemu-system-s390x -nographic -nodefaults -S -monitor stdio
+QEMU 2.9.92 monitor - type 'help' for more information
+(qemu) device_add diag288,id=x
+(qemu) device_del x
+**
+ERROR:qemu/qdev-monitor.c:872:qdev_unplug: assertion failed: (hotplug_ctrl)
+Aborted (core dumped)
+
+The device is not designed as hot-pluggable (it should only be used
+via the "-watchdog" parameter), so let's simply remove the possibility
+to hotplug it to prevent that users can run into this ugly situation.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1502892528-22618-1-git-send-email-thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 84ebd3e8c7d4fe955b359b9aac84395907b0412e)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/watchdog/wdt_diag288.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
+index a7b64e2..47f2892 100644
+--- a/hw/watchdog/wdt_diag288.c
++++ b/hw/watchdog/wdt_diag288.c
+@@ -121,6 +121,7 @@ static void wdt_diag288_class_init(ObjectClass *klass, void *data)
+     dc->realize = wdt_diag288_realize;
+     dc->unrealize = wdt_diag288_unrealize;
+     dc->reset = wdt_diag288_reset;
++    dc->hotpluggable = false;
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     dc->vmsd = &vmstate_diag288;
+     diag288->handle_timer = wdt_diag288_handle_timer;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-x86.conf b/SOURCES/kvm-x86.conf
new file mode 100644
index 0000000..3f7842a
--- /dev/null
+++ b/SOURCES/kvm-x86.conf
@@ -0,0 +1,12 @@
+# Setting modprobe kvm_intel/kvm_amd nested = 1
+# only enables Nested Virtualization until the next reboot or
+# module reload. Uncomment the option applicable
+# to your system below to enable the feature permanently.
+#
+# User changes in this file are preserved across upgrades.
+#
+# For Intel
+#options kvm_intel nested=1
+#
+# For AMD
+#options kvm_amd nested=1
diff --git a/SOURCES/kvm-xen-pt-Mark-TYPE_XEN_PT_DEVICE-as-hybrid.patch b/SOURCES/kvm-xen-pt-Mark-TYPE_XEN_PT_DEVICE-as-hybrid.patch
new file mode 100644
index 0000000..5055e74
--- /dev/null
+++ b/SOURCES/kvm-xen-pt-Mark-TYPE_XEN_PT_DEVICE-as-hybrid.patch
@@ -0,0 +1,43 @@
+From 031cfd078110d2ccdde9ffa446cb34ebf5592419 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:16 +0200
+Subject: [PATCH 11/19] xen/pt: Mark TYPE_XEN_PT_DEVICE as hybrid
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-7-ehabkost@redhat.com>
+Patchwork-id: 77426
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 6/7] xen/pt: Mark TYPE_XEN_PT_DEVICE as hybrid
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+xen-pt doesn't set the is_express field, but is supposed to be
+able to handle PCI Express devices too.  Mark it as hybrid.
+
+Suggested-by: Jan Beulich <JBeulich@suse.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 6d7023763ec8cc7999468769a0c6bf1335dc3bf4)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/xen/xen_pt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
+index 01df341..9bba717 100644
+--- a/hw/xen/xen_pt.c
++++ b/hw/xen/xen_pt.c
+@@ -966,6 +966,7 @@ static const TypeInfo xen_pci_passthrough_info = {
+     .class_init = xen_pci_passthrough_class_init,
+     .interfaces = (InterfaceInfo[]) {
+         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
++        { INTERFACE_PCIE_DEVICE },
+         { },
+     },
+ };
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-xio3130_downstream-Report-error-if-pcie_chassis_add_.patch b/SOURCES/kvm-xio3130_downstream-Report-error-if-pcie_chassis_add_.patch
new file mode 100644
index 0000000..a1cfe0e
--- /dev/null
+++ b/SOURCES/kvm-xio3130_downstream-Report-error-if-pcie_chassis_add_.patch
@@ -0,0 +1,53 @@
+From f6968c5837e2201172968a49dcd7cd10e1e5a337 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Fri, 20 Oct 2017 18:29:11 +0200
+Subject: [PATCH 06/19] xio3130_downstream: Report error if
+ pcie_chassis_add_slot() failed
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20171020182917.10771-2-ehabkost@redhat.com>
+Patchwork-id: 77421
+O-Subject: [RHV7.5 qemu-kvm-rhev PATCH v2 1/7] xio3130_downstream: Report error if pcie_chassis_add_slot() failed
+Bugzilla: 1390348
+RH-Acked-by: Marcel Apfelbaum <marcel@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+
+On commit f8cd1b02 ("pci: Convert to realize"), no error_set*()
+call was added for the pcie_chassis_add_slot() error case.
+pcie_chassis_add_slot() errors get ignored, making QEMU crash
+later.  e.g.:
+
+  $ qemu-system-x86_64 -device ioh3420 -device xio3130-downstream
+  qemu-system-x86_64: memory.c:2166: memory_region_del_subregion: Assertion `subregion->container == mr' failed.
+  Aborted (core dumped)
+
+Fix it by reporting the error using error_setg().
+
+Fixes: f8cd1b0201c41d88bb97dcafb80348a0e88d8805
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 8b3d26342c4aa171e759e6392fe3b742759d4963)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/pci-bridge/xio3130_downstream.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
+index e706f36..5a882b0 100644
+--- a/hw/pci-bridge/xio3130_downstream.c
++++ b/hw/pci-bridge/xio3130_downstream.c
+@@ -94,6 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
+     pcie_chassis_create(s->chassis);
+     rc = pcie_chassis_add_slot(s);
+     if (rc < 0) {
++        error_setg(errp, "Can't add chassis slot, error %d", rc);
+         goto err_pcie_cap;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm.conf b/SOURCES/kvm.conf
new file mode 100644
index 0000000..24e60e9
--- /dev/null
+++ b/SOURCES/kvm.conf
@@ -0,0 +1,3 @@
+#
+# User changes in this file are preserved across upgrades.
+#
diff --git a/SOURCES/qemu-ga.sysconfig b/SOURCES/qemu-ga.sysconfig
new file mode 100644
index 0000000..f54018e
--- /dev/null
+++ b/SOURCES/qemu-ga.sysconfig
@@ -0,0 +1,19 @@
+# This is a systemd environment file, not a shell script.
+# It provides settings for "/lib/systemd/system/qemu-guest-agent.service".
+
+# Comma-separated blacklist of RPCs to disable, or empty list to enable all.
+#
+# You can get the list of RPC commands using "qemu-ga --blacklist='?'".
+# There should be no spaces between commas and commands in the blacklist.
+BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush
+
+# Fsfreeze hook script specification.
+#
+# FSFREEZE_HOOK_PATHNAME=/dev/null           : disables the feature.
+#
+# FSFREEZE_HOOK_PATHNAME=/path/to/executable : enables the feature with the
+# specified binary or shell script.
+#
+# FSFREEZE_HOOK_PATHNAME=                    : enables the feature with the
+# default value (invoke "qemu-ga --help" to interrogate).
+FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook
diff --git a/SOURCES/qemu-guest-agent.service b/SOURCES/qemu-guest-agent.service
new file mode 100644
index 0000000..ab50e75
--- /dev/null
+++ b/SOURCES/qemu-guest-agent.service
@@ -0,0 +1,21 @@
+[Unit]
+Description=QEMU Guest Agent
+BindsTo=dev-virtio\x2dports-org.qemu.guest_agent.0.device
+After=dev-virtio\x2dports-org.qemu.guest_agent.0.device
+IgnoreOnIsolate=True
+
+[Service]
+UMask=0077
+EnvironmentFile=/etc/sysconfig/qemu-ga
+ExecStart=/usr/bin/qemu-ga \
+  --method=virtio-serial \
+  --path=/dev/virtio-ports/org.qemu.guest_agent.0 \
+  --blacklist=${BLACKLIST_RPC} \
+  -F${FSFREEZE_HOOK_PATHNAME}
+StandardError=syslog
+Restart=always
+RestartSec=0
+
+[Install]
+WantedBy=dev-virtio\x2dports-org.qemu.guest_agent.0.device
+
diff --git a/SOURCES/qemu-pr-helper.service b/SOURCES/qemu-pr-helper.service
new file mode 100644
index 0000000..a1d27b0
--- /dev/null
+++ b/SOURCES/qemu-pr-helper.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Persistent Reservation Daemon for QEMU
+
+[Service]
+WorkingDirectory=/tmp
+Type=simple
+ExecStart=/usr/bin/qemu-pr-helper
+PrivateTmp=yes
+ProtectSystem=strict
+ReadWritePaths=/var/run
+RestrictAddressFamilies=AF_UNIX
+Restart=always
+RestartSec=0
+
+[Install]
diff --git a/SOURCES/qemu-pr-helper.socket b/SOURCES/qemu-pr-helper.socket
new file mode 100644
index 0000000..9d7c3e5
--- /dev/null
+++ b/SOURCES/qemu-pr-helper.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=Persistent Reservation Daemon for QEMU
+
+[Socket]
+ListenStream=/run/qemu-pr-helper.sock
+SocketMode=0600
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/vhost.conf b/SOURCES/vhost.conf
new file mode 100644
index 0000000..68d6d7f
--- /dev/null
+++ b/SOURCES/vhost.conf
@@ -0,0 +1,3 @@
+# Increase default vhost memory map limit to match
+# KVM's memory slot limit
+options vhost max_mem_regions=509
diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec
new file mode 100644
index 0000000..73aaa96
--- /dev/null
+++ b/SPECS/qemu-kvm.spec
@@ -0,0 +1,8144 @@
+%define rhev 0
+
+%global SLOF_gittagdate 20170303
+%global SLOF_gittagcommit 66d250e
+
+%global have_usbredir 1
+%global have_spice    1
+%global have_fdt      0
+%global have_gluster  1
+%global have_kvm_setup 0
+%global have_seccomp 1
+%global have_memlock_limits 0
+%global have_vxhs     0
+%global have_vtd      0
+%global have_live_block_ops 1
+%global have_vhost_user 1
+
+%ifnarch %{ix86} x86_64
+    %global have_usbredir 0
+%endif
+
+%ifnarch s390 s390x
+    %global have_librdma 1
+    %global have_tcmalloc 1
+%else
+    %global have_librdma 0
+    %global have_tcmalloc 0
+%endif
+
+%ifarch %{ix86}
+    %global kvm_target    i386
+%endif
+%ifarch x86_64
+    %global kvm_target    x86_64
+    %global have_vxhs    1
+%else
+    %global have_spice   0
+    %global have_gluster 0
+%endif
+%ifarch %{power64}
+    %global kvm_target    ppc64
+    %global have_fdt     1
+    %global have_kvm_setup 1
+    %global have_memlock_limits 1
+%endif
+%ifarch s390x s390
+    %global kvm_target    s390x
+%endif
+%ifarch ppc
+    %global kvm_target    ppc
+    %global have_fdt     1
+%endif
+%ifarch aarch64
+    %global kvm_target    aarch64
+    %global have_fdt     1
+%endif
+
+#Versions of various parts:
+
+%define pkgname qemu-kvm
+%define rhel_ma_suffix -ma
+%define rhel_suffix -rhel
+%define rhev_suffix -rhev
+
+# Setup for RHEL/RHEV package handling
+# We need to define tree suffixes:
+# - pkgsuffix:             used for package name
+# - extra_provides_suffix: used for dependency checking of other packages
+# - conflicts_suffix:      used to prevent installation of both RHEL and RHEV
+
+%if %{rhev}
+    %global pkgsuffix %{rhev_suffix}
+    %global extra_provides_suffix %{nil}
+    %global conflicts_suffix %{rhel_suffix}
+    %global obsoletes_version 15:0-0
+    %global obsoletes_version2 15:0-0
+    %global have_vtd 1
+%else
+    %global pkgsuffix %{rhel_ma_suffix}
+    %global extra_provides_suffix %{nil}
+    %global extra_provides_suffix2 %{rhel_suffix}
+    %global conflicts_suffix %{rhev_suffix}
+    %global conflicts_suffix2 %{rhel_suffix}
+    %global have_live_block_ops 0
+    %global have_vhost_user 0
+    %global obsoletes_version 15:0-0
+%endif
+
+# Macro to properly setup RHEL/RHEV conflict handling
+%define rhel_rhev_conflicts()                                          \
+Conflicts: %1%{conflicts_suffix}                                       \
+Provides: %1%{extra_provides_suffix} = %{epoch}:%{version}-%{release}  \
+%if 0%{?extra_provides_suffix2:1}                                      \
+Provides: %1%{extra_provides_suffix2} = %{epoch}:%{version}-%{release} \
+%endif                                                                 \
+%if 0%{?conflicts_suffix2:1}                                           \
+Conflicts: %1%{conflicts_suffix2}                                      \
+%endif                                                                 \
+%if 0%{?obsoletes_version:1}                                           \
+Obsoletes: %1 < %{obsoletes_version}                                   \
+%endif                                                                 \
+%if 0%{?obsoletes_version2:1}                                          \
+Obsoletes: %1%{rhel_ma_suffix} < %{obsoletes_version2}                 \
+%endif
+
+Summary: QEMU is a machine emulator and virtualizer
+Name: %{pkgname}%{?pkgsuffix}
+Version: 2.10.0
+Release: 21%{?dist}
+# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
+Epoch: 10
+License: GPLv2+ and LGPLv2+ and BSD
+Group: Development/Tools
+URL: http://www.qemu.org/
+%if %{rhev}
+ExclusiveArch: x86_64 %{power64} aarch64 s390x
+%else
+ExclusiveArch: %{power64} aarch64 s390x
+%endif
+%ifarch %{ix86} x86_64
+Requires: seabios-bin >= 1.10.2-1
+Requires: sgabios-bin
+%endif
+%ifnarch aarch64 s390x
+Requires: seavgabios-bin >= 1.10.2-1
+Requires: ipxe-roms-qemu >= 20170123-1
+%endif
+%ifarch %{power64}
+Requires: SLOF >= %{SLOF_gittagdate}-1.git%{SLOF_gittagcommit}
+%endif
+Requires: %{pkgname}-common%{?pkgsuffix} = %{epoch}:%{version}-%{release}
+%if %{have_seccomp}
+Requires: libseccomp >= 2.3.0
+%endif
+# For compressed guest memory dumps
+Requires: lzo snappy
+%if %{have_gluster}
+Requires: glusterfs-api >= 3.6.0
+%endif
+%if %{have_kvm_setup}
+Requires(post): systemd-units
+    %ifarch %{power64}
+Requires: powerpc-utils
+    %endif
+%endif
+Requires: libusbx >= 1.0.19
+%if %{have_usbredir}
+Requires: usbredir >= 0.7.1
+%endif
+
+
+# OOM killer breaks builds with parallel make on s390(x)
+%ifarch s390 s390x
+    %define _smp_mflags %{nil}
+%endif
+
+Source0: http://wiki.qemu.org/download/qemu-2.10.0.tar.xz
+
+# Creates /dev/kvm
+Source3: 80-kvm.rules
+# KSM control scripts
+Source4: ksm.service
+Source5: ksm.sysconfig
+Source6: ksmctl.c
+Source7: ksmtuned.service
+Source8: ksmtuned
+Source9: ksmtuned.conf
+Source10: qemu-guest-agent.service
+Source11: 99-qemu-guest-agent.rules
+Source12: bridge.conf
+Source13: qemu-ga.sysconfig
+Source14: rhel6-virtio.rom
+Source15: rhel6-pcnet.rom
+Source16: rhel6-rtl8139.rom
+Source17: rhel6-ne2k_pci.rom
+Source18: bios-256k.bin
+Source19: README.rhel6-gpxe-source
+Source20: rhel6-e1000.rom
+Source21: kvm-setup
+Source22: kvm-setup.service
+Source23: 85-kvm.preset
+Source24: build_configure.sh
+Source25: kvm-unit-tests.git-4ea7633.tar.bz2
+Source26: vhost.conf
+Source27: kvm.conf
+Source28: 95-kvm-memlock.conf
+Source29: pxe-e1000e.rom
+Source30: kvm-s390x.conf
+Source31: kvm-x86.conf
+Source32: qemu-pr-helper.service
+Source33: qemu-pr-helper.socket
+
+
+
+Patch2: 0002-Initial-redhat-build.patch
+Patch3: 0003-Add-RHEL-7-machine-types.patch
+Patch4: 0004-Enable-disable-devices-for-RHEL-7.patch
+Patch5: 0005-Use-kvm-by-default.patch
+Patch6: 0006-add-qxl_screendump-monitor-command.patch
+Patch7: 0007-seabios-paravirt-allow-more-than-1TB-in-x86-guest.patch
+Patch8: 0008-monitor-Remove-usb_add-del-commands-for-Red-Hat-Ente.patch
+Patch9: 0009-monitor-Remove-host_net_add-remove-for-Red-Hat-Enter.patch
+Patch10: 0010-vfio-cap-number-of-devices-that-can-be-assigned.patch
+Patch11: 0011-QMP-Forward-port-__com.redhat_drive_del-from-RHEL-6.patch
+Patch12: 0012-QMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch
+Patch13: 0013-HMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch
+Patch14: 0014-Add-support-statement-to-help-output.patch
+Patch15: 0015-vl-Round-memory-sizes-below-2MiB-up-to-2MiB.patch
+Patch16: 0016-use-recommended-max-vcpu-count.patch
+Patch17: 0017-Add-support-for-simpletrace.patch
+Patch18: 0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch
+Patch19: 0019-qmp-add-__com.redhat_reason-to-the-BLOCK_IO_ERROR-ev.patch
+Patch20: 0020-Migration-compat-for-pckbd.patch
+Patch21: 0021-Migration-compat-for-fdc.patch
+Patch22: 0022-RHEL-Set-vcpus-hard-limit-to-240-for-Power.patch
+Patch23: 0023-spapr-Reduce-advertised-max-LUNs-for-spapr_vscsi.patch
+Patch24: 0024-qmp-Report-__com.redhat_drive_add-error-to-monitor.patch
+Patch25: 0025-RHEL-only-hw-char-pl011-fix-SBSA-reset.patch
+Patch26: 0026-blockdev-ignore-cache-options-for-empty-CDROM-drives.patch
+Patch27: 0027-Revert-kvm_stat-Remove.patch
+Patch28: 0028-migcompat-e1000e-Work-around-7.3-msi-intr_state-fiel.patch
+Patch29: 0029-migcompat-rtl8139-Work-around-version-bump.patch
+Patch30: 0030-usb-xhci-Fix-PCI-capability-order.patch
+Patch31: 0031-blockdev-ignore-aio-native-for-empty-drives.patch
+Patch32: 0032-scsi-Disable-deprecated-implicit-SCSI-HBA-creation-m.patch
+Patch33: 0033-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch
+Patch34: 0034-hmp-fix-dump-quest-memory-segfault-ppc.patch
+Patch35: 0035-hmp-fix-dump-quest-memory-segfault-arm.patch
+Patch36: 0036-dump-do-not-dump-non-existent-guest-memory.patch
+Patch37: 0037-tests-hmp-test-none-machine-with-memory.patch
+Patch38: 0038-vfio-spapr-Fix-levels-calculation.patch
+# For bz#1489670 - Hot-unplugging a vhost network device leaks references to VFIOPCIDevice's
+Patch39: kvm-vhost-Release-memory-references-on-cleanup.patch
+# For bz#1491647 - [RFE] Enable seccomp (sandbox) support in QEMU for s390x
+Patch40: kvm-configure-Allow-enable-seccomp-on-s390x-too.patch
+# For bz#1448344 - Failed to hot unplug cpu core which hotplugged in early boot stages
+Patch41: kvm-hw-ppc-spapr_drc.c-change-spapr_drc_needed-to-use-dr.patch
+# For bz#1448344 - Failed to hot unplug cpu core which hotplugged in early boot stages
+Patch42: kvm-hw-ppc-clear-pending_events-on-machine-reset.patch
+# For bz#1448344 - Failed to hot unplug cpu core which hotplugged in early boot stages
+Patch43: kvm-hw-ppc-CAS-reset-on-early-device-hotplug.patch
+# For bz#1448344 - Failed to hot unplug cpu core which hotplugged in early boot stages
+Patch44: kvm-spapr-fix-CAS-generated-reset.patch
+# For bz#1498754 - Definition of HW_COMPAT_RHEL7_3 is not correct
+Patch45: kvm-redhat-fix-HW_COMPAT_RHEL7_3.patch
+# For bz#1486643 - CVE-2017-13672 qemu-kvm-rhev: Qemu: vga: OOB read access during display update [rhel-7.5]
+Patch46: kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch
+# For bz#1494548 - Disable ais facility on s390x
+Patch47: kvm-s390x-ais-for-2.10-stable-disable-ais-facility.patch
+# For bz#1494548 - Disable ais facility on s390x
+Patch48: kvm-s390x-cpumodel-remove-ais-from-z14-default-model-als.patch
+# For bz#1479178 - QEMU does not yet have support for setting the virtual SMT mode on Power 9, which is required to run with KVM and more than one thread per core.
+Patch49: kvm-PPC-KVM-Support-machine-option-to-set-VSMT-mode.patch
+# For bz#1482478 - Fail to quit source qemu when do live migration after mirroring guest to NBD server
+Patch50: kvm-nbd-client-avoid-read_reply_co-entry-if-send-failed.patch
+# For bz#1482478 - Fail to quit source qemu when do live migration after mirroring guest to NBD server
+Patch51: kvm-qemu-iotests-improve-nbd-fault-injector.py-startup-p.patch
+# For bz#1482478 - Fail to quit source qemu when do live migration after mirroring guest to NBD server
+Patch52: kvm-qemu-iotests-test-NBD-over-UNIX-domain-sockets-in-08.patch
+# For bz#1482478 - Fail to quit source qemu when do live migration after mirroring guest to NBD server
+Patch53: kvm-block-nbd-client-nbd_co_send_request-fix-return-code.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch54: kvm-usb-drop-HOST_USB.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch55: kvm-usb-only-build-usb-host-with-CONFIG_USB-y.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch56: kvm-usb-fix-libusb-config-variable-name.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch57: kvm-usb-fix-host-stub.c-build-race.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch58: kvm-s390x-s390-stattrib-Mark-the-storage-attribute-as-no.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch59: kvm-s390x-s390-skeys-Mark-the-storage-key-devices-with-u.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch60: kvm-watchdog-wdt_diag288-Mark-diag288-watchdog-as-non-ho.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch61: kvm-s390x-ipl-The-s390-ipl-device-is-not-hot-pluggable.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch62: kvm-hw-s390x-Mark-the-sclpquiesce-device-with-user_creat.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch63: kvm-s390x-sclp-mark-sclp-cpu-hotplug-as-non-usercreatabl.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch64: kvm-s390x-sclp-Mark-the-sclp-device-with-user_creatable-.patch
+# For bz#1492033 - Disable unwanted device in QEMU for s390x
+Patch65: kvm-RHEL-Disable-vfio-ccw-and-x-terminal3270-devices.patch
+# For bz#1473292 - Need RHEL-specific machine types for qemu-kvm on s390x
+Patch66: kvm-s390x-css-fix-css-migration-compat-handling.patch
+# For bz#1473292 - Need RHEL-specific machine types for qemu-kvm on s390x
+Patch67: kvm-RHEL-Add-RHEL7-machine-type-for-qemu-on-s390x.patch
+# For bz#1490869 - [Pegas1.0] qemu device spapr-nvram crashes with SIGABRT (qemu-kvm)
+Patch68: kvm-hw-nvram-spapr_nvram-Device-can-not-be-created-by-th.patch
+# For bz#1491743 - qemu crashes with 'Abort' when a negative number is used for 'maxcpus' argument (qemu-kvm)
+Patch69: kvm-vl-exit-if-maxcpus-is-negative.patch
+# For bz#1460595 - [virtio-vga]Display 2 should be dropped when guest reboot
+Patch70: kvm-virtio-gpu-don-t-clear-QemuUIInfo-information-on-res.patch
+# For bz#1486648 - CVE-2017-13673 qemu-kvm-rhev: Qemu: vga: reachable assert failure during during display update [rhel-7.5]
+Patch71: kvm-vga-fix-display-update-region-calculation-split-scre.patch
+# For bz#1445834 - Add support for AMD EPYC processors
+Patch72: kvm-target-i386-cpu-Add-new-EPYC-CPU-model.patch
+# For bz#1498865 - There is no switch to build qemu-kvm-rhev or qemu-kvm-ma packages
+Patch73: kvm-redhat-add-CONFIG_RHV-flag.patch
+# For bz#1449067 - [RFE] Device passthrough support for VT-d emulation
+Patch74: kvm-intel_iommu-fix-missing-BQL-in-pt-fast-path.patch
+# For bz#1478478 - RHEL 7.5 machine types for Power 8 and 9 - qemu-kvm-ma
+Patch75: kvm-redhat-define-HW_COMPAT_RHEL7_4.patch
+# For bz#1478478 - RHEL 7.5 machine types for Power 8 and 9 - qemu-kvm-ma
+Patch76: kvm-redhat-define-pseries-rhel7.5.0-machine-type.patch
+# For bz#1478478 - RHEL 7.5 machine types for Power 8 and 9 - qemu-kvm-ma
+Patch77: kvm-qemu-kvm-ma-define-only-pseries-rhel7.5.0-machine-ty.patch
+# For bz#1499011 - 7.5: x86 machine types for 7.5
+Patch78: kvm-Create-x86-7.5.0-machine-types.patch
+# For bz#1500347 - [Hyper-V][RHEL-7.4]Nested virt: Windows guest doesn't use TSC page when Hyper-V role is enabled
+Patch79: kvm-i386-kvm-use-a-switch-statement-for-MSR-detection.patch
+# For bz#1500347 - [Hyper-V][RHEL-7.4]Nested virt: Windows guest doesn't use TSC page when Hyper-V role is enabled
+Patch80: kvm-i386-kvm-set-tsc_khz-before-configuring-Hyper-V-CPUI.patch
+# For bz#1500347 - [Hyper-V][RHEL-7.4]Nested virt: Windows guest doesn't use TSC page when Hyper-V role is enabled
+Patch81: kvm-i386-kvm-introduce-tsc_is_stable_and_known.patch
+# For bz#1500347 - [Hyper-V][RHEL-7.4]Nested virt: Windows guest doesn't use TSC page when Hyper-V role is enabled
+Patch82: kvm-i386-kvm-advertise-Hyper-V-frequency-MSRs.patch
+# For bz#1489800 - q35/ovmf: Machine type compat vs OVMF vs windows
+Patch83: kvm-acpi-Force-rev1-FADT-on-old-q35-machine-types.patch
+# For bz#1489800 - q35/ovmf: Machine type compat vs OVMF vs windows
+Patch84: kvm-pc-make-pc_rom-RO-only-on-new-machine-types.patch
+# For bz#1378241 - QEMU image file locking
+Patch85: kvm-osdep-Force-define-F_OFD_GETLK-RHEL-only.patch
+# For bz#1498496 - Handle device tree changes in QEMU 2.10.0
+Patch86: kvm-Disable-vhost-user-scsi-and-vhost-user-scsi-pci.patch
+# For bz#1498496 - Handle device tree changes in QEMU 2.10.0
+Patch87: kvm-Disable-sm501-and-sysbus-sm501-devices.patch
+# For bz#1485399 - Backport selective allocation of PGSTE to avoid global vm.allocate_pgste
+Patch88: kvm-configure-enable-s390-pgste-linker-option.patch
+# For bz#1498662 - RHEL-7.5 machine machine type for aarch64 (qemu-kvm-ma)
+Patch90: kvm-arm-virt-Add-RHEL-7.5-machine-type.patch
+# For bz#1497137 - Update kvm_stat
+Patch91: kvm-tools-kvm_stat-hide-cursor.patch
+# For bz#1497137 - Update kvm_stat
+Patch92: kvm-tools-kvm_stat-catch-curses-exceptions-only.patch
+# For bz#1497137 - Update kvm_stat
+Patch93: kvm-tools-kvm_stat-handle-SIGINT-in-log-and-batch-modes.patch
+# For bz#1497137 - Update kvm_stat
+Patch94: kvm-tools-kvm_stat-fix-misc-glitches.patch
+# For bz#1497137 - Update kvm_stat
+Patch95: kvm-tools-kvm_stat-fix-trace-setup-glitch-on-field-updat.patch
+# For bz#1497137 - Update kvm_stat
+Patch96: kvm-tools-kvm_stat-full-PEP8-compliance.patch
+# For bz#1497137 - Update kvm_stat
+Patch97: kvm-tools-kvm_stat-reduce-perceived-idle-time-on-filter-.patch
+# For bz#1497137 - Update kvm_stat
+Patch98: kvm-tools-kvm_stat-document-list-of-interactive-commands.patch
+# For bz#1497137 - Update kvm_stat
+Patch99: kvm-tools-kvm_stat-display-guest-name-when-using-pid-fil.patch
+# For bz#1497137 - Update kvm_stat
+Patch100: kvm-tools-kvm_stat-remove-pid-filter-on-empty-input.patch
+# For bz#1497137 - Update kvm_stat
+Patch101: kvm-tools-kvm_stat-print-error-messages-on-faulty-pid-fi.patch
+# For bz#1497137 - Update kvm_stat
+Patch102: kvm-tools-kvm_stat-display-regex-when-set-to-non-default.patch
+# For bz#1497137 - Update kvm_stat
+Patch103: kvm-tools-kvm_stat-remove-regex-filter-on-empty-input.patch
+# For bz#1497137 - Update kvm_stat
+Patch104: kvm-tools-kvm_stat-add-option-guest.patch
+# For bz#1497137 - Update kvm_stat
+Patch105: kvm-tools-kvm_stat-add-interactive-command-c.patch
+# For bz#1497137 - Update kvm_stat
+Patch106: kvm-tools-kvm_stat-add-interactive-command-r.patch
+# For bz#1497137 - Update kvm_stat
+Patch107: kvm-tools-kvm_stat-add-Total-column.patch
+# For bz#1497137 - Update kvm_stat
+Patch108: kvm-tools-kvm_stat-fix-typo.patch
+# For bz#1497137 - Update kvm_stat
+Patch109: kvm-tools-kvm_stat-fix-event-counts-display-for-interrup.patch
+# For bz#1497137 - Update kvm_stat
+Patch110: kvm-tools-kvm_stat-fix-undue-use-of-initial-sleeptime.patch
+# For bz#1497137 - Update kvm_stat
+Patch111: kvm-tools-kvm_stat-remove-unnecessary-header-redraws.patch
+# For bz#1497137 - Update kvm_stat
+Patch112: kvm-tools-kvm_stat-simplify-line-print-logic.patch
+# For bz#1497137 - Update kvm_stat
+Patch113: kvm-tools-kvm_stat-removed-unused-function.patch
+# For bz#1497137 - Update kvm_stat
+Patch114: kvm-tools-kvm_stat-remove-extra-statement.patch
+# For bz#1497137 - Update kvm_stat
+Patch115: kvm-tools-kvm_stat-simplify-initializers.patch
+# For bz#1497137 - Update kvm_stat
+Patch116: kvm-tools-kvm_stat-move-functions-to-corresponding-class.patch
+# For bz#1497137 - Update kvm_stat
+Patch117: kvm-tools-kvm_stat-show-cursor-in-selection-screens.patch
+# For bz#1497137 - Update kvm_stat
+Patch118: kvm-tools-kvm_stat-display-message-indicating-lack-of-ev.patch
+# For bz#1497137 - Update kvm_stat
+Patch119: kvm-tools-kvm_stat-make-heading-look-a-bit-more-like-top.patch
+# For bz#1497137 - Update kvm_stat
+Patch120: kvm-tools-kvm_stat-rename-Current-column-to-CurAvg-s.patch
+# For bz#1497137 - Update kvm_stat
+Patch121: kvm-tools-kvm_stat-add-new-interactive-command-h.patch
+# For bz#1497137 - Update kvm_stat
+Patch122: kvm-tools-kvm_stat-add-new-interactive-command-s.patch
+# For bz#1497137 - Update kvm_stat
+Patch123: kvm-tools-kvm_stat-add-new-interactive-command-o.patch
+# For bz#1497137 - Update kvm_stat
+Patch124: kvm-tools-kvm_stat-display-guest-list-in-pid-guest-selec.patch
+# For bz#1497137 - Update kvm_stat
+Patch125: kvm-tools-kvm_stat-display-guest-list-in-pid-guest-sele2.patch
+# For bz#1497137 - Update kvm_stat
+Patch126: kvm-tools-kvm_stat-add-new-command-line-switch-i.patch
+# For bz#1497137 - Update kvm_stat
+Patch127: kvm-tools-kvm_stat-add-new-interactive-command-b.patch
+# For bz#1497137 - Update kvm_stat
+Patch128: kvm-tools-kvm_stat-use-variables-instead-of-hard-paths-i.patch
+# For bz#1497137 - Update kvm_stat
+Patch129: kvm-tools-kvm_stat-add-f-help-to-get-the-available-event.patch
+# For bz#1460848 - RFE: Enhance qemu to support freeing memory before exit when using memory-backend-file
+Patch130: kvm-iothread-Make-iothread_stop-idempotent.patch
+# For bz#1460848 - RFE: Enhance qemu to support freeing memory before exit when using memory-backend-file
+Patch131: kvm-vl-Clean-up-user-creatable-objects-when-exiting.patch
+# For bz#1460848 - RFE: Enhance qemu to support freeing memory before exit when using memory-backend-file
+Patch132: kvm-osdep-Define-QEMU_MADV_REMOVE.patch
+# For bz#1460848 - RFE: Enhance qemu to support freeing memory before exit when using memory-backend-file
+Patch133: kvm-hostmem-file-Add-discard-data-option.patch
+# For bz#1503998 - Remove redundant "user_creatable = false" flags from the downstream qemu-kvm-rhev code
+Patch134: kvm-hw-dma-i8257-Remove-redundant-downstream-user_creata.patch
+# For bz#1503998 - Remove redundant "user_creatable = false" flags from the downstream qemu-kvm-rhev code
+Patch135: kvm-hw-pci-host-q35-Remove-redundant-downstream-user_cre.patch
+# For bz#1503998 - Remove redundant "user_creatable = false" flags from the downstream qemu-kvm-rhev code
+Patch136: kvm-hw-Remove-the-redundant-user_creatable-false-from-SY.patch
+# For bz#1499320 - qemu-kvm-ma differentiation - cpu unplug
+Patch137: kvm-spapr-disable-cpu-hot-remove.patch
+# For bz#1501301 - CVE-2017-15289 qemu-kvm-rhev: Qemu: cirrus: OOB access issue in  mode4and5 write functions [rhel-7.5]
+Patch138: kvm-vga-drop-line_offset-variable.patch
+# For bz#1501301 - CVE-2017-15289 qemu-kvm-rhev: Qemu: cirrus: OOB access issue in  mode4and5 write functions [rhel-7.5]
+Patch139: kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch
+# For bz#1501301 - CVE-2017-15289 qemu-kvm-rhev: Qemu: cirrus: OOB access issue in  mode4and5 write functions [rhel-7.5]
+Patch140: kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch
+# For bz#1498817 - Vhost IOMMU support regression since qemu-kvm-rhev-2.9.0-16.el7_4.5
+Patch141: kvm-exec-add-page_mask-for-address_space_do_translate.patch
+# For bz#1498817 - Vhost IOMMU support regression since qemu-kvm-rhev-2.9.0-16.el7_4.5
+Patch142: kvm-exec-simplify-address_space_get_iotlb_entry.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch143: kvm-xio3130_downstream-Report-error-if-pcie_chassis_add_.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch144: kvm-pci-conventional-pci-device-and-pci-express-device-i.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch145: kvm-pci-Add-interface-names-to-hybrid-PCI-devices.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch146: kvm-pci-Add-INTERFACE_PCIE_DEVICE-to-all-PCIe-devices.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch147: kvm-pci-Add-INTERFACE_CONVENTIONAL_PCI_DEVICE-to-Convent.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch148: kvm-xen-pt-Mark-TYPE_XEN_PT_DEVICE-as-hybrid.patch
+# For bz#1390348 - PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid
+Patch149: kvm-pci-Validate-interfaces-on-base_class_init.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch150: kvm-migration-Add-pause-before-switchover-capability.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch151: kvm-migration-Add-pre-switchover-and-device-statuses.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch152: kvm-migration-Wait-for-semaphore-before-completing-migra.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch153: kvm-migration-migrate-continue.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch154: kvm-migrate-HMP-migate_continue.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch155: kvm-migration-allow-cancel-to-unpause.patch
+# For bz#1497120 - migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed
+Patch156: kvm-migration-pause-before-switchover-for-postcopy.patch
+# For bz#1478469 - RHEL 7.5 machine types for Power 8 and 9 - qemu-kvm-rhev
+Patch157: kvm-qemu-kvm-rhev-only-allows-pseries-rhel7.5.0-machine-.patch
+# For bz#1503128 - update reverse keymaps for qemu vnc server
+Patch158: kvm-pc-bios-keymaps-keymaps-update.patch
+# For bz#1508799 - qemu-kvm core dumped when doing 'savevm/loadvm/delvm' for the second time
+Patch159: kvm-migration-Reset-rather-than-destroy-main_thread_load.patch
+# For bz#1508799 - qemu-kvm core dumped when doing 'savevm/loadvm/delvm' for the second time
+Patch160: kvm-snapshot-tests-Try-loadvm-twice.patch
+# For bz#1508271 - Migration is failed from host RHEL7.4.z to host RHEL7.5 with "-machine pseries-rhel7.4.0 -device pci-bridge,id=pci_bridge,bus=pci.0,addr=03,chassis_nr=1"
+Patch161: kvm-machine-compat-pci_bridge-shpc-always-enable.patch
+# For bz#1460957 - Implement INTx to GSI routing on ARM virt
+Patch162: kvm-hw-pci-host-gpex-Set-INTx-index-gsi-mapping.patch
+# For bz#1460957 - Implement INTx to GSI routing on ARM virt
+Patch163: kvm-hw-arm-virt-Set-INTx-gsi-mapping.patch
+# For bz#1460957 - Implement INTx to GSI routing on ARM virt
+Patch164: kvm-hw-pci-host-gpex-Implement-PCI-INTx-routing.patch
+# For bz#1460957 - Implement INTx to GSI routing on ARM virt
+Patch165: kvm-hw-pci-host-gpex-Improve-INTX-to-gsi-routing-error-c.patch
+# For bz#1501124 - CVE-2017-14167 qemu-kvm-rhev: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5]
+Patch166: kvm-multiboot-validate-multiboot-header-address-values.patch
+# For bz#1510001 - Pegas1.0 - qemu crashed during "info cpus" in monitor with change in default cpu in hotplug/unplug sequence (kvm)
+Patch167: kvm-monitor-fix-dangling-CPU-pointer.patch
+# For bz#1445460 - EEH freeze up when reattaching an i40evf VF to host
+Patch168: kvm-qdev-store-DeviceState-s-canonical-path-to-use-when-.patch
+# For bz#1445460 - EEH freeze up when reattaching an i40evf VF to host
+Patch169: kvm-Revert-qdev-Free-QemuOpts-when-the-QOM-path-goes-awa.patch
+# For bz#1445460 - EEH freeze up when reattaching an i40evf VF to host
+Patch170: kvm-qdev-defer-DEVICE_DEL-event-until-instance_finalize.patch
+# For bz#1504138 - Disable older CPU models in qemu-kvm-ma on s390x
+Patch171: kvm-s390x-print-CPU-definitions-in-sorted-order.patch
+# For bz#1504138 - Disable older CPU models in qemu-kvm-ma on s390x
+Patch172: kvm-s390x-cpumodel-Disable-unsupported-CPU-models.patch
+# For bz#1437113 - PCIe: Allow configuring  Generic PCIe Root Ports MMIO Window
+Patch173: kvm-hw-pci-introduce-bridge-only-vendor-specific-capabil.patch
+# For bz#1437113 - PCIe: Allow configuring  Generic PCIe Root Ports MMIO Window
+Patch174: kvm-hw-pci-add-QEMU-specific-PCI-capability-to-the-Gener.patch
+# For bz#1508886 - QEMU's AIO subsystem gets stuck inhibiting all I/O operations on virtio-blk-pci devices
+Patch175: kvm-util-async-use-atomic_mb_set-in-qemu_bh_cancel.patch
+# For bz#1344299 - PCIe: Add an option to PCIe ports to disable IO port space support
+Patch176: kvm-hw-gen_pcie_root_port-make-IO-RO-0-on-IO-disabled.patch
+# For bz#1511312 - Migrate an VM with  pci-bridge or pcie-root-port failed
+Patch177: kvm-pcie_root_port-Fix-x-migrate-msix-compat.patch
+# For bz#1511312 - Migrate an VM with  pci-bridge or pcie-root-port failed
+Patch178: kvm-q35-Fix-mismerge.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch179: kvm-virtio-pci-Replace-modern_as-with-direct-access-to-m.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch180: kvm-atomic-update-documentation.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch181: kvm-memory-avoid-resurrection-of-dead-FlatViews.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch182: kvm-exec-Explicitly-export-target-AS-from-address_space_.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch183: kvm-memory-Open-code-FlatView-rendering.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch184: kvm-memory-Move-FlatView-allocation-to-a-helper.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch185: kvm-memory-Move-AddressSpaceDispatch-from-AddressSpace-t.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch186: kvm-memory-Remove-AddressSpace-pointer-from-AddressSpace.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch187: kvm-memory-Switch-memory-from-using-AddressSpace-to-Flat.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch188: kvm-memory-Cleanup-after-switching-to-FlatView.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch189: kvm-memory-Rename-mem_begin-mem_commit-mem_add-helpers.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch190: kvm-memory-Store-physical-root-MR-in-FlatView.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch191: kvm-memory-Alloc-dispatch-tree-where-topology-is-generar.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch192: kvm-memory-Move-address_space_update_ioeventfds.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch193: kvm-memory-Share-FlatView-s-and-dispatch-trees-between-a.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch194: kvm-memory-Do-not-allocate-FlatView-in-address_space_ini.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch195: kvm-memory-Rework-info-mtree-to-print-flat-views-and-dis.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch196: kvm-memory-Get-rid-of-address_space_init_shareable.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch197: kvm-memory-Create-FlatView-directly.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch198: kvm-memory-trace-FlatView-creation-and-destruction.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch199: kvm-memory-seek-FlatView-sharing-candidates-among-childr.patch
+# For bz#1481593 - Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges
+Patch200: kvm-memory-Share-special-empty-FlatView.patch
+# For bz#1390346 - PCI: Reserve MMIO space over 4G for PCI hotplug
+Patch201: kvm-hw-pci-host-Fix-x86-Host-Bridges-64bit-PCI-hole.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch202: kvm-block-move-ThrottleGroup-membership-to-ThrottleGroup.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch203: kvm-block-add-aio_context-field-in-ThrottleGroupMember.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch204: kvm-block-tidy-ThrottleGroupMember-initializations.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch205: kvm-block-all-I-O-should-be-completed-before-removing-th.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch206: kvm-throttle-groups-drain-before-detaching-ThrottleState.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch207: kvm-block-Check-for-inserted-BlockDriverState-in-blk_io_.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch208: kvm-block-Leave-valid-throttle-timers-when-removing-a-BD.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch209: kvm-qemu-iotests-Test-I-O-limits-with-removable-media.patch
+# For bz#1492295 - Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing
+Patch210: kvm-throttle-groups-forget-timer-and-schedule-next-TGM-o.patch
+# For bz#1451959 - Windows 2016 guest blue screen with page fault in nonpaged area when using hv flags
+Patch211: kvm-i386-cpu-hyperv-support-over-64-vcpus-for-windows-gu.patch
+# For bz#1396120 - [IBM 7.5 FEAT] POWER9 - Virt: QEMU: POWER8/P8-Compat mode - HPT to guest
+Patch212: kvm-target-ppc-correct-htab-shift-for-hash-on-radix.patch
+# For bz#1396120 - [IBM 7.5 FEAT] POWER9 - Virt: QEMU: POWER8/P8-Compat mode - HPT to guest
+Patch213: kvm-target-ppc-Update-setting-of-cpu-features-to-account.patch
+# For bz#1514352 - [RHEL-ALT][s390x] qemu process terminated after rebooting the guest
+Patch214: kvm-s390-ccw-Fix-alignment-for-CCW1.patch
+# For bz#1514352 - [RHEL-ALT][s390x] qemu process terminated after rebooting the guest
+Patch215: kvm-pc-bios-s390-ccw-Fix-problem-with-invalid-virtio-scs.patch
+# For bz#1499647 - qemu miscalculates guest RAM size during HPT resizing
+Patch216: kvm-spapr-Correct-RAM-size-calculation-for-HPT-resizing.patch
+# For bz#1515173 - Cross migration from rhel6.9 to rhel7.5 failed
+Patch217: kvm-migration-Reenable-incoming-live-block-migration.patch
+# For bz#1506882 - Call trace showed up in dmesg after migrating guest when "stress-ng --numa 2" was running inside guest
+Patch218: kvm-ppc-fix-VTB-migration.patch
+# For bz#1515393 - bootindex is not taken into account for virtio-scsi devices on ppc64 if the LUN is >= 256
+Patch219: kvm-hw-ppc-spapr-Fix-virtio-scsi-bootindex-handling-for-.patch
+# For bz#1495090 - Transfer a file about 10M failed from host to guest through spapr-vty device
+Patch220: kvm-spapr-Implement-bug-in-spapr-vty-device-to-be-compat.patch
+# For bz#1516145 - Pegas1.0 - [memory hotplug/unplug] qemu crashes with assertion failed from hw/virtio/vhost.c:649 (qemu-kvm)
+Patch221: kvm-spapr-reset-DRCs-after-devices.patch
+# For bz#1414049 - [RFE] Add support to qemu-img  for resizing with preallocation
+Patch222: kvm-qcow2-fix-return-error-code-in-qcow2_truncate.patch
+# For bz#1414049 - [RFE] Add support to qemu-img  for resizing with preallocation
+Patch223: kvm-qcow2-Fix-unaligned-preallocated-truncation.patch
+# For bz#1414049 - [RFE] Add support to qemu-img  for resizing with preallocation
+Patch224: kvm-qcow2-Always-execute-preallocate-in-a-coroutine.patch
+# For bz#1414049 - [RFE] Add support to qemu-img  for resizing with preallocation
+Patch225: kvm-iotests-Add-cluster_size-64k-to-125.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch226: kvm-fw_cfg-rename-read-callback.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch227: kvm-fw_cfg-add-write-callback.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch228: kvm-hw-misc-add-vmcoreinfo-device.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch229: kvm-dump-add-guest-ELF-note.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch230: kvm-dump-update-phys_base-header-field-based-on-VMCOREIN.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch231: kvm-kdump-set-vmcoreinfo-location.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch232: kvm-scripts-dump-guest-memory.py-add-vmcoreinfo.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch233: kvm-vmcoreinfo-put-it-in-the-misc-device-category.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch234: kvm-build-sys-restrict-vmcoreinfo-to-fw_cfg-dma-capable-.patch
+# For bz#1508750 - CVE-2017-13711 qemu-kvm-rhev: Qemu: Slirp: use-after-free when sending response [rhel-7.5]
+Patch235: kvm-slirp-fix-clearing-ifq_so-from-pending-packets.patch
+# For bz#1516956 - Pegas1.0 - [qemu]: loadvm fails to restore VM snapshot saved using savevm in destination after postcopy migration (kvm)
+Patch236: kvm-migration-ram.c-do-not-set-postcopy_running-in-POSTC.patch
+# For bz#1497740 - -cdrom option is broken
+Patch237: kvm-scsi-Fix-onboard-HBAs-to-pick-up-drive-if-scsi.patch
+# For bz#1506151 - [data-plane] Quitting qemu in destination side encounters "core dumped" when doing live migration
+Patch238: kvm-virtio-net-don-t-touch-virtqueue-if-vm-is-stopped.patch
+# For bz#1498042 - RFE: option to mark virtual block device as rotational/non-rotational
+Patch239: kvm-scsi-disk-support-reporting-of-rotation-rate.patch
+# For bz#1498042 - RFE: option to mark virtual block device as rotational/non-rotational
+Patch240: kvm-ide-support-reporting-of-rotation-rate.patch
+# For bz#1498042 - RFE: option to mark virtual block device as rotational/non-rotational
+Patch241: kvm-ide-avoid-referencing-NULL-dev-in-rotational-rate-se.patch
+# For bz#1406803 - RFE: native integration of LUKS and qcow2
+Patch242: kvm-qcow2-don-t-permit-changing-encryption-parameters.patch
+# For bz#1406803 - RFE: native integration of LUKS and qcow2
+Patch243: kvm-qcow2-fix-image-corruption-after-committing-qcow2-im.patch
+# For bz#1494210 - Document image locking in the qemu-img manpage
+Patch244: kvm-qemu-doc-Add-UUID-support-in-initiator-name.patch
+# For bz#1494210 - Document image locking in the qemu-img manpage
+Patch245: kvm-docs-add-qemu-block-drivers-7-man-page.patch
+# For bz#1494210 - Document image locking in the qemu-img manpage
+Patch246: kvm-docs-Add-image-locking-subsection.patch
+# For bz#1494210 - Document image locking in the qemu-img manpage
+Patch247: kvm-qemu-options-Mention-locking-option-of-file-driver.patch
+# For bz#1505701 - -blockdev fails if a qcow2 image has backing store format and backing store is referenced via node-name
+Patch248: kvm-block-don-t-add-driver-to-options-when-referring-to-.patch
+# For bz#1487515 - wrong error code is reported if __com.redhat.drive_del can't find the device to delete
+Patch249: kvm-blockdev-Report-proper-error-class-in-__com.redhat.d.patch
+# For bz#1500334 - LUKS driver has poor performance compared to in-kernel driver
+Patch250: kvm-block-use-1-MB-bounce-buffers-for-crypto-instead-of-.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch251: kvm-io-add-new-qio_channel_-readv-writev-read-write-_all.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch252: kvm-io-Yield-rather-than-wait-when-already-in-coroutine.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch253: kvm-scsi-bus-correct-responses-for-INQUIRY-and-REQUEST-S.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch254: kvm-scsi-Refactor-scsi-sense-interpreting-code.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch255: kvm-scsi-Improve-scsi_sense_to_errno.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch256: kvm-scsi-Introduce-scsi_sense_buf_to_errno.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch257: kvm-scsi-rename-scsi_build_sense-to-scsi_convert_sense.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch258: kvm-scsi-move-non-emulation-specific-code-to-scsi.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch259: kvm-scsi-introduce-scsi_build_sense.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch260: kvm-scsi-introduce-sg_io_sense_from_errno.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch261: kvm-scsi-move-block-scsi.h-to-include-scsi-constants.h.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch262: kvm-scsi-file-posix-add-support-for-persistent-reservati.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch263: kvm-scsi-build-qemu-pr-helper.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch264: kvm-scsi-add-multipath-support-to-qemu-pr-helper.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch265: kvm-scsi-add-persistent-reservation-manager-using-qemu-p.patch
+# For bz#1464908 - [RFE] Add S3 PR support to qemu (similar to mpathpersist)
+Patch266: kvm-qemu-pr-helper-miscellaneous-fixes.patch
+# For bz#1495456 - Update downstream qemu's max supported cpus for pseries to the RHEL supported number
+Patch267: kvm-Match-POWER-max-cpus-to-x86.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch268: kvm-qemu-io-Drop-write-permissions-before-read-only-reop.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch269: kvm-block-Add-reopen_queue-to-bdrv_child_perm.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch270: kvm-block-Add-reopen-queue-to-bdrv_check_perm.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch271: kvm-block-Base-permissions-on-rw-state-after-reopen.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch272: kvm-block-reopen-Queue-children-after-their-parents.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch273: kvm-block-Fix-permissions-after-bdrv_reopen.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch274: kvm-qemu-iotests-Test-change-backing-file-command.patch
+# For bz#1492178 - Non-top-level change-backing-file causes assertion failure
+Patch275: kvm-iotests-Fix-195-if-IMGFMT-is-part-of-TEST_DIR.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch276: kvm-block-add-bdrv_co_drain_end-callback.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch277: kvm-block-rename-bdrv_co_drain-to-bdrv_co_drain_begin.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch278: kvm-blockjob-do-not-allow-coroutine-double-entry-or-entr.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch279: kvm-coroutine-abort-if-we-try-to-schedule-or-enter-a-pen.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch280: kvm-qemu-iotests-add-option-in-common.qemu-for-mismatch-.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch281: kvm-qemu-iotest-add-test-for-blockjob-coroutine-race-con.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch282: kvm-blockjob-Remove-the-job-from-the-list-earlier-in-blo.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch283: kvm-block-Expect-graph-changes-in-bdrv_parent_drained_be.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch284: kvm-blockjob-remove-clock-argument-from-block_job_sleep_.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch285: kvm-blockjob-introduce-block_job_do_yield.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch286: kvm-blockjob-reimplement-block_job_sleep_ns-to-allow-can.patch
+# For bz#1506531 - [data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running
+Patch287: kvm-blockjob-Make-block_job_pause_all-keep-a-reference-t.patch
+# For bz#1517051 - POWER9 - Virt: QEMU: Migration of HPT guest on Radix host fails
+Patch288: kvm-target-ppc-Move-setting-of-patb_entry-on-hash-table-.patch
+# For bz#1517051 - POWER9 - Virt: QEMU: Migration of HPT guest on Radix host fails
+Patch289: kvm-target-ppc-Fix-setting-of-cpu-compat_pvr-on-incoming.patch
+# For bz#1513294 - Guest got stuck when attached memory beforehand.[-device dimm and object memory-backend-ram]
+Patch290: kvm-BZ1513294-spapr-Include-pre-plugged-DIMMS-in-ram-siz.patch
+# For bz#1491909 - IP network can not recover after several vhost-user reconnect
+Patch291: kvm-virtio-Add-queue-interface-to-restore-avail-index-fr.patch
+# For bz#1491909 - IP network can not recover after several vhost-user reconnect
+Patch292: kvm-vhost-restore-avail-index-from-vring-used-index-on-d.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch293: kvm-dump-guest-memory.py-fix-No-symbol-vmcoreinfo_find.patch
+# For bz#1396119 - [IBM 7.5 Feature] POWER9 - Virt: QEMU: POWER8/P8-Compat mode for POWER8 Guests on POWER9 platform
+Patch294: kvm-ppc-fix-setting-of-compat-mode.patch
+# For bz#1506856 - [abrt] qemu-kvm-rhev: object_get_class(): qemu-kvm killed by SIGSEGV
+Patch295: kvm-pc-fix-crash-on-attempted-cpu-unplug.patch
+# For bz#1506218 - seg at exit - due to missing fd?
+Patch296: kvm-sockets-avoid-crash-when-cleaning-up-sockets-for-an-.patch
+# For bz#1523235 - Pegas1.0 - qemu cpu information is not up-to-date (qemu-kvm)
+Patch297: kvm-target-ppc-Add-POWER9-DD2.0-model-information.patch
+# For bz#1505654 - Missing libvxhs share-able object  file when try to query vxhs protocol
+Patch298: kvm-block-vxhs-improve-error-message-for-missing-bad-vxh.patch
+# For bz#1451269 - Clarify the relativity of backing file and created image in "qemu-img create"
+Patch299: kvm-qemu-img-Clarify-about-relative-backing-file-options.patch
+# For bz#1518529 - CVE-2017-15119 qemu-kvm-rhev: qemu: DoS via large option request [rhel-7.5]
+# For bz#1518551 - CVE-2017-15119 qemu-kvm-ma: qemu: DoS via large option request [rhel-7.5]
+Patch300: kvm-nbd-server-CVE-2017-15119-Reject-options-larger-than.patch
+# For bz#1516545 - CVE-2017-15118 qemu-kvm-rhev: qemu NBD server vulnerable to stack smash from client requesting long export name [rhel-7.5]
+# For bz#1518548 - CVE-2017-15118 qemu-kvm-ma: Qemu: stack buffer overflow in NBD server triggered via long export name [rhel-7.5]
+Patch301: kvm-nbd-server-CVE-2017-15118-Stack-smash-on-large-expor.patch
+# For bz#1520294 - Hot-unplug the second pf cause qemu promote " Failed to remove group $iommu_group_num from KVM VFIO device:"
+Patch302: kvm-vfio-Fix-vfio-kvm-group-registration.patch
+# For bz#1525866 - P9 to P8 guest migration fails when kernel is not started
+Patch303: kvm-spapr-don-t-initialize-PATB-entry-if-max-cpu-compat-.patch
+# For bz#1520824 - Migration with dataplane, qemu processor hang, vm hang and migration can't finish
+Patch304: kvm-block-avoid-recursive-AioContext-acquire-in-bdrv_ina.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch305: kvm-io-send-proper-HTTP-response-for-websocket-errors.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch306: kvm-io-include-full-error-message-in-websocket-handshake.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch307: kvm-io-use-case-insensitive-check-for-Connection-Upgrade.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch308: kvm-ui-Always-remove-an-old-VNC-channel-watch-before-add.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch309: kvm-io-Small-updates-in-preparation-for-websocket-change.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch310: kvm-io-Add-support-for-fragmented-websocket-binary-frame.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch311: kvm-io-Allow-empty-websocket-payload.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch312: kvm-io-Ignore-websocket-PING-and-PONG-frames.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch313: kvm-io-Reply-to-ping-frames.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch314: kvm-io-Attempt-to-send-websocket-close-messages-to-clien.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch315: kvm-io-add-trace-events-for-websockets-frame-handling.patch
+# For bz#1518650 - CVE-2017-15268 qemu-kvm-rhev: Qemu: I/O: potential memory exhaustion via websock connection to VNC [rhel-7.5]
+Patch316: kvm-io-monitor-encoutput-buffer-size-from-websocket-GSou.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch317: kvm-io-simplify-websocket-ping-reply-handling.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch318: kvm-io-get-rid-of-qio_channel_websock_encode-helper-meth.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch319: kvm-io-pass-a-struct-iovec-into-qio_channel_websock_enco.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch320: kvm-io-get-rid-of-bounce-buffering-in-websock-write-path.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch321: kvm-io-cope-with-websock-Connection-header-having-multip.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch322: kvm-io-add-trace-points-for-websocket-HTTP-protocol-head.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch323: kvm-io-fix-mem-leak-in-websock-error-path.patch
+# For bz#1518649 - Client compatibility flaws in VNC websockets server
+Patch324: kvm-io-Add-missing-GCC_FMT_ATTR-fix-Werror-suggest-attri.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch325: kvm-qemu.py-make-VM-a-context-manager.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch326: kvm-iotests.py-add-FilePath-context-manager.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch327: kvm-qemu-iothread-IOThread-supports-the-GMainContext-eve.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch328: kvm-qom-provide-root-container-for-internal-objs.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch329: kvm-iothread-provide-helpers-for-internal-use.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch330: kvm-iothread-export-iothread_stop.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch331: kvm-iothread-delay-the-context-release-to-finalize.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch332: kvm-aio-fix-assert-when-remove-poll-during-destroy.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch333: kvm-blockdev-hold-AioContext-for-bdrv_unref-in-external_.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch334: kvm-block-don-t-keep-AioContext-acquired-after-external_.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch335: kvm-block-don-t-keep-AioContext-acquired-after-drive_bac.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch336: kvm-block-don-t-keep-AioContext-acquired-after-blockdev_.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch337: kvm-block-don-t-keep-AioContext-acquired-after-internal_.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch338: kvm-iothread-add-iothread_by_id-API.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch339: kvm-blockdev-add-x-blockdev-set-iothread-testing-command.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch340: kvm-qemu-iotests-add-202-external-snapshots-IOThread-tes.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch341: kvm-blockdev-add-x-blockdev-set-iothread-force-boolean.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch342: kvm-iotests-add-VM.add_object.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch343: kvm-iothread-fix-iothread_stop-race-condition.patch
+# For bz#1519721 - Both qemu and guest hang when performing live snapshot transaction with data-plane
+Patch344: kvm-qemu-iotests-add-203-savevm-with-IOThreads-test.patch
+# For bz#CVE-2017-5715 
+Patch345: kvm-target-i386-add-support-for-SPEC_CTRL-MSR.patch
+# For bz#CVE-2017-5715 
+Patch346: kvm-target-i386-cpu-add-new-CPUID-bits-for-indirect-bran.patch
+# For bz#CVE-2017-5715 
+Patch347: kvm-target-i386-cpu-add-new-CPU-models-for-indirect-bran.patch
+# For bz#1513323 - vITS reset
+Patch348: kvm-gicv3-Convert-to-DEFINE_PROP_LINK.patch
+# For bz#1513323 - vITS reset
+Patch349: kvm-hw-intc-arm_gicv3_its-Fix-the-VM-termination-in-vm_c.patch
+# For bz#1513323 - vITS reset
+Patch350: kvm-hw-intc-arm_gicv3_its-Don-t-abort-on-table-save-fail.patch
+# For bz#1513323 - vITS reset
+Patch351: kvm-hw-intc-arm_gicv3_its-Don-t-call-post_load-on-reset.patch
+# For bz#1513323 - vITS reset
+Patch352: kvm-hw-intc-arm_gicv3_its-Implement-a-minimalist-reset.patch
+# For bz#1513323 - vITS reset
+Patch353: kvm-linux-headers-Partial-header-update-against-v4.15-rc.patch
+# For bz#1513323 - vITS reset
+Patch354: kvm-hw-intc-arm_gicv3_its-Implement-full-reset.patch
+# For bz#1525868 - Guest hit core dump with both IO throttling and data plane
+Patch355: kvm-block-throttle-groups.c-allocate-RestartData-on-the-.patch
+# For bz#1529676 - kvm_stat: option '--guest' doesn't work
+Patch356: kvm-tools-kvm_stat-fix-command-line-option-g.patch
+# For bz#1527449 - qemu-kvm-ma: vCPU count should be limited to 240 on all arches
+Patch357: kvm-redhat-globally-limit-the-maximum-number-of-CPUs.patch
+# For bz#1527449 - qemu-kvm-ma: vCPU count should be limited to 240 on all arches
+Patch358: kvm-redhat-remove-manual-max_cpus-limitations-for-ppc.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch359: kvm-dump-guest-memory.py-fix-You-can-t-do-that-without-a.patch
+# For bz#1528173 - Hot-unplug memory  during booting early stage induced qemu-kvm coredump
+Patch360: kvm-hw-ppc-spapr.c-abort-unplug_request-if-previous-unpl.patch
+# For bz#1528234 - Pegas1.1 Alpha: Hotplugged vcpu does not guarantee CPU P8compat mode on POWER9 host (qemu-kvm)
+Patch361: kvm-spapr-Correct-compatibility-mode-setting-for-hotplug.patch
+# For bz#1510809 - qemu-kvm core dumped when booting up guest using both virtio-vga and VGA
+Patch362: kvm-ui-fix-dcl-unregister.patch
+# For bz#1526212 - qemu-img should not need a write lock for creating the overlay image
+Patch363: kvm-block-Open-backing-image-in-force-share-mode-for-siz.patch
+# For bz#1462145 - Qemu crashes when all fw_cfg slots are used
+Patch364: kvm-fw_cfg-fix-memory-corruption-when-all-fw_cfg-slots-a.patch
+# For bz#1515604 - qemu-img info: failed to get "consistent read" lock on a mirroring image
+Patch365: kvm-block-Don-t-use-BLK_PERM_CONSISTENT_READ-for-format-.patch
+# For bz#1515604 - qemu-img info: failed to get "consistent read" lock on a mirroring image
+Patch366: kvm-block-Don-t-request-I-O-permission-with-BDRV_O_NO_IO.patch
+# For bz#1515604 - qemu-img info: failed to get "consistent read" lock on a mirroring image
+Patch367: kvm-block-Formats-don-t-need-CONSISTENT_READ-with-NO_IO.patch
+# For bz#1459945 - migration fails with hungup serial console reader on -M pc-i440fx-rhel7.0.0 and pc-i440fx-rhel7.1.0
+Patch368: kvm-serial-always-transmit-send-receive-buffers-on-migra.patch
+# For bz#1507693 - Unable to hot plug device to VM reporting libvirt errors.
+Patch369: kvm-hw-acpi-Move-acpi_set_pci_info-to-pcihp.patch
+# For bz#1518482 - "share-rw" property is unavailable on scsi passthrough devices
+Patch370: kvm-scsi-block-Add-share-rw-option.patch
+# For bz#1518482 - "share-rw" property is unavailable on scsi passthrough devices
+Patch371: kvm-scsi-generic-Add-share-rw-option.patch
+# For bz#1529461 - On amd hosts, after migration from rhel6.9.z to rhel7.5, CPU utilization of qemu-kvm is always more than 100% on destination rhel7.5 host
+Patch372: kvm-target-i386-sanitize-x86-MSR_PAT-loaded-from-another.patch
+# For bz#1526423 - QEMU hang with data plane enabled after some sg_write_same operations in guest
+Patch373: kvm-scsi-disk-release-AioContext-in-unaligned-WRITE-SAME.patch
+# For bz#1520858 - qemu-kvm core dumped when booting guest with more pcie-root-ports than available slots and io-reserve=0
+Patch374: kvm-hw-pci-bridge-fix-QEMU-crash-because-of-pcie-root-po.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch375: kvm-spapr-Capabilities-infrastructure.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch376: kvm-spapr-Treat-Hardware-Transactional-Memory-HTM-as-an-.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch377: kvm-spapr-Validate-capabilities-on-migration.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch378: kvm-spapr-Handle-VMX-VSX-presence-as-an-spapr-capability.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch379: kvm-spapr-Handle-Decimal-Floating-Point-DFP-as-an-option.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch380: kvm-hw-ppc-spapr_caps-Rework-spapr_caps-to-use-uint8-int.patch
+# For bz#1523414 - [POWER guests] Verify compatible CPU & hypervisor capabilities across migration
+Patch381: kvm-spapr-Remove-unnecessary-options-field-from-sPAPRCap.patch
+# For bz#1529243 - Migration from P9 to P8, migration failed and qemu quit on dst end with "error while loading state for instance 0x0 of device 'ics'"
+Patch382: kvm-ppc-Change-Power9-compat-table-to-support-at-most-8-.patch
+# For bz#1529243 - Migration from P9 to P8, migration failed and qemu quit on dst end with "error while loading state for instance 0x0 of device 'ics'"
+Patch383: kvm-target-ppc-Clarify-compat-mode-max_threads-value.patch
+# For bz#1529243 - Migration from P9 to P8, migration failed and qemu quit on dst end with "error while loading state for instance 0x0 of device 'ics'"
+Patch384: kvm-spapr-Allow-some-cases-where-we-can-t-set-VSMT-mode-.patch
+# For bz#1529243 - Migration from P9 to P8, migration failed and qemu quit on dst end with "error while loading state for instance 0x0 of device 'ics'"
+Patch385: kvm-spapr-Adjust-default-VSMT-value-for-better-migration.patch
+# For bz#1535992 - Set force shared option "-U" as default option for "qemu-img info"
+Patch386: kvm-qemu-img-info-Force-U-downstream.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch387: kvm-dump-guest-memory.py-fix-python-2-support.patch
+# For bz#1535752 - Device tree incorrectly advertises compatibility modes for secondary CPUs
+Patch388: kvm-spapr-fix-device-tree-properties-when-using-compatib.patch
+# For bz#1513870 - For VNC connection, characters '|' and '<' are both recognized as '>' in linux guests, while '<' and '>' are both recognized as '|' in windows guest
+Patch389: kvm-Drop-105th-key-from-en-us-keymap.patch
+# For bz#1535606 - Spectre mitigation patches for qemu-kvm-ma on z Systems
+Patch390: kvm-linux-headers-update.patch
+# For bz#1535606 - Spectre mitigation patches for qemu-kvm-ma on z Systems
+Patch391: kvm-s390x-kvm-Handle-bpb-feature.patch
+# For bz#1535606 - Spectre mitigation patches for qemu-kvm-ma on z Systems
+Patch392: kvm-s390x-kvm-provide-stfle.81.patch
+# For bz#1529053 - Miss the handling of EINTR in the fcntl calls made by QEMU
+Patch393: kvm-osdep-Retry-SETLK-upon-EINTR.patch
+# For bz#1534682 - CVE-2018-5683 qemu-kvm-rhev: Qemu: Out-of-bounds read in vga_draw_text routine [rhel-7.5]
+Patch394: kvm-vga-check-the-validation-of-memory-addr-when-draw-te.patch
+# For bz#1525324 - 2 VMs both with 'share-rw=on' appending on '-device usb-storage' for the same source image can not be started at the same time
+Patch395: kvm-usb-storage-Fix-share-rw-option-parsing.patch
+# For bz#1535952 - qemu-kvm-ma differentiation - memory hotplug
+Patch396: kvm-spapr-disable-memory-hotplug.patch
+# For bz#1505696 - Qemu crashed when open the second display of virtio video
+Patch397: kvm-console-fix-dpy_gfx_replace_surface-assert.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch398: kvm-ui-add-tracing-of-VNC-operations-related-to-QIOChann.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch399: kvm-ui-add-tracing-of-VNC-authentication-process.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch400: kvm-ui-remove-sync-parameter-from-vnc_update_client.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch401: kvm-ui-remove-unreachable-code-in-vnc_update_client.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch402: kvm-ui-remove-redundant-indentation-in-vnc_client_update.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch403: kvm-ui-avoid-pointless-VNC-updates-if-framebuffer-isn-t-.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch404: kvm-ui-track-how-much-decoded-data-we-consumed-when-doin.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch405: kvm-ui-introduce-enum-to-track-VNC-client-framebuffer-up.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch406: kvm-ui-correctly-reset-framebuffer-update-state-after-pr.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch407: kvm-ui-refactor-code-for-determining-if-an-update-should.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch408: kvm-ui-fix-VNC-client-throttling-when-audio-capture-is-a.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch409: kvm-ui-fix-VNC-client-throttling-when-forced-update-is-r.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch410: kvm-ui-place-a-hard-cap-on-VNC-server-output-buffer-size.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch411: kvm-ui-add-trace-events-related-to-VNC-client-throttling.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch412: kvm-ui-mix-misleading-comments-return-types-of-VNC-I-O-h.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch413: kvm-ui-avoid-sign-extension-using-client-width-height.patch
+# For bz#1527404 - CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5]
+Patch414: kvm-ui-correctly-advance-output-buffer-when-writing-SASL.patch
+# For bz#1398633 - [RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev)
+Patch415: kvm-dump-guest-memory.py-skip-vmcoreinfo-section-if-not-.patch
+# For bz#1540182 - QEMU: disallow virtio-gpu to boot with vIOMMU
+Patch416: kvm-virtio-gpu-disallow-vIOMMU.patch
+# For bz#1538494 - Guest crashed on the source host when cancel migration by virDomainMigrateBegin3Params sometimes
+Patch417: kvm-migration-Recover-block-devices-if-failure-in-device.patch
+# For bz#1540003 - Postcopy migration failed with "Unreasonably large packaged state"
+Patch418: kvm-migration-savevm.c-set-MAX_VM_CMD_PACKAGED_SIZE-to-1.patch
+# For bz#1538953 - IOTLB entry size mismatch before/after migration during DPDK PVP testing
+Patch419: kvm-pci-bus-let-it-has-higher-migration-priority.patch
+# For bz#1542421 - Pegas1.1 Snapshot1 [4.14.0-35.el7a.ppc64le] [qemu-kvm-ma-2.10.0-18.el7.ppc64le] qemu-kvm behaves incorrectly for guest boot with invalid threads
+Patch420: kvm-spapr-set-vsmt-to-MAX-8-smp_threads.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch421: kvm-target-ppc-spapr_caps-Add-macro-to-generate-spapr_ca.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch422: kvm-target-ppc-kvm-Add-cap_ppc_safe_-cache-bounds_check-.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch423: kvm-target-ppc-spapr_caps-Add-support-for-tristate-spapr.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch424: kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_cach.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch425: kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_boun.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch426: kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_indi.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch427: kvm-target-ppc-introduce-the-PPC_BIT-macro.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch428: kvm-target-ppc-spapr-Add-H-Call-H_GET_CPU_CHARACTERISTIC.patch
+# For bz#1532050 - [CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5)
+Patch429: kvm-spapr-add-missing-break-in-h_get_cpu_characteristics.patch
+# For bz#1508330 - Interrupt latency issues with vGPU on KVM hypervisor.
+Patch430: kvm-vfio-pci-Add-option-to-disable-GeForce-quirks.patch
+# For bz#1508330 - Interrupt latency issues with vGPU on KVM hypervisor.
+Patch431: kvm-Disable-GeForce-quirks-in-vfio-pci-for-RHEL-machines.patch
+
+BuildRequires: zlib-devel
+BuildRequires: glib2-devel
+BuildRequires: which
+BuildRequires: gnutls-devel
+BuildRequires: cyrus-sasl-devel
+BuildRequires: libtool
+BuildRequires: libaio-devel
+BuildRequires: rsync
+BuildRequires: python
+BuildRequires: pciutils-devel
+BuildRequires: libiscsi-devel
+BuildRequires: ncurses-devel
+BuildRequires: libattr-devel
+BuildRequires: libusbx-devel >= 1.0.19
+%if %{have_usbredir}
+BuildRequires: usbredir-devel >= 0.7.1
+%endif
+BuildRequires: texinfo
+%if %{have_spice}
+BuildRequires: spice-protocol >= 0.12.12
+BuildRequires: spice-server-devel >= 0.12.8
+BuildRequires: libcacard-devel
+# For smartcard NSS support
+BuildRequires: nss-devel
+%endif
+%if %{have_seccomp}
+BuildRequires: libseccomp-devel >= 2.3.0
+%endif
+# For network block driver
+BuildRequires: libcurl-devel
+BuildRequires: libssh2-devel
+%ifarch x86_64
+BuildRequires: librados2-devel
+BuildRequires: librbd1-devel
+%endif
+%if %{have_gluster}
+# For gluster block driver
+BuildRequires: glusterfs-api-devel >= 3.6.0
+BuildRequires: glusterfs-devel
+%endif
+# We need both because the 'stap' binary is probed for by configure
+BuildRequires: systemtap
+BuildRequires: systemtap-sdt-devel
+# For XFS discard support in raw-posix.c
+# For VNC JPEG support
+BuildRequires: libjpeg-devel
+# For VNC PNG support
+BuildRequires: libpng-devel
+# For uuid generation
+BuildRequires: libuuid-devel
+# For BlueZ device support
+BuildRequires: bluez-libs-devel
+# For Braille device support
+BuildRequires: brlapi-devel
+# For test suite
+BuildRequires: check-devel
+# For virtfs
+BuildRequires: libcap-devel
+# Hard requirement for version >= 1.3
+BuildRequires: pixman-devel
+# Documentation requirement
+BuildRequires: perl-podlators
+BuildRequires: texinfo
+# For rdma
+%if 0%{?have_librdma}
+BuildRequires: rdma-core-devel
+%endif
+%if 0%{?have_tcmalloc}
+BuildRequires: gperftools-devel
+%endif
+%if %{have_fdt}
+BuildRequires: libfdt-devel >= 1.4.3
+%endif
+# iasl and cpp for acpi generation (not a hard requirement as we can use
+# pre-compiled files, but it's better to use this)
+%ifarch %{ix86} x86_64
+BuildRequires: iasl
+BuildRequires: cpp
+%endif
+# For compressed guest memory dumps
+BuildRequires: lzo-devel snappy-devel
+# For NUMA memory binding
+%ifnarch s390x
+BuildRequires: numactl-devel
+%endif
+BuildRequires: libgcrypt-devel
+# qemu-pr-helper multipath support (requires libudev too)
+BuildRequires: device-mapper-multipath-devel
+BuildRequires: systemd-devel
+# used by qemu-bridge-helper and qemu-pr-helper
+BuildRequires: libcap-ng-devel
+
+# For kvm-unit-tests
+%ifarch x86_64
+BuildRequires: binutils
+BuildRequires: kernel-devel
+%endif
+
+BuildRequires: diffutils
+
+# For s390-pgste flag
+%ifarch s390x
+BuildRequires: binutils >= 2.27-16
+%endif
+
+Requires: qemu-img%{?pkgsuffix} = %{epoch}:%{version}-%{release}
+
+# RHEV-specific changes:
+# We provide special suffix for qemu-kvm so the conflit is easy
+# In addition, RHEV version should obsolete all RHEL version in case both
+# RHEL and RHEV channels are used
+%rhel_rhev_conflicts qemu-kvm
+
+
+%define qemudocdir %{_docdir}/%{pkgname}
+
+%description
+qemu-kvm%{?pkgsuffix} is an open source virtualizer that provides hardware
+emulation for the KVM hypervisor. qemu-kvm%{?pkgsuffix} acts as a virtual
+machine monitor together with the KVM kernel modules, and emulates the
+hardware for a full system such as a PC and its associated peripherals.
+
+%package -n qemu-img%{?pkgsuffix}
+Summary: QEMU command line tool for manipulating disk images
+Group: Development/Tools
+
+%rhel_rhev_conflicts qemu-img
+
+%description -n qemu-img%{?pkgsuffix}
+This package provides a command line tool for manipulating disk images.
+
+%package -n qemu-kvm-common%{?pkgsuffix}
+Summary: QEMU common files needed by all QEMU targets
+Group: Development/Tools
+Requires(post): /usr/bin/getent
+Requires(post): /usr/sbin/groupadd
+Requires(post): /usr/sbin/useradd
+Requires(post): systemd-units
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+
+%rhel_rhev_conflicts qemu-kvm-common
+
+%description -n qemu-kvm-common%{?pkgsuffix}
+qemu-kvm is an open source virtualizer that provides hardware emulation for
+the KVM hypervisor.
+
+This package provides documentation and auxiliary programs used with qemu-kvm.
+
+%package -n qemu-kvm-tools%{?pkgsuffix}
+Summary: KVM debugging and diagnostics tools
+Group: Development/Tools
+
+%rhel_rhev_conflicts qemu-kvm-tools
+
+%description -n qemu-kvm-tools%{?pkgsuffix}
+This package contains some diagnostics and debugging tools for KVM, such as kvm_stat.
+
+%prep
+%setup -q -n qemu-%{version}
+
+# Copy bios files to allow 'make check' pass
+cp %{SOURCE14} pc-bios
+cp %{SOURCE15} pc-bios
+cp %{SOURCE16} pc-bios
+cp %{SOURCE17} pc-bios
+cp %{SOURCE18} pc-bios
+cp %{SOURCE20} pc-bios
+cp %{SOURCE29} pc-bios
+
+# if patch fuzzy patch applying will be forbidden
+%define with_fuzzy_patches 0
+%if %{with_fuzzy_patches}
+    patch_command='patch -p1 -s'
+%else
+    patch_command='patch -p1 -F1 -s'
+%endif
+
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
+%patch40 -p1
+%patch41 -p1
+%patch42 -p1
+%patch43 -p1
+%patch44 -p1
+%patch45 -p1
+%patch46 -p1
+%patch47 -p1
+%patch48 -p1
+%patch49 -p1
+%patch50 -p1
+%patch51 -p1
+%patch52 -p1
+%patch53 -p1
+%patch54 -p1
+%patch55 -p1
+%patch56 -p1
+%patch57 -p1
+%patch58 -p1
+%patch59 -p1
+%patch60 -p1
+%patch61 -p1
+%patch62 -p1
+%patch63 -p1
+%patch64 -p1
+%patch65 -p1
+%patch66 -p1
+%patch67 -p1
+%patch68 -p1
+%patch69 -p1
+%patch70 -p1
+%patch71 -p1
+%patch72 -p1
+%patch73 -p1
+%patch74 -p1
+%patch75 -p1
+%patch76 -p1
+%patch77 -p1
+%patch78 -p1
+%patch79 -p1
+%patch80 -p1
+%patch81 -p1
+%patch82 -p1
+%patch83 -p1
+%patch84 -p1
+%patch85 -p1
+%patch86 -p1
+%patch87 -p1
+%patch88 -p1
+%patch90 -p1
+%patch91 -p1
+%patch92 -p1
+%patch93 -p1
+%patch94 -p1
+%patch95 -p1
+%patch96 -p1
+%patch97 -p1
+%patch98 -p1
+%patch99 -p1
+%patch100 -p1
+%patch101 -p1
+%patch102 -p1
+%patch103 -p1
+%patch104 -p1
+%patch105 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+%patch118 -p1
+%patch119 -p1
+%patch120 -p1
+%patch121 -p1
+%patch122 -p1
+%patch123 -p1
+%patch124 -p1
+%patch125 -p1
+%patch126 -p1
+%patch127 -p1
+%patch128 -p1
+%patch129 -p1
+%patch130 -p1
+%patch131 -p1
+%patch132 -p1
+%patch133 -p1
+%patch134 -p1
+%patch135 -p1
+%patch136 -p1
+%patch137 -p1
+%patch138 -p1
+%patch139 -p1
+%patch140 -p1
+%patch141 -p1
+%patch142 -p1
+%patch143 -p1
+%patch144 -p1
+%patch145 -p1
+%patch146 -p1
+%patch147 -p1
+%patch148 -p1
+%patch149 -p1
+%patch150 -p1
+%patch151 -p1
+%patch152 -p1
+%patch153 -p1
+%patch154 -p1
+%patch155 -p1
+%patch156 -p1
+%patch157 -p1
+%patch158 -p1
+%patch159 -p1
+%patch160 -p1
+%patch161 -p1
+%patch162 -p1
+%patch163 -p1
+%patch164 -p1
+%patch165 -p1
+%patch166 -p1
+%patch167 -p1
+%patch168 -p1
+%patch169 -p1
+%patch170 -p1
+%patch171 -p1
+%patch172 -p1
+%patch173 -p1
+%patch174 -p1
+%patch175 -p1
+%patch176 -p1
+%patch177 -p1
+%patch178 -p1
+%patch179 -p1
+%patch180 -p1
+%patch181 -p1
+%patch182 -p1
+%patch183 -p1
+%patch184 -p1
+%patch185 -p1
+%patch186 -p1
+%patch187 -p1
+%patch188 -p1
+%patch189 -p1
+%patch190 -p1
+%patch191 -p1
+%patch192 -p1
+%patch193 -p1
+%patch194 -p1
+%patch195 -p1
+%patch196 -p1
+%patch197 -p1
+%patch198 -p1
+%patch199 -p1
+%patch200 -p1
+%patch201 -p1
+%patch202 -p1
+%patch203 -p1
+%patch204 -p1
+%patch205 -p1
+%patch206 -p1
+%patch207 -p1
+%patch208 -p1
+%patch209 -p1
+%patch210 -p1
+%patch211 -p1
+%patch212 -p1
+%patch213 -p1
+%patch214 -p1
+%patch215 -p1
+%patch216 -p1
+%patch217 -p1
+%patch218 -p1
+%patch219 -p1
+%patch220 -p1
+%patch221 -p1
+%patch222 -p1
+%patch223 -p1
+%patch224 -p1
+%patch225 -p1
+%patch226 -p1
+%patch227 -p1
+%patch228 -p1
+%patch229 -p1
+%patch230 -p1
+%patch231 -p1
+%patch232 -p1
+%patch233 -p1
+%patch234 -p1
+%patch235 -p1
+%patch236 -p1
+%patch237 -p1
+%patch238 -p1
+%patch239 -p1
+%patch240 -p1
+%patch241 -p1
+%patch242 -p1
+%patch243 -p1
+%patch244 -p1
+%patch245 -p1
+%patch246 -p1
+%patch247 -p1
+%patch248 -p1
+%patch249 -p1
+%patch250 -p1
+%patch251 -p1
+%patch252 -p1
+%patch253 -p1
+%patch254 -p1
+%patch255 -p1
+%patch256 -p1
+%patch257 -p1
+%patch258 -p1
+%patch259 -p1
+%patch260 -p1
+%patch261 -p1
+%patch262 -p1
+%patch263 -p1
+%patch264 -p1
+%patch265 -p1
+%patch266 -p1
+%patch267 -p1
+%patch268 -p1
+%patch269 -p1
+%patch270 -p1
+%patch271 -p1
+%patch272 -p1
+%patch273 -p1
+%patch274 -p1
+%patch275 -p1
+%patch276 -p1
+%patch277 -p1
+%patch278 -p1
+%patch279 -p1
+%patch280 -p1
+%patch281 -p1
+%patch282 -p1
+%patch283 -p1
+%patch284 -p1
+%patch285 -p1
+%patch286 -p1
+%patch287 -p1
+%patch288 -p1
+%patch289 -p1
+%patch290 -p1
+%patch291 -p1
+%patch292 -p1
+%patch293 -p1
+%patch294 -p1
+%patch295 -p1
+%patch296 -p1
+%patch297 -p1
+%patch298 -p1
+%patch299 -p1
+%patch300 -p1
+%patch301 -p1
+%patch302 -p1
+%patch303 -p1
+%patch304 -p1
+%patch305 -p1
+%patch306 -p1
+%patch307 -p1
+%patch308 -p1
+%patch309 -p1
+%patch310 -p1
+%patch311 -p1
+%patch312 -p1
+%patch313 -p1
+%patch314 -p1
+%patch315 -p1
+%patch316 -p1
+%patch317 -p1
+%patch318 -p1
+%patch319 -p1
+%patch320 -p1
+%patch321 -p1
+%patch322 -p1
+%patch323 -p1
+%patch324 -p1
+%patch325 -p1
+%patch326 -p1
+%patch327 -p1
+%patch328 -p1
+%patch329 -p1
+%patch330 -p1
+%patch331 -p1
+%patch332 -p1
+%patch333 -p1
+%patch334 -p1
+%patch335 -p1
+%patch336 -p1
+%patch337 -p1
+%patch338 -p1
+%patch339 -p1
+%patch340 -p1
+%patch341 -p1
+%patch342 -p1
+%patch343 -p1
+%patch344 -p1
+%patch345 -p1
+%patch346 -p1
+%patch347 -p1
+%patch348 -p1
+%patch349 -p1
+%patch350 -p1
+%patch351 -p1
+%patch352 -p1
+%patch353 -p1
+%patch354 -p1
+%patch355 -p1
+%patch356 -p1
+%patch357 -p1
+%patch358 -p1
+%patch359 -p1
+%patch360 -p1
+%patch361 -p1
+%patch362 -p1
+%patch363 -p1
+%patch364 -p1
+%patch365 -p1
+%patch366 -p1
+%patch367 -p1
+%patch368 -p1
+%patch369 -p1
+%patch370 -p1
+%patch371 -p1
+%patch372 -p1
+%patch373 -p1
+%patch374 -p1
+%patch375 -p1
+%patch376 -p1
+%patch377 -p1
+%patch378 -p1
+%patch379 -p1
+%patch380 -p1
+%patch381 -p1
+%patch382 -p1
+%patch383 -p1
+%patch384 -p1
+%patch385 -p1
+%patch386 -p1
+%patch387 -p1
+%patch388 -p1
+%patch389 -p1
+%patch390 -p1
+%patch391 -p1
+%patch392 -p1
+%patch393 -p1
+%patch394 -p1
+%patch395 -p1
+%patch396 -p1
+%patch397 -p1
+%patch398 -p1
+%patch399 -p1
+%patch400 -p1
+%patch401 -p1
+%patch402 -p1
+%patch403 -p1
+%patch404 -p1
+%patch405 -p1
+%patch406 -p1
+%patch407 -p1
+%patch408 -p1
+%patch409 -p1
+%patch410 -p1
+%patch411 -p1
+%patch412 -p1
+%patch413 -p1
+%patch414 -p1
+%patch415 -p1
+%patch416 -p1
+%patch417 -p1
+%patch418 -p1
+%patch419 -p1
+%patch420 -p1
+%patch421 -p1
+%patch422 -p1
+%patch423 -p1
+%patch424 -p1
+%patch425 -p1
+%patch426 -p1
+%patch427 -p1
+%patch428 -p1
+%patch429 -p1
+%patch430 -p1
+%patch431 -p1
+
+# for tscdeadline_latency.flat
+%ifarch x86_64
+  tar -xf %{SOURCE25}
+%endif
+
+%build
+buildarch="%{kvm_target}-softmmu"
+
+# --build-id option is used for giving info to the debug packages.
+extraldflags="-Wl,--build-id";
+buildldflags="VL_LDFLAGS=-Wl,--build-id"
+
+# QEMU already knows how to set _FORTIFY_SOURCE
+%global optflags %(echo %{optflags} | sed 's/-Wp,-D_FORTIFY_SOURCE=2//')
+
+%ifarch s390
+    # drop -g flag to prevent memory exhaustion by linker
+    %global optflags %(echo %{optflags} | sed 's/-g//')
+    sed -i.debug 's/"-g $CFLAGS"/"$CFLAGS"/g' configure
+%endif
+
+cp %{SOURCE24} build_configure.sh
+
+./build_configure.sh  \
+  "%{_prefix}" \
+  "%{_libdir}" \
+  "%{_sysconfdir}" \
+  "%{_localstatedir}" \
+  "%{_libexecdir}" \
+  "%{qemudocdir}" \
+  "%{pkgname}" \
+  "%{kvm_target}" \
+  "%{name}-%{version}-%{release}" \
+  "%{optflags}" \
+%if 0%{have_fdt}
+  enable \
+%else
+  disable \
+ %endif
+%if 0%{have_gluster}
+  enable \
+%else
+  disable \
+%endif
+  disable \
+%ifnarch s390x
+  enable \
+%else
+  disable \
+%endif
+%ifarch x86_64
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_librdma}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_seccomp}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_spice}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_usbredir}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_tcmalloc}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_vxhs}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_vtd}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_live_block_ops}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{have_vhost_user}
+  enable \
+%else
+  disable \
+%endif
+%if 0%{rhev}
+  enable \
+%else
+  disable \
+%endif
+  --target-list="$buildarch"
+
+echo "config-host.mak contents:"
+echo "==="
+cat config-host.mak
+echo "==="
+
+make V=1 %{?_smp_mflags} $buildldflags
+
+# Setup back compat qemu-kvm binary
+./scripts/tracetool.py --backend dtrace --format stap --group=all \
+  --binary %{_libexecdir}/qemu-kvm --target-name %{kvm_target} \
+  --target-type system --probe-prefix \
+  qemu.kvm trace-events-all > qemu-kvm.stp
+
+./scripts/tracetool.py --backend dtrace --format simpletrace-stap \
+  --group=all --binary %{_libexecdir}/qemu-kvm --target-name %{kvm_target} \
+  --target-type system --probe-prefix \
+  qemu.kvm trace-events-all > qemu-kvm-simpletrace.stp
+
+cp -a %{kvm_target}-softmmu/qemu-system-%{kvm_target} qemu-kvm
+
+gcc %{SOURCE6} -O2 -g -o ksmctl
+
+# build tscdeadline_latency.flat
+%ifarch x86_64
+  (cd  kvm-unit-tests && ./configure)
+  make -C kvm-unit-tests
+%endif
+
+%install
+%define _udevdir %(pkg-config --variable=udevdir udev)/rules.d
+
+install -D -p -m 0644 %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/ksm.service
+install -D -p -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ksm
+install -D -p -m 0755 ksmctl $RPM_BUILD_ROOT%{_libexecdir}/ksmctl
+
+install -D -p -m 0644 %{SOURCE7} $RPM_BUILD_ROOT%{_unitdir}/ksmtuned.service
+install -D -p -m 0755 %{SOURCE8} $RPM_BUILD_ROOT%{_sbindir}/ksmtuned
+install -D -p -m 0644 %{SOURCE9} $RPM_BUILD_ROOT%{_sysconfdir}/ksmtuned.conf
+install -D -p -m 0644 %{SOURCE26} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/vhost.conf
+%ifarch s390x s390
+    install -D -p -m 0644 %{SOURCE30} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/kvm.conf
+%else
+%ifarch %{ix86} x86_64
+    install -D -p -m 0644 %{SOURCE31} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/kvm.conf
+%else
+    install -D -p -m 0644 %{SOURCE27} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/kvm.conf
+%endif
+%endif
+
+mkdir -p $RPM_BUILD_ROOT%{_bindir}/
+mkdir -p $RPM_BUILD_ROOT%{_udevdir}
+
+install -m 0755 scripts/kvm/kvm_stat $RPM_BUILD_ROOT%{_bindir}/
+mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man1/
+install -m 0644 kvm_stat.1 ${RPM_BUILD_ROOT}%{_mandir}/man1/
+install -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_udevdir}
+
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}
+install -m 0644 scripts/dump-guest-memory.py \
+                $RPM_BUILD_ROOT%{_datadir}/%{pkgname}
+%ifarch x86_64
+    install -m 0644 kvm-unit-tests/x86/tscdeadline_latency.flat \
+                    $RPM_BUILD_ROOT%{_datadir}/%{pkgname}
+%endif
+
+make DESTDIR=$RPM_BUILD_ROOT \
+    sharedir="%{_datadir}/%{pkgname}" \
+    datadir="%{_datadir}/%{pkgname}" \
+    install
+
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset
+
+# Install compatibility roms
+install %{SOURCE14} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/
+install %{SOURCE15} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/
+install %{SOURCE16} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/
+install %{SOURCE17} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/
+install %{SOURCE20} $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/
+
+install -m 0755 qemu-kvm $RPM_BUILD_ROOT%{_libexecdir}/
+install -m 0644 qemu-kvm.stp $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/
+install -m 0644 qemu-kvm-simpletrace.stp $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/
+
+rm $RPM_BUILD_ROOT%{_bindir}/qemu-system-%{kvm_target}
+rm $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/qemu-system-%{kvm_target}.stp
+rm $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/qemu-system-%{kvm_target}-simpletrace.stp
+
+# Install simpletrace
+install -m 0755 scripts/simpletrace.py $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/simpletrace.py
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool
+install -m 0644 -t $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool scripts/tracetool/*.py
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/backend
+install -m 0644 -t $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/backend scripts/tracetool/backend/*.py
+mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/format
+install -m 0644 -t $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/tracetool/format scripts/tracetool/format/*.py
+
+mkdir -p $RPM_BUILD_ROOT%{qemudocdir}
+install -p -m 0644 -t ${RPM_BUILD_ROOT}%{qemudocdir} Changelog README README.systemtap COPYING COPYING.LIB LICENSE %{SOURCE19} docs/interop/qmp-spec.txt 
+chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man1/*
+chmod -x ${RPM_BUILD_ROOT}%{_mandir}/man8/*
+
+install -D -p -m 0644 qemu.sasl $RPM_BUILD_ROOT%{_sysconfdir}/sasl2/%{pkgname}.conf
+
+# Provided by package openbios
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/openbios-ppc
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/openbios-sparc32
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/openbios-sparc64
+# Provided by package SLOF
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/slof.bin
+
+# Remove unpackaged files.
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/palcode-clipper
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/petalogix*.dtb
+rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/bamboo.dtb
+rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/ppc_rom.bin
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/s390-zipl.rom
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/u-boot.e500
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/qemu_vga.ndrv
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/skiboot.lid
+
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/s390-ccw.img
+%ifarch s390x
+    # Use the s390-ccw.img that we've just built, not the pre-built one
+    install -m 0644 pc-bios/s390-ccw/s390-ccw.img $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/
+%else
+    rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/s390-netboot.img
+%endif
+
+%ifnarch %{power64}
+    rm -f ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/spapr-rtas.bin
+%endif
+
+%ifnarch x86_64
+    rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/acpi-dsdt.aml
+    rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/kvmvapic.bin
+    rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/linuxboot.bin
+    rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/multiboot.bin
+%endif
+
+# Remove sparc files
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/QEMU,tcx.bin
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/QEMU,cgthree.bin
+
+# Remove ivshmem example programs
+rm -rf ${RPM_BUILD_ROOT}%{_bindir}/ivshmem-client
+rm -rf ${RPM_BUILD_ROOT}%{_bindir}/ivshmem-server
+
+# Remove efi roms
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/efi*.rom
+
+# Provided by package ipxe
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/pxe*rom
+# Provided by package vgabios
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/vgabios*bin
+# Provided by package seabios
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/bios*.bin
+# Provided by package sgabios
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{pkgname}/sgabios.bin
+
+# the pxe gpxe images will be symlinks to the images on
+# /usr/share/ipxe, as QEMU doesn't know how to look
+# for other paths, yet.
+pxe_link() {
+    ln -s ../ipxe/$2.rom %{buildroot}%{_datadir}/%{pkgname}/pxe-$1.rom
+}
+
+%ifnarch aarch64 s390x
+pxe_link e1000 8086100e
+pxe_link ne2k_pci 10ec8029
+pxe_link pcnet 10222000
+pxe_link rtl8139 10ec8139
+pxe_link virtio 1af41000
+pxe_link e1000e 808610d3
+%endif
+
+rom_link() {
+    ln -s $1 %{buildroot}%{_datadir}/%{pkgname}/$2
+}
+
+%ifnarch aarch64 s390x
+  rom_link ../seavgabios/vgabios-isavga.bin vgabios.bin
+  rom_link ../seavgabios/vgabios-cirrus.bin vgabios-cirrus.bin
+  rom_link ../seavgabios/vgabios-qxl.bin vgabios-qxl.bin
+  rom_link ../seavgabios/vgabios-stdvga.bin vgabios-stdvga.bin
+  rom_link ../seavgabios/vgabios-vmware.bin vgabios-vmware.bin
+  rom_link ../seavgabios/vgabios-virtio.bin vgabios-virtio.bin
+%endif
+%ifarch x86_64
+  rom_link ../seabios/bios.bin bios.bin
+  rom_link ../seabios/bios-256k.bin bios-256k.bin
+  rom_link ../sgabios/sgabios.bin sgabios.bin
+%endif
+
+%if 0%{have_kvm_setup}
+    install -D -p -m 755 %{SOURCE21} $RPM_BUILD_ROOT%{_prefix}/lib/systemd/kvm-setup
+	install -D -p -m 644 %{SOURCE22} $RPM_BUILD_ROOT%{_unitdir}/kvm-setup.service
+	install -D -p -m 644 %{SOURCE23} $RPM_BUILD_ROOT%{_presetdir}/85-kvm.preset
+%endif
+
+%if 0%{have_memlock_limits}
+    install -D -p -m 644 %{SOURCE28} $RPM_BUILD_ROOT%{_sysconfdir}/security/limits.d/95-kvm-memlock.conf
+%endif
+
+# Install rules to use the bridge helper with libvirt's virbr0
+install -D -m 0644 %{SOURCE12} $RPM_BUILD_ROOT%{_sysconfdir}/%{pkgname}/bridge.conf
+
+# Install qemu-pr-helper service
+install -m 0644 %{_sourcedir}/qemu-pr-helper.service %{buildroot}%{_unitdir}
+install -m 0644 %{_sourcedir}/qemu-pr-helper.socket %{buildroot}%{_unitdir}
+
+%if 0
+make %{?_smp_mflags} $buildldflags DESTDIR=$RPM_BUILD_ROOT install-libcacard
+
+find $RPM_BUILD_ROOT -name "libcacard.so*" -exec chmod +x \{\} \;
+%endif
+
+find $RPM_BUILD_ROOT -name '*.la' -or -name '*.a' | xargs rm -f
+
+%check
+export DIFF=diff; make check V=1
+
+%post
+# load kvm modules now, so we can make sure no reboot is needed.
+# If there's already a kvm module installed, we don't mess with it
+%udev_rules_update
+sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || :
+    udevadm trigger --subsystem-match=misc --sysname-match=kvm --action=add || :
+%if %{have_kvm_setup}
+    systemctl daemon-reload # Make sure it sees the new presets and unitfile
+    %systemd_post kvm-setup.service
+    if systemctl is-enabled kvm-setup.service > /dev/null; then
+        systemctl start kvm-setup.service
+    fi
+%endif
+
+%post -n qemu-kvm-common%{?pkgsuffix}
+%systemd_post ksm.service
+%systemd_post ksmtuned.service
+
+getent group kvm >/dev/null || groupadd -g 36 -r kvm
+getent group qemu >/dev/null || groupadd -g 107 -r qemu
+getent passwd qemu >/dev/null || \
+useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
+  -c "qemu user" qemu
+
+%preun -n qemu-kvm-common%{?pkgsuffix}
+%systemd_preun ksm.service
+%systemd_preun ksmtuned.service
+
+%postun -n qemu-kvm-common%{?pkgsuffix}
+%systemd_postun_with_restart ksm.service
+%systemd_postun_with_restart ksmtuned.service
+
+%global kvm_files \
+%{_udevdir}/80-kvm.rules
+
+%global qemu_kvm_files \
+%{_libexecdir}/qemu-kvm \
+%{_datadir}/systemtap/tapset/qemu-kvm.stp \
+%{_datadir}/%{pkgname}/trace-events-all \
+%{_datadir}/systemtap/tapset/qemu-kvm-simpletrace.stp \
+%{_datadir}/%{pkgname}/systemtap/script.d/qemu_kvm.stp \
+%{_datadir}/%{pkgname}/systemtap/conf.d/qemu_kvm.conf
+
+%files -n qemu-kvm-common%{?pkgsuffix}
+%defattr(-,root,root)
+%dir %{qemudocdir}
+%doc %{qemudocdir}/Changelog
+%doc %{qemudocdir}/README
+%doc %{qemudocdir}/qemu-doc.html
+%doc %{qemudocdir}/COPYING
+%doc %{qemudocdir}/COPYING.LIB
+%doc %{qemudocdir}/LICENSE
+%doc %{qemudocdir}/README.rhel6-gpxe-source
+%doc %{qemudocdir}/README.systemtap
+%doc %{qemudocdir}/qmp-spec.txt
+%doc %{qemudocdir}/qemu-doc.txt
+%doc %{qemudocdir}/qemu-qmp-ref.html
+%doc %{qemudocdir}/qemu-qmp-ref.txt
+%{_mandir}/man7/qemu-qmp-ref.7*
+%{_bindir}/qemu-pr-helper
+%{_unitdir}/qemu-pr-helper.service
+%{_unitdir}/qemu-pr-helper.socket
+
+%dir %{_datadir}/%{pkgname}/
+%{_datadir}/%{pkgname}/keymaps/
+%{_mandir}/man1/%{pkgname}.1*
+%{_mandir}/man7/qemu-block-drivers.7*
+%attr(4755, -, -) %{_libexecdir}/qemu-bridge-helper
+%config(noreplace) %{_sysconfdir}/sasl2/%{pkgname}.conf
+%{_unitdir}/ksm.service
+%{_libexecdir}/ksmctl
+%config(noreplace) %{_sysconfdir}/sysconfig/ksm
+%{_unitdir}/ksmtuned.service
+%{_sbindir}/ksmtuned
+%config(noreplace) %{_sysconfdir}/ksmtuned.conf
+%dir %{_sysconfdir}/%{pkgname}
+%config(noreplace) %{_sysconfdir}/%{pkgname}/bridge.conf
+%config(noreplace) %{_sysconfdir}/modprobe.d/vhost.conf
+%config(noreplace) %{_sysconfdir}/modprobe.d/kvm.conf
+%{_datadir}/%{pkgname}/simpletrace.py*
+%{_datadir}/%{pkgname}/tracetool/*.py*
+%{_datadir}/%{pkgname}/tracetool/backend/*.py*
+%{_datadir}/%{pkgname}/tracetool/format/*.py*
+
+%files
+%defattr(-,root,root)
+%ifarch x86_64
+    %{_datadir}/%{pkgname}/acpi-dsdt.aml
+    %{_datadir}/%{pkgname}/bios.bin
+    %{_datadir}/%{pkgname}/bios-256k.bin
+    %{_datadir}/%{pkgname}/linuxboot.bin
+    %{_datadir}/%{pkgname}/multiboot.bin
+    %{_datadir}/%{pkgname}/kvmvapic.bin
+    %{_datadir}/%{pkgname}/sgabios.bin
+%endif
+%ifarch s390x
+    %{_datadir}/%{pkgname}/s390-ccw.img
+    %{_datadir}/%{pkgname}/s390-netboot.img
+%endif
+%ifnarch aarch64 s390x
+    %{_datadir}/%{pkgname}/vgabios.bin
+    %{_datadir}/%{pkgname}/vgabios-cirrus.bin
+    %{_datadir}/%{pkgname}/vgabios-qxl.bin
+    %{_datadir}/%{pkgname}/vgabios-stdvga.bin
+    %{_datadir}/%{pkgname}/vgabios-vmware.bin
+    %{_datadir}/%{pkgname}/vgabios-virtio.bin
+    %{_datadir}/%{pkgname}/pxe-e1000.rom
+    %{_datadir}/%{pkgname}/pxe-e1000e.rom
+    %{_datadir}/%{pkgname}/pxe-virtio.rom
+    %{_datadir}/%{pkgname}/pxe-pcnet.rom
+    %{_datadir}/%{pkgname}/pxe-rtl8139.rom
+    %{_datadir}/%{pkgname}/pxe-ne2k_pci.rom
+%endif
+%{_datadir}/%{pkgname}/qemu-icon.bmp
+%{_datadir}/%{pkgname}/qemu_logo_no_text.svg
+%{_datadir}/%{pkgname}/rhel6-virtio.rom
+%{_datadir}/%{pkgname}/rhel6-pcnet.rom
+%{_datadir}/%{pkgname}/rhel6-rtl8139.rom
+%{_datadir}/%{pkgname}/rhel6-ne2k_pci.rom
+%{_datadir}/%{pkgname}/rhel6-e1000.rom
+%{_datadir}/%{pkgname}/linuxboot_dma.bin
+%{_datadir}/%{pkgname}/dump-guest-memory.py*
+%ifarch %{power64}
+    %{_datadir}/%{pkgname}/spapr-rtas.bin
+%endif
+%{?kvm_files:}
+%{?qemu_kvm_files:}
+%if 0%{have_kvm_setup}
+    %{_prefix}/lib/systemd/kvm-setup
+    %{_unitdir}/kvm-setup.service
+    %{_presetdir}/85-kvm.preset
+%endif
+%if 0%{have_memlock_limits}
+    %{_sysconfdir}/security/limits.d/95-kvm-memlock.conf
+%endif
+
+%files -n qemu-kvm-tools%{?pkgsuffix}
+%defattr(-,root,root,-)
+%{_bindir}/kvm_stat
+%{_mandir}/man1/kvm_stat.1*
+%ifarch x86_64
+%{_datadir}/%{pkgname}/tscdeadline_latency.flat
+%endif
+
+%files -n qemu-img%{?pkgsuffix}
+%defattr(-,root,root)
+%{_bindir}/qemu-img
+%{_bindir}/qemu-io
+%{_bindir}/qemu-nbd
+%{_mandir}/man1/qemu-img.1*
+%{_mandir}/man8/qemu-nbd.8*
+
+%if 0
+%files -n libcacard%{?pkgsuffix}
+%defattr(-,root,root,-)
+%{_libdir}/libcacard.so.*
+
+%files -n libcacard-tools%{?pkgsuffix}
+%defattr(-,root,root,-)
+%{_bindir}/vscclient
+
+%files -n libcacard-devel%{?pkgsuffix}
+%defattr(-,root,root,-)
+%{_includedir}/cacard
+%{_libdir}/libcacard.so
+%{_libdir}/pkgconfig/libcacard.pc
+%endif
+
+%changelog
+* Tue Feb 20 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-21.el7
+- kvm-migration-Recover-block-devices-if-failure-in-device.patch [bz#1538494]
+- kvm-migration-savevm.c-set-MAX_VM_CMD_PACKAGED_SIZE-to-1.patch [bz#1540003]
+- kvm-pci-bus-let-it-has-higher-migration-priority.patch [bz#1538953]
+- kvm-spapr-set-vsmt-to-MAX-8-smp_threads.patch [bz#1542421]
+- kvm-target-ppc-spapr_caps-Add-macro-to-generate-spapr_ca.patch [bz#1532050]
+- kvm-target-ppc-kvm-Add-cap_ppc_safe_-cache-bounds_check-.patch [bz#1532050]
+- kvm-target-ppc-spapr_caps-Add-support-for-tristate-spapr.patch [bz#1532050]
+- kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_cach.patch [bz#1532050]
+- kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_boun.patch [bz#1532050]
+- kvm-target-ppc-spapr_caps-Add-new-tristate-cap-safe_indi.patch [bz#1532050]
+- kvm-target-ppc-introduce-the-PPC_BIT-macro.patch [bz#1532050]
+- kvm-target-ppc-spapr-Add-H-Call-H_GET_CPU_CHARACTERISTIC.patch [bz#1532050]
+- kvm-spapr-add-missing-break-in-h_get_cpu_characteristics.patch [bz#1532050]
+- kvm-vfio-pci-Add-option-to-disable-GeForce-quirks.patch [bz#1508330]
+- kvm-Disable-GeForce-quirks-in-vfio-pci-for-RHEL-machines.patch [bz#1508330]
+- Resolves: bz#1508330
+  (Interrupt latency issues with vGPU on KVM hypervisor.)
+- Resolves: bz#1532050
+  ([CVE-2017-5754] Variant3: POWER {qemu-kvm-rhev} (rhel 7.5))
+- Resolves: bz#1538494
+  (Guest crashed on the source host when cancel migration by virDomainMigrateBegin3Params sometimes)
+- Resolves: bz#1538953
+  (IOTLB entry size mismatch before/after migration during DPDK PVP testing)
+- Resolves: bz#1540003
+  (Postcopy migration failed with "Unreasonably large packaged state")
+- Resolves: bz#1542421
+  (Pegas1.1 Snapshot1 [4.14.0-35.el7a.ppc64le] [qemu-kvm-ma-2.10.0-18.el7.ppc64le] qemu-kvm behaves incorrectly for guest boot with invalid threads)
+
+* Wed Feb 07 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-20.el7
+- kvm-console-fix-dpy_gfx_replace_surface-assert.patch [bz#1505696]
+- kvm-ui-add-tracing-of-VNC-operations-related-to-QIOChann.patch [bz#1527404]
+- kvm-ui-add-tracing-of-VNC-authentication-process.patch [bz#1527404]
+- kvm-ui-remove-sync-parameter-from-vnc_update_client.patch [bz#1527404]
+- kvm-ui-remove-unreachable-code-in-vnc_update_client.patch [bz#1527404]
+- kvm-ui-remove-redundant-indentation-in-vnc_client_update.patch [bz#1527404]
+- kvm-ui-avoid-pointless-VNC-updates-if-framebuffer-isn-t-.patch [bz#1527404]
+- kvm-ui-track-how-much-decoded-data-we-consumed-when-doin.patch [bz#1527404]
+- kvm-ui-introduce-enum-to-track-VNC-client-framebuffer-up.patch [bz#1527404]
+- kvm-ui-correctly-reset-framebuffer-update-state-after-pr.patch [bz#1527404]
+- kvm-ui-refactor-code-for-determining-if-an-update-should.patch [bz#1527404]
+- kvm-ui-fix-VNC-client-throttling-when-audio-capture-is-a.patch [bz#1527404]
+- kvm-ui-fix-VNC-client-throttling-when-forced-update-is-r.patch [bz#1527404]
+- kvm-ui-place-a-hard-cap-on-VNC-server-output-buffer-size.patch [bz#1527404]
+- kvm-ui-add-trace-events-related-to-VNC-client-throttling.patch [bz#1527404]
+- kvm-ui-mix-misleading-comments-return-types-of-VNC-I-O-h.patch [bz#1527404]
+- kvm-ui-avoid-sign-extension-using-client-width-height.patch [bz#1527404]
+- kvm-ui-correctly-advance-output-buffer-when-writing-SASL.patch [bz#1527404]
+- kvm-dump-guest-memory.py-skip-vmcoreinfo-section-if-not-.patch [bz#1398633]
+- kvm-virtio-gpu-disallow-vIOMMU.patch [bz#1540182]
+- Resolves: bz#1398633
+  ([RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev))
+- Resolves: bz#1505696
+  (Qemu crashed when open the second display of virtio video)
+- Resolves: bz#1527404
+  (CVE-2017-15124 qemu-kvm-rhev: Qemu: memory exhaustion through framebuffer update request message in VNC server [rhel-7.5])
+- Resolves: bz#1540182
+  (QEMU: disallow virtio-gpu to boot with vIOMMU)
+
+* Fri Feb 02 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-19.el7
+- kvm-Drop-105th-key-from-en-us-keymap.patch [bz#1513870]
+- kvm-linux-headers-update.patch [bz#1535606]
+- kvm-s390x-kvm-Handle-bpb-feature.patch [bz#1535606]
+- kvm-s390x-kvm-provide-stfle.81.patch [bz#1535606]
+- kvm-osdep-Retry-SETLK-upon-EINTR.patch [bz#1529053]
+- kvm-vga-check-the-validation-of-memory-addr-when-draw-te.patch [bz#1534682]
+- kvm-usb-storage-Fix-share-rw-option-parsing.patch [bz#1525324]
+- kvm-spapr-disable-memory-hotplug.patch [bz#1535952]
+- Resolves: bz#1513870
+  (For VNC connection, characters '|' and '<' are both recognized as '>' in linux guests, while '<' and '>' are both recognized as '|' in windows guest)
+- Resolves: bz#1525324
+  (2 VMs both with 'share-rw=on' appending on '-device usb-storage' for the same source image can not be started at the same time)
+- Resolves: bz#1529053
+  (Miss the handling of EINTR in the fcntl calls made by QEMU)
+- Resolves: bz#1534682
+  (CVE-2018-5683 qemu-kvm-rhev: Qemu: Out-of-bounds read in vga_draw_text routine [rhel-7.5])
+- Resolves: bz#1535606
+  (Spectre mitigation patches for qemu-kvm-ma on z Systems)
+- Resolves: bz#1535952
+  (qemu-kvm-ma differentiation - memory hotplug)
+
+* Tue Jan 23 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-18.el7
+- kvm-serial-always-transmit-send-receive-buffers-on-migra.patch [bz#1459945]
+- kvm-hw-acpi-Move-acpi_set_pci_info-to-pcihp.patch [bz#1507693]
+- kvm-scsi-block-Add-share-rw-option.patch [bz#1518482]
+- kvm-scsi-generic-Add-share-rw-option.patch [bz#1518482]
+- kvm-target-i386-sanitize-x86-MSR_PAT-loaded-from-another.patch [bz#1529461]
+- kvm-scsi-disk-release-AioContext-in-unaligned-WRITE-SAME.patch [bz#1526423]
+- kvm-hw-pci-bridge-fix-QEMU-crash-because-of-pcie-root-po.patch [bz#1520858]
+- kvm-spapr-Capabilities-infrastructure.patch [bz#1523414]
+- kvm-spapr-Treat-Hardware-Transactional-Memory-HTM-as-an-.patch [bz#1523414]
+- kvm-spapr-Validate-capabilities-on-migration.patch [bz#1523414]
+- kvm-spapr-Handle-VMX-VSX-presence-as-an-spapr-capability.patch [bz#1523414]
+- kvm-spapr-Handle-Decimal-Floating-Point-DFP-as-an-option.patch [bz#1523414]
+- kvm-hw-ppc-spapr_caps-Rework-spapr_caps-to-use-uint8-int.patch [bz#1523414]
+- kvm-spapr-Remove-unnecessary-options-field-from-sPAPRCap.patch [bz#1523414]
+- kvm-ppc-Change-Power9-compat-table-to-support-at-most-8-.patch [bz#1529243]
+- kvm-target-ppc-Clarify-compat-mode-max_threads-value.patch [bz#1529243]
+- kvm-spapr-Allow-some-cases-where-we-can-t-set-VSMT-mode-.patch [bz#1529243]
+- kvm-spapr-Adjust-default-VSMT-value-for-better-migration.patch [bz#1529243]
+- kvm-qemu-img-info-Force-U-downstream.patch [bz#1535992]
+- kvm-dump-guest-memory.py-fix-python-2-support.patch [bz#1398633]
+- kvm-spapr-fix-device-tree-properties-when-using-compatib.patch [bz#1535752]
+- Resolves: bz#1398633
+  ([RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev))
+- Resolves: bz#1459945
+  (migration fails with hungup serial console reader on -M pc-i440fx-rhel7.0.0 and pc-i440fx-rhel7.1.0)
+- Resolves: bz#1507693
+  (Unable to hot plug device to VM reporting libvirt errors.)
+- Resolves: bz#1518482
+  ("share-rw" property is unavailable on scsi passthrough devices)
+- Resolves: bz#1520858
+  (qemu-kvm core dumped when booting guest with more pcie-root-ports than available slots and io-reserve=0)
+- Resolves: bz#1523414
+  ([POWER guests] Verify compatible CPU & hypervisor capabilities across migration)
+- Resolves: bz#1526423
+  (QEMU hang with data plane enabled after some sg_write_same operations in guest)
+- Resolves: bz#1529243
+  (Migration from P9 to P8, migration failed and qemu quit on dst end with "error while loading state for instance 0x0 of device 'ics'")
+- Resolves: bz#1529461
+  (On amd hosts, after migration from rhel6.9.z to rhel7.5, CPU utilization of qemu-kvm is always more than 100% on destination rhel7.5 host)
+- Resolves: bz#1535752
+  (Device tree incorrectly advertises compatibility modes for secondary CPUs)
+- Resolves: bz#1535992
+  (Set force shared option "-U" as default option for "qemu-img info")
+
+* Tue Jan 16 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-17.el7
+- kvm-tools-kvm_stat-fix-command-line-option-g.patch [bz#1529676]
+- kvm-redhat-globally-limit-the-maximum-number-of-CPUs.patch [bz#1527449]
+- kvm-redhat-remove-manual-max_cpus-limitations-for-ppc.patch [bz#1527449]
+- kvm-dump-guest-memory.py-fix-You-can-t-do-that-without-a.patch [bz#1398633]
+- kvm-hw-ppc-spapr.c-abort-unplug_request-if-previous-unpl.patch [bz#1528173]
+- kvm-spapr-Correct-compatibility-mode-setting-for-hotplug.patch [bz#1528234]
+- kvm-ui-fix-dcl-unregister.patch [bz#1510809]
+- kvm-block-Open-backing-image-in-force-share-mode-for-siz.patch [bz#1526212]
+- kvm-fw_cfg-fix-memory-corruption-when-all-fw_cfg-slots-a.patch [bz#1462145]
+- kvm-block-Don-t-use-BLK_PERM_CONSISTENT_READ-for-format-.patch [bz#1515604]
+- kvm-block-Don-t-request-I-O-permission-with-BDRV_O_NO_IO.patch [bz#1515604]
+- kvm-block-Formats-don-t-need-CONSISTENT_READ-with-NO_IO.patch [bz#1515604]
+- Resolves: bz#1398633
+  ([RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev))
+- Resolves: bz#1462145
+  (Qemu crashes when all fw_cfg slots are used)
+- Resolves: bz#1510809
+  (qemu-kvm core dumped when booting up guest using both virtio-vga and VGA)
+- Resolves: bz#1515604
+  (qemu-img info: failed to get "consistent read" lock on a mirroring image)
+- Resolves: bz#1526212
+  (qemu-img should not need a write lock for creating the overlay image)
+- Resolves: bz#1527449
+  (qemu-kvm-ma: vCPU count should be limited to 240 on all arches)
+- Resolves: bz#1528173
+  (Hot-unplug memory  during booting early stage induced qemu-kvm coredump)
+- Resolves: bz#1528234
+  (Pegas1.1 Alpha: Hotplugged vcpu does not guarantee CPU P8compat mode on POWER9 host (qemu-kvm))
+- Resolves: bz#1529676
+  (kvm_stat: option '--guest' doesn't work)
+
+* Mon Jan 08 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-16.el7
+- kvm-gicv3-Convert-to-DEFINE_PROP_LINK.patch [bz#1513323]
+- kvm-hw-intc-arm_gicv3_its-Fix-the-VM-termination-in-vm_c.patch [bz#1513323]
+- kvm-hw-intc-arm_gicv3_its-Don-t-abort-on-table-save-fail.patch [bz#1513323]
+- kvm-hw-intc-arm_gicv3_its-Don-t-call-post_load-on-reset.patch [bz#1513323]
+- kvm-hw-intc-arm_gicv3_its-Implement-a-minimalist-reset.patch [bz#1513323]
+- kvm-linux-headers-Partial-header-update-against-v4.15-rc.patch [bz#1513323]
+- kvm-hw-intc-arm_gicv3_its-Implement-full-reset.patch [bz#1513323]
+- kvm-block-throttle-groups.c-allocate-RestartData-on-the-.patch [bz#1525868]
+- kvm-redhat-Fix-permissions-of-dev-kvm-on-a-freshly-boote.patch [bz#1527947]
+- Resolves: bz#1513323
+  (vITS reset)
+- Resolves: bz#1525868
+  (Guest hit core dump with both IO throttling and data plane)
+- Resolves: bz#1527947
+  (Pegas1.1 - virsh domcapabilities doesn't report KVM capabilities on s390x)
+
+* Thu Jan 04 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-15.el7
+- kvm-target-i386-add-support-for-SPEC_CTRL-MSR.patch [CVE-2017-5715]
+- kvm-target-i386-cpu-add-new-CPUID-bits-for-indirect-bran.patch [CVE-2017-5715]
+- kvm-target-i386-cpu-add-new-CPU-models-for-indirect-bran.patch [CVE-2017-5715]
+
+* Tue Jan 02 2018 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-14.el7
+- kvm-spapr-don-t-initialize-PATB-entry-if-max-cpu-compat-.patch [bz#1525866]
+- kvm-block-avoid-recursive-AioContext-acquire-in-bdrv_ina.patch [bz#1520824]
+- kvm-io-send-proper-HTTP-response-for-websocket-errors.patch [bz#1518649]
+- kvm-io-include-full-error-message-in-websocket-handshake.patch [bz#1518649]
+- kvm-io-use-case-insensitive-check-for-Connection-Upgrade.patch [bz#1518649]
+- kvm-ui-Always-remove-an-old-VNC-channel-watch-before-add.patch [bz#1518649]
+- kvm-io-Small-updates-in-preparation-for-websocket-change.patch [bz#1518649]
+- kvm-io-Add-support-for-fragmented-websocket-binary-frame.patch [bz#1518649]
+- kvm-io-Allow-empty-websocket-payload.patch [bz#1518649]
+- kvm-io-Ignore-websocket-PING-and-PONG-frames.patch [bz#1518649]
+- kvm-io-Reply-to-ping-frames.patch [bz#1518649]
+- kvm-io-Attempt-to-send-websocket-close-messages-to-clien.patch [bz#1518649]
+- kvm-io-add-trace-events-for-websockets-frame-handling.patch [bz#1518649]
+- kvm-io-monitor-encoutput-buffer-size-from-websocket-GSou.patch [bz#1518650]
+- kvm-io-simplify-websocket-ping-reply-handling.patch [bz#1518649]
+- kvm-io-get-rid-of-qio_channel_websock_encode-helper-meth.patch [bz#1518649]
+- kvm-io-pass-a-struct-iovec-into-qio_channel_websock_enco.patch [bz#1518649]
+- kvm-io-get-rid-of-bounce-buffering-in-websock-write-path.patch [bz#1518649]
+- kvm-io-cope-with-websock-Connection-header-having-multip.patch [bz#1518649]
+- kvm-io-add-trace-points-for-websocket-HTTP-protocol-head.patch [bz#1518649]
+- kvm-io-fix-mem-leak-in-websock-error-path.patch [bz#1518649]
+- kvm-io-Add-missing-GCC_FMT_ATTR-fix-Werror-suggest-attri.patch [bz#1518649]
+- kvm-qemu.py-make-VM-a-context-manager.patch [bz#1519721]
+- kvm-iotests.py-add-FilePath-context-manager.patch [bz#1519721]
+- kvm-qemu-iothread-IOThread-supports-the-GMainContext-eve.patch [bz#1519721]
+- kvm-qom-provide-root-container-for-internal-objs.patch [bz#1519721]
+- kvm-iothread-provide-helpers-for-internal-use.patch [bz#1519721]
+- kvm-iothread-export-iothread_stop.patch [bz#1519721]
+- kvm-iothread-delay-the-context-release-to-finalize.patch [bz#1519721]
+- kvm-aio-fix-assert-when-remove-poll-during-destroy.patch [bz#1519721]
+- kvm-blockdev-hold-AioContext-for-bdrv_unref-in-external_.patch [bz#1519721]
+- kvm-block-don-t-keep-AioContext-acquired-after-external_.patch [bz#1519721]
+- kvm-block-don-t-keep-AioContext-acquired-after-drive_bac.patch [bz#1519721]
+- kvm-block-don-t-keep-AioContext-acquired-after-blockdev_.patch [bz#1519721]
+- kvm-block-don-t-keep-AioContext-acquired-after-internal_.patch [bz#1519721]
+- kvm-iothread-add-iothread_by_id-API.patch [bz#1519721]
+- kvm-blockdev-add-x-blockdev-set-iothread-testing-command.patch [bz#1519721]
+- kvm-qemu-iotests-add-202-external-snapshots-IOThread-tes.patch [bz#1519721]
+- kvm-blockdev-add-x-blockdev-set-iothread-force-boolean.patch [bz#1519721]
+- kvm-iotests-add-VM.add_object.patch [bz#1519721]
+- kvm-iothread-fix-iothread_stop-race-condition.patch [bz#1519721]
+- kvm-qemu-iotests-add-203-savevm-with-IOThreads-test.patch [bz#1519721]
+- Resolves: bz#1518649
+  (Client compatibility flaws in VNC websockets server)
+- Resolves: bz#1518650
+  (CVE-2017-15268 qemu-kvm-rhev: Qemu: I/O: potential memory exhaustion via websock connection to VNC [rhel-7.5])
+- Resolves: bz#1519721
+  (Both qemu and guest hang when performing live snapshot transaction with data-plane)
+- Resolves: bz#1520824
+  (Migration with dataplane, qemu processor hang, vm hang and migration can't finish)
+- Resolves: bz#1525866
+  (P9 to P8 guest migration fails when kernel is not started)
+
+* Tue Dec 19 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-13.el7
+- kvm-target-ppc-Add-POWER9-DD2.0-model-information.patch [bz#1523235]
+- kvm-block-vxhs-improve-error-message-for-missing-bad-vxh.patch [bz#1505654]
+- kvm-qemu-img-Clarify-about-relative-backing-file-options.patch [bz#1451269]
+- kvm-nbd-server-CVE-2017-15119-Reject-options-larger-than.patch [bz#1518529 bz#1518551]
+- kvm-nbd-server-CVE-2017-15118-Stack-smash-on-large-expor.patch [bz#1516545 bz#1518548]
+- kvm-vfio-Fix-vfio-kvm-group-registration.patch [bz#1520294]
+- Resolves: bz#1451269
+  (Clarify the relativity of backing file and created image in "qemu-img create")
+- Resolves: bz#1505654
+  (Missing libvxhs share-able object  file when try to query vxhs protocol)
+- Resolves: bz#1516545
+  (CVE-2017-15118 qemu-kvm-rhev: qemu NBD server vulnerable to stack smash from client requesting long export name [rhel-7.5])
+- Resolves: bz#1518529
+  (CVE-2017-15119 qemu-kvm-rhev: qemu: DoS via large option request [rhel-7.5])
+- Resolves: bz#1518548
+  (CVE-2017-15118 qemu-kvm-ma: Qemu: stack buffer overflow in NBD server triggered via long export name [rhel-7.5])
+- Resolves: bz#1518551
+  (CVE-2017-15119 qemu-kvm-ma: qemu: DoS via large option request [rhel-7.5])
+- Resolves: bz#1520294
+  (Hot-unplug the second pf cause qemu promote " Failed to remove group $iommu_group_num from KVM VFIO device:")
+- Resolves: bz#1523235
+  (Pegas1.0 - qemu cpu information is not up-to-date (qemu-kvm))
+
+* Mon Dec 11 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-12.el7
+- kvm-block-add-bdrv_co_drain_end-callback.patch [bz#1506531]
+- kvm-block-rename-bdrv_co_drain-to-bdrv_co_drain_begin.patch [bz#1506531]
+- kvm-blockjob-do-not-allow-coroutine-double-entry-or-entr.patch [bz#1506531]
+- kvm-coroutine-abort-if-we-try-to-schedule-or-enter-a-pen.patch [bz#1506531]
+- kvm-qemu-iotests-add-option-in-common.qemu-for-mismatch-.patch [bz#1506531]
+- kvm-qemu-iotest-add-test-for-blockjob-coroutine-race-con.patch [bz#1506531]
+- kvm-blockjob-Remove-the-job-from-the-list-earlier-in-blo.patch [bz#1506531]
+- kvm-block-Expect-graph-changes-in-bdrv_parent_drained_be.patch [bz#1506531]
+- kvm-blockjob-remove-clock-argument-from-block_job_sleep_.patch [bz#1506531]
+- kvm-blockjob-introduce-block_job_do_yield.patch [bz#1506531]
+- kvm-blockjob-reimplement-block_job_sleep_ns-to-allow-can.patch [bz#1506531]
+- kvm-blockjob-Make-block_job_pause_all-keep-a-reference-t.patch [bz#1506531]
+- kvm-target-ppc-Move-setting-of-patb_entry-on-hash-table-.patch [bz#1517051]
+- kvm-target-ppc-Fix-setting-of-cpu-compat_pvr-on-incoming.patch [bz#1517051]
+- kvm-BZ1513294-spapr-Include-pre-plugged-DIMMS-in-ram-siz.patch [bz#1513294]
+- kvm-virtio-Add-queue-interface-to-restore-avail-index-fr.patch [bz#1491909]
+- kvm-vhost-restore-avail-index-from-vring-used-index-on-d.patch [bz#1491909]
+- kvm-dump-guest-memory.py-fix-No-symbol-vmcoreinfo_find.patch [bz#1398633]
+- kvm-ppc-fix-setting-of-compat-mode.patch [bz#1396119]
+- kvm-pc-fix-crash-on-attempted-cpu-unplug.patch [bz#1506856]
+- kvm-sockets-avoid-crash-when-cleaning-up-sockets-for-an-.patch [bz#1506218]
+- Resolves: bz#1396119
+  ([IBM 7.5 Feature] POWER9 - Virt: QEMU: POWER8/P8-Compat mode for POWER8 Guests on POWER9 platform)
+- Resolves: bz#1398633
+  ([RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev))
+- Resolves: bz#1491909
+  (IP network can not recover after several vhost-user reconnect)
+- Resolves: bz#1506218
+  (seg at exit - due to missing fd?)
+- Resolves: bz#1506531
+  ([data-plane] Qemu-kvm core dumped when hot-unplugging a block device with data-plane while the drive-mirror job is running)
+- Resolves: bz#1506856
+  ([abrt] qemu-kvm-rhev: object_get_class(): qemu-kvm killed by SIGSEGV)
+- Resolves: bz#1513294
+  (Guest got stuck when attached memory beforehand.[-device dimm and object memory-backend-ram])
+- Resolves: bz#1517051
+  (POWER9 - Virt: QEMU: Migration of HPT guest on Radix host fails)
+
+* Tue Dec 05 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-11.el7
+- kvm-qcow2-don-t-permit-changing-encryption-parameters.patch [bz#1406803]
+- kvm-qcow2-fix-image-corruption-after-committing-qcow2-im.patch [bz#1406803]
+- kvm-qemu-doc-Add-UUID-support-in-initiator-name.patch [bz#1494210]
+- kvm-docs-add-qemu-block-drivers-7-man-page.patch [bz#1494210]
+- kvm-docs-Add-image-locking-subsection.patch [bz#1494210]
+- kvm-qemu-options-Mention-locking-option-of-file-driver.patch [bz#1494210]
+- kvm-Package-qemu-block-drivers-manpage.patch [bz#1494210]
+- kvm-block-don-t-add-driver-to-options-when-referring-to-.patch [bz#1505701]
+- kvm-blockdev-Report-proper-error-class-in-__com.redhat.d.patch [bz#1487515]
+- kvm-block-use-1-MB-bounce-buffers-for-crypto-instead-of-.patch [bz#1500334]
+- kvm-io-add-new-qio_channel_-readv-writev-read-write-_all.patch [bz#1464908]
+- kvm-io-Yield-rather-than-wait-when-already-in-coroutine.patch [bz#1464908]
+- kvm-scsi-bus-correct-responses-for-INQUIRY-and-REQUEST-S.patch [bz#1464908]
+- kvm-scsi-Refactor-scsi-sense-interpreting-code.patch [bz#1464908]
+- kvm-scsi-Improve-scsi_sense_to_errno.patch [bz#1464908]
+- kvm-scsi-Introduce-scsi_sense_buf_to_errno.patch [bz#1464908]
+- kvm-scsi-rename-scsi_build_sense-to-scsi_convert_sense.patch [bz#1464908]
+- kvm-scsi-move-non-emulation-specific-code-to-scsi.patch [bz#1464908]
+- kvm-scsi-introduce-scsi_build_sense.patch [bz#1464908]
+- kvm-scsi-introduce-sg_io_sense_from_errno.patch [bz#1464908]
+- kvm-scsi-move-block-scsi.h-to-include-scsi-constants.h.patch [bz#1464908]
+- kvm-scsi-file-posix-add-support-for-persistent-reservati.patch [bz#1464908]
+- kvm-scsi-build-qemu-pr-helper.patch [bz#1464908]
+- kvm-scsi-add-multipath-support-to-qemu-pr-helper.patch [bz#1464908]
+- kvm-scsi-add-persistent-reservation-manager-using-qemu-p.patch [bz#1464908]
+- kvm-update-spec-to-build-and-install-qemu-pr-helper.patch [bz#1464908]
+- kvm-qemu-pr-helper-miscellaneous-fixes.patch [bz#1464908]
+- kvm-Match-POWER-max-cpus-to-x86.patch [bz#1495456]
+- kvm-qemu-io-Drop-write-permissions-before-read-only-reop.patch [bz#1492178]
+- kvm-block-Add-reopen_queue-to-bdrv_child_perm.patch [bz#1492178]
+- kvm-block-Add-reopen-queue-to-bdrv_check_perm.patch [bz#1492178]
+- kvm-block-Base-permissions-on-rw-state-after-reopen.patch [bz#1492178]
+- kvm-block-reopen-Queue-children-after-their-parents.patch [bz#1492178]
+- kvm-block-Fix-permissions-after-bdrv_reopen.patch [bz#1492178]
+- kvm-qemu-iotests-Test-change-backing-file-command.patch [bz#1492178]
+- kvm-iotests-Fix-195-if-IMGFMT-is-part-of-TEST_DIR.patch [bz#1492178]
+- Resolves: bz#1406803
+  (RFE: native integration of LUKS and qcow2)
+- Resolves: bz#1464908
+  ([RFE] Add S3 PR support to qemu (similar to mpathpersist))
+- Resolves: bz#1487515
+  (wrong error code is reported if __com.redhat.drive_del can't find the device to delete)
+- Resolves: bz#1492178
+  (Non-top-level change-backing-file causes assertion failure)
+- Resolves: bz#1494210
+  (Document image locking in the qemu-img manpage)
+- Resolves: bz#1495456
+  (Update downstream qemu's max supported cpus for pseries to the RHEL supported number)
+- Resolves: bz#1500334
+  (LUKS driver has poor performance compared to in-kernel driver)
+- Resolves: bz#1505701
+  (-blockdev fails if a qcow2 image has backing store format and backing store is referenced via node-name)
+
+* Thu Nov 30 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-10.el7
+- kvm-qcow2-fix-return-error-code-in-qcow2_truncate.patch [bz#1414049]
+- kvm-qcow2-Fix-unaligned-preallocated-truncation.patch [bz#1414049]
+- kvm-qcow2-Always-execute-preallocate-in-a-coroutine.patch [bz#1414049]
+- kvm-iotests-Add-cluster_size-64k-to-125.patch [bz#1414049]
+- kvm-fw_cfg-rename-read-callback.patch [bz#1398633]
+- kvm-fw_cfg-add-write-callback.patch [bz#1398633]
+- kvm-hw-misc-add-vmcoreinfo-device.patch [bz#1398633]
+- kvm-dump-add-guest-ELF-note.patch [bz#1398633]
+- kvm-dump-update-phys_base-header-field-based-on-VMCOREIN.patch [bz#1398633]
+- kvm-kdump-set-vmcoreinfo-location.patch [bz#1398633]
+- kvm-scripts-dump-guest-memory.py-add-vmcoreinfo.patch [bz#1398633]
+- kvm-vmcoreinfo-put-it-in-the-misc-device-category.patch [bz#1398633]
+- kvm-build-sys-restrict-vmcoreinfo-to-fw_cfg-dma-capable-.patch [bz#1398633]
+- kvm-slirp-fix-clearing-ifq_so-from-pending-packets.patch [bz#1508750]
+- kvm-migration-ram.c-do-not-set-postcopy_running-in-POSTC.patch [bz#1516956]
+- kvm-scsi-Fix-onboard-HBAs-to-pick-up-drive-if-scsi.patch [bz#1497740]
+- kvm-virtio-net-don-t-touch-virtqueue-if-vm-is-stopped.patch [bz#1506151]
+- kvm-scsi-disk-support-reporting-of-rotation-rate.patch [bz#1498042]
+- kvm-ide-support-reporting-of-rotation-rate.patch [bz#1498042]
+- kvm-ide-avoid-referencing-NULL-dev-in-rotational-rate-se.patch [bz#1498042]
+- Resolves: bz#1398633
+  ([RFE] Kernel address space layout randomization [KASLR] support (qemu-kvm-rhev))
+- Resolves: bz#1414049
+  ([RFE] Add support to qemu-img  for resizing with preallocation)
+- Resolves: bz#1497740
+  (-cdrom option is broken)
+- Resolves: bz#1498042
+  (RFE: option to mark virtual block device as rotational/non-rotational)
+- Resolves: bz#1506151
+  ([data-plane] Quitting qemu in destination side encounters "core dumped" when doing live migration)
+- Resolves: bz#1508750
+  (CVE-2017-13711 qemu-kvm-rhev: Qemu: Slirp: use-after-free when sending response [rhel-7.5])
+- Resolves: bz#1516956
+  (Pegas1.0 - [qemu]: loadvm fails to restore VM snapshot saved using savevm in destination after postcopy migration (kvm))
+
+* Tue Nov 28 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-9.el7
+- kvm-spapr-Correct-RAM-size-calculation-for-HPT-resizing.patch [bz#1499647]
+- kvm-migration-Reenable-incoming-live-block-migration.patch [bz#1515173]
+- kvm-ppc-fix-VTB-migration.patch [bz#1506882]
+- kvm-hw-ppc-spapr-Fix-virtio-scsi-bootindex-handling-for-.patch [bz#1515393]
+- kvm-spapr-Implement-bug-in-spapr-vty-device-to-be-compat.patch [bz#1495090]
+- kvm-spapr-reset-DRCs-after-devices.patch [bz#1516145]
+- kvm-redhat-install-generic-kvm.conf-except-for-s390-and-.patch [bz#1517144]
+- Resolves: bz#1495090
+  (Transfer a file about 10M failed from host to guest through spapr-vty device)
+- Resolves: bz#1499647
+  (qemu miscalculates guest RAM size during HPT resizing)
+- Resolves: bz#1506882
+  (Call trace showed up in dmesg after migrating guest when "stress-ng --numa 2" was running inside guest)
+- Resolves: bz#1515173
+  (Cross migration from rhel6.9 to rhel7.5 failed)
+- Resolves: bz#1515393
+  (bootindex is not taken into account for virtio-scsi devices on ppc64 if the LUN is >= 256)
+- Resolves: bz#1516145
+  (Pegas1.0 - [memory hotplug/unplug] qemu crashes with assertion failed from hw/virtio/vhost.c:649 (qemu-kvm))
+- Resolves: bz#1517144
+  (Provide a ppc64le specific /etc/modprobe.d/kvm.conf)
+
+* Mon Nov 27 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-8.el7
+- kvm-block-move-ThrottleGroup-membership-to-ThrottleGroup.patch [bz#1492295]
+- kvm-block-add-aio_context-field-in-ThrottleGroupMember.patch [bz#1492295]
+- kvm-block-tidy-ThrottleGroupMember-initializations.patch [bz#1492295]
+- kvm-block-all-I-O-should-be-completed-before-removing-th.patch [bz#1492295]
+- kvm-throttle-groups-drain-before-detaching-ThrottleState.patch [bz#1492295]
+- kvm-block-Check-for-inserted-BlockDriverState-in-blk_io_.patch [bz#1492295]
+- kvm-block-Leave-valid-throttle-timers-when-removing-a-BD.patch [bz#1492295]
+- kvm-qemu-iotests-Test-I-O-limits-with-removable-media.patch [bz#1492295]
+- kvm-throttle-groups-forget-timer-and-schedule-next-TGM-o.patch [bz#1492295]
+- kvm-i386-cpu-hyperv-support-over-64-vcpus-for-windows-gu.patch [bz#1451959]
+- kvm-target-ppc-correct-htab-shift-for-hash-on-radix.patch [bz#1396120]
+- kvm-target-ppc-Update-setting-of-cpu-features-to-account.patch [bz#1396120]
+- kvm-s390-ccw-Fix-alignment-for-CCW1.patch [bz#1514352]
+- kvm-pc-bios-s390-ccw-Fix-problem-with-invalid-virtio-scs.patch [bz#1514352]
+- kvm-redhat-qemu-kvm.spec-Use-the-freshly-built-s390-ccw..patch [bz#1514352]
+- Resolves: bz#1396120
+  ([IBM 7.5 FEAT] POWER9 - Virt: QEMU: POWER8/P8-Compat mode - HPT to guest)
+- Resolves: bz#1451959
+  (Windows 2016 guest blue screen with page fault in nonpaged area when using hv flags)
+- Resolves: bz#1492295
+  (Guest hit call trace with iothrottling(iops) after the status from stop to cont during doing io testing)
+- Resolves: bz#1514352
+  ([RHEL-ALT][s390x] qemu process terminated after rebooting the guest)
+
+* Wed Nov 22 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-7.el7
+- kvm-hw-pci-introduce-bridge-only-vendor-specific-capabil.patch [bz#1437113]
+- kvm-hw-pci-add-QEMU-specific-PCI-capability-to-the-Gener.patch [bz#1437113]
+- kvm-util-async-use-atomic_mb_set-in-qemu_bh_cancel.patch [bz#1508886]
+- kvm-hw-gen_pcie_root_port-make-IO-RO-0-on-IO-disabled.patch [bz#1344299]
+- kvm-pcie_root_port-Fix-x-migrate-msix-compat.patch [bz#1511312]
+- kvm-q35-Fix-mismerge.patch [bz#1511312]
+- kvm-virtio-pci-Replace-modern_as-with-direct-access-to-m.patch [bz#1481593]
+- kvm-atomic-update-documentation.patch [bz#1481593]
+- kvm-memory-avoid-resurrection-of-dead-FlatViews.patch [bz#1481593]
+- kvm-exec-Explicitly-export-target-AS-from-address_space_.patch [bz#1481593]
+- kvm-memory-Open-code-FlatView-rendering.patch [bz#1481593]
+- kvm-memory-Move-FlatView-allocation-to-a-helper.patch [bz#1481593]
+- kvm-memory-Move-AddressSpaceDispatch-from-AddressSpace-t.patch [bz#1481593]
+- kvm-memory-Remove-AddressSpace-pointer-from-AddressSpace.patch [bz#1481593]
+- kvm-memory-Switch-memory-from-using-AddressSpace-to-Flat.patch [bz#1481593]
+- kvm-memory-Cleanup-after-switching-to-FlatView.patch [bz#1481593]
+- kvm-memory-Rename-mem_begin-mem_commit-mem_add-helpers.patch [bz#1481593]
+- kvm-memory-Store-physical-root-MR-in-FlatView.patch [bz#1481593]
+- kvm-memory-Alloc-dispatch-tree-where-topology-is-generar.patch [bz#1481593]
+- kvm-memory-Move-address_space_update_ioeventfds.patch [bz#1481593]
+- kvm-memory-Share-FlatView-s-and-dispatch-trees-between-a.patch [bz#1481593]
+- kvm-memory-Do-not-allocate-FlatView-in-address_space_ini.patch [bz#1481593]
+- kvm-memory-Rework-info-mtree-to-print-flat-views-and-dis.patch [bz#1481593]
+- kvm-memory-Get-rid-of-address_space_init_shareable.patch [bz#1481593]
+- kvm-memory-Create-FlatView-directly.patch [bz#1481593]
+- kvm-memory-trace-FlatView-creation-and-destruction.patch [bz#1481593]
+- kvm-memory-seek-FlatView-sharing-candidates-among-childr.patch [bz#1481593]
+- kvm-memory-Share-special-empty-FlatView.patch [bz#1481593]
+- kvm-hw-pci-host-Fix-x86-Host-Bridges-64bit-PCI-hole.patch [bz#1390346]
+- kvm-redhat-Provide-s390x-specific-etc-modprobe.d-kvm.con.patch [bz#1511990]
+- Resolves: bz#1344299
+  (PCIe: Add an option to PCIe ports to disable IO port space support)
+- Resolves: bz#1390346
+  (PCI: Reserve MMIO space over 4G for PCI hotplug)
+- Resolves: bz#1437113
+  (PCIe: Allow configuring  Generic PCIe Root Ports MMIO Window)
+- Resolves: bz#1481593
+  (Boot guest failed with "src/central_freelist.cc:333] tcmalloc: allocation failed 196608" when 465 disks are attached to 465 pci-bridges)
+- Resolves: bz#1508886
+  (QEMU's AIO subsystem gets stuck inhibiting all I/O operations on virtio-blk-pci devices)
+- Resolves: bz#1511312
+  (Migrate an VM with  pci-bridge or pcie-root-port failed)
+- Resolves: bz#1511990
+  (Provide a s390x specific /etc/modprobe.d/kvm.conf)
+
+* Mon Nov 13 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-6.el7
+- kvm-multiboot-validate-multiboot-header-address-values.patch [bz#1501124]
+- kvm-monitor-fix-dangling-CPU-pointer.patch [bz#1510001]
+- kvm-qdev-store-DeviceState-s-canonical-path-to-use-when-.patch [bz#1445460]
+- kvm-Revert-qdev-Free-QemuOpts-when-the-QOM-path-goes-awa.patch [bz#1445460]
+- kvm-qdev-defer-DEVICE_DEL-event-until-instance_finalize.patch [bz#1445460]
+- kvm-s390x-print-CPU-definitions-in-sorted-order.patch [bz#1504138]
+- kvm-s390x-cpumodel-Disable-unsupported-CPU-models.patch [bz#1504138]
+- Resolves: bz#1445460
+  (EEH freeze up when reattaching an i40evf VF to host)
+- Resolves: bz#1501124
+  (CVE-2017-14167 qemu-kvm-rhev: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.5])
+- Resolves: bz#1504138
+  (Disable older CPU models in qemu-kvm-ma on s390x)
+- Resolves: bz#1510001
+  (Pegas1.0 - qemu crashed during "info cpus" in monitor with change in default cpu in hotplug/unplug sequence (kvm))
+
+* Wed Nov 08 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-5.el7
+- kvm-qemu-kvm-rhev-only-allows-pseries-rhel7.5.0-machine-.patch [bz#1478469]
+- kvm-pc-bios-keymaps-keymaps-update.patch [bz#1503128]
+- kvm-migration-Reset-rather-than-destroy-main_thread_load.patch [bz#1508799]
+- kvm-snapshot-tests-Try-loadvm-twice.patch [bz#1508799]
+- kvm-machine-compat-pci_bridge-shpc-always-enable.patch [bz#1508271]
+- kvm-hw-pci-host-gpex-Set-INTx-index-gsi-mapping.patch [bz#1460957]
+- kvm-hw-arm-virt-Set-INTx-gsi-mapping.patch [bz#1460957]
+- kvm-hw-pci-host-gpex-Implement-PCI-INTx-routing.patch [bz#1460957]
+- kvm-hw-pci-host-gpex-Improve-INTX-to-gsi-routing-error-c.patch [bz#1460957]
+- Resolves: bz#1460957
+  (Implement INTx to GSI routing on ARM virt)
+- Resolves: bz#1478469
+  (RHEL 7.5 machine types for Power 8 and 9 - qemu-kvm-rhev)
+- Resolves: bz#1503128
+  (update reverse keymaps for qemu vnc server)
+- Resolves: bz#1508271
+  (Migration is failed from host RHEL7.4.z to host RHEL7.5 with "-machine pseries-rhel7.4.0 -device pci-bridge,id=pci_bridge,bus=pci.0,addr=03,chassis_nr=1")
+- Resolves: bz#1508799
+  (qemu-kvm core dumped when doing 'savevm/loadvm/delvm' for the second time)
+
+* Thu Nov 02 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-4.el7
+- kvm-vga-drop-line_offset-variable.patch [bz#1501301]
+- kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch [bz#1501301]
+- kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch [bz#1501301]
+- kvm-exec-add-page_mask-for-address_space_do_translate.patch [bz#1498817]
+- kvm-exec-simplify-address_space_get_iotlb_entry.patch [bz#1498817]
+- kvm-xio3130_downstream-Report-error-if-pcie_chassis_add_.patch [bz#1390348]
+- kvm-pci-conventional-pci-device-and-pci-express-device-i.patch [bz#1390348]
+- kvm-pci-Add-interface-names-to-hybrid-PCI-devices.patch [bz#1390348]
+- kvm-pci-Add-INTERFACE_PCIE_DEVICE-to-all-PCIe-devices.patch [bz#1390348]
+- kvm-pci-Add-INTERFACE_CONVENTIONAL_PCI_DEVICE-to-Convent.patch [bz#1390348]
+- kvm-xen-pt-Mark-TYPE_XEN_PT_DEVICE-as-hybrid.patch [bz#1390348]
+- kvm-pci-Validate-interfaces-on-base_class_init.patch [bz#1390348]
+- kvm-migration-Add-pause-before-switchover-capability.patch [bz#1497120]
+- kvm-migration-Add-pre-switchover-and-device-statuses.patch [bz#1497120]
+- kvm-migration-Wait-for-semaphore-before-completing-migra.patch [bz#1497120]
+- kvm-migration-migrate-continue.patch [bz#1497120]
+- kvm-migrate-HMP-migate_continue.patch [bz#1497120]
+- kvm-migration-allow-cancel-to-unpause.patch [bz#1497120]
+- kvm-migration-pause-before-switchover-for-postcopy.patch [bz#1497120]
+- Resolves: bz#1390348
+  (PCI: Provide to libvirt a new query command whether a device is PCI/PCIe/hybrid)
+- Resolves: bz#1497120
+  (migration+new block migration race: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed)
+- Resolves: bz#1498817
+  (Vhost IOMMU support regression since qemu-kvm-rhev-2.9.0-16.el7_4.5)
+- Resolves: bz#1501301
+  (CVE-2017-15289 qemu-kvm-rhev: Qemu: cirrus: OOB access issue in  mode4and5 write functions [rhel-7.5])
+
+* Fri Oct 20 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-3.el7
+- kvm-virtio-gpu-don-t-clear-QemuUIInfo-information-on-res.patch [bz#1460595]
+- kvm-vga-fix-display-update-region-calculation-split-scre.patch [bz#1486648]
+- kvm-target-i386-cpu-Add-new-EPYC-CPU-model.patch [bz#1445834]
+- kvm-redhat-add-CONFIG_RHV-flag.patch [bz#1498865]
+- kvm-intel_iommu-fix-missing-BQL-in-pt-fast-path.patch [bz#1449067]
+- kvm-redhat-define-HW_COMPAT_RHEL7_4.patch [bz#1478478]
+- kvm-redhat-define-pseries-rhel7.5.0-machine-type.patch [bz#1478478]
+- kvm-qemu-kvm-ma-define-only-pseries-rhel7.5.0-machine-ty.patch [bz#1478478]
+- kvm-Create-x86-7.5.0-machine-types.patch [bz#1499011]
+- kvm-i386-kvm-use-a-switch-statement-for-MSR-detection.patch [bz#1500347]
+- kvm-i386-kvm-set-tsc_khz-before-configuring-Hyper-V-CPUI.patch [bz#1500347]
+- kvm-i386-kvm-introduce-tsc_is_stable_and_known.patch [bz#1500347]
+- kvm-i386-kvm-advertise-Hyper-V-frequency-MSRs.patch [bz#1500347]
+- kvm-acpi-Force-rev1-FADT-on-old-q35-machine-types.patch [bz#1489800]
+- kvm-pc-make-pc_rom-RO-only-on-new-machine-types.patch [bz#1489800]
+- kvm-osdep-Force-define-F_OFD_GETLK-RHEL-only.patch [bz#1378241]
+- kvm-Disable-vhost-user-scsi-and-vhost-user-scsi-pci.patch [bz#1498496]
+- kvm-Disable-sm501-and-sysbus-sm501-devices.patch [bz#1498496]
+- kvm-configure-enable-s390-pgste-linker-option.patch [bz#1485399]
+- kvm-s390x-vm.allocate_pgste-sysctl-is-no-longer-needed.patch [bz#1485399]
+- kvm-arm-virt-Add-RHEL-7.5-machine-type.patch [bz#1498662]
+- kvm-tools-kvm_stat-hide-cursor.patch [bz#1497137]
+- kvm-tools-kvm_stat-catch-curses-exceptions-only.patch [bz#1497137]
+- kvm-tools-kvm_stat-handle-SIGINT-in-log-and-batch-modes.patch [bz#1497137]
+- kvm-tools-kvm_stat-fix-misc-glitches.patch [bz#1497137]
+- kvm-tools-kvm_stat-fix-trace-setup-glitch-on-field-updat.patch [bz#1497137]
+- kvm-tools-kvm_stat-full-PEP8-compliance.patch [bz#1497137]
+- kvm-tools-kvm_stat-reduce-perceived-idle-time-on-filter-.patch [bz#1497137]
+- kvm-tools-kvm_stat-document-list-of-interactive-commands.patch [bz#1497137]
+- kvm-tools-kvm_stat-display-guest-name-when-using-pid-fil.patch [bz#1497137]
+- kvm-tools-kvm_stat-remove-pid-filter-on-empty-input.patch [bz#1497137]
+- kvm-tools-kvm_stat-print-error-messages-on-faulty-pid-fi.patch [bz#1497137]
+- kvm-tools-kvm_stat-display-regex-when-set-to-non-default.patch [bz#1497137]
+- kvm-tools-kvm_stat-remove-regex-filter-on-empty-input.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-option-guest.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-interactive-command-c.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-interactive-command-r.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-Total-column.patch [bz#1497137]
+- kvm-tools-kvm_stat-fix-typo.patch [bz#1497137]
+- kvm-tools-kvm_stat-fix-event-counts-display-for-interrup.patch [bz#1497137]
+- kvm-tools-kvm_stat-fix-undue-use-of-initial-sleeptime.patch [bz#1497137]
+- kvm-tools-kvm_stat-remove-unnecessary-header-redraws.patch [bz#1497137]
+- kvm-tools-kvm_stat-simplify-line-print-logic.patch [bz#1497137]
+- kvm-tools-kvm_stat-removed-unused-function.patch [bz#1497137]
+- kvm-tools-kvm_stat-remove-extra-statement.patch [bz#1497137]
+- kvm-tools-kvm_stat-simplify-initializers.patch [bz#1497137]
+- kvm-tools-kvm_stat-move-functions-to-corresponding-class.patch [bz#1497137]
+- kvm-tools-kvm_stat-show-cursor-in-selection-screens.patch [bz#1497137]
+- kvm-tools-kvm_stat-display-message-indicating-lack-of-ev.patch [bz#1497137]
+- kvm-tools-kvm_stat-make-heading-look-a-bit-more-like-top.patch [bz#1497137]
+- kvm-tools-kvm_stat-rename-Current-column-to-CurAvg-s.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-new-interactive-command-h.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-new-interactive-command-s.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-new-interactive-command-o.patch [bz#1497137]
+- kvm-tools-kvm_stat-display-guest-list-in-pid-guest-selec.patch [bz#1497137]
+- kvm-tools-kvm_stat-display-guest-list-in-pid-guest-sele2.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-new-command-line-switch-i.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-new-interactive-command-b.patch [bz#1497137]
+- kvm-tools-kvm_stat-use-variables-instead-of-hard-paths-i.patch [bz#1497137]
+- kvm-tools-kvm_stat-add-f-help-to-get-the-available-event.patch [bz#1497137]
+- kvm-iothread-Make-iothread_stop-idempotent.patch [bz#1460848]
+- kvm-vl-Clean-up-user-creatable-objects-when-exiting.patch [bz#1460848]
+- kvm-osdep-Define-QEMU_MADV_REMOVE.patch [bz#1460848]
+- kvm-hostmem-file-Add-discard-data-option.patch [bz#1460848]
+- kvm-hw-dma-i8257-Remove-redundant-downstream-user_creata.patch [bz#1503998]
+- kvm-hw-pci-host-q35-Remove-redundant-downstream-user_cre.patch [bz#1503998]
+- kvm-hw-Remove-the-redundant-user_creatable-false-from-SY.patch [bz#1503998]
+- kvm-spapr-disable-cpu-hot-remove.patch [bz#1499320]
+- kvm-Update-build_configure-for-2.10.0-options.patch [bz#1502949]
+- Resolves: bz#1378241
+  (QEMU image file locking)
+- Resolves: bz#1445834
+  (Add support for AMD EPYC processors)
+- Resolves: bz#1449067
+  ([RFE] Device passthrough support for VT-d emulation)
+- Resolves: bz#1460595
+  ([virtio-vga]Display 2 should be dropped when guest reboot)
+- Resolves: bz#1460848
+  (RFE: Enhance qemu to support freeing memory before exit when using memory-backend-file)
+- Resolves: bz#1478478
+  (RHEL 7.5 machine types for Power 8 and 9 - qemu-kvm-ma)
+- Resolves: bz#1485399
+  (Backport selective allocation of PGSTE to avoid global vm.allocate_pgste)
+- Resolves: bz#1486648
+  (CVE-2017-13673 qemu-kvm-rhev: Qemu: vga: reachable assert failure during during display update [rhel-7.5])
+- Resolves: bz#1489800
+  (q35/ovmf: Machine type compat vs OVMF vs windows)
+- Resolves: bz#1497137
+  (Update kvm_stat)
+- Resolves: bz#1498496
+  (Handle device tree changes in QEMU 2.10.0)
+- Resolves: bz#1498662
+  (RHEL-7.5 machine machine type for aarch64 (qemu-kvm-ma))
+- Resolves: bz#1498865
+  (There is no switch to build qemu-kvm-rhev or qemu-kvm-ma packages)
+- Resolves: bz#1499011
+  (7.5: x86 machine types for 7.5)
+- Resolves: bz#1499320
+  (qemu-kvm-ma differentiation - cpu unplug)
+- Resolves: bz#1500347
+  ([Hyper-V][RHEL-7.4]Nested virt: Windows guest doesn't use TSC page when Hyper-V role is enabled)
+- Resolves: bz#1502949
+  (Update configure parameters to cover changes in 2.10.0)
+- Resolves: bz#1503998
+  (Remove redundant "user_creatable = false" flags from the downstream qemu-kvm-rhev code)
+
+* Fri Oct 13 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-2.el7
+- kvm-vhost-Release-memory-references-on-cleanup.patch [bz#1489670]
+- kvm-configure-Allow-enable-seccomp-on-s390x-too.patch [bz#1491647]
+- kvm-redhat-qemu-kvm.spec.template-Enable-seccomp-on-s390.patch [bz#1491647]
+- kvm-hw-ppc-spapr_drc.c-change-spapr_drc_needed-to-use-dr.patch [bz#1448344]
+- kvm-hw-ppc-clear-pending_events-on-machine-reset.patch [bz#1448344]
+- kvm-hw-ppc-CAS-reset-on-early-device-hotplug.patch [bz#1448344]
+- kvm-spapr-fix-CAS-generated-reset.patch [bz#1448344]
+- kvm-redhat-Remove-qemu.binfmt-from-the-downstream-reposi.patch [bz#1498122]
+- kvm-redhat-fix-HW_COMPAT_RHEL7_3.patch [bz#1498754]
+- kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch [bz#1486643]
+- kvm-s390x-ais-for-2.10-stable-disable-ais-facility.patch [bz#1494548]
+- kvm-s390x-cpumodel-remove-ais-from-z14-default-model-als.patch [bz#1494548]
+- kvm-PPC-KVM-Support-machine-option-to-set-VSMT-mode.patch [bz#1479178]
+- kvm-nbd-client-avoid-read_reply_co-entry-if-send-failed.patch [bz#1482478]
+- kvm-qemu-iotests-improve-nbd-fault-injector.py-startup-p.patch [bz#1482478]
+- kvm-qemu-iotests-test-NBD-over-UNIX-domain-sockets-in-08.patch [bz#1482478]
+- kvm-block-nbd-client-nbd_co_send_request-fix-return-code.patch [bz#1482478]
+- kvm-usb-drop-HOST_USB.patch [bz#1492033]
+- kvm-usb-only-build-usb-host-with-CONFIG_USB-y.patch [bz#1492033]
+- kvm-usb-fix-libusb-config-variable-name.patch [bz#1492033]
+- kvm-usb-fix-host-stub.c-build-race.patch [bz#1492033]
+- kvm-s390x-s390-stattrib-Mark-the-storage-attribute-as-no.patch [bz#1492033]
+- kvm-s390x-s390-skeys-Mark-the-storage-key-devices-with-u.patch [bz#1492033]
+- kvm-watchdog-wdt_diag288-Mark-diag288-watchdog-as-non-ho.patch [bz#1492033]
+- kvm-s390x-ipl-The-s390-ipl-device-is-not-hot-pluggable.patch [bz#1492033]
+- kvm-hw-s390x-Mark-the-sclpquiesce-device-with-user_creat.patch [bz#1492033]
+- kvm-s390x-sclp-mark-sclp-cpu-hotplug-as-non-usercreatabl.patch [bz#1492033]
+- kvm-s390x-sclp-Mark-the-sclp-device-with-user_creatable-.patch [bz#1492033]
+- kvm-RHEL-Disable-vfio-ccw-and-x-terminal3270-devices.patch [bz#1492033]
+- kvm-s390x-css-fix-css-migration-compat-handling.patch [bz#1473292]
+- kvm-RHEL-Add-RHEL7-machine-type-for-qemu-on-s390x.patch [bz#1473292]
+- kvm-hw-nvram-spapr_nvram-Device-can-not-be-created-by-th.patch [bz#1490869]
+- kvm-vl-exit-if-maxcpus-is-negative.patch [bz#1491743]
+- kvm-Disable-build-of-qemu-kvm-ma-for-x86_64.patch [bz#1501230]
+- Resolves: bz#1448344
+  (Failed to hot unplug cpu core which hotplugged in early boot stages)
+- Resolves: bz#1473292
+  (Need RHEL-specific machine types for qemu-kvm on s390x)
+- Resolves: bz#1479178
+  (QEMU does not yet have support for setting the virtual SMT mode on Power 9, which is required to run with KVM and more than one thread per core.)
+- Resolves: bz#1482478
+  (Fail to quit source qemu when do live migration after mirroring guest to NBD server)
+- Resolves: bz#1486643
+  (CVE-2017-13672 qemu-kvm-rhev: Qemu: vga: OOB read access during display update [rhel-7.5])
+- Resolves: bz#1489670
+  (Hot-unplugging a vhost network device leaks references to VFIOPCIDevice's)
+- Resolves: bz#1490869
+  ([Pegas1.0] qemu device spapr-nvram crashes with SIGABRT (qemu-kvm))
+- Resolves: bz#1491647
+  ([RFE] Enable seccomp (sandbox) support in QEMU for s390x)
+- Resolves: bz#1491743
+  (qemu crashes with 'Abort' when a negative number is used for 'maxcpus' argument (qemu-kvm))
+- Resolves: bz#1492033
+  (Disable unwanted device in QEMU for s390x)
+- Resolves: bz#1494548
+  (Disable ais facility on s390x)
+- Resolves: bz#1498122
+  (Remove superfluous file qemu.binfmt from the qemu-kvm-rhev package)
+- Resolves: bz#1498754
+  (Definition of HW_COMPAT_RHEL7_3 is not correct)
+- Resolves: bz#1501230
+  (Disable x86_64 build for qemu-kvm-ma)
+
+* Fri Sep 29 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.10.0-1.el7
+- Rebase to 2.10.0 [bz#1470749]
+- Resolves: bz#1470749
+  (Rebase qemu-kvm-rhev for RHEL-7.5)
+
+* Thu Sep 21 2017 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.9.0-23.el7a
+- kvm-vfio-spapr-Fix-levels-calculation.patch [bz#1491749]
+- Resolves: bz#1491749
+  (Pegas1.0 - Guest crashes during boot with VF Pass-through and 129GB memory (qemu-kvm))
+
+* Tue Aug 29 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-22.el7a
+- kvm-qemu-kvm.spec-Configure-vm.allocate_pgste-for-s390x.patch [bz#1454281]
+- Resolves: bz#1454281
+  (Enable vm.allocate_pgste sysctl before running qemu-kvm on s390x)
+
+* Tue Aug 15 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-21.el7a
+- kvm-target-ppc-Implement-TIDR.patch [bz#1478822]
+- kvm-target-ppc-Add-stub-implementation-of-the-PSSCR.patch [bz#1478822]
+- kvm-target-ppc-Fix-size-of-struct-PPCElfPrstatus.patch [bz#1480418]
+- Resolves: bz#1478822
+  (The KVM guest SPRs TIDR (144) and PSSCR (823) are  currently not migrated right on POWER9)
+- Resolves: bz#1480418
+  ([guest memory dump] Dump guest's memory to file and GDB fails to process the core file)
+
+* Tue Aug 08 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-20.el7a
+- kvm-Downstream-Update-pseries-machine-types-for-RHEL-ALT.patch [bz#1473518]
+- kvm-cpu-don-t-allow-negative-core-id.patch [bz#1476181]
+- kvm-pegas-add-disable-vhost-user.patch [bz#1455269]
+- kvm-pegas-add-rpm-spec-options-for-vhost-user.patch [bz#1455269]
+- Resolves: bz#1455269
+  ([Pegas 1.0] qemu-kvm differentiation patches for Power9 - vhost-user)
+- Resolves: bz#1473518
+  (Need to remove (or not?) pseries-rhel7.2.0, pseries-rhel7.3.0 machine types for RHEL-ALT qemu-kvm)
+- Resolves: bz#1476181
+  (qemu core dumped  after hotplug one cpu core with a negative core id)
+
+* Tue Aug 01 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-19.el7a
+- kvm-AArch64-remove-mach-virt-7.3-machine-type.patch [bz#1473548]
+- kvm-nbd-strict-nbd_wr_syncv.patch [bz#1473638]
+- kvm-nbd-read_sync-and-friends-return-0-on-success.patch [bz#1473638]
+- kvm-nbd-make-nbd_drop-public.patch [bz#1473638]
+- kvm-nbd-server-get-rid-of-nbd_negotiate_read-and-friends.patch [bz#1473638]
+- kvm-spapr-htab-fix-savevm.patch [bz#1470035]
+- kvm-migration-rdma-Fix-race-on-source.patch [bz#1475751]
+- kvm-migration-rdma-fix-qemu_rdma_block_for_wrid-error-pa.patch [bz#1475751]
+- kvm-migration-rdma-Allow-cancelling-while-waiting-for-wr.patch [bz#1475751]
+- kvm-migration-rdma-Safely-convert-control-types.patch [bz#1475751]
+- kvm-migration-rdma-Send-error-during-cancelling.patch [bz#1475751]
+- kvm-configure-allow-to-disable-VT-d-emulation.patch [bz#1465450]
+- kvm-Disable-VT-d-for-rhel-builds.patch [bz#1465450]
+- kvm-RHEL-Diff.-Add-option-in-configure-to-disable-live-b.patch [bz#1418532]
+- kvm-RHEL-Diff.-Unregister-live-block-operations.patch [bz#1418532]
+- kvm-RHEL-Diff.-Disable-live-block-operations-in-HMP-moni.patch [bz#1418532]
+- kvm-RHEL-Diff.-Add-rpm-spec-options-for-live-block-ops.patch [bz#1418532]
+- Resolves: bz#1418532
+  ([Pegas 1.0] qemu-kvm differentiation patches for Power9 - block)
+- Resolves: bz#1465450
+  ([Pegas 1.0] qemu-kvm differentiation - vIOMMU)
+- Resolves: bz#1470035
+  ([qmp] Load internal snapshot failed on Power9)
+- Resolves: bz#1473548
+  (AArch64: remove 7.3 machine type)
+- Resolves: bz#1473638
+  (CVE-2017-7539 qemu-kvm-rhev: Qemu: qemu-nbd crashes due to undefined I/O coroutine [rhel-alt-7.4])
+- Resolves: bz#1475751
+  (migration/RDMA: backport fixes)
+
+* Tue Jul 18 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-18.el7a
+- kvm-ppc-kvm-have-the-family-CPU-alias-to-point-to-TYPE_H.patch [bz#1460908]
+- kvm-Disable-virtio-pci-for-s390x-builds.patch [bz#1469000]
+- kvm-target-ppc-Implement-ISA-V3.00-radix-page-fault-hand.patch [bz#1470558]
+- kvm-target-ppc-Fix-return-value-in-tcg-radix-mmu-fault-h.patch [bz#1470558]
+- kvm-target-ppc-Refactor-tcg-radix-mmu-code.patch [bz#1470558]
+- kvm-target-ppc-Add-debug-function-for-radix-mmu-translat.patch [bz#1470558]
+- Resolves: bz#1460908
+  (qemu-kvm: POWER9 CPU model not usable on POWER9 machine)
+- Resolves: bz#1469000
+  (Disable virtio-pci devices in qemu-kvm on s390x)
+- Resolves: bz#1470558
+  ([qmp] qemu-kvm process aborted after issuing QMP 'memsave' command on Power9)
+
+* Tue Jul 11 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-17.el7a
+- kvm-spapr-Consolidate-HPT-freeing-code-into-a-routine.patch [bz#1456287]
+- kvm-spapr-Add-a-no-HPT-encoding-to-HTAB-migration-stream.patch [bz#1456287]
+- kvm-spapr-Fix-migration-of-Radix-guests.patch [bz#1456287]
+- kvm-qemu-nbd-Ignore-SIGPIPE.patch [bz#1469463]
+- Resolves: bz#1456287
+  ([Pegas1.0 EA2] [qemu-kvm-rhev-2.9] After 'virsh managedsave', domain not starting)
+- Resolves: bz#1469463
+  (CVE-2017-10664 qemu-kvm: Qemu: qemu-nbd: server breaks with SIGPIPE upon client abort [rhel-7.4-Alt])
+
+* Tue Jul 04 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-16.el7a
+- kvm-AArch64-Add-pci-testdev.patch [bz#1465048]
+- Resolves: bz#1465048
+  (AArch64: Add pci-testdev)
+
+* Tue Jun 27 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-15.el7a
+- kvm-hw-ppc-spapr-Adjust-firmware-name-for-PCI-bridges.patch [bz#1459170]
+- Resolves: bz#1459170
+  (SLOF: Can't boot from virtio-scsi disk behind pci-bridge: E3405: No such device)
+
+* Fri Jun 23 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-14.el7
+- kvm-sockets-ensure-we-can-bind-to-both-ipv4-ipv6-separat.patch [bz#1446003]
+- Resolves: bz#1446003
+  (vnc cannot find a free port to use)
+
+* Tue Jun 20 2017 Miroslav Rezanina <mrezanin@redhat.com> - 2.9.0-13.el7
+- kvm-linux-headers-update.patch [bz#1462061]
+- kvm-all-Pass-an-error-object-to-kvm_device_access.patch [bz#1462061]
+- kvm-hw-intc-arm_gicv3_its-Implement-state-save-restore.patch [bz#1462061]
+- kvm-hw-intc-arm_gicv3_kvm-Implement-pending-table-save.patch [bz#1462061]
+- kvm-hw-intc-arm_gicv3_its-Allow-save-restore.patch [bz#1462061]
+- Resolves: bz#1462061
+  (Backport QEMU ITS migration series)
+
+* Tue Jun 20 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-12.el7
+- kvm-pseries-Correct-panic-behaviour-for-pseries-machine-.patch [bz#1458705]
+- kvm-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch [bz#1378816]
+- kvm-block-rbd-enable-filename-option-and-parsing.patch [bz#1457088]
+- kvm-block-iscsi-enable-filename-option-and-parsing.patch [bz#1457088]
+- kvm-nbd-fix-NBD-over-TLS-bz1461827.patch [bz#1461827]
+- kvm-monitor-add-handle_hmp_command-trace-event.patch [bz#1457740]
+- kvm-monitor-resurrect-handle_qmp_command-trace-event.patch [bz#1457740]
+- kvm-hw-pcie-fix-the-generic-pcie-root-port-to-support-mi.patch [bz#1455150]
+- Resolves: bz#1378816
+  (Core dump when use "data-plane" and execute change cd)
+- Resolves: bz#1455150
+  (Unable to detach virtio disk from pcie-root-port after migration)
+- Resolves: bz#1457088
+  (rbd/iscsi: json: pseudo-protocol format is incompatible with 7.3)
+- Resolves: bz#1457740
+  ([Tracing] compling qemu-kvm failed through systemtap)
+- Resolves: bz#1458705
+  (pvdump: QMP reports "GUEST_PANICKED" event but HMP still shows VM running after guest crashed)
+- Resolves: bz#1461827
+  (QEMU hangs in aio wait when trying to access NBD volume over TLS)
+
+* Fri Jun 16 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-11.el7
+- kvm-Enable-USB_CONFIG-for-aarch64.patch [bz#1460010]
+- Resolves: bz#1460010
+  (USB HID (keyboard and tablet) missing [aarch64])
+
+* Tue Jun 13 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-10.el7
+- kvm-Revert-Change-net-socket.c-to-use-socket_-functions-.patch [bz#1451629]
+- kvm-nbd-Fully-initialize-client-in-case-of-failed-negoti.patch [bz#1447948]
+- kvm-nbd-Fix-regression-on-resiliency-to-port-scan.patch [bz#1447948]
+- kvm-nbd-make-it-thread-safe-fix-qcow2-over-nbd.patch [bz#1454582]
+- kvm-commit-Fix-use-after-free-in-completion.patch [bz#1452048]
+- kvm-qemu-iotests-Test-automatic-commit-job-cancel-on-hot.patch [bz#1452048]
+- kvm-commit-Fix-completion-with-extra-reference.patch [bz#1453169]
+- kvm-qemu-iotests-Allow-starting-new-qemu-after-cleanup.patch [bz#1453169]
+- kvm-qemu-iotests-Test-exiting-qemu-with-running-job.patch [bz#1453169]
+- kvm-virtio-serial-fix-segfault-on-disconnect.patch [bz#1447257]
+- kvm-block-fix-external-snapshot-abort-permission-error.patch [bz#1447184]
+- kvm-xhci-only-update-dequeue-ptr-on-completed-transfers.patch [bz#1451631]
+- kvm-virtio-scsi-Unset-hotplug-handler-when-unrealize.patch [bz#1449031]
+- Resolves: bz#1447184
+  (qemu abort when live snapshot for multiple block device simultaneously with transaction and one is to a non-exist path)
+- Resolves: bz#1447257
+  (QEMU coredump while doing hexdump test onto virtio serial ports)
+- Resolves: bz#1447948
+  (qemu-nbd segment fault when nmap sweeps its port [rhel-7.4])
+- Resolves: bz#1449031
+  (qemu core dump when hot-unplug/hot-plug scsi controller in turns)
+- Resolves: bz#1451629
+  (TCP tunnel network: the guest with interface type=client can not start)
+- Resolves: bz#1451631
+  (Keyboard does not work after migration)
+- Resolves: bz#1452048
+  (qemu abort when hot unplug block device during live commit)
+- Resolves: bz#1453169
+  (qemu aborts if quit during live commit process)
+- Resolves: bz#1454582
+  (Qemu crashes when start guest with qcow2 nbd image)
+
+* Thu Jun 08 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-9.el7
+- kvm-shutdown-Simplify-shutdown_signal.patch [bz#1418927]
+- kvm-shutdown-Prepare-for-use-of-an-enum-in-reset-shutdow.patch [bz#1418927]
+- kvm-shutdown-Preserve-shutdown-cause-through-replay.patch [bz#1418927]
+- kvm-shutdown-Add-source-information-to-SHUTDOWN-and-RESE.patch [bz#1418927]
+- kvm-shutdown-Expose-bool-cause-in-SHUTDOWN-and-RESET-eve.patch [bz#1418927]
+- kvm-irqchip-trace-changes-on-msi-add-remove.patch [bz#1448813]
+- kvm-msix-trace-control-bit-write-op.patch [bz#1448813]
+- kvm-irqchip-skip-update-msi-when-disabled.patch [bz#1448813]
+- kvm-vhost-propagate-errors-in-vhost_device_iotlb_miss.patch [bz#1451862]
+- kvm-vhost-rework-IOTLB-messaging.patch [bz#1451862]
+- kvm-vhost-user-add-vhost_user-to-hold-the-chr.patch [bz#1451862]
+- kvm-vhost-user-add-slave-req-fd-support.patch [bz#1451862]
+- kvm-spec-vhost-user-spec-Add-IOMMU-support.patch [bz#1451862]
+- kvm-pc-Use-min-x-level-on-compat_props-on-RHEL-machine-t.patch [bz#1454641]
+- kvm-usb-don-t-wakeup-during-coldplug.patch [bz#1452512]
+- kvm-ehci-fix-overflow-in-frame-timer-code.patch [bz#1449609]
+- kvm-ehci-fix-frame-timer-invocation.patch [bz#1449609]
+- Resolves: bz#1418927
+  (The lifecycle event for Guest OS Shutdown is not distinguishable from a qemu process that was quit with SIG_TERM)
+- Resolves: bz#1448813
+  (qemu crash when shutdown guest with '-device intel-iommu' and '-device vfio-pci')
+- Resolves: bz#1449609
+  (qemu coredump when dd on multiple usb-storage devices concurrently in guest)
+- Resolves: bz#1451862
+  (IOMMU support in QEMU for Vhost-user backend)
+- Resolves: bz#1452512
+  (qemu coredump when add more than 12 usb-storage devices to ehci)
+- Resolves: bz#1454641
+  (Windows 10 BSOD when using rhel6.4.0/rhel6.5.0/rhel6.6.0)
+
+* Tue Jun 06 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-8.el7
+- kvm-input-don-t-queue-delay-if-paused.patch [bz#1444326]
+- kvm-block-gluster-glfs_lseek-workaround.patch [bz#1451191]
+- kvm-mirror-Drop-permissions-on-s-target-on-completion.patch [bz#1456456]
+- kvm-stream-fix-crash-in-stream_start-when-block_job_crea.patch [bz#1456424]
+- kvm-qemu-iotests-Test-streaming-with-missing-job-ID.patch [bz#1456424]
+- kvm-monitor-Use-numa_get_node_for_cpu-on-info-numa.patch [bz#1274567]
+- kvm-virtio_net-Bypass-backends-for-MTU-feature-negotiati.patch [bz#1452756]
+- kvm-vhost-user-pass-message-as-a-pointer-to-process_mess.patch [bz#1447592]
+- kvm-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch [bz#1458782]
+- kvm-gluster-add-support-for-PREALLOC_MODE_FALLOC.patch [bz#1450759]
+- kvm-numa-Allow-setting-NUMA-distance-for-different-NUMA-.patch [bz#1395339]
+- kvm-tests-acpi-extend-cphp-and-memhp-testcase-with-numa-.patch [bz#1395339]
+- kvm-copy-SLIT-test-reference-blobs-into-tests-directory.patch [bz#1395339]
+- Resolves: bz#1274567
+  (HMP doesn't reflect the correct numa topology after hot plugging vCPU)
+- Resolves: bz#1395339
+  ([Intel 7.4 FEAT] Enable configuration of NUMA distance in QEMU)
+- Resolves: bz#1444326
+  (Keyboard inputs are buffered when qemu in stop status)
+- Resolves: bz#1447592
+  (vhost-user/reply-ack: Wait for ack even if no request sent (one-time requests))
+- Resolves: bz#1450759
+  (Creating fallocated image using qemu-img using gfapi fails)
+- Resolves: bz#1451191
+  (qemu-img: block/gluster.c:1307: find_allocation: Assertion `offs >= start' failed.)
+- Resolves: bz#1452756
+  (Enable VIRTIO_NET_F_MTU feature in QEMU)
+- Resolves: bz#1456424
+  (qemu crash when starting image streaming job fails)
+- Resolves: bz#1456456
+  (qemu crashes on job completion during drain)
+- Resolves: bz#1458782
+  (QEMU crashes after hot-unplugging virtio-serial device)
+
+* Tue May 30 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-7.el7
+- kvm-e1000e-Fix-ICR-Other-causes-clear-logic.patch [bz#1449490]
+- kvm-pc-fwcfg-unbreak-migration-from-qemu-2.5-and-qemu-2..patch [bz#1441394]
+- kvm-disable-linuxboot_dma.bin-option-rom-for-7.3-machine.patch [bz#1441394]
+- kvm-Revert-hw-pci-disable-pci-bridge-s-shpc-by-default.patch [bz#1434706]
+- kvm-qemu-img-wait-for-convert-coroutines-to-complete.patch [bz#1451849]
+- kvm-target-ppc-Show-POWER9-in-cpu-help.patch
+- Resolves: bz#1434706
+  ([pci-bridge] Hotplug devices to pci-bridge failed)
+- Resolves: bz#1441394
+  (fw_cfg.dma_enabled value incorrect in pc-i440fx-7.3.0 compat_props)
+- Resolves: bz#1449490
+  ([q35] guest hang after do migration with virtio-scsi-pci.)
+- Resolves: bz#1451849
+  (qemu-img convert crashes on error)
+- Resolves: bz#1449969
+  ([Pegas1.0] POWER9* cpu model is not listed in  /usr/libexec/qemu-kvm -cpu ?)
+
+
+* Tue May 23 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-6.el7
+- kvm-aarch64-Enable-usb-xhci.patch [bz#1446570]
+- kvm-scsi-Disable-deprecated-implicit-SCSI-HBA-creation-m.patch [bz#971799]
+- kvm-block-vhdx-Make-vhdx_create-always-set-errp.patch [bz#1447551]
+- kvm-block-Add-errp-to-b-lk-drv-_truncate.patch [bz#1447551]
+- kvm-blockdev-use-drained_begin-end-for-qmp_block_resize.patch [bz#1447551]
+- kvm-spapr-Don-t-accidentally-advertise-HTM-support-on-PO.patch [bz#1449007]
+- kvm-target-ppc-Allow-workarounds-for-POWER9-DD1.patch [bz#1443289]
+- kvm-xhci-relax-link-check.patch [bz#1444003]
+- kvm-curl-strengthen-assertion-in-curl_clean_state.patch [bz#1437393]
+- kvm-curl-never-invoke-callbacks-with-s-mutex-held.patch [bz#1437393]
+- kvm-curl-avoid-recursive-locking-of-BDRVCURLState-mutex.patch [bz#1437393]
+- kvm-curl-split-curl_find_state-curl_init_state.patch [bz#1437393]
+- kvm-curl-convert-CURLAIOCB-to-byte-values.patch [bz#1437393]
+- kvm-curl-convert-readv-to-coroutines.patch [bz#1437393]
+- kvm-curl-do-not-do-aio_poll-when-waiting-for-a-free-CURL.patch [bz#1437393]
+- kvm-usb-hub-clear-PORT_STAT_SUSPEND-on-wakeup.patch [bz#1447581]
+- kvm-migration-setup-bi-directional-I-O-channel-for-exec-.patch [bz#1430620]
+- kvm-block-Reuse-bs-as-backing-hd-for-drive-backup-sync-n.patch [bz#1452066]
+- kvm-migration-Fix-non-multiple-of-page-size-migration.patch [bz#1449037]
+- kvm-postcopy-Require-RAMBlocks-that-are-whole-pages.patch [bz#1449037]
+- kvm-hw-virtio-fix-vhost-user-fails-to-startup-when-MQ.patch [bz#1447592]
+- kvm-iommu-Don-t-crash-if-machine-is-not-PC_MACHINE.patch [bz#1451483]
+- kvm-migration-Call-blk_resume_after_migration-for-postco.patch [bz#1452148]
+- kvm-migration-Unify-block-node-activation-error-handling.patch [bz#1452148]
+- kvm-disable-pulseaudio-and-alsa.patch [bz#1452605]
+- kvm-block-An-empty-filename-counts-as-no-filename.patch [bz#1452702]
+- kvm-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch [bz#1452752]
+- Resolves: bz#1430620
+  (TLS encryption migration via exec failed with "TLS handshake failed: The TLS connection was non-properly terminated")
+- Resolves: bz#1437393
+  (snapshot created base on the image in https server will hang during booting)
+- Resolves: bz#1443289
+  ([Pegas1.0 04/03 nightly build + 4.10.0-7 kernel] qemu+guest fail to apply POWER9 DD1 workarounds)
+- Resolves: bz#1444003
+  (USB 3.0 flash drive not accessible on Windows guest)
+- Resolves: bz#1446570
+  (enable qemu-xhci USB3 controller device model for the aarch64 target)
+- Resolves: bz#1447551
+  (qemu hang when do block_resize guest disk during crystal running)
+- Resolves: bz#1447581
+  ([RHEV7.4] [usb-hub] input devices under usb hub don't work on win2016 with xhci)
+- Resolves: bz#1447592
+  (vhost-user/reply-ack: Wait for ack even if no request sent (one-time requests))
+- Resolves: bz#1449007
+  (Pegas 1.0: Booting pegas guest on pegas host (POWER9 DD1) panics with signal 4 at userspace entry)
+- Resolves: bz#1449037
+  (Dst qemu quit when migrate guest with hugepage and total memory is not a multiple of pagesize)
+- Resolves: bz#1451483
+  (QEMU crashes with "-machine none -device intel-iommu")
+- Resolves: bz#1452066
+  (Fix backing image referencing in drive-backup sync=none)
+- Resolves: bz#1452148
+  (Op blockers don't work after postcopy migration)
+- Resolves: bz#1452605
+  (disable pulseaudio and alsa support)
+- Resolves: bz#1452702
+  (qemu-img aborts on empty filenames)
+- Resolves: bz#1452752
+  (Some block drivers incorrectly close their associated file)
+- Resolves: bz#971799
+  (qemu should not crash when if=scsi although it's unsupportable device)
+
+* Tue May 16 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-5.el7
+- kvm-blockdev-ignore-aio-native-for-empty-drives.patch [bz#1402645]
+- kvm-dump-Acquire-BQL-around-vm_start-in-dump-thread.patch [bz#1445174]
+- kvm-Downstream-Don-t-disable-SMT-on-POWER9-hosts.patch [bz#1450724]
+- kvm-aio-add-missing-aio_notify-to-aio_enable_external.patch [bz#1446498]
+- kvm-Update-configuration-for-qemu-2.9.patch [bz#1400962]
+- Resolves: bz#1400962
+  (Verify configuration coverage for rebased qemu-kvm-rhev)
+- Resolves: bz#1402645
+  (Required cache.direct=on when set aio=native)
+- Resolves: bz#1445174
+  ([RHEV7.4] [guest memory dump]dump-guest-memory QMP command with "detach" param makes qemu-kvm process aborted)
+- Resolves: bz#1446498
+  (Guest freeze after live snapshot with data-plane)
+- Resolves: bz#1450724
+  ([Pegas 1.0] qemu package scripts should not disable host multi-threading for POWER9)
+
+* Fri May 12 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-4.el7
+- kvm-Reenable-Educational-device.patch [bz#1414694]
+- kvm-usb-xhci-Fix-PCI-capability-order.patch [bz#1447874]
+- kvm-block-vxhs.c-Add-support-for-a-new-block-device-type.patch [bz#1265869]
+- kvm-block-vxhs.c-Add-qemu-iotests-for-new-block-device-t.patch [bz#1265869]
+- kvm-qemu-iotests-exclude-vxhs-from-image-creation-via-pr.patch [bz#1265869]
+- kvm-block-vxhs-modularize-VXHS-via-g_module.patch [bz#1265869]
+- kvm-Remove-the-dependencies-to-seavgabios-bin-and-ipxe-r.patch [bz#1449939]
+- Resolves: bz#1265869
+  (RFE: Veritas HyperScale VxHS block device support (qemu-kvm-rhev))
+- Resolves: bz#1414694
+  (Reenable edu device for kvm-unit-tests support)
+- Resolves: bz#1447874
+  (Migration failed from rhel7.2.z->rhel7.4 with "-M rhel7.0.0" and "-device nec-usb-xhci")
+- Resolves: bz#1449939
+  (Remove dependency on seavgabios-bin and ipxe-roms-qemu for qemu-kvm-rhev on s390x)
+
+* Fri May 05 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-3.el7
+- kvm-x86-machine-compat-2.9-stragglers.patch [bz#1435756]
+- kvm-block-add-bdrv_set_read_only-helper-function.patch [bz#1189998]
+- kvm-block-do-not-set-BDS-read_only-if-copy_on_read-enabl.patch [bz#1189998]
+- kvm-block-honor-BDRV_O_ALLOW_RDWR-when-clearing-bs-read_.patch [bz#1189998]
+- kvm-block-code-movement.patch [bz#1189998]
+- kvm-block-introduce-bdrv_can_set_read_only.patch [bz#1189998]
+- kvm-block-use-bdrv_can_set_read_only-during-reopen.patch [bz#1189998]
+- kvm-block-rbd-update-variable-names-to-more-apt-names.patch [bz#1189998]
+- kvm-block-rbd-Add-support-for-reopen.patch [bz#1189998]
+- kvm-replication-Make-disable-replication-compile-again.patch [bz#1422846]
+- kvm-Disable-replication-feature.patch [bz#1422846]
+- Resolves: bz#1189998
+  (Active commit does not support on rbd based disk)
+- Resolves: bz#1422846
+  (Disable replication feature)
+- Resolves: bz#1435756
+  (Backport device/machtype compat settings from v2.8.0..v2.9.0 final)
+
+* Fri Apr 28 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-2.el7
+- kvm-Disable-unimplemented-device.patch [bz#1443029]
+- kvm-Disable-serial-isa-for-ppc64.patch [bz#1443029]
+- kvm-Disable-rs6000-mc-device.patch [bz#1443029]
+- kvm-ppc64le-Remove-isabus-bridge-device.patch [bz#1443029]
+- kvm-hmp-gpa2hva-and-gpa2hpa-hostaddr-command.patch [bz#1432295]
+- kvm-memory-add-section-range-info-for-IOMMU-notifier.patch [bz#1335808]
+- kvm-memory-provide-IOMMU_NOTIFIER_FOREACH-macro.patch [bz#1335808]
+- kvm-memory-provide-iommu_replay_all.patch [bz#1335808]
+- kvm-memory-introduce-memory_region_notify_one.patch [bz#1335808]
+- kvm-memory-add-MemoryRegionIOMMUOps.replay-callback.patch [bz#1335808]
+- kvm-intel_iommu-use-the-correct-memory-region-for-device.patch [bz#1335808]
+- kvm-intel_iommu-provide-its-own-replay-callback.patch [bz#1335808]
+- kvm-intel_iommu-allow-dynamic-switch-of-IOMMU-region.patch [bz#1335808]
+- kvm-intel_iommu-enable-remote-IOTLB.patch [bz#1335808]
+- kvm-virtio-rng-stop-virtqueue-while-the-CPU-is-stopped.patch [bz#1435521]
+- kvm-target-ppc-kvm-make-use-of-KVM_CREATE_SPAPR_TCE_64.patch [bz#1440619]
+- kvm-spapr-Add-ibm-processor-radix-AP-encodings-to-the-de.patch [bz#1368786]
+- kvm-target-ppc-support-KVM_CAP_PPC_MMU_RADIX-KVM_CAP_PPC.patch [bz#1368786]
+- kvm-target-ppc-Add-new-H-CALL-shells-for-in-memory-table.patch [bz#1368786]
+- kvm-target-ppc-Implement-H_REGISTER_PROCESS_TABLE-H_CALL.patch [bz#1368786]
+- kvm-spapr-move-spapr_populate_pa_features.patch [bz#1368786]
+- kvm-spapr-Enable-ISA-3.0-MMU-mode-selection-via-CAS.patch [bz#1368786]
+- kvm-spapr-Workaround-for-broken-radix-guests.patch [bz#1368786]
+- Resolves: bz#1335808
+  ([RFE] [vIOMMU] Add Support for VFIO devices with vIOMMU present)
+- Resolves: bz#1368786
+  ([Pegas1.0 FEAT] POWER9 guest - qemu - base enablement)
+- Resolves: bz#1432295
+  (Add gpa2hpa command to qemu hmp)
+- Resolves: bz#1435521
+  (Migration failed with postcopy enabled from rhel7.3.z host to rhel7.4 host "error while loading state for instance 0x0 of device 'pci)
+- Resolves: bz#1440619
+  (Reboot guest will induce error message - KVM: Failed to create TCE table for liobn 0x80000001)
+- Resolves: bz#1443029
+  (Disable new devices in qemu 2.9)
+
+* Fri Apr 21 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.9.0-1.el7
+- Rebase to QEMU 2.9.0
+
+* Wed Mar 08 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.8.0-6.el7
+- kvm-virtio-Report-real-progress-in-VQ-aio-poll-handler.patch [bz#1425700]
+- kvm-intel-hda-fix-rhel6-compat-property.patch [bz#1425765]
+- Resolves: bz#1425700
+  (virtio-scsi data plane takes 100% host CPU with polling)
+- Resolves: bz#1425765
+  (The guest failed to start with ich6 sound when machine type is rhel6.*.0)
+
+* Mon Feb 20 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.8.0-5.el7
+- kvm-Disable-qemu-register-device.patch [bz#1392328]
+- kvm-Disable-vfio-pci-igd-lpc-bridge-device.patch [bz#1392328]
+- kvm-Disable-new-virtio-crypto-devices.patch [bz#1392328]
+- kvm-Disable-amd-iommu-devices.patch [bz#1392328]
+- kvm-Disable-loader-device.patch [bz#1392328]
+- kvm-Disable-or-irq-device.patch [bz#1392328]
+- kvm-Hide-new-floppy-device.patch [bz#1392328]
+- kvm-migcompat-e1000e-Work-around-7.3-msi-intr_state-fiel.patch [bz#1420216]
+- kvm-migcompat-rtl8139-Work-around-version-bump.patch [bz#1420195]
+- kvm-sync-linux-headers.patch [bz#1391942]
+- kvm-kvmclock-reduce-kvmclock-difference-on-migration.patch [bz#1391942]
+- kvm-ahci-advertise-HOST_CAP_64.patch [bz#1411105]
+- kvm-Disable-devices-for-for-AArch64-QEMU.patch [bz#1422349]
+- kvm-hw-arm-virt-Disable-virtio-net-pci-option-ROM-file-l.patch [bz#1337510]
+- kvm-vfio-Use-error_setg-when-reporting-max-assigned-devi.patch [bz#1369795]
+- kvm-cirrus-fix-patterncopy-checks.patch [bz#1420494]
+- kvm-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch [bz#1420494]
+- kvm-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch [bz#1420494]
+- kvm-Package-man-page-of-kvm_stat-tool.patch [bz#1417840]
+- kvm-Update-configuration-for-2.8.0-release.patch [bz#1400962]
+- Resolves: bz#1337510
+  (Don't try to use a romfile for virtio-net-pci on aarch64)
+- Resolves: bz#1369795
+  (QMP should prompt more specific information when hotplug more than 32 vfs to guest)
+- Resolves: bz#1391942
+  (kvmclock: advance clock by time window between vm_stop and pre_save (backport patch))
+- Resolves: bz#1392328
+  (Disable new devices in QEMU 2.8 (x86_64))
+- Resolves: bz#1400962
+  (Verify configuration coverage for rebased qemu-kvm-rhev)
+- Resolves: bz#1411105
+  (Windows Server 2008-32 crashes on startup with q35 if cdrom attached)
+- Resolves: bz#1417840
+  (Include kvm_stat man page in qemu-kvm-tools package)
+- Resolves: bz#1420195
+  (Migration from RHEL7.4 -> RHEL7.3.z failed with rtl8139 nic card)
+- Resolves: bz#1420216
+  (Migration from RHEL7.3.z -> RHEL4 failed with e1000e nic card)
+- Resolves: bz#1420494
+  (EMBARGOED CVE-2017-2620 qemu-kvm-rhev: Qemu: display: cirrus: potential arbitrary code execution via cirrus_bitblt_cputovideo [rhel-7.4])
+- Resolves: bz#1422349
+  (Disable new devices in QEMU 2.8 (aarch64))
+
+* Fri Feb 10 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.8.0-4.el7
+- kvm-fix-abort-in-acpi_setup-since-2.8-with-rhel6-machine.patch [bz#1410826]
+- kvm-spapr-clock-should-count-only-if-vm-is-running.patch [bz#1264258]
+- kvm-display-cirrus-ignore-source-pitch-value-as-needed-i.patch [bz#1418236]
+- kvm-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch [bz#1418236]
+- kvm-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch [bz#1418236]
+- kvm-cirrus-fix-blit-address-mask-handling.patch [bz#1418236]
+- kvm-cirrus-fix-oob-access-issue-CVE-2017-2615.patch [bz#1418236]
+- kvm-QMP-Fix-forward-port-of-__com.redhat_drive_add.patch [bz#1418575]
+- kvm-QMP-Fix-forward-port-of-__com.redhat_drive_del.patch [bz#1418575]
+- kvm-Drop-macro-RFQDN_REDHAT.patch [bz#1418575]
+- kvm-HMP-Clean-up-botched-conflict-resolution-in-user-man.patch [bz#1418575]
+- kvm-HMP-Fix-user-manual-typo-of-__com.redhat_qxl_screend.patch [bz#1419899]
+- kvm-HMP-Fix-documentation-of-__com.redhat.drive_add.patch [bz#1419899]
+- kvm-aio-add-flag-to-skip-fds-to-aio_dispatch.patch [bz#1404303]
+- kvm-aio-add-AioPollFn-and-io_poll-interface.patch [bz#1404303]
+- kvm-aio-add-polling-mode-to-AioContext.patch [bz#1404303]
+- kvm-virtio-poll-virtqueues-for-new-buffers.patch [bz#1404303]
+- kvm-linux-aio-poll-ring-for-completions.patch [bz#1404303]
+- kvm-iothread-add-polling-parameters.patch [bz#1404303]
+- kvm-virtio-blk-suppress-virtqueue-kick-during-processing.patch [bz#1404303]
+- kvm-virtio-scsi-suppress-virtqueue-kick-during-processin.patch [bz#1404303]
+- kvm-aio-add-.io_poll_begin-end-callbacks.patch [bz#1404303]
+- kvm-virtio-disable-virtqueue-notifications-during-pollin.patch [bz#1404303]
+- kvm-aio-self-tune-polling-time.patch [bz#1404303]
+- kvm-iothread-add-poll-grow-and-poll-shrink-parameters.patch [bz#1404303]
+- kvm-virtio-disable-notifications-again-after-poll-succee.patch [bz#1404303]
+- kvm-aio-posix-honor-is_external-in-AioContext-polling.patch [bz#1404303]
+- kvm-iothread-enable-AioContext-polling-by-default.patch [bz#1404303]
+- kvm-Disable-usbredir-and-libcacard-for-unsupported-archi.patch [bz#1418166]
+- Resolves: bz#1264258
+  (Guest's time stops with option clock=vm when guest is paused)
+- Resolves: bz#1404303
+  (RFE: virtio-blk/scsi polling mode (QEMU))
+- Resolves: bz#1410826
+  (rhel6 machine types assert; acpi-build.c:2985: acpi_setup: Assertion `build_state->table_mr != ((void *)0)' failed)
+- Resolves: bz#1418166
+  (Remove dependencies required by spice on ppc64le)
+- Resolves: bz#1418236
+  (CVE-2017-2615 qemu-kvm-rhev: Qemu: display: cirrus: oob access while doing bitblt copy backward mode [rhel-7.4])
+- Resolves: bz#1418575
+  (Forward port of downstream-only QMP commands is incorrect)
+- Resolves: bz#1419899
+  (Documentation inaccurate for __com.redhat_qxl_screendump and __com.redhat_drive_add)
+
+* Fri Feb 03 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.8.0-3.el7
+- kvm-hw-arm-virt-remove-aarch64-rhel-machine-type.patch [bz#1390964]
+- kvm-hw-arm-virt-create-virt-rhel7.3.0-machine-type.patch [bz#1390964]
+- kvm-hw-arm-virt-create-virt-rhel7.4.0-machine-type.patch [bz#1390964]
+- kvm-tools-kvm_stat-Introduce-pid-monitoring.patch [bz#1397697]
+- kvm-tools-kvm_stat-Add-comments.patch [bz#1397697]
+- kvm-x86-Split-out-options-for-the-head-rhel7-machine-typ.patch [bz#1390737]
+- kvm-x86-Create-PC_RHEL7_3_COMPAT-definition.patch [bz#1390737]
+- kvm-x86-Define-pc-i440fx-rhel7.4.0.patch [bz#1390737]
+- kvm-x86-Define-pc-q35-rhel7.4.0.patch [bz#1390737]
+- kvm-x86-Remove-downstream-opteron-rdtscp-override.patch [bz#1390737]
+- kvm-pci-mark-ROMs-read-only.patch [bz#1404673]
+- kvm-vhost-skip-ROM-sections.patch [bz#1404673]
+- kvm-Enable-seccomp-for-ppc64-ppc64le-architecture.patch [bz#1385537]
+- kvm-Update-qemu-kvm-package-Summary-and-Description.patch [bz#1378538]
+- Resolves: bz#1378538
+  (QEMU: update package summary and description)
+- Resolves: bz#1385537
+  ([V4.1 FEAT] Enable seccomp support in QEMU)
+- Resolves: bz#1390737
+  (RHEL-7.4 new qemu-kvm-rhev machine type (x86))
+- Resolves: bz#1390964
+  (RHEL-7.4 new QEMU machine type (AArch64))
+- Resolves: bz#1397697
+  (Backport remaining kvm_stat patches from the kernel to QEMU)
+- Resolves: bz#1404673
+  ([ppc64le]qemu-kvm-rhev-2.8  upstream package, reset vm when do migration, HMP in src host promp "tcmalloc: large alloc 1073872896 bytes...")
+
+* Mon Jan 16 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.8.0-2.el7
+- kvm-Revert-kvm_stat-Remove.patch [bz#1389238]
+- kvm-Include-kvm_stat-in-qemu-kvm.spec.patch [bz#1389238]
+- kvm-tools-kvm_stat-Powerpc-related-fixes.patch [bz#1389238]
+- kvm-compat-define-HW_COMPAT_RHEL7_3.patch [bz#1390734]
+- kvm-spapr-define-pseries-rhel7.4.0-machine-type.patch [bz#1390734]
+- kvm-config-Remove-EHCI-from-ppc64-builds.patch [bz#1410674]
+- kvm-Fix-unuseds-Fedora-build.patch [bz#1410758]
+- Resolves: bz#1389238
+  (Re-enable kvm_stat script)
+- Resolves: bz#1390734
+  (ppc64: pseries-rhel7.4.0 machine type)
+- Resolves: bz#1410674
+  (qemu: Remove unnecessary EHCI implementation for Power)
+- Resolves: bz#1410758
+  (Make 7.4 qemu-kvm-rhev build on fedora25)
+
+* Tue Jan 10 2017 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.8.0-1.el7
+- Rebase to QEMU 2.8.0 [bz#1387600]
+- Resolves: bz#1387600
+  (Rebase qemu-kvm-rhev to 2.8.0)
+
+* Tue Sep 27 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-28.el7
+- kvm-ARM-ACPI-fix-the-AML-ID-format-for-CPU-devices.patch [bz#1373733]
+- Resolves: bz#1373733
+  (failed to run a guest VM with >= 12 vcpu under ACPI mode)
+
+* Fri Sep 23 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-27.el7
+- kvm-char-fix-waiting-for-TLS-and-telnet-connection.patch [bz#1300773]
+- kvm-target-i386-introduce-kvm_put_one_msr.patch [bz#1377920]
+- kvm-apic-set-APIC-base-as-part-of-kvm_apic_put.patch [bz#1377920]
+- Resolves: bz#1300773
+  (RFE: add support for native TLS encryption on chardev  TCP transports)
+- Resolves: bz#1377920
+  (Guest fails reboot and causes kernel-panic)
+
+* Tue Sep 20 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-26.el7
+- kvm-target-i386-Add-more-Intel-AVX-512-instructions-supp.patch [bz#1372455]
+- kvm-iothread-Stop-threads-before-main-quits.patch [bz#1343021]
+- kvm-virtio-pci-error-out-when-both-legacy-and-modern-mod.patch [bz#1370005]
+- kvm-virtio-bus-Plug-devices-after-features-are-negotiate.patch [bz#1370005]
+- kvm-virtio-pci-reduce-modern_mem_bar-size.patch [bz#1365613]
+- kvm-virtio-vga-adapt-to-page-per-vq-off.patch [bz#1365613]
+- kvm-virtio-gpu-pci-tag-as-not-hotpluggable.patch [bz#1368032]
+- kvm-scsi-disk-Cleaning-up-around-tray-open-state.patch [bz#1374251]
+- kvm-virtio-scsi-Don-t-abort-when-media-is-ejected.patch [bz#1374251]
+- kvm-io-remove-mistaken-call-to-object_ref-on-QTask.patch [bz#1375677]
+- kvm-block-Invalidate-all-children.patch [bz#1355927]
+- kvm-block-Drop-superfluous-invalidating-bs-file-from-dri.patch [bz#1355927]
+- kvm-block-Inactivate-all-children.patch [bz#1355927]
+- kvm-vfio-pci-Fix-regression-in-MSI-routing-configuration.patch [bz#1373802]
+- kvm-x86-lapic-Load-LAPIC-state-at-post_load.patch [bz#1363998]
+- kvm-blockdev-ignore-cache-options-for-empty-CDROM-drives.patch [bz#1342999]
+- kvm-block-reintroduce-bdrv_flush_all.patch [bz#1338638]
+- kvm-qemu-use-bdrv_flush_all-for-vm_stop-et-al.patch [bz#1338638]
+- Resolves: bz#1338638
+  (Migration fails after ejecting the cdrom in the guest)
+- Resolves: bz#1342999
+  ('cache=x' cannot work with empty cdrom)
+- Resolves: bz#1343021
+  (Core dump when quit from HMP after migration finished)
+- Resolves: bz#1355927
+  (qemu SIGABRT when doing inactive blockcommit with external system checkpoint snapshot)
+- Resolves: bz#1363998
+  (Live  migration via a compressed file  causes the guest desktop to freeze)
+- Resolves: bz#1365613
+  ([PCI] The default MMIO range reserved by firmware for PCI bridges is not enough to hotplug virtio-1 devices)
+- Resolves: bz#1368032
+  (kernel crash after hot remove virtio-gpu device)
+- Resolves: bz#1370005
+  (Fail to get network device info(eth0) in guest with virtio-net-pci/vhostforce)
+- Resolves: bz#1372455
+  ([Intel 7.3 Bug] SKL-SP Guest cpu doesn't support avx512 instruction sets(avx512bw, avx512dq and avx512vl)(qemu-kvm-rhev))
+- Resolves: bz#1373802
+  (Network can't recover when trigger EEH  one time)
+- Resolves: bz#1374251
+  (qemu-kvm-rhev core dumped when enabling virtio-scsi "data plane" and executing "eject")
+- Resolves: bz#1375677
+  (Crash when performing VNC websockets handshake)
+
+* Tue Sep 13 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-25.el7
+- kvm-virtio-recalculate-vq-inuse-after-migration.patch [bz#1372763]
+- kvm-virtio-decrement-vq-inuse-in-virtqueue_discard.patch [bz#1372763]
+- kvm-virtio-balloon-discard-virtqueue-element-on-reset.patch [bz#1370703]
+- kvm-virtio-zero-vq-inuse-in-virtio_reset.patch [bz#1370703 bz#1374623]
+- Resolves: bz#1370703
+  ([Balloon] Whql Job "Commom scenario stress with IO" failed on 2008-32/64)
+- Resolves: bz#1372763
+  (RHSA-2016-1756 breaks migration of instances)
+- Resolves: bz#1374623
+  (RHSA-2016-1756 breaks migration of instances)
+
+* Fri Sep 09 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-24.el7
+- kvm-Fix-configure-test-for-PBKDF2-in-nettle.patch [bz#1301019]
+- kvm-redhat-switch-from-gcrypt-to-nettle-for-crypto.patch [bz#1301019]
+- kvm-crypto-assert-that-qcrypto_hash_digest_len-is-in-ran.patch [bz#1301019]
+- kvm-crypto-fix-handling-of-iv-generator-hash-defaults.patch [bz#1301019]
+- kvm-crypto-ensure-XTS-is-only-used-with-ciphers-with-16-.patch [bz#1301019]
+- kvm-vhost-user-test-Use-libqos-instead-of-pxe-virtio.rom.patch [bz#1371211]
+- kvm-vl-Delay-initialization-of-memory-backends.patch [bz#1371211]
+- kvm-spapr-implement-H_CHANGE_LOGICAL_LAN_MAC-h_call.patch [bz#1371419]
+- Resolves: bz#1301019
+  (RFE: add support for LUKS disk encryption format driver w/ RBD, iSCSI, and qcow2)
+- Resolves: bz#1371211
+  (Qemu 2.6 won't boot guest with 2 meg hugepages)
+- Resolves: bz#1371419
+  ([ppc64le] Can't modify mac address for spapr-vlan device in rhel6.8 guest)
+
+* Tue Sep 06 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-23.el7
+- kvm-vhost-user-disconnect-on-HUP.patch [bz#1355902]
+- kvm-vhost-don-t-assume-opaque-is-a-fd-use-backend-cleanu.patch [bz#1355902]
+- kvm-vhost-make-vhost_log_put-idempotent.patch [bz#1355902]
+- kvm-vhost-assert-the-log-was-cleaned-up.patch [bz#1355902]
+- kvm-vhost-fix-cleanup-on-not-fully-initialized-device.patch [bz#1355902]
+- kvm-vhost-make-vhost_dev_cleanup-idempotent.patch [bz#1355902]
+- kvm-vhost-net-always-call-vhost_dev_cleanup-on-failure.patch [bz#1355902]
+- kvm-vhost-fix-calling-vhost_dev_cleanup-after-vhost_dev_.patch [bz#1355902]
+- kvm-vhost-do-not-assert-on-vhost_ops-failure.patch [bz#1355902]
+- kvm-vhost-add-missing-VHOST_OPS_DEBUG.patch [bz#1355902]
+- kvm-vhost-use-error_report-instead-of-fprintf-stderr.patch [bz#1355902]
+- kvm-qemu-char-fix-qemu_chr_fe_set_msgfds-crash-when-disc.patch [bz#1355902]
+- kvm-vhost-user-call-set_msgfds-unconditionally.patch [bz#1355902]
+- kvm-vhost-user-check-qemu_chr_fe_set_msgfds-return-value.patch [bz#1355902]
+- kvm-vhost-user-check-vhost_user_-read-write-return-value.patch [bz#1355902]
+- kvm-vhost-user-keep-vhost_net-after-a-disconnection.patch [bz#1355902]
+- kvm-vhost-user-add-get_vhost_net-assertions.patch [bz#1355902]
+- kvm-Revert-vhost-net-do-not-crash-if-backend-is-not-pres.patch [bz#1355902]
+- kvm-vhost-net-vhost_migration_done-is-vhost-user-specifi.patch [bz#1355902]
+- kvm-vhost-add-assert-to-check-runtime-behaviour.patch [bz#1355902]
+- kvm-char-add-chr_wait_connected-callback.patch [bz#1355902]
+- kvm-char-add-and-use-tcp_chr_wait_connected.patch [bz#1355902]
+- kvm-vhost-user-wait-until-backend-init-is-completed.patch [bz#1355902]
+- kvm-vhost-user-add-error-report-in-vhost_user_write.patch [bz#1355902]
+- kvm-vhost-add-vhost_net_set_backend.patch [bz#1355902]
+- kvm-vhost-do-not-update-last-avail-idx-on-get_vring_base.patch [bz#1355902]
+- kvm-vhost-check-for-vhost_ops-before-using.patch [bz#1355902]
+- kvm-vhost-user-Introduce-a-new-protocol-feature-REPLY_AC.patch [bz#1355902]
+- kvm-linux-aio-Handle-io_submit-failure-gracefully.patch [bz#1285928]
+- kvm-Revert-acpi-pc-add-fw_cfg-device-node-to-dsdt.patch [bz#1368153]
+- Resolves: bz#1285928
+  (linux-aio aborts on io_submit() failure)
+- Resolves: bz#1355902
+  (vhost-user reconnect misc fixes and improvements)
+- Resolves: bz#1368153
+  (Please hide fw_cfg device in windows guest in order to make svvp test pass)
+
+* Mon Aug 22 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-22.el7
+- kvm-target-i386-kvm-Report-kvm_pv_unhalt-as-unsupported-.patch [bz#1363679]
+- kvm-ioapic-keep-RO-bits-for-IOAPIC-entry.patch [bz#1358653]
+- kvm-ioapic-clear-remote-irr-bit-for-edge-triggered-inter.patch [bz#1358653]
+- kvm-x86-iommu-introduce-parent-class.patch [bz#1358653]
+- kvm-intel_iommu-rename-VTD_PCI_DEVFN_MAX-to-x86-iommu.patch [bz#1358653]
+- kvm-x86-iommu-provide-x86_iommu_get_default.patch [bz#1358653]
+- kvm-x86-iommu-introduce-intremap-property.patch [bz#1358653]
+- kvm-acpi-enable-INTR-for-DMAR-report-structure.patch [bz#1358653]
+- kvm-intel_iommu-allow-queued-invalidation-for-IR.patch [bz#1358653]
+- kvm-intel_iommu-set-IR-bit-for-ECAP-register.patch [bz#1358653]
+- kvm-acpi-add-DMAR-scope-definition-for-root-IOAPIC.patch [bz#1358653]
+- kvm-intel_iommu-define-interrupt-remap-table-addr-regist.patch [bz#1358653]
+- kvm-intel_iommu-handle-interrupt-remap-enable.patch [bz#1358653]
+- kvm-intel_iommu-define-several-structs-for-IOMMU-IR.patch [bz#1358653]
+- kvm-intel_iommu-add-IR-translation-faults-defines.patch [bz#1358653]
+- kvm-intel_iommu-Add-support-for-PCI-MSI-remap.patch [bz#1358653]
+- kvm-intel_iommu-get-rid-of-0-initializers.patch [bz#1358653]
+- kvm-q35-ioapic-add-support-for-emulated-IOAPIC-IR.patch [bz#1358653]
+- kvm-ioapic-introduce-ioapic_entry_parse-helper.patch [bz#1358653]
+- kvm-intel_iommu-add-support-for-split-irqchip.patch [bz#1358653]
+- kvm-x86-iommu-introduce-IEC-notifiers.patch [bz#1358653]
+- kvm-ioapic-register-IOMMU-IEC-notifier-for-ioapic.patch [bz#1358653]
+- kvm-intel_iommu-Add-support-for-Extended-Interrupt-Mode.patch [bz#1358653]
+- kvm-intel_iommu-add-SID-validation-for-IR.patch [bz#1358653]
+- kvm-irqchip-simplify-kvm_irqchip_add_msi_route.patch [bz#1358653]
+- kvm-irqchip-i386-add-hook-for-add-remove-virq.patch [bz#1358653]
+- kvm-irqchip-x86-add-msi-route-notify-fn.patch [bz#1358653]
+- kvm-irqchip-do-explicit-commit-when-update-irq.patch [bz#1358653]
+- kvm-intel_iommu-support-all-masks-in-interrupt-entry-cac.patch [bz#1358653]
+- kvm-all-add-trace-events-for-kvm-irqchip-ops.patch [bz#1358653]
+- kvm-intel_iommu-disallow-kernel-irqchip-on-with-IR.patch [bz#1358653]
+- kvm-intel_iommu-avoid-unnamed-fields.patch [bz#1358653]
+- kvm-irqchip-only-commit-route-when-irqchip-is-used.patch [bz#1358653]
+- kvm-x86-ioapic-ignore-level-irq-during-processing.patch [bz#1358653]
+- kvm-x86-ioapic-add-support-for-explicit-EOI.patch [bz#1358653]
+- kvm-memory-Fix-IOMMU-replay-base-address.patch [bz#1364035]
+- kvm-Add-luks-to-block-driver-whitelist.patch [bz#1301019]
+- Resolves: bz#1301019
+  (RFE: add support for LUKS disk encryption format driver w/ RBD, iSCSI, and qcow2)
+- Resolves: bz#1358653
+  ([RFE] Interrupt remapping support for Intel vIOMMUs)
+- Resolves: bz#1363679
+  (RHEL guest hangs with kernel-irqchip=off and smp>1)
+- Resolves: bz#1364035
+  ([ppc64le][VFIO]Qemu complains:vfio_dma_map(0x10033d3a980, 0x1f34f0000, 0x10000, 0x3fff9a6d0000) = -6 (No such device or address))
+
+* Tue Aug 16 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-21.el7
+- kvm-fix-qemu-exit-on-memory-hotplug-when-allocation-fail.patch [bz#1351409]
+- kvm-spapr-remove-extra-type-variable.patch [bz#1363812]
+- kvm-ppc-Introduce-a-function-to-look-up-CPU-alias-string.patch [bz#1363812]
+- kvm-hw-ppc-spapr-Look-up-CPU-alias-names-instead-of-hard.patch [bz#1363812]
+- kvm-ppc-kvm-Do-not-mess-up-the-generic-CPU-family-regist.patch [bz#1363812]
+- kvm-ppc-kvm-Register-also-a-generic-spapr-CPU-core-famil.patch [bz#1363812]
+- kvm-ppc64-fix-compressed-dump-with-pseries-kernel.patch [bz#1240497]
+- kvm-monitor-fix-crash-when-leaving-qemu-with-spice-audio.patch [bz#1355704]
+- kvm-audio-clean-up-before-monitor-clean-up.patch [bz#1355704]
+- kvm-vnc-don-t-crash-getting-server-info-if-lsock-is-NULL.patch [bz#1359655]
+- kvm-vnc-fix-crash-when-vnc_server_info_get-has-an-error.patch [bz#1359655]
+- kvm-vnc-ensure-connection-sharing-limits-is-always-confi.patch [bz#1359655]
+- kvm-vnc-make-sure-we-finish-disconnect.patch [bz#1352799]
+- kvm-virtio-net-allow-increasing-rx-queue-size.patch [bz#1358962]
+- kvm-input-add-trace-events-for-full-queues.patch [bz#1366471]
+- kvm-virtio-set-low-features-early-on-load.patch [bz#1365747]
+- kvm-Revert-virtio-net-unbreak-self-announcement-and-gues.patch [bz#1365747]
+- Resolves: bz#1240497
+  (qemu-kvm-rhev: dump-guest-memory creates invalid header with format kdump-{zlib,lzo,snappy} on ppc64)
+- Resolves: bz#1351409
+  (When hotplug memory, guest will shutdown as Insufficient free host memory pages available to allocate)
+- Resolves: bz#1352799
+  (Client information from hmp doesn't vanish after client disconnect when using vnc display)
+- Resolves: bz#1355704
+  (spice: core dump when 'quit')
+- Resolves: bz#1358962
+  (Increase the queue size to the max allowed, 1024.)
+- Resolves: bz#1359655
+  (Qemu crashes when connecting to a guest started with "-vnc none" by virt-viewer)
+- Resolves: bz#1363812
+  (qemu-kvm-rhev: -cpu POWER8 no longer works)
+- Resolves: bz#1365747
+  (Migrate guest(win10) after hot plug/unplug memory balloon device [Missing section footer for 0000:00:07.0/virtio-net])
+- Resolves: bz#1366471
+  (QEMU prints "usb-kbd: warning: key event queue full" when pressing keys during SLOF boot)
+
+* Wed Aug 10 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-20.el7
+- kvm-block-gluster-rename-server-volname-image-host-volum.patch [bz#1247933]
+- kvm-block-gluster-code-cleanup.patch [bz#1247933]
+- kvm-block-gluster-deprecate-rdma-support.patch [bz#1247933]
+- kvm-block-gluster-using-new-qapi-schema.patch [bz#1247933]
+- kvm-block-gluster-add-support-for-multiple-gluster-serve.patch [bz#1247933]
+- kvm-block-gluster-fix-doc-in-the-qapi-schema-and-member-.patch [bz#1247933]
+- kvm-throttle-Don-t-allow-burst-limits-to-be-lower-than-t.patch [bz#1355665]
+- kvm-throttle-Test-burst-limits-lower-than-the-normal-lim.patch [bz#1355665]
+- kvm-spapr-Error-out-when-CPU-hotplug-is-attempted-on-old.patch [bz#1362019]
+- kvm-spapr-Correctly-set-query_hotpluggable_cpus-hook-bas.patch [bz#1362019]
+- Resolves: bz#1247933
+  (RFE: qemu-kvm-rhev: support multiple volume hosts for gluster volumes)
+- Resolves: bz#1355665
+  (Suggest to limit the burst value to be not less than the throttle value)
+- Resolves: bz#1362019
+  (Crashes when using query-hotpluggable-cpus with pseries-rhel7.2.0 machine type)
+
+* Fri Aug 05 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-19.el7
+- kvm-hw-pcie-root-port-Fix-PCIe-root-port-initialization.patch [bz#1323976]
+- kvm-hw-pxb-declare-pxb-devices-as-not-hot-pluggable.patch [bz#1323976]
+- kvm-hw-acpi-fix-a-DSDT-table-issue-when-a-pxb-is-present.patch [bz#1323976]
+- kvm-acpi-refactor-pxb-crs-computation.patch [bz#1323976]
+- kvm-hw-apci-handle-64-bit-MMIO-regions-correctly.patch [bz#1323976]
+- kvm-target-i386-Move-TCG-initialization-check-to-tcg_x86.patch [bz#1087672]
+- kvm-target-i386-Move-TCG-initialization-to-realize-time.patch [bz#1087672]
+- kvm-target-i386-Call-cpu_exec_init-on-realize.patch [bz#1087672]
+- kvm-tests-acpi-report-names-of-expected-files-in-verbose.patch [bz#1087672]
+- kvm-acpi-add-aml_debug.patch [bz#1087672]
+- kvm-acpi-add-aml_refof.patch [bz#1087672]
+- kvm-pc-acpi-remove-AML-for-empty-not-used-GPE-handlers.patch [bz#1087672]
+- kvm-pc-acpi-consolidate-CPU-hotplug-AML.patch [bz#1087672]
+- kvm-pc-acpi-consolidate-GPE._E02-with-the-rest-of-CPU-ho.patch [bz#1087672]
+- kvm-pc-acpi-cpu-hotplug-make-AML-CPU_foo-defines-local-t.patch [bz#1087672]
+- kvm-pc-acpi-mark-current-CPU-hotplug-functions-as-legacy.patch [bz#1087672]
+- kvm-pc-acpi-consolidate-legacy-CPU-hotplug-in-one-file.patch [bz#1087672]
+- kvm-pc-acpi-simplify-build_legacy_cpu_hotplug_aml-signat.patch [bz#1087672]
+- kvm-pc-acpi-cpuhp-legacy-switch-ProcessorID-to-possible_.patch [bz#1087672]
+- kvm-acpi-extend-ACPI-interface-to-provide-send_event-hoo.patch [bz#1087672]
+- kvm-pc-use-AcpiDeviceIfClass.send_event-to-issue-GPE-eve.patch [bz#1087672]
+- kvm-target-i386-Remove-xlevel-hv-spinlocks-option-fixups.patch [bz#1087672]
+- kvm-target-i386-Move-features-logic-that-requires-CPUSta.patch [bz#1087672]
+- kvm-target-i386-Remove-assert-kvm_enabled-from-host_x86_.patch [bz#1087672]
+- kvm-target-i386-Move-xcc-kvm_required-check-to-realize-t.patch [bz#1087672]
+- kvm-target-i386-Use-cpu_generic_init-in-cpu_x86_init.patch [bz#1087672]
+- kvm-target-i386-Consolidate-calls-of-object_property_par.patch [bz#1087672]
+- kvm-docs-update-ACPI-CPU-hotplug-spec-with-new-protocol.patch [bz#1087672]
+- kvm-pc-piix4-ich9-add-cpu-hotplug-legacy-property.patch [bz#1087672]
+- kvm-acpi-cpuhp-add-CPU-devices-AML-with-_STA-method.patch [bz#1087672]
+- kvm-pc-acpi-introduce-AcpiDeviceIfClass.madt_cpu-hook.patch [bz#1087672]
+- kvm-acpi-cpuhp-implement-hot-add-parts-of-CPU-hotplug-in.patch [bz#1087672]
+- kvm-acpi-cpuhp-implement-hot-remove-parts-of-CPU-hotplug.patch [bz#1087672]
+- kvm-acpi-cpuhp-add-cpu._OST-handling.patch [bz#1087672]
+- kvm-pc-use-new-CPU-hotplug-interface-since-2.7-machine-t.patch [bz#1087672]
+- kvm-pc-acpi-drop-intermediate-PCMachineState.node_cpu.patch [bz#1087672]
+- kvm-qmp-fix-spapr-example-of-query-hotpluggable-cpus.patch [bz#1087672]
+- kvm-qdev-Don-t-stop-applying-globals-on-first-error.patch [bz#1087672]
+- kvm-qdev-Eliminate-qemu_add_globals-function.patch [bz#1087672]
+- kvm-qdev-Use-GList-for-global-properties.patch [bz#1087672]
+- kvm-qdev-GlobalProperty.errp-field.patch [bz#1087672]
+- kvm-vl-Simplify-global-property-registration.patch [bz#1087672]
+- kvm-machine-add-properties-to-compat_props-incrementaly.patch [bz#1087672]
+- kvm-machine-Add-machine_register_compat_props-function.patch [bz#1087672]
+- kvm-vl-Set-errp-to-error_abort-on-machine-compat_props.patch [bz#1087672]
+- kvm-target-sparc-Use-sparc_cpu_parse_features-directly.patch [bz#1087672]
+- kvm-target-i386-Avoid-using-locals-outside-their-scope.patch [bz#1087672]
+- kvm-cpu-Use-CPUClass-parse_features-as-convertor-to-glob.patch [bz#1087672]
+- kvm-arm-virt-Parse-cpu_model-only-once.patch [bz#1087672]
+- kvm-cpu-make-cpu-qom.h-only-include-able-from-cpu.h.patch [bz#1087672]
+- kvm-target-i386-make-cpu-qom.h-not-target-specific.patch [bz#1087672]
+- kvm-target-Don-t-redefine-cpu_exec.patch [bz#1087672]
+- kvm-pc-Parse-CPU-features-only-once.patch [bz#1087672]
+- kvm-target-i386-Use-uint32_t-for-X86CPU.apic_id.patch [bz#1087672]
+- kvm-pc-Add-x86_topo_ids_from_apicid.patch [bz#1087672]
+- kvm-pc-Extract-CPU-lookup-into-a-separate-function.patch [bz#1087672]
+- kvm-pc-cpu-Consolidate-apic-id-validity-checks-in-pc_cpu.patch [bz#1087672]
+- kvm-target-i386-Replace-custom-apic-id-setter-getter-wit.patch [bz#1087672]
+- kvm-target-i386-Add-socket-core-thread-properties-to-X86.patch [bz#1087672]
+- kvm-target-i386-cpu-Do-not-ignore-error-and-fix-apic-par.patch [bz#1087672]
+- kvm-target-i386-Fix-apic-object-leak-when-CPU-is-deleted.patch [bz#1087672]
+- kvm-pc-Set-APIC-ID-based-on-socket-core-thread-ids-if-it.patch [bz#1087672]
+- kvm-pc-Delay-setting-number-of-boot-CPUs-to-machine_done.patch [bz#1087672]
+- kvm-pc-Register-created-initial-and-hotpluged-CPUs-in-on.patch [bz#1087672]
+- kvm-pc-Forbid-BSP-removal.patch [bz#1087672]
+- kvm-pc-Enforce-adding-CPUs-contiguously-and-removing-the.patch [bz#1087672]
+- kvm-pc-cpu-Allow-device_add-to-be-used-with-x86-cpu.patch [bz#1087672]
+- kvm-pc-Implement-query-hotpluggable-cpus-callback.patch [bz#1087672]
+- kvm-apic-move-MAX_APICS-check-to-apic-class.patch [bz#1087672]
+- kvm-apic-Drop-APICCommonState.idx-and-use-APIC-ID-as-ind.patch [bz#1087672]
+- kvm-apic-kvm-apic-Fix-crash-due-to-access-to-freed-memor.patch [bz#1087672]
+- kvm-apic-Add-unrealize-callbacks.patch [bz#1087672]
+- kvm-apic-Use-apic_id-as-apic-s-migration-instance_id.patch [bz#1087672]
+- kvm-target-i386-Add-x86_cpu_unrealizefn.patch [bz#1087672]
+- kvm-pc-Make-device_del-CPU-work-for-x86-CPUs.patch [bz#1087672]
+- kvm-exec-Reduce-CONFIG_USER_ONLY-ifdeffenery.patch [bz#1087672]
+- kvm-exec-Don-t-use-cpu_index-to-detect-if-cpu_exec_init-.patch [bz#1087672]
+- kvm-exec-Set-cpu_index-only-if-it-s-not-been-explictly-s.patch [bz#1087672]
+- kvm-qdev-Fix-object-reference-leak-in-case-device.realiz.patch [bz#1087672]
+- kvm-pc-Init-CPUState-cpu_index-with-index-in-possible_cp.patch [bz#1087672]
+- kvm-Revert-pc-Enforce-adding-CPUs-contiguously-and-remov.patch [bz#1087672]
+- kvm-qdev-ignore-GlobalProperty.errp-for-hotplugged-devic.patch [bz#1087672]
+- kvm-vl-exit-if-a-bad-property-value-is-passed-to-global.patch [bz#1087672]
+- kvm-apic-fix-broken-migration-for-kvm-apic.patch [bz#1087672]
+- kvm-RHEL-only-hw-char-pl011-fix-SBSA-reset.patch [bz#1266048]
+- kvm-migration-regain-control-of-images-when-migration-fa.patch [bz#1361539]
+- kvm-migration-Promote-improved-autoconverge-commands-out.patch [bz#1358141]
+- kvm-spapr-Ensure-CPU-cores-are-added-contiguously-and-re.patch [bz#1361443]
+- kvm-spapr-disintricate-core-id-from-DT-semantics.patch [bz#1361443]
+- kvm-spapr-init-CPUState-cpu_index-with-index-relative-to.patch [bz#1361443]
+- kvm-Revert-spapr-Ensure-CPU-cores-are-added-contiguously.patch [bz#1361443]
+- kvm-spapr-Prevent-boot-CPU-core-removal.patch [bz#1361443]
+- kvm-virtio-vga-propagate-on-gpu-realized-error.patch [bz#1360664]
+- kvm-hw-virtio-pci-fix-virtio-behaviour.patch [bz#1360664]
+- kvm-q35-disable-s3-s4-by-default.patch [bz#1357202]
+- kvm-pcie-fix-link-active-status-bit-migration.patch [bz#1352860]
+- kvm-pc-rhel-7.2-pcie-fix-link-active-status-bit-migratio.patch [bz#1352860]
+- kvm-add-e1000e-ipxe-rom-symlink.patch [bz#1343092]
+- kvm-e1000e-add-boot-rom.patch [bz#1343092]
+- Resolves: bz#1087672
+  ([Fujitsu 7.2 FEAT]: qemu vcpu hot-remove support)
+- Resolves: bz#1266048
+  (login prompt does not work inside KVM guest when keys are pressed while the kernel is booting)
+- Resolves: bz#1323976
+  (PCI: Add 64-bit MMIO support to PXB devices)
+- Resolves: bz#1343092
+  (RFE: Integrate e1000e implementation in downstream QEMU)
+- Resolves: bz#1352860
+  (Migration is failed from host RHEL7.2.z to host RHEL7.3 with "-M pc-i440fx-rhel7.0.0 -device nec-usb-xhci")
+- Resolves: bz#1357202
+  ([Q35] S3 should be disabled by default for the pc-q35-rhel7.3.0 machine type)
+- Resolves: bz#1358141
+  (Removal of the "x-" prefix for dynamic cpu throttling)
+- Resolves: bz#1360664
+  ([virtio] Update default virtio-1 behavior for virtio devices)
+- Resolves: bz#1361443
+  (ppc64le: Introduce stable cpu_index for cpu hotplugging)
+- Resolves: bz#1361539
+  (block/io.c:1342: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)' failed on failed migrate)
+
+* Tue Aug 02 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-18.el7
+- kvm-pci-fix-unaligned-access-in-pci_xxx_quad.patch [bz#1343092]
+- kvm-msix-make-msix_clr_pending-visible-for-clients.patch [bz#1343092]
+- kvm-pci-Introduce-define-for-PM-capability-version-1.1.patch [bz#1343092]
+- kvm-pcie-Add-support-for-PCIe-CAP-v1.patch [bz#1343092]
+- kvm-pcie-Introduce-function-for-DSN-capability-creation.patch [bz#1343092]
+- kvm-vmxnet3-Use-generic-function-for-DSN-capability-defi.patch [bz#1343092]
+- kvm-net-Introduce-Toeplitz-hash-calculator.patch [bz#1343092]
+- kvm-net-Add-macros-for-MAC-address-tracing.patch [bz#1343092]
+- kvm-vmxnet3-Use-common-MAC-address-tracing-macros.patch [bz#1343092]
+- kvm-net_pkt-Name-vmxnet3-packet-abstractions-more-generi.patch [bz#1343092]
+- kvm-rtl8139-Move-more-TCP-definitions-to-common-header.patch [bz#1343092]
+- kvm-net_pkt-Extend-packet-abstraction-as-required-by-e10.patch [bz#1343092]
+- kvm-vmxnet3-Use-pci_dma_-API-instead-of-cpu_physical_mem.patch [bz#1343092]
+- kvm-e1000_regs-Add-definitions-for-Intel-82574-specific-.patch [bz#1343092]
+- kvm-e1000-Move-out-code-that-will-be-reused-in-e1000e.patch [bz#1343092]
+- kvm-net-Introduce-e1000e-device-emulation.patch [bz#1343092]
+- kvm-e1000e-Fix-build-with-gcc-4.6.3-and-ust-tracing.patch [bz#1343092]
+- kvm-pci-fix-pci_requester_id.patch [bz#1350196]
+- kvm-hw-pci-delay-bus_master_enable_region-initialization.patch [bz#1350196]
+- kvm-q35-allow-dynamic-sysbus.patch [bz#1350196]
+- kvm-q35-rhel-allow-dynamic-sysbus.patch [bz#1350196]
+- kvm-hw-iommu-enable-iommu-with-device.patch [bz#1350196]
+- kvm-machine-remove-iommu-property.patch [bz#1350196]
+- kvm-rhel-Revert-unwanted-inconsequential-changes-to-ivsh.patch [bz#1333318]
+- kvm-rhel-Disable-ivshmem-plain-migration-ivshmem-doorbel.patch [bz#1333318]
+- kvm-nvdimm-fix-memory-leak-in-error-code-path.patch [bz#1361205]
+- kvm-i8257-Set-no-user-flag.patch [bz#1337457]
+- kvm-bitops-Add-MAKE_64BIT_MASK-macro.patch [bz#1339196]
+- kvm-target-i386-Provide-TCG_PHYS_ADDR_BITS.patch [bz#1339196]
+- kvm-target-i386-Allow-physical-address-bits-to-be-set.patch [bz#1339196]
+- kvm-target-i386-Mask-mtrr-mask-based-on-CPU-physical-add.patch [bz#1339196]
+- kvm-target-i386-Fill-high-bits-of-mtrr-mask.patch [bz#1339196]
+- kvm-target-i386-Set-physical-address-bits-based-on-host.patch [bz#1339196]
+- kvm-target-i386-Enable-host-phys-bits-on-RHEL.patch [bz#1339196]
+- kvm-pc-Fix-rhel6.3.0-compat_props-setting.patch [bz#1362264]
+- Resolves: bz#1333318
+  (ivshmem-plain support in RHEL 7.3)
+- Resolves: bz#1337457
+  (enable i8257 device)
+- Resolves: bz#1339196
+  (qemu-kvm (on target host) killed by SIGABRT when migrating a guest from AMD host to Intel host.)
+- Resolves: bz#1343092
+  (RFE: Integrate e1000e implementation in downstream QEMU)
+- Resolves: bz#1350196
+  (Enable IOMMU device with -device intel-iommu)
+- Resolves: bz#1361205
+  (nvdimm: fix memory leak in error code path)
+- Resolves: bz#1362264
+  (rhel6.3.0 machine-type using wrong compat_props list)
+
+* Fri Jul 29 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-17.el7
+- kvm-Disable-mptsas1068-device.patch [bz#1333282]
+- kvm-Disable-sd-card.patch [bz#1333282]
+- kvm-Disable-rocker-device.patch [bz#1333282]
+- kvm-Disable-new-ipmi-devices.patch [bz#1333282]
+- kvm-Disable-hyperv-testdev.patch [bz#1333282]
+- kvm-Disable-allwiner_ahci-device.patch [bz#1333282]
+- kvm-Disable-igd-passthrough-i440FX.patch [bz#1333282]
+- kvm-Disable-vfio-platform-device.patch [bz#1333282]
+- kvm-tap-vhost-busy-polling-support.patch [bz#1345715 bz#1353791]
+- kvm-vl-change-runstate-only-if-new-state-is-different-fr.patch [bz#1355982]
+- kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch [bz#1359733]
+- kvm-migration-set-state-to-post-migrate-on-failure.patch [bz#1355683]
+- kvm-block-drop-support-for-using-qcow-2-encryption-with-.patch [bz#1336659]
+- kvm-json-streamer-Don-t-leak-tokens-on-incomplete-parse.patch [bz#1360612]
+- kvm-json-streamer-fix-double-free-on-exiting-during-a-pa.patch [bz#1360612]
+- kvm-Add-dump-guest-memory.py-to-all-archs.patch [bz#1360225]
+- Resolves: bz#1333282
+  (Disable new devices in QEMU 2.6)
+- Resolves: bz#1336659
+  (Core dump when re-launch guest with encrypted block device)
+- Resolves: bz#1345715
+  (Busy polling support for vhost net in qemu)
+- Resolves: bz#1353791
+  (Busy polling support for vhost)
+- Resolves: bz#1355683
+  (qemu core dump when do postcopy migration again after canceling a migration in postcopy phase)
+- Resolves: bz#1355982
+  (qemu will abort after type two"system_reset" after the guest poweroff)
+- Resolves: bz#1359733
+  (CVE-2016-5403 qemu-kvm-rhev: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.3])
+- Resolves: bz#1360225
+  (Can't extract guest memory dump from qemu core)
+- Resolves: bz#1360612
+  (Memory leak on incomplete JSON parse)
+
+* Tue Jul 26 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-16.el7
+- kvm-exec-Remove-cpu-from-cpus-list-during-cpu_exec_exit.patch [bz#1172917]
+- kvm-exec-Do-vmstate-unregistration-from-cpu_exec_exit.patch [bz#1172917]
+- kvm-cpu-Reclaim-vCPU-objects.patch [bz#1172917]
+- kvm-cpu-Add-a-sync-version-of-cpu_remove.patch [bz#1172917]
+- kvm-qdev-hotplug-Introduce-HotplugHandler.pre_plug-callb.patch [bz#1172917]
+- kvm-cpu-Abstract-CPU-core-type.patch [bz#1172917]
+- kvm-xics-xics_kvm-Handle-CPU-unplug-correctly.patch [bz#1172917]
+- kvm-spapr_drc-Prevent-detach-racing-against-attach-for-C.patch [bz#1172917]
+- kvm-qom-API-to-get-instance_size-of-a-type.patch [bz#1172917]
+- kvm-spapr-Abstract-CPU-core-device-and-type-specific-cor.patch [bz#1172917]
+- kvm-spapr-Move-spapr_cpu_init-to-spapr_cpu_core.c.patch [bz#1172917]
+- kvm-spapr-convert-boot-CPUs-into-CPU-core-devices.patch [bz#1172917]
+- kvm-spapr-CPU-hotplug-support.patch [bz#1172917]
+- kvm-spapr-CPU-hot-unplug-support.patch [bz#1172917]
+- kvm-QMP-Add-query-hotpluggable-cpus.patch [bz#1172917]
+- kvm-hmp-Add-info-hotpluggable-cpus-HMP-command.patch [bz#1172917]
+- kvm-spapr-implement-query-hotpluggable-cpus-callback.patch [bz#1172917]
+- kvm-qapi-Report-support-for-device-cpu-hotplug-in-query-.patch [bz#1172917]
+- kvm-qapi-keep-names-in-CpuInstanceProperties-in-sync-wit.patch [bz#1172917]
+- kvm-spapr-fix-write-past-end-of-array-error-in-cpu-core-.patch [bz#1172917]
+- kvm-spapr-Restore-support-for-older-PowerPC-CPU-cores.patch [bz#1172917]
+- kvm-spapr-Restore-support-for-970MP-and-POWER8NVL-CPU-co.patch [bz#1172917]
+- kvm-spapr-drop-reference-on-child-object-during-core-rea.patch [bz#1172917]
+- kvm-spapr-do-proper-error-propagation-in-spapr_cpu_core_.patch [bz#1172917]
+- kvm-spapr-drop-duplicate-variable-in-spapr_core_release.patch [bz#1172917]
+- kvm-spapr-Ensure-thread0-of-CPU-core-is-always-realized-.patch [bz#1172917]
+- kvm-spapr-fix-core-unplug-crash.patch [bz#1172917]
+- kvm-usbredir-add-streams-property.patch [bz#1353180]
+- kvm-usbredir-turn-off-streams-for-rhel7.2-older.patch [bz#1353180]
+- kvm-net-fix-qemu_announce_self-not-emitting-packets.patch [bz#1343433]
+- kvm-Fix-crash-bug-in-rebase-of__com.redhat_drive_add.patch [bz#1352865]
+- kvm-ppc-Yet-another-fix-for-the-huge-page-support-detect.patch [bz#1347498]
+- kvm-ppc-Huge-page-detection-mechanism-fixes-Episode-III.patch [bz#1347498]
+- kvm-hw-ppc-spapr-Make-sure-to-close-the-htab_fd-when-mig.patch [bz#1354341]
+- Resolves: bz#1172917
+  (add support for CPU hotplugging (qemu-kvm-rhev))
+- Resolves: bz#1343433
+  (migration: announce_self fix)
+- Resolves: bz#1347498
+  ([ppc64le] Guest can't boot up with hugepage memdev)
+- Resolves: bz#1352865
+  (Boot guest with two virtio-scsi-pci devices and spice, QEMU core dump after executing '(qemu)__com.redhat_drive_add')
+- Resolves: bz#1353180
+  (7.3->7.2 migration: qemu-kvm: usbredirparser: error unserialize caps mismatch)
+- Resolves: bz#1354341
+  (guest hang after cancel migration then migrate again)
+
+* Fri Jul 22 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-15.el7
+- kvm-spapr_pci-Use-correct-DMA-LIOBN-when-composing-the-d.patch [bz#1213667]
+- kvm-spapr_iommu-Finish-renaming-vfio_accel-to-need_vfio.patch [bz#1213667]
+- kvm-spapr_iommu-Move-table-allocation-to-helpers.patch [bz#1213667]
+- kvm-vmstate-Define-VARRAY-with-VMS_ALLOC.patch [bz#1213667]
+- kvm-spapr_iommu-Introduce-enabled-state-for-TCE-table.patch [bz#1213667]
+- kvm-spapr_iommu-Migrate-full-state.patch [bz#1213667]
+- kvm-spapr_iommu-Add-root-memory-region.patch [bz#1213667]
+- kvm-spapr_pci-Reset-DMA-config-on-PHB-reset.patch [bz#1213667]
+- kvm-spapr_pci-Add-and-export-DMA-resetting-helper.patch [bz#1213667]
+- kvm-memory-Add-reporting-of-supported-page-sizes.patch [bz#1213667]
+- kvm-spapr-ensure-device-trees-are-always-associated-with.patch [bz#1213667]
+- kvm-spapr_iommu-Realloc-guest-visible-TCE-table-when-sta.patch [bz#1213667]
+- kvm-vfio-spapr-Add-DMA-memory-preregistering-SPAPR-IOMMU.patch [bz#1213667]
+- kvm-vfio-Add-host-side-DMA-window-capabilities.patch [bz#1213667]
+- kvm-vfio-spapr-Create-DMA-window-dynamically-SPAPR-IOMMU.patch [bz#1213667]
+- kvm-spapr_pci-spapr_pci_vfio-Support-Dynamic-DMA-Windows.patch [bz#1213667]
+- kvm-qemu-sockets-use-qapi_free_SocketAddress-in-cleanup.patch [bz#1354090]
+- kvm-tap-use-an-exit-notifier-to-call-down_script.patch [bz#1354090]
+- kvm-slirp-use-exit-notifier-for-slirp_smb_cleanup.patch [bz#1354090]
+- kvm-net-do-not-use-atexit-for-cleanup.patch [bz#1354090]
+- kvm-virtio-mmio-format-transport-base-address-in-BusClas.patch [bz#1356815]
+- kvm-vfio-pci-Hide-ARI-capability.patch [bz#1356376]
+- kvm-qxl-factor-out-qxl_get_check_slot_offset.patch [bz#1235732]
+- kvm-qxl-store-memory-region-and-offset-instead-of-pointe.patch [bz#1235732]
+- kvm-qxl-fix-surface-migration.patch [bz#1235732]
+- kvm-qxl-fix-qxl_set_dirty-call-in-qxl_dirty_one_surface.patch [bz#1235732]
+- kvm-Add-install-dependency-required-for-usb-streams.patch [bz#1354443]
+- Resolves: bz#1213667
+  (Dynamic DMA Windows for VFIO on Power (qemu component))
+- Resolves: bz#1235732
+  (spice-gtk shows outdated screen state after migration [qemu-kvm-rhev])
+- Resolves: bz#1354090
+  (Boot guest with vhostuser server mode, QEMU prompt 'Segmentation fault' after executing '(qemu)system_powerdown')
+- Resolves: bz#1354443
+  (/usr/libexec/qemu-kvm: undefined symbol: libusb_free_ss_endpoint_companion_descriptor)
+- Resolves: bz#1356376
+  ([Q35] Nic which passthrough from host didn't be found in guest when enable multifunction)
+- Resolves: bz#1356815
+  (AArch64: backport virtio-mmio dev pathname fix)
+
+* Tue Jul 19 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-14.el7
+- kvm-add-vgabios-virtio.bin-symlink.patch [bz#1347402]
+- kvm-usb-enable-streams-support.patch [bz#1033733]
+- kvm-hw-arm-virt-kill-7.2-machine-type.patch [bz#1356814]
+- kvm-blockdev-Fix-regression-with-the-default-naming-of-t.patch [bz#1353801]
+- kvm-qemu-iotests-Test-naming-of-throttling-groups.patch [bz#1353801]
+- kvm-target-i386-Show-host-and-VM-TSC-frequencies-on-mism.patch [bz#1351442]
+- Resolves: bz#1033733
+  (RFE: add support for USB-3 bulk streams - qemu-kvm)
+- Resolves: bz#1347402
+  (vgabios-virtio.bin should be symlinked in qemu-kvm-rhev)
+- Resolves: bz#1351442
+  ("TSC frequency mismatch" warning message after migration)
+- Resolves: bz#1353801
+  (The default io throttling group name is null, which makes all throttled disks with a default group name in the same group)
+- Resolves: bz#1356814
+  (AArch64: remove non-released 7.2 machine type)
+
+* Tue Jul 12 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-13.el7
+- kvm-block-gluster-add-support-for-selecting-debug-loggin.patch [bz#1320714]
+- kvm-Revert-static-checker-e1000-82540em-got-aliased-to-e.patch [bz#1353070]
+- kvm-Revert-e1000-use-alias-for-default-model.patch [bz#1353070]
+- kvm-7.x-compat-e1000-82540em.patch [bz#1353070]
+- kvm-target-i386-add-Skylake-Client-cpu-model.patch [bz#1327589]
+- kvm-scsi-generic-Merge-block-max-xfer-len-in-INQUIRY-res.patch [bz#1353816]
+- kvm-raw-posix-Fetch-max-sectors-for-host-block-device.patch [bz#1353816]
+- kvm-scsi-Advertise-limits-by-blocksize-not-512.patch [bz#1353816]
+- kvm-mirror-clarify-mirror_do_read-return-code.patch [bz#1336705]
+- kvm-mirror-limit-niov-to-IOV_MAX-elements-again.patch [bz#1336705]
+- kvm-iotests-add-small-granularity-mirror-test.patch [bz#1336705]
+- Resolves: bz#1320714
+  ([RFE] Allow the libgfapi logging level to be controlled.)
+- Resolves: bz#1327589
+  (Add Skylake CPU model)
+- Resolves: bz#1336705
+  (Drive mirror with option granularity fail)
+- Resolves: bz#1353070
+  (Migration is failed from host RHEL7.2.z to host RHEL7.3 with "-M rhel6.6.0 -device e1000-82540em")
+- Resolves: bz#1353816
+  (expose host BLKSECTGET limit in scsi-block (qemu-kvm-rhev))
+
+* Fri Jul 08 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-12.el7
+- kvm-Fix-crash-with-__com.redhat_drive_del.patch [bz#1341531]
+- kvm-hw-arm-virt-fix-limit-of-64-bit-ACPI-ECAM-PCI-MMIO-r.patch [bz#1349337]
+- kvm-Increase-locked-memory-limit-for-all-users-not-just-.patch [bz#1350735]
+- kvm-target-i386-Remove-SSE4a-from-qemu64-CPU-model.patch [bz#1318386 bz#1321139 bz#1321139]
+- kvm-target-i386-Remove-ABM-from-qemu64-CPU-model.patch [bz#1318386 bz#1321139 bz#1321139]
+- kvm-pc-Recover-PC_RHEL7_1_COMPAT-from-RHEL-7.2-code.patch [bz#1318386 bz#1318386 bz#1321139]
+- kvm-pc-Include-missing-PC_COMPAT_2_3-entries-in-PC_RHEL7.patch [bz#1318386 bz#1318386 bz#1321139]
+- kvm-vhost-user-disable-chardev-handlers-on-close.patch [bz#1347077]
+- kvm-char-clean-up-remaining-chardevs-when-leaving.patch [bz#1347077]
+- kvm-socket-add-listen-feature.patch [bz#1347077]
+- kvm-socket-unlink-unix-socket-on-remove.patch [bz#1347077]
+- kvm-char-do-not-use-atexit-cleanup-handler.patch [bz#1347077]
+- kvm-vfio-add-pcie-extended-capability-support.patch [bz#1346688]
+- kvm-vfio-pci-Hide-SR-IOV-capability.patch [bz#1346688]
+- kvm-memory-Add-MemoryRegionIOMMUOps.notify_started-stopp.patch [bz#1346920]
+- kvm-intel_iommu-Throw-hw_error-on-notify_started.patch [bz#1346920]
+- Resolves: bz#1318386
+  (pc-rhel7.2.0 machine type definition needs some fixes)
+- Resolves: bz#1321139
+  (qemu-kvm-rhev prints warnings in the default CPU+machine-type configuration.)
+- Resolves: bz#1341531
+  (qemu gets SIGSEGV when hot-plug a scsi hostdev device with duplicate target address)
+- Resolves: bz#1346688
+  ([Q35] vfio read-only SR-IOV capability confuses OVMF)
+- Resolves: bz#1346920
+  (vIOMMU: prevent unsupported configurations with vfio)
+- Resolves: bz#1347077
+  (vhost-user: A socket file is not deleted after VM's port is detached.)
+- Resolves: bz#1349337
+  (hw/arm/virt: fix limit of 64-bit ACPI/ECAM PCI MMIO range)
+- Resolves: bz#1350735
+  (memory locking limit for regular users is too low to launch guests through libvirt)
+
+* Fri Jul 01 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-11.el7
+- kvm-Postcopy-Avoid-0-length-discards.patch [bz#1347256]
+- kvm-Migration-Split-out-ram-part-of-qmp_query_migrate.patch [bz#1347256]
+- kvm-Postcopy-Add-stats-on-page-requests.patch [bz#1347256]
+- kvm-test-Postcopy.patch [bz#1347256]
+- kvm-tests-fix-libqtest-socket-timeouts.patch [bz#1347256]
+- kvm-Postcopy-Check-for-support-when-setting-the-capabili.patch [bz#1347256]
+- kvm-rbd-change-error_setg-to-error_setg_errno.patch [bz#1329641]
+- kvm-ppc-Disable-huge-page-support-if-it-is-not-available.patch [bz#1347498]
+- kvm-acpi-do-not-use-TARGET_PAGE_SIZE.patch [bz#1270345]
+- kvm-acpi-convert-linker-from-GArray-to-BIOSLinker-struct.patch [bz#1270345]
+- kvm-acpi-simplify-bios_linker-API-by-removing-redundant-.patch [bz#1270345]
+- kvm-acpi-cleanup-bios_linker_loader_cleanup.patch [bz#1270345]
+- kvm-tpm-apci-cleanup-TCPA-table-initialization.patch [bz#1270345]
+- kvm-acpi-make-bios_linker_loader_add_pointer-API-offset-.patch [bz#1270345]
+- kvm-acpi-make-bios_linker_loader_add_checksum-API-offset.patch [bz#1270345]
+- kvm-pc-dimm-get-memory-region-from-get_memory_region.patch [bz#1270345]
+- kvm-pc-dimm-introduce-realize-callback.patch [bz#1270345]
+- kvm-pc-dimm-introduce-get_vmstate_memory_region-callback.patch [bz#1270345]
+- kvm-nvdimm-support-nvdimm-label.patch [bz#1270345]
+- kvm-acpi-add-aml_object_type.patch [bz#1270345]
+- kvm-acpi-add-aml_call5.patch [bz#1270345]
+- kvm-nvdimm-acpi-set-HDLE-properly.patch [bz#1270345]
+- kvm-nvdimm-acpi-save-arg3-of-_DSM-method.patch [bz#1270345]
+- kvm-nvdimm-acpi-check-UUID.patch [bz#1270345]
+- kvm-nvdimm-acpi-abstract-the-operations-for-root-nvdimm-.patch [bz#1270345]
+- kvm-nvdimm-acpi-check-revision.patch [bz#1270345]
+- kvm-nvdimm-acpi-support-Get-Namespace-Label-Size-functio.patch [bz#1270345]
+- kvm-nvdimm-acpi-support-Get-Namespace-Label-Data-functio.patch [bz#1270345]
+- kvm-nvdimm-acpi-support-Set-Namespace-Label-Data-functio.patch [bz#1270345]
+- kvm-docs-add-NVDIMM-ACPI-documentation.patch [bz#1270345]
+- kvm-Fix-qemu-kvm-does-not-quit-when-booting-guest-w-241-.patch [bz#1126666]
+- kvm-Adjust-locked-memory-limits-to-allow-unprivileged-VM.patch [bz#1350735]
+- kvm-dma-helpers-dma_blk_io-cancel-support.patch [bz#1346237]
+- Resolves: bz#1126666
+  (qemu-kvm does not quit when booting guest w/ 161 vcpus and "-no-kvm")
+- Resolves: bz#1270345
+  ([Intel 7.3 FEAT] Virtualization support for NVDIMM - qemu support)
+- Resolves: bz#1329641
+  ([RFE]Ceph/RBD block driver for qemu-kvm : change error_setg() to error_setg_errno())
+- Resolves: bz#1346237
+  (win 10.x86_64 guest coredump when execute avocado test case: win_virtio_update.install_driver)
+- Resolves: bz#1347256
+  (Backport 2.7 postcopy fix, test and stats)
+- Resolves: bz#1347498
+  ([ppc64le] Guest can't boot up with hugepage memdev)
+- Resolves: bz#1350735
+  (memory locking limit for regular users is too low to launch guests through libvirt)
+
+* Tue Jun 28 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-10.el7
+- kvm-block-clarify-error-message-for-qmp-eject.patch [bz#961589]
+- kvm-blockdev-clean-up-error-handling-in-do_open_tray.patch [bz#961589]
+- kvm-blockdev-clarify-error-on-attempt-to-open-locked-tra.patch [bz#961589]
+- kvm-blockdev-backup-Use-bdrv_lookup_bs-on-target.patch [bz#1336310 bz#1339498]
+- kvm-blockdev-backup-Don-t-move-target-AioContext-if-it-s.patch [bz#1336310 bz#1339498]
+- kvm-virtio-blk-Remove-op-blocker-for-dataplane.patch [bz#1336310 bz#1339498]
+- kvm-virtio-scsi-Remove-op-blocker-for-dataplane.patch [bz#1336310 bz#1339498]
+- kvm-spec-add-a-sample-kvm.conf-to-enable-Nested-Virtuali.patch [bz#1290150]
+- Resolves: bz#1290150
+  (Include example kvm.conf with nested options commented out)
+- Resolves: bz#1336310
+  (virtio-scsi data-plane does not support block management QMP commands)
+- Resolves: bz#1339498
+  (Core dump when do 'block-job-complete' after 'drive-mirror')
+- Resolves: bz#961589
+  (rhel7 guest sometimes didnt unlock the cdrom when qemu-kvm trying to eject)
+
+* Thu Jun 23 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-9.el7
+- kvm-7.2-machine-type-compatibility.patch [bz#1344269]
+- kvm-vhost-user-add-ability-to-know-vhost-user-backend-di.patch [bz#1322087]
+- kvm-tests-vhost-user-bridge-add-client-mode.patch [bz#1322087]
+- kvm-tests-vhost-user-bridge-workaround-stale-vring-base.patch [bz#1322087]
+- kvm-qemu-char-add-qemu_chr_disconnect-to-close-a-fd-acce.patch [bz#1322087]
+- kvm-vhost-user-disconnect-on-start-failure.patch [bz#1322087]
+- kvm-vhost-net-do-not-crash-if-backend-is-not-present.patch [bz#1322087]
+- kvm-vhost-net-save-restore-vhost-user-acked-features.patch [bz#1322087]
+- kvm-vhost-net-save-restore-vring-enable-state.patch [bz#1322087]
+- kvm-tests-append-i386-tests.patch [bz#1322087]
+- kvm-test-start-vhost-user-reconnect-test.patch [bz#1322087]
+- kvm-block-Prevent-sleeping-jobs-from-resuming-if-they-ha.patch [bz#1265179]
+- kvm-blockjob-move-iostatus-reset-out-of-block_job_enter.patch [bz#1265179]
+- kvm-blockjob-rename-block_job_is_paused.patch [bz#1265179]
+- kvm-blockjob-add-pause-points.patch [bz#1265179]
+- kvm-blockjob-add-block_job_get_aio_context.patch [bz#1265179]
+- kvm-block-use-safe-iteration-over-AioContext-notifiers.patch [bz#1265179]
+- kvm-blockjob-add-AioContext-attached-callback.patch [bz#1265179]
+- kvm-mirror-follow-AioContext-change-gracefully.patch [bz#1265179]
+- kvm-backup-follow-AioContext-change-gracefully.patch [bz#1265179]
+- kvm-block-Fix-snapshot-on-with-aio-native.patch [bz#1336649]
+- kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch [bz#1340930]
+- kvm-block-fixed-BdrvTrackedRequest-filling-in-bdrv_co_di.patch [bz#1348763]
+- kvm-block-fix-race-in-bdrv_co_discard-with-drive-mirror.patch [bz#1348763]
+- kvm-block-process-before_write_notifiers-in-bdrv_co_disc.patch [bz#1348763]
+- Resolves: bz#1265179
+  (With dataplane, when migrate to  remote NBD disk after drive-mirror, qemu core dump ( both src host and des host))
+- Resolves: bz#1322087
+  (No recovery after vhost-user process restart)
+- Resolves: bz#1336649
+  ([RHEL.7.3] Guest will not boot up when specify aio=native and snapshot=on together)
+- Resolves: bz#1340930
+  (CVE-2016-5126 qemu-kvm-rhev: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.3])
+- Resolves: bz#1344269
+  (Migration: Fixup machine types and HW_COMPAT (stage 2a))
+- Resolves: bz#1348763
+  (Fix dirty marking with block discard requests)
+
+* Tue Jun 21 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-8.el7
+- kvm-Disable-Windows-enlightnements.patch [bz#1336517]
+- kvm-ppc-spapr-Refactor-h_client_architecture_support-CPU.patch [bz#1341492]
+- kvm-ppc-Split-pcr_mask-settings-into-supported-bits-and-.patch [bz#1341492]
+- kvm-ppc-Provide-function-to-get-CPU-class-of-the-host-CP.patch [bz#1341492]
+- kvm-ppc-Improve-PCR-bit-selection-in-ppc_set_compat.patch [bz#1341492]
+- kvm-ppc-Add-PowerISA-2.07-compatibility-mode.patch [bz#1341492]
+- kvm-machine-types-fix-pc_machine_-_options-chain.patch [bz#1344320]
+- kvm-Fix-rhel6-rom-file.patch [bz#1344320]
+- kvm-fix-vga-type-for-older-machines.patch [bz#1344320]
+- kvm-Revert-aio_notify-force-main-loop-wakeup-with-SIGIO-.patch [bz#1188656]
+- kvm-Make-avx2-configure-test-work-with-O2.patch [bz#1323294]
+- kvm-avx2-configure-Use-primitives-in-test.patch [bz#1323294]
+- kvm-vfio-Fix-broken-EEH.patch [bz#1346627]
+- Resolves: bz#1188656
+  (lost block IO completion notification (for virtio-scsi disk) hangs main loop)
+- Resolves: bz#1323294
+  (AVX-2 migration optimisation)
+- Resolves: bz#1336517
+  (Disable hv-vpindex, hv-runtime, hv-reset, hv-synic & hv-stimer enlightenment for Windows)
+- Resolves: bz#1341492
+  (QEMU on POWER does not support the PowerISA 2.07 compatibility mode)
+- Resolves: bz#1344320
+  (migration: fix pc_i440fx_*_options chaining)
+- Resolves: bz#1346627
+  (qemu discards EEH ioctl results)
+
+* Thu Jun 16 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-7.el7
+- kvm-pc-allow-raising-low-memory-via-max-ram-below-4g-opt.patch [bz#1176144]
+- kvm-vga-add-sr_vbe-register-set.patch [bz#1331415 bz#1346976]
+- Resolves: bz#1176144
+  ([Nokia RHEL 7.3 Feature]: 32-bit operating systems get very little memory space with new Qemu's)
+- Resolves: bz#1331415
+  (CVE-2016-3710 qemu-kvm-rhev: qemu: incorrect banked access bounds checking in vga module [rhel-7.3])
+- Resolves: bz#1346976
+  (Regression from CVE-2016-3712: windows installer fails to start)
+- Resolves: bz#1339467
+  (User can not create windows 7 virtual machine in rhevm3.6.5.)
+
+* Wed Jun 15 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-6.el7
+- kvm-throttle-refuse-iops-size-without-iops-total-read-wr.patch [bz#1342330]
+- kvm-scsi-mark-TYPE_SCSI_DISK_BASE-as-abstract.patch [bz#1338043]
+- kvm-scsi-disk-add-missing-break.patch [bz#1338043]
+- kvm-Disable-spapr-rng.patch [bz#1343891]
+- kvm-spec-Update-rules-before-triggering-for-kvm-device.patch [bz#1338755]
+- kvm-spec-Do-not-package-ivshmem-server-and-ivshmem-clien.patch [bz#1320476]
+- Resolves: bz#1320476
+  (Failed to upgrade qemu-kvm-tools-rhev from 2.3.0 to 2.5.0)
+- Resolves: bz#1338043
+  (scsi-block fix - receive the right SCSI status on reads and writes)
+- Resolves: bz#1338755
+  (qemu-kvm-rhev doesn't reload udev rules before triggering for kvm device)
+- Resolves: bz#1342330
+  (There is no error prompt when set the io throttling parameters iops_size without iops)
+- Resolves: bz#1343891
+  (Disable spapr-rng device in downstream qemu 2.6)
+
+* Mon Jun 06 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-5.el7
+- kvm-spapr-update-RHEL-7.2-machine-type.patch [bz#1316303]
+- kvm-migration-fix-HW_COMPAT_RHEL7_2.patch [bz#1316303]
+- kvm-target-i386-add-a-generic-x86-nmi-handler.patch [bz#1335720]
+- kvm-nmi-remove-x86-specific-nmi-handling.patch [bz#1335720]
+- kvm-cpus-call-the-core-nmi-injection-function.patch [bz#1335720]
+- kvm-spec-link-sgabios.bin-only-for-x86_64.patch [bz#1337917]
+- kvm-Add-PCIe-bridge-devices-for-AArch64.patch [bz#1326420]
+- kvm-Remove-unsupported-VFIO-devices-from-QEMU.patch [bz#1326420]
+- kvm-hw-net-spapr_llan-Delay-flushing-of-the-RX-queue-whi.patch [bz#1210221]
+- kvm-hw-net-spapr_llan-Provide-counter-with-dropped-rx-fr.patch [bz#1210221]
+- kvm-iscsi-pass-SCSI-status-back-for-SG_IO.patch [bz#1338043]
+- kvm-dma-helpers-change-BlockBackend-to-opaque-value-in-D.patch [bz#1338043]
+- kvm-scsi-disk-introduce-a-common-base-class.patch [bz#1338043]
+- kvm-scsi-disk-introduce-dma_readv-and-dma_writev.patch [bz#1338043]
+- kvm-scsi-disk-add-need_fua_emulation-to-SCSIDiskClass.patch [bz#1338043]
+- kvm-scsi-disk-introduce-scsi_disk_req_check_error.patch [bz#1338043]
+- kvm-scsi-block-always-use-SG_IO.patch [bz#1338043]
+- kvm-tools-kvm_stat-Powerpc-related-fixes.patch [bz#1337033]
+- kvm-pc-New-default-pc-i440fx-rhel7.3.0-machine-type.patch [bz#1305121]
+- kvm-7.3-mismerge-fix-Fix-ich9-intel-hda-compatibility.patch [bz#1342015]
+- kvm-PC-migration-compat-Section-footers-global-state.patch [bz#1342015]
+- kvm-fw_cfg-for-7.2-compatibility.patch [bz#1342015]
+- kvm-pc-Create-new-pc-q35-rhel7.3.0-machine-type.patch [bz#1342015]
+- kvm-q35-Remove-7.0-7.1-7.2-machine-types.patch [bz#1342015]
+- Resolves: bz#1210221
+  (Netperf UDP_STREAM Lost most of the packets on spapr-vlan device)
+- Resolves: bz#1305121
+  (rhel7.3.0 machine-types)
+- Resolves: bz#1316303
+  (Live migration of VMs from RHEL 7.2 <--> 7.3 with pseries-rhel7.2.0 machine type (qemu 2.6))
+- Resolves: bz#1326420
+  (AArch64: clean and add devices to fully support aarch64 vm)
+- Resolves: bz#1335720
+  (watchdog action 'inject-nmi' takes no effect)
+- Resolves: bz#1337033
+  (kvm_stat AttributeError: 'ArchPPC' object has no attribute 'exit_reasons')
+- Resolves: bz#1337917
+  (qemu-kvm-rhev: Only ship /usr/share/qemu-kvm/sgabios.bin on x86)
+- Resolves: bz#1338043
+  (scsi-block fix - receive the right SCSI status on reads and writes)
+- Resolves: bz#1342015
+  (Migration: Fixup machine types and HW_COMPAT (stage 1b))
+
+* Wed May 25 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-4.el7
+- kvm-pc-Use-right-HW_COMPAT_-macros-at-PC_RHEL7-compat-ma.patch [bz#1318386]
+- kvm-compat-Add-missing-any_layout-in-HW_COMPAT_RHEL7_1.patch [bz#1318386]
+- kvm-RHEL-Disable-unsupported-PowerPC-CPU-models.patch [bz#1317977]
+- kvm-spec-Use-correct-upstream-QEMU-version.patch [bz#1335705]
+- Resolves: bz#1317977
+  (qemu-kvm-rhev supports a lot of CPU models)
+- Resolves: bz#1318386
+  (pc-rhel7.2.0 machine type definition needs some fixes)
+- Resolves: bz#1335705
+  ('QEMU 2.5.94 monitor' is used for qemu-kvm-rhev-2.6.0-1.el7.x86_64)
+
+* Mon May 23 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-3.el7
+- kvm-qmp-Report-drive_add-error-to-monitor.patch [bz#1337100]
+- kvm-spec-Remove-dependency-to-ipxe-roms-qemu-for-aarch64.patch [bz#1337496]
+- Resolves: bz#1337100
+  (redhat_drive_add should report error to qmp if it fails to initialize)
+- Resolves: bz#1337496
+  (qemu-kvm-rhev should not depend on ipxe-roms-qemu on aarch64)
+
+* Tue May 17 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-2.el7
+- kvm-Fix-SLOF-dependency.patch [bz#1336296]
+- Resolves: bz#1336296
+  (failed dependencies on SLOF)
+
+* Thu May 12 2016 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.6.0-1.el7
+- Rebase to QEMU 2.6.0 [bz#1289417]
+- Resolves: bz#1289417
+  (Rebase to QEMU 2.6)
+
+* Wed Oct 14 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-31.el7
+- kvm-Migration-Generate-the-completed-event-only-when-we-.patch [bz#1271145]
+- Resolves: bz#1271145
+  (Guest OS paused after migration.)
+
+* Mon Oct 12 2015 Jeff E. Nelson <jen@redhat.com> - rhev-2.3.0-30.el7
+- kvm-memhp-extend-address-auto-assignment-to-support-gaps.patch [bz#1267533]
+- kvm-pc-memhp-force-gaps-between-DIMM-s-GPA.patch [bz#1267533]
+- kvm-memory-allow-destroying-a-non-empty-MemoryRegion.patch [bz#1264347]
+- kvm-hw-do-not-pass-NULL-to-memory_region_init-from-insta.patch [bz#1264347]
+- kvm-tests-Fix-how-qom-test-is-run.patch [bz#1264347]
+- kvm-libqtest-Clean-up-unused-QTestState-member-sigact_ol.patch [bz#1264347]
+- kvm-libqtest-New-hmp-friends.patch [bz#1264347]
+- kvm-device-introspect-test-New-covering-device-introspec.patch [bz#1264347]
+- kvm-qmp-Fix-device-list-properties-not-to-crash-for-abst.patch [bz#1264347]
+- kvm-qdev-Protect-device-list-properties-against-broken-d.patch [bz#1264347]
+- kvm-Revert-qdev-Use-qdev_get_device_class-for-device-typ.patch [bz#1264347]
+- Resolves: bz#1264347
+  (QMP device-list-properties crashes for CPU devices)
+- Resolves: bz#1267533
+  (qemu quit when rebooting guest which hotplug memory >=13 times)
+
+* Thu Oct 08 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-29.el7
+- kvm-vfio-Remove-unneeded-union-from-VFIOContainer.patch [bz#1259556]
+- kvm-vfio-Generalize-vfio_listener_region_add-failure-pat.patch [bz#1259556]
+- kvm-vfio-Check-guest-IOVA-ranges-against-host-IOMMU-capa.patch [bz#1259556]
+- kvm-vfio-Record-host-IOMMU-s-available-IO-page-sizes.patch [bz#1259556]
+- kvm-memory-Allow-replay-of-IOMMU-mapping-notifications.patch [bz#1259556]
+- kvm-vfio-Allow-hotplug-of-containers-onto-existing-guest.patch [bz#1259556]
+- kvm-spapr_pci-Allow-PCI-host-bridge-DMA-window-to-be-con.patch [bz#1259556]
+- kvm-spapr_iommu-Rename-vfio_accel-parameter.patch [bz#1259556]
+- kvm-spapr_iommu-Provide-a-function-to-switch-a-TCE-table.patch [bz#1259556]
+- kvm-spapr_pci-Allow-VFIO-devices-to-work-on-the-normal-P.patch [bz#1259556]
+- Resolves: bz#1259556
+  (Allow VFIO devices on the same guest PHB as emulated devices)
+
+* Mon Oct 05 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-28.el7
+- kvm-rhel-Revert-unwanted-cannot_instantiate_with_device_.patch [bz#1224542]
+- kvm-Disable-additional-e1000-models.patch [bz#1224542 bz#1265161]
+- kvm-Remove-intel-iommu-device.patch [bz#1224542]
+- kvm-virtio-net-unbreak-self-announcement-and-guest-offlo.patch [bz#1262232]
+- kvm-block-mirror-fix-full-sync-mode-when-target-does-not.patch [bz#1136382]
+- Resolves: bz#1136382
+  (block: Mirroring to raw block device doesn't zero out unused blocks)
+- Resolves: bz#1224542
+  (unsupported devices need to be disabled in qemu-kvm-rhev after rebasing to 2.3.0)
+- Resolves: bz#1262232
+  (self announcement and ctrl offloads does not work after migration)
+- Resolves: bz#1265161
+  (Support various e1000 variants)
+
+* Wed Sep 30 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-27.el7
+- kvm-sdl2-Fix-RGB555.patch [bz#1247479]
+- kvm-spice-surface-switch-fast-path-requires-same-format-.patch [bz#1247479]
+- kvm-virtio-blk-only-clear-VIRTIO_F_ANY_LAYOUT-for-legacy.patch [bz#1207687]
+- kvm-vhost-enable-vhost-without-without-MSI-X.patch [bz#1207687]
+- kvm-vhost-user-Send-VHOST_RESET_OWNER-on-vhost-stop.patch [bz#1207687]
+- kvm-virtio-avoid-leading-underscores-for-helpers.patch [bz#1207687]
+- kvm-vhost-user-use-VHOST_USER_XXX-macro-for-switch-state.patch [bz#1207687]
+- kvm-vhost-user-add-protocol-feature-negotiation.patch [bz#1207687]
+- kvm-vhost-rename-VHOST_RESET_OWNER-to-VHOST_RESET_DEVICE.patch [bz#1207687]
+- kvm-vhost-user-add-VHOST_USER_GET_QUEUE_NUM-message.patch [bz#1207687]
+- kvm-vhost-introduce-vhost_backend_get_vq_index-method.patch [bz#1207687]
+- kvm-vhost-user-add-multiple-queue-support.patch [bz#1207687]
+- kvm-vhost-user-add-a-new-message-to-disable-enable-a-spe.patch [bz#1207687]
+- Resolves: bz#1207687
+  ([6wind 7.2 FEAT]: vhost-user does not support multique)
+- Resolves: bz#1247479
+  (display mess when boot a win2012-r2-64 guest with -vga std)
+
+* Thu Sep 24 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-26.el7
+- kvm-qcow2-Make-size_to_clusters-return-uint64_t.patch [bz#1260365]
+- kvm-iotests-Add-test-for-checking-large-image-files.patch [bz#1260365]
+- Resolves: bz#1260365
+  (Guest image created coredump after installation.)
+
+* Wed Sep 23 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-25.el7
+- kvm-block-backend-Expose-bdrv_write_zeroes.patch [bz#1256541]
+- kvm-qemu-img-convert-Rewrite-copying-logic.patch [bz#1256541]
+- kvm-main-loop-fix-qemu_notify_event-for-aio_notify-optim.patch [bz#1256541]
+- kvm-error-New-error_fatal.patch [bz#1232308]
+- kvm-Fix-bad-error-handling-after-memory_region_init_ram.patch [bz#1232308]
+- kvm-loader-Fix-memory_region_init_resizeable_ram-error-h.patch [bz#1232308]
+- kvm-memory-Fix-bad-error-handling-in-memory_region_init_.patch [bz#1232308]
+- kvm-spapr_pci-encode-class-code-including-Prog-IF-regist.patch [bz#1264845]
+- kvm-scripts-dump-guest-memory.py-fix-after-RAMBlock-chan.patch [bz#1234802]
+- kvm-spec-Require-proper-version-of-SLOF.patch [bz#1263795]
+- Resolves: bz#1232308
+  ([abrt] qemu-system-x86: qemu_ram_alloc(): qemu-system-x86_64 killed by SIGABRT)
+- Resolves: bz#1234802
+  ([RHEL7.2] dump-guest-memory failed because of Python Exception <class 'gdb.error'> There is no member named length.)
+- Resolves: bz#1256541
+  (qemu-img hangs forever in aio_poll when used to convert some images)
+- Resolves: bz#1263795
+  (vfio device can't be hot unplugged on powerpc guest)
+- Resolves: bz#1264845
+  ([regression] Guest usb mouse/keyboard could not be used on qemu-kvm-rhev-2.3.0-24.el7.ppc64le)
+
+* Fri Sep 18 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-24.el7
+- kvm-spapr-Don-t-use-QOM-syntax-for-DR-connectors.patch [bz#1262143]
+- kvm-virtio-mmio-ioeventfd-support.patch [bz#1185480]
+- kvm-scsi-fix-buffer-overflow-in-scsi_req_parse_cdb-CVE-2.patch [bz#1244334]
+- kvm-spapr-Populate-ibm-associativity-lookup-arrays-corre.patch [bz#1262670]
+- kvm-ppc-spapr-Fix-buffer-overflow-in-spapr_populate_drco.patch [bz#1262670]
+- kvm-spapr_pci-Introduce-a-liobn-number-generating-macros.patch [bz#1263795]
+- kvm-spapr_iommu-Make-spapr_tce_find_by_liobn-public.patch [bz#1263795]
+- kvm-spapr_pci-Rework-device-tree-rendering.patch [bz#1263795]
+- kvm-spapr_pci-enumerate-and-add-PCI-device-tree.patch [bz#1263795]
+- kvm-spapr_pci-populate-ibm-loc-code.patch [bz#1263795]
+- kvm-tests-remove-irrelevant-assertions-from-test-aio.patch [bz#1211689]
+- kvm-aio-posix-move-pollfds-to-thread-local-storage.patch [bz#1211689]
+- kvm-aio-Introduce-type-in-aio_set_fd_handler-and-aio_set.patch [bz#1211689]
+- kvm-aio-Save-type-to-AioHandler.patch [bz#1211689]
+- kvm-aio-posix-Introduce-aio_poll_clients.patch [bz#1211689]
+- kvm-block-Mark-fd-handlers-as-protocol.patch [bz#1211689]
+- kvm-nbd-Mark-fd-handlers-client-type-as-nbd-server.patch [bz#1211689]
+- kvm-aio-Mark-ctx-notifier-s-client-type-as-context.patch [bz#1211689]
+- kvm-dataplane-Mark-host-notifiers-client-type-as-datapla.patch [bz#1211689]
+- kvm-block-Introduce-bdrv_aio_poll.patch [bz#1211689]
+- kvm-block-Replace-nested-aio_poll-with-bdrv_aio_poll.patch [bz#1211689]
+- kvm-block-Only-poll-block-layer-fds-in-bdrv_aio_poll.patch [bz#1211689]
+- Resolves: bz#1185480
+  (backport ioeventfd support for virtio-mmio)
+- Resolves: bz#1211689
+  (atomic live snapshots are not atomic with dataplane-backed devices)
+- Resolves: bz#1244334
+  (qemu-kvm-rhev: Qemu: scsi stack buffer overflow [rhel-7.2])
+- Resolves: bz#1262143
+  (VM startup is very slow with large amounts of hotpluggable memory)
+- Resolves: bz#1262670
+  ([PowerKVM]SIGSEGV when boot up guest with -numa node and set up the cpus in one node to the boundary)
+- Resolves: bz#1263795
+  (vfio device can't be hot unplugged on powerpc guest)
+
+* Tue Sep 15 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-23.el7
+- kvm-scsi-disk-Fix-assertion-failure-on-WRITE-SAME.patch [bz#1247042]
+- kvm-mirror-Speed-up-bitmap-initial-scanning.patch [bz#1259229]
+- kvm-qemu-iotests-Disable-099-requires-blkverify.patch [bz#1257059]
+- kvm-spapr-Reduce-advertised-max-LUNs-for-spapr_vscsi.patch [bz#1260464]
+- kvm-vnc-Don-t-assert-if-opening-unix-socket-fails.patch [bz#1261263]
+- kvm-qcow2-Handle-EAGAIN-returned-from-update_refcount.patch [bz#1254927]
+- kvm-pc-memhotplug-fix-incorrectly-set-reserved-memory-en.patch [bz#1261846]
+- kvm-pc-memhotplug-keep-reserved-memory-end-broken-on-rhe.patch [bz#1261846]
+- Resolves: bz#1247042
+  (qemu quit when using sg_write_same command inside RHEL7.2 guest)
+- Resolves: bz#1254927
+  (qemu-img shows Input/output error when compressing guest image)
+- Resolves: bz#1257059
+  (qemu-iotests 099 failed for vmdk)
+- Resolves: bz#1259229
+  (drive-mirror blocks QEMU due to lseek64() on raw image files)
+- Resolves: bz#1260464
+  (The spapr vscsi disks for lun id '9-31' and channel id '4-7' could not be recognized inside a power pc guest)
+- Resolves: bz#1261263
+  (qemu crash while start a guest with invalid vnc socket path)
+- Resolves: bz#1261846
+  (qemu-kvm-rhev: 64-bit PCI bars may overlap hotplugged memory and vice verse)
+
+* Thu Sep 03 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-22.el7
+- kvm-mirror-Fix-coroutine-reentrance.patch [bz#1251487]
+- kvm-RHEL-Set-vcpus-hard-limit-to-240-for-Power.patch [bz#1257781]
+- kvm-provide-vhost-module-config-file-with-max_mem_region.patch [bz#1255349]
+- Resolves: bz#1251487
+  (qemu core dump when do drive mirror)
+- Resolves: bz#1255349
+  (vhost: default value of 'max_mem_regions' should be set  larger(>=260) than 64)
+- Resolves: bz#1257781
+  (The prompt is confusing when boot a guest with larger vcpu number than host physical cpu)
+
+* Fri Aug 28 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-21.el7
+- kvm-vnc-fix-memory-corruption-CVE-2015-5225.patch [bz#1255898]
+- Resolves: bz#1255898
+  (CVE-2015-5225 qemu-kvm-rhev: Qemu: ui: vnc: heap memory corruption in vnc_refresh_server_surface [rhel-7.2])
+
+* Thu Aug 27 2015 Yash Mankad <ymankad@redhat.com> - rhev-2.3.0-20.el7
+- kvm-pseries-define-coldplugged-devices-as-configured.patch [bz#1243721]
+- kvm-spice-fix-spice_chr_add_watch-pre-condition.patch [bz#1128992]
+- Resolves: bz#1128992
+  (Spiceport character device is not reliable caused domain shutoff)
+- Resolves: bz#1243721
+  (After hotunpug virtio device, the device still exist in pci info)
+
+* Mon Aug 24 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-19.el7
+- kvm-ppc-add-helpful-message-when-KVM-fails-to-start-VCPU.patch [bz#1215618]
+- kvm-pci-allow-0-address-for-PCI-IO-MEM-regions.patch [bz#1241886]
+- kvm-RHEL-Suppress-scary-but-unimportant-errors-for-KVM-V.patch [bz#1237034]
+- Resolves: bz#1215618
+  (Unhelpful error message on Power when SMT is enabled)
+- Resolves: bz#1237034
+  (Error prompt while booting with vfio-pci device)
+- Resolves: bz#1241886
+  (hot plugged pci devices won't appear unless reboot)
+
+* Fri Aug 14 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-18.el7
+- kvm-vhost-correctly-pass-error-to-caller-in-vhost_dev_en.patch [bz#1248312]
+- kvm-Revert-virtio-net-enable-virtio-1.0.patch [bz#1248312]
+- kvm-virtio-net-unbreak-any-layout.patch [bz#1248312]
+- kvm-virtio-hide-legacy-features-from-modern-guests.patch [bz#1248312]
+- kvm-virtio-serial-fix-ANY_LAYOUT.patch [bz#1248312]
+- kvm-virtio-9p-fix-any_layout.patch [bz#1248312]
+- kvm-virtio-set-any_layout-in-virtio-core.patch [bz#1248312]
+- kvm-virtio-pci-fix-memory-MR-cleanup-for-modern.patch [bz#1248312]
+- kvm-virtio-get_features-can-fail.patch [bz#1248312]
+- kvm-virtio-blk-fail-get_features-when-both-scsi-and-1.0-.patch [bz#1248312]
+- kvm-virtio-minor-cleanup.patch [bz#1248312]
+- kvm-memory-do-not-add-a-reference-to-the-owner-of-aliase.patch [bz#1248312]
+- kvm-virtio-net-remove-virtio-queues-if-the-guest-doesn-t.patch [bz#1248312]
+- kvm-virtio-fix-1.0-virtqueue-migration.patch [bz#1248312]
+- kvm-Downstream-only-Start-kvm-setup-service-before-libvi.patch [bz#1251962]
+- kvm-qcow2-Flush-pending-discards-before-allocating-clust.patch [bz#1226297]
+- Resolves: bz#1226297
+  (qcow2 crash during discard operation)
+- Resolves: bz#1248312
+  ("fdisk -l"can not output anything and the process status is D+ after migrating RHEL7.2 guest with virtio-1 virtio-scsi disk)
+- Resolves: bz#1251962
+  (kvm-setup.service should include Before=libvirtd.service)
+
+* Wed Aug 12 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-17.el7
+- kvm-migration-avoid-divide-by-zero-in-xbzrle-cache-miss-.patch [bz#580006]
+- kvm-migration-move-ram-stuff-to-migration-ram.patch [bz#580006]
+- kvm-migration-move-savevm.c-inside-migration.patch [bz#580006]
+- kvm-migration-Add-myself-to-the-copyright-list-of-both-f.patch [bz#580006]
+- kvm-migration-reduce-include-files.patch [bz#580006]
+- kvm-migration-Remove-duplicated-assignment-of-SETUP-stat.patch [bz#580006]
+- kvm-migration-create-savevm_state.patch [bz#580006]
+- kvm-migration-Use-normal-VMStateDescriptions-for-Subsect.patch [bz#580006]
+- kvm-Add-qemu_get_counted_string-to-read-a-string-prefixe.patch [bz#580006]
+- kvm-runstate-Add-runstate-store.patch [bz#580006]
+- kvm-runstate-migration-allows-more-transitions-now.patch [bz#580006]
+- kvm-migration-create-new-section-to-store-global-state.patch [bz#580006]
+- kvm-global_state-Make-section-optional.patch [bz#580006]
+- kvm-vmstate-Create-optional-sections.patch [bz#580006]
+- kvm-migration-Add-configuration-section.patch [bz#580006]
+- kvm-migration-ensure-we-start-in-NONE-state.patch [bz#580006]
+- kvm-migration-Use-always-helper-to-set-state.patch [bz#580006]
+- kvm-migration-No-need-to-call-trace_migrate_set_state.patch [bz#580006]
+- kvm-migration-create-migration-event.patch [bz#580006]
+- kvm-migration-Make-events-a-capability.patch [bz#580006]
+- kvm-migration-Add-migration-events-on-target-side.patch [bz#580006]
+- kvm-migration-Only-change-state-after-migration-has-fini.patch [bz#580006]
+- kvm-migration-Trace-event-and-migration-event-are-differ.patch [bz#580006]
+- kvm-migration-Write-documetation-for-events-capabilites.patch [bz#580006]
+- kvm-migration-Register-global-state-section-before-loadv.patch [bz#580006]
+- kvm-migration-We-also-want-to-store-the-global-state-for.patch [bz#580006]
+- kvm-block-mirror-limit-qiov-to-IOV_MAX-elements.patch [bz#1238585]
+- kvm-i6300esb-fix-timer-overflow.patch [bz#1247893]
+- Resolves: bz#1238585
+  (drive-mirror has spurious failures with low 'granularity' values)
+- Resolves: bz#1247893
+  (qemu's i6300esb watchdog does not fire on time with large heartbeat like 2046)
+- Resolves: bz#580006
+  (QMP: A QMP event notification when migration finish.)
+
+* Fri Aug 07 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-16.el7
+- kvm-virtio-scsi-use-virtqueue_map_sg-when-loading-reques.patch [bz#1160169]
+- kvm-scsi-disk-fix-cmd.mode-field-typo.patch [bz#1160169]
+- kvm-target-i386-emulate-CPUID-level-of-real-hardware.patch [bz#1223317]
+- kvm-target-i386-fix-IvyBridge-xlevel-in-PC_COMPAT_2_3.patch [bz#1223317]
+- Resolves: bz#1160169
+  (Segfault occurred at Dst VM while completed migration upon ENOSPC)
+- Resolves: bz#1223317
+  (BSod occurs When installing latest Windows Enterprise Insider 10 and windows server 2016 Preview)
+
+* Wed Aug 05 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-15.el7
+- kvm-usb-ccid-add-missing-wakeup-calls.patch [bz#1211970]
+- kvm-vfio-pci-Fix-bootindex.patch [bz#1245127]
+- kvm-acpi-fix-pvpanic-device-is-not-shown-in-ui.patch [bz#1238141]
+- kvm-redhat-add-kvm-unit-tests-tarball-to-environment.patch [bz#1225980]
+- kvm-spec-Build-tscdeadline_latency.flat-from-kvm-unit-te.patch [bz#1225980]
+- Resolves: bz#1211970
+  (smart card emulation doesn't work with USB3 (nec-xhci) controller)
+- Resolves: bz#1225980
+  (Package tscdeadline_latency.flat with qemu-kvm-rhev)
+- Resolves: bz#1238141
+  ([virtio-win][pvpanic]win10-32 guest can not detect pvpanic device in device manager)
+- Resolves: bz#1245127
+  (bootindex doesn't work for vfio-pci)
+
+* Fri Jul 31 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-14.el7
+- kvm-rtl8139-avoid-nested-ifs-in-IP-header-parsing-CVE-20.patch [bz#1248768]
+- kvm-rtl8139-drop-tautologous-if-ip-.-statement-CVE-2015-.patch [bz#1248768]
+- kvm-rtl8139-skip-offload-on-short-Ethernet-IP-header-CVE.patch [bz#1248768]
+- kvm-rtl8139-check-IP-Header-Length-field-CVE-2015-5165.patch [bz#1248768]
+- kvm-rtl8139-check-IP-Total-Length-field-CVE-2015-5165.patch [bz#1248768]
+- kvm-rtl8139-skip-offload-on-short-TCP-header-CVE-2015-51.patch [bz#1248768]
+- kvm-rtl8139-check-TCP-Data-Offset-field-CVE-2015-5165.patch [bz#1248768]
+- Resolves: bz#1248768
+  (EMBARGOED CVE-2015-5165 qemu-kvm-rhev: Qemu: rtl8139 uninitialized heap memory information leakage to guest [rhel-7.2])
+
+* Fri Jul 24 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-13.el7
+- kvm-block-Add-bdrv_get_block_status_above.patch [bz#1242316]
+- kvm-qmp-Add-optional-bool-unmap-to-drive-mirror.patch [bz#1242316]
+- kvm-mirror-Do-zero-write-on-target-if-sectors-not-alloca.patch [bz#1242316]
+- kvm-block-Fix-dirty-bitmap-in-bdrv_co_discard.patch [bz#1242316]
+- kvm-block-Remove-bdrv_reset_dirty.patch [bz#1242316]
+- kvm-iotests-add-QMP-event-waiting-queue.patch [bz#1242316]
+- kvm-qemu-iotests-Make-block-job-methods-common.patch [bz#1242316]
+- kvm-qemu-iotests-Add-test-case-for-mirror-with-unmap.patch [bz#1242316]
+- kvm-iotests-Use-event_wait-in-wait_ready.patch [bz#1242316]
+- kvm-rdma-fix-memory-leak.patch [bz#1210715]
+- kvm-Only-try-and-read-a-VMDescription-if-it-should-be-th.patch [bz#1210715]
+- kvm-qemu_ram_foreach_block-pass-up-error-value-and-down-.patch [bz#1210715]
+- kvm-rdma-Fix-qemu-crash-when-IPv6-address-is-used-for-mi.patch [bz#1210715]
+- kvm-Rename-RDMA-structures-to-make-destination-clear.patch [bz#1210715]
+- kvm-Remove-unneeded-memset.patch [bz#1210715]
+- kvm-rdma-typos.patch [bz#1210715]
+- kvm-Store-block-name-in-local-blocks-structure.patch [bz#1210715]
+- kvm-Translate-offsets-to-destination-address-space.patch [bz#1210715]
+- kvm-Rework-ram_control_load_hook-to-hook-during-block-lo.patch [bz#1210715]
+- kvm-Allow-rdma_delete_block-to-work-without-the-hash.patch [bz#1210715]
+- kvm-Rework-ram-block-hash.patch [bz#1210715]
+- kvm-Sort-destination-RAMBlocks-to-be-the-same-as-the-sou.patch [bz#1210715]
+- kvm-Sanity-check-RDMA-remote-data.patch [bz#1210715]
+- kvm-Fail-more-cleanly-in-mismatched-RAM-cases.patch [bz#1210715]
+- kvm-migration-Use-cmpxchg-correctly.patch [bz#1210715]
+- kvm-RDMA-Fix-error-exits-for-2.4.patch [bz#1210715]
+- kvm-block-mirror-Sleep-periodically-during-bitmap-scanni.patch [bz#1233826]
+- kvm-block-curl-Don-t-lose-original-error-when-a-connecti.patch [bz#1235813]
+- kvm-vfio-pci-Add-pba_offset-PCI-quirk-for-Chelsio-T5-dev.patch [bz#1244348]
+- kvm-hostmem-Fix-qemu_opt_get_bool-crash-in-host_memory_b.patch [bz#1237220]
+- kvm-pc-pc-dimm-Extract-hotplug-related-fields-in-PCMachi.patch [bz#1211117]
+- kvm-pc-pc-dimm-Factor-out-reusable-parts-in-pc_dimm_plug.patch [bz#1211117]
+- kvm-pc-Abort-if-HotplugHandlerClass-plug-fails.patch [bz#1211117]
+- kvm-numa-pc-dimm-Store-pc-dimm-memory-information-in-num.patch [bz#1211117]
+- kvm-numa-Store-boot-memory-address-range-in-node_info.patch [bz#1211117]
+- kvm-numa-API-to-lookup-NUMA-node-by-address.patch [bz#1211117]
+- kvm-docs-add-sPAPR-hotplug-dynamic-reconfiguration-docum.patch [bz#1211117]
+- kvm-machine-add-default_ram_size-to-machine-class.patch [bz#1211117]
+- kvm-spapr-override-default-ram-size-to-512MB.patch [bz#1211117]
+- kvm-spapr_pci-Make-find_phb-find_dev-public.patch [bz#1211117]
+- kvm-spapr-Merge-sPAPREnvironment-into-sPAPRMachineState.patch [bz#1211117]
+- kvm-spapr-Remove-obsolete-ram_limit-field-from-sPAPRMach.patch [bz#1211117]
+- kvm-spapr-Remove-obsolete-entry_point-field-from-sPAPRMa.patch [bz#1211117]
+- kvm-spapr-Add-sPAPRMachineClass.patch [bz#1211117]
+- kvm-spapr-ensure-we-have-at-least-one-XICS-server.patch [bz#1211117]
+- kvm-spapr-Consider-max_cpus-during-xics-initialization.patch [bz#1211117]
+- kvm-spapr-Support-ibm-lrdr-capacity-device-tree-property.patch [bz#1211117]
+- kvm-cpus-Add-a-macro-to-walk-CPUs-in-reverse.patch [bz#1211117]
+- kvm-spapr-Reorganize-CPU-dt-generation-code.patch [bz#1211117]
+- kvm-spapr-Consolidate-cpu-init-code-into-a-routine.patch [bz#1211117]
+- kvm-ppc-Update-cpu_model-in-MachineState.patch [bz#1211117]
+- kvm-xics_kvm-Don-t-enable-KVM_CAP_IRQ_XICS-if-already-en.patch [bz#1211117]
+- kvm-spapr-Initialize-hotplug-memory-address-space.patch [bz#1211117]
+- kvm-spapr-Add-LMB-DR-connectors.patch [bz#1211117]
+- kvm-spapr-Support-ibm-dynamic-reconfiguration-memory.patch [bz#1211117]
+- kvm-spapr-Make-hash-table-size-a-factor-of-maxram_size.patch [bz#1211117]
+- kvm-spapr-Memory-hotplug-support.patch [bz#1211117]
+- kvm-spapr-Don-t-allow-memory-hotplug-to-memory-less-node.patch [bz#1211117]
+- Resolves: bz#1210715
+  (migration/rdma: 7.1->7.2: RDMA ERROR: ram blocks mismatch #3!)
+- Resolves: bz#1211117
+  (add support for memory hotplug on Power)
+- Resolves: bz#1233826
+  (issueing drive-mirror command causes monitor unresponsive)
+- Resolves: bz#1235813
+  (block/curl: Fix generic "Input/output error" on failure)
+- Resolves: bz#1237220
+  (Fail to create NUMA guest with <nosharepages/>)
+- Resolves: bz#1242316
+  (Add "unmap" support for drive-mirror)
+- Resolves: bz#1244348
+  (Quirk for Chelsio T5 MSI-X PBA)
+
+* Fri Jul 17 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-12.el7
+- kvm-ide-Check-array-bounds-before-writing-to-io_buffer-C.patch [bz#1243692]
+- kvm-ide-atapi-Fix-START-STOP-UNIT-command-completion.patch [bz#1243692]
+- kvm-ide-Clear-DRQ-after-handling-all-expected-accesses.patch [bz#1243692]
+- Resolves: bz#1243692
+  ()
+
+* Fri Jul 17 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-11.el7
+- kvm-hw-acpi-acpi_pm1_cnt_init-take-disable_s3-and-disabl.patch [bz#1204696]
+- kvm-hw-acpi-move-etc-system-states-fw_cfg-file-from-PIIX.patch [bz#1204696]
+- kvm-hw-acpi-piix4_pm_init-take-fw_cfg-object-no-more.patch [bz#1204696]
+- kvm-i386-pc-pc_basic_device_init-delegate-FDC-creation-r.patch [bz#1227282]
+- kvm-i386-pc-drive-if-floppy-should-imply-a-board-default.patch [bz#1227282]
+- kvm-i386-pc_q35-don-t-insist-on-board-FDC-if-there-s-no-.patch [bz#1227282]
+- kvm-i386-drop-FDC-in-pc-q35-rhel7.2.0-if-neither-it-nor-.patch [bz#1227282]
+- kvm-hw-i386-pc-factor-out-pc_cmos_init_floppy.patch [bz#1227282]
+- kvm-hw-i386-pc-reflect-any-FDC-ioport-0x3f0-in-the-CMOS.patch [bz#1227282]
+- kvm-hw-i386-pc-don-t-carry-FDC-from-pc_basic_device_init.patch [bz#1227282]
+- kvm-Fix-reported-machine-type.patch [bz#1241331]
+- kvm-i386-acpi-build-more-traditional-_UID-and-_HID-for-P.patch [bz#1242479]
+- kvm-i386-acpi-build-fix-PXB-workarounds-for-unsupported-.patch [bz#1242479]
+- kvm-hw-core-rebase-sysbus_get_fw_dev_path-to-g_strdup_pr.patch [bz#1242479]
+- kvm-migration-introduce-VMSTATE_BUFFER_UNSAFE_INFO_TEST.patch [bz#1242479]
+- kvm-hw-pci-bridge-expose-_test-parameter-in-SHPC_VMSTATE.patch [bz#1242479]
+- kvm-hw-pci-bridge-add-macro-for-chassis_nr-property.patch [bz#1242479]
+- kvm-hw-pci-bridge-add-macro-for-msi-property.patch [bz#1242479]
+- kvm-hw-pci-introduce-shpc_present-helper-function.patch [bz#1242479]
+- kvm-hw-pci-bridge-introduce-shpc-property.patch [bz#1242479]
+- kvm-hw-pci-bridge-disable-SHPC-in-PXB.patch [bz#1242479]
+- kvm-hw-core-explicit-OFW-unit-address-callback-for-SysBu.patch [bz#1242479]
+- kvm-hw-pci-bridge-format-special-OFW-unit-address-for-PX.patch [bz#1242479]
+- Resolves: bz#1204696
+  (Expose PM system states in fw_cfg file on Q35)
+- Resolves: bz#1227282
+  (tighten conditions for board-implied FDC in pc-q35-rhel7.2.0+)
+- Resolves: bz#1241331
+  (Machine type reported by guest is different with that in RHEL.7.1 GA version)
+- Resolves: bz#1242479
+  (backport QEMU changes needed for supporting multiple PCI root buses with OVMF)
+
+* Tue Jul 14 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-10.el7
+- kvm-Disable-Educational-device.patch [bz#1194151]
+- kvm-Disable-sdhci-device.patch [bz#1194151]
+- kvm-Mark-onboard-devices-as-cannot_instantiate_with_devi.patch [bz#1194151]
+- kvm-target-arm-Add-GIC-phandle-to-VirtBoardInfo.patch [bz#1231929]
+- kvm-arm_gicv2m-Add-GICv2m-widget-to-support-MSIs.patch [bz#1231929]
+- kvm-target-arm-Extend-the-gic-node-properties.patch [bz#1231929]
+- kvm-target-arm-Add-the-GICv2m-to-the-virt-board.patch [bz#1231929]
+- kvm-introduce-kvm_arch_msi_data_to_gsi.patch [bz#1231929]
+- kvm-arm_gicv2m-set-kvm_gsi_direct_mapping-and-kvm_msi_vi.patch [bz#1231929]
+- kvm-hw-arm-virt-acpi-build-Fix-table-revision-and-some-c.patch [bz#1231929]
+- kvm-hw-arm-virt-acpi-build-Add-GICv2m-description-in-ACP.patch [bz#1231929]
+- Resolves: bz#1194151
+  (Rebase to qemu 2.3)
+- Resolves: bz#1231929
+  (AArch64: backport MSI support (gicv2m))
+
+* Thu Jul 09 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-9.el7
+- kvm-acpi-add-a-missing-backslash-to-the-_SB-scope.patch [bz#1103313]
+- kvm-range-remove-useless-inclusions.patch [bz#1103313]
+- kvm-acpi-Simplify-printing-to-dynamic-string.patch [bz#1103313]
+- kvm-acpi-add-aml_add-term.patch [bz#1103313]
+- kvm-acpi-add-aml_lless-term.patch [bz#1103313]
+- kvm-acpi-add-aml_index-term.patch [bz#1103313]
+- kvm-acpi-add-aml_shiftleft-term.patch [bz#1103313]
+- kvm-acpi-add-aml_shiftright-term.patch [bz#1103313]
+- kvm-acpi-add-aml_increment-term.patch [bz#1103313]
+- kvm-acpi-add-aml_while-term.patch [bz#1103313]
+- kvm-acpi-add-implementation-of-aml_while-term.patch [bz#1103313]
+- kvm-hw-pci-made-pci_bus_is_root-a-PCIBusClass-method.patch [bz#1103313]
+- kvm-hw-pci-made-pci_bus_num-a-PCIBusClass-method.patch [bz#1103313]
+- kvm-hw-i386-query-only-for-q35-pc-when-looking-for-pci-h.patch [bz#1103313]
+- kvm-hw-pci-extend-PCI-config-access-to-support-devices-b.patch [bz#1103313]
+- kvm-hw-acpi-add-support-for-i440fx-snooping-root-busses.patch [bz#1103313]
+- kvm-hw-apci-add-_PRT-method-for-extra-PCI-root-busses.patch [bz#1103313]
+- kvm-hw-acpi-add-_CRS-method-for-extra-root-busses.patch [bz#1103313]
+- kvm-hw-acpi-remove-from-root-bus-0-the-crs-resources-use.patch [bz#1103313]
+- kvm-hw-pci-removed-rootbus-nr-is-0-assumption-from-qmp_p.patch [bz#1103313]
+- kvm-hw-pci-introduce-PCI-Expander-Bridge-PXB.patch [bz#1103313]
+- kvm-hw-pci-inform-bios-if-the-system-has-extra-pci-root-.patch [bz#1103313]
+- kvm-hw-pxb-add-map_irq-func.patch [bz#1103313]
+- kvm-hw-pci-add-support-for-NUMA-nodes.patch [bz#1103313]
+- kvm-hw-pxb-add-numa_node-parameter.patch [bz#1103313]
+- kvm-apci-fix-PXB-behaviour-if-used-with-unsupported-BIOS.patch [bz#1103313]
+- kvm-docs-Add-PXB-documentation.patch [bz#1103313]
+- kvm-sPAPR-Don-t-enable-EEH-on-emulated-PCI-devices.patch [bz#1213681]
+- kvm-sPAPR-Reenable-EEH-functionality-on-reboot.patch [bz#1213681]
+- kvm-sPAPR-Clear-stale-MSIx-table-during-EEH-reset.patch [bz#1213681]
+- kvm-configure-Add-support-for-tcmalloc.patch [bz#1213882]
+- Resolves: bz#1103313
+  (RFE: configure guest NUMA node locality for guest PCI devices)
+- Resolves: bz#1213681
+  (PAPR PCI-e EEH (Enhanced Error Handling) for KVM/Power guests with VFIO devices (qemu))
+- Resolves: bz#1213882
+  (enable using tcmalloc for memory allocation in qemu-kvm-rhev)
+
+* Wed Jul 08 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-8.el7
+- kvm-block-Fix-NULL-deference-for-unaligned-write-if-qiov.patch [bz#1207034]
+- kvm-qemu-iotests-Test-unaligned-sub-block-zero-write.patch [bz#1207034]
+- kvm-spapr_drc-initial-implementation-of-sPAPRDRConnector.patch [bz#1172478]
+- kvm-spapr_rtas-add-get-set-power-level-RTAS-interfaces.patch [bz#1172478]
+- kvm-spapr_rtas-add-set-indicator-RTAS-interface.patch [bz#1172478]
+- kvm-spapr_rtas-add-get-sensor-state-RTAS-interface.patch [bz#1172478]
+- kvm-spapr-add-rtas_st_buffer_direct-helper.patch [bz#1172478]
+- kvm-spapr_rtas-add-ibm-configure-connector-RTAS-interfac.patch [bz#1172478]
+- kvm-spapr_events-re-use-EPOW-event-infrastructure-for-ho.patch [bz#1172478]
+- kvm-spapr_events-event-scan-RTAS-interface.patch [bz#1172478]
+- kvm-spapr_drc-add-spapr_drc_populate_dt.patch [bz#1172478]
+- kvm-spapr_pci-add-dynamic-reconfiguration-option-for-spa.patch [bz#1172478]
+- kvm-spapr_pci-create-DRConnectors-for-each-PCI-slot-duri.patch [bz#1172478]
+- kvm-pci-make-pci_bar-useable-outside-pci.c.patch [bz#1172478]
+- kvm-spapr_pci-enable-basic-hotplug-operations.patch [bz#1172478]
+- kvm-spapr_pci-emit-hotplug-add-remove-events-during-hotp.patch [bz#1172478]
+- kvm-Print-error-when-failing-to-load-PCI-config-data.patch [bz#1209793]
+- kvm-Fix-ich9-intel-hda-compatibility.patch [bz#1209793]
+- kvm-pseries-Enable-in-kernel-H_LOGICAL_CI_-LOAD-STORE-im.patch [bz#1217277]
+- kvm-Split-serial-isa-into-its-own-config-option.patch [bz#1191845]
+- kvm-rhel-Disable-info-irq-and-info-pic-for-Power.patch [bz#1191845]
+- kvm-RHEL-Disable-remaining-unsupported-devices-for-ppc.patch [bz#1191845]
+- kvm-linux-headers-sync-vhost.h.patch [bz#1225715]
+- kvm-virtio-introduce-virtio_legacy_is_cross_endian.patch [bz#1225715]
+- kvm-vhost-set-vring-endianness-for-legacy-virtio.patch [bz#1225715]
+- kvm-tap-add-VNET_LE-VNET_BE-operations.patch [bz#1225715]
+- kvm-tap-fix-non-linux-build.patch [bz#1225715]
+- kvm-vhost-net-tell-tap-backend-about-the-vnet-endianness.patch [bz#1225715]
+- kvm-vhost_net-re-enable-when-cross-endian.patch [bz#1225715]
+- kvm-linux-headers-update.patch [bz#1227343]
+- kvm-virtio-input-add-linux-input.h.patch [bz#1227343]
+- kvm-virtio-input-core-code-base-class-device.patch [bz#1227343]
+- kvm-virtio-input-emulated-devices-device.patch [bz#1227343]
+- kvm-virtio-net-Move-DEFINE_VIRTIO_NET_FEATURES-to-virtio.patch [bz#1227343]
+- kvm-virtio-scsi-Move-DEFINE_VIRTIO_SCSI_FEATURES-to-virt.patch [bz#1227343]
+- kvm-memory-Define-API-for-MemoryRegionOps-to-take-attrs-.patch [bz#1227343]
+- kvm-memory-Replace-io_mem_read-write-with-memory_region_.patch [bz#1227343]
+- kvm-Make-CPU-iotlb-a-structure-rather-than-a-plain-hwadd.patch [bz#1227343]
+- kvm-Add-MemTxAttrs-to-the-IOTLB.patch [bz#1227343]
+- kvm-exec.c-Convert-subpage-memory-ops-to-_with_attrs.patch [bz#1227343]
+- kvm-exec.c-Make-address_space_rw-take-transaction-attrib.patch [bz#1227343]
+- kvm-exec.c-Add-new-address_space_ld-st-functions.patch [bz#1227343]
+- kvm-Switch-non-CPU-callers-from-ld-st-_phys-to-address_s.patch [bz#1227343]
+- kvm-s390-virtio-sort-into-categories.patch [bz#1227343]
+- kvm-s390-virtio-use-common-features.patch [bz#1227343]
+- kvm-virtio-move-host_features.patch [bz#1227343]
+- kvm-virtio-ccw-Don-t-advertise-VIRTIO_F_BAD_FEATURE.patch [bz#1227343]
+- kvm-virtio-move-VIRTIO_F_NOTIFY_ON_EMPTY-into-core.patch [bz#1227343]
+- kvm-qdev-add-64bit-properties.patch [bz#1227343]
+- kvm-virtio-make-features-64bit-wide.patch [bz#1227343]
+- kvm-virtio-input-const_le16-and-const_le32-not-build-tim.patch [bz#1227343]
+- kvm-virtio-input-make-virtio-devices-follow-usual-naming.patch [bz#1227343]
+- kvm-virtio-64bit-features-fixups.patch [bz#1227343]
+- kvm-virtio-endianness-checks-for-virtio-1.0-devices.patch [bz#1227343]
+- kvm-virtio-allow-virtio-1-queue-layout.patch [bz#1227343]
+- kvm-virtio-disallow-late-feature-changes-for-virtio-1.patch [bz#1227343]
+- kvm-virtio-allow-to-fail-setting-status.patch [bz#1227343]
+- kvm-virtio-net-no-writeable-mac-for-virtio-1.patch [bz#1227343]
+- kvm-virtio-net-support-longer-header.patch [bz#1227343]
+- kvm-virtio-net-enable-virtio-1.0.patch [bz#1227343]
+- kvm-vhost_net-add-version_1-feature.patch [bz#1227343]
+- kvm-vhost-64-bit-features.patch [bz#1227343]
+- kvm-linux-headers-add-virtio_pci.patch [bz#1227343]
+- kvm-virtio-pci-initial-virtio-1.0-support.patch [bz#1227343]
+- kvm-virtio-generation-counter-support.patch [bz#1227343]
+- kvm-virtio-add-modern-config-accessors.patch [bz#1227343]
+- kvm-virtio-pci-switch-to-modern-accessors-for-1.0.patch [bz#1227343]
+- kvm-virtio-pci-add-flags-to-enable-disable-legacy-modern.patch [bz#1227343]
+- kvm-virtio-pci-make-QEMU_VIRTIO_PCI_QUEUE_MEM_MULT-small.patch [bz#1227343]
+- kvm-virtio-pci-change-document-virtio-pci-bar-layout.patch [bz#1227343]
+- kvm-virtio-pci-make-modern-bar-64bit-prefetchable.patch [bz#1227343]
+- kvm-virtio-pci-correctly-set-host-notifiers-for-modern-b.patch [bz#1227343]
+- kvm-virtio_balloon-header-update.patch [bz#1227343]
+- kvm-virtio-balloon-switch-to-virtio_add_feature.patch [bz#1227343]
+- kvm-virtio-pci-add-struct-VirtIOPCIRegion-for-virtio-1-r.patch [bz#1227343]
+- kvm-virtio-pci-add-virtio_pci_modern_regions_init.patch [bz#1227343]
+- kvm-virtio-pci-add-virtio_pci_modern_region_map.patch [bz#1227343]
+- kvm-virtio-pci-move-virtio_pci_add_mem_cap-call-to-virti.patch [bz#1227343]
+- kvm-virtio-pci-move-cap-type-to-VirtIOPCIRegion.patch [bz#1227343]
+- kvm-virtio-pci-drop-identical-virtio_pci_cap.patch [bz#1227343]
+- kvm-virtio-pci-fill-VirtIOPCIRegions-early.patch [bz#1227343]
+- kvm-pci-add-PCI_CLASS_INPUT_.patch [bz#1227343]
+- kvm-virtio-input-core-code-base-class-pci.patch [bz#1227343]
+- kvm-virtio-input-emulated-devices-pci.patch [bz#1227343]
+- kvm-virtio-net-move-qdev-properties-into-virtio-net.c.patch [bz#1227343]
+- kvm-virtio-net.h-Remove-unsed-DEFINE_VIRTIO_NET_PROPERTI.patch [bz#1227343]
+- kvm-virtio-scsi-move-qdev-properties-into-virtio-scsi.c.patch [bz#1227343]
+- kvm-virtio-rng-move-qdev-properties-into-virtio-rng.c.patch [bz#1227343]
+- kvm-virtio-serial-bus-move-qdev-properties-into-virtio-s.patch [bz#1227343]
+- kvm-virtio-9p-device-move-qdev-properties-into-virtio-9p.patch [bz#1227343]
+- kvm-vhost-scsi-move-qdev-properties-into-vhost-scsi.c.patch [bz#1227343]
+- kvm-virito-pci-fix-OVERRUN-problem.patch [bz#1227343]
+- kvm-virtio-input-move-properties-use-virtio_instance_ini.patch [bz#1227343]
+- kvm-virtio-input-evdev-passthrough.patch [bz#1227343]
+- kvm-Add-MAINTAINERS-entry-for-virtio-input.patch [bz#1227343]
+- kvm-virtio-input-add-input-routing-support.patch [bz#1227343]
+- kvm-dataplane-fix-cross-endian-issues.patch [bz#1227343]
+- kvm-aarch64-allow-enable-seccomp.patch [bz#1174861]
+- kvm-aarch64-redhat-spec-enable-seccomp.patch [bz#1174861]
+- kvm-rhel-Update-package-version-for-SLOF-dependency.patch [bz#1236447]
+- Resolves: bz#1172478
+  (add support for PCI hotplugging)
+- Resolves: bz#1174861
+  (use seccomp)
+- Resolves: bz#1191845
+  ([PowerKVM] There are some unsupported x86 devices under the output of cmds 'man qemu-kvm' and '/usr/libexec/qemu-kvm -device help')
+- Resolves: bz#1207034
+  (QEMU segfault when doing unaligned zero write to non-512 disk)
+- Resolves: bz#1209793
+  (migration: 7.1->7.2 error while loading state for instance 0x0 of device '0000:00:04.0/intel-hda')
+- Resolves: bz#1217277
+  (Enable KVM implementation of H_LOGICAL_CI_{LOAD,STORE})
+- Resolves: bz#1225715
+  (Enable cross-endian vhost devices)
+- Resolves: bz#1227343
+  ([virtio-1] QEMU Virtio-1 Support)
+- Resolves: bz#1236447
+  (Update qemu-kvm-rhev package for new SLOF)
+
+* Thu Jul 02 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-7.el7
+- kvm-docs-update-documentation-for-memory-hot-unplug.patch [bz#1120706]
+- kvm-acpi-mem-hotplug-add-acpi_memory_slot_status-to-get-.patch [bz#1120706]
+- kvm-acpi-mem-hotplug-add-unplug-request-cb-for-memory-de.patch [bz#1120706]
+- kvm-acpi-mem-hotplug-add-unplug-cb-for-memory-device.patch [bz#1120706]
+- kvm-acpi-extend-aml_field-to-support-UpdateRule.patch [bz#1120706]
+- kvm-acpi-fix-Memory-device-control-fields-register.patch [bz#1120706]
+- kvm-acpi-add-hardware-implementation-for-memory-hot-unpl.patch [bz#1120706]
+- kvm-qmp-event-add-event-notification-for-memory-hot-unpl.patch [bz#1120706]
+- kvm-hw-acpi-aml-build-Fix-memory-leak.patch [bz#1120706]
+- kvm-memory-add-memory_region_ram_resize.patch [bz#1231719]
+- kvm-acpi-build-remove-dependency-from-ram_addr.h.patch [bz#1231719]
+- kvm-hw-i386-Move-ACPI-header-definitions-in-an-arch-inde.patch [bz#1231719]
+- kvm-hw-i386-acpi-build-move-generic-acpi-building-helper.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Make-enum-values-to-be-upper-case-.patch [bz#1231719]
+- kvm-hw-arm-virt-Move-common-definitions-to-virt.h.patch [bz#1231719]
+- kvm-hw-arm-virt-Record-PCIe-ranges-in-MemMapEntry-array.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Basic-framework-for-building-.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_memory32_fixed-term.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_interrupt-term.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generation-of-DSDT-table-for-.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generate-FADT-table-and-updat.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generate-MADT-table.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generate-GTDT-table.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generate-RSDT-table.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generate-RSDP-table.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Generate-MCFG-table.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Make-aml_buffer-definition-consist.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-ToUUID-macro.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_or-term.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_lnot-term.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_else-term.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_create_dword_field-term.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-aml_dword_io-term.patch [bz#1231719]
+- kvm-hw-acpi-aml-build-Add-Unicode-macro.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Add-PCIe-controller-in-ACPI-D.patch [bz#1231719]
+- kvm-ACPI-split-CONFIG_ACPI-into-4-pieces.patch [bz#1231719]
+- kvm-hw-arm-virt-Enable-dynamic-generation-of-ACPI-v5.1-t.patch [bz#1231719]
+- kvm-ACPI-Add-definitions-for-the-SPCR-table.patch [bz#1231719]
+- kvm-hw-arm-virt-acpi-build-Add-SPCR-table.patch [bz#1231719]
+- kvm-AArch64-Enable-ACPI.patch [bz#1231719]
+- kvm-i8254-fix-out-of-bounds-memory-access-in-pit_ioport_.patch [bz#1229647]
+- kvm-hw-q35-fix-floppy-controller-definition-in-ich9.patch [bz#894956]
+- kvm-Migration-compat-for-pckbd.patch [bz#1215092]
+- kvm-Migration-compat-for-fdc.patch [bz#1215091]
+- Resolves: bz#1120706
+  (Support dynamic virtual Memory deallocation - qemu-kvm)
+- Resolves: bz#1215091
+  (migration: 7.2->earlier; floppy compatibility)
+- Resolves: bz#1215092
+  (migration: 7.2->earlier: pckbd compatibility)
+- Resolves: bz#1229647
+  (CVE-2015-3214 qemu-kvm-rhev: qemu: i8254: out-of-bounds memory access in pit_ioport_read function [rhel-7.2])
+- Resolves: bz#1231719
+  (AArch64: backport ACPI support)
+- Resolves: bz#894956
+  (floppy can not be recognized by Windows guest (q35))
+
+* Fri Jun 26 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-6.el7
+- kvm-vfio-pci-Fix-error-path-sign.patch [bz#1219090]
+- kvm-vfio-pci-Further-fix-BAR-size-overflow.patch [bz#1219090]
+- kvm-Add-flag-for-pre-2.2-migration-compatibility.patch [bz#1215087]
+- kvm-Serial-Migration-compatibility-pre-2.2-7.2.patch [bz#1215087]
+- kvm-Migration-compat-for-mc146818rtc-irq_reinject_on_ack.patch [bz#1215088]
+- Resolves: bz#1215087
+  (migration: 7.2->earlier;  serial compatibility)
+- Resolves: bz#1215088
+  (migration: 7.2->earlier; mc146818rtc compatibility)
+- Resolves: bz#1219090
+  (vfio-pci - post QEMU2.3 fixes, error sign + BAR overflow)
+
+* Wed Jun 24 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-5.el7
+- kvm-atomics-add-explicit-compiler-fence-in-__atomic-memo.patch [bz#1231335]
+- kvm-pc-acpi-fix-pvpanic-for-buggy-guests.patch [bz#1221943]
+- Resolves: bz#1221943
+  (On_crash events didn't work when using guest's pvpanic device)
+- Resolves: bz#1231335
+  ([abrt] qemu-kvm: bdrv_error_action(): qemu-kvm killed by SIGABRT)
+
+* Mon Jun 22 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-4.el7
+- kvm-virtio-ccw-using-VIRTIO_NO_VECTOR-instead-of-0-for-i.patch [bz#1231610]
+- kvm-virtio-ccw-sort-into-categories.patch [bz#1231610]
+- kvm-virtio-ccw-change-realization-sequence.patch [bz#1231610]
+- kvm-virtio-ccw-implement-device_plugged.patch [bz#1231610]
+- kvm-virtio-net-fix-the-upper-bound-when-trying-to-delete.patch [bz#1231610]
+- kvm-monitor-replace-the-magic-number-255-with-MAX_QUEUE_.patch [bz#1231610]
+- kvm-monitor-check-return-value-of-qemu_find_net_clients_.patch [bz#1231610]
+- kvm-virtio-introduce-vector-to-virtqueues-mapping.patch [bz#1231610]
+- kvm-virtio-pci-speedup-MSI-X-masking-and-unmasking.patch [bz#1231610]
+- kvm-pci-remove-hard-coded-bar-size-in-msix_init_exclusiv.patch [bz#1231610]
+- kvm-virtio-net-adding-all-queues-in-.realize.patch [bz#1231610]
+- kvm-virtio-device_plugged-can-fail.patch [bz#1231610]
+- kvm-virtio-introduce-virtio_get_num_queues.patch [bz#1231610]
+- kvm-virtio-ccw-introduce-ccw-specific-queue-limit.patch [bz#1231610]
+- kvm-virtio-ccw-validate-the-number-of-queues-against-bus.patch [bz#1231610]
+- kvm-virtio-s390-introduce-virito-s390-queue-limit.patch [bz#1231610]
+- kvm-virtio-s390-introduce-virtio_s390_device_plugged.patch [bz#1231610]
+- kvm-virtio-rename-VIRTIO_PCI_QUEUE_MAX-to-VIRTIO_QUEUE_M.patch [bz#1231610]
+- kvm-virtio-increase-the-queue-limit-to-1024.patch [bz#1231610]
+- kvm-virtio-pci-don-t-try-to-mask-or-unmask-vqs-without-n.patch [bz#1231610]
+- Resolves: bz#1231610
+  (Support more virtio queues)
+
+* Fri Jun 19 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-3.el7
+- kvm-vmdk-Fix-overflow-if-l1_size-is-0x20000000.patch [bz#1226809]
+- kvm-Downstream-only-Add-rhel7.2.0-machine-type.patch [bz#1228574]
+- kvm-spice-display-fix-segfault-in-qemu_spice_create_upda.patch [bz#1230550]
+- kvm-pc-dimm-don-t-assert-if-pc-dimm-alignment-hotpluggab.patch [bz#1221425]
+- kvm-Strip-brackets-from-vnc-host.patch [bz#1229073]
+- kvm-qcow2-Set-MIN_L2_CACHE_SIZE-to-2.patch [bz#1226996]
+- kvm-iotests-qcow2-COW-with-minimal-L2-cache-size.patch [bz#1226996]
+- kvm-qcow2-Add-DEFAULT_L2_CACHE_CLUSTERS.patch [bz#1226996]
+- kvm-spec-Ship-complete-QMP-documentation-files.patch [bz#1222834]
+- Resolves: bz#1221425
+  (qemu crash when hot-plug a memory device)
+- Resolves: bz#1222834
+  (We ship incomplete QMP documentation)
+- Resolves: bz#1226809
+  (Overflow in malloc size calculation in VMDK driver)
+- Resolves: bz#1226996
+  (qcow2: Fix minimum L2 cache size)
+- Resolves: bz#1228574
+  (Add RHEL7.2 machine type in QEMU for PPC64LE)
+- Resolves: bz#1229073
+  ([graphical framebuffer]Start guest failed when VNC listen on IPV6 address)
+- Resolves: bz#1230550
+  ([abrt] qemu-system-x86: __memcmp_sse4_1(): qemu-system-x86_64 killed by SIGSEGV)
+
+* Wed May 27 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-2.el7
+- kvm-balloon-improve-error-msg-when-adding-second-device.patch [bz#1165534]
+- kvm-qmp-add-error-reason-to-the-BLOCK_IO_ERROR-event.patch [bz#1199174]
+- kvm-spec-Remove-obsolete-differentiation-code.patch [bz#1122778]
+- kvm-spec-Use-external-configuration-script.patch [bz#1122778]
+- kvm-spec-Use-configure-options-to-prevent-default-resolu.patch [bz#1122778]
+- kvm-fdc-force-the-fifo-access-to-be-in-bounds-of-the-all.patch [bz#1219272]
+- Resolves: bz#1122778
+  (miss  "vhdx" and "iscsi" in qemu-img supported format list)
+- Resolves: bz#1165534
+  (balloon: improve error message when adding second device)
+- Resolves: bz#1199174
+  (QMP: forward port rhel-only error reason to BLOCK_IO_ERROR event)
+- Resolves: bz#1219272
+  (CVE-2015-3456 qemu-kvm-rhev: qemu: floppy disk controller flaw [rhel-7.2])
+
+* Tue Apr 28 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.3.0-1.el7
+- Rebase to 2.3.0 [bz#1194151]
+- kvm-misc-Add-pc-i440fx-rhel7-2-0-machine-type.patch [bz#1210050]
+- kvm-misc-Add-pc-q35-rhel7-2-0-machine-type.patch [bz#1210050]
+- Resolves: bz#1194151
+  (Rebase to qemu 2.3)
+- Resolves: bz#1210050
+  (Add pc-i440fx-rhel7.2.0 machine type)
+
+* Thu Mar 19 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-8.el7
+- kvm-pc_sysfw-prevent-pflash-and-or-mis-sized-firmware-fo.patch [bz#1175099]
+- kvm-build-reenable-local-builds-to-pass-enable-debug-dow.patch []
+- kvm-RPM-spec-install-dump-guest-memory.py-downstream-onl.patch [bz#1194304]
+- kvm-vga-Expose-framebuffer-byteorder-as-a-QOM-property.patch [bz#1146809]
+- kvm-pseries-Switch-VGA-endian-on-H_SET_MODE.patch [bz#1146809]
+- kvm-Generalize-QOM-publishing-of-date-and-time-from-mc14.patch [bz#1172583]
+- kvm-Add-more-VMSTATE_-_TEST-variants-for-integers.patch [bz#1171700]
+- kvm-pseries-Move-sPAPR-RTC-code-into-its-own-file.patch [bz#1170132 bz#1171700 bz#1172583]
+- kvm-pseries-Add-more-parameter-validation-in-RTAS-time-o.patch [bz#1170132 bz#1171700 bz#1172583]
+- kvm-pseries-Add-spapr_rtc_read-helper-function.patch [bz#1170132 bz#1171700 bz#1172583]
+- kvm-pseries-Make-RTAS-time-of-day-functions-respect-rtc-.patch [bz#1170132]
+- kvm-pseries-Make-the-PAPR-RTC-a-qdev-device.patch [bz#1170132 bz#1171700 bz#1172583]
+- kvm-pseries-Move-rtc_offset-into-RTC-device-s-state-stru.patch [bz#1171700]
+- kvm-pseries-Export-RTC-time-via-QOM.patch [bz#1172583]
+- kvm-pseries-Limit-PCI-host-bridge-index-value.patch [bz#1181409]
+- Resolves: bz#1146809
+  (Incorrect colours on virtual VGA with ppc64le guest under ppc64 host)
+- Resolves: bz#1170132
+  (Guest time could change with host time even specify the guest clock as "-rtc base=utc,clock=vm,...")
+- Resolves: bz#1171700
+  ('hwclock' in destination guest returns to base '2006-06-06' after migration)
+- Resolves: bz#1172583
+  ([Power KVM] Qemu monitor command don't support {"execute":"qom-get","arguments":{"path":"/machine","property":"rtc-time"}})
+- Resolves: bz#1175099
+  ([migration]migration failed when configure guest with OVMF bios + machine type=rhel6.5.0)
+- Resolves: bz#1181409
+  (PCI pass-through device works improperly due to the PHB's index being set to a big value)
+- Resolves: bz#1194304
+  ([Hitachi 7.2 FEAT] Extract guest memory dump from qemu-kvm-rhev core)
+
+* Tue Mar 10 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-7.el7
+- kvm-aarch64-Add-PCI-and-VIRTIO_PCI-devices-for-AArch64.patch [bz#1200090]
+- kvm-Add-specific-config-options-for-PCI-E-bridges.patch [bz#1200090]
+- Resolves: bz#1200090
+  (qemu-kvm-rhev (2.2.0-6) breaks ISO installation)
+
+* Mon Mar 02 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-6.el7
+- kvm-AArch64-Prune-the-devices-available-for-AArch64-gues.patch [bz#1170734]
+- kvm-Give-ivshmem-its-own-config-option.patch [bz#1170734]
+- kvm-aarch64-Prune-unsupported-CPU-types-for-aarch64.patch [bz#1170734]
+- Resolves: bz#1170734
+  (Trim qemu-kvm devices for aarch64)
+
+* Wed Feb 11 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-5.el7
+- kvm-kvm_stat-Add-aarch64-support.patch [bz#1184603]
+- kvm-kvm_stat-Update-exit-reasons-to-the-latest-defintion.patch [bz#1184603]
+- kvm-kvm_stat-Add-RESET-support-for-perf-event-ioctl.patch [bz#1184603]
+- kvm-ignore-SIGIO-in-tests-that-use-AIO-context-aarch64-h.patch [bz#1184405]
+- kvm-aio_notify-force-main-loop-wakeup-with-SIGIO-aarch64.patch [bz#1184405]
+- Resolves: bz#1184405
+  (lost block IO completion notification (for virtio-scsi disk) hangs main loop)
+- Resolves: bz#1184603
+  (enable kvm_stat support for aarch64)
+
+* Mon Feb 09 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-4.el7
+- kvm-Downstream-only-Restore-pseries-machine-alias.patch [bz#1170934]
+- kvm-PPC-Fix-crash-on-spapr_tce_table_finalize.patch [bz#1170934]
+- kvm-virtio_serial-Don-t-use-vser-config.max_nr_ports-int.patch [bz#1169230]
+- kvm-virtio-serial-Don-t-keep-a-persistent-copy-of-config.patch [bz#1169230]
+- kvm-spapr-Fix-stale-HTAB-during-live-migration-KVM.patch [bz#1168446]
+- kvm-spapr-Fix-integer-overflow-during-migration-TCG.patch [bz#1168446]
+- kvm-spapr-Fix-stale-HTAB-during-live-migration-TCG.patch [bz#1168446]
+- Resolves: bz#1168446
+  (Stale hash PTEs may be transferred during live migration of PAPR guests)
+- Resolves: bz#1169230
+  (QEMU core dumped when do ping-pong migration to file for LE guest)
+- Resolves: bz#1170934
+  (Segfault at spapr_tce_table_finalize(): QLIST_REMOVE(tcet, list))
+
+* Thu Jan 22 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-3.el7
+- kvm-Downstream-only-arm-define-a-new-machine-type-for-RH.patch [bz#1176838]
+- Resolves: bz#1176838
+  (create rhelsa machine type)
+
+* Wed Jan 14 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-2.el7.next.candidate
+- kvm-Update-to-qemu-kvm-rhev-2.1.2-19.el7.patch []
+- kvm-fw_cfg-remove-superfluous-blank-line.patch [bz#1169869]
+- kvm-hw-arm-boot-fix-uninitialized-scalar-variable-warnin.patch [bz#1169869]
+- kvm-Sort-include-qemu-typedefs.h.patch [bz#1169869]
+- kvm-fw_cfg-hard-separation-between-the-MMIO-and-I-O-port.patch [bz#1169869]
+- kvm-fw_cfg-move-boards-to-fw_cfg_init_io-fw_cfg_init_mem.patch [bz#1169869]
+- kvm-fw_cfg_mem-max-access-size-and-region-size-are-the-s.patch [bz#1169869]
+- kvm-fw_cfg_mem-flip-ctl_mem_ops-and-data_mem_ops-to-DEVI.patch [bz#1169869]
+- kvm-exec-allows-8-byte-accesses-in-subpage_ops.patch [bz#1169869]
+- kvm-fw_cfg_mem-introduce-the-data_width-property.patch [bz#1169869]
+- kvm-fw_cfg_mem-expose-the-data_width-property-with-fw_cf.patch [bz#1169869]
+- kvm-arm-add-fw_cfg-to-virt-board.patch [bz#1169869]
+- kvm-hw-loader-split-out-load_image_gzipped_buffer.patch [bz#1169869]
+- kvm-hw-arm-pass-pristine-kernel-image-to-guest-firmware-.patch [bz#1169869]
+- kvm-hw-arm-virt-enable-passing-of-EFI-stubbed-kernel-to-.patch [bz#1169869]
+- kvm-fw_cfg-fix-endianness-in-fw_cfg_data_mem_read-_write.patch [bz#1169869]
+- Resolves: bz#1169869
+  (add fw_cfg to mach-virt)
+
+* Tue Jan 13 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-19.el7
+- kvm-smbios-Fix-dimm-size-calculation-when-RAM-is-multipl.patch [bz#1179165]
+- kvm-smbios-Don-t-report-unknown-CPU-speed-fix-SVVP-regre.patch [bz#1177127]
+- Resolves: bz#1177127
+  ([SVVP]smbios HCT job failed with  'Processor Max Speed cannot be Unknown' with -M pc-i440fx-rhel7.1.0)
+- Resolves: bz#1179165
+  ([SVVP]smbios HCT job failed with  Unspecified error  with -M pc-i440fx-rhel7.1.0)
+
+* Thu Jan 08 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.2.0-1.el7
+- rebase to qemu 2.2.0
+
+* Thu Jan 08 2015 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-18.el7
+- kvm-vl-Adjust-the-place-of-calling-mlockall-to-speedup-V.patch [bz#1173394]
+- kvm-block-delete-cow-block-driver.patch [bz#1175841]
+- Resolves: bz#1173394
+  (numa_smaps doesn't respect bind policy with huge page)
+- Resolves: bz#1175841
+  (Delete cow block driver)
+
+* Tue Dec 16 2014 Jeff E. Nelson <jen@redhat.com> - rhev-2.1.2-17.el7
+- kvm-numa-Don-t-allow-memdev-on-RHEL-6-machine-types.patch [bz#1170093]
+- kvm-block-allow-bdrv_unref-to-be-passed-NULL-pointers.patch [bz#1136381]
+- kvm-block-vdi-use-block-layer-ops-in-vdi_create-instead-.patch [bz#1136381]
+- kvm-block-use-the-standard-ret-instead-of-result.patch [bz#1136381]
+- kvm-block-vpc-use-block-layer-ops-in-vpc_create-instead-.patch [bz#1136381]
+- kvm-block-iotest-update-084-to-test-static-VDI-image-cre.patch [bz#1136381]
+- kvm-block-remove-BLOCK_OPT_NOCOW-from-vdi_create_opts.patch [bz#1136381]
+- kvm-block-remove-BLOCK_OPT_NOCOW-from-vpc_create_opts.patch [bz#1136381]
+- kvm-migration-fix-parameter-validation-on-ram-load-CVE-2.patch [bz#1163079]
+- kvm-qdev-monitor-fix-segmentation-fault-on-qdev_device_h.patch [bz#1169280]
+- kvm-block-migration-Disable-cache-invalidate-for-incomin.patch [bz#1171552]
+- kvm-acpi-Use-apic_id_limit-when-calculating-legacy-ACPI-.patch [bz#1173167]
+- Resolves: bz#1136381
+  (RFE: Supporting creating vdi/vpc format disk with protocols (glusterfs) for qemu-kvm-rhev-2.1.x)
+- Resolves: bz#1163079
+  (CVE-2014-7840 qemu-kvm-rhev: qemu: insufficient parameter validation during ram load [rhel-7.1])
+- Resolves: bz#1169280
+  (Segfault while query device properties (ics, icp))
+- Resolves: bz#1170093
+  (guest NUMA failed to migrate when machine is rhel6.5.0)
+- Resolves: bz#1171552
+  (Storage vm migration failed when running BurnInTes)
+- Resolves: bz#1173167
+  (Corrupted ACPI tables in some configurations using pc-i440fx-rhel7.0.0)
+
+* Fri Dec 05 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-16.el7
+- kvm-qemu-iotests-Fix-broken-test-cases.patch [bz#1169589]
+- kvm-Fix-for-crash-after-migration-in-virtio-rng-on-bi-en.patch [bz#1165087]
+- kvm-Downstream-only-remove-unsupported-machines-from-AAr.patch [bz#1169847]
+- Resolves: bz#1165087
+  (QEMU core dumped for the destination guest when do migating guest to file)
+- Resolves: bz#1169589
+  (test case 051 071 and 087 of qemu-iotests fail for qcow2 with qemu-kvm-rhev-2.1.2-14.el7)
+- Resolves: bz#1169847
+  (only support mach-virt)
+
+* Tue Dec 02 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-15.el7
+- kvm-scsi-Optimize-scsi_req_alloc.patch [bz#1141656]
+- kvm-virtio-scsi-Optimize-virtio_scsi_init_req.patch [bz#1141656]
+- kvm-virtio-scsi-Fix-comment-for-VirtIOSCSIReq.patch [bz#1141656]
+- kvm-Downstream-only-Move-daemon-reload-to-make-sure-new-.patch [bz#1168085]
+- Resolves: bz#1141656
+  (Virtio-scsi: performance degradation from 1.5.3 to 2.1.0)
+- Resolves: bz#1168085
+  (qemu-kvm-rhev install scripts sometimes don't recognize newly installed systemd presets)
+
+* Thu Nov 27 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-14.el7
+- kvm-xhci-add-sanity-checks-to-xhci_lookup_uport.patch [bz#1161397]
+- kvm-qemu-img-Allow-source-cache-mode-specification.patch [bz#1166481]
+- kvm-qemu-img-Allow-cache-mode-specification-for-amend.patch [bz#1166481]
+- kvm-qemu-img-fix-img_compare-flags-error-path.patch [bz#1166481]
+- kvm-qemu-img-clarify-src_cache-option-documentation.patch [bz#1166481]
+- kvm-qemu-img-fix-rebase-src_cache-option-documentation.patch [bz#1166481]
+- Resolves: bz#1161397
+  (qemu core dump when install a RHEL.7 guest(xhci) with migration)
+- Resolves: bz#1166481
+  (Allow qemu-img to bypass the host cache (check, compare, convert, rebase, amend))
+
+* Tue Nov 25 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-13.el7
+- kvm-hw-pci-fixed-error-flow-in-pci_qdev_init.patch [bz#1166067]
+- kvm-hw-pci-fixed-hotplug-crash-when-using-rombar-0-with-.patch [bz#1166067]
+- Resolves: bz#1166067
+  (qemu-kvm aborted when hot plug PCI device to guest with romfile and rombar=0)
+
+* Fri Nov 21 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-12.el7
+- kvm-migration-static-variables-will-not-be-reset-at-seco.patch [bz#1166501]
+- Resolves: bz#1166501
+  (Migration "expected downtime" does not refresh after reset to a new value)
+
+* Fri Nov 21 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-11.el7
+- kvm-iscsi-Refuse-to-open-as-writable-if-the-LUN-is-write.patch [bz#1160102]
+- kvm-vnc-sanitize-bits_per_pixel-from-the-client.patch [bz#1157646]
+- kvm-usb-host-fix-usb_host_speed_compat-tyops.patch [bz#1160504]
+- kvm-block-raw-posix-Fix-disk-corruption-in-try_fiemap.patch [bz#1142331]
+- kvm-block-raw-posix-use-seek_hole-ahead-of-fiemap.patch [bz#1142331]
+- kvm-raw-posix-Fix-raw_co_get_block_status-after-EOF.patch [bz#1142331]
+- kvm-raw-posix-raw_co_get_block_status-return-value.patch [bz#1142331]
+- kvm-raw-posix-SEEK_HOLE-suffices-get-rid-of-FIEMAP.patch [bz#1142331]
+- kvm-raw-posix-The-SEEK_HOLE-code-is-flawed-rewrite-it.patch [bz#1142331]
+- kvm-exec-Handle-multipage-ranges-in-invalidate_and_set_d.patch [bz#1164759]
+- Resolves: bz#1142331
+  (qemu-img convert intermittently corrupts output images)
+- Resolves: bz#1157646
+  (CVE-2014-7815 qemu-kvm-rhev: qemu: vnc: insufficient bits_per_pixel from the client sanitization [rhel-7.1])
+- Resolves: bz#1160102
+  (opening read-only iscsi lun as read-write should fail)
+- Resolves: bz#1160504
+  (guest can not show usb device after adding some usb controllers and redirdevs.)
+- Resolves: bz#1164759
+  (Handle multipage ranges in invalidate_and_set_dirty())
+
+* Thu Nov 20 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-10.el7
+- kvm-pc-dimm-Don-t-check-dimm-node-when-there-is-non-NUMA.patch [bz#1150510 bz#1163735]
+- kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch [bz#1146809]
+- kvm-vga-Remove-remainder-of-old-conversion-cruft.patch [bz#1146809]
+- kvm-vga-Separate-LE-and-BE-conversion-functions.patch [bz#1146809]
+- kvm-vga-Remove-rgb_to_pixel-indirection.patch [bz#1146809]
+- kvm-vga-Simplify-vga_draw_blank-a-bit.patch [bz#1146809]
+- kvm-cirrus-Remove-non-32bpp-cursor-drawing.patch [bz#1146809]
+- kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch [bz#1146809]
+- kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch [bz#1146809]
+- kvm-vga-Make-fb-endian-a-common-state-variable.patch [bz#1146809]
+- kvm-vga-Add-endian-to-vmstate.patch [bz#1146809]
+- kvm-vga-pci-add-qext-region-to-mmio.patch [bz#1146809]
+- kvm-virtio-scsi-work-around-bug-in-old-BIOSes.patch [bz#1123812]
+- kvm-Revert-Downstream-only-Add-script-to-autoload-KVM-mo.patch [bz#1158250 bz#1159706]
+- kvm-Downstream-only-add-script-on-powerpc-to-configure-C.patch [bz#1158250 bz#1158251 bz#1159706]
+- kvm-block-New-bdrv_nb_sectors.patch [bz#1132385]
+- kvm-vmdk-Optimize-cluster-allocation.patch [bz#1132385]
+- kvm-vmdk-Handle-failure-for-potentially-large-allocation.patch [bz#1132385]
+- kvm-vmdk-Use-bdrv_nb_sectors-where-sectors-not-bytes-are.patch [bz#1132385]
+- kvm-vmdk-fix-vmdk_parse_extents-extent_file-leaks.patch [bz#1132385]
+- kvm-vmdk-fix-buf-leak-in-vmdk_parse_extents.patch [bz#1132385]
+- kvm-vmdk-Fix-integer-overflow-in-offset-calculation.patch [bz#1132385]
+- kvm-Revert-Build-ceph-rbd-only-for-rhev.patch [bz#1140744]
+- kvm-Revert-rbd-Only-look-for-qemu-specific-copy-of-librb.patch [bz#1140744]
+- kvm-Revert-rbd-link-and-load-librbd-dynamically.patch [bz#1140744]
+- kvm-spec-Enable-rbd-driver-add-dependency.patch [bz#1140744]
+- kvm-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch [bz#1140620]
+- kvm-ide-stash-aiocb-for-flushes.patch [bz#1024599]
+- kvm-ide-simplify-reset-callbacks.patch [bz#1024599]
+- kvm-ide-simplify-set_inactive-callbacks.patch [bz#1024599]
+- kvm-ide-simplify-async_cmd_done-callbacks.patch [bz#1024599]
+- kvm-ide-simplify-start_transfer-callbacks.patch [bz#1024599]
+- kvm-ide-wrap-start_dma-callback.patch [bz#1024599]
+- kvm-ide-remove-wrong-setting-of-BM_STATUS_INT.patch [bz#1024599]
+- kvm-ide-fold-add_status-callback-into-set_inactive.patch [bz#1024599]
+- kvm-ide-move-BM_STATUS-bits-to-pci.-ch.patch [bz#1024599]
+- kvm-ide-move-retry-constants-out-of-BM_STATUS_-namespace.patch [bz#1024599]
+- kvm-ahci-remove-duplicate-PORT_IRQ_-constants.patch [bz#1024599]
+- kvm-ide-stop-PIO-transfer-on-errors.patch [bz#1024599]
+- kvm-ide-make-all-commands-go-through-cmd_done.patch [bz#1024599]
+- kvm-ide-atapi-Mark-non-data-commands-as-complete.patch [bz#1024599]
+- kvm-ahci-construct-PIO-Setup-FIS-for-PIO-commands.patch [bz#1024599]
+- kvm-ahci-properly-shadow-the-TFD-register.patch [bz#1024599]
+- kvm-ahci-Correct-PIO-D2H-FIS-responses.patch [bz#1024599]
+- kvm-ahci-Update-byte-count-after-DMA-completion.patch [bz#1024599]
+- kvm-ahci-Fix-byte-count-regression-for-ATAPI-PIO.patch [bz#1024599]
+- kvm-ahci-Fix-SDB-FIS-Construction.patch [bz#1024599]
+- kvm-vhost-user-fix-mmap-offset-calculation.patch [bz#1159710]
+- Resolves: bz#1024599
+  (Windows7 x86 guest with ahci backend hit BSOD when do "hibernate")
+- Resolves: bz#1123812
+  (Reboot guest and guest's virtio-scsi disk will be lost after forwards migration (from RHEL6.6 host to RHEL7.1 host))
+- Resolves: bz#1132385
+  (qemu-img convert rate about 100k/second from qcow2/raw to vmdk format on nfs system file)
+- Resolves: bz#1140620
+  (Should replace "qemu-system-i386" by "/usr/libexec/qemu-kvm" in manpage of qemu-kvm for our official qemu-kvm build)
+- Resolves: bz#1140744
+  (Enable native support for Ceph)
+- Resolves: bz#1146809
+  (Incorrect colours on virtual VGA with ppc64le guest under ppc64 host)
+- Resolves: bz#1150510
+  (kernel ignores ACPI memory devices (PNP0C80) present at boot time)
+- Resolves: bz#1158250
+  (KVM modules are not autoloaded on POWER hosts)
+- Resolves: bz#1158251
+  (POWER KVM host starts by default with threads enabled, which prevents running guests)
+- Resolves: bz#1159706
+  (Need means to configure subcore mode for RHEL POWER8 hosts)
+- Resolves: bz#1159710
+  (vhost-user:Bad ram offset)
+- Resolves: bz#1163735
+  (-device pc-dimm fails to initialize on non-NUMA configs)
+
+* Wed Nov 19 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-9.el7
+- kvm-aarch64-raise-max_cpus-to-8.patch [bz#1160325]
+- kvm-hw-arm-virt-add-linux-stdout-path-to-chosen-DT-node.patch [bz#1160325]
+- kvm-hw-arm-virt-Provide-flash-devices-for-boot-ROMs.patch [bz#1160325]
+- kvm-hw-arm-boot-load-DTB-as-a-ROM-image.patch [bz#1160325]
+- kvm-hw-arm-boot-pass-an-address-limit-to-and-return-size.patch [bz#1160325]
+- kvm-hw-arm-boot-load-device-tree-to-base-of-DRAM-if-no-k.patch [bz#1160325]
+- kvm-hw-arm-boot-enable-DTB-support-when-booting-ELF-imag.patch [bz#1160325]
+- kvm-hw-arm-virt-mark-timer-in-fdt-as-v8-compatible.patch [bz#1160325]
+- kvm-hw-arm-boot-register-cpu-reset-handlers-if-using-bio.patch [bz#1160325]
+- kvm-Downstream-only-Declare-ARM-kernel-support-read-only.patch [bz#1160325]
+- Resolves: bz#1160325
+  (arm64: support aavmf)
+
+* Thu Nov 13 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-8.el7
+- kvm-ide-Add-wwn-support-to-IDE-ATAPI-drive.patch [bz#1150820]
+- kvm-exec-report-error-when-memory-hpagesize.patch [bz#1147354]
+- kvm-exec-add-parameter-errp-to-gethugepagesize.patch [bz#1147354]
+- kvm-block-curl-Improve-type-safety-of-s-timeout.patch [bz#1152901]
+- kvm-virtio-serial-avoid-crash-when-port-has-no-name.patch [bz#1151947]
+- Resolves: bz#1147354
+  (Qemu core dump when boot up a guest on a non-existent hugepage path)
+- Resolves: bz#1150820
+  (fail to specify wwn for virtual IDE CD-ROM)
+- Resolves: bz#1151947
+  (virtconsole causes qemu-kvm core dump)
+- Resolves: bz#1152901
+  (block/curl: Fix type safety of s->timeout)
+
+* Thu Nov 06 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-7.el7
+- kvm-ac97-register-reset-via-qom.patch [bz#1141666]
+- kvm-specfile-Require-glusterfs-api-3.6.patch [bz#1157329]
+- kvm-smbios-Fix-assertion-on-socket-count-calculation.patch [bz#1146573]
+- kvm-smbios-Encode-UUID-according-to-SMBIOS-specification.patch [bz#1152922]
+- kvm-virtio-scsi-Report-error-if-num_queues-is-0-or-too-l.patch [bz#1146826]
+- kvm-virtio-scsi-Fix-memory-leak-when-realize-failed.patch [bz#1146826]
+- kvm-virtio-scsi-Fix-num_queue-input-validation.patch [bz#1146826]
+- kvm-util-Improve-os_mem_prealloc-error-message.patch [bz#1153590]
+- kvm-Downstream-only-Add-script-to-autoload-KVM-modules-o.patch [bz#1158250]
+- kvm-Downstream-only-remove-uneeded-PCI-devices-for-POWER.patch [bz#1160120]
+- kvm-Downstream-only-Remove-assorted-unneeded-devices-for.patch [bz#1160120]
+- kvm-Downstream-only-Remove-ISA-bus-and-device-support-fo.patch [bz#1160120]
+- kvm-well-defined-listing-order-for-machine-types.patch [bz#1145042]
+- kvm-i386-pc-add-piix-and-q35-machtypes-to-sorting-famili.patch [bz#1145042]
+- kvm-i386-pc-add-RHEL-machtypes-to-sorting-families-for-M.patch [bz#1145042]
+- Resolves: bz#1141666
+  (Qemu crashed if reboot guest after hot remove AC97 sound device)
+- Resolves: bz#1145042
+  (The output of "/usr/libexec/qemu-kvm -M ?" should be ordered.)
+- Resolves: bz#1146573
+  (qemu core dump when boot guest with smp(num)<cores(num))
+- Resolves: bz#1146826
+  (QEMU will not reject invalid number of queues (num_queues = 0) specified for virtio-scsi)
+- Resolves: bz#1152922
+  (smbios uuid mismatched)
+- Resolves: bz#1153590
+  (Improve error message on huge page preallocation)
+- Resolves: bz#1157329
+  (qemu-kvm: undefined symbol: glfs_discard_async)
+- Resolves: bz#1158250
+  (KVM modules are not autoloaded on POWER hosts)
+- Resolves: bz#1160120
+  (qemu-kvm-rhev shouldn't include non supported devices for POWER)
+
+* Tue Nov 04 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-6.el7
+- kvm-ivshmem-use-error_report.patch [bz#1104063]
+- kvm-ivshmem-RHEL-only-remove-unsupported-code.patch [bz#1104063]
+- kvm-ivshmem-RHEL-only-explicitly-remove-dead-code.patch [bz#1104063]
+- kvm-Revert-rhel-Drop-ivshmem-device.patch [bz#1104063]
+- kvm-serial-reset-state-at-startup.patch [bz#1135844]
+- kvm-spice-call-qemu_spice_set_passwd-during-init.patch [bz#1140975]
+- kvm-input-fix-send-key-monitor-command-release-event-ord.patch [bz#1145028 bz#1146801]
+- kvm-virtio-scsi-sense-in-virtio_scsi_command_complete.patch [bz#1152830]
+- Resolves: bz#1104063
+  ([RHEL7.1 Feat] Enable qemu-kvm Inter VM Shared Memory (IVSHM) feature)
+- Resolves: bz#1135844
+  ([virtio-win]communication ports were marked with a  yellow exclamation after hotplug pci-serial,pci-serial-2x,pci-serial-4x)
+- Resolves: bz#1140975
+  (fail to login spice session with password + expire time)
+- Resolves: bz#1145028
+  (send-key does not crash windows guest even when it should)
+- Resolves: bz#1146801
+  (sendkey: releasing order of combined keys was wrongly converse)
+- Resolves: bz#1152830
+  (Fix sense buffer in virtio-scsi LUN passthrough)
+
+* Fri Oct 24 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-5.el7
+- kvm-blockdev-Orphaned-drive-search.patch [bz#946993]
+- kvm-blockdev-Allow-overriding-if_max_dev-property.patch [bz#946993]
+- kvm-pc-vl-Add-units-per-default-bus-property.patch [bz#946993]
+- kvm-ide-Update-ide_drive_get-to-be-HBA-agnostic.patch [bz#946993]
+- kvm-qtest-bios-tables-Correct-Q35-command-line.patch [bz#946993]
+- kvm-q35-ahci-Pick-up-cdrom-and-hda-options.patch [bz#946993]
+- kvm-trace-events-drop-orphan-virtio_blk_data_plane_compl.patch [bz#1144325]
+- kvm-trace-events-drop-orphan-usb_mtp_data_out.patch [bz#1144325]
+- kvm-trace-events-drop-orphan-iscsi-trace-events.patch [bz#1144325]
+- kvm-cleanup-trace-events.pl-Tighten-search-for-trace-eve.patch [bz#1144325]
+- kvm-trace-events-Drop-unused-megasas-trace-event.patch [bz#1144325]
+- kvm-trace-events-Drop-orphaned-monitor-trace-event.patch [bz#1144325]
+- kvm-trace-events-Fix-comments-pointing-to-source-files.patch [bz#1144325]
+- kvm-simpletrace-add-simpletrace.py-no-header-option.patch [bz#1155015]
+- kvm-trace-extract-stap_escape-function-for-reuse.patch [bz#1155015]
+- kvm-trace-add-tracetool-simpletrace_stap-format.patch [bz#1155015]
+- kvm-trace-install-simpletrace-SystemTap-tapset.patch [bz#1155015]
+- kvm-trace-install-trace-events-file.patch [bz#1155015]
+- kvm-trace-add-SystemTap-init-scripts-for-simpletrace-bri.patch [bz#1155015]
+- kvm-simpletrace-install-simpletrace.py.patch [bz#1155015]
+- kvm-trace-add-systemtap-initscript-README-file-to-RPM.patch [bz#1155015]
+- Resolves: bz#1144325
+  (Can not probe  "qemu.kvm.virtio_blk_data_plane_complete_request")
+- Resolves: bz#1155015
+  ([Fujitsu 7.1 FEAT]:QEMU: capturing trace data all the time using ftrace-based tracing)
+- Resolves: bz#946993
+  (Q35 does not honor -drive if=ide,... and its sugared forms -cdrom, -hda, ...)
+
+* Mon Oct 20 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-4.el7
+- kvm-seccomp-add-semctl-to-the-syscall-whitelist.patch [bz#1126704]
+- kvm-dataplane-fix-virtio_blk_data_plane_create-op-blocke.patch [bz#1140001]
+- kvm-block-fix-overlapping-multiwrite-requests.patch [bz#1123908]
+- kvm-qemu-iotests-add-multiwrite-test-cases.patch [bz#1123908]
+- Resolves: bz#1123908
+  (block.c: multiwrite_merge() truncates overlapping requests)
+- Resolves: bz#1126704
+  (BUG: When use '-sandbox on'+'vnc'+'hda' and quit, qemu-kvm hang)
+- Resolves: bz#1140001
+  (data-plane hotplug should be refused to start if device is already in use (drive-mirror job))
+
+* Fri Oct 10 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-3.el7
+- kvm-Disable-tests-for-removed-features.patch [bz#1108040]
+- kvm-Disable-arm-board-types-using-lsi53c895a.patch [bz#1108040]
+- kvm-libqtest-launch-QEMU-with-QEMU_AUDIO_DRV-none.patch [bz#1108040]
+- kvm-Whitelist-blkdebug-driver.patch [bz#1108040]
+- kvm-Turn-make-check-on.patch [bz#1108040]
+- Resolves: bz#1108040
+  (Enable make check for qemu-kvm-rhev 2.0 and newer)
+
+* Fri Oct 10 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-2.el7
+- kvm-RPM-spec-Add-enable-numa-to-configure-command-line.patch [bz#1076990]
+- kvm-block.curl-adding-timeout-option.patch [bz#1132569]
+- kvm-curl-Allow-a-cookie-or-cookies-to-be-sent-with-http-.patch [bz#1132569]
+- kvm-curl-Don-t-deref-NULL-pointer-in-call-to-aio_poll.patch [bz#1132569]
+- kvm-curl-Add-timeout-and-cookie-options-and-misc.-fix-RH.patch [bz#1132569]
+- kvm-Introduce-cpu_clean_all_dirty.patch [bz#1143054]
+- kvm-kvmclock-Ensure-proper-env-tsc-value-for-kvmclock_cu.patch [bz#1143054]
+- kvm-kvmclock-Ensure-time-in-migration-never-goes-backwar.patch [bz#1143054]
+- kvm-IDE-Fill-the-IDENTIFY-request-consistently.patch [bz#852348]
+- kvm-ide-Add-resize-callback-to-ide-core.patch [bz#852348]
+- kvm-virtio-balloon-fix-integer-overflow-in-memory-stats-.patch [bz#1140997]
+- kvm-block-extend-BLOCK_IO_ERROR-event-with-nospace-indic.patch [bz#1117445]
+- kvm-block-extend-BLOCK_IO_ERROR-with-reason-string.patch [bz#1117445]
+- Resolves: bz#1076990
+  (Enable complex memory requirements for virtual machines)
+- Resolves: bz#1117445
+  (QMP: extend block events with error information)
+- Resolves: bz#1132569
+  (RFE: Enable curl driver in qemu-kvm-rhev: https only)
+- Resolves: bz#1140997
+  (guest is stuck when setting balloon memory with large guest-stats-polling-interval)
+- Resolves: bz#1143054
+  (kvmclock: Ensure time in migration never goes backward (backport))
+- Resolves: bz#852348
+  (fail to block_resize local data disk with IDE/AHCI disk_interface)
+
+* Fri Sep 26 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.2-1.el7
+- Rebase to qemu 2.1.2 [bz#1121609]
+- Resolves: bz#1121609
+  Rebase qemu-kvm-rhev to qemu 2.1.2
+
+* Wed Sep 24 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.0-5.el7
+- kvm-target-i386-Reject-invalid-CPU-feature-names-on-the-.patch [bz#1055532]
+- kvm-target-ppc-virtex-ml507-machine-type-should-depend-o.patch [bz#1113998]
+- kvm-RHEL-only-Disable-tests-that-don-t-work-with-RHEL-bu.patch [bz#1113998]
+- kvm-RHEL-onlyy-Disable-unused-ppc-machine-types.patch [bz#1113998]
+- kvm-RHEL-only-Remove-unneeded-devices-from-ppc64-qemu-kv.patch []
+- kvm-RHEL-only-Replace-upstream-pseries-machine-types-wit.patch []
+- kvm-scsi-bus-prepare-scsi_req_new-for-introduction-of-pa.patch [bz#1123349]
+- kvm-scsi-bus-introduce-parse_cdb-in-SCSIDeviceClass-and-.patch [bz#1123349]
+- kvm-scsi-block-extract-scsi_block_is_passthrough.patch [bz#1123349]
+- kvm-scsi-block-scsi-generic-implement-parse_cdb.patch [bz#1123349]
+- kvm-virtio-scsi-implement-parse_cdb.patch [bz#1123349]
+- kvm-exec-file_ram_alloc-print-error-when-prealloc-fails.patch [bz#1135893]
+- kvm-pc-increase-maximal-VCPU-count-to-240.patch [bz#1144089]
+- kvm-ssh-Enable-ssh-driver-in-qemu-kvm-rhev-RHBZ-1138359.patch [bz#1138359]
+- Resolves: bz#1055532
+  (QEMU should abort when invalid CPU flag name is used)
+- Resolves: bz#1113998
+  (RHEL Power/KVM (qemu-kvm-rhev))
+- Resolves: bz#1123349
+  ([FJ7.0 Bug] SCSI command issued from KVM guest doesn't reach target device)
+- Resolves: bz#1135893
+  (qemu-kvm should report an error message when host's freehugepage memory < domain's memory)
+- Resolves: bz#1138359
+  (RFE: Enable ssh driver in qemu-kvm-rhev)
+- Resolves: bz#1144089
+  ([HP 7.1 FEAT] Increase qemu-kvm-rhev's VCPU limit to 240)
+
+* Wed Sep 17 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.0-4.el7
+- kvm-virtio-rng-add-some-trace-events.patch [bz#1129259]
+- kvm-block-vhdx-add-error-check.patch [bz#1126976]
+- kvm-block-VHDX-endian-fixes.patch [bz#1126976]
+- kvm-qdev-monitor-include-QOM-properties-in-device-FOO-he.patch [bz#1133736]
+- kvm-block-acquire-AioContext-in-qmp_block_resize.patch [bz#1136752]
+- kvm-virtio-blk-allow-block_resize-with-dataplane.patch [bz#1136752]
+- kvm-block-acquire-AioContext-in-do_drive_del.patch [bz#1136752]
+- kvm-virtio-blk-allow-drive_del-with-dataplane.patch [bz#1136752]
+- kvm-rhel-Add-rhel7.1.0-machine-types.patch [bz#1093023]
+- kvm-vmstate_xhci_event-bug-compat-for-rhel7.0.0-machine-.patch [bz#1136512]
+- kvm-pflash_cfi01-fixup-stale-DPRINTF-calls.patch [bz#1139706]
+- kvm-pflash_cfi01-write-flash-contents-to-bdrv-on-incomin.patch [bz#1139706]
+- kvm-ide-Fix-segfault-when-flushing-a-device-that-doesn-t.patch [bz#1140145]
+- kvm-xhci-PCIe-endpoint-migration-compatibility-fix.patch [bz#1138579]
+- kvm-rh-machine-types-xhci-PCIe-endpoint-migration-compat.patch [bz#1138579]
+- Resolves: bz#1093023
+  (provide RHEL-specific machine types in QEMU)
+- Resolves: bz#1126976
+  (VHDX image format does not work on PPC64 (Endian issues))
+- Resolves: bz#1129259
+  (Add traces to virtio-rng device)
+- Resolves: bz#1133736
+  (qemu should provide iothread and x-data-plane properties for /usr/libexec/qemu-kvm -device virtio-blk-pci,?)
+- Resolves: bz#1136512
+  (rhel7.0.0 machtype compat after CVE-2014-5263 vmstate_xhci_event: fix unterminated field list)
+- Resolves: bz#1136752
+  (virtio-blk dataplane support for block_resize and hot unplug)
+- Resolves: bz#1138579
+  (Migration failed with nec-usb-xhci from RHEL7. 0 to RHEL7.1)
+- Resolves: bz#1139706
+  (pflash (UEFI varstore) migration shortcut for libvirt [RHEV])
+- Resolves: bz#1140145
+  (qemu-kvm crashed when doing iofuzz testing)
+
+* Thu Aug 28 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.0-3.el7
+- kvm-Fix-pkgversion-value.patch [bz#1064742]
+- kvm-virtio-serial-create-a-linked-list-of-all-active-dev.patch [bz#1003432]
+- kvm-virtio-serial-search-for-duplicate-port-names-before.patch [bz#1003432]
+- kvm-pc-RHEL-6-CPUID-compat-code-for-Broadwell-CPU-model.patch [bz#1111351]
+- kvm-rpm-spec-build-qemu-kvm-with-lzo-and-snappy-enabled.patch [bz#1126933]
+- Resolves: bz#1003432
+  (qemu-kvm should not allow different virtio serial port use the same name)
+- Resolves: bz#1064742
+  (QMP: "query-version" doesn't include the -rhev prefix from the qemu-kvm-rhev package)
+- Resolves: bz#1111351
+  (RHEL-6.6 migration compatibility: CPU models)
+- Resolves: bz#1126933
+  ([FEAT RHEV7.1]: qemu: Support compression for dump-guest-memory command)
+
+* Mon Aug 18 2014 Miroslav Rezanina <> - rhev-2.1.0-2.el7
+- kvm-exit-when-no-kvm-and-vcpu-count-160.patch [bz#1076326 bz#1118665]
+- kvm-Revert-Use-legacy-SMBIOS-for-rhel-machine-types.patch [bz#1118665]
+- kvm-rhel-Use-SMBIOS-legacy-mode-for-machine-types-7.0.patch [bz#1118665]
+- kvm-rhel-Suppress-hotplug-memory-address-space-for-machi.patch [bz#1118665]
+- kvm-rhel-Fix-ACPI-table-size-for-machine-types-7.0.patch [bz#1118665]
+- kvm-rhel-Fix-missing-pc-q35-rhel7.0.0-compatibility-prop.patch [bz#1118665]
+- kvm-rhel-virtio-scsi-pci.any_layout-off-for-machine-type.patch [bz#1118665]
+- kvm-rhel-PIIX4_PM.memory-hotplug-support-off-for-machine.patch [bz#1118665]
+- kvm-rhel-apic.version-0x11-for-machine-types-7.0.patch [bz#1118665]
+- kvm-rhel-nec-usb-xhci.superspeed-ports-first-off-for-mac.patch [bz#1118665]
+- kvm-rhel-pci-serial.prog_if-0-for-machine-types-7.0.patch [bz#1118665]
+- kvm-rhel-virtio-net-pci.guest_announce-off-for-machine-t.patch [bz#1118665]
+- kvm-rhel-ICH9-LPC.memory-hotplug-support-off-for-machine.patch [bz#1118665]
+- kvm-rhel-.power_controller_present-off-for-machine-types.patch [bz#1118665]
+- kvm-rhel-virtio-net-pci.ctrl_guest_offloads-off-for-mach.patch [bz#1118665]
+- kvm-pc-q35-rhel7.0.0-Disable-x2apic-default.patch [bz#1118665]
+- Resolves: bz#1076326
+  (qemu-kvm does not quit when booting guest w/ 161 vcpus and "-no-kvm")
+- Resolves: bz#1118665
+  (Migration: rhel7.0->rhev7.1)
+
+* Sat Aug 02 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.1.0-1.el7
+- Rebase to 2.1.0 [bz#1121609]
+- Resolves: bz#1121609
+ (Rebase qemu-kvm-rhev to qemu 2.1)
+
+* Wed Jul 09 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.0.0-3.el7
+- kvm-Remove-CONFIG_NE2000_ISA-from-all-config-files.patch []
+- kvm-Fix-conditional-rpmbuild.patch []
+- kvm-RHEL7-RHEV7.1-2.0-migration-compatibility.patch [bz#1085950]
+- kvm-remove-superfluous-.hot_add_cpu-and-.max_cpus-initia.patch [bz#1085950]
+- kvm-set-model-in-PC_RHEL6_5_COMPAT-for-qemu32-VCPU-RHEV-.patch [bz#1085950]
+- kvm-Undo-Enable-x2apic-by-default-for-compatibility.patch [bz#1085950]
+- kvm-qemu_loadvm_state-shadow-SeaBIOS-for-VM-incoming-fro.patch [bz#1103579]
+- Resolves: bz#1085950
+  (Migration/virtio-net: 7.0->vp-2.0-rc2: Mix of migration issues)
+- Resolves: bz#1103579
+  (fail to reboot guest after migration from RHEL6.5 host to RHEL7.0 host)
+
+* Fri May 30 2014 Miroslav Rezanina <mrezanin@redhat.com> - rhev-2.0.0-2.el7
+- kvm-pc-add-hot_add_cpu-callback-to-all-machine-types.patch [bz#1093411]
+- Resolves: bz#1093411
+  (Hot unplug CPU not working for RHEL7 host)
+
+* Fri Apr 18 2014 Miroslav Rezanina <mrezanin@redhat.com> - 2.0.0-1.el7ev
+- Rebase to qemu 2.0.0
+
+* Wed Apr 02 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-60.el7
+- kvm-qcow2-fix-dangling-refcount-table-entry.patch [bz#1081793]
+- kvm-qcow2-link-all-L2-meta-updates-in-preallocate.patch [bz#1081393]
+- Resolves: bz#1081393
+  (qemu-img will prompt that 'leaked clusters were found' while creating images with '-o preallocation=metadata,cluster_size<=1024')
+- Resolves: bz#1081793
+  (qemu-img core dumped when creating a qcow2 image base on block device(iscsi or libiscsi))
+
+* Wed Mar 26 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-59.el7
+- kvm-qemu-iotests-add-.-check-cloop-support.patch [bz#1066691]
+- kvm-qemu-iotests-add-cloop-input-validation-tests.patch [bz#1066691]
+- kvm-block-cloop-validate-block_size-header-field-CVE-201.patch [bz#1079455]
+- kvm-block-cloop-prevent-offsets_size-integer-overflow-CV.patch [bz#1079320]
+- kvm-block-cloop-refuse-images-with-huge-offsets-arrays-C.patch [bz#1079455]
+- kvm-block-cloop-refuse-images-with-bogus-offsets-CVE-201.patch [bz#1079455]
+- kvm-size-off-by-one.patch [bz#1066691]
+- kvm-qemu-iotests-Support-for-bochs-format.patch [bz#1066691]
+- kvm-bochs-Unify-header-structs-and-make-them-QEMU_PACKED.patch [bz#1066691]
+- kvm-bochs-Use-unsigned-variables-for-offsets-and-sizes-C.patch [bz#1079339]
+- kvm-bochs-Check-catalog_size-header-field-CVE-2014-0143.patch [bz#1079320]
+- kvm-bochs-Check-extent_size-header-field-CVE-2014-0142.patch [bz#1079315]
+- kvm-bochs-Fix-bitmap-offset-calculation.patch [bz#1066691]
+- kvm-vpc-vhd-add-bounds-check-for-max_table_entries-and-b.patch [bz#1079455]
+- kvm-vpc-Validate-block-size-CVE-2014-0142.patch [bz#1079315]
+- kvm-vdi-add-bounds-checks-for-blocks_in_image-and-disk_s.patch [bz#1079455]
+- kvm-vhdx-Bounds-checking-for-block_size-and-logical_sect.patch [bz#1079346]
+- kvm-curl-check-data-size-before-memcpy-to-local-buffer.-.patch [bz#1079455]
+- kvm-qcow2-Check-header_length-CVE-2014-0144.patch [bz#1079455]
+- kvm-qcow2-Check-backing_file_offset-CVE-2014-0144.patch [bz#1079455]
+- kvm-qcow2-Check-refcount-table-size-CVE-2014-0144.patch [bz#1079455]
+- kvm-qcow2-Validate-refcount-table-offset.patch [bz#1066691]
+- kvm-qcow2-Validate-snapshot-table-offset-size-CVE-2014-0.patch [bz#1079455]
+- kvm-qcow2-Validate-active-L1-table-offset-and-size-CVE-2.patch [bz#1079455]
+- kvm-qcow2-Fix-backing-file-name-length-check.patch [bz#1066691]
+- kvm-qcow2-Don-t-rely-on-free_cluster_index-in-alloc_refc.patch [bz#1079339]
+- kvm-qcow2-Avoid-integer-overflow-in-get_refcount-CVE-201.patch [bz#1079320]
+- kvm-qcow2-Check-new-refcount-table-size-on-growth.patch [bz#1066691]
+- kvm-qcow2-Fix-types-in-qcow2_alloc_clusters-and-alloc_cl.patch [bz#1066691]
+- kvm-qcow2-Protect-against-some-integer-overflows-in-bdrv.patch [bz#1066691]
+- kvm-qcow2-Fix-new-L1-table-size-check-CVE-2014-0143.patch [bz#1079320]
+- kvm-dmg-coding-style-and-indentation-cleanup.patch [bz#1066691]
+- kvm-dmg-prevent-out-of-bounds-array-access-on-terminator.patch [bz#1066691]
+- kvm-dmg-drop-broken-bdrv_pread-loop.patch [bz#1066691]
+- kvm-dmg-use-appropriate-types-when-reading-chunks.patch [bz#1066691]
+- kvm-dmg-sanitize-chunk-length-and-sectorcount-CVE-2014-0.patch [bz#1079325]
+- kvm-dmg-use-uint64_t-consistently-for-sectors-and-length.patch [bz#1066691]
+- kvm-dmg-prevent-chunk-buffer-overflow-CVE-2014-0145.patch [bz#1079325]
+- kvm-block-vdi-bounds-check-qemu-io-tests.patch [bz#1066691]
+- kvm-block-Limit-request-size-CVE-2014-0143.patch [bz#1079320]
+- kvm-qcow2-Fix-copy_sectors-with-VM-state.patch [bz#1066691]
+- kvm-qcow2-Fix-NULL-dereference-in-qcow2_open-error-path-.patch [bz#1079333]
+- kvm-qcow2-Fix-L1-allocation-size-in-qcow2_snapshot_load_.patch [bz#1079325]
+- kvm-qcow2-Check-maximum-L1-size-in-qcow2_snapshot_load_t.patch [bz#1079320]
+- kvm-qcow2-Limit-snapshot-table-size.patch [bz#1066691]
+- kvm-parallels-Fix-catalog-size-integer-overflow-CVE-2014.patch [bz#1079320]
+- kvm-parallels-Sanity-check-for-s-tracks-CVE-2014-0142.patch [bz#1079315]
+- kvm-fix-machine-check-propagation.patch [bz#740107]
+- Resolves: bz#1066691
+  (qemu-kvm: include leftover patches from block layer security audit)
+- Resolves: bz#1079315
+  (CVE-2014-0142 qemu-kvm: qemu: crash by possible division by zero [rhel-7.0])
+- Resolves: bz#1079320
+  (CVE-2014-0143 qemu-kvm: Qemu: block: multiple integer overflow flaws [rhel-7.0])
+- Resolves: bz#1079325
+  (CVE-2014-0145 qemu-kvm: Qemu: prevent possible buffer overflows [rhel-7.0])
+- Resolves: bz#1079333
+  (CVE-2014-0146 qemu-kvm: Qemu: qcow2: NULL dereference in qcow2_open() error path [rhel-7.0])
+- Resolves: bz#1079339
+  (CVE-2014-0147 qemu-kvm: Qemu: block: possible crash due signed types or logic error [rhel-7.0])
+- Resolves: bz#1079346
+  (CVE-2014-0148 qemu-kvm: Qemu: vhdx: bounds checking for block_size and logical_sector_size [rhel-7.0])
+- Resolves: bz#1079455
+  (CVE-2014-0144 qemu-kvm: Qemu: block: missing input validation [rhel-7.0])
+- Resolves: bz#740107
+  ([Hitachi 7.0 FEAT]  KVM: MCA Recovery for KVM guest OS memory)
+
+* Wed Mar 26 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-58.el7
+- kvm-pc-Use-cpu64-rhel6-CPU-model-by-default-on-rhel6-mac.patch [bz#1080170]
+- kvm-target-i386-Copy-cpu64-rhel6-definition-into-qemu64.patch [bz#1078607 bz#1080170]
+- Resolves: bz#1080170
+  (intel 82576 VF not work in windows 2008 x86 - Code 12 [TestOnly])
+- Resolves: bz#1080170
+  (Default CPU model for rhel6.* machine-types is different from RHEL-6)
+
+* Fri Mar 21 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-57.el7
+- kvm-virtio-net-fix-guest-triggerable-buffer-overrun.patch [bz#1078308]
+- Resolves: bz#1078308
+  (EMBARGOED CVE-2014-0150 qemu: virtio-net: fix guest-triggerable buffer overrun [rhel-7.0])
+
+* Fri Mar 21 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-56.el7
+- kvm-configure-Fix-bugs-preventing-Ceph-inclusion.patch [bz#1078809]
+- Resolves: bz#1078809
+  (can not boot qemu-kvm-rhev with rbd image)
+
+* Wed Mar 19 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-55.el7
+- kvm-scsi-Change-scsi-sense-buf-size-to-252.patch [bz#1058173]
+- kvm-scsi-Fix-migration-of-scsi-sense-data.patch [bz#1058173]
+- Resolves: bz#1058173
+  (qemu-kvm core dump booting guest with scsi-generic disk attached when using built-in iscsi driver)
+
+* Wed Mar 19 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-54.el7
+- kvm-qdev-monitor-Set-properties-after-parent-is-assigned.patch [bz#1046248]
+- kvm-block-Update-image-size-in-bdrv_invalidate_cache.patch [bz#1048575]
+- kvm-qcow2-Keep-option-in-qcow2_invalidate_cache.patch [bz#1048575]
+- kvm-qcow2-Check-bs-drv-in-copy_sectors.patch [bz#1048575]
+- kvm-block-bs-drv-may-be-NULL-in-bdrv_debug_resume.patch [bz#1048575]
+- kvm-iotests-Test-corruption-during-COW-request.patch [bz#1048575]
+- Resolves: bz#1046248
+  (qemu-kvm crash when send "info qtree" after hot plug a device with invalid addr)
+- Resolves: bz#1048575
+  (Segmentation fault occurs after migrate guest(use scsi disk and add stress) to des machine)
+
+* Wed Mar 12 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-53.el7
+- kvm-dataplane-Fix-startup-race.patch [bz#1069541]
+- kvm-QMP-Relax-__com.redhat_drive_add-parameter-checking.patch [bz#1057471]
+- kvm-all-exit-in-case-max-vcpus-exceeded.patch [bz#993429]
+- kvm-block-gluster-code-movements-state-storage-changes.patch [bz#1031526]
+- kvm-block-gluster-add-reopen-support.patch [bz#1031526]
+- kvm-virtio-net-add-feature-bit-for-any-header-s-g.patch [bz#990989]
+- kvm-spec-Add-README.rhel6-gpxe-source.patch [bz#1073774]
+- kvm-pc-Add-RHEL6-e1000-gPXE-image.patch [bz#1073774]
+- kvm-loader-rename-in_ram-has_mr.patch [bz#1064018]
+- kvm-pc-avoid-duplicate-names-for-ROM-MRs.patch [bz#1064018]
+- kvm-qemu-img-convert-Fix-progress-output.patch [bz#1073728]
+- kvm-qemu-iotests-Test-progress-output-for-conversion.patch [bz#1073728]
+- kvm-iscsi-Use-bs-sg-for-everything-else-than-disks.patch [bz#1067784]
+- kvm-block-Fix-bs-request_alignment-assertion-for-bs-sg-1.patch [bz#1067784]
+- kvm-qemu_file-use-fwrite-correctly.patch [bz#1005103]
+- kvm-qemu_file-Fix-mismerge-of-use-fwrite-correctly.patch [bz#1005103]
+- Resolves: bz#1005103
+  (Migration should fail when migrate guest offline to a file which is specified to a readonly directory.)
+- Resolves: bz#1031526
+  (Can not commit snapshot when disk is using glusterfs:native backend)
+- Resolves: bz#1057471
+  (fail to do hot-plug with "discard = on" with "Invalid parameter 'discard'" error)
+- Resolves: bz#1064018
+  (abort from conflicting genroms)
+- Resolves: bz#1067784
+  (qemu-kvm: block.c:850: bdrv_open_common: Assertion `bs->request_alignment != 0' failed. Aborted (core dumped))
+- Resolves: bz#1069541
+  (Segmentation fault when boot guest with dataplane=on)
+- Resolves: bz#1073728
+  (progress bar doesn't display when converting with -p)
+- Resolves: bz#1073774
+  (e1000 ROM cause migrate fail  from RHEL6.5 host to RHEL7.0 host)
+- Resolves: bz#990989
+  (backport inline header virtio-net optimization)
+- Resolves: bz#993429
+  (kvm: test maximum number of vcpus supported (rhel7))
+
+* Wed Mar 05 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-52.el7
+- kvm-target-i386-Move-hyperv_-static-globals-to-X86CPU.patch [bz#1004773]
+- kvm-Fix-uninitialized-cpuid_data.patch [bz#1057173]
+- kvm-fix-coexistence-of-KVM-and-Hyper-V-leaves.patch [bz#1004773]
+- kvm-make-availability-of-Hyper-V-enlightenments-depe.patch [bz#1004773]
+- kvm-make-hyperv-hypercall-and-guest-os-id-MSRs-migra.patch [bz#1004773]
+- kvm-make-hyperv-vapic-assist-page-migratable.patch [bz#1004773]
+- kvm-target-i386-Convert-hv_relaxed-to-static-property.patch [bz#1057173]
+- kvm-target-i386-Convert-hv_vapic-to-static-property.patch [bz#1057173]
+- kvm-target-i386-Convert-hv_spinlocks-to-static-property.patch [bz#1057173]
+- kvm-target-i386-Convert-check-and-enforce-to-static-prop.patch [bz#1004773]
+- kvm-target-i386-Cleanup-foo-feature-handling.patch [bz#1057173]
+- kvm-add-support-for-hyper-v-timers.patch [bz#1057173]
+- Resolves: bz#1004773
+  (Hyper-V guest OS id and hypercall MSRs not migrated)
+- Resolves: bz#1057173
+  (KVM Hyper-V Enlightenment - New feature - hv-time (QEMU))
+
+* Wed Mar 05 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-51.el7
+- kvm-qmp-access-the-local-QemuOptsLists-for-drive-option.patch [bz#1026184]
+- kvm-qxl-add-sanity-check.patch [bz#751937]
+- kvm-Fix-two-XBZRLE-corruption-issues.patch [bz#1063417]
+- kvm-qdev-monitor-set-DeviceState-opts-before-calling-rea.patch [bz#1037956]
+- kvm-vfio-blacklist-loading-of-unstable-roms.patch [bz#1037956]
+- kvm-block-Set-block-filename-sizes-to-PATH_MAX-instead-o.patch [bz#1072339]
+- Resolves: bz#1026184
+  (QMP: querying -drive option returns a NULL parameter list)
+- Resolves: bz#1037956
+  (bnx2x: boot one guest to do vfio-pci with all PFs assigned in same group meet QEMU segmentation fault (Broadcom BCM57810 card))
+- Resolves: bz#1063417
+  (google stressapptest vs Migration)
+- Resolves: bz#1072339
+  (RHEV: Cannot start VMs that have more than 23 snapshots.)
+- Resolves: bz#751937
+  (qxl triggers assert during iofuzz test)
+
+* Wed Feb 26 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-50.el7
+- kvm-mempath-prefault-fix-off-by-one-error.patch [bz#1069039]
+- kvm-qemu-option-has_help_option-and-is_valid_option_list.patch [bz#1065873]
+- kvm-qemu-img-create-Support-multiple-o-options.patch [bz#1065873]
+- kvm-qemu-img-convert-Support-multiple-o-options.patch [bz#1065873]
+- kvm-qemu-img-amend-Support-multiple-o-options.patch [bz#1065873]
+- kvm-qemu-img-Allow-o-help-with-incomplete-argument-list.patch [bz#1065873]
+- kvm-qemu-iotests-Check-qemu-img-command-line-parsing.patch [bz#1065873]
+- Resolves: bz#1065873
+  (qemu-img silently ignores options with multiple -o parameters)
+- Resolves: bz#1069039
+  (-mem-prealloc option behaviour is opposite to expected)
+
+* Wed Feb 19 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-49.el7
+- kvm-xhci-add-support-for-suspend-resume.patch [bz#1012365]
+- kvm-qcow2-remove-n_start-and-n_end-of-qcow2_alloc_cluste.patch [bz#1049176]
+- kvm-qcow2-fix-offset-overflow-in-qcow2_alloc_clusters_at.patch [bz#1049176]
+- kvm-qcow2-check-for-NULL-l2meta.patch [bz#1055848]
+- kvm-qemu-iotests-add-test-for-qcow2-preallocation-with-d.patch [bz#1055848]
+- Resolves: bz#1012365
+  (xhci usb storage lost in guest after wakeup from S3)
+- Resolves: bz#1049176
+  (qemu-img core dump when using "-o preallocation=metadata,cluster_size=2048k" to create image of libiscsi lun)
+- Resolves: bz#1055848
+  (qemu-img core dumped when cluster size is larger than the default value with opreallocation=metadata specified)
+
+* Mon Feb 17 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-48.el7
+- kvm-spec-disable-qom-cast-debug.patch [bz#1063942]
+- kvm-fix-guest-physical-bits-to-match-host-to-go-beyond-1.patch [bz#989677]
+- kvm-monitor-Cleanup-mon-outbuf-on-write-error.patch [bz#1065225]
+- Resolves: bz#1063942
+  (configure qemu-kvm with --disable-qom-cast-debug)
+- Resolves: bz#1065225
+  (QMP socket breaks on unexpected close)
+- Resolves: bz#989677
+  ([HP 7.0 FEAT]: Increase KVM guest supported memory to 4TiB)
+
+* Wed Feb 12 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-47.el7
+- kvm-seccomp-add-mkdir-and-fchmod-to-the-whitelist.patch [bz#1026314]
+- kvm-seccomp-add-some-basic-shared-memory-syscalls-to-the.patch [bz#1026314]
+- kvm-scsi-Support-TEST-UNIT-READY-in-the-dummy-LUN0.patch [bz#1004143]
+- kvm-usb-add-vendor-request-defines.patch [bz#1039530]
+- kvm-usb-move-usb_-hi-lo-helpers-to-header-file.patch [bz#1039530]
+- kvm-usb-add-support-for-microsoft-os-descriptors.patch [bz#1039530]
+- kvm-usb-add-microsoft-os-descriptors-compat-property.patch [bz#1039530]
+- kvm-usb-hid-add-microsoft-os-descriptor-support.patch [bz#1039530]
+- kvm-configure-add-option-to-disable-fstack-protect.patch [bz#1044182]
+- kvm-exec-always-use-MADV_DONTFORK.patch [bz#1004197]
+- kvm-pc-Save-size-of-RAM-below-4GB.patch [bz#1048080]
+- kvm-acpi-Fix-PCI-hole-handling-on-build_srat.patch [bz#1048080]
+- kvm-Add-check-for-cache-size-smaller-than-page-size.patch [bz#1017096]
+- kvm-XBZRLE-cache-size-should-not-be-larger-than-guest-me.patch [bz#1047448]
+- kvm-Don-t-abort-on-out-of-memory-when-creating-page-cach.patch [bz#1047448]
+- kvm-Don-t-abort-on-memory-allocation-error.patch [bz#1047448]
+- kvm-Set-xbzrle-buffers-to-NULL-after-freeing-them-to-avo.patch [bz#1038540]
+- kvm-migration-fix-free-XBZRLE-decoded_buf-wrong.patch [bz#1038540]
+- kvm-block-resize-backing-file-image-during-offline-commi.patch [bz#1047254]
+- kvm-block-resize-backing-image-during-active-layer-commi.patch [bz#1047254]
+- kvm-block-update-block-commit-documentation-regarding-im.patch [bz#1047254]
+- kvm-block-Fix-bdrv_commit-return-value.patch [bz#1047254]
+- kvm-block-remove-QED-.bdrv_make_empty-implementation.patch [bz#1047254]
+- kvm-block-remove-qcow2-.bdrv_make_empty-implementation.patch [bz#1047254]
+- kvm-qemu-progress-Drop-unused-include.patch [bz#997878]
+- kvm-qemu-progress-Fix-progress-printing-on-SIGUSR1.patch [bz#997878]
+- kvm-Documentation-qemu-img-Mention-SIGUSR1-progress-repo.patch [bz#997878]
+- Resolves: bz#1004143
+  ("test unit ready failed" on LUN 0 delays boot when a virtio-scsi target does not have any disk on LUN 0)
+- Resolves: bz#1004197
+  (Cannot hot-plug nic in windows VM when the vmem is larger)
+- Resolves: bz#1017096
+  (Fail to migrate while the size of migrate-compcache less then 4096)
+- Resolves: bz#1026314
+  (qemu-kvm hang when use '-sandbox on'+'vnc'+'hda')
+- Resolves: bz#1038540
+  (qemu-kvm aborted while cancel migration then restart it (with page delta compression))
+- Resolves: bz#1039530
+  (add support for microsoft os descriptors)
+- Resolves: bz#1044182
+  (Relax qemu-kvm stack protection to -fstack-protector-strong)
+- Resolves: bz#1047254
+  (qemu-img failed to commit image)
+- Resolves: bz#1047448
+  (qemu-kvm core  dump in src host when do migration with "migrate_set_capability xbzrle on and migrate_set_cache_size 10000G")
+- Resolves: bz#1048080
+  (Qemu-kvm NUMA emulation failed)
+- Resolves: bz#997878
+  (Kill -SIGUSR1 `pidof qemu-img convert` can not get progress of qemu-img)
+
+* Wed Feb 12 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-46.el7
+- kvm-block-fix-backing-file-segfault.patch [bz#748906]
+- kvm-block-Move-initialisation-of-BlockLimits-to-bdrv_ref.patch [bz#748906]
+- kvm-raw-Fix-BlockLimits-passthrough.patch [bz#748906]
+- kvm-block-Inherit-opt_transfer_length.patch [bz#748906]
+- kvm-block-Update-BlockLimits-when-they-might-have-change.patch [bz#748906]
+- kvm-qemu_memalign-Allow-small-alignments.patch [bz#748906]
+- kvm-block-Detect-unaligned-length-in-bdrv_qiov_is_aligne.patch [bz#748906]
+- kvm-block-Don-t-use-guest-sector-size-for-qemu_blockalig.patch [bz#748906]
+- kvm-block-rename-buffer_alignment-to-guest_block_size.patch [bz#748906]
+- kvm-raw-Probe-required-direct-I-O-alignment.patch [bz#748906]
+- kvm-block-Introduce-bdrv_aligned_preadv.patch [bz#748906]
+- kvm-block-Introduce-bdrv_co_do_preadv.patch [bz#748906]
+- kvm-block-Introduce-bdrv_aligned_pwritev.patch [bz#748906]
+- kvm-block-write-Handle-COR-dependency-after-I-O-throttli.patch [bz#748906]
+- kvm-block-Introduce-bdrv_co_do_pwritev.patch [bz#748906]
+- kvm-block-Switch-BdrvTrackedRequest-to-byte-granularity.patch [bz#748906]
+- kvm-block-Allow-waiting-for-overlapping-requests-between.patch [bz#748906]
+- kvm-block-use-DIV_ROUND_UP-in-bdrv_co_do_readv.patch [bz#748906]
+- kvm-block-Make-zero-after-EOF-work-with-larger-alignment.patch [bz#748906]
+- kvm-block-Generalise-and-optimise-COR-serialisation.patch [bz#748906]
+- kvm-block-Make-overlap-range-for-serialisation-dynamic.patch [bz#748906]
+- kvm-block-Fix-32-bit-truncation-in-mark_request_serialis.patch [bz#748906]
+- kvm-block-Allow-wait_serialising_requests-at-any-point.patch [bz#748906]
+- kvm-block-Align-requests-in-bdrv_co_do_pwritev.patch [bz#748906]
+- kvm-lock-Fix-memory-leaks-in-bdrv_co_do_pwritev.patch [bz#748906]
+- kvm-block-Assert-serialisation-assumptions-in-pwritev.patch [bz#748906]
+- kvm-block-Change-coroutine-wrapper-to-byte-granularity.patch [bz#748906]
+- kvm-block-Make-bdrv_pread-a-bdrv_prwv_co-wrapper.patch [bz#748906]
+- kvm-block-Make-bdrv_pwrite-a-bdrv_prwv_co-wrapper.patch [bz#748906]
+- kvm-iscsi-Set-bs-request_alignment.patch [bz#748906]
+- kvm-blkdebug-Make-required-alignment-configurable.patch [bz#748906]
+- kvm-blkdebug-Don-t-leak-bs-file-on-failure.patch [bz#748906]
+- kvm-qemu-io-New-command-sleep.patch [bz#748906]
+- kvm-qemu-iotests-Filter-out-qemu-io-prompt.patch [bz#748906]
+- kvm-qemu-iotests-Test-pwritev-RMW-logic.patch [bz#748906]
+- kvm-block-bdrv_aligned_pwritev-Assert-overlap-range.patch [bz#748906]
+- kvm-block-Don-t-call-ROUND_UP-with-negative-values.patch [bz#748906]
+- Resolves: bz#748906
+  (qemu fails on disk with 4k sectors and cache=off)
+
+* Wed Feb 05 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-45.el7
+- kvm-vfio-pci-Fail-initfn-on-DMA-mapping-errors.patch [bz#1044815]
+- kvm-vfio-Destroy-memory-regions.patch [bz#1052030]
+- kvm-docs-qcow2-compat-1.1-is-now-the-default.patch [bz#1048092]
+- kvm-hda-codec-disable-streams-on-reset.patch [bz#947812]
+- kvm-QEMUBH-make-AioContext-s-bh-re-entrant.patch [bz#1009297]
+- kvm-qxl-replace-pipe-signaling-with-bottom-half.patch [bz#1009297]
+- Resolves: bz#1009297
+  (RHEL7.0 guest gui can not be used in dest host after migration)
+- Resolves: bz#1044815
+  (vfio initfn succeeds even if IOMMU mappings fail)
+- Resolves: bz#1048092
+  (manpage of qemu-img contains error statement about compat option)
+- Resolves: bz#1052030
+  (src qemu-kvm core dump after hotplug/unhotplug GPU device and do local migration)
+- Resolves: bz#947812
+  (There's a shot voice after  'system_reset'  during playing music inside rhel6 guest w/ intel-hda device)
+
+* Wed Jan 29 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-44.el7
+- kvm-Partially-revert-rhel-Drop-cfi.pflash01-and-isa-ide-.patch [bz#1032346]
+- kvm-Revert-pc-Disable-the-use-flash-device-for-BIOS-unle.patch [bz#1032346]
+- kvm-memory-Replace-open-coded-memory_region_is_romd.patch [bz#1032346]
+- kvm-memory-Rename-readable-flag-to-romd_mode.patch [bz#1032346]
+- kvm-isapc-Fix-non-KVM-qemu-boot-read-write-memory-for-is.patch [bz#1032346]
+- kvm-add-kvm_readonly_mem_enabled.patch [bz#1032346]
+- kvm-support-using-KVM_MEM_READONLY-flag-for-regions.patch [bz#1032346]
+- kvm-pc_sysfw-allow-flash-pflash-memory-to-be-used-with-K.patch [bz#1032346]
+- kvm-fix-double-free-the-memslot-in-kvm_set_phys_mem.patch [bz#1032346]
+- kvm-sysfw-remove-read-only-pc_sysfw_flash_vs_rom_bug_com.patch [bz#1032346]
+- kvm-pc_sysfw-remove-the-rom_only-property.patch [bz#1032346]
+- kvm-pc_sysfw-do-not-make-it-a-device-anymore.patch [bz#1032346]
+- kvm-hw-i386-pc_sysfw-support-two-flash-drives.patch [bz#1032346]
+- kvm-i440fx-test-qtest_start-should-be-paired-with-qtest_.patch [bz#1032346]
+- kvm-i440fx-test-give-each-GTest-case-its-own-qtest.patch [bz#1032346]
+- kvm-i440fx-test-generate-temporary-firmware-blob.patch [bz#1032346]
+- kvm-i440fx-test-verify-firmware-under-4G-and-1M-both-bio.patch [bz#1032346]
+- kvm-piix-fix-32bit-pci-hole.patch [bz#1032346]
+- kvm-qapi-Add-backing-to-BlockStats.patch [bz#1041564]
+- kvm-pc-Disable-RDTSCP-unconditionally-on-rhel6.-machine-.patch [bz#918907]
+- kvm-pc-Disable-RDTSCP-on-AMD-CPU-models.patch [bz#1056428 bz#874400]
+- kvm-block-add-.bdrv_reopen_prepare-stub-for-iscsi.patch [bz#1030301]
+- Resolves: bz#1030301
+  (qemu-img can not merge live snapshot to backing file(r/w backing file via libiscsi))
+- Resolves: bz#1032346
+  (basic OVMF support (non-volatile UEFI variables in flash, and fixup for ACPI tables))
+- Resolves: bz#1041564
+  ([NFR] qemu: Returning the watermark for all the images opened for writing)
+- Resolves: bz#1056428
+  ("rdtscp" flag defined on Opteron_G5 model and cann't be exposed to guest)
+- Resolves: bz#874400
+  ("rdtscp" flag defined on Opteron_G5 model and cann't be exposed to guest)
+- Resolves: bz#918907
+  (provide backwards-compatible RHEL specific machine types in QEMU - CPU features)
+
+* Mon Jan 27 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-43.el7
+- kvm-piix-gigabyte-alignment-for-ram.patch [bz#1026548]
+- kvm-pc_piix-document-gigabyte_align.patch [bz#1026548]
+- kvm-q35-gigabyle-alignment-for-ram.patch [bz#1026548]
+- kvm-virtio-bus-remove-vdev-field.patch [bz#983344]
+- kvm-virtio-pci-remove-vdev-field.patch [bz#983344]
+- kvm-virtio-bus-cleanup-plug-unplug-interface.patch [bz#983344]
+- kvm-virtio-blk-switch-exit-callback-to-VirtioDeviceClass.patch [bz#983344]
+- kvm-virtio-serial-switch-exit-callback-to-VirtioDeviceCl.patch [bz#983344]
+- kvm-virtio-net-switch-exit-callback-to-VirtioDeviceClass.patch [bz#983344]
+- kvm-virtio-scsi-switch-exit-callback-to-VirtioDeviceClas.patch [bz#983344]
+- kvm-virtio-balloon-switch-exit-callback-to-VirtioDeviceC.patch [bz#983344]
+- kvm-virtio-rng-switch-exit-callback-to-VirtioDeviceClass.patch [bz#983344]
+- kvm-virtio-pci-add-device_unplugged-callback.patch [bz#983344]
+- kvm-block-use-correct-filename-for-error-report.patch [bz#1051438]
+- Resolves: bz#1026548
+  (i386: pc: align gpa<->hpa on 1GB boundary)
+- Resolves: bz#1051438
+  (Error message contains garbled characters when unable to open image due to bad permissions (permission denied).)
+- Resolves: bz#983344
+  (QEMU core dump and host will reboot when do hot-unplug a virtio-blk disk which use  the switch behind switch)
+
+* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 10:1.5.3-42
+- Mass rebuild 2014-01-24
+
+* Wed Jan 22 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-41.el7
+- kvm-help-add-id-suboption-to-iscsi.patch [bz#1019221]
+- kvm-scsi-disk-add-UNMAP-limits-to-block-limits-VPD-page.patch [bz#1037503]
+- kvm-qdev-Fix-32-bit-compilation-in-print_size.patch [bz#1034876]
+- kvm-qdev-Use-clz-in-print_size.patch [bz#1034876]
+- Resolves: bz#1019221
+  (Iscsi miss id sub-option in help output)
+- Resolves: bz#1034876
+  (export acpi tables to guests)
+- Resolves: bz#1037503
+  (fix thin provisioning support for block device backends)
+
+* Wed Jan 22 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-40.el7
+- kvm-avoid-a-bogus-COMPLETED-CANCELLED-transition.patch [bz#1053699]
+- kvm-introduce-MIG_STATE_CANCELLING-state.patch [bz#1053699]
+- kvm-vvfat-use-bdrv_new-to-allocate-BlockDriverState.patch [bz#1041301]
+- kvm-block-implement-reference-count-for-BlockDriverState.patch [bz#1041301]
+- kvm-block-make-bdrv_delete-static.patch [bz#1041301]
+- kvm-migration-omit-drive-ref-as-we-have-bdrv_ref-now.patch [bz#1041301]
+- kvm-xen_disk-simplify-blk_disconnect-with-refcnt.patch [bz#1041301]
+- kvm-nbd-use-BlockDriverState-refcnt.patch [bz#1041301]
+- kvm-block-use-BDS-ref-for-block-jobs.patch [bz#1041301]
+- kvm-block-Make-BlockJobTypes-const.patch [bz#1041301]
+- kvm-blockjob-rename-BlockJobType-to-BlockJobDriver.patch [bz#1041301]
+- kvm-qapi-Introduce-enum-BlockJobType.patch [bz#1041301]
+- kvm-qapi-make-use-of-new-BlockJobType.patch [bz#1041301]
+- kvm-mirror-Don-t-close-target.patch [bz#1041301]
+- kvm-mirror-Move-base-to-MirrorBlockJob.patch [bz#1041301]
+- kvm-block-Add-commit_active_start.patch [bz#1041301]
+- kvm-commit-Support-commit-active-layer.patch [bz#1041301]
+- kvm-qemu-iotests-prefill-some-data-to-test-image.patch [bz#1041301]
+- kvm-qemu-iotests-Update-test-cases-for-commit-active.patch [bz#1041301]
+- kvm-commit-Remove-unused-check.patch [bz#1041301]
+- kvm-blockdev-use-bdrv_getlength-in-qmp_drive_mirror.patch [bz#921890]
+- kvm-qemu-iotests-make-assert_no_active_block_jobs-common.patch [bz#921890]
+- kvm-block-drive-mirror-Check-for-NULL-backing_hd.patch [bz#921890]
+- kvm-qemu-iotests-Extend-041-for-unbacked-mirroring.patch [bz#921890]
+- kvm-qapi-schema-Update-description-for-NewImageMode.patch [bz#921890]
+- kvm-block-drive-mirror-Reuse-backing-HD-for-sync-none.patch [bz#921890]
+- kvm-qemu-iotests-Fix-test-041.patch [bz#921890]
+- kvm-scsi-bus-fix-transfer-length-and-direction-for-VERIF.patch [bz#1035644]
+- kvm-scsi-disk-fix-VERIFY-emulation.patch [bz#1035644]
+- kvm-block-ensure-bdrv_drain_all-works-during-bdrv_delete.patch [bz#1041301]
+- kvm-use-recommended-max-vcpu-count.patch [bz#998708]
+- kvm-pc-Create-pc_compat_rhel-functions.patch [bz#1049706]
+- kvm-pc-Enable-x2apic-by-default-on-more-recent-CPU-model.patch [bz#1049706]
+- kvm-Build-all-subpackages-for-RHEV.patch [bz#1007204]
+- Resolves: bz#1007204
+  (qemu-img-rhev  qemu-kvm-rhev-tools are not built for qemu-kvm-1.5.3-3.el7)
+- Resolves: bz#1035644
+  (rhel7.0host + windows guest + virtio-win + 'chkdsk' in the guest gives qemu assertion in scsi_dma_complete)
+- Resolves: bz#1041301
+  (live snapshot merge (commit) of the active layer)
+- Resolves: bz#1049706
+  (MIss CPUID_EXT_X2APIC in Westmere cpu model)
+- Resolves: bz#1053699
+  (Backport Cancelled race condition fixes)
+- Resolves: bz#921890
+  (Core dump when block mirror with "sync" is "none" and mode is "absolute-paths")
+- Resolves: bz#998708
+  (qemu-kvm: maximum vcpu should be recommended maximum)
+
+* Tue Jan 21 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-39.el7
+- kvm-Revert-qdev-monitor-Fix-crash-when-device_add-is-cal.patch [bz#669524]
+- kvm-Revert-qdev-Do-not-let-the-user-try-to-device_add-wh.patch [bz#669524]
+- kvm-qdev-monitor-Clean-up-qdev_device_add-variable-namin.patch [bz#669524]
+- kvm-qdev-monitor-Fix-crash-when-device_add-is-called.2.patch.patch [bz#669524]
+- kvm-qdev-monitor-Avoid-qdev-as-variable-name.patch [bz#669524]
+- kvm-qdev-monitor-Inline-qdev_init-for-device_add.patch [bz#669524]
+- kvm-qdev-Do-not-let-the-user-try-to-device_add-when-it.2.patch.patch [bz#669524]
+- kvm-qdev-monitor-Avoid-device_add-crashing-on-non-device.patch [bz#669524]
+- kvm-qdev-monitor-Improve-error-message-for-device-nonexi.patch [bz#669524]
+- kvm-exec-change-well-known-physical-sections-to-macros.patch [bz#1003535]
+- kvm-exec-separate-sections-and-nodes-per-address-space.patch [bz#1003535]
+- Resolves: bz#1003535
+  (qemu-kvm core dump when boot vm with more than 32 virtio disks/nics)
+- Resolves: bz#669524
+  (Confusing error message from -device <unknown dev>)
+
+* Fri Jan 17 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-38.el7
+- kvm-intel-hda-fix-position-buffer.patch [bz#947785]
+- kvm-The-calculation-of-bytes_xfer-in-qemu_put_buffer-is-.patch [bz#1003467]
+- kvm-migration-Fix-rate-limit.patch [bz#1003467]
+- kvm-audio-honor-QEMU_AUDIO_TIMER_PERIOD-instead-of-wakin.patch [bz#1017636]
+- kvm-audio-Lower-default-wakeup-rate-to-100-times-second.patch [bz#1017636]
+- kvm-audio-adjust-pulse-to-100Hz-wakeup-rate.patch [bz#1017636]
+- kvm-pc-Fix-rhel6.-3dnow-3dnowext-compat-bits.patch [bz#918907]
+- kvm-add-firmware-to-machine-options.patch [bz#1038603]
+- kvm-switch-rhel7-machine-types-to-big-bios.patch [bz#1038603]
+- kvm-add-bios-256k.bin-from-seabios-bin-1.7.2.2-10.el7.no.patch [bz#1038603]
+- kvm-pci-fix-pci-bridge-fw-path.patch [bz#1034518]
+- kvm-hw-cannot_instantiate_with_device_add_yet-due-to-poi.patch [bz#1031098]
+- kvm-qdev-Document-that-pointer-properties-kill-device_ad.patch [bz#1031098]
+- kvm-Add-back-no-hpet-but-ignore-it.patch [bz#1044742]
+- Resolves: bz#1003467
+  (Backport migration fixes from post qemu 1.6)
+- Resolves: bz#1017636
+  (PATCH: fix qemu using 50% host cpu when audio is playing)
+- Resolves: bz#1031098
+  (Disable device smbus-eeprom)
+- Resolves: bz#1034518
+  (boot order wrong with q35)
+- Resolves: bz#1038603
+  (make seabios 256k for rhel7 machine types)
+- Resolves: bz#1044742
+  (Cannot create guest on remote RHEL7 host using F20 virt-manager, libvirt's qemu -no-hpet detection is broken)
+- Resolves: bz#918907
+  (provide backwards-compatible RHEL specific machine types in QEMU - CPU features)
+- Resolves: bz#947785
+  (In rhel6.4 guest  sound recorder doesn't work when  playing audio)
+
+* Wed Jan 15 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-37.el7
+- kvm-bitmap-use-long-as-index.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_set_dirty_flags-result-is.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_set_dirty_range-return-vo.patch [bz#997559]
+- kvm-exec-use-accessor-function-to-know-if-memory-is-dirt.patch [bz#997559]
+- kvm-memory-create-function-to-set-a-single-dirty-bit.patch [bz#997559]
+- kvm-exec-drop-useless-if.patch [bz#997559]
+- kvm-exec-create-function-to-get-a-single-dirty-bit.patch [bz#997559]
+- kvm-memory-make-cpu_physical_memory_is_dirty-return-bool.patch [bz#997559]
+- kvm-memory-all-users-of-cpu_physical_memory_get_dirty-us.patch [bz#997559]
+- kvm-memory-set-single-dirty-flags-when-possible.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_set_dirty_range-always-di.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_mask_dirty_range-always-c.patch [bz#997559]
+- kvm-memory-use-bit-2-for-migration.patch [bz#997559]
+- kvm-memory-make-sure-that-client-is-always-inside-range.patch [bz#997559]
+- kvm-memory-only-resize-dirty-bitmap-when-memory-size-inc.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_clear_dirty_flag-result-i.patch [bz#997559]
+- kvm-bitmap-Add-bitmap_zero_extend-operation.patch [bz#997559]
+- kvm-memory-split-dirty-bitmap-into-three.patch [bz#997559]
+- kvm-memory-unfold-cpu_physical_memory_clear_dirty_flag-i.patch [bz#997559]
+- kvm-memory-unfold-cpu_physical_memory_set_dirty-in-its-o.patch [bz#997559]
+- kvm-memory-unfold-cpu_physical_memory_set_dirty_flag.patch [bz#997559]
+- kvm-memory-make-cpu_physical_memory_get_dirty-the-main-f.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_get_dirty-is-used-as-retu.patch [bz#997559]
+- kvm-memory-s-mask-clear-cpu_physical_memory_mask_dirty_r.patch [bz#997559]
+- kvm-memory-use-find_next_bit-to-find-dirty-bits.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_set_dirty_range-now-uses-.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_clear_dirty_range-now-use.patch [bz#997559]
+- kvm-memory-s-dirty-clean-in-cpu_physical_memory_is_dirty.patch [bz#997559]
+- kvm-memory-make-cpu_physical_memory_reset_dirty-take-a-l.patch [bz#997559]
+- kvm-exec-Remove-unused-global-variable-phys_ram_fd.patch [bz#997559]
+- kvm-memory-cpu_physical_memory_set_dirty_tracking-should.patch [bz#997559]
+- kvm-memory-move-private-types-to-exec.c.patch [bz#997559]
+- kvm-memory-split-cpu_physical_memory_-functions-to-its-o.patch [bz#997559]
+- kvm-memory-unfold-memory_region_test_and_clear.patch [bz#997559]
+- kvm-use-directly-cpu_physical_memory_-api-for-tracki.patch [bz#997559]
+- kvm-refactor-start-address-calculation.patch [bz#997559]
+- kvm-memory-move-bitmap-synchronization-to-its-own-functi.patch [bz#997559]
+- kvm-memory-syncronize-kvm-bitmap-using-bitmaps-operation.patch [bz#997559]
+- kvm-ram-split-function-that-synchronizes-a-range.patch [bz#997559]
+- kvm-migration-synchronize-memory-bitmap-64bits-at-a-time.patch [bz#997559]
+- Resolves: bz#997559
+  (Improve live migration bitmap handling)
+
+* Tue Jan 14 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-36.el7
+- kvm-Add-support-statement-to-help-output.patch [bz#972773]
+- kvm-__com.redhat_qxl_screendump-add-docs.patch [bz#903910]
+- kvm-vl-Round-memory-sizes-below-2MiB-up-to-2MiB.patch [bz#999836]
+- kvm-seccomp-exit-if-seccomp_init-fails.patch [bz#1044845]
+- kvm-redhat-qemu-kvm.spec-require-python-for-build.patch [bz#1034876]
+- kvm-redhat-qemu-kvm.spec-require-iasl.patch [bz#1034876]
+- kvm-configure-make-iasl-option-actually-work.patch [bz#1034876]
+- kvm-redhat-qemu-kvm.spec-add-cpp-as-build-dependency.patch [bz#1034876]
+- kvm-acpi-build-disable-with-no-acpi.patch [bz#1045386]
+- kvm-ehci-implement-port-wakeup.patch [bz#1039513]
+- kvm-qdev-monitor-Fix-crash-when-device_add-is-called-wit.patch [bz#1026712 bz#1046007]
+- kvm-block-vhdx-improve-error-message-and-.bdrv_check-imp.patch [bz#1035001]
+- kvm-docs-updated-qemu-img-man-page-and-qemu-doc-to-refle.patch [bz#1017650]
+- kvm-enable-pvticketlocks-by-default.patch [bz#1052340]
+- kvm-fix-boot-strict-regressed-in-commit-6ef4716.patch [bz#997817]
+- kvm-vl-make-boot_strict-variable-static-not-used-outside.patch [bz#997817]
+- Resolves: bz#1017650
+  (need to update qemu-img man pages on "VHDX" format)
+- Resolves: bz#1026712
+  (Qemu core dumpd when boot guest with driver name as "virtio-pci")
+- Resolves: bz#1034876
+  (export acpi tables to guests)
+- Resolves: bz#1035001
+  (VHDX: journal log should not be replayed by default, but rather via qemu-img check -r all)
+- Resolves: bz#1039513
+  (backport remote wakeup for ehci)
+- Resolves: bz#1044845
+  (QEMU seccomp sandbox - exit if seccomp_init() fails)
+- Resolves: bz#1045386
+  (qemu-kvm: hw/i386/acpi-build.c:135: acpi_get_pm_info: Assertion `obj' failed.)
+- Resolves: bz#1046007
+  (qemu-kvm aborted when hot plug PCI device to guest with romfile and rombar=0)
+- Resolves: bz#1052340
+  (pvticketlocks: default on)
+- Resolves: bz#903910
+  (RHEL7 does not have equivalent functionality for __com.redhat_qxl_screendump)
+- Resolves: bz#972773
+  (RHEL7: Clarify support statement in KVM help)
+- Resolves: bz#997817
+  (-boot order and -boot once regressed since RHEL-6)
+- Resolves: bz#999836
+  (-m 1 crashes)
+
+* Thu Jan 09 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-35.el7
+- kvm-option-Add-assigned-flag-to-QEMUOptionParameter.patch [bz#1033490]
+- kvm-qcow2-refcount-Snapshot-update-for-zero-clusters.patch [bz#1033490]
+- kvm-qemu-iotests-Snapshotting-zero-clusters.patch [bz#1033490]
+- kvm-block-Image-file-option-amendment.patch [bz#1033490]
+- kvm-qcow2-cache-Empty-cache.patch [bz#1033490]
+- kvm-qcow2-cluster-Expand-zero-clusters.patch [bz#1033490]
+- kvm-qcow2-Save-refcount-order-in-BDRVQcowState.patch [bz#1033490]
+- kvm-qcow2-Implement-bdrv_amend_options.patch [bz#1033490]
+- kvm-qcow2-Correct-bitmap-size-in-zero-expansion.patch [bz#1033490]
+- kvm-qcow2-Free-only-newly-allocated-clusters-on-error.patch [bz#1033490]
+- kvm-qcow2-Add-missing-space-in-error-message.patch [bz#1033490]
+- kvm-qemu-iotest-qcow2-image-option-amendment.patch [bz#1033490]
+- kvm-qemu-iotests-New-test-case-in-061.patch [bz#1033490]
+- kvm-qemu-iotests-Preallocated-zero-clusters-in-061.patch [bz#1033490]
+- Resolves: bz#1033490
+  (Cannot upgrade/downgrade qcow2 images)
+
+* Wed Jan 08 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-34.el7
+- kvm-block-stream-Don-t-stream-unbacked-devices.patch [bz#965636]
+- kvm-qemu-io-Let-open-pass-options-to-block-driver.patch [bz#1004347]
+- kvm-qcow2.py-Subcommand-for-changing-header-fields.patch [bz#1004347]
+- kvm-qemu-iotests-Remaining-error-propagation-adjustments.patch [bz#1004347]
+- kvm-qemu-iotests-Add-test-for-inactive-L2-overlap.patch [bz#1004347]
+- kvm-qemu-iotests-Adjust-test-result-039.patch [bz#1004347]
+- kvm-virtio-net-don-t-update-mac_table-in-error-state.patch [bz#1048671]
+- kvm-qcow2-Zero-initialise-first-cluster-for-new-images.patch [bz#1032904]
+- Resolves: bz#1004347
+  (Backport qcow2 corruption prevention patches)
+- Resolves: bz#1032904
+  (qemu-img can not create libiscsi qcow2_v3 image)
+- Resolves: bz#1048671
+  (virtio-net: mac_table change isn't recovered in error state)
+- Resolves: bz#965636
+  (streaming with no backing file should not do anything)
+
+* Wed Jan 08 2014 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-33.el7
+- kvm-block-qemu-iotests-for-vhdx-read-sample-dynamic-imag.patch [bz#879234]
+- kvm-block-qemu-iotests-add-quotes-to-TEST_IMG-usage-io-p.patch [bz#879234]
+- kvm-block-qemu-iotests-fix-_make_test_img-to-work-with-s.patch [bz#879234]
+- kvm-block-qemu-iotests-add-quotes-to-TEST_IMG.base-usage.patch [bz#879234]
+- kvm-block-qemu-iotests-add-quotes-to-TEST_IMG-usage-in-0.patch [bz#879234]
+- kvm-block-qemu-iotests-removes-duplicate-double-quotes-i.patch [bz#879234]
+- kvm-block-vhdx-minor-comments-and-typo-correction.patch [bz#879234]
+- kvm-block-vhdx-add-header-update-capability.patch [bz#879234]
+- kvm-block-vhdx-code-movement-VHDXMetadataEntries-and-BDR.patch [bz#879234]
+- kvm-block-vhdx-log-support-struct-and-defines.patch [bz#879234]
+- kvm-block-vhdx-break-endian-translation-functions-out.patch [bz#879234]
+- kvm-block-vhdx-update-log-guid-in-header-and-first-write.patch [bz#879234]
+- kvm-block-vhdx-code-movement-move-vhdx_close-above-vhdx_.patch [bz#879234]
+- kvm-block-vhdx-log-parsing-replay-and-flush-support.patch [bz#879234]
+- kvm-block-vhdx-add-region-overlap-detection-for-image-fi.patch [bz#879234]
+- kvm-block-vhdx-add-log-write-support.patch [bz#879234]
+- kvm-block-vhdx-write-support.patch [bz#879234]
+- kvm-block-vhdx-remove-BAT-file-offset-bit-shifting.patch [bz#879234]
+- kvm-block-vhdx-move-more-endian-translations-to-vhdx-end.patch [bz#879234]
+- kvm-block-vhdx-break-out-code-operations-to-functions.patch [bz#879234]
+- kvm-block-vhdx-fix-comment-typos-in-header-fix-incorrect.patch [bz#879234]
+- kvm-block-vhdx-add-.bdrv_create-support.patch [bz#879234]
+- kvm-block-vhdx-update-_make_test_img-to-filter-out-vhdx-.patch [bz#879234]
+- kvm-block-qemu-iotests-for-vhdx-add-write-test-support.patch [bz#879234]
+- kvm-block-vhdx-qemu-iotest-log-replay-of-data-sector.patch [bz#879234]
+- Resolves: bz#879234
+  ([RFE] qemu-img: Add/improve support for VHDX format)
+
+* Mon Jan 06 2014 Michal Novotny <minovotn@redhat.com> - 1.5.3-32.el7
+- kvm-block-change-default-of-.has_zero_init-to-0.patch.patch [bz#1007815]
+- kvm-iscsi-factor-out-sector-conversions.patch.patch [bz#1007815]
+- kvm-iscsi-add-logical-block-provisioning-information-to-.patch.patch [bz#1007815]
+- kvm-iscsi-add-.bdrv_get_block_status.patch.patch.patch [bz#1007815]
+- kvm-iscsi-split-discard-requests-in-multiple-parts.patch.patch.patch [bz#1007815]
+- kvm-block-make-BdrvRequestFlags-public.patch.patch.patch [bz#1007815]
+- kvm-block-add-flags-to-bdrv_-_write_zeroes.patch.patch.patch [bz#1007815]
+- kvm-block-introduce-BDRV_REQ_MAY_UNMAP-request-flag.patch.patch.patch [bz#1007815]
+- kvm-block-add-logical-block-provisioning-info-to-BlockDr.patch.patch.patch [bz#1007815]
+- kvm-block-add-wrappers-for-logical-block-provisioning-in.patch.patch.patch [bz#1007815]
+- kvm-block-iscsi-add-.bdrv_get_info.patch.patch [bz#1007815]
+- kvm-block-add-BlockLimits-structure-to-BlockDriverState.patch.patch.patch [bz#1007815]
+- kvm-block-raw-copy-BlockLimits-on-raw_open.patch.patch.patch [bz#1007815]
+- kvm-block-honour-BlockLimits-in-bdrv_co_do_write_zeroes.patch.patch.patch [bz#1007815]
+- kvm-block-honour-BlockLimits-in-bdrv_co_discard.patch.patch.patch [bz#1007815]
+- kvm-iscsi-set-limits-in-BlockDriverState.patch.patch.patch [bz#1007815]
+- kvm-iscsi-simplify-iscsi_co_discard.patch.patch.patch [bz#1007815]
+- kvm-iscsi-add-bdrv_co_write_zeroes.patch.patch.patch [bz#1007815]
+- kvm-block-introduce-bdrv_make_zero.patch.patch.patch [bz#1007815]
+- kvm-block-get_block_status-fix-BDRV_BLOCK_ZERO-for-unall.patch.patch.patch [bz#1007815]
+- kvm-qemu-img-add-support-for-fully-allocated-images.patch.patch.patch [bz#1007815]
+- kvm-qemu-img-conditionally-zero-out-target-on-convert.patch.patch.patch [bz#1007815]
+- kvm-block-generalize-BlockLimits-handling-to-cover-bdrv_.patch.patch.patch [bz#1007815]
+- kvm-block-add-flags-to-BlockRequest.patch.patch.patch [bz#1007815]
+- kvm-block-add-flags-argument-to-bdrv_co_write_zeroes-tra.patch.patch.patch [bz#1007815]
+- kvm-block-add-bdrv_aio_write_zeroes.patch.patch.patch [bz#1007815]
+- kvm-block-handle-ENOTSUP-from-discard-in-generic-code.patch.patch.patch [bz#1007815]
+- kvm-block-make-bdrv_co_do_write_zeroes-stricter-in-produ.patch.patch.patch [bz#1007815]
+- kvm-vpc-vhdx-add-get_info.patch.patch.patch [bz#1007815]
+- kvm-block-drivers-add-discard-write_zeroes-properties-to.patch.patch.patch [bz#1007815]
+- kvm-block-drivers-expose-requirement-for-write-same-alig.patch.patch.patch [bz#1007815]
+- kvm-block-iscsi-remove-.bdrv_has_zero_init.patch.patch.patch [bz#1007815]
+- kvm-block-iscsi-updated-copyright.patch.patch.patch [bz#1007815]
+- kvm-block-iscsi-check-WRITE-SAME-support-differently-dep.patch.patch.patch [bz#1007815]
+- kvm-scsi-disk-catch-write-protection-errors-in-UNMAP.patch.patch.patch [bz#1007815]
+- kvm-scsi-disk-reject-ANCHOR-1-for-UNMAP-and-WRITE-SAME-c.patch.patch.patch [bz#1007815]
+- kvm-scsi-disk-correctly-implement-WRITE-SAME.patch.patch.patch [bz#1007815]
+- kvm-scsi-disk-fix-WRITE-SAME-with-large-non-zero-payload.patch.patch.patch [bz#1007815]
+- kvm-raw-posix-implement-write_zeroes-with-MAY_UNMAP-for-.patch.patch.patch.patch [bz#1007815]
+- kvm-raw-posix-implement-write_zeroes-with-MAY_UNMAP-for-.patch.patch.patch.patch.patch [bz#1007815]
+- kvm-raw-posix-add-support-for-write_zeroes-on-XFS-and-bl.patch.patch [bz#1007815]
+- kvm-qemu-iotests-033-is-fast.patch.patch [bz#1007815]
+- kvm-qemu-img-add-support-for-skipping-zeroes-in-input-du.patch.patch [bz#1007815]
+- kvm-qemu-img-fix-usage-instruction-for-qemu-img-convert.patch.patch [bz#1007815]
+- kvm-block-iscsi-set-bdi-cluster_size.patch.patch [bz#1007815]
+- kvm-block-add-opt_transfer_length-to-BlockLimits.patch.patch [bz#1039557]
+- kvm-block-iscsi-set-bs-bl.opt_transfer_length.patch.patch [bz#1039557]
+- kvm-qemu-img-dynamically-adjust-iobuffer-size-during-con.patch.patch [bz#1039557]
+- kvm-qemu-img-round-down-request-length-to-an-aligned-sec.patch.patch [bz#1039557]
+- kvm-qemu-img-decrease-progress-update-interval-on-conver.patch.patch [bz#1039557]
+- Resolves: bz#1007815
+  (fix WRITE SAME support)
+- Resolves: bz#1039557
+  (optimize qemu-img for thin provisioned images)
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 10:1.5.3-31
+- Mass rebuild 2013-12-27
+
+* Wed Dec 18 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-30.el7
+- kvm-Revert-HMP-Disable-drive_add-for-Red-Hat-Enterprise-2.patch.patch [bz#889051]
+- Resolves: bz#889051
+  (Commands "__com.redhat_drive_add/del" don' t exist in RHEL7.0)
+
+* Wed Dec 18 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-29.el7
+- kvm-QMP-Forward-port-__com.redhat_drive_del-from-RHEL-6.patch [bz#889051]
+- kvm-QMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch [bz#889051]
+- kvm-HMP-Forward-port-__com.redhat_drive_add-from-RHEL-6.patch [bz#889051]
+- kvm-QMP-Document-throttling-parameters-of-__com.redhat_d.patch [bz#889051]
+- kvm-HMP-Disable-drive_add-for-Red-Hat-Enterprise-Linux.patch [bz#889051]
+- Resolves: bz#889051
+  (Commands "__com.redhat_drive_add/del" don' t exist in RHEL7.0)
+
+* Wed Dec 18 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-28.el7
+- kvm-virtio_pci-fix-level-interrupts-with-irqfd.patch [bz#1035132]
+- Resolves: bz#1035132
+  (fail to boot and call trace with x-data-plane=on specified for rhel6.5 guest)
+
+* Wed Dec 18 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-27.el7
+- Change systemd service location [bz#1025217]
+- kvm-vmdk-Allow-read-only-open-of-VMDK-version-3.patch [bz#1007710 bz#1029852]
+- Resolves: bz#1007710
+  ([RFE] Enable qemu-img to support VMDK version 3)
+- Resolves: bz#1025217
+  (systemd can't control ksm.service and ksmtuned.service)
+- Resolves: bz#1029852
+  (qemu-img fails to convert vmdk image with "qemu-img: Could not open 'image.vmdk'")
+
+* Wed Dec 18 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-26.el7
+- Add BuildRequires to libRDMAcm-devel for RDMA support [bz#1011720]
+- kvm-add-a-header-file-for-atomic-operations.patch [bz#1011720]
+- kvm-savevm-Fix-potential-memory-leak.patch [bz#1011720]
+- kvm-migration-Fail-migration-on-bdrv_flush_all-error.patch [bz#1011720]
+- kvm-rdma-add-documentation.patch [bz#1011720]
+- kvm-rdma-introduce-qemu_update_position.patch [bz#1011720]
+- kvm-rdma-export-yield_until_fd_readable.patch [bz#1011720]
+- kvm-rdma-export-throughput-w-MigrationStats-QMP.patch [bz#1011720]
+- kvm-rdma-introduce-qemu_file_mode_is_not_valid.patch [bz#1011720]
+- kvm-rdma-introduce-qemu_ram_foreach_block.patch [bz#1011720]
+- kvm-rdma-new-QEMUFileOps-hooks.patch [bz#1011720]
+- kvm-rdma-introduce-capability-x-rdma-pin-all.patch [bz#1011720]
+- kvm-rdma-update-documentation-to-reflect-new-unpin-suppo.patch [bz#1011720]- kvm-rdma-bugfix-ram_control_save_page.patch [bz#1011720]
+- kvm-rdma-introduce-ram_handle_compressed.patch [bz#1011720]
+- kvm-rdma-core-logic.patch [bz#1011720]
+- kvm-rdma-send-pc.ram.patch [bz#1011720]
+- kvm-rdma-allow-state-transitions-between-other-states-be.patch [bz#1011720]
+- kvm-rdma-introduce-MIG_STATE_NONE-and-change-MIG_STATE_S.patch [bz#1011720]
+- kvm-rdma-account-for-the-time-spent-in-MIG_STATE_SETUP-t.patch [bz#1011720]
+- kvm-rdma-bugfix-make-IPv6-support-work.patch [bz#1011720]
+- kvm-rdma-forgot-to-turn-off-the-debugging-flag.patch [bz#1011720]
+- kvm-rdma-correct-newlines-in-error-statements.patch [bz#1011720]
+- kvm-rdma-don-t-use-negative-index-to-array.patch [bz#1011720]
+- kvm-rdma-qemu_rdma_post_send_control-uses-wrongly-RDMA_W.patch [bz#1011720]
+- kvm-rdma-use-DRMA_WRID_READY.patch [bz#1011720]
+- kvm-rdma-memory-leak-RDMAContext-host.patch [bz#1011720]
+- kvm-rdma-use-resp.len-after-validation-in-qemu_rdma_regi.patch [bz#1011720]
+- kvm-rdma-validate-RDMAControlHeader-len.patch [bz#1011720]
+- kvm-rdma-check-if-RDMAControlHeader-len-match-transferre.patch [bz#1011720]
+- kvm-rdma-proper-getaddrinfo-handling.patch [bz#1011720]
+- kvm-rdma-IPv6-over-Ethernet-RoCE-is-broken-in-linux-work.patch [bz#1011720]
+- kvm-rdma-remaining-documentation-fixes.patch [bz#1011720]
+- kvm-rdma-silly-ipv6-bugfix.patch [bz#1011720]
+- kvm-savevm-fix-wrong-initialization-by-ram_control_load_.patch [bz#1011720]
+- kvm-arch_init-right-return-for-ram_save_iterate.patch [bz#1011720]
+- kvm-rdma-clean-up-of-qemu_rdma_cleanup.patch [bz#1011720]
+- kvm-rdma-constify-ram_chunk_-index-start-end.patch [bz#1011720]
+- kvm-migration-Fix-debug-print-type.patch [bz#1011720]
+- kvm-arch_init-make-is_zero_page-accept-size.patch [bz#1011720]
+- kvm-migration-ram_handle_compressed.patch [bz#1011720]
+- kvm-migration-fix-spice-migration.patch [bz#1011720]
+- kvm-pci-assign-cap-number-of-devices-that-can-be-assigne.patch [bz#678368]
+- kvm-vfio-cap-number-of-devices-that-can-be-assigned.patch [bz#678368]
+- kvm-Revert-usb-tablet-Don-t-claim-wakeup-capability-for-.patch [bz#1039513]
+- kvm-mempath-prefault-pages-manually-v4.patch [bz#1026554]
+- Resolves: bz#1011720
+  ([HP 7.0 Feat]: Backport RDMA based live guest migration changes from upstream to RHEL7.0 KVM)
+- Resolves: bz#1026554
+  (qemu: mempath: prefault pages manually)
+- Resolves: bz#1039513
+  (backport remote wakeup for ehci)
+- Resolves: bz#678368
+  (RFE: Support more than 8 assigned devices)
+
+* Wed Dec 18 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-25.el7
+- kvm-Change-package-description.patch [bz#1017696]
+- kvm-seccomp-add-kill-to-the-syscall-whitelist.patch [bz#1026314]
+- kvm-json-parser-fix-handling-of-large-whole-number-value.patch [bz#997915]
+- kvm-qapi-add-QMP-input-test-for-large-integers.patch [bz#997915]
+- kvm-qapi-fix-visitor-serialization-tests-for-numbers-dou.patch [bz#997915]
+- kvm-qapi-add-native-list-coverage-for-visitor-serializat.patch [bz#997915]
+- kvm-qapi-add-native-list-coverage-for-QMP-output-visitor.patch [bz#997915]
+- kvm-qapi-add-native-list-coverage-for-QMP-input-visitor-.patch [bz#997915]
+- kvm-qapi-lack-of-two-commas-in-dict.patch [bz#997915]
+- kvm-tests-QAPI-schema-parser-tests.patch [bz#997915]
+- kvm-tests-Use-qapi-schema-test.json-as-schema-parser-tes.patch [bz#997915]
+- kvm-qapi.py-Restructure-lexer-and-parser.patch [bz#997915]
+- kvm-qapi.py-Decent-syntax-error-reporting.patch [bz#997915]
+- kvm-qapi.py-Reject-invalid-characters-in-schema-file.patch [bz#997915]
+- kvm-qapi.py-Fix-schema-parser-to-check-syntax-systematic.patch [bz#997915]
+- kvm-qapi.py-Fix-diagnosing-non-objects-at-a-schema-s-top.patch [bz#997915]
+- kvm-qapi.py-Rename-expr_eval-to-expr-in-parse_schema.patch [bz#997915]
+- kvm-qapi.py-Permit-comments-starting-anywhere-on-the-lin.patch [bz#997915]
+- kvm-scripts-qapi.py-Avoid-syntax-not-supported-by-Python.patch [bz#997915]
+- kvm-tests-Fix-schema-parser-test-for-in-tree-build.patch [bz#997915]
+- Resolves: bz#1017696
+  ([branding] remove references to dynamic translation and user-mode emulation)
+- Resolves: bz#1026314
+  (qemu-kvm hang when use '-sandbox on'+'vnc'+'hda')
+- Resolves: bz#997915
+  (Backport new QAPI parser proactively to help developers and avoid silly conflicts)
+
+* Tue Dec 17 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-24.el7
+- kvm-range-add-Range-structure.patch [bz#1034876]
+- kvm-range-add-Range-to-typedefs.patch [bz#1034876]
+- kvm-range-add-min-max-operations-on-ranges.patch [bz#1034876]
+- kvm-qdev-Add-SIZE-type-to-qdev-properties.patch [bz#1034876]
+- kvm-qapi-make-visit_type_size-fallback-to-type_int.patch [bz#1034876]
+- kvm-pc-move-IO_APIC_DEFAULT_ADDRESS-to-include-hw-i386-i.patch [bz#1034876]
+- kvm-pci-add-helper-to-retrieve-the-64-bit-range.patch [bz#1034876]
+- kvm-pci-fix-up-w64-size-calculation-helper.patch [bz#1034876]
+- kvm-refer-to-FWCfgState-explicitly.patch [bz#1034876]
+- kvm-fw_cfg-move-typedef-to-qemu-typedefs.h.patch [bz#1034876]
+- kvm-arch_init-align-MR-size-to-target-page-size.patch [bz#1034876]
+- kvm-loader-store-FW-CFG-ROM-files-in-RAM.patch [bz#1034876]
+- kvm-pci-store-PCI-hole-ranges-in-guestinfo-structure.patch [bz#1034876]
+- kvm-pc-pass-PCI-hole-ranges-to-Guests.patch [bz#1034876]
+- kvm-pc-replace-i440fx_common_init-with-i440fx_init.patch [bz#1034876]
+- kvm-pc-don-t-access-fw-cfg-if-NULL.patch [bz#1034876]
+- kvm-pc-add-I440FX-QOM-cast-macro.patch [bz#1034876]
+- kvm-pc-limit-64-bit-hole-to-2G-by-default.patch [bz#1034876]
+- kvm-q35-make-pci-window-address-size-match-guest-cfg.patch [bz#1034876]
+- kvm-q35-use-64-bit-window-programmed-by-guest.patch [bz#1034876]
+- kvm-piix-use-64-bit-window-programmed-by-guest.patch [bz#1034876]
+- kvm-pc-fix-regression-for-64-bit-PCI-memory.patch [bz#1034876]
+- kvm-cleanup-object.h-include-error.h-directly.patch [bz#1034876]
+- kvm-qom-cleanup-struct-Error-references.patch [bz#1034876]
+- kvm-qom-add-pointer-to-int-property-helpers.patch [bz#1034876]
+- kvm-fw_cfg-interface-to-trigger-callback-on-read.patch [bz#1034876]
+- kvm-loader-support-for-unmapped-ROM-blobs.patch [bz#1034876]
+- kvm-pcie_host-expose-UNMAPPED-macro.patch [bz#1034876]
+- kvm-pcie_host-expose-address-format.patch [bz#1034876]
+- kvm-q35-use-macro-for-MCFG-property-name.patch [bz#1034876]
+- kvm-q35-expose-mmcfg-size-as-a-property.patch [bz#1034876]
+- kvm-i386-add-ACPI-table-files-from-seabios.patch [bz#1034876]
+- kvm-acpi-add-rules-to-compile-ASL-source.patch [bz#1034876]
+- kvm-acpi-pre-compiled-ASL-files.patch [bz#1034876]
+- kvm-acpi-ssdt-pcihp-updat-generated-file.patch [bz#1034876]
+- kvm-loader-use-file-path-size-from-fw_cfg.h.patch [bz#1034876]
+- kvm-i386-add-bios-linker-loader.patch [bz#1034876]
+- kvm-loader-allow-adding-ROMs-in-done-callbacks.patch [bz#1034876]
+- kvm-i386-define-pc-guest-info.patch [bz#1034876]
+- kvm-acpi-piix-add-macros-for-acpi-property-names.patch [bz#1034876]
+- kvm-piix-APIs-for-pc-guest-info.patch [bz#1034876]
+- kvm-ich9-APIs-for-pc-guest-info.patch [bz#1034876]
+- kvm-pvpanic-add-API-to-access-io-port.patch [bz#1034876]
+- kvm-hpet-add-API-to-find-it.patch [bz#1034876]
+- kvm-hpet-fix-build-with-CONFIG_HPET-off.patch [bz#1034876]
+- kvm-acpi-add-interface-to-access-user-installed-tables.patch [bz#1034876]
+- kvm-pc-use-new-api-to-add-builtin-tables.patch [bz#1034876]
+- kvm-i386-ACPI-table-generation-code-from-seabios.patch [bz#1034876]
+- kvm-ssdt-fix-PBLK-length.patch [bz#1034876]
+- kvm-ssdt-proc-update-generated-file.patch [bz#1034876]
+- kvm-pc-disable-pci-info.patch [bz#1034876]
+- kvm-acpi-build-fix-build-on-glib-2.22.patch [bz#1034876]
+- kvm-acpi-build-fix-build-on-glib-2.14.patch [bz#1034876]
+- kvm-acpi-build-fix-support-for-glib-2.22.patch [bz#1034876]
+- kvm-acpi-build-Fix-compiler-warning-missing-gnu_printf-f.patch [bz#1034876]
+- kvm-exec-Fix-prototype-of-phys_mem_set_alloc-and-related.patch [bz#1034876]
+- Resolves: bz#1034876
+  (export acpi tables to guests)
+
+* Tue Dec 17 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-23.el7
+- kvm-qdev-monitor-Unref-device-when-device_add-fails.patch [bz#1003773]
+- kvm-qdev-Drop-misleading-qdev_free-function.patch [bz#1003773]
+- kvm-blockdev-fix-drive_init-opts-and-bs_opts-leaks.patch [bz#1003773]
+- kvm-libqtest-rename-qmp-to-qmp_discard_response.patch [bz#1003773]
+- kvm-libqtest-add-qmp-fmt-.-QDict-function.patch [bz#1003773]
+- kvm-blockdev-test-add-test-case-for-drive_add-duplicate-.patch [bz#1003773]
+- kvm-qdev-monitor-test-add-device_add-leak-test-cases.patch [bz#1003773]
+- kvm-qtest-Use-display-none-by-default.patch [bz#1003773]
+- Resolves: bz#1003773
+  (When virtio-blk-pci device with dataplane is failed to be added, the drive cannot be released.)
+
+* Tue Dec 17 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-22.el7
+- Fix ksmtuned with set_process_name=1 [bz#1027420]
+- Fix committed memory when no qemu-kvm running [bz#1027418]
+- kvm-virtio-net-fix-the-memory-leak-in-rxfilter_notify.patch [bz#1033810]
+- kvm-qom-Fix-memory-leak-in-object_property_set_link.patch [bz#1033810]
+- kvm-fix-intel-hda-live-migration.patch [bz#1036537]
+- kvm-vfio-pci-Release-all-MSI-X-vectors-when-disabled.patch [bz#1029743]
+- kvm-Query-KVM-for-available-memory-slots.patch [bz#921490]
+- kvm-block-Dont-ignore-previously-set-bdrv_flags.patch [bz#1039501]
+- kvm-cleanup-trace-events.pl-New.patch [bz#997832]
+- kvm-slavio_misc-Fix-slavio_led_mem_readw-_writew-tracepo.patch [bz#997832]
+- kvm-milkymist-minimac2-Fix-minimac2_read-_write-tracepoi.patch [bz#997832]
+- kvm-trace-events-Drop-unused-events.patch [bz#997832]
+- kvm-trace-events-Fix-up-source-file-comments.patch [bz#997832]
+- kvm-trace-events-Clean-up-with-scripts-cleanup-trace-eve.patch [bz#997832]
+- kvm-trace-events-Clean-up-after-removal-of-old-usb-host-.patch [bz#997832]
+- kvm-net-Update-netdev-peer-on-link-change.patch [bz#1027571]
+- Resolves: bz#1027418
+  (ksmtuned committed_memory() still returns "", not 0, when no qemu running)
+- Resolves: bz#1027420
+  (ksmtuned can’t handle libvirt WITH set_process_name=1)
+- Resolves: bz#1027571
+  ([virtio-win]win8.1 guest network can not resume automatically after do "set_link tap1 on")
+- Resolves: bz#1029743
+  (qemu-kvm core dump after hot plug/unplug 82576 PF about 100 times)
+- Resolves: bz#1033810
+  (memory leak in using object_get_canonical_path())
+- Resolves: bz#1036537
+  (Cross version migration from RHEL6.5 host to RHEL7.0 host with sound device failed.)
+- Resolves: bz#1039501
+  ([provisioning] discard=on broken)
+- Resolves: bz#921490
+  (qemu-kvm core dumped after hot plugging more than 11 VF through vfio-pci)
+- Resolves: bz#997832
+  (Backport trace fixes proactively to avoid confusion and silly conflicts)
+
+* Tue Dec 03 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-21.el7
+- kvm-scsi-Allocate-SCSITargetReq-r-buf-dynamically-CVE-20.patch [bz#1007334]
+- Resolves: bz#1007334
+  (CVE-2013-4344 qemu-kvm: qemu: buffer overflow in scsi_target_emulate_report_luns [rhel-7.0])
+
+* Thu Nov 28 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-20.el7
+- kvm-pc-drop-virtio-balloon-pci-event_idx-compat-property.patch [bz#1029539]
+- kvm-virtio-net-only-delete-bh-that-existed.patch [bz#922463]
+- kvm-virtio-net-broken-RX-filtering-logic-fixed.patch [bz#1029370]
+- kvm-block-Avoid-unecessary-drv-bdrv_getlength-calls.patch [bz#1025138]
+- kvm-block-Round-up-total_sectors.patch [bz#1025138]
+- kvm-doc-fix-hardcoded-helper-path.patch [bz#1016952]
+- kvm-introduce-RFQDN_REDHAT-RHEL-6-7-fwd.patch [bz#971933]
+- kvm-error-reason-in-BLOCK_IO_ERROR-BLOCK_JOB_ERROR-event.patch [bz#971938]
+- kvm-improve-debuggability-of-BLOCK_IO_ERROR-BLOCK_JOB_ER.patch [bz#895041]
+- kvm-vfio-pci-Fix-multifunction-on.patch [bz#1029275]
+- kvm-qcow2-Change-default-for-new-images-to-compat-1.1.patch [bz#1026739]
+- kvm-qcow2-change-default-for-new-images-to-compat-1.1-pa.patch [bz#1026739]
+- kvm-rng-egd-offset-the-point-when-repeatedly-read-from-t.patch [bz#1032862]
+- kvm-Fix-rhel-rhev-conflict-for-qemu-kvm-common.patch [bz#1033463]
+- Resolves: bz#1016952
+  (qemu-kvm man page guide wrong path for qemu-bridge-helper)
+- Resolves: bz#1025138
+  (Read/Randread/Randrw performance regression)
+- Resolves: bz#1026739
+  (qcow2: Switch to compat=1.1 default for new images)
+- Resolves: bz#1029275
+  (Guest only find one 82576 VF(function 0) while use multifunction)
+- Resolves: bz#1029370
+  ([whql][netkvm][wlk] Virtio-net device handles RX multicast filtering improperly)
+- Resolves: bz#1029539
+  (Machine type rhel6.1.0 and  balloon device cause migration fail from RHEL6.5 host to RHEL7.0 host)
+- Resolves: bz#1032862
+  (virtio-rng-egd: repeatedly read same random data-block w/o considering the buffer offset)
+- Resolves: bz#1033463
+  (can not upgrade qemu-kvm-common to qemu-kvm-common-rhev due to conflicts)
+- Resolves: bz#895041
+  (QMP: forward port I/O error debug messages)
+- Resolves: bz#922463
+  (qemu-kvm core dump when virtio-net multi queue guest hot-unpluging vNIC)
+- Resolves: bz#971933
+  (QMP: add RHEL's vendor extension prefix)
+- Resolves: bz#971938
+  (QMP: Add error reason to BLOCK_IO_ERROR event)
+
+* Mon Nov 11 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-19.el7
+- kvm-qapi-qapi-visit.py-fix-list-handling-for-union-types.patch [bz#848203]
+- kvm-qapi-qapi-visit.py-native-list-support.patch [bz#848203]
+- kvm-qapi-enable-generation-of-native-list-code.patch [bz#848203]
+- kvm-net-add-support-of-mac-programming-over-macvtap-in-Q.patch [bz#848203]
+- Resolves: bz#848203
+  (MAC Programming for virtio over macvtap - qemu-kvm support)
+
+* Fri Nov 08 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-18.el7
+- Removing leaked patch kvm-e1000-rtl8139-update-HMP-NIC-when-every-bit-is-writt.patch
+
+* Thu Nov 07 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-17.el7
+- kvm-pci-assign-Add-MSI-affinity-support.patch [bz#1025877]
+- kvm-Fix-potential-resource-leak-missing-fclose.patch [bz#1025877]
+- kvm-pci-assign-remove-the-duplicate-function-name-in-deb.patch [bz#1025877]
+- kvm-Remove-s390-ccw-img-loader.patch [bz#1017682]
+- kvm-Fix-vscclient-installation.patch [bz#1017681]
+- kvm-Change-qemu-bridge-helper-permissions-to-4755.patch [bz#1017689]
+- kvm-net-update-nic-info-during-device-reset.patch [bz#922589]
+- kvm-net-e1000-update-network-information-when-macaddr-is.patch [bz#922589]
+- kvm-net-rtl8139-update-network-information-when-macaddr-.patch [bz#922589]
+- kvm-virtio-net-fix-up-HMP-NIC-info-string-on-reset.patch [bz#1026689]
+- kvm-vfio-pci-VGA-quirk-update.patch [bz#1025477]
+- kvm-vfio-pci-Add-support-for-MSI-affinity.patch [bz#1025477]
+- kvm-vfio-pci-Test-device-reset-capabilities.patch [bz#1026550]
+- kvm-vfio-pci-Lazy-PCI-option-ROM-loading.patch [bz#1026550]
+- kvm-vfio-pci-Cleanup-error_reports.patch [bz#1026550]
+- kvm-vfio-pci-Add-dummy-PCI-ROM-write-accessor.patch [bz#1026550]
+- kvm-vfio-pci-Fix-endian-issues-in-vfio_pci_size_rom.patch [bz#1026550]
+- kvm-linux-headers-Update-to-include-vfio-pci-hot-reset-s.patch [bz#1025472]
+- kvm-vfio-pci-Implement-PCI-hot-reset.patch [bz#1025472]
+- kvm-linux-headers-Update-for-KVM-VFIO-device.patch [bz#1025474]
+- kvm-vfio-pci-Make-use-of-new-KVM-VFIO-device.patch [bz#1025474]
+- kvm-vmdk-Fix-vmdk_parse_extents.patch [bz#995866]
+- kvm-vmdk-fix-VMFS-extent-parsing.patch [bz#995866]
+- kvm-e1000-rtl8139-update-HMP-NIC-when-every-bit-is-writt.patch [bz#922589]
+- kvm-don-t-disable-ctrl_mac_addr-feature-for-6.5-machine-.patch [bz#1005039]
+- Resolves: bz#1005039
+  (add compat property to disable ctrl_mac_addr feature)
+- Resolves: bz#1017681
+  (rpmdiff test "Multilib regressions": vscclient is a libtool script on s390/s390x/ppc/ppc64)
+- Resolves: bz#1017682
+  (/usr/share/qemu-kvm/s390-ccw.img need not be distributed)
+- Resolves: bz#1017689
+  (/usr/libexec/qemu-bridge-helper permissions should be 4755)
+- Resolves: bz#1025472
+  (Nvidia GPU device assignment - qemu-kvm - bus reset support)
+- Resolves: bz#1025474
+  (Nvidia GPU device assignment - qemu-kvm - NoSnoop support)
+- Resolves: bz#1025477
+  (VFIO MSI affinity)
+- Resolves: bz#1025877
+  (pci-assign lacks MSI affinity support)
+- Resolves: bz#1026550
+  (QEMU VFIO update ROM loading code)
+- Resolves: bz#1026689
+  (virtio-net: macaddr is reset but network info of monitor isn't updated)
+- Resolves: bz#922589
+  (e1000/rtl8139: qemu mac address can not be changed via set the hardware address in guest)
+- Resolves: bz#995866
+  (fix vmdk support to ESX images)
+
+* Thu Nov 07 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-16.el7
+- kvm-block-drop-bs_snapshots-global-variable.patch [bz#1026524]
+- kvm-block-move-snapshot-code-in-block.c-to-block-snapsho.patch [bz#1026524]
+- kvm-block-fix-vvfat-error-path-for-enable_write_target.patch [bz#1026524]
+- kvm-block-Bugfix-format-and-snapshot-used-in-drive-optio.patch [bz#1026524]
+- kvm-iscsi-use-bdrv_new-instead-of-stack-structure.patch [bz#1026524]
+- kvm-qcow2-Add-corrupt-bit.patch [bz#1004347]
+- kvm-qcow2-Metadata-overlap-checks.patch [bz#1004347]
+- kvm-qcow2-Employ-metadata-overlap-checks.patch [bz#1004347]
+- kvm-qcow2-refcount-Move-OFLAG_COPIED-checks.patch [bz#1004347]
+- kvm-qcow2-refcount-Repair-OFLAG_COPIED-errors.patch [bz#1004347]
+- kvm-qcow2-refcount-Repair-shared-refcount-blocks.patch [bz#1004347]
+- kvm-qcow2_check-Mark-image-consistent.patch [bz#1004347]
+- kvm-qemu-iotests-Overlapping-cluster-allocations.patch [bz#1004347]
+- kvm-w32-Fix-access-to-host-devices-regression.patch [bz#1026524]
+- kvm-add-qemu-img-convert-n-option-skip-target-volume-cre.patch [bz#1026524]
+- kvm-bdrv-Use-Error-for-opening-images.patch [bz#1026524]
+- kvm-bdrv-Use-Error-for-creating-images.patch [bz#1026524]
+- kvm-block-Error-parameter-for-open-functions.patch [bz#1026524]
+- kvm-block-Error-parameter-for-create-functions.patch [bz#1026524]
+- kvm-qemu-img-create-Emit-filename-on-error.patch [bz#1026524]
+- kvm-qcow2-Use-Error-parameter.patch [bz#1026524]
+- kvm-qemu-iotests-Adjustments-due-to-error-propagation.patch [bz#1026524]
+- kvm-block-raw-Employ-error-parameter.patch [bz#1026524]
+- kvm-block-raw-win32-Employ-error-parameter.patch [bz#1026524]
+- kvm-blkdebug-Employ-error-parameter.patch [bz#1026524]
+- kvm-blkverify-Employ-error-parameter.patch [bz#1026524]
+- kvm-block-raw-posix-Employ-error-parameter.patch [bz#1026524]
+- kvm-block-raw-win32-Always-use-errno-in-hdev_open.patch [bz#1026524]
+- kvm-qmp-Documentation-for-BLOCK_IMAGE_CORRUPTED.patch [bz#1004347]
+- kvm-qcow2-Correct-snapshots-size-for-overlap-check.patch [bz#1004347]
+- kvm-qcow2-CHECK_OFLAG_COPIED-is-obsolete.patch [bz#1004347]
+- kvm-qcow2-Correct-endianness-in-overlap-check.patch [bz#1004347]
+- kvm-qcow2-Switch-L1-table-in-a-single-sequence.patch [bz#1004347]
+- kvm-qcow2-Use-pread-for-inactive-L1-in-overlap-check.patch [bz#1004347]
+- kvm-qcow2-Remove-wrong-metadata-overlap-check.patch [bz#1004347]
+- kvm-qcow2-Use-negated-overflow-check-mask.patch [bz#1004347]
+- kvm-qcow2-Make-overlap-check-mask-variable.patch [bz#1004347]
+- kvm-qcow2-Add-overlap-check-options.patch [bz#1004347]
+- kvm-qcow2-Array-assigning-options-to-OL-check-bits.patch [bz#1004347]
+- kvm-qcow2-Add-more-overlap-check-bitmask-macros.patch [bz#1004347]
+- kvm-qcow2-Evaluate-overlap-check-options.patch [bz#1004347]
+- kvm-qapi-types.py-Split-off-generate_struct_fields.patch [bz#978402]
+- kvm-qapi-types.py-Fix-enum-struct-sizes-on-i686.patch [bz#978402]
+- kvm-qapi-types-visit.py-Pass-whole-expr-dict-for-structs.patch [bz#978402]
+- kvm-qapi-types-visit.py-Inheritance-for-structs.patch [bz#978402]
+- kvm-blockdev-Introduce-DriveInfo.enable_auto_del.patch [bz#978402]
+- kvm-Implement-qdict_flatten.patch [bz#978402]
+- kvm-blockdev-blockdev-add-QMP-command.patch [bz#978402]
+- kvm-blockdev-Separate-ID-generation-from-DriveInfo-creat.patch [bz#978402]
+- kvm-blockdev-Pass-QDict-to-blockdev_init.patch [bz#978402]
+- kvm-blockdev-Move-parsing-of-media-option-to-drive_init.patch [bz#978402]
+- kvm-blockdev-Move-parsing-of-if-option-to-drive_init.patch [bz#978402]
+- kvm-blockdev-Moving-parsing-of-geometry-options-to-drive.patch [bz#978402]
+- kvm-blockdev-Move-parsing-of-boot-option-to-drive_init.patch [bz#978402]
+- kvm-blockdev-Move-bus-unit-index-processing-to-drive_ini.patch [bz#978402]
+- kvm-blockdev-Move-virtio-blk-device-creation-to-drive_in.patch [bz#978402]
+- kvm-blockdev-Remove-IF_-check-for-read-only-blockdev_ini.patch [bz#978402]
+- kvm-qemu-iotests-Check-autodel-behaviour-for-device_del.patch [bz#978402]
+- kvm-blockdev-Remove-media-parameter-from-blockdev_init.patch [bz#978402]
+- kvm-blockdev-Don-t-disable-COR-automatically-with-blockd.patch [bz#978402]
+- kvm-blockdev-blockdev_init-error-conversion.patch [bz#978402]
+- kvm-sd-Avoid-access-to-NULL-BlockDriverState.patch [bz#978402]
+- kvm-blockdev-fix-cdrom-read_only-flag.patch [bz#978402]
+- kvm-block-fix-backing-file-overriding.patch [bz#978402]
+- kvm-block-Disable-BDRV_O_COPY_ON_READ-for-the-backing-fi.patch [bz#978402]
+- kvm-block-Don-t-copy-backing-file-name-on-error.patch [bz#978402]
+- kvm-qemu-iotests-Try-creating-huge-qcow2-image.patch [bz#980771]
+- kvm-block-move-qmp-and-info-dump-related-code-to-block-q.patch [bz#980771]
+- kvm-block-dump-snapshot-and-image-info-to-specified-outp.patch [bz#980771]
+- kvm-block-add-snapshot-info-query-function-bdrv_query_sn.patch [bz#980771]
+- kvm-block-add-image-info-query-function-bdrv_query_image.patch [bz#980771]
+- kvm-qmp-add-ImageInfo-in-BlockDeviceInfo-used-by-query-b.patch [bz#980771]
+- kvm-vmdk-Implement-.bdrv_has_zero_init.patch [bz#980771]
+- kvm-qemu-iotests-Add-basic-ability-to-use-binary-sample-.patch [bz#980771]
+- kvm-qemu-iotests-Quote-TEST_IMG-and-TEST_DIR-usage.patch [bz#980771]
+- kvm-qemu-iotests-fix-test-case-059.patch [bz#980771]
+- kvm-qapi-Add-ImageInfoSpecific-type.patch [bz#980771]
+- kvm-block-Add-bdrv_get_specific_info.patch [bz#980771]
+- kvm-block-qapi-Human-readable-ImageInfoSpecific-dump.patch [bz#980771]
+- kvm-qcow2-Add-support-for-ImageInfoSpecific.patch [bz#980771]
+- kvm-qemu-iotests-Discard-specific-info-in-_img_info.patch [bz#980771]
+- kvm-qemu-iotests-Additional-info-from-qemu-img-info.patch [bz#980771]
+- kvm-vmdk-convert-error-code-to-use-errp.patch [bz#980771]
+- kvm-vmdk-refuse-enabling-zeroed-grain-with-flat-images.patch [bz#980771]
+- kvm-qapi-Add-optional-field-compressed-to-ImageInfo.patch [bz#980771]
+- kvm-vmdk-Only-read-cid-from-image-file-when-opening.patch [bz#980771]
+- kvm-vmdk-Implment-bdrv_get_specific_info.patch [bz#980771]
+- Resolves: bz#1004347
+  (Backport qcow2 corruption prevention patches)
+- Resolves: bz#1026524
+  (Backport block layer error parameter patches)
+- Resolves: bz#978402
+  ([RFE] Add discard support to qemu-kvm layer)
+- Resolves: bz#980771
+  ([RFE]  qemu-img should be able to tell the compat version of a qcow2 image)
+
+* Thu Nov 07 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-15.el7
+- kvm-cow-make-reads-go-at-a-decent-speed.patch [bz#989646]
+- kvm-cow-make-writes-go-at-a-less-indecent-speed.patch [bz#989646]
+- kvm-cow-do-not-call-bdrv_co_is_allocated.patch [bz#989646]
+- kvm-block-keep-bs-total_sectors-up-to-date-even-for-grow.patch [bz#989646]
+- kvm-block-make-bdrv_co_is_allocated-static.patch [bz#989646]
+- kvm-block-do-not-use-total_sectors-in-bdrv_co_is_allocat.patch [bz#989646]
+- kvm-block-remove-bdrv_is_allocated_above-bdrv_co_is_allo.patch [bz#989646]
+- kvm-block-expect-errors-from-bdrv_co_is_allocated.patch [bz#989646]
+- kvm-block-Fix-compiler-warning-Werror-uninitialized.patch [bz#989646]
+- kvm-qemu-img-always-probe-the-input-image-for-allocated-.patch [bz#989646]
+- kvm-block-make-bdrv_has_zero_init-return-false-for-copy-.patch [bz#989646]
+- kvm-block-introduce-bdrv_get_block_status-API.patch [bz#989646]
+- kvm-block-define-get_block_status-return-value.patch [bz#989646]
+- kvm-block-return-get_block_status-data-and-flags-for-for.patch [bz#989646]
+- kvm-block-use-bdrv_has_zero_init-to-return-BDRV_BLOCK_ZE.patch [bz#989646]
+- kvm-block-return-BDRV_BLOCK_ZERO-past-end-of-backing-fil.patch [bz#989646]
+- kvm-qemu-img-add-a-map-subcommand.patch [bz#989646]
+- kvm-docs-qapi-document-qemu-img-map.patch [bz#989646]
+- kvm-raw-posix-return-get_block_status-data-and-flags.patch [bz#989646]
+- kvm-raw-posix-report-unwritten-extents-as-zero.patch [bz#989646]
+- kvm-block-add-default-get_block_status-implementation-fo.patch [bz#989646]
+- kvm-block-look-for-zero-blocks-in-bs-file.patch [bz#989646]
+- kvm-qemu-img-fix-invalid-JSON.patch [bz#989646]
+- kvm-block-get_block_status-set-pnum-0-on-error.patch [bz#989646]
+- kvm-block-get_block_status-avoid-segfault-if-there-is-no.patch [bz#989646]
+- kvm-block-get_block_status-avoid-redundant-callouts-on-r.patch [bz#989646]
+- kvm-qcow2-Restore-total_sectors-value-in-save_vmstate.patch [bz#1025740]
+- kvm-qcow2-Unset-zero_beyond_eof-in-save_vmstate.patch [bz#1025740]
+- kvm-qemu-iotests-Test-for-loading-VM-state-from-qcow2.patch [bz#1025740]
+- kvm-apic-rename-apic-specific-bitopts.patch [bz#1001216]
+- kvm-hw-import-bitmap-operations-in-qdev-core-header.patch [bz#1001216]
+- kvm-qemu-help-Sort-devices-by-logical-functionality.patch [bz#1001216]
+- kvm-devices-Associate-devices-to-their-logical-category.patch [bz#1001216]
+- kvm-Mostly-revert-qemu-help-Sort-devices-by-logical-func.patch [bz#1001216]
+- kvm-qdev-monitor-Group-device_add-help-and-info-qdm-by-c.patch [bz#1001216]
+- kvm-qdev-Replace-no_user-by-cannot_instantiate_with_devi.patch [bz#1001216]
+- kvm-sysbus-Set-cannot_instantiate_with_device_add_yet.patch [bz#1001216]
+- kvm-cpu-Document-why-cannot_instantiate_with_device_add_.patch [bz#1001216]
+- kvm-apic-Document-why-cannot_instantiate_with_device_add.patch [bz#1001216]
+- kvm-pci-host-Consistently-set-cannot_instantiate_with_de.patch [bz#1001216]
+- kvm-ich9-Document-why-cannot_instantiate_with_device_add.patch [bz#1001216]
+- kvm-piix3-piix4-Clean-up-use-of-cannot_instantiate_with_.patch [bz#1001216]
+- kvm-vt82c686-Clean-up-use-of-cannot_instantiate_with_dev.patch [bz#1001216]
+- kvm-isa-Clean-up-use-of-cannot_instantiate_with_device_a.patch [bz#1001216]
+- kvm-qdev-Do-not-let-the-user-try-to-device_add-when-it-c.patch [bz#1001216]
+- kvm-rhel-Revert-unwanted-cannot_instantiate_with_device_.patch [bz#1001216]
+- kvm-rhel-Revert-downstream-changes-to-unused-default-con.patch [bz#1001076]
+- kvm-rhel-Drop-cfi.pflash01-and-isa-ide-device.patch [bz#1001076]
+- kvm-rhel-Drop-isa-vga-device.patch [bz#1001088]
+- kvm-rhel-Make-isa-cirrus-vga-device-unavailable.patch [bz#1001088]
+- kvm-rhel-Make-ccid-card-emulated-device-unavailable.patch [bz#1001123]
+- kvm-x86-fix-migration-from-pre-version-12.patch [bz#1005695]
+- kvm-x86-cpuid-reconstruct-leaf-0Dh-data.patch [bz#1005695]
+- kvm-kvmvapic-Catch-invalid-ROM-size.patch [bz#920021]
+- kvm-kvmvapic-Enter-inactive-state-on-hardware-reset.patch [bz#920021]
+- kvm-kvmvapic-Clear-also-physical-ROM-address-when-enteri.patch [bz#920021]
+- kvm-block-optionally-disable-live-block-jobs.patch [bz#987582]
+- kvm-rpm-spec-template-disable-live-block-ops-for-rhel-en.patch [bz#987582]
+- kvm-migration-disable-live-block-migration-b-i-for-rhel-.patch [bz#1022392]
+- kvm-Build-ceph-rbd-only-for-rhev.patch [bz#987583]
+- kvm-spec-Disable-host-cdrom-RHEL-only.patch [bz#760885]
+- kvm-rhel-Make-pci-serial-2x-and-pci-serial-4x-device-una.patch [bz#1001180]
+- kvm-usb-host-libusb-Fix-reset-handling.patch [bz#980415]
+- kvm-usb-host-libusb-Configuration-0-may-be-a-valid-confi.patch [bz#980383]
+- kvm-usb-host-libusb-Detach-kernel-drivers-earlier.patch [bz#980383]
+- kvm-monitor-Remove-pci_add-command-for-Red-Hat-Enterpris.patch [bz#1010858]
+- kvm-monitor-Remove-pci_del-command-for-Red-Hat-Enterpris.patch [bz#1010858]
+- kvm-monitor-Remove-usb_add-del-commands-for-Red-Hat-Ente.patch [bz#1010858]
+- kvm-monitor-Remove-host_net_add-remove-for-Red-Hat-Enter.patch [bz#1010858]
+- kvm-fw_cfg-add-API-to-find-FW-cfg-object.patch [bz#990601]
+- kvm-pvpanic-use-FWCfgState-explicitly.patch [bz#990601]
+- kvm-pvpanic-initialization-cleanup.patch [bz#990601]
+- kvm-pvpanic-fix-fwcfg-for-big-endian-hosts.patch [bz#990601]
+- kvm-hw-misc-make-pvpanic-known-to-user.patch [bz#990601]
+- kvm-gdbstub-do-not-restart-crashed-guest.patch [bz#990601]
+- kvm-gdbstub-fix-for-commit-87f25c12bfeaaa0c41fb857713bbc.patch [bz#990601]
+- kvm-vl-allow-cont-from-panicked-state.patch [bz#990601]
+- kvm-hw-misc-don-t-create-pvpanic-device-by-default.patch [bz#990601]
+- kvm-block-vhdx-add-migration-blocker.patch [bz#1007176]
+- kvm-qemu-kvm.spec-add-vhdx-to-the-read-only-block-driver.patch [bz#1007176]
+- kvm-qemu-kvm.spec-Add-VPC-VHD-driver-to-the-block-read-o.patch [bz#1007176]
+- Resolves: bz#1001076
+  (Disable or remove other block devices we won't support)
+- Resolves: bz#1001088
+  (Disable or remove display devices we won't support)
+- Resolves: bz#1001123
+  (Disable or remove device ccid-card-emulated)
+- Resolves: bz#1001180
+  (Disable or remove devices pci-serial-2x, pci-serial-4x)
+- Resolves: bz#1001216
+  (Fix no_user or provide another way make devices unavailable with -device / device_add)
+- Resolves: bz#1005695
+  (QEMU should hide CPUID.0Dh values that it does not support)
+- Resolves: bz#1007176
+  (Add VPC and VHDX file formats as supported in qemu-kvm (read-only))
+- Resolves: bz#1010858
+  (Disable unused human monitor commands)
+- Resolves: bz#1022392
+  (Disable live-storage-migration in qemu-kvm (migrate -b/-i))
+- Resolves: bz#1025740
+  (Saving VM state on qcow2 images results in VM state corruption)
+- Resolves: bz#760885
+  (Disable host cdrom passthrough)
+- Resolves: bz#920021
+  (qemu-kvm segment fault when reboot guest after hot unplug device with option ROM)
+- Resolves: bz#980383
+  (The usb3.0 stick can't be returned back to host after shutdown guest with usb3.0 pass-through)
+- Resolves: bz#980415
+  (libusbx: error [_open_sysfs_attr] open /sys/bus/usb/devices/4-1/bConfigurationValue failed ret=-1 errno=2)
+- Resolves: bz#987582
+  (Initial Virtualization Differentiation for RHEL7 (Live snapshots))
+- Resolves: bz#987583
+  (Initial Virtualization Differentiation for RHEL7 (Ceph enablement))
+- Resolves: bz#989646
+  (Support backup vendors in qemu to access qcow disk readonly)
+- Resolves: bz#990601
+  (pvpanic device triggers guest bugs when present by default)
+
+* Wed Nov 06 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-14.el7
+- kvm-target-i386-remove-tabs-from-target-i386-cpu.h.patch [bz#928867]
+- kvm-migrate-vPMU-state.patch [bz#928867]
+- kvm-blockdev-do-not-default-cache.no-flush-to-true.patch [bz#1009993]
+- kvm-virtio-blk-do-not-relay-a-previous-driver-s-WCE-conf.patch [bz#1009993]
+- kvm-rng-random-use-error_setg_file_open.patch [bz#907743]
+- kvm-block-mirror_complete-use-error_setg_file_open.patch [bz#907743]
+- kvm-blockdev-use-error_setg_file_open.patch [bz#907743]
+- kvm-cpus-use-error_setg_file_open.patch [bz#907743]
+- kvm-dump-qmp_dump_guest_memory-use-error_setg_file_open.patch [bz#907743]
+- kvm-savevm-qmp_xen_save_devices_state-use-error_setg_fil.patch [bz#907743]
+- kvm-block-bdrv_reopen_prepare-don-t-use-QERR_OPEN_FILE_F.patch [bz#907743]
+- kvm-qerror-drop-QERR_OPEN_FILE_FAILED-macro.patch [bz#907743]
+- kvm-rhel-Drop-ivshmem-device.patch [bz#787463]
+- kvm-usb-remove-old-usb-host-code.patch [bz#1001144]
+- kvm-Add-rhel6-pxe-roms-files.patch [bz#997702]
+- kvm-Add-rhel6-pxe-rom-to-redhat-rpm.patch [bz#997702]
+- kvm-Fix-migration-from-rhel6.5-to-rhel7-with-ipxe.patch [bz#997702]
+- kvm-pc-Don-t-prematurely-explode-QEMUMachineInitArgs.patch [bz#994490]
+- kvm-pc-Don-t-explode-QEMUMachineInitArgs-into-local-vari.patch [bz#994490]
+- kvm-smbios-Normalize-smbios_entry_add-s-error-handling-t.patch [bz#994490]
+- kvm-smbios-Convert-to-QemuOpts.patch [bz#994490]
+- kvm-smbios-Improve-diagnostics-for-conflicting-entries.patch [bz#994490]
+- kvm-smbios-Make-multiple-smbios-type-accumulate-sanely.patch [bz#994490]
+- kvm-smbios-Factor-out-smbios_maybe_add_str.patch [bz#994490]
+- kvm-hw-Pass-QEMUMachine-to-its-init-method.patch [bz#994490]
+- kvm-smbios-Set-system-manufacturer-product-version-by-de.patch [bz#994490]
+- kvm-smbios-Decouple-system-product-from-QEMUMachine.patch [bz#994490]
+- kvm-rhel-SMBIOS-type-1-branding.patch [bz#994490]
+- kvm-Add-disable-rhev-features-option-to-configure.patch []
+- Resolves: bz#1001144
+  (Disable or remove device usb-host-linux)
+- Resolves: bz#1009993
+  (RHEL7 guests do not issue fdatasyncs on virtio-blk)
+- Resolves: bz#787463
+  (disable ivshmem (was: [Hitachi 7.0 FEAT] Support ivshmem (Inter-VM Shared Memory)))
+- Resolves: bz#907743
+  (qemu-ga: empty reason string for OpenFileFailed error)
+- Resolves: bz#928867
+  (Virtual PMU support during live migration - qemu-kvm)
+- Resolves: bz#994490
+  (Set per-machine-type SMBIOS strings)
+- Resolves: bz#997702
+  (Migration from RHEL6.5 host to RHEL7.0 host is failed with virtio-net device)
+
+* Tue Nov 05 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-13.el7
+- kvm-seabios-paravirt-allow-more-than-1TB-in-x86-guest.patch [bz#989677]
+- kvm-scsi-prefer-UUID-to-VM-name-for-the-initiator-name.patch [bz#1006468]
+- kvm-Fix-incorrect-rhel_rhev_conflicts-macro-usage.patch [bz#1017693]
+- Resolves: bz#1006468
+  (libiscsi initiator name should use vm UUID)
+- Resolves: bz#1017693
+  (incorrect use of rhel_rhev_conflicts)
+- Resolves: bz#989677
+  ([HP 7.0 FEAT]: Increase KVM guest supported memory to 4TiB)
+
+* Mon Nov 04 2013 Michal Novotny <minovotn@redhat.com> - 1.5.3-12.el7
+- kvm-vl-Clean-up-parsing-of-boot-option-argument.patch [bz#997817]
+- kvm-qemu-option-check_params-is-now-unused-drop-it.patch [bz#997817]
+- kvm-vl-Fix-boot-order-and-once-regressions-and-related-b.patch [bz#997817]
+- kvm-vl-Rename-boot_devices-to-boot_order-for-consistency.patch [bz#997817]
+- kvm-pc-Make-no-fd-bootchk-stick-across-boot-order-change.patch [bz#997817]
+- kvm-doc-Drop-ref-to-Bochs-from-no-fd-bootchk-documentati.patch [bz#997817]
+- kvm-libqtest-Plug-fd-and-memory-leaks-in-qtest_quit.patch [bz#997817]
+- kvm-libqtest-New-qtest_end-to-go-with-qtest_start.patch [bz#997817]
+- kvm-qtest-Don-t-reset-on-qtest-chardev-connect.patch [bz#997817]
+- kvm-boot-order-test-New-covering-just-PC-for-now.patch [bz#997817]
+- kvm-qemu-ga-execute-fsfreeze-freeze-in-reverse-order-of-.patch [bz#1019352]
+- kvm-rbd-link-and-load-librbd-dynamically.patch [bz#989608]
+- kvm-rbd-Only-look-for-qemu-specific-copy-of-librbd.so.1.patch [bz#989608]
+- kvm-spec-Whitelist-rbd-block-driver.patch [bz#989608]
+- Resolves: bz#1019352
+  (qemu-guest-agent: "guest-fsfreeze-freeze" deadlocks if the guest have mounted disk images)
+- Resolves: bz#989608
+  ([7.0 FEAT] qemu runtime support for librbd backend (ceph))
+- Resolves: bz#997817
+  (-boot order and -boot once regressed since RHEL-6)
+
+* Thu Oct 31 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-11.el7
+- kvm-chardev-fix-pty_chr_timer.patch [bz#994414]
+- kvm-qemu-socket-zero-initialize-SocketAddress.patch [bz#922010]
+- kvm-qemu-socket-drop-pointless-allocation.patch [bz#922010]
+- kvm-qemu-socket-catch-monitor_get_fd-failures.patch [bz#922010]
+- kvm-qemu-char-check-optional-fields-using-has_.patch [bz#922010]
+- kvm-error-add-error_setg_file_open-helper.patch [bz#922010]
+- kvm-qemu-char-use-more-specific-error_setg_-variants.patch [bz#922010]
+- kvm-qemu-char-print-notification-to-stderr.patch [bz#922010]
+- kvm-qemu-char-fix-documentation-for-telnet-wait-socket-f.patch [bz#922010]
+- kvm-qemu-char-don-t-leak-opts-on-error.patch [bz#922010]
+- kvm-qemu-char-use-ChardevBackendKind-in-CharDriver.patch [bz#922010]
+- kvm-qemu-char-minor-mux-chardev-fixes.patch [bz#922010]
+- kvm-qemu-char-add-chardev-mux-support.patch [bz#922010]
+- kvm-qemu-char-report-udp-backend-errors.patch [bz#922010]
+- kvm-qemu-socket-don-t-leak-opts-on-error.patch [bz#922010]
+- kvm-chardev-handle-qmp_chardev_add-KIND_MUX-failure.patch [bz#922010]
+- kvm-acpi-piix4-Enable-qemu-kvm-compatibility-mode.patch [bz#1019474]
+- kvm-target-i386-support-loading-of-cpu-xsave-subsection.patch [bz#1004743]
+- Resolves: bz#1004743
+  (XSAVE migration format not compatible between RHEL6 and RHEL7)
+- Resolves: bz#1019474
+  (RHEL-7 can't load piix4_pm migration section from RHEL-6.5)
+- Resolves: bz#922010
+  (RFE: support hotplugging chardev & serial ports)
+- Resolves: bz#994414
+  (hot-unplug chardev with pty backend caused qemu Segmentation fault)
+
+* Thu Oct 17 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-10.el7
+- kvm-xhci-fix-endpoint-interval-calculation.patch [bz#1001604]
+- kvm-xhci-emulate-intr-endpoint-intervals-correctly.patch [bz#1001604]
+- kvm-xhci-reset-port-when-disabling-slot.patch [bz#1001604]
+- kvm-Revert-usb-hub-report-status-changes-only-once.patch [bz#1001604]
+- kvm-target-i386-Set-model-6-on-qemu64-qemu32-CPU-models.patch [bz#1004290]
+- kvm-pc-rhel6-doesn-t-have-APIC-on-pentium-CPU-models.patch [bz#918907]
+- kvm-pc-RHEL-6-had-x2apic-set-on-Opteron_G-123.patch [bz#918907]
+- kvm-pc-RHEL-6-don-t-have-RDTSCP.patch [bz#918907]
+- kvm-scsi-Fix-scsi_bus_legacy_add_drive-scsi-generic-with.patch [bz#1009285]
+- kvm-seccomp-fine-tuning-whitelist-by-adding-times.patch [bz#1004175]
+- kvm-block-add-bdrv_write_zeroes.patch [bz#921465]
+- kvm-block-raw-add-bdrv_co_write_zeroes.patch [bz#921465]
+- kvm-rdma-export-qemu_fflush.patch [bz#921465]
+- kvm-block-migration-efficiently-encode-zero-blocks.patch [bz#921465]
+- kvm-Fix-real-mode-guest-migration.patch [bz#921465]
+- kvm-Fix-real-mode-guest-segments-dpl-value-in-savevm.patch [bz#921465]
+- kvm-migration-add-autoconvergence-documentation.patch [bz#921465]
+- kvm-migration-send-total-time-in-QMP-at-completed-stage.patch [bz#921465]
+- kvm-migration-don-t-use-uninitialized-variables.patch [bz#921465]
+- kvm-pc-drop-external-DSDT-loading.patch [bz#921465]
+- kvm-hda-codec-refactor-common-definitions-into-a-header-.patch [bz#954195]
+- kvm-hda-codec-make-mixemu-selectable-at-runtime.patch [bz#954195]
+- kvm-audio-remove-CONFIG_MIXEMU-configure-option.patch [bz#954195]
+- kvm-pc_piix-disable-mixer-for-6.4.0-machine-types-and-be.patch [bz#954195]
+- kvm-spec-mixemu-config-option-is-no-longer-supported-and.patch [bz#954195]
+- Resolves: bz#1001604
+  (usb hub doesn't work properly (win7 sees downstream port #1 only).)
+- Resolves: bz#1004175
+  ('-sandbox on'  option  cause  qemu-kvm process hang)
+- Resolves: bz#1004290
+  (Use model 6 for qemu64 and intel cpus)
+- Resolves: bz#1009285
+  (-device usb-storage,serial=... crashes with SCSI generic drive)
+- Resolves: bz#918907
+  (provide backwards-compatible RHEL specific machine types in QEMU - CPU features)
+- Resolves: bz#921465
+  (Migration can not finished even the "remaining ram" is already 0 kb)
+- Resolves: bz#954195
+  (RHEL machines <=6.4 should not use mixemu)
+
+* Thu Oct 10 2013 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-9.el7
+- kvm-qxl-fix-local-renderer.patch [bz#1005036]
+- kvm-spec-include-userspace-iSCSI-initiator-in-block-driv.patch [bz#923843]
+- kvm-linux-headers-update-to-kernel-3.10.0-26.el7.patch [bz#1008987]
+- kvm-target-i386-add-feature-kvm_pv_unhalt.patch [bz#1008987]
+- kvm-warn-if-num-cpus-is-greater-than-num-recommended.patch [bz#1010881]
+- kvm-char-move-backends-io-watch-tag-to-CharDriverState.patch [bz#1007222]
+- kvm-char-use-common-function-to-disable-callbacks-on-cha.patch [bz#1007222]
+- kvm-char-remove-watch-callback-on-chardev-detach-from-fr.patch [bz#1007222]
+- kvm-block-don-t-lose-data-from-last-incomplete-sector.patch [bz#1017049]
+- kvm-vmdk-fix-cluster-size-check-for-flat-extents.patch [bz#1017049]
+- kvm-qemu-iotests-add-monolithicFlat-creation-test-to-059.patch [bz#1017049]
+- Resolves: bz#1005036
+  (When using “-vga qxl” together with “-display vnc=:5” or “-display  sdl” qemu displays  pixel garbage)
+- Resolves: bz#1007222
+  (QEMU core dumped when do hot-unplug virtio serial port during transfer file between host to guest with virtio serial through TCP socket)
+- Resolves: bz#1008987
+  (pvticketlocks: add kvm feature kvm_pv_unhalt)
+- Resolves: bz#1010881
+  (backport vcpu soft limit warning)
+- Resolves: bz#1017049
+  (qemu-img refuses to open the vmdk format image its created)
+- Resolves: bz#923843
+  (include userspace iSCSI initiator in block driver whitelist)
+
+* Wed Oct 09 2013 Miroslav Rezanina <mrezanin@redhat.com> - qemu-kvm-1.5.3-8.el7
+- kvm-vmdk-Make-VMDK3Header-and-VmdkGrainMarker-QEMU_PACKE.patch [bz#995866]
+- kvm-vmdk-use-unsigned-values-for-on-disk-header-fields.patch [bz#995866]
+- kvm-qemu-iotests-add-poke_file-utility-function.patch [bz#995866]
+- kvm-qemu-iotests-add-empty-test-case-for-vmdk.patch [bz#995866]
+- kvm-vmdk-check-granularity-field-in-opening.patch [bz#995866]
+- kvm-vmdk-check-l2-table-size-when-opening.patch [bz#995866]
+- kvm-vmdk-check-l1-size-before-opening-image.patch [bz#995866]
+- kvm-vmdk-use-heap-allocation-for-whole_grain.patch [bz#995866]
+- kvm-vmdk-rename-num_gtes_per_gte-to-num_gtes_per_gt.patch [bz#995866]
+- kvm-vmdk-Move-l1_size-check-into-vmdk_add_extent.patch [bz#995866]
+- kvm-vmdk-fix-L1-and-L2-table-size-in-vmdk3-open.patch [bz#995866]
+- kvm-vmdk-support-vmfsSparse-files.patch [bz#995866]
+- kvm-vmdk-support-vmfs-files.patch [bz#995866]
+- Resolves: bz#995866
+  (fix vmdk support to ESX images)
+
+* Thu Sep 26 2013 Miroslav Rezanina <mrezanin@redhat.com> - qemu-kvm-1.5.3-7.el7
+- kvm-spice-fix-display-initialization.patch [bz#974887]
+- kvm-Remove-i82550-network-card-emulation.patch [bz#921983]
+- kvm-Remove-usb-wacom-tablet.patch [bz#903914]
+- kvm-Disable-usb-uas.patch [bz#903914]
+- kvm-Disable-vhost-scsi.patch [bz#994642]
+- kvm-Remove-no-hpet-option.patch [bz#947441]
+- kvm-Disable-isa-parallel.patch [bz#1002286]
+- kvm-xhci-implement-warm-port-reset.patch [bz#949514]
+- kvm-usb-add-serial-bus-property.patch [bz#953304]
+- kvm-rhel6-compat-usb-serial-numbers.patch [bz#953304]
+- kvm-vmdk-fix-comment-for-vmdk_co_write_zeroes.patch [bz#995866]
+- kvm-gluster-Add-image-resize-support.patch [bz#1007226]
+- kvm-block-Introduce-bs-zero_beyond_eof.patch [bz#1007226]
+- kvm-block-Produce-zeros-when-protocols-reading-beyond-en.patch [bz#1007226]
+- kvm-gluster-Abort-on-AIO-completion-failure.patch [bz#1007226]
+- kvm-Preparation-for-usb-bt-dongle-conditional-build.patch [bz#1001131]
+- kvm-Remove-dev-bluetooth.c-dependency-from-vl.c.patch [bz#1001131]
+- kvm-exec-Fix-Xen-RAM-allocation-with-unusual-options.patch [bz#1009328]
+- kvm-exec-Clean-up-fall-back-when-mem-path-allocation-fai.patch [bz#1009328]
+- kvm-exec-Reduce-ifdeffery-around-mem-path.patch [bz#1009328]
+- kvm-exec-Simplify-the-guest-physical-memory-allocation-h.patch [bz#1009328]
+- kvm-exec-Drop-incorrect-dead-S390-code-in-qemu_ram_remap.patch [bz#1009328]
+- kvm-exec-Clean-up-unnecessary-S390-ifdeffery.patch [bz#1009328]
+- kvm-exec-Don-t-abort-when-we-can-t-allocate-guest-memory.patch [bz#1009328]
+- kvm-pc_sysfw-Fix-ISA-BIOS-init-for-ridiculously-big-flas.patch [bz#1009328]
+- kvm-virtio-scsi-Make-type-virtio-scsi-common-abstract.patch [bz#903918]
+- kvm-qga-move-logfiles-to-new-directory-for-easier-SELinu.patch [bz#1009491]
+- kvm-target-i386-add-cpu64-rhel6-CPU-model.patch [bz#918907]
+- kvm-fix-steal-time-MSR-vmsd-callback-to-proper-opaque-ty.patch [bz#903889]
+- Resolves: bz#1001131
+  (Disable or remove device usb-bt-dongle)
+- Resolves: bz#1002286
+  (Disable or remove device isa-parallel)
+- Resolves: bz#1007226
+  (Introduce bs->zero_beyond_eof)
+- Resolves: bz#1009328
+  ([RFE] Nicer error report when qemu-kvm can't allocate guest RAM)
+- Resolves: bz#1009491
+  (move qga logfiles to new /var/log/qemu-ga/ directory [RHEL-7])
+- Resolves: bz#903889
+  (The value of steal time in "top" command always is "0.0% st" after guest migration)
+- Resolves: bz#903914
+  (Disable or remove usb related devices that we will not support)
+- Resolves: bz#903918
+  (Disable or remove emulated SCSI devices we will not support)
+- Resolves: bz#918907
+  (provide backwards-compatible RHEL specific machine types in QEMU - CPU features)
+- Resolves: bz#921983
+  (Disable or remove emulated network devices that we will not support)
+- Resolves: bz#947441
+  (HPET device must be disabled)
+- Resolves: bz#949514
+  (fail to passthrough the USB3.0 stick to windows guest with xHCI controller under pc-i440fx-1.4)
+- Resolves: bz#953304
+  (Serial number of some USB devices must be fixed for older RHEL machine types)
+- Resolves: bz#974887
+  (the screen of guest fail to display correctly when use spice + qxl driver)
+- Resolves: bz#994642
+  (should disable vhost-scsi)
+- Resolves: bz#995866
+  (fix vmdk support to ESX images)
+
+* Mon Sep 23 2013 Paolo Bonzini <pbonzini@redhat.com> - qemu-kvm-1.5.3-6.el7
+- re-enable spice
+- Related: #979953
+
+* Mon Sep 23 2013 Paolo Bonzini <pbonzini@redhat.com> - qemu-kvm-1.5.3-5.el7
+- temporarily disable spice until libiscsi rebase is complete
+- Related: #979953
+
+* Thu Sep 19 2013 Michal Novotny <minovotn@redhat.com> - qemu-kvm-1.5.3-4.el7
+- kvm-block-package-preparation-code-in-qmp_transaction.patch [bz#1005818]
+- kvm-block-move-input-parsing-code-in-qmp_transaction.patch [bz#1005818]
+- kvm-block-package-committing-code-in-qmp_transaction.patch [bz#1005818]
+- kvm-block-package-rollback-code-in-qmp_transaction.patch [bz#1005818]
+- kvm-block-make-all-steps-in-qmp_transaction-as-callback.patch [bz#1005818]
+- kvm-blockdev-drop-redundant-proto_drv-check.patch [bz#1005818]
+- kvm-block-Don-t-parse-protocol-from-file.filename.patch [bz#1005818]
+- kvm-Revert-block-Disable-driver-specific-options-for-1.5.patch [bz#1005818]
+- kvm-qcow2-Add-refcount-update-reason-to-all-callers.patch [bz#1005818]
+- kvm-qcow2-Options-to-enable-discard-for-freed-clusters.patch [bz#1005818]
+- kvm-qcow2-Batch-discards.patch [bz#1005818]
+- kvm-block-Always-enable-discard-on-the-protocol-level.patch [bz#1005818]
+- kvm-qapi.py-Avoid-code-duplication.patch [bz#1005818]
+- kvm-qapi.py-Allow-top-level-type-reference-for-command-d.patch [bz#1005818]
+- kvm-qapi-schema-Use-BlockdevSnapshot-type-for-blockdev-s.patch [bz#1005818]
+- kvm-qapi-types.py-Implement-base-for-unions.patch [bz#1005818]
+- kvm-qapi-visit.py-Split-off-generate_visit_struct_fields.patch [bz#1005818]
+- kvm-qapi-visit.py-Implement-base-for-unions.patch [bz#1005818]
+- kvm-docs-Document-QAPI-union-types.patch [bz#1005818]
+- kvm-qapi-Add-visitor-for-implicit-structs.patch [bz#1005818]
+- kvm-qapi-Flat-unions-with-arbitrary-discriminator.patch [bz#1005818]
+- kvm-qapi-Add-consume-argument-to-qmp_input_get_object.patch [bz#1005818]
+- kvm-qapi.py-Maintain-a-list-of-union-types.patch [bz#1005818]
+- kvm-qapi-qapi-types.py-native-list-support.patch [bz#1005818]
+- kvm-qapi-Anonymous-unions.patch [bz#1005818]
+- kvm-block-Allow-driver-option-on-the-top-level.patch [bz#1005818]
+- kvm-QemuOpts-Add-qemu_opt_unset.patch [bz#1005818]
+- kvm-blockdev-Rename-I-O-throttling-options-for-QMP.patch [bz#1005818]
+- kvm-qemu-iotests-Update-051-reference-output.patch [bz#1005818]
+- kvm-blockdev-Rename-readonly-option-to-read-only.patch [bz#1005818]
+- kvm-blockdev-Split-up-cache-option.patch [bz#1005818]
+- kvm-qcow2-Use-dashes-instead-of-underscores-in-options.patch [bz#1005818]
+- kvm-qemu-iotests-filter-QEMU-version-in-monitor-banner.patch [bz#1006959]
+- kvm-tests-set-MALLOC_PERTURB_-to-expose-memory-bugs.patch [bz#1006959]
+- kvm-qemu-iotests-Whitespace-cleanup.patch [bz#1006959]
+- kvm-qemu-iotests-Fixed-test-case-026.patch [bz#1006959]
+- kvm-qemu-iotests-Fix-test-038.patch [bz#1006959]
+- kvm-qemu-iotests-Remove-lsi53c895a-tests-from-051.patch [bz#1006959]
+- Resolves: bz#1005818
+  (qcow2: Backport discard command line options)
+- Resolves: bz#1006959
+  (qemu-iotests false positives)
+
+* Thu Aug 29 2013 Miroslav Rezanina <mrezanin@redhat.com> - qemu-kvm-1.5.3-3.el7
+- Fix rhel/rhev split
+
+* Thu Aug 29 2013 Miroslav Rezanina <mrezanin@redhat.com> - qemu-kvm-1.5.3-2.el7
+- kvm-osdep-add-qemu_get_local_state_pathname.patch [bz#964304]
+- kvm-qga-determine-default-state-dir-and-pidfile-dynamica.patch [bz#964304]
+- kvm-configure-don-t-save-any-fixed-local_statedir-for-wi.patch [bz#964304]
+- kvm-qga-create-state-directory-on-win32.patch [bz#964304]
+- kvm-qga-save-state-directory-in-ga_install_service-RHEL-.patch [bz#964304]
+- kvm-Makefile-create-.-var-run-when-installing-the-POSIX-.patch [bz#964304]
+- kvm-qemu-option-Fix-qemu_opts_find-for-null-id-arguments.patch [bz#980782]
+- kvm-qemu-option-Fix-qemu_opts_set_defaults-for-corner-ca.patch [bz#980782]
+- kvm-vl-New-qemu_get_machine_opts.patch [bz#980782]
+- kvm-Fix-machine-options-accel-kernel_irqchip-kvm_shadow_.patch [bz#980782]
+- kvm-microblaze-Fix-latent-bug-with-default-DTB-lookup.patch [bz#980782]
+- kvm-Simplify-machine-option-queries-with-qemu_get_machin.patch [bz#980782]
+- kvm-pci-add-VMSTATE_MSIX.patch [bz#838170]
+- kvm-xhci-add-XHCISlot-addressed.patch [bz#838170]
+- kvm-xhci-add-xhci_alloc_epctx.patch [bz#838170]
+- kvm-xhci-add-xhci_init_epctx.patch [bz#838170]
+- kvm-xhci-add-live-migration-support.patch [bz#838170]
+- kvm-pc-set-level-xlevel-correctly-on-486-qemu32-CPU-mode.patch [bz#918907]
+- kvm-pc-Remove-incorrect-rhel6.x-compat-model-value-for-C.patch [bz#918907]
+- kvm-pc-rhel6.x-has-x2apic-present-on-Conroe-Penryn-Nehal.patch [bz#918907]
+- kvm-pc-set-compat-CPUID-0x80000001-.EDX-bits-on-Westmere.patch [bz#918907]
+- kvm-pc-Remove-PCLMULQDQ-from-Westmere-on-rhel6.x-machine.patch [bz#918907]
+- kvm-pc-SandyBridge-rhel6.x-compat-fixes.patch [bz#918907]
+- kvm-pc-Haswell-doesn-t-have-rdtscp-on-rhel6.x.patch [bz#918907]
+- kvm-i386-fix-LAPIC-TSC-deadline-timer-save-restore.patch [bz#972433]
+- kvm-all.c-max_cpus-should-not-exceed-KVM-vcpu-limit.patch [bz#996258]
+- kvm-add-timestamp-to-error_report.patch [bz#906937]
+- kvm-Convert-stderr-message-calling-error_get_pretty-to-e.patch [bz#906937]
+- Resolves: bz#838170
+  (Add live migration support for USB [xhci, usb-uas])
+- Resolves: bz#906937
+  ([Hitachi 7.0 FEAT][QEMU]Add a time stamp to error message (*))
+- Resolves: bz#918907
+  (provide backwards-compatible RHEL specific machine types in QEMU - CPU features)
+- Resolves: bz#964304
+  (Windows guest agent service failed to be started)
+- Resolves: bz#972433
+  ("INFO: rcu_sched detected stalls" after RHEL7 kvm vm migrated)
+- Resolves: bz#980782
+  (kernel_irqchip defaults to off instead of on without -machine)
+- Resolves: bz#996258
+  (boot guest with maxcpu=255 successfully but actually max number of vcpu is 160)
+
+* Wed Aug 28 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.3-1
+- Rebase to qemu 1.5.3
+
+* Tue Aug 20 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.2-4
+- qemu: guest agent creates files with insecure permissions in deamon mode [rhel-7.0] (rhbz 974444)
+- update qemu-ga config & init script in RHEL7 wrt. fsfreeze hook (rhbz 969942)
+- RHEL7 does not have equivalent functionality for __com.redhat_qxl_screendump (rhbz 903910)
+- SEP flag behavior for CPU models of RHEL6 machine types should be compatible (rhbz 960216)
+- crash command can not read the dump-guest-memory file when paging=false [RHEL-7] (rhbz 981582)
+- RHEL 7 qemu-kvm fails to build on F19 host due to libusb deprecated API (rhbz 996469)
+- Live migration support in virtio-blk-data-plane (rhbz 995030)
+- qemu-img resize can execute successfully even input invalid syntax (rhbz 992935)
+
+* Fri Aug 09 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.2-3
+- query mem info from monitor would cause qemu-kvm hang [RHEL-7] (rhbz #970047)
+- Throttle-down guest to help with live migration convergence (backport to RHEL7.0) (rhbz #985958)
+- disable (for now) EFI-enabled roms (rhbz #962563)
+- qemu-kvm "vPMU passthrough" mode breaks migration, shouldn't be enabled by default (rhbz #853101)
+- Remove pending watches after virtserialport unplug (rhbz #992900)
+- Containment of error when an SR-IOV device encounters an error... (rhbz #984604)
+
+* Wed Jul 31 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.2-2
+- SPEC file prepared for RHEL/RHEV split (rhbz #987165)
+- RHEL guest( sata disk ) can not boot up (rhbz #981723)
+- Kill the "use flash device for BIOS unless KVM" misfeature (rhbz #963280)
+- Provide RHEL-6 machine types (rhbz #983991)
+- Change s3/s4 default to "disable". (rhbz #980840)
+- Support Virtual Memory Disk Format in qemu (rhbz #836675)
+- Glusterfs backend for QEMU (rhbz #805139)
+
+* Tue Jul 02 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.2-1
+- Rebase to 1.5.2
+
+* Tue Jul 02 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.1-2
+- Fix package package version info (bz #952996)
+- pc: Replace upstream machine types by RHEL-7 types (bz #977864)
+- target-i386: Update model values on Conroe/Penryn/Nehalem CPU model (bz #861210)
+- target-i386: Set level=4 on Conroe/Penryn/Nehalem (bz #861210)
+
+* Fri Jun 28 2013 Miroslav Rezanina <mrezanin@redhat.com> - 10:1.5.1-1
+- Rebase to 1.5.1
+- Change epoch to 10 to obsolete RHEL-6 qemu-kvm-rhev package (bz #818626)
+
+* Fri May 24 2013 Miroslav Rezanina <mrezanin@redhat.com> - 3:1.5.0-2
+- Enable werror (bz #948290)
+- Enable nbd driver (bz #875871)
+- Fix udev rules file location (bz #958860)
+- Remove +x bit from systemd unit files (bz #965000)
+- Drop unneeded kvm.modules on x86 (bz #963642)
+- Fix build flags
+- Enable libusb
+
+* Thu May 23 2013 Miroslav Rezanina <mrezanin@redhat.com> - 3:1.5.0-1
+- Rebase to 1.5.0
+
+* Tue Apr 23 2013 Miroslav Rezanina <mrezanin@redhat.com> - 3:1.4.0-4
+- Enable build of libcacard subpackage for non-x86_64 archs (bz #873174)
+- Enable build of qemu-img subpackage for non-x86_64 archs (bz #873174)
+- Enable build of qemu-guest-agent subpackage for non-x86_64 archs (bz #873174)
+
+* Tue Apr 23 2013 Miroslav Rezanina <mrezanin@redhat.com> - 3:1.4.0-3
+- Enable/disable features supported by rhel7
+- Use qemu-kvm instead of qemu in filenames and pathes
+
+* Fri Apr 19 2013 Daniel Mach <dmach@redhat.com> - 3:1.4.0-2.1
+- Rebuild for cyrus-sasl
+
+* Fri Apr 05 2013 Miroslav Rezanina <mrezanin@redhat.com> - 3:1.4.0-2
+- Synchronization with Fedora 19 package version 2:1.4.0-8
+
+* Wed Apr 03 2013 Daniel Mach <dmach@redhat.com> - 3:1.4.0-1.1
+- Rebuild for libseccomp
+
+* Thu Mar 07 2013 Miroslav Rezanina <mrezanin@redhat.com> - 3:1.4.0-1
+- Rebase to 1.4.0
+
+* Mon Feb 25 2013 Michal Novotny <minovotn@redhat.com> - 3:1.3.0-8
+- Missing package qemu-system-x86 in hardware certification kvm testing (bz#912433)
+- Resolves: bz#912433
+  (Missing package qemu-system-x86 in hardware certification kvm testing)
+
+* Fri Feb 22 2013 Alon Levy <alevy@redhat.com> - 3:1.3.0-6
+- Bump epoch back to 3 since there has already been a 3 package release:
+  3:1.2.0-20.el7 https://brewweb.devel.redhat.com/buildinfo?buildID=244866
+- Mark explicit libcacard dependency on new enough qemu-img to avoid conflict
+  since /usr/bin/vscclient was moved from qemu-img to libcacard subpackage.
+
+* Wed Feb 13 2013 Michal Novotny <minovotn@redhat.com> - 2:1.3.0-5
+- Fix patch contents for usb-redir (bz#895491)
+- Resolves: bz#895491
+  (PATCH: 0110-usb-redir-Add-flow-control-support.patch has been mangled on rebase !!)
+
+* Wed Feb 06 2013 Alon Levy <alevy@redhat.com> - 2:1.3.0-4
+- Add patch from f19 package for libcacard missing error_set symbol.
+- Resolves: bz#891552
+
+* Mon Jan 07 2013 Michal Novotny <minovotn@redhat.com> - 2:1.3.0-3
+- Remove dependency on bogus qemu-kvm-kvm package [bz#870343]
+- Resolves: bz#870343
+  (qemu-kvm-1.2.0-16.el7 cant be installed)
+
+* Tue Dec 18 2012 Michal Novotny <minovotn@redhat.com> - 2:1.3.0-2
+- Rename qemu to qemu-kvm
+- Move qemu-kvm to libexecdir
+
+* Fri Dec 07 2012 Cole Robinson <crobinso@redhat.com> - 2:1.3.0-1
+- Switch base tarball from qemu-kvm to qemu
+- qemu 1.3 release
+- Option to use linux VFIO driver to assign PCI devices
+- Many USB3 improvements
+- New paravirtualized hardware random number generator device.
+- Support for Glusterfs volumes with "gluster://" -drive URI
+- Block job commands for live block commit and storage migration
+
+* Wed Nov 28 2012 Alon Levy <alevy@redhat.com> - 2:1.2.0-25
+* Merge libcacard into qemu, since they both use the same sources now.
+
+* Thu Nov 22 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-24
+- Move vscclient to qemu-common, qemu-nbd to qemu-img
+
+* Tue Nov 20 2012 Alon Levy <alevy@redhat.com> - 2:1.2.0-23
+- Rewrite fix for bz #725965 based on fix for bz #867366
+- Resolve bz #867366
+
+* Fri Nov 16 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-23
+- Backport --with separate_kvm support from EPEL branch
+
+* Fri Nov 16 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-22
+- Fix previous commit
+
+* Fri Nov 16 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-21
+- Backport commit 38f419f (configure: Fix CONFIG_QEMU_HELPERDIR generation,
+  2012-10-17)
+
+* Thu Nov 15 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-20
+- Install qemu-bridge-helper as suid root
+- Distribute a sample /etc/qemu/bridge.conf file
+
+* Thu Nov  1 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-19
+- Sync spice patches with upstream, minor bugfixes and set the qxl pci
+  device revision to 4 by default, so that guests know they can use
+  the new features
+
+* Tue Oct 30 2012 Cole Robinson <crobinso@redhat.com> - 2:1.2.0-18
+- Fix loading arm initrd if kernel is very large (bz #862766)
+- Don't use reserved word 'function' in systemtap files (bz #870972)
+- Drop assertion that was triggering when pausing guests w/ qxl (bz
+  #870972)
+
+* Sun Oct 28 2012 Cole Robinson <crobinso@redhat.com> - 2:1.2.0-17
+- Pull patches queued for qemu 1.2.1
+
+* Fri Oct 19 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-16
+- add s390x KVM support
+- distribute pre-built firmware or device trees for Alpha, Microblaze, S390
+- add missing system targets
+- add missing linux-user targets
+- fix previous commit
+
+* Thu Oct 18 2012 Dan Horák <dan[at]danny.cz> - 2:1.2.0-15
+- fix build on non-kvm arches like s390(x)
+
+* Wed Oct 17 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-14
+- Change SLOF Requires for the new version number
+
+* Thu Oct 11 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-13
+- Add ppc support to kvm.modules (original patch by David Gibson)
+- Replace x86only build with kvmonly build: add separate defines and
+  conditionals for all packages, so that they can be chosen and
+  renamed in kvmonly builds and so that qemu has the appropriate requires
+- Automatically pick libfdt dependancy
+- Add knob to disable spice+seccomp
+
+* Fri Sep 28 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-12
+- Call udevadm on post, fixing bug 860658
+
+* Fri Sep 28 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-11
+- Rebuild against latest spice-server and spice-protocol
+- Fix non-seamless migration failing with vms with usb-redir devices,
+  to allow boxes to load such vms from disk
+
+* Tue Sep 25 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-10
+- Sync Spice patchsets with upstream (rhbz#860238)
+- Fix building with usbredir >= 0.5.2
+
+* Thu Sep 20 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-9
+- Sync USB and Spice patchsets with upstream
+
+* Sun Sep 16 2012 Richard W.M. Jones <rjones@redhat.com> - 2:1.2.0-8
+- Use 'global' instead of 'define', and underscore in definition name,
+  n-v-r, and 'dist' tag of SLOF, all to fix RHBZ#855252.
+
+* Fri Sep 14 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.2.0-4
+- add versioned dependency from qemu-system-ppc to SLOF (BZ#855252)
+
+* Wed Sep 12 2012 Richard W.M. Jones <rjones@redhat.com> - 2:1.2.0-3
+- Fix RHBZ#853408 which causes libguestfs failure.
+
+* Sat Sep  8 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-2
+- Fix crash on (seamless) migration
+- Sync usbredir live migration patches with upstream
+
+* Fri Sep  7 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-1
+- New upstream release 1.2.0 final
+- Add support for Spice seamless migration
+- Add support for Spice dynamic monitors
+- Add support for usb-redir live migration
+
+* Tue Sep 04 2012 Adam Jackson <ajax@redhat.com> 1.2.0-0.5.rc1
+- Flip Requires: ceph >= foo to Conflicts: ceph < foo, so we pull in only the
+  libraries which we need and not the rest of ceph which we don't.
+
+* Tue Aug 28 2012 Cole Robinson <crobinso@redhat.com> 1.2.0-0.4.rc1
+- Update to 1.2.0-rc1
+
+* Mon Aug 20 2012 Richard W.M. Jones <rjones@redhat.com> - 1.2-0.3.20120806git3e430569
+- Backport Bonzini's vhost-net fix (RHBZ#848400).
+
+* Tue Aug 14 2012 Cole Robinson <crobinso@redhat.com> - 1.2-0.2.20120806git3e430569
+- Bump release number, previous build forgot but the dist bump helped us out
+
+* Tue Aug 14 2012 Cole Robinson <crobinso@redhat.com> - 1.2-0.1.20120806git3e430569
+- Revive qemu-system-{ppc*, sparc*} (bz 844502)
+- Enable KVM support for all targets (bz 844503)
+
+* Mon Aug 06 2012 Cole Robinson <crobinso@redhat.com> - 1.2-0.1.20120806git3e430569.fc18
+- Update to git snapshot
+
+* Sun Jul 29 2012 Cole Robinson <crobinso@redhat.com> - 1.1.1-1
+- Upstream stable release 1.1.1
+- Fix systemtap tapsets (bz 831763)
+- Fix VNC audio tunnelling (bz 840653)
+- Don't renable ksm on update (bz 815156)
+- Bump usbredir dep (bz 812097)
+- Fix RPM install error on non-virt machines (bz 660629)
+- Obsolete openbios to fix upgrade dependency issues (bz 694802)
+
+* Sat Jul 21 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2:1.1.0-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jul 10 2012 Richard W.M. Jones <rjones@redhat.com> - 2:1.1.0-8
+- Re-diff previous patch so that it applies and actually apply it
+
+* Tue Jul 10 2012 Richard W.M. Jones <rjones@redhat.com> - 2:1.1.0-7
+- Add patch to fix default machine options.  This fixes libvirt
+  detection of qemu.
+- Back out patch 1 which conflicts.
+
+* Fri Jul  6 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.1.0-5
+- Fix qemu crashing (on an assert) whenever USB-2.0 isoc transfers are used
+
+* Thu Jul  5 2012 Richard W.M. Jones <rjones@redhat.com> - 2:1.1.0-4
+- Disable tests since they hang intermittently.
+- Add kvmvapic.bin (replaces vapic.bin).
+- Add cpus-x86_64.conf.  qemu now creates /etc/qemu/target-x86_64.conf
+  as an empty file.
+- Add qemu-icon.bmp.
+- Add qemu-bridge-helper.
+- Build and include virtfs-proxy-helper + man page (thanks Hans de Goede).
+
+* Wed Jul  4 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.1.0-1
+- New upstream release 1.1.0
+- Drop about a 100 spice + USB patches, which are all upstream
+
+* Mon Apr 23 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.0-17
+- Fix install failure due to set -e (rhbz #815272)
+
+* Mon Apr 23 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.0-16
+- Fix kvm.modules to exit successfully on non-KVM capable systems (rhbz #814932)
+
+* Thu Apr 19 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.0-15
+- Add a couple of backported QXL/Spice bugfixes
+- Add spice volume control patches
+
+* Fri Apr 6 2012 Paolo Bonzini <pbonzini@redhat.com> - 2:1.0-12
+- Add back PPC and SPARC user emulators
+- Update binfmt rules from upstream
+
+* Mon Apr  2 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.0-11
+- Some more USB bugfixes from upstream
+
+* Thu Mar 29 2012 Eduardo Habkost <ehabkost@redhat.com> - 2:1.0-12
+- Fix ExclusiveArch mistake that disabled all non-x86_64 builds on Fedora
+
+* Wed Mar 28 2012 Eduardo Habkost <ehabkost@redhat.com> - 2:1.0-11
+- Use --with variables for build-time settings
+
+* Wed Mar 28 2012 Daniel P. Berrange <berrange@redhat.com> - 2:1.0-10
+- Switch to use iPXE for netboot ROMs
+
+* Thu Mar 22 2012 Daniel P. Berrange <berrange@redhat.com> - 2:1.0-9
+- Remove O_NOATIME for 9p filesystems
+
+* Mon Mar 19 2012 Daniel P. Berrange <berrange@redhat.com> - 2:1.0-8
+- Move udev rules to /lib/udev/rules.d (rhbz #748207)
+
+* Fri Mar  9 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.0-7
+- Add a whole bunch of USB bugfixes from upstream
+
+* Mon Feb 13 2012 Daniel P. Berrange <berrange@redhat.com> - 2:1.0-6
+- Add many more missing BRs for misc QEMU features
+- Enable running of test suite during build
+
+* Tue Feb 07 2012 Justin M. Forbes <jforbes@redhat.com> - 2:1.0-5
+- Add support for virtio-scsi
+
+* Sun Feb  5 2012 Richard W.M. Jones <rjones@redhat.com> - 2:1.0-4
+- Require updated ceph for latest librbd with rbd_flush symbol.
+
+* Tue Jan 24 2012 Justin M. Forbes <jforbes@redhat.com> - 2:1.0-3
+- Add support for vPMU
+- e1000: bounds packet size against buffer size CVE-2012-0029
+
+* Fri Jan 13 2012 Justin M. Forbes <jforbes@redhat.com> - 2:1.0-2
+- Add patches for USB redirect bits
+- Remove palcode-clipper, we don't build it
+
+* Wed Jan 11 2012 Justin M. Forbes <jforbes@redhat.com> - 2:1.0-1
+- Add patches from 1.0.1 queue
+
+* Fri Dec 16 2011 Justin M. Forbes <jforbes@redhat.com> - 2:1.0-1
+- Update to qemu 1.0
+
+* Tue Nov 15 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.1-3
+- Enable spice for i686 users as well
+
+* Thu Nov 03 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.1-2
+- Fix POSTIN scriplet failure (#748281)
+
+* Fri Oct 21 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.1-1
+- Require seabios-bin >= 0.6.0-2 (#741992)
+- Replace init scripts with systemd units (#741920)
+- Update to 0.15.1 stable upstream
+
+* Fri Oct 21 2011 Paul Moore <pmoore@redhat.com>
+- Enable full relro and PIE (rhbz #738812)
+
+* Wed Oct 12 2011 Daniel P. Berrange <berrange@redhat.com> - 2:0.15.0-6
+- Add BR on ceph-devel to enable RBD block device
+
+* Wed Oct  5 2011 Daniel P. Berrange <berrange@redhat.com> - 2:0.15.0-5
+- Create a qemu-guest-agent sub-RPM for guest installation
+
+* Tue Sep 13 2011 Daniel P. Berrange <berrange@redhat.com> - 2:0.15.0-4
+- Enable DTrace tracing backend for SystemTAP (rhbz #737763)
+- Enable build with curl (rhbz #737006)
+
+* Thu Aug 18 2011 Hans de Goede <hdegoede@redhat.com> - 2:0.15.0-3
+- Add missing BuildRequires: usbredir-devel, so that the usbredir code
+  actually gets build
+
+* Thu Aug 18 2011 Richard W.M. Jones <rjones@redhat.com> - 2:0.15.0-2
+- Add upstream qemu patch 'Allow to leave type on default in -machine'
+  (2645c6dcaf6ea2a51a3b6dfa407dd203004e4d11).
+
+* Sun Aug 14 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.0-1
+- Update to 0.15.0 stable release.
+
+* Thu Aug 04 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.0-0.3.201108040af4922
+- Update to 0.15.0-rc1 as we prepare for 0.15.0 release
+
+* Thu Aug  4 2011 Daniel P. Berrange <berrange@redhat.com> - 2:0.15.0-0.3.2011072859fadcc
+- Fix default accelerator for non-KVM builds (rhbz #724814)
+
+* Thu Jul 28 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.0-0.1.2011072859fadcc
+- Update to 0.15.0-rc0 as we prepare for 0.15.0 release
+
+* Tue Jul 19 2011 Hans de Goede <hdegoede@redhat.com> - 2:0.15.0-0.2.20110718525e3df
+- Add support usb redirection over the network, see:
+  http://fedoraproject.org/wiki/Features/UsbNetworkRedirection
+- Restore chardev flow control patches
+
+* Mon Jul 18 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.15.0-0.1.20110718525e3df
+- Update to git snapshot as we prepare for 0.15.0 release
+
+* Wed Jun 22 2011 Richard W.M. Jones <rjones@redhat.com> - 2:0.14.0-9
+- Add BR libattr-devel.  This caused the -fstype option to be disabled.
+  https://www.redhat.com/archives/libvir-list/2011-June/thread.html#01017
+
+* Mon May  2 2011 Hans de Goede <hdegoede@redhat.com> - 2:0.14.0-8
+- Fix a bug in the spice flow control patches which breaks the tcp chardev
+
+* Tue Mar 29 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-7
+- Disable qemu-ppc and qemu-sparc packages (#679179)
+
+* Mon Mar 28 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-6
+- Spice fixes for flow control.
+
+* Tue Mar 22 2011 Dan Horák <dan[at]danny.cz> - 2:0.14.0-5
+- be more careful when removing the -g flag on s390
+
+* Fri Mar 18 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-4
+- Fix thinko on adding the most recent patches.
+
+* Wed Mar 16 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-3
+- Fix migration issue with vhost
+- Fix qxl locking issues for spice
+
+* Wed Mar 02 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-2
+- Re-enable sparc and cris builds
+
+* Thu Feb 24 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-1
+- Update to 0.14.0 release
+
+* Fri Feb 11 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-0.1.20110210git7aa8c46
+- Update git snapshot
+- Temporarily disable qemu-cris and qemu-sparc due to build errors (to be resolved shorly)
+
+* Tue Feb 08 2011 Justin M. Forbes <jforbes@redhat.com> - 2:0.14.0-0.1.20110208git3593e6b
+- Update to 0.14.0 rc git snapshot
+- Add virtio-net to modules
+
+* Wed Nov  3 2010 Daniel P. Berrange <berrange@redhat.com> - 2:0.13.0-2
+- Revert previous change
+- Make qemu-common own the /etc/qemu directory
+- Add /etc/qemu/target-x86_64.conf to qemu-system-x86 regardless
+  of host architecture.
+
+* Wed Nov 03 2010 Dan Horák <dan[at]danny.cz> - 2:0.13.0-2
+- Remove kvm config file on non-x86 arches (part of #639471)
+- Own the /etc/qemu directory
+
+* Mon Oct 18 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-1
+- Update to 0.13.0 upstream release
+- Fixes for vhost
+- Fix mouse in certain guests (#636887)
+- Fix issues with WinXP guest install (#579348)
+- Resolve build issues with S390 (#639471)
+- Fix Windows XP on Raw Devices (#631591)
+
+* Tue Oct 05 2010 jkeating - 2:0.13.0-0.7.rc1.1
+- Rebuilt for gcc bug 634757
+
+* Tue Sep 21 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.7.rc1
+- Flip qxl pci id from unstable to stable (#634535)
+- KSM Fixes from upstream (#558281)
+
+* Tue Sep 14 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.6.rc1
+- Move away from git snapshots as 0.13 is close to release
+- Updates for spice 0.6
+
+* Tue Aug 10 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.5.20100809git25fdf4a
+- Fix typo in e1000 gpxe rom requires.
+- Add links to newer vgabios
+
+* Tue Aug 10 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.4.20100809git25fdf4a
+- Disable spice on 32bit, it is not supported and buildreqs don't exist.
+
+* Mon Aug 9 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.3.20100809git25fdf4a
+- Updates from upstream towards 0.13 stable
+- Fix requires on gpxe
+- enable spice now that buildreqs are in the repository.
+- ksmtrace has moved to a separate upstream package
+
+* Tue Jul 27 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.2.20100727gitb81fe95
+- add texinfo buildreq for manpages.
+
+* Tue Jul 27 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.13.0-0.1.20100727gitb81fe95
+- Update to 0.13.0 upstream snapshot
+- ksm init fixes from upstream
+
+* Tue Jul 20 2010 Dan Horák <dan[at]danny.cz> - 2:0.12.3-8
+- Add avoid-llseek patch from upstream needed for building on s390(x)
+- Don't use parallel make on s390(x)
+
+* Tue Jun 22 2010 Amit Shah <amit.shah@redhat.com> - 2:0.12.3-7
+- Add vvfat hardening patch from upstream (#605202)
+
+* Fri Apr 23 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-6
+- Change requires to the noarch seabios-bin
+- Add ownership of docdir to qemu-common (#572110)
+- Fix "Cannot boot from non-existent NIC" error when using virt-install (#577851)
+
+* Thu Apr 15 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-5
+- Update virtio console patches from upstream
+
+* Thu Mar 11 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-4
+- Detect cdrom via ioctl (#473154)
+- re add increased buffer for USB control requests (#546483)
+
+* Wed Mar 10 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-3
+- Migration clear the fd in error cases (#518032)
+
+* Tue Mar 09 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-2
+- Allow builds --with x86only
+- Add libaio-devel buildreq for aio support
+
+* Fri Feb 26 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-1
+- Update to 0.12.3 upstream
+- vhost-net migration/restart fixes
+- Add F-13 machine type
+- virtio-serial fixes
+
+* Tue Feb 09 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.2-6
+- Add vhost net support.
+
+* Thu Feb 04 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.2-5
+- Avoid creating too large iovecs in multiwrite merge (#559717)
+- Don't try to set max_kernel_pages during ksm init on newer kernels (#558281)
+- Add logfile options for ksmtuned debug.
+
+* Wed Jan 27 2010 Amit Shah <amit.shah@redhat.com> - 2:0.12.2-4
+- Remove build dependency on iasl now that we have seabios
+
+* Wed Jan 27 2010 Amit Shah <amit.shah@redhat.com> - 2:0.12.2-3
+- Remove source target for 0.12.1.2
+
+* Wed Jan 27 2010 Amit Shah <amit.shah@redhat.com> - 2:0.12.2-2
+- Add virtio-console patches from upstream for the F13 VirtioSerial feature
+
+* Mon Jan 25 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.2-1
+- Update to 0.12.2 upstream
+
+* Sun Jan 10 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.1.2-3
+- Point to seabios instead of bochs, and add a requires for seabios
+
+* Mon Jan  4 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.1.2-2
+- Remove qcow2 virtio backing file patch
+
+* Mon Jan  4 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.1.2-1
+- Update to 0.12.1.2 upstream
+- Remove patches included in upstream
+
+* Fri Nov 20 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-12
+- Fix a use-after-free crasher in the slirp code (#539583)
+- Fix overflow in the parallels image format support (#533573)
+
+* Wed Nov  4 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-11
+- Temporarily disable preadv/pwritev support to fix data corruption (#526549)
+
+* Tue Nov  3 2009 Justin M. Forbes <jforbes@redhat.com> - 2:0.11.0-10
+- Default ksm and ksmtuned services on.
+
+* Thu Oct 29 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-9
+- Fix dropped packets with non-virtio NICs (#531419)
+
+* Wed Oct 21 2009 Glauber Costa <gcosta@redhat.com> - 2:0.11.0-8
+- Properly save kvm time registers (#524229)
+
+* Mon Oct 19 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-7
+- Fix potential segfault from too small MSR_COUNT (#528901)
+
+* Fri Oct  9 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-6
+- Fix fs errors with virtio and qcow2 backing file (#524734)
+- Fix ksm initscript errors on kernel missing ksm (#527653)
+- Add missing Requires(post): getent, useradd, groupadd (#527087)
+
+* Tue Oct  6 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-5
+- Add 'retune' verb to ksmtuned init script
+
+* Mon Oct  5 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-4
+- Use rtl8029 PXE rom for ne2k_pci, not ne (#526777)
+- Also, replace the gpxe-roms-qemu pkg requires with file-based requires
+
+* Thu Oct  1 2009 Justin M. Forbes <jmforbes@redhat.com> - 2:0.11.0-3
+- Improve error reporting on file access (#524695)
+
+* Mon Sep 28 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-2
+- Fix pci hotplug to not exit if supplied an invalid NIC model (#524022)
+
+* Mon Sep 28 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.11.0-1
+- Update to 0.11.0 release
+- Drop a couple of upstreamed patches
+
+* Wed Sep 23 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-5
+- Fix issue causing NIC hotplug confusion when no model is specified (#524022)
+
+* Wed Sep 16 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-4
+- Fix for KSM patch from Justin Forbes
+
+* Wed Sep 16 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-3
+- Add ksmtuned, also from Dan Kenigsberg
+- Use %%_initddir macro
+
+* Wed Sep 16 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-2
+- Add ksm control script from Dan Kenigsberg
+
+* Mon Sep  7 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.92-1
+- Update to qemu-kvm-0.11.0-rc2
+- Drop upstreamed patches
+- extboot install now fixed upstream
+- Re-place TCG init fix (#516543) with the one gone upstream
+
+* Mon Sep  7 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.10.rc1
+- Fix MSI-X error handling on older kernels (#519787)
+
+* Fri Sep  4 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.9.rc1
+- Make pulseaudio the default audio backend (#519540, #495964, #496627)
+
+* Thu Aug 20 2009 Richard W.M. Jones <rjones@redhat.com> - 2:0.10.91-0.8.rc1
+- Fix segfault when qemu-kvm is invoked inside a VM (#516543)
+
+* Tue Aug 18 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.7.rc1
+- Fix permissions on udev rules (#517571)
+
+* Mon Aug 17 2009 Lubomir Rintel <lkundrak@v3.sk> - 2:0.10.91-0.6.rc1
+- Allow blacklisting of kvm modules (#517866)
+
+* Fri Aug  7 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.5.rc1
+- Fix virtio_net with -net user (#516022)
+
+* Tue Aug  4 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.4.rc1
+- Update to qemu-kvm-0.11-rc1; no changes from rc1-rc0
+
+* Tue Aug  4 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.3.rc1.rc0
+- Fix extboot checksum (bug #514899)
+
+* Fri Jul 31 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.2.rc1.rc0
+- Add KSM support
+- Require bochs-bios >= 2.3.8-0.8 for latest kvm bios updates
+
+* Thu Jul 30 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.91-0.1.rc1.rc0
+- Update to qemu-kvm-0.11.0-rc1-rc0
+- This is a pre-release of the official -rc1
+- A vista installer regression is blocking the official -rc1 release
+- Drop qemu-prefer-sysfs-for-usb-host-devices.patch
+- Drop qemu-fix-build-for-esd-audio.patch
+- Drop qemu-slirp-Fix-guestfwd-for-incoming-data.patch
+- Add patch to ensure extboot.bin is installed
+
+* Sun Jul 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2:0.10.50-14.kvm88
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Thu Jul 23 2009 Glauber Costa <glommer@redhat.com> - 2:0.10.50-13.kvm88
+- Fix bug 513249, -net channel option is broken
+
+* Thu Jul 16 2009 Daniel P. Berrange <berrange@redhat.com> - 2:0.10.50-12.kvm88
+- Add 'qemu' user and group accounts
+- Force disable xen until it can be made to build
+
+* Thu Jul 16 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-11.kvm88
+- Update to kvm-88, see http://www.linux-kvm.org/page/ChangeLog
+- Package mutiboot.bin
+- Update for how extboot is built
+- Fix sf.net source URL
+- Drop qemu-fix-ppc-softmmu-kvm-disabled-build.patch
+- Drop qemu-fix-pcspk-build-with-kvm-disabled.patch
+- Cherry-pick fix for esound support build failure
+
+* Wed Jul 15 2009 Daniel Berrange <berrange@lettuce.camlab.fab.redhat.com> - 2:0.10.50-10.kvm87
+- Add udev rules to make /dev/kvm world accessible & group=kvm (rhbz #497341)
+- Create a kvm group if it doesn't exist (rhbz #346151)
+
+* Tue Jul 07 2009 Glauber Costa <glommer@redhat.com> - 2:0.10.50-9.kvm87
+- use pxe roms from gpxe, instead of etherboot package.
+
+* Fri Jul  3 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-8.kvm87
+- Prefer sysfs over usbfs for usb passthrough (#508326)
+
+* Sat Jun 27 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-7.kvm87
+- Update to kvm-87
+- Drop upstreamed patches
+- Cherry-pick new ppc build fix from upstream
+- Work around broken linux-user build on ppc
+- Fix hw/pcspk.c build with --disable-kvm
+- Re-enable preadv()/pwritev() since #497429 is long since fixed
+- Kill petalogix-s3adsp1800.dtb, since we don't ship the microblaze target
+
+* Fri Jun  5 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-6.kvm86
+- Fix 'kernel requires an x86-64 CPU' error
+- BuildRequires ncurses-devel to enable '-curses' option (#504226)
+
+* Wed Jun  3 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-5.kvm86
+- Prevent locked cdrom eject - fixes hang at end of anaconda installs (#501412)
+- Avoid harmless 'unhandled wrmsr' warnings (#499712)
+
+* Thu May 21 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-4.kvm86
+- Update to kvm-86 release
+- ChangeLog here: http://marc.info/?l=kvm&m=124282885729710
+
+* Fri May  1 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-3.kvm85
+- Really provide qemu-kvm as a metapackage for comps
+
+* Tue Apr 28 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-2.kvm85
+- Provide qemu-kvm as a metapackage for comps
+
+* Mon Apr 27 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10.50-1.kvm85
+- Update to qemu-kvm-devel-85
+- kvm-85 is based on qemu development branch, currently version 0.10.50
+- Include new qemu-io utility in qemu-img package
+- Re-instate -help string for boot=on to fix virtio booting with libvirt
+- Drop upstreamed patches
+- Fix missing kernel/include/asm symlink in upstream tarball
+- Fix target-arm build
+- Fix build on ppc
+- Disable preadv()/pwritev() until bug #497429 is fixed
+- Kill more .kernelrelease uselessness
+- Make non-kvm qemu build verbose
+
+* Fri Apr 24 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-15
+- Fix source numbering typos caused by make-release addition
+
+* Thu Apr 23 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-14
+- Improve instructions for generating the tarball
+
+* Tue Apr 21 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-13
+- Enable pulseaudio driver to fix qemu lockup at shutdown (#495964)
+
+* Tue Apr 21 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-12
+- Another qcow2 image corruption fix (#496642)
+
+* Mon Apr 20 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-11
+- Fix qcow2 image corruption (#496642)
+
+* Sun Apr 19 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-10
+- Run sysconfig.modules from %%post on x86_64 too (#494739)
+
+* Sun Apr 19 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-9
+- Align VGA ROM to 4k boundary - fixes 'qemu-kvm -std vga' (#494376)
+
+* Tue Apr  14 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-8
+- Provide qemu-kvm conditional on the architecture.
+
+* Thu Apr  9 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-7
+- Add a much cleaner fix for vga segfault (#494002)
+
+* Sun Apr  5 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-6
+- Fixed qcow2 segfault creating disks over 2TB. #491943
+
+* Fri Apr  3 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-5
+- Fix vga segfault under kvm-autotest (#494002)
+- Kill kernelrelease hack; it's not needed
+- Build with "make V=1" for more verbose logs
+
+* Thu Apr 02 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-4
+- Support botting gpxe roms.
+
+* Wed Apr 01 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-2
+- added missing patch. love for CVS.
+
+* Wed Apr 01 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-1
+- Include debuginfo for qemu-img
+- Do not require qemu-common for qemu-img
+- Explicitly own each of the firmware files
+- remove firmwares for ppc and sparc. They should be provided by an external package.
+  Not that the packages exists for sparc in the secondary arch repo as noarch, but they
+  don't automatically get into main repos. Unfortunately it's the best we can do right
+  now.
+- rollback a bit in time. Snapshot from avi's maint/2.6.30
+  - this requires the sasl patches to come back.
+  - with-patched-kernel comes back.
+
+* Wed Mar 25 2009 Mark McLoughlin <markmc@redhat.com> - 2:0.10-0.12.kvm20090323git
+- BuildRequires pciutils-devel for device assignment (#492076)
+
+* Mon Mar 23 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.11.kvm20090323git
+- Update to snapshot kvm20090323.
+- Removed patch2 (upstream).
+- use upstream's new split package.
+- --with-patched-kernel flag not needed anymore
+- Tell how to get the sources.
+
+* Wed Mar 18 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.10.kvm20090310git
+- Added extboot to files list.
+
+* Wed Mar 11 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.9.kvm20090310git
+- Fix wrong reference to bochs bios.
+
+* Wed Mar 11 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.8.kvm20090310git
+- fix Obsolete/Provides pair
+- Use kvm bios from bochs-bios package.
+- Using RPM_OPT_FLAGS in configure
+- Picked back audio-drv-list from kvm package
+
+* Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.7.kvm20090310git
+- modify ppc patch
+
+* Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.6.kvm20090310git
+- updated to kvm20090310git
+- removed sasl patches (already in this release)
+
+* Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.5.kvm20090303git
+- kvm.modules were being wrongly mentioned at %%install.
+- update description for the x86 system package to include kvm support
+- build kvm's own bios. It is still necessary while kvm uses a slightly different
+  irq routing mechanism
+
+* Thu Mar 05 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.4.kvm20090303git
+- seems Epoch does not go into the tags. So start back here.
+
+* Thu Mar 05 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.1.kvm20090303git
+- Use bochs-bios instead of bochs-bios-data
+- It's official: upstream set on 0.10
+
+* Thu Mar  5 2009 Daniel P. Berrange <berrange@redhat.com> - 2:0.9.2-0.2.kvm20090303git
+- Added BSD to license list, since many files are covered by BSD
+
+* Wed Mar 04 2009 Glauber Costa <glommer@redhat.com> - 0.9.2-0.1.kvm20090303git
+- missing a dot. shame on me
+
+* Wed Mar 04 2009 Glauber Costa <glommer@redhat.com> - 0.92-0.1.kvm20090303git
+- Set Epoch to 2
+- Set version to 0.92. It seems upstream keep changing minds here, so pick the lowest
+- Provides KVM, Obsoletes KVM
+- Only install qemu-kvm in ix86 and x86_64
+- Remove pkgdesc macros, as they were generating bogus output for rpm -qi.
+- fix ppc and ppc64 builds
+
+* Tue Mar 03 2009 Glauber Costa <glommer@redhat.com> - 0.10-0.3.kvm20090303git
+- only execute post scripts for user package.
+- added kvm tools.
+
+* Tue Mar 03 2009 Glauber Costa <glommer@redhat.com> - 0.10-0.2.kvm20090303git
+- put kvm.modules into cvs
+
+* Tue Mar 03 2009 Glauber Costa <glommer@redhat.com> - 0.10-0.1.kvm20090303git
+- Set Epoch to 1
+- Build KVM (basic build, no tools yet)
+- Set ppc in ExcludeArch. This is temporary, just to fix one issue at a time.
+  ppc users (IBM ? ;-)) please wait a little bit.
+
+* Tue Mar  3 2009 Daniel P. Berrange <berrange@redhat.com> - 1.0-0.5.svn6666
+- Support VNC SASL authentication protocol
+- Fix dep on bochs-bios-data
+
+* Tue Mar 03 2009 Glauber Costa <glommer@redhat.com> - 1.0-0.4.svn6666
+- use bios from bochs-bios package.
+
+* Tue Mar 03 2009 Glauber Costa <glommer@redhat.com> - 1.0-0.3.svn6666
+- use vgabios from vgabios package.
+
+* Mon Mar 02 2009 Glauber Costa <glommer@redhat.com> - 1.0-0.2.svn6666
+- use pxe roms from etherboot package.
+
+* Mon Mar 02 2009 Glauber Costa <glommer@redhat.com> - 1.0-0.1.svn6666
+- Updated to tip svn (release 6666). Featuring split packages for qemu.
+  Unfortunately, still using binary blobs for the bioses.
+
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.9.1-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Sun Jan 11 2009 Debarshi Ray <rishi@fedoraproject.org> - 0.9.1-12
+- Updated build patch. Closes Red Hat Bugzilla bug #465041.
+
+* Wed Dec 31 2008 Dennis Gilmore <dennis@ausil.us> - 0.9.1-11
+- add sparcv9 and sparc64 support
+
+* Fri Jul 25 2008 Bill Nottingham <notting@redhat.com>
+- Fix qemu-img summary (#456344)
+
+* Wed Jun 25 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-10.fc10
+- Rebuild for GNU TLS ABI change
+
+* Wed Jun 11 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-9.fc10
+- Remove bogus wildcard from files list (rhbz #450701)
+
+* Sat May 17 2008 Lubomir Rintel <lkundrak@v3.sk> - 0.9.1-8
+- Register binary handlers also for shared libraries
+
+* Mon May  5 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-7.fc10
+- Fix text console PTYs to be in rawmode
+
+* Sun Apr 27 2008 Lubomir Kundrak <lkundrak@redhat.com> - 0.9.1-6
+- Register binary handler for SuperH-4 CPU
+
+* Wed Mar 19 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-5.fc9
+- Split qemu-img tool into sub-package for smaller footprint installs
+
+* Wed Feb 27 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-4.fc9
+- Fix block device checks for extendable disk formats (rhbz #435139)
+
+* Sat Feb 23 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-3.fc9
+- Fix block device extents check (rhbz #433560)
+
+* Mon Feb 18 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 0.9.1-2
+- Autorebuild for GCC 4.3
+
+* Tue Jan  8 2008 Daniel P. Berrange <berrange@redhat.com> - 0.9.1-1.fc9
+- Updated to 0.9.1 release
+- Fix license tag syntax
+- Don't mark init script as a config file
+
+* Wed Sep 26 2007 Daniel P. Berrange <berrange@redhat.com> - 0.9.0-5.fc8
+- Fix rtl8139 checksum calculation for Vista (rhbz #308201)
+
+* Tue Aug 28 2007 Daniel P. Berrange <berrange@redhat.com> - 0.9.0-4.fc8
+- Fix debuginfo by passing -Wl,--build-id to linker
+
+* Tue Aug 28 2007 David Woodhouse <dwmw2@infradead.org> 0.9.0-4
+- Update licence
+- Fix CDROM emulation (#253542)
+
+* Tue Aug 28 2007 Daniel P. Berrange <berrange@redhat.com> - 0.9.0-3.fc8
+- Added backport of VNC password auth, and TLS+x509 cert auth
+- Switch to rtl8139 NIC by default for linkstate reporting
+- Fix rtl8139 mmio region mappings with multiple NICs
+
+* Sun Apr  1 2007 Hans de Goede <j.w.r.degoede@hhs.nl> 0.9.0-2
+- Fix direct loading of a linux kernel with -kernel & -initrd (bz 234681)
+- Remove spurious execute bits from manpages (bz 222573)
+
+* Tue Feb  6 2007 David Woodhouse <dwmw2@infradead.org> 0.9.0-1
+- Update to 0.9.0
+
+* Wed Jan 31 2007 David Woodhouse <dwmw2@infradead.org> 0.8.2-5
+- Include licences
+
+* Mon Nov 13 2006 Hans de Goede <j.w.r.degoede@hhs.nl> 0.8.2-4
+- Backport patch to make FC6 guests work by Kevin Kofler
+  <Kevin@tigcc.ticalc.org> (bz 207843).
+
+* Mon Sep 11 2006 David Woodhouse <dwmw2@infradead.org> 0.8.2-3
+- Rebuild
+
+* Thu Aug 24 2006 Matthias Saou <http://freshrpms.net/> 0.8.2-2
+- Remove the target-list iteration for x86_64 since they all build again.
+- Make gcc32 vs. gcc34 conditional on %%{fedora} to share the same spec for
+  FC5 and FC6.
+
+* Wed Aug 23 2006 Matthias Saou <http://freshrpms.net/> 0.8.2-1
+- Update to 0.8.2 (#200065).
+- Drop upstreamed syscall-macros patch2.
+- Put correct scriplet dependencies.
+- Force install mode for the init script to avoid umask problems.
+- Add %%postun condrestart for changes to the init script to be applied if any.
+- Update description with the latest "about" from the web page (more current).
+- Update URL to qemu.org one like the Source.
+- Add which build requirement.
+- Don't include texi files in %%doc since we ship them in html.
+- Switch to using gcc34 on devel, FC5 still has gcc32.
+- Add kernheaders patch to fix linux/compiler.h inclusion.
+- Add target-sparc patch to fix compiling on ppc (some int32 to float).
+
+* Thu Jun  8 2006 David Woodhouse <dwmw2@infradead.org> 0.8.1-3
+- More header abuse in modify_ldt(), change BuildRoot:
+
+* Wed Jun  7 2006 David Woodhouse <dwmw2@infradead.org> 0.8.1-2
+- Fix up kernel header abuse
+
+* Tue May 30 2006 David Woodhouse <dwmw2@infradead.org> 0.8.1-1
+- Update to 0.8.1
+
+* Sat Mar 18 2006 David Woodhouse <dwmw2@infradead.org> 0.8.0-6
+- Update linker script for PPC
+
+* Sat Mar 18 2006 David Woodhouse <dwmw2@infradead.org> 0.8.0-5
+- Just drop $RPM_OPT_FLAGS. They're too much of a PITA
+
+* Sat Mar 18 2006 David Woodhouse <dwmw2@infradead.org> 0.8.0-4
+- Disable stack-protector options which gcc 3.2 doesn't like
+
+* Fri Mar 17 2006 David Woodhouse <dwmw2@infradead.org> 0.8.0-3
+- Use -mcpu= instead of -mtune= on x86_64 too
+- Disable SPARC targets on x86_64, because dyngen doesn't like fnegs
+
+* Fri Mar 17 2006 David Woodhouse <dwmw2@infradead.org> 0.8.0-2
+- Don't use -mtune=pentium4 on i386. GCC 3.2 doesn't like it
+
+* Fri Mar 17 2006 David Woodhouse <dwmw2@infradead.org> 0.8.0-1
+- Update to 0.8.0
+- Resort to using compat-gcc-32
+- Enable ALSA
+
+* Mon May 16 2005 David Woodhouse <dwmw2@infradead.org> 0.7.0-2
+- Proper fix for GCC 4 putting 'blr' or 'ret' in the middle of the function,
+  for i386, x86_64 and PPC.
+
+* Sat Apr 30 2005 David Woodhouse <dwmw2@infradead.org> 0.7.0-1
+- Update to 0.7.0
+- Fix dyngen for PPC functions which end in unconditional branch
+
+* Thu Apr  7 2005 Michael Schwendt <mschwendt[AT]users.sf.net>
+- rebuilt
+
+* Sun Feb 13 2005 David Woodhouse <dwmw2@infradead.org> 0.6.1-2
+- Package cleanup
+
+* Sun Nov 21 2004 David Woodhouse <dwmw2@redhat.com> 0.6.1-1
+- Update to 0.6.1
+
+* Tue Jul 20 2004 David Woodhouse <dwmw2@redhat.com> 0.6.0-2
+- Compile fix from qemu CVS, add x86_64 host support
+
+* Wed May 12 2004 David Woodhouse <dwmw2@redhat.com> 0.6.0-1
+- Update to 0.6.0.
+
+* Sat May 8 2004 David Woodhouse <dwmw2@redhat.com> 0.5.5-1
+- Update to 0.5.5.
+
+* Sun May 2 2004 David Woodhouse <dwmw2@redhat.com> 0.5.4-1
+- Update to 0.5.4.
+
+* Thu Apr 22 2004 David Woodhouse <dwmw2@redhat.com> 0.5.3-1
+- Update to 0.5.3. Add init script.
+
+* Thu Jul 17 2003 Jeff Johnson <jbj@redhat.com> 0.4.3-1
+- Create.