From 4a2fecc46a7a90f76fded8863922a530409d45cc Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 10 2018 05:15:34 +0000 Subject: import qemu-kvm-ma-2.10.0-21.el7 --- 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 +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 ++#include "block/vxhs_shim.h" ++#include + #include + #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 < +-#include +- +-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 ++ ++/* ++ * 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://: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 +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 + +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 + #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 +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 + +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 ++#include ++#include ++ ++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 +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 + +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 +Date: Tue, 14 Mar 2017 13:21:06 +0100 +Subject: add qxl_screendump monitor command + +RH-Author: Gerd Hoffmann +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Michal Novotny + +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 +(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 +Date: Tue, 8 Oct 2013 17:05:45 +0200 +Subject: seabios paravirt: allow more than 1TB in x86 guest + +RH-Author: Andrea Arcangeli +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 +RH-Acked-by: Gleb Natapov +RH-Acked-by: Laszlo Ersek + +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 +(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 +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 +Message-id: +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Orit Wasserman +RH-Acked-by: Eric Blake + +From: Miroslav Rezanina + +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 + +Signed-off-by: Miroslav Rezanina +(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 +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 +Message-id: +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Orit Wasserman +RH-Acked-by: Eric Blake + +From: Miroslav Rezanina + +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 + +Signed-off-by: Miroslav Rezanina +(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 +Date: Tue, 3 Dec 2013 20:05:13 +0100 +Subject: vfio: cap number of devices that can be assigned + +RH-Author: Bandan Das +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 +RH-Acked-by: Marcelo Tosatti +RH-Acked-by: Michael S. Tsirkin + +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 + +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 +Date: Tue, 14 Mar 2017 14:03:39 +0100 +Subject: QMP: Forward-port __com.redhat_drive_del from RHEL-6 + +RH-Author: Markus Armbruster +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Luiz Capitulino + +From: Markus Armbruster + +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 + +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 +Date: Tue, 14 Mar 2017 14:16:45 +0100 +Subject: QMP: Forward-port __com.redhat_drive_add from RHEL-6 + +RH-Author: Markus Armbruster +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Luiz Capitulino + +From: Markus Armbruster + +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 + +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 +Date: Tue, 14 Mar 2017 14:25:44 +0100 +Subject: HMP: Forward-port __com.redhat_drive_add from RHEL-6 + +RH-Author: Markus Armbruster +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Luiz Capitulino + +From: Markus Armbruster + +Signed-off-by: Markus Armbruster + +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 +Date: Wed, 4 Dec 2013 18:53:17 +0100 +Subject: Add support statement to -help output + +RH-Author: Eduardo Habkost +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 +RH-Acked-by: knoel@redhat.com +RH-Acked-by: Paolo Bonzini + +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 +(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 +Date: Mon, 7 Jul 2014 10:28:38 +0200 +Subject: vl: Round memory sizes below 2MiB up to 2MiB + +RH-Author: Markus Armbruster +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 +RH-Acked-by: Luiz Capitulino +RH-Acked-by: Igor Mammedov + +From: Markus Armbruster + +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 +(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 +Date: Tue, 21 Jan 2014 10:46:52 +0100 +Subject: use recommended max vcpu count + +RH-Author: Andrew Jones +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Marcelo Tosatti + +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 +(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 +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 + +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 +Date: Fri, 14 Nov 2014 08:51:50 +0100 +Subject: Use qemu-kvm in documentation instead of qemu-system- + +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 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Stefan Hajnoczi + +From: Miroslav Rezanina + +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 + +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[:'] where is the name of the + virtual machine. + +@@ -1112,7 +1112,7 @@ cat >iscsi.conf < 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://[:]//'' + +-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[:]' 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 . + + 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 +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 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Eric Blake + +This commit forward ports the following RHEL-7.0 commit to RHEL-7.2: + + commit 771a3a333eb0c9299a69a78ddb9c4181850b827d + Author: Laszlo Ersek + 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 +Signed-off-by: Miroslav Rezanina + +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" +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Paolo Bonzini + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +(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" +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Juan Quintela + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +(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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +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 +Signed-off-by: Miroslav Rezanina +(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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +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 + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +(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 +Date: Thu, 19 May 2016 06:39:44 +0200 +Subject: qmp: Report __com.redhat_drive_add error to monitor + +RH-Author: Fam Zheng +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Kevin Wolf + +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 +Signed-off-by: Miroslav Rezanina +(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 +Date: Mon, 1 Aug 2016 14:27:09 +0200 +Subject: RHEL-only: hw/char/pl011: fix SBSA reset + +RH-Author: Andrew Jones +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Wei Huang + +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 +Signed-off-by: Miroslav Rezanina +(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 +Date: Fri, 16 Sep 2016 22:06:28 +0200 +Subject: blockdev: ignore cache options for empty CDROM drives + +RH-Author: John Snow +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 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Stefan Hajnoczi + +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 +Signed-off-by: Miroslav Rezanina +(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" +Date: Mon, 16 Jan 2017 11:52:49 +0100 +Subject: Revert "kvm_stat: Remove" + +RH-Author: ddepaula +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Miroslav Rezanina + +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 ++# ++# 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 ++@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" +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 +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 +RH-Acked-by: Xiao Wang +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +(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" +Date: Wed, 29 Mar 2017 10:57:23 +0200 +Subject: migcompat/rtl8139: Work around version bump + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Laurent Vivier + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina + +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" +Date: Fri, 5 May 2017 19:06:14 +0200 +Subject: usb-xhci: Fix PCI capability order + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Juan Quintela + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina + +-- +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 +Date: Thu, 11 May 2017 20:53:51 +0200 +Subject: blockdev: ignore aio=native for empty drives + +RH-Author: John Snow +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 +RH-Acked-by: Eric Blake +RH-Acked-by: Max Reitz + +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 +(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 +Date: Fri, 28 Apr 2017 12:22:27 +0200 +Subject: scsi: Disable deprecated implicit SCSI HBA creation more cleanly + +RH-Author: Markus Armbruster +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 +RH-Acked-by: John Snow +RH-Acked-by: Jeffrey Cody + +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 +Signed-off-by: Miroslav Rezanina +(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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Max Reitz + +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 +Signed-off-by: Miroslav Rezanina +(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 +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 +Reviewed-by: Greg Kurz +Reviewed-by: Thomas Huth +Message-Id: <20170913142036.2469-2-lvivier@redhat.com> +Acked-by: David Gibson +Signed-off-by: Dr. David Alan Gilbert +(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 +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 +Reviewed-by: Thomas Huth +Reviewed-by: Greg Kurz +Message-Id: <20170913142036.2469-3-lvivier@redhat.com> +Reviewed-by: Eric Auger +Tested-by: Eric Auger +Signed-off-by: Dr. David Alan Gilbert +(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=' 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 +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 +Tested-by: Laurent Vivier +Reviewed-by: Laurent Vivier +Reviewed-by: Greg Kurz +Reviewed-by: Peter Xu +Message-Id: <20170913142036.2469-4-lvivier@redhat.com> +Signed-off-by: Laurent Vivier +Signed-off-by: Dr. David Alan Gilbert +(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 +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 +Reviewed-by: Thomas Huth +Reviewed-by: Cornelia Huck +Message-Id: <20170913142036.2469-5-lvivier@redhat.com> +Signed-off-by: Dr. David Alan Gilbert +(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 +Date: Mon, 18 Sep 2017 00:20:08 +0100 +Subject: vfio, spapr: Fix levels calculation + +RH-Author: David Gibson +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 +RH-Acked-by: Suraj Jitindar Singh +RH-Acked-by: Sam Bobroff + +From: Alexey Kardashevskiy + +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 +Signed-off-by: David Gibson +(cherry picked from commit e100161b69f8cf56dae866912dfffe7dcd7140af) +Signed-off-by: David Gibson +Signed-off-by: Danilo C. L. de Paula +(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 . + * Based on the original sysvinit script by Dan Kenigsberg + * This file is distributed under the GNU General Public License, version 2 + * or later. */ + +#include +#include +#include +#include +#include +#include + +#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 +# +# 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Igor Mammedov + +From: David Gibson + +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 +Reviewed-by: Greg Kurz +Tested-by: Greg Kurz +(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 +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Paolo Bonzini + +From: "Dr. David Alan Gilbert" + +Not that much change from 2.9.0 + +Signed-off-by: Dr. David Alan Gilbert +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Auger Eric +RH-Acked-by: Marcel Apfelbaum + +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) 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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 13 Oct 2017 11:56:49 +0200 +Subject: [PATCH 18/69] Disable sm501 and sysbus-sm501 devices + +RH-Author: Miroslav Rezanina +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +From: Miroslav Rezanina + +We are not goint to support these devices so disable them. + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +From: Miroslav Rezanina + +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 +--- + 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 +Date: Fri, 12 Jan 2018 10:45:52 +0100 +Subject: [PATCH 1/8] Drop 105th key from en-us keymap. + +RH-Author: Gerd Hoffmann +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Markus Armbruster + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 4 Dec 2017 06:30:08 +0100 +Subject: [PATCH 28/36] Match POWER max cpus to x86 + +RH-Author: David Gibson +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Serhii Popovych + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Sam Bobroff + +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 +Signed-off-by: David Gibson +(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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jens Freimann +RH-Acked-by: Laurent Vivier + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +Upstream-status: downstream only + +We don't support them in downstream RHEL, so disable them in +the config files. + +Signed-off-by: Thomas Huth +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +From: Michael Roth + +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 +Reviewed-by: Greg Kurz +Tested-by: Eric Auger +Reviewed-by: David Gibson +Message-Id: <20171016222315.407-3-mdroth@linux.vnet.ibm.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2fc06c4ac65594ad248e9a9150ebdde9ff5a1253) +Signed-off-by: Serhii Popovych +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Igor Mammedov + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Fam Zheng +Signed-off-by: Peter Xu +Message-id: 20170928025958.1420-6-peterx@redhat.com +[peterx: write the commit message] +Signed-off-by: Peter Xu +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit f708a5e71cba0d784e307334c07ade5f56f827ab) +Signed-off-by: Stefan Hajnoczi + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Andrew Jones + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:12 +0100 +Subject: [PATCH 08/30] atomic: update documentation + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Paolo Bonzini + +Signed-off-by: Paolo Bonzini +(cherry picked from commit db81b9953761cac71906728fb3dfefce661ab903) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Eric Blake +(cherry picked from commit 3121fb45b004ea85fb3589368ea699f32e6ef832) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Eric Blake +(cherry picked from commit e0995dc3da0894d0a8260bddaa200a4cd7809ba4) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Eric Blake +(cherry picked from commit 148eb13c84cccd0eedd6e59f90e0151bd7bac9fa) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Alberto Garcia + +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 +Signed-off-by: Alberto Garcia +Reviewed-by: Max Reitz +Message-id: 0d3a67ce8d948bb33e08672564714dcfb76a3d8c.1510339534.git.berto@igalia.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 48bf7ea81aa848027bad24f7e7791b503dff727d) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +'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 +Reviewed-by: Fam Zheng +Reviewed-by: Alberto Garcia +(cherry picked from commit 1f4ad7d3b8f7162ec0471506d86f57a5d77b8f76) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +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 +Reviewed-by: Fam Zheng +(cherry picked from commit dacaa16238cc5915a609ddaab4b7f81c4bceb9ae) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Kevin Wolf + +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 +Tested-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Jeff Cody +Reviewed-by: Alberto Garcia +Reviewed-by: Fam Zheng +Signed-off-by: Kevin Wolf +(cherry picked from commit 02d213009d571bcd7171e3ff9234722a11d30d1b) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 4 Dec 2017 12:10:05 +0100 +Subject: [PATCH 34/36] block: Fix permissions after bdrv_reopen() + +RH-Author: Kevin Wolf +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Eric Blake +(cherry picked from commit 3045025991ebeec77ce89c8ec56e83858950bbb3) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +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 +(cherry picked from commit 5fbfabd313b77e1cc7038ae8c4481c4b9f8b650a) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Alberto Garcia + +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 +--Stefan] + +Reported-by: sochin jiang +Signed-off-by: Alberto Garcia +Reviewed-by: Max Reitz +Message-id: e089c66e7c20289b046d782cea4373b765c5bc1d.1510339534.git.berto@igalia.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit c89bcf3af01e7a8834cca5344e098bf879e99999) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +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 +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit cc954f01e3c004aad081aa36736a17e842b80211) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 17 Nov 2017 11:19:01 +0100 +Subject: [PATCH 02/15] block: add aio_context field in ThrottleGroupMember + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Manos Pitsidianakis + +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 +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Manos Pitsidianakis +Signed-off-by: Kevin Wolf +(cherry picked from commit c61791fc23ecd96e6a1e038c379c4033ffd5f40c) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 30 Nov 2017 22:49:05 +0100 +Subject: [PATCH 01/21] block: add bdrv_co_drain_end callback + +RH-Author: Jeffrey Cody +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Manos Pitsidianakis + +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 +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Fam Zheng +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 481cad48e5e655746893e001af31c161f4587a02) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Zhengui + +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 +. +--Stefan] + +Signed-off-by: Zhengui +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Alberto Garcia +Message-id: 1508564040-120700-1-git-send-email-lizhengui@huawei.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 632a77354317df32c7ff2d23424f0559c23fee51) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Laurent Vivier + +From: Paolo Bonzini + +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 +Signed-off-by: Paolo Bonzini +Reviewed-by: Eric Blake +Message-id: 20171207201320.19284-2-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit bd6458e410c1e7d2912357aeb399fe7d8ee9f9a3) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow + +From: Peter Krempa + +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 +Signed-off-by: Kevin Wolf +(cherry picked from commit 6bff597bf6580ecc691258e849f652911dbdda7c) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-5-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit edd5adeecddf665e7954bc146ff458bb30f178ae) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-4-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 66d56054bca3c1c45861d18ea97f147f7d376d21) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-3-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 2d24b60b7747f7bf40fd00b0375b6bd988d4f0d9) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-6-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit a36e458cdda0196911c1cbe7cfe6f9530f2280e3) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 17 Nov 2017 11:19:00 +0100 +Subject: [PATCH 01/15] block: move ThrottleGroup membership to + ThrottleGroupMember + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Manos Pitsidianakis + +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 +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Manos Pitsidianakis +Signed-off-by: Kevin Wolf +(cherry picked from commit 022cdc9f407434ad6eb7ace80362a1218a009bcc) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Stefan Hajnoczi + +From: Vladimir Sementsov-Ogievskiy + +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 +Reviewed-by: Eric Blake +Message-Id: <20170920124507.18841-4-vsementsov@virtuozzo.com> +Signed-off-by: Eric Blake +(cherry picked from commit a693437037328a95d815ad5aec37ac2f8e130e58) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +Message-id: +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Manos Pitsidianakis + +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Fam Zheng +Signed-off-by: Manos Pitsidianakis +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit f8ea8dacf0de636e2c0f13b90c0d75db97dc9b44) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 4 Dec 2017 12:10:04 +0100 +Subject: [PATCH 33/36] block: reopen: Queue children after their parents + +RH-Author: Kevin Wolf +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Eric Blake +(cherry picked from commit 1857c97b76af02537b954c86dab066503950a4fd) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Fam Zheng +RH-Acked-by: Jeffrey Cody + +From: Manos Pitsidianakis + +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 +Reviewed-by: Eric Blake +Reviewed-by: Alberto Garcia +Signed-off-by: Kevin Wolf +(cherry picked from commit 43a5dc02fd6070827d5c4ff652b885219fa8cbe1) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 17 Nov 2017 11:19:02 +0100 +Subject: [PATCH 03/15] block: tidy ThrottleGroupMember initializations + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Manos Pitsidianakis + +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 +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Manos Pitsidianakis +Signed-off-by: Kevin Wolf +(cherry picked from commit f738cfc843055238ad969782db69156929873832) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Stefan Hajnoczi + +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 +Message-id: 20170927125340.12360-2-berrange@redhat.com +Reviewed-by: Eric Blake +Reviewed-by: Max Reitz +Signed-off-by: Max Reitz +(cherry picked from commit 161253e2d0a83a1b33bca019c6e926013e1a03db) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Laszlo Ersek + +[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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Jeffrey Cody + +From: Eric Blake +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Eric Blake +Message-id: 20171207201320.19284-4-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 882e9b89af7c1086d97cee11b2437337e756fa00) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-9-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ca00bbb153d03c5338d8c8136812163f463f841e) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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=, 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=, has_props=, props=, errp=errp@entry=0x7ffe4a1fc9d8) at blockdev.c:2308 + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-2-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit b9464ba19f821ea6b29969104dc48dcdb26243dd) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +Message-id: +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Stefan Hajnoczi + +From: Alberto Garcia + +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 +Signed-off-by: Kevin Wolf +(cherry picked from commit 3d5d319e1221082974711af1d09d82f0755c1698) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Alberto Garcia + +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 +Signed-off-by: Kevin Wolf +(cherry picked from commit 0a3e155f3f5ec9b6f12d00894c7701b3cbb66590) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +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 +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 4afeffc8572f40d8844b946a30c00b10da4442b1) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 30 Nov 2017 22:49:14 +0100 +Subject: [PATCH 10/21] blockjob: introduce block_job_do_yield + +RH-Author: Jeffrey Cody +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Paolo Bonzini + +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 +Tested-By: Jeff Cody +Reviewed-by: Fam Zheng +Reviewed-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit 356f59b8757f47c0aca3e2e4e51d6010f64cade1) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Paolo Bonzini + +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 +Tested-By: Jeff Cody +Reviewed-by: Fam Zheng +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Jeff Cody +Signed-off-by: Kevin Wolf +(cherry picked from commit fc24908e7d232b79c2a6f0363f52bda18dedb57b) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +From: Paolo Bonzini + +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 +Reviewed-by: Alberto Garcia +Tested-By: Jeff Cody +Reviewed-by: Fam Zheng +Reviewed-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit 5bf1d5a73a4a6d0e2d692bd02b6d7f3eedeed3b7) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Thomas Huth +Reviewed-by: Daniel Henrique Barboza +Tested-by: Daniel Henrique Barboza +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit f865da7c369fa00b2ccaf6bce158ad2701b2a27c) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Laurent Vivier + +Move dst calculation into the loop, so we apply the mask on each +interation and will not overflow vga memory. + +Cc: Prasad J Pandit +Reported-by: Niu Guoxiang +Signed-off-by: Gerd Hoffmann +Message-id: 20171011084314.21752-1-kraxel@redhat.com +(cherry picked from commit eb38e1bc3740725ca29a535351de94107ec58d51) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 2 Oct 2017 07:04:17 +0200 +Subject: [PATCH 02/34] configure: Allow --enable-seccomp on s390x, too + +RH-Author: Thomas Huth +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 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Stefan Hajnoczi + +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 +Message-Id: <1505385363-27717-1-git-send-email-thuth@redhat.com> +Acked-by: Christian Borntraeger +Acked-by: Eduardo Otubo +Acked-by: Halil Pasic +Signed-off-by: Cornelia Huck +(cherry picked from commit 3aa35fcffcf0fe22ac48d4277ed6057ae3e57ce0) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 13 Oct 2017 14:13:00 +0200 +Subject: [PATCH 19/69] configure: enable --s390-pgste linker option + +RH-Author: Cornelia Huck +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Jens Freimann + +From: Christian Borntraeger + +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 +Cc: Alexander Graf +Cc: Dan Horak +Cc: David Hildenbrand +Signed-off-by: Christian Borntraeger +Acked-by: Janosch Frank +Reviewed-by: Thomas Huth +Message-Id: <1503483383-199649-1-git-send-email-borntraeger@de.ibm.com> +Reviewed-by: David Hildenbrand +Signed-off-by: Cornelia Huck +(cherry picked from commit e9a3591fa09f273592451f8b9f83692bcbedb60c) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Laszlo Ersek + +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 +Reviewed-by: Marc-André Lureau +Message-id: 20170906142109.2685-1-kraxel@redhat.com +(cherry picked from commit 1540008629bbb6a9c0826582d94ecf7a559f784c) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +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 +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 6133b39f3c36623425a6ede9e89d93175fde15cd) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 30 Nov 2017 09:25:42 +0100 +Subject: [PATCH 05/36] docs: Add image locking subsection + +RH-Author: Fam Zheng +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +This documents the image locking feature and explains when and how +related options can be used. + +Signed-off-by: Fam Zheng +Signed-off-by: Kevin Wolf +(cherry picked from commit b1d1cb272882dd6868740155120f6aeb260a204c) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +From: Stefan Hajnoczi + +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 +Signed-off-by: Kevin Wolf +(cherry picked from commit 78aa8aa019b999ec07b62b322c1280a8250e44ac) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina + +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://[[%]@@][:]// ++@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= ++export LIBISCSI_CHAP_PASSWORD= ++iscsi://// ++@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[:'] where is the UUID of the ++virtual machine. If the UUID is not specified qemu will use ++'iqn.2008-11.org.linux-kvm[:'] where 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 <= 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://[[%]@@][:]// +-@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= +-export LIBISCSI_CHAP_PASSWORD= +-iscsi://// +-@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[:'] where is the UUID of the +-virtual machine. If the UUID is not specified qemu will use +-'iqn.2008-11.org.linux-kvm[:'] where 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 < +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit 903ef7349699dcd932b5981b85c1f1ebe4a4bf2a) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 + #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?= +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Reviewed-by: Laszlo Ersek +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit d36d0a9d152316a41e02c2613a71f5859f407da1) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: John Snow +RH-Acked-by: Miroslav Rezanina + +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 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 +Reviewed-by: Laszlo Ersek + +(cherry picked from commit c3b1642b9b6b3ba4314d6be3be509d396372cfd5) + +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Marc-André Lureau +Acked-by: Laszlo Ersek +Reviewed-by: Eric Blake + +(cherry picked from commit 6f49ec4034e55dfb675a56a62c9579384f7fb8cc) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +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 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 +Reviewed-by: Laszlo Ersek + +(cherry picked from commit ce6b9e421a9ab45d7e6c97af092a07c049954444) + +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +If the guest note is VMCOREINFO, try to get phys_base from it. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit d9feb51772b4ade9700c7fa54529327a6c8183a7) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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, ¬e_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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-2-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit e76bb18f7e430e0c50fb38d051feacf268bd78f4) +Signed-off-by: Miroslav Rezanina + +Conflicts: + exec.c + +Conflicts because we applied 076a93d7 "exec: simplify +address_space_get_iotlb_entry" out of order downstream. + +Signed-off-by: David Gibson +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Jens Freimann + +From: Peter Xu + +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 +Signed-off-by: Maxime Coquelin +Message-Id: <20171010094247.10173-2-maxime.coquelin@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit d5e5fafd11be4458443c43f19c1ebdd24d99a751) +Signed-off-by: Maxime Coquelin +Signed-off-by: Miroslav Rezanina + +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 +Date: Fri, 20 Oct 2017 14:17:07 +0200 +Subject: [PATCH 05/19] exec: simplify address_space_get_iotlb_entry + +RH-Author: Maxime Coquelin +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Jens Freimann + +From: Peter Xu + +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 +Signed-off-by: Maxime Coquelin +Acked-by: Michael S. Tsirkin +Message-Id: <20171010094247.10173-3-maxime.coquelin@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 076a93d7972c9c1e3839d2f65edc32568a2cce93) +Signed-off-by: Maxime Coquelin +Signed-off-by: Miroslav Rezanina + +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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit 5f9252f7cc12c5cec1b3c6695aca02eb52ea7acc) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Igor Mammedov +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Laszlo Ersek + +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 +Message-Id: <20180108215007.46471-1-marcel@redhat.com> +Reviewed-by: Laszlo Ersek +Signed-off-by: Eduardo Habkost +(cherry picked from commit 45eda6c8eb45107630da670bc993074cf85ef64c) +Signed-off-by: Marcel Apfelbaum +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit 6f6f4aec749ba9a4fb58c7c20536a61b0381ff35) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 28 Nov 2017 15:14:02 +0100 +Subject: [PATCH 1/9] gicv3: Convert to DEFINE_PROP_LINK + +RH-Author: Auger Eric +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +From: Fam Zheng + +Signed-off-by: Fam Zheng +Message-id: 20170905131149.10669-4-famz@redhat.com +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +(cherry picked from commit 9ea26c70498cde1887746222c3cada968e46ec23) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 19 Oct 2017 01:34:53 +0200 +Subject: [PATCH 64/69] hostmem-file: Add "discard-data" option + +RH-Author: Eduardo Habkost +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 +RH-Acked-by: Igor Mammedov +RH-Acked-by: Paolo Bonzini + +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 +Message-Id: <20170824192315.5897-4-ehabkost@redhat.com> +[ehabkost: fixup: improved documentation] +Reviewed-by: Daniel P. Berrange +Tested-by: Zack Cornelius +Signed-off-by: Eduardo Habkost +(cherry picked from commit 11ae6ed8affdd131e735bac39b21e7d3cde66f7b) +Signed-off-by: Eduardo Habkost + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Eduardo Habkost + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laszlo Ersek + +From: Anthony PERARD + +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 +Signed-off-by: Anthony PERARD +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit ab938ae43f8a3a71a3525566edf586081b7a7452) +Signed-off-by: Marcel Apfelbaum + + Conflicts: + stubs/Makefile.objs + (some stubs were added before it) + +Signed-off-by: Marcel Apfelbaum +--- + +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 +--- + 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 +Date: Mon, 6 Nov 2017 17:08:43 +0100 +Subject: [PATCH 7/9] hw/arm/virt: Set INTx/gsi mapping + +RH-Author: Auger Eric +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: Pranavkumar Sawargaonkar + +Let's provide the GPEX host bridge with the INTx/gsi mapping. This is +needed for INTx/gsi routing. + +Signed-off-by: Pranavkumar Sawargaonkar +Signed-off-by: Tushar Jagad +Signed-off-by: Eric Auger +Reviewed-by: Andrew Jones +Tested-by: Feng Kan +Message-id: 1505296004-6798-3-git-send-email-eric.auger@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit c9bb8e16080d189a0c393a1061b427993516ae2b) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Eduardo Habkost + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Dr. David Alan Gilbert + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 8e36c336d943c3bfe0d06f5465cc64d44b306e13) +Signed-off-by: Marcel Apfelbaum +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +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 +Reported-by: wanghaibin +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +(cherry picked from commit 8a7348b5d62d7ea16807e6bea54b448a0184bb0f) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +>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 +Reviewed-by: Peter Maydell + +--- + +v4 -> V5: +- added Peter's R-b + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +From: Shanker Donthineni + +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 --mode acpi" instead of reboot. + +KVM Error: 'KVM_SET_DEVICE_ATTR failed: Group 4 attr 0x00000000000001' + +Signed-off-by: Shanker Donthineni +Reviewed-by: Eric Auger +Message-id: 1509712671-16299-1-git-send-email-shankerd@codeaurora.org +Signed-off-by: Peter Maydell +(cherry picked from commit 3a575cd2c2411f139a95ace4b2523bc1dfd21755) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +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 + +--- +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 +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +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 +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit 6e43353f10c6688060af0bc26bdfdd4cf9c96ea2) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 ++ * ++ * 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 ++ * ++ * 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Laurent Vivier + +From: Thomas Huth + +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 +Signed-off-by: David Gibson +(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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Gerd Hoffmann + +From: Aleksandr Bezzubikov + +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 +Reviewed-by: Marcel Apfelbaum +Tested-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 226263fb5cdaa4a4a95f1680fabbc9dd2123fd67) +Signed-off-by: Marcel Apfelbaum +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit fced4d00e68e7559c73746d963265f7fd0b6abf9) +Signed-off-by: Marcel Apfelbaum +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laszlo Ersek + +Tests: Hotplug an ivshmem device with 2G on Q35 and I440fx machines + (passes only if this patch is applied) + +Signed-off-by: Miroslav Rezanina + +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 +Reviewed-by: Gerd Hoffmann +Signed-off-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 9fa99d2519cbf71f871e46871df12cb446dc1c3e) +Signed-off-by: Marcel Apfelbaum +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: Pranavkumar Sawargaonkar + +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 +Signed-off-by: Tushar Jagad +Signed-off-by: Eric Auger +Reviewed-by: Andrew Jones +Tested-by: Feng Kan +Message-id: 1505296004-6798-4-git-send-email-eric.auger@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit d464814ae729f3200234ff74d5f050ddad4f1f20) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +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 +Message-id: 1508776211-22175-1-git-send-email-eric.auger@redhat.com +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +(cherry picked from commit 168df2dea701bbf3118bdfea7794369dfa694d3d) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: Pranavkumar Sawargaonkar + +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 +Signed-off-by: Tushar Jagad +Signed-off-by: Eric Auger +Tested-by: Feng Kan +Reviewed-by: Andrew Jones +Message-id: 1505296004-6798-2-git-send-email-eric.auger@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit 70bfdce6a1263fd06144ecc1c3727c44e562d89b) +Signed-off-by: Eric Auger +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Eduardo Habkost + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Gerd Hoffmann + +From: Aleksandr Bezzubikov + +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 +Reviewed-by: Marcel Apfelbaum +Tested-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 70e1ee59bb9490d9ac529e96820a03b346086ca1) +Signed-off-by: Marcel Apfelbaum +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Daniel Henrique Barboza + +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 +Signed-off-by: David Gibson +(cherry picked from commit 10f12e6450407b18b4d5a6b50d3852dcfd7fff75) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Daniel Henrique Barboza + +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 +Signed-off-by: David Gibson +(cherry picked from commit 56258174238eb25df629a53a96e1ac16a32dc7d4) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Laszlo Ersek + +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 +Signed-off-by: David Gibson +(cherry picked from commit bac658d1a4dc9dd637b2eb5006abda137071f17f) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Thomas Huth + +From: Daniel Henrique Barboza + +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 +Signed-off-by: David Gibson +(cherry picked from commit 2a129767ebb13ffc29dad6a8e8e6eec06dc38b25) +Signed-off-by: Serhii Popovych +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Suraj Jitindar Singh + +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 +(cherry picked from commit 4e5fe3688e23d61b45cc549ff1322aff8f50ef45) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Daniel Henrique Barboza + +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 +Signed-off-by: David Gibson +(cherry picked from commit c618e300eb2276996e7004100686768cf1445128) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +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 +Message-Id: <1507193105-15627-1-git-send-email-thuth@redhat.com> +Reviewed-by: Halil Pasic +Reviewed-by: Claudio Imbrenda +Signed-off-by: Cornelia Huck +(cherry picked from commit b923ab3112ed5ab47c2ff35776f17ab54c60d651) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Gonglei + +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 +Message-Id: <1505143227-14324-1-git-send-email-arei.gonglei@huawei.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Vadim Rozenfeld +--- + 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 +Date: Tue, 10 Oct 2017 14:02:51 +0200 +Subject: [PATCH 13/69] i386/kvm: advertise Hyper-V frequency MSRs + +RH-Author: Ladi Prosek +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Laszlo Ersek + +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 +Reviewed-by: David Hildenbrand +Message-Id: <20170807085703.32267-5-lprosek@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit d72bc7f6f8a397790abee4a25ba1b8c35dd2b841) +Signed-off-by: Ladi Prosek +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Laszlo Ersek + +Move the "is TSC stable and known" condition to a reusable helper. + +Signed-off-by: Ladi Prosek +Reviewed-by: David Hildenbrand +Message-Id: <20170807085703.32267-4-lprosek@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 4bb95b82df7ea4a1c7de15649dd16a70a19e6bab) +Signed-off-by: Ladi Prosek +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Laszlo Ersek + +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 +Message-Id: <20170807085703.32267-3-lprosek@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit ddb98b5a9ff27b21100da1d701ddf5da34c66673) +Signed-off-by: Ladi Prosek +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Laszlo Ersek + +Switch is easier on the eye and might lead to better codegen. + +Signed-off-by: Ladi Prosek +Reviewed-by: David Hildenbrand +Message-Id: <20170807085703.32267-2-lprosek@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1d268dece4991915c0dd0f882248cbcb22ae8ffc) +Signed-off-by: Ladi Prosek +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi + +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 +Reviewed-by: Stefan Hajnoczi +Message-id: 20171020091403.1479-1-berrange@redhat.com +Signed-off-by: John Snow +(cherry picked from commit 96f43c2b0a663f4789b51ed97297163321e7ba5e) +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Wed, 29 Nov 2017 14:26:05 +0100 +Subject: [PATCH 19/21] ide: support reporting of rotation rate + +RH-Author: Daniel P. Berrange +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 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi + +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 +Message-Id: <20171004114008.14849-3-berrange@redhat.com> +Reviewed-by: John Snow +Signed-off-by: Paolo Bonzini +(cherry picked from commit 3b19f4506901ecce25ff36cf62353a2b4bfe4f2b) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +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 +CC: Jason Wang +CC: Michael S. Tsirkin +Signed-off-by: Peter Xu +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 66a4a0318e6b9539505491e4576fb93a708095d8) +Signed-off-by: Peter Xu +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Stefan Weil + +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 +Acked-by: Daniel P. Berrange +Signed-off-by: Michael Tokarev +(cherry picked from commit 52aa5644e8e89ebfc3b1d0abdb7cc502ce9db599) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit ff1300e626949fa9850b0f91dc5e8c2cb45b6a88) +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Wed, 20 Dec 2017 17:56:49 +0100 +Subject: [PATCH 09/42] io: Allow empty websocket payload + +RH-Author: Daniel P. Berrange +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +Some browsers send pings/pongs with no payload, so allow empty payloads +instead of closing the connection. + +Signed-off-by: Brandon Carpenter +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 3a29640e2cbae9d47b89ffaf98ed358920eb6797) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 530ca60c16c83435d4becc9916d74fa43e003815) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +Keep pings and gratuitous pongs generated by web browsers from killing +websocket connections. + +Signed-off-by: Brandon Carpenter +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 01af17fc002414ee1ac0800babfb0edc2bef1a7d) +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Wed, 20 Dec 2017 17:56:51 +0100 +Subject: [PATCH 11/42] io: Reply to ping frames + +RH-Author: Daniel P. Berrange +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +Add an immediate ping reply (pong) to the outgoing stream when a ping +is received. Unsolicited pongs are ignored. + +Signed-off-by: Brandon Carpenter +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 268a53f50de795481dd73ffd0e0c1339ad3dc44b) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit eefa3d8ef649f9055611361e2201cca49f8c3433) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +From: Eric Blake + +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 +Message-Id: <20170905191114.5959-2-eblake@redhat.com> +Acked-by: Daniel P. Berrange +[commit message updated] +Signed-off-by: Eric Blake +(cherry picked from commit 9ffb8270205a274a18ee4f8a735e2fccaf957246) + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +From: "Daniel P. Berrange" + +These functions wait until they are able to read / write the full +requested data buffer(s). + +Reviewed-by: Eric Blake +Signed-off-by: Daniel P. Berrange +(cherry picked from commit d4622e55883211072621958d39ddaa73483d201e) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +It is useful to trace websockets frame encoding/decoding when debugging +problems. + +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 59f183bbd54eecffb8915bffe03f9c2720b28bcc) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +Reviewed-by: Eric Blake +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 0efd6c9ec19a1ea6c413424fbea54e1dfe471026) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 6d5d23b00709510d55711661c7ca41408fd9934e) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +Coverity pointed out the 'date' is not free()d in the error +path + +Reviewed-by: Eric Blake +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 7fc3fcefe2fc5966c6aa1ef4f10e9740d8d73bf2) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 8dfd5f96515ca20c4eb109cb0ee28e2bb32fc505) + +NB, include of iov.h was pushed into previous patch to fix bisect +buld. + +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(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 +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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é +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 3a3f8705962c8c8a47a9b981ffd5aab7274ad508) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit a7b20a8efa28e5f22c26c06cd06c2f12bc863493) +Signed-off-by: Miroslav Rezanina +--- + 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 + + +-/* 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(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 +--- + 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 + +@@ -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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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é +Signed-off-by: Daniel P. Berrange +(cherry picked from commit f69a8bde29354493ff8aea64cc9cb3b531d16337) +Signed-off-by: Miroslav Rezanina +--- + 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 ++ + + /* 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" +Date: Wed, 20 Dec 2017 17:56:55 +0100 +Subject: [PATCH 15/42] io: simplify websocket ping reply handling + +RH-Author: Daniel P. Berrange +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 57b0cdf152b7266e68bfa3e84635d4bdb64ef2cd) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 33badfd1e3735b877e41939100511c65572be6b9) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 27 Nov 2017 16:19:59 +0100 +Subject: [PATCH 04/21] iotests: Add cluster_size=64k to 125 + +RH-Author: Max Reitz +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Fam Zheng +RH-Acked-by: John Snow + +Apparently it would be a good idea to test that, too. + +Signed-off-by: Max Reitz +Message-id: 20171009215533.12530-4-mreitz@redhat.com +Reviewed-by: Eric Blake +Reviewed-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Max Reitz +(cherry picked from commit 4c112a397c2f61038914fa315a7896ce6d645d18) +Signed-off-by: Max Reitz +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +From: Max Reitz + +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 +Message-id: 20170927211334.3988-1-mreitz@redhat.com +Reviewed-by: Eric Blake +Signed-off-by: Max Reitz +(cherry picked from commit 47500c6775813c8f2b5a5de04d84222f3cecc62d) +Signed-off-by: Kevin Wolf +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:58 +0100 +Subject: [PATCH 40/42] iotests: add VM.add_object() + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +The VM.add_object() method can be used to add IOThreads or memory +backend objects. + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Eric Blake +Message-id: 20171207201320.19284-5-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ccc15f7dafff63cbcc3f6a7c51e380025d67f7f4) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:42 +0100 +Subject: [PATCH 24/42] iotests.py: add FilePath context manager + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Message-id: 20170824072202.26818-3-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit f4844ac0adabc458ba4610a71155448783d37c73) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 19 Oct 2017 01:34:50 +0200 +Subject: [PATCH 61/69] iothread: Make iothread_stop() idempotent + +RH-Author: Eduardo Habkost +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 +RH-Acked-by: Igor Mammedov +RH-Acked-by: Paolo Bonzini + +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 +Signed-off-by: Eduardo Habkost +Message-Id: <20170926130028.12471-1-ehabkost@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 65072c157e466db2785748a929e775703b20eefe) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:54 +0100 +Subject: [PATCH 36/42] iothread: add iothread_by_id() API + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +Encapsulate IOThread QOM object lookup so that callers don't need to +know how and where IOThread objects live. + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-8-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit fbcc6923b00c2b468a7470fec7863f0403a65736) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:47 +0100 +Subject: [PATCH 29/42] iothread: delay the context release to finalize + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Peter Xu + +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 +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Peter Xu +Message-id: 20170928025958.1420-5-peterx@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 5b3ac23fee97fc1a79ad2bb1cf3a1ce518d27905) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:46 +0100 +Subject: [PATCH 28/42] iothread: export iothread_stop() + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Peter Xu + +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 +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Peter Xu +Message-id: 20170928025958.1420-4-peterx@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 82d90705fe203cc6e150c10bd61f0dbe6979e8f4) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:59 +0100 +Subject: [PATCH 41/42] iothread: fix iothread_stop() race condition + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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=, __fds=) at /usr/include/bits/poll2.h:77 + #2 0x000055959992eac9 in qemu_poll_ns (fds=, nfds=, timeout=) 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=) at util/qemu-thread-posix.c:547 + #2 0x00005595996808ae in iothread_stop (iothread=) at iothread.c:91 + #3 0x000055959968094d in iothread_stop_iter (object=, opaque=) at iothread.c:102 + #4 0x0000559599857d97 in do_object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 , 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 , opaque=opaque@entry=0x0) at qom/object.c:867 + #6 0x0000559599680a6e in iothread_stop_all () at iothread.c:341 + #7 0x000055959955b1d5 in main (argc=, argv=, envp=) 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 +Reviewed-by: Eric Blake +Message-id: 20171207201320.19284-6-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 2362a28ea11c145e1a13ae79342d76dc118a72a6) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 22 Dec 2017 11:08:45 +0100 +Subject: [PATCH 27/42] iothread: provide helpers for internal use + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Peter Xu + +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 +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Peter Xu +Message-id: 20170928025958.1420-3-peterx@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 0173e21b617d3de1fcfa917e329bb9194ab332a4) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit 9ada575bbafaf6d3724a7f59df9da89776817cac) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Wei Huang + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 23 Jan 2018 19:12:44 +0100 +Subject: [PATCH 2/8] linux-headers: update + +RH-Author: Thomas Huth +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Cornelia Huck + +Update headers against 4.15-rc9. + +Signed-off-by: Cornelia Huck +(cherry picked from commit 9cbb636270b4df6f0a548e5c34b895330db5df8b) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 + */ + #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 + * Christian Borntraeger + */ +@@ -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 + */ +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" +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +This is to make next patches simpler. + +Signed-off-by: Alexey Kardashevskiy +Message-Id: <20170921085110.25598-11-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 9bf561e36cf8fed9565011a19ba9ea0100e1811e) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:20 +0100 +Subject: [PATCH 16/30] memory: Cleanup after switching to FlatView + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-8-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 9950322a593ff900a860fb52938159461798a831) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:29 +0100 +Subject: [PATCH 25/30] memory: Create FlatView directly + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-18-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 202fc01b05572ecb258fdf4c5bd56cf6de8140c7) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-14-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 67ace39b253ed5ae465275bc870f7e495547658b) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-17-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit b516572f31c0ea0937cd9d11d9bd72dd83809886) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +Date: Thu, 16 Nov 2017 03:07:17 +0100 +Subject: [PATCH 13/30] memory: Move AddressSpaceDispatch from AddressSpace to + FlatView + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-5-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 66a6df1dc6d5b28cc3e65db0d71683fbdddc6b62) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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(§ion->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 +Date: Thu, 16 Nov 2017 03:07:16 +0100 +Subject: [PATCH 12/30] memory: Move FlatView allocation to a helper + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-4-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit cc94cd6d36602d976a5e7bc29134d1eaefb4102e) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:24 +0100 +Subject: [PATCH 20/30] memory: Move address_space_update_ioeventfds + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +So it is called (twice) from the same function. This is to make the next +patches a bit simpler. + +Signed-off-by: Alexey Kardashevskiy +Message-Id: <20170921085110.25598-12-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 02218487649558ed66c3689d4cc55250a42601d8) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:15 +0100 +Subject: [PATCH 11/30] memory: Open code FlatView rendering + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-3-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 9a62e24f45bc97f8eaf198caf58906b47c50a8d5) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:18 +0100 +Subject: [PATCH 14/30] memory: Remove AddressSpace pointer from + AddressSpaceDispatch + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-6-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit c7752523787dc148f5ee976162e80ab594c386a1) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +This renames some helpers to reflect better what they do. + +This should cause no behavioural change. + +Signed-off-by: Alexey Kardashevskiy +Message-Id: <20170921085110.25598-9-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 8629d3fcb77e9775e44d9051bad0fb5187925eae) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-15-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 5e8fd947e2670c3c18f139de6a83fafcb56abbcc) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-13-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 967dc9b1194a9281124b2e1ce67b6c3359a2138f) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:32 +0100 +Subject: [PATCH 28/30] memory: Share special empty FlatView + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-16-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 092aa2fc65b7a35121616aad8f39d47b8f921618) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:22 +0100 +Subject: [PATCH 18/30] memory: Store physical root MR in FlatView + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-10-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 89c177bbdd6cf8e50b3fd4831697d50e195d6432) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Message-Id: <20170921085110.25598-7-aik@ozlabs.ru> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 166206845f7fd75e720e6feea0bb01957c8da07f) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +Date: Thu, 16 Nov 2017 03:07:13 +0100 +Subject: [PATCH 09/30] memory: avoid "resurrection" of dead FlatViews + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Paolo Bonzini + +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 + + +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 +(cherry picked from commit 447b0d0b9ee8a0ac216c3186e0f3c427a1001f0c) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Paolo Bonzini + +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 +(cherry picked from commit e673ba9af9bf8fd8e0f44025ac738b8285b3ed27) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 16 Nov 2017 03:07:30 +0100 +Subject: [PATCH 26/30] memory: trace FlatView creation and destruction + +RH-Author: David Gibson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Paolo Bonzini + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 02d9651d6a46479e9d70b72dca34e43605d06cda) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Wed, 25 Oct 2017 18:28:36 +0200 +Subject: [PATCH 17/19] migrate: HMP migate_continue + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +HMP equivalent to the just added migrate-continue +Unpause a migrate paused at a given state. + +Signed-off-by: Dr. David Alan Gilbert +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 94ae12cba4f18253e3cf5f9a70335e22870053b4) + Conflict: + Change in qapi_enum_parse parameters + +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +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 +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 93fbd0314ec060ffaf90169a06d5737fa97ffb25) +Signed-off-by: Miroslav Rezanina + +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" +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 +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +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 +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 31e060774cf5c3b9945f6f16d6c18d6eae18e4d9) +Signed-off-by: Miroslav Rezanina + +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" +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Kevin Wolf + +From: "Dr. David Alan Gilbert" + +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 +Reviewed-by: Peter Xu +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 6039dd5b1c45d76403b9dcadd2afd7efd8f42330) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Fam Zheng +RH-Acked-by: Juan Quintela + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Dr. David Alan Gilbert +Message-Id: <20170825141940.20740-2-dgilbert@redhat.com> +Reviewed-by: Peter Xu +Tested-by: Stafford Horne +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 5089e1862fe80b6f23ba4c494e2902cbe3d9d48e) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +Wait for a semaphore before completing the migration, +if the previously added capability was enabled. + +Signed-off-by: Dr. David Alan Gilbert +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit e91d8951d59d483f085f7650381b8e55a1a55e4c) +Signed-off-by: Miroslav Rezanina +--- + 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, ¤t_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" +Date: Wed, 25 Oct 2017 18:28:37 +0200 +Subject: [PATCH 18/19] migration: allow cancel to unpause + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +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 +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit a7b36b486dd58d8f44f788a2a2efa6a4fa3b1223) +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Wed, 25 Oct 2017 18:28:35 +0200 +Subject: [PATCH 16/19] migration: migrate-continue + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +A new qmp command allows the caller to continue from a given +paused state. + +Signed-off-by: Dr. David Alan Gilbert +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 89cfc02cb6e3fdaf8ae246493ea51e75be2818c1) +Signed-off-by: Miroslav Rezanina + +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" +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 +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 +RH-Acked-by: Juan Quintela +RH-Acked-by: Miroslav Rezanina + +From: "Dr. David Alan Gilbert" + +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 +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +(cherry picked from commit 0331c8cabf6168aa263aa0b25f5e135b328606ac) +Signed-off-by: Miroslav Rezanina +--- + 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, ¤t_active_state); ++ ret = migration_maybe_pause(s, ¤t_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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Juan Quintela +RH-Acked-by: David Gibson + +From: Daniel Henrique Barboza + +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 +CC: Juan Quintela +CC: Dr. David Alan Gilbert +Reviewed-by: Peter Xu +Reviewed-by: Juan Quintela +Reported-by: Balamuruhan S +Signed-off-by: Juan Quintela +(cherry picked from commit acab30b85db0885ab161aff4c83c550628f6d8ca) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Thomas Huth + +From: Daniel Henrique Barboza + +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 +Reported-by: Balamuruhan S +Reviewed-by: Juan Quintela +Signed-off-by: Juan Quintela +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit ee555cdf4d495ddd83633406e3099c5d1ef22e0a) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Wed, 8 Nov 2017 13:35:20 +0100 +Subject: [PATCH 2/7] monitor: fix dangling CPU pointer + +RH-Author: Serhii Popovych +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 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Peter Xu + +From: Greg Kurz + +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 +Suggested-by: Igor Mammedov +Signed-off-by: Greg Kurz +Message-Id: <150822818243.26242.12993827911736928961.stgit@bahia.lan> +Reviewed-by: Igor Mammedov +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 751f8cfe2a556b3ef49f6af2860e2d1d2a1ec66a) +Signed-off-by: Serhii Popovych +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 26 Oct 2017 09:55:58 +0200 +Subject: [PATCH 1/7] multiboot: validate multiboot header address values + +RH-Author: Bandan Das +Message-id: +Patchwork-id: 77442 +O-Subject: [RHV7.5 qemu-kvm-rhev PATCH] multiboot: validate multiboot header address values +Bugzilla: 1501124 +RH-Acked-by: Thomas Huth +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Prasad J Pandit +Message-Id: <20170907063256.7418-1-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Stefan Hajnoczi + +From: Stefan Hajnoczi + +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=) at block/nbd-client.c:207 + #2 0x000000d3c012fb58 in nbd_client_co_preadv (bs=0xd3c0fec650, offset=0, bytes=, 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=, i1=) 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 +Signed-off-by: Stefan Hajnoczi +Message-Id: <20170829122745.14309-2-stefanha@redhat.com> +Signed-off-by: Eric Blake +(cherry picked from commit 3c2d5183f9fa4eac3d17d841e26da65a0181ae7b) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi + +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 +(cherry picked from commit 51ae4f8455c9e32c54770c4ebc25bf86a8128183) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi + +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 +(cherry picked from commit fdad35ef6c5839d50dfc14073364ac893afebc30) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 19 Oct 2017 01:34:52 +0200 +Subject: [PATCH 63/69] osdep: Define QEMU_MADV_REMOVE + +RH-Author: Eduardo Habkost +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 +RH-Acked-by: Igor Mammedov +RH-Acked-by: Paolo Bonzini + +Define QEMU_MADV_REMOVE, so we can use it with qemu_madvise(). + +Signed-off-by: Eduardo Habkost +Message-Id: <20170824192315.5897-3-ehabkost@redhat.com> +Reviewed-by: Dr. David Alan Gilbert +Tested-by: Zack Cornelius +Signed-off-by: Eduardo Habkost +(cherry picked from commit 0f81d3353029d26c6f8731a65d8052c532b1ced6) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 26 Jan 2018 02:07:36 +0100 +Subject: [PATCH 5/8] osdep: Retry SETLK upon EINTR + +RH-Author: Fam Zheng +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Kevin Wolf + +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 +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit f86428a1f4f91a460ed585682af70d3e8c31dc06) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 23 Oct 2017 12:29:35 +0200 +Subject: [PATCH 2/9] pc-bios/keymaps: keymaps update + +RH-Author: Gerd Hoffmann +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +Update the keymaps with the ones generated by qemu-keymap + +Signed-off-by: Gerd Hoffmann +Message-id: 20171005153330.19210-4-kraxel@redhat.com +(cherry picked from commit a7815faffb2bd594b92aa3542d7b799cc89c5414) +Signed-off-by: Miroslav Rezanina +--- + 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 ++# ++# 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Miroslav Rezanina + +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 +Message-Id: <1510942228-22822-1-git-send-email-thuth@redhat.com> +Acked-by: Christian Borntraeger +Reviewed-by: David Hildenbrand +Signed-off-by: Cornelia Huck +(cherry picked from commit 8775d91a0f42d016833330881bb587982db88a3c) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Wed, 6 Dec 2017 13:47:58 +0100 +Subject: [PATCH 20/21] pc: fix crash on attempted cpu unplug + +RH-Author: Igor Mammedov +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 +RH-Acked-by: Marcel Apfelbaum +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Eduardo Habkost +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 75ba2ddb188fa07c3442446766782036e3085cba) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Igor Mammedov + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Acked-by: John Snow +Acked-by: Anthony PERARD +Signed-off-by: Eduardo Habkost +Reviewed-by: David Gibson +Acked-by: David Gibson +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit fd3b02c8896d597dd8b9e053dec579cf0386aee1) +Signed-off-by: Eduardo Habkost +--- +Changes v1 -> v2: +* Removed hw/net/sungem.c and hw/net/sunhme.c + (Mistake spotted by David Gibson) + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Cc: Kevin Wolf +Cc: Max Reitz +Cc: Dmitry Fleytman +Cc: Jason Wang +Cc: "Michael S. Tsirkin" +Cc: Marcel Apfelbaum +Cc: Paul Burton +Cc: Paolo Bonzini +Cc: Hannes Reinecke +Cc: qemu-block@nongnu.org +Reviewed-by: Alistair Francis +Signed-off-by: Eduardo Habkost +Reviewed-by: David Gibson +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 71d787677d0cacea846dc851c3e56ad076d59c04) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Cc: Jason Wang +Cc: Paolo Bonzini +Cc: Gerd Hoffmann +Cc: Alex Williamson +Cc: "Michael S. Tsirkin" +Signed-off-by: Eduardo Habkost +Reviewed-by: David Gibson +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit a5fa336f11a1eddad9f2be6506e59ba50ed81818) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 20 Oct 2017 18:29:17 +0200 +Subject: [PATCH 12/19] pci: Validate interfaces on base_class_init + +RH-Author: Eduardo Habkost +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Revieed-by: David Gibson +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 2fefa16cec5a719f5cbc26c0672dd2099cd2ed9b) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Auger Eric +RH-Acked-by: Dr. David Alan Gilbert + +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 +CC: Marcel Apfelbaum +CC: Michael S. Tsirkin +CC: Dr. David Alan Gilbert +CC: Juan Quintela +CC: Laurent Vivier +Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1538953 +Reported-by: Maxime Coquelin +Signed-off-by: Peter Xu +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 9d6b9db19c4b99ce5a1ad75b490c01edd2c2b0cf) +Signed-off-by: Peter Xu +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Reviewed-by: David Gibson +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 619f02aefc587e5e2821cd84b584eba199c97c9e) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Laszlo Ersek + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: Jose Ricardo Ziviani + +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 +[dwg: Added an explanatory comment] +Signed-off-by: David Gibson +(cherry picked from commit 03ee51d3548f5f553a3089f466483c1c6d5c666b) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 23 Nov 2017 16:14:21 +0100 +Subject: [PATCH 3/7] ppc: fix VTB migration + +RH-Author: Laurent Vivier +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 +RH-Acked-by: David Gibson +RH-Acked-by: Thomas Huth + +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 +Signed-off-by: David Gibson +(cherry picked from commit 6dd836f5d32b989e18c6dda655a26f4d73a52f6a) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Wed, 6 Dec 2017 02:57:59 +0100 +Subject: [PATCH 19/21] ppc: fix setting of compat mode + +RH-Author: Suraj Jitindar Singh +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +From: Greg Kurz + +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 +Signed-off-by: Greg Kurz +Signed-off-by: David Gibson +(cherry picked from commit e4f0c6bb1a9f72ad9e32c3171d36bae17ea1cd67) + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Wed, 15 Nov 2017 12:29:20 +0100 +Subject: [PATCH 06/30] q35: Fix mismerge + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Laszlo Ersek + +From: "Dr. David Alan Gilbert" + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 27 Nov 2017 16:19:58 +0100 +Subject: [PATCH 03/21] qcow2: Always execute preallocate() in a coroutine + +RH-Author: Max Reitz +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Fam Zheng +RH-Acked-by: John Snow + +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 +Message-id: 20171009215533.12530-3-mreitz@redhat.com +Cc: qemu-stable@nongnu.org +Reviewed-by: Eric Blake +Reviewed-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Max Reitz +(cherry picked from commit 572b07bea1d1a0f7726fd95c2613c76002a379bc) +Signed-off-by: Max Reitz +Signed-off-by: Miroslav Rezanina +--- + 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(¶ms); ++ } else { ++ Coroutine *co = qemu_coroutine_create(preallocate_co, ¶ms); ++ 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 +Date: Mon, 27 Nov 2017 16:19:57 +0100 +Subject: [PATCH 02/21] qcow2: Fix unaligned preallocated truncation + +RH-Author: Max Reitz +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Fam Zheng +RH-Acked-by: John Snow + +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 +Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1414049 +Signed-off-by: Max Reitz +Message-id: 20171009215533.12530-2-mreitz@redhat.com +Cc: qemu-stable@nongnu.org +Reviewed-by: Eric Blake +Reviewed-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Max Reitz +(cherry picked from commit e400ad1e1f0127b4fdabcb1c8de1e99be91788df) +Signed-off-by: Max Reitz +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Kevin Wolf + +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 +Reviewed-by: Alberto Garcia +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit f66afbe26f0c093d639610d70d16d7cc3183b652) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Kevin Wolf + +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 +Signed-off-by: Daniel P. Berrange +Signed-off-by: Kevin Wolf +(cherry picked from commit f06033295b51d4868c2b4921ad2287e8f55eb688) +Signed-off-by: Miroslav Rezanina + +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 . ++# ++ ++# 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Fam Zheng +RH-Acked-by: John Snow + +From: Pavel Butsykin + +Signed-off-by: Pavel Butsykin +Reviewed-by: Eric Blake +Reviewed-by: John Snow +Reviewed-by: Max Reitz +Message-id: 20170929121613.25997-2-pbutsykin@virtuozzo.com +Signed-off-by: Max Reitz +(cherry picked from commit 76a2a30a99c670e9ec1b4a5d976868059c6bc258) +Signed-off-by: Max Reitz +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +From: Michael Roth + +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 +Reviewed-by: Greg Kurz +Tested-by: Eric Auger +Reviewed-by: David Gibson +Message-Id: <20171016222315.407-4-mdroth@linux.vnet.ibm.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit f7b879e072ae6839b1b1d1312f48fa7f256397e2) +Signed-off-by: Serhii Popovych +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +From: Michael Roth + +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 +Cc: Paolo Bonzini +Signed-off-by: Michael Roth +Signed-off-by: Greg Kurz +Signed-off-by: Michael Roth +Tested-by: Eric Auger +Reviewed-by: David Gibson +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 + +(cherry picked from commit 04162f8f4bcf8c9ae2422def4357289b44208c8c) +Signed-off-by: Serhii Popovych +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +From: Fred Rolland + +Update doc with the usage of UUID for initiator name. + +Related-To: https://bugzilla.redhat.com/1006468 +Signed-off-by: Fred Rolland +Message-id: 20170823084830.30500-1-frolland@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit fb9429ddc124c46731185b2781804d4fd39b658c) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina + +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[:'] where is the name of the ++of 'iqn.2008-11.org.linux-kvm[:'] where is the UUID of the ++virtual machine. If the UUID is not specified qemu will use ++'iqn.2008-11.org.linux-kvm[:'] where 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 +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 +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 +RH-Acked-by: Peter Xu +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Eric Blake +Reviewed-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit a16efd53406bc8d89f87253ab10290f8d1b145a7) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 22 Jan 2018 03:07:16 +0100 +Subject: [PATCH 19/21] qemu-img: info: Force -U [downstream] + +RH-Author: Fam Zheng +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Fam Zheng +(cherry picked from commit f3adefb2cea1c63b7b198acaef5e40eb4b2d2d39) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +Message-id: +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +Signed-off-by: Jeff Cody +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit d975301dc8ae56fb3154348878e47a6211843c0b) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 . ++# ++ ++# 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Alberto Garcia + +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 +Reviewed-by: Max Reitz +Message-id: 071eb397118ed207c5a7f01d58766e415ee18d6a.1510339534.git.berto@igalia.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 0761562687e0d8135310a94b1d3e08376387c027) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 5 Dec 2017 10:26:10 +0100 +Subject: [PATCH 35/36] qemu-iotests: Test change-backing-file command + +RH-Author: Kevin Wolf +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 +RH-Acked-by: Max Reitz +RH-Acked-by: Jeffrey Cody + +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 +(cherry picked from commit 3fb23e07516aae13d1ba566740c1c81ae12184b7) +Signed-off-by: Miroslav Rezanina +--- + 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 . ++# ++ ++# 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 < +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Kevin Wolf +Reviewed-by: Eric Blake +Message-id: 20171206144550.22295-10-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 6dd64919ea36db9fd7e754ed394c25ced45ea39a) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 . ++# ++# Creator/Owner: Stefan Hajnoczi ++# ++# 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +This test case will prevent future regressions with savevm and +IOThreads. + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Eric Blake +Message-id: 20171207201320.19284-7-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 7a9dda0d7f9831c2432620dcfefdadbb7ae888dc) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 . ++# ++# Creator/Owner: Stefan Hajnoczi ++# ++# 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 +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 +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: John Snow + +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 +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit a2339699c3d35f19253b3b9b51f8a9b8e24f90eb) +Signed-off-by: Jeff Cody +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Stefan Hajnoczi + +From: Stefan Hajnoczi + +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 +Signed-off-by: Stefan Hajnoczi +Message-Id: <20170829122745.14309-3-stefanha@redhat.com> +Signed-off-by: Eric Blake +(cherry picked from commit 6e592fc92234a58c7156c385840633c17dedd24f) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Stefan Hajnoczi + +From: Stefan Hajnoczi + +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 +Signed-off-by: Stefan Hajnoczi +Message-Id: <20170829122745.14309-4-stefanha@redhat.com> +Signed-off-by: Eric Blake +(cherry picked from commit 02d2d860d25e439f0e88658c701668ab684568fb) +Signed-off-by: Miroslav Rezanina +--- + 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" <"$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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Wang Yong + +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 +Signed-off-by: Wang Yong +Signed-off-by: Wang Guang +Signed-off-by: Jason Wang +(cherry picked from commit 329163cbe64a615b4edf6c40f2fff8c79dbc8fb4) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: David Gibson + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow + +Signed-off-by: Fam Zheng +Signed-off-by: Kevin Wolf +(cherry picked from commit 1878eaff9bdeece4546d4f9587e6c75ab0b79b8b) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Sat, 2 Dec 2017 12:19:53 +0100 +Subject: [PATCH 27/36] qemu-pr-helper: miscellaneous fixes + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +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 +Signed-off-by: Paolo Bonzini +(cherry picked from commit 041a4acfdf4d9b2db60b10805aed94178dbf0463) +Signed-off-by: Miroslav Rezanina +--- + 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(¶mp, 0, sizeof(paramp)); + memcpy(¶mp.key, ¶m[0], 8); + memcpy(¶mp.sa_key, ¶m[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(¶m[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 +Date: Fri, 22 Dec 2017 11:08:41 +0100 +Subject: [PATCH 23/42] qemu.py: make VM() a context manager + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Eduardo Habkost +Message-id: 20170824072202.26818-2-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit d792bc3811f22a22a46c7d9a725fd29029f54095) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Peter Xu + +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 +CC: Markus Armbruster +CC: Paolo Bonzini +Suggested-by: Daniel P. Berrange +Signed-off-by: Peter Xu +Reviewed-by: Fam Zheng +Message-id: 20170928025958.1420-2-peterx@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 7c47c4ead75d0b733ee8f2f51fd1de0644cc1308) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 6 Oct 2017 16:04:07 +0200 +Subject: [PATCH 04/69] redhat: add CONFIG_RHV flag + +RH-Author: Laurent Vivier +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 9 Oct 2017 14:23:15 +0200 +Subject: [PATCH 06/69] redhat: define HW_COMPAT_RHEL7_4 + +RH-Author: Laurent Vivier +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Dr. David Alan Gilbert + +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 5 Oct 2017 08:16:15 +0200 +Subject: [PATCH 09/34] redhat: fix HW_COMPAT_RHEL7_3 + +RH-Author: Laurent Vivier +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Cornelia Huck + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Cornelia Huck + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Wed, 22 Nov 2017 10:43:30 +0100 +Subject: [PATCH 13/15] s390-ccw: Fix alignment for CCW1 + +RH-Author: Thomas Huth +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Miroslav Rezanina + +From: Farhan Ali + +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 +Reviewed-by: Halil Pasic +Reviewed-by: Eric Farman +Acked-by: Christian Borntraeger +Message-Id: <3ed8b810b6592daee6a775037ce21f850e40647d.1503667215.git.alifm@linux.vnet.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 3a1e4561ad63b303b092387ae006bd41468ece63) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jens Freimann +RH-Acked-by: Dr. David Alan Gilbert + +From: Christian Borntraeger + +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 +Message-Id: <20170921140834.14233-2-borntraeger@de.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 3f2d07b3b01ea61126b382633ab4006320923048) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 10 Nov 2017 14:49:04 +0100 +Subject: [PATCH 7/7] s390x/cpumodel: Disable unsupported CPU models + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Eduardo Habkost + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jens Freimann +RH-Acked-by: Dr. David Alan Gilbert + +From: Christian Borntraeger + +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 +Message-Id: <20170927072030.35737-2-borntraeger@de.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 9dacc908462693719d84ec594e839434959cf6f1) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 9 Oct 2017 15:50:33 +0200 +Subject: [PATCH 30/34] s390x/css: fix css migration compat handling + +RH-Author: Thomas Huth +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 +RH-Acked-by: Jens Freimann +RH-Acked-by: Laurent Vivier + +From: Halil Pasic + +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 +Reported-by: Thomas Huth +Message-Id: <20171004110109.16525-1-pasic@linux.vnet.ibm.com> +Tested-by: Christian Borntraeger +Acked-by: Christian Borntraeger +Signed-off-by: Cornelia Huck +(cherry picked from commit 489c909f097a387eb6913c89cf1851750397110c) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +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 +Message-Id: <1502861458-30270-1-git-send-email-thuth@redhat.com> +Reviewed-by: David Hildenbrand +Signed-off-by: Cornelia Huck +(cherry picked from commit 0d4fa4996fc5ee56ea7d072e272b8e69948460a5) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 23 Jan 2018 19:12:45 +0100 +Subject: [PATCH 3/8] s390x/kvm: Handle bpb feature + +RH-Author: Thomas Huth +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Christian Borntraeger + +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 +Message-Id: <20180118085628.40798-3-borntraeger@de.ibm.com> +Reviewed-by: Thomas Huth +Reviewed-by: David Hildenbrand +[CH: 'Branch Prediction Blocking' -> 'Branch prediction blocking'] +Signed-off-by: Cornelia Huck +(cherry picked from commit b073c87517d4d348c7bac0f0b35e8e83e6354d82) + +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 23 Jan 2018 19:12:46 +0100 +Subject: [PATCH 4/8] s390x/kvm: provide stfle.81 + +RH-Author: Thomas Huth +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Christian Borntraeger + +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 +Message-Id: <20180118085628.40798-4-borntraeger@de.ibm.com> +Reviewed-by: Halil Pasic +Reviewed-by: David Hildenbrand +Reviewed-by: Thomas Huth +Signed-off-by: Cornelia Huck +(cherry picked from commit 9f0d13f4f1de3cf9b70435cc4e87a301ee12471f) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 10 Nov 2017 14:49:03 +0100 +Subject: [PATCH 6/7] s390x: print CPU definitions in sorted order + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Eduardo Habkost + +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 +Signed-off-by: David Hildenbrand +Message-Id: <20170913132417.24384-16-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 99aa6bf29b87052d9603c5bf5c23d0db960f30ce) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +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 +Message-Id: <1503569328-22197-1-git-send-email-thuth@redhat.com> +Reviewed-by: Claudio Imbrenda +Reviewed-by: Halil Pasic +Signed-off-by: Cornelia Huck +(cherry picked from commit 574ee06de9c4fe63c90be90dc9c747fc9382bb2b) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Thomas Huth +Message-Id: <1503576029-24264-1-git-send-email-thuth@redhat.com> +Reviewed-by: Claudio Imbrenda +Reviewed-by: Halil Pasic +Signed-off-by: Cornelia Huck +(cherry picked from commit 3ea6d20e0baacb4a1211ed0ea57db14e2fc927ce) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +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 +Message-Id: <1507125199-22562-1-git-send-email-thuth@redhat.com> +Reviewed-by: Claudio Imbrenda +Reviewed-by: Farhan Ali +Acked-by: Halil Pasic +Signed-off-by: Cornelia Huck +(cherry picked from commit e6cb60bf158fe7ea4505d760fdbb7abe4dbf4362) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +From: Cornelia Huck + +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 +Acked-by: Christian Borntraeger +Signed-off-by: Cornelia Huck +(cherry picked from commit 7aa4d85d2962a072931657bee964113727ebf0c8) +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +Add a vmcoreinfo ELF note in the dump if vmcoreinfo device has the +memory location details. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit d23bfa91b7789534d16ede6cb7d925bfac3f3c4c) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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(" 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Jeffrey Cody + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Sat, 2 Dec 2017 12:19:41 +0100 +Subject: [PATCH 15/36] scsi: Improve scsi_sense_to_errno + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +From: Fam Zheng + +Tweak the errno mapping to return more accurate/appropriate values. + +Signed-off-by: Fam Zheng +Message-Id: <20170821141008.19383-3-famz@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 5efa3c04483d408a03ff5f018842501a2048a51b) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Sat, 2 Dec 2017 12:19:42 +0100 +Subject: [PATCH 16/36] scsi: Introduce scsi_sense_buf_to_errno + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +From: Fam Zheng + +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 +Message-Id: <20170821141008.19383-4-famz@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit a485b23425c755867d6caa6ab590be4e0473e35a) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Sat, 2 Dec 2017 12:19:40 +0100 +Subject: [PATCH 14/36] scsi: Refactor scsi sense interpreting code + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +From: Fam Zheng + +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 +Message-Id: <20170821141008.19383-2-famz@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2875135807771a0d07ba1c878c20b757ed7adffb) +Signed-off-by: Miroslav Rezanina +--- + 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 + 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 + #include +@@ -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 ++ * ++ * 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 ++ * ++ * 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +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 +(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 +--- + 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 < ++#include ++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 + #include + ++#ifdef CONFIG_MPATH ++#include ++#include ++#include ++#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(¶mp, 0, sizeof(paramp)); ++ memcpy(¶mp.key, ¶m[0], 8); ++ memcpy(¶mp.sa_key, ¶m[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(¶m[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, ¶m[i + 8], 8); ++ j += offsetof(struct transportid, n_port_name[8]); ++ i += 24; ++ break; ++ case 3: ++ case 0x43: ++ /* iSCSI transport. */ ++ len = lduw_be_p(¶m[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(¶m[i + 4], 0, len) == NULL) { ++ goto illegal_req; ++ } ++ memcpy(id->iscsi_name, ¶m[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, ¶m[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, ++ ¶mp, 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +This adds a concrete subclass of pr-manager that talks to qemu-pr-helper. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 9bad2a6b9d0aeb2dcf91a07652cc63bbb6e73141) +Signed-off-by: Miroslav Rezanina +--- + 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 ++ * ++ * 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 ++ ++#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 { ++ /* */ ++ 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 +Date: Wed, 17 Jan 2018 06:08:33 +0100 +Subject: [PATCH 03/21] scsi-block: Add share-rw option + +RH-Author: Fam Zheng +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 +RH-Acked-by: John Snow +RH-Acked-by: Jeffrey Cody + +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 +Message-Id: <20171205071928.30242-1-famz@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 07488549f884a658689370b9ef878dc50eced83e) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Sat, 2 Dec 2017 12:19:49 +0100 +Subject: [PATCH 23/36] scsi: build qemu-pr-helper + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +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 +(cherry picked from commit b855f8d175a0a26c9798cbc5962bb8c0d9538231) +Signed-off-by: Miroslav Rezanina +--- + 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 ++ * ++ * 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 ++ ++#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. ++ * ++ * Author: Paolo Bonzini ++ * ++ * 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 . ++ */ ++ ++#include "qemu/osdep.h" ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_LIBCAP ++#include ++#endif ++#include ++#include ++ ++#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=]][,events=][,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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +From: Hannes Reinecke + +According to SPC-3 INQUIRY and REQUEST SENSE should return GOOD +even on unsupported LUNS. + +Signed-off-by: Hannes Reinecke +Message-Id: <1503049022-14749-1-git-send-email-hare@suse.de> +Reported-by: Laszlo Ersek +Fixes: ded6ddc5a7b95217557fa360913d1213e12d4a6d +Cc: qemu-stable@nongnu.org +Signed-off-by: Hannes Reinecke +Signed-off-by: Paolo Bonzini +(cherry picked from commit b07fbce6349c7b84642e7ed56c7a1ac3c1caca61) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: John Snow +RH-Acked-by: Laszlo Ersek + +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 +Cc: qemu-stable@nongnu.org +Reported-by: Cong Li +Signed-off-by: Stefan Hajnoczi +Message-Id: <20180104142502.15175-1-stefanha@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 24355b79bdaf6ab12f7c610b032fc35ec045cd55) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: John Snow +RH-Acked-by: Stefan Hajnoczi + +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 +Message-Id: <20171004114008.14849-2-berrange@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 070f80095ad5b1143b50d2faffd2b1a84292e00d) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +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 +(cherry picked from commit 7c9e527659c67d4d7b41d9504f93d2d7ee482488) +Signed-off-by: Miroslav Rezanina +--- + 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 + #include +@@ -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 { ++ /* */ ++ Object parent; ++} PRManager; ++ ++/** ++ * PRManagerClass: ++ * @parent_class: the base class ++ * @run: callback invoked in thread pool context ++ */ ++typedef struct PRManagerClass { ++ /* */ ++ ObjectClass parent_class; ++ ++ /* */ ++ 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 ++ * ++ * This code is licensed under the LGPL. ++ * ++ */ ++ ++#include "qemu/osdep.h" ++#include ++ ++#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 +Date: Wed, 17 Jan 2018 06:08:34 +0100 +Subject: [PATCH 04/21] scsi-generic: Add share-rw option + +RH-Author: Fam Zheng +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 +RH-Acked-by: John Snow +RH-Acked-by: Jeffrey Cody + +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 +Message-Id: <20171205151553.7834-1-famz@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit d9bcd6f7f23a13ea627d8edb85c0706525da0b75) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +Move more knowledge of sense data format out of hw/scsi/scsi-bus.c +for reusability. + +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Paolo Bonzini +(cherry picked from commit a3760467c6b0ff5d1ff952fdc8cec69c65e19499) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Sat, 2 Dec 2017 12:19:46 +0100 +Subject: [PATCH 20/36] scsi: introduce sg_io_sense_from_errno + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +Move more knowledge of SG_IO out of hw/scsi/scsi-generic.c, for +reusability. + +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1ead6b4e242e59711976cdf2502dd5c7cd5d340a) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +Complete the transition by renaming this header, which was +shared by block/iscsi.c and the SCSI emulation code. + +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Paolo Bonzini +(cherry picked from commit 08e2c9f19ce791b3a0fb6adbf962ab4902ec5a7b) +Signed-off-by: Miroslav Rezanina +--- + 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 + #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 +-#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 . +-*/ +- +-/* +- * 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 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 . ++*/ ++ ++/* ++ * 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 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +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é +Signed-off-by: Paolo Bonzini +(cherry picked from commit e5b5728cd330f533e02e483af8973ad7ffccce8b) +Signed-off-by: Miroslav Rezanina +--- + 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 ++L: qemu-block@nongnu.org ++S: Supported ++F: include/scsi/* ++F: scsi/* ++ + Block Jobs + M: Jeff Cody + 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 + #include ++#undef SCSI_XFER_NONE ++QEMU_BUILD_BUG_ON((int)SCSI_XFER_NONE != (int)ISCSI_XFER_NONE); + + #ifdef __linux__ + #include +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 + #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 +- * +- * 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 ++#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 ++ * Paolo Bonzini ++ * ++ * 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 +- * +- * 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: John Snow + +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é +Signed-off-by: Paolo Bonzini +(cherry picked from commit 37b6045c455275af37f0433b05b0dad123e14daf) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: wexu@redhat.com +RH-Acked-by: Michael S. Tsirkin + +From: Samuel Thibault + +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 +Reviewed-by: Philippe Mathieu-Daudé +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Maydell +(cherry picked from commit 1201d308519f1e915866d7583d5136d03cc1d384) +Signed-off-by: Miroslav Rezanina +--- + 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" +Date: Thu, 2 Nov 2017 15:36:57 +0100 +Subject: [PATCH 4/9] snapshot/tests: Try loadvm twice + +RH-Author: Dr. David Alan Gilbert +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi + +From: "Dr. David Alan Gilbert" + +It's legal to loadvm twice, modify the existing save/loadvm test +to do it twice. + +Signed-off-by: Dr. David Alan Gilbert +Message-Id: <20170825141940.20740-3-dgilbert@redhat.com> +Reviewed-by: Peter Xu +Signed-off-by: Dr. David Alan Gilbert +(cherry picked from commit 04583a9e8fbeb2c5c0607327b853b306aef7465f) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Markus Armbruster + +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 +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Daniel P. Berrange +(cherry picked from commit 2d7ad7c05e762d5b10a57eba9af1bb6b41700854) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Laurent Vivier +Reviewed-by: Jose Ricardo Ziviani +Reviewed-by: Greg Kurz +(cherry picked from commit 8904e5a75005fe579c28806003892d8ae4a27dfa) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Laurent Vivier +Tested-by: Greg Kurz +Reviewed-by: Greg Kurz +(cherry picked from commit 1f20f2e0ee61d91abff4e86ed1cda1b5244647d3) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 19 Jan 2018 02:34:36 +0100 +Subject: [PATCH 08/21] spapr: Capabilities infrastructure + +RH-Author: David Gibson +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Greg Kurz +(cherry picked from commit 33face6b8981add8eba1f7cdaf4cf6cede415d2e) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Thomas Huth + +From: David Gibson + +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 + 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 + Reviewed-by: Greg Kurz + Reviewed-by: Laurent Vivier + +Signed-off-by: Serhii Popovych +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Serhii Popovych + +From: David Gibson + +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 +Reported-by: Satheesh Rajendran +Tested-by: Satheesh Rajendran +Reviewed-by: Alexey Kardashevskiy +(cherry picked from commit 51f84465dd985fc21589b2eac1f18658fc9783e9) +Signed-off-by: Miroslav Rezanina + +Conflicts: + hw/ppc/spapr_rtas.c + +Minor contextual conflict. + +Signed-off-by: David Gibson +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Greg Kurz +(cherry picked from commit 2d1fb9bc8e6e78931d8e1bfeb0ed7a4d223b0480) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Greg Kurz +(cherry picked from commit 2938664286499c0c30d6e455a7e2e5d3e6c3f63d) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Thomas Huth +Reviewed-by: Greg Kurz +(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 +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 19 Jan 2018 02:34:42 +0100 +Subject: [PATCH 14/21] spapr: Remove unnecessary 'options' field from + sPAPRCapabilityInfo + +RH-Author: David Gibson +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +(cherry picked from commit 895d5cd620d358c2623c639a150d9320d581b4f8) + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1523414 + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Greg Kurz +(cherry picked from commit ee76a09fc72cfbfab2bb5529320ef7e460adffd8) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +Date: Fri, 19 Jan 2018 02:34:38 +0100 +Subject: [PATCH 10/21] spapr: Validate capabilities on migration + +RH-Author: David Gibson +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Greg Kurz +(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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Greg Kurz + +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 +Signed-off-by: Greg Kurz +Reviewed-by: Suraj Jitindar Singh +Signed-off-by: David Gibson +(cherry picked from commit fa86f59234919b479b7e8da6b0dc2dad894a5eac) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 19 Oct 2017 15:28:13 +0200 +Subject: [PATCH 68/69] spapr: disable cpu hot-remove + +RH-Author: Igor Mammedov +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: David Gibson + +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 +--- +v2: + - use CONFIG_RHV to not break RHEV build + +Thanks to Laszlo for hints to use CONFIG_RHV! + +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Wed, 31 Jan 2018 10:44:31 +0100 +Subject: [PATCH 8/8] spapr: disable memory hotplug + +RH-Author: Igor Mammedov +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Dr. David Alan Gilbert + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Eduardo Habkost + +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 +Signed-off-by: David Gibson +(cherry picked from commit 1481fe5fcfeb7fcf3c1ebb9d8c0432e3e0188ccf) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Cédric Le Goater + +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 +Signed-off-by: David Gibson +(cherry picked from commit 30bf9ed1684da582e47ae004f8f3cf14fd6f39dd) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +From: Greg Kurz + +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 +Signed-off-by: David Gibson +(cherry picked from commit 9012a53f067a78022947e18050b145c34a3dc599) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina + +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 +Date: Mon, 27 Nov 2017 09:03:20 +0100 +Subject: [PATCH 6/7] spapr: reset DRCs after devices + +RH-Author: Laurent Vivier +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Thomas Huth + +From: Greg Kurz + +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 +Signed-off-by: Greg Kurz +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Michael Roth +Signed-off-by: David Gibson +(cherry picked from commit 82512483940c756e2db1bd67ea91b02bc29c5e01) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Serhii Popovych + +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 +Reviewed-by: Greg Kurz +Signed-off-by: David Gibson +(cherry picked from commit 4ad64cbd0c3f9df15be5f7d1c920285551e802ca) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Bandan Das +RH-Acked-by: Igor Mammedov + +From: Brijesh Singh + +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 +Message-Id: <20170815170051.127257-1-brijesh.singh@amd.com> +Reviewed-by: Eduardo Habkost +Signed-off-by: Eduardo Habkost +(cherry picked from commit 2e2efc7dbe2b0adc1200b5aa286cdbed729f6751) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina + +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 . +--- + 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 +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 +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 +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Miroslav Rezanina + +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 +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +(cherry picked from commit 1ed9c8af501f8d1bdf5a8725a038527be059f54d) +Signed-off-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina + +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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Miroslav Rezanina + +From: David Gibson + +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 +Reviewed-by: Laurent Vivier +Reviewed-by: Greg Kurz +Reviewed-by: Jose Ricardo Ziviani +(cherry picked from commit abbc124753896f72e3715813ea20dd1924202ff0) +Signed-off-by: Miroslav Rezanina + +Conflicts: + hw/ppc/spapr.c + +Contextual conflict. + +Signed-off-by: David Gibson +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Signed-off-by: David Gibson +(cherry picked from commit e07cc1929515cfb808b5c2fcc60c079e6be110cf) + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Signed-off-by: David Gibson +(cherry picked from commit ee4d9ecc3675af1e68a9c00a8b338641898d613e) + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Signed-off-by: David Gibson +(cherry picked from commit 7abd43baec0649002d32bbb1380e936bec6f5867) + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Sam Bobroff + +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 + +[1] See http://www.spinics.net/lists/kvm-ppc/msg13057.html +Signed-off-by: David Gibson + +(cherry picked from commit e05fba5004676cd0fa7c47b623cb0a14ad1feed8) + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Cédric Le Goater + +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 +Signed-off-by: David Gibson +(cherry picked from commit 2a83f9976efa9a85e8ceb9d1035a68f25c321334) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Reviewed-by: David Gibson +[dwg: Correct some compile errors due to name change in final kernel + patch version] +Signed-off-by: David Gibson + +(cherry picked from commit 8acc2ae5e91681ceda3ff4cf946ebf163f6012e9) +Signed-off-by: Miroslav Rezanina + +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 +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Signed-off-by: David Gibson +(cherry picked from commit c59704b254734182c3202e0c261589ea2ccf485e) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Signed-off-by: David Gibson +(cherry picked from commit 1f63ebaa91f73f469c8f107dbd266cabdbea3a40) + +Conflicts: None + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +Add new tristate cap cap-sbbc to represent the speculation barrier +bounds checking capability. + +Signed-off-by: Suraj Jitindar Singh +Reviewed-by: David Gibson +Signed-off-by: David Gibson +(cherry picked from commit 09114fd8179977e4157b36aab2e3d68eaf08adca) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +Add new tristate cap cap-cfpc to represent the cache flush on privilege +change capability. + +Signed-off-by: Suraj Jitindar Singh +Reviewed-by: David Gibson +Signed-off-by: David Gibson +(cherry picked from commit 8f38eaf8f9dd194c9961cf76c675724930ce4570) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +Add new tristate cap cap-ibs to represent the indirect branch +serialisation capability. + +Signed-off-by: Suraj Jitindar Singh +Reviewed-by: David Gibson +Signed-off-by: David Gibson +(cherry picked from commit 4be8d4e7d935fc8919d61f53a0f0fb7230052bb3) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Suraj Jitindar Singh + +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 +Signed-off-by: David Gibson +(cherry picked from commit 6898aed77f4636c3e77af9c12631f583f22cb5db) + +Conflicts: none + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050 + +Signed-off-by: Suraj Jitindar Singh +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 17 Nov 2017 11:19:04 +0100 +Subject: [PATCH 05/15] throttle-groups: drain before detaching ThrottleState + +RH-Author: Stefan Hajnoczi +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +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 +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Alberto Garcia +Message-id: 20171110151934.16883-1-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit dc868fb03b9b829ed9d2ecdae0fcc12f3fe19b4f) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +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 +Message-id: 20171116112150.27607-1-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 341e0b5658681f46680024cdbfc998717d85cc35) +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git e55fe3ccccc1efb8f20c99728c8863424ae9ee4a + +commit e55fe3ccccc1efb8f20c99728c8863424ae9ee4a +Author: Stefan Raspl +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 + Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 67fbcd62f54d4503e3dc63b68af1c6757b74e050 + +commit 67fbcd62f54d4503e3dc63b68af1c6757b74e050 +Author: Lin Ma +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 4443084fa0cf85f91d357c8917b90504b784d925 + +Convertion of documentation (for man page generation) to texi. + +commit 4443084fa0cf85f91d357c8917b90504b784d925 +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 9f114a03c6854f49065dd036c17e1b4bb947f842 + +Convertion of documentation (for man page generation) to texi. + +commit 9f114a03c6854f49065dd036c17e1b4bb947f842 +Author: Stefan Raspl +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 + Acked-by: Janosch Frank + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git ab7ef193fab628fc5da6fd4f4672ffd0d1bb53df + +Convertion of documentation (for man page generation) to texi. + +commit ab7ef193fab628fc5da6fd4f4672ffd0d1bb53df +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 5c1954d25d1b9e857be2a4c77437312075875589 + +Convertion of documentation (for man page generation) to texi. + +commit 5c1954d25d1b9e857be2a4c77437312075875589 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 1fdea7b2893045e5258a13937c3d78c425fd7aa0 + +Convertion of documentation (for man page generation) to texi. + +commit 1fdea7b2893045e5258a13937c3d78c425fd7aa0 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 6667ae8f395099257afca0963838d2dc50a18da7 + +Convertion of documentation (for man page generation) to texi. + +commit 6667ae8f395099257afca0963838d2dc50a18da7 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 64eefad2cdbf2d7c76e24d0b67e19efdbe1c97a9 + +Convertion of documentation (for man page generation) to texi. + +commit 64eefad2cdbf2d7c76e24d0b67e19efdbe1c97a9 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git f9ff1087354e5e063b96a291360a8de84bea0bed + +Convertion of documentation (for man page generation) to texi. + +commit f9ff1087354e5e063b96a291360a8de84bea0bed +Author: Stefan Raspl +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 + Reviewed-by: Janosch Frank + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 9fc0adfc427a5e3f95f8db8dafabe1eaa3720f4a + +commit 9fc0adfc427a5e3f95f8db8dafabe1eaa3720f4a +Author: Stefan Raspl +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 + Reviewed-by: Janosch Frank + Reviewed-by: Sascha Silbe + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 61f381bb7e1a8e9250aa32b3963a7a5c4b92cbf5 + +commit 61f381bb7e1a8e9250aa32b3963a7a5c4b92cbf5 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 865279c53ca9d88718d974bb014b2c6ce259ac75 + +commit 865279c53ca9d88718d974bb014b2c6ce259ac75 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git a24e85f6a69f09a9d09a86110a6bb168c60610ef + +commit a24e85f6a69f09a9d09a86110a6bb168c60610ef +Author: Stefan Raspl +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 + Reviewed-By: Janosch Frank + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 5725393764a342b6a5420fdd10184984ca08b5f6 + +commit 5725393764a342b6a5420fdd10184984ca08b5f6 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 72187dfa8e2686b748ad7485d0ca59ba993ba526 + +commit 72187dfa8e2686b748ad7485d0ca59ba993ba526 +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 1eaa2f9022d55a8d7249c42def8dc4b0d682e142 + +Convertion of documentation (for man page generation) to texi. + +commit 1eaa2f9022d55a8d7249c42def8dc4b0d682e142 +Author: Stefan Raspl +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 + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi + +commit 19e8e54f4309eaa438237aa1973fe40c331903d4 (HEAD) +Author: Stefan Raspl +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 + Tested-by: Christian Borntraeger + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 124c2fc9fdf5fb1d9cea4707d7e5471e317ba3bf + +commit 124c2fc9fdf5fb1d9cea4707d7e5471e317ba3bf +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git e0ba38765c1d1d670246d6f6c518594aa8e62587 + +commit e0ba38765c1d1d670246d6f6c518594aa8e62587 +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git a183606937489ab5ada2215aa8211374a6b26bd3 + +commit a183606937489ab5ada2215aa8211374a6b26bd3 +Author: Stefan Raspl +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 + Based-on-text-by: Janosch Frank + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 17 Oct 2017 19:15:44 +0200 +Subject: [PATCH 39/69] tools/kvm_stat: fix typo + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 773bffeeb2f1fca7739516d0a5a814dd14a5cc83 + +commit 773bffeeb2f1fca7739516d0a5a814dd14a5cc83 +Author: Stefan Raspl +Date: Wed Jun 7 21:08:25 2017 +0200 + + tools/kvm_stat: fix typo + + Signed-off-by: Stefan Raspl + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 81468d73b6eb0ed251e7c77f2cc44c0f4edb4d36 + +commit 81468d73b6eb0ed251e7c77f2cc44c0f4edb4d36 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 692c7f6deb553dde2531102cd10ac17ab61438e4 + +commit 692c7f6deb553dde2531102cd10ac17ab61438e4 +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git dadf1e7839243474b691ca4258bfd2a59e628a5e + +commit dadf1e7839243474b691ca4258bfd2a59e628a5e +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git a0b4e6a0325e325d91901342dd436d917da0ddd6 + +commit a0b4e6a0325e325d91901342dd436d917da0ddd6 +Author: Stefan Raspl +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 + Reviewed-By: Sascha Silbe + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git f6d753102a2469ae4ce08ef3e34d170ec583fb50 + +commit f6d753102a2469ae4ce08ef3e34d170ec583fb50 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 099a2dfc674e3333bd4ff5e5b106ccd788aa46d7 + +commit 099a2dfc674e3333bd4ff5e5b106ccd788aa46d7 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 0152c20f0400498774ae56067f8076cef312abc7 + +commit 0152c20f0400498774ae56067f8076cef312abc7 +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 184b2d23b057b35fba7fd4049962a897ef0e3f9d + +commit 184b2d23b057b35fba7fd4049962a897ef0e3f9d +Author: Stefan Raspl +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 + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 17 Oct 2017 19:15:50 +0200 +Subject: [PATCH 45/69] tools/kvm_stat: remove extra statement + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 5e3823a49c50d70cc6b92808c262a43cf3505f3c + +commit 5e3823a49c50d70cc6b92808c262a43cf3505f3c +Author: Stefan Raspl +Date: Wed Jun 7 21:08:31 2017 +0200 + + tools/kvm_stat: remove extra statement + + Signed-off-by: Stefan Raspl + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git be03ea3b77387db36617d71d60ee182a866fb9cd + +commit be03ea3b77387db36617d71d60ee182a866fb9cd +Author: Stefan Raspl +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 + Reviewed-by: Janosch Frank + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 645c1728a9d33d78028d93a2ed770f51df0a92c6 + +commit 645c1728a9d33d78028d93a2ed770f51df0a92c6 +Author: Stefan Raspl +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 + Reviewed-by: Marc Hartmayer + Signed-off-by: Radim Krčmář + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 17 Oct 2017 19:15:47 +0200 +Subject: [PATCH 42/69] tools/kvm_stat: remove unnecessary header redraws + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 2da9d4aaa7348fc13374d7398c9c7027b0a9e2cb + +commit 2da9d4aaa7348fc13374d7398c9c7027b0a9e2cb +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 17 Oct 2017 19:15:49 +0200 +Subject: [PATCH 44/69] tools/kvm_stat: removed unused function + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 42a947b77b00da8fb1c9b1350eaa85fd3d53bacb + +commit 42a947b77b00da8fb1c9b1350eaa85fd3d53bacb +Author: Stefan Raspl +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 + Reviewed-by: Janosch Frank + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 38e89c37a1e05e6e16af582b980534abda29a4d9 + +commit 38e89c37a1e05e6e16af582b980534abda29a4d9 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 62d1b6cc24d0dedde89e6a39aae1711270aee1c9 + +commit 62d1b6cc24d0dedde89e6a39aae1711270aee1c9 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 17 Oct 2017 19:15:51 +0200 +Subject: [PATCH 46/69] tools/kvm_stat: simplify initializers + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git c469117df05955901d2950b6130770e526b1dbf4 + +commit c469117df05955901d2950b6130770e526b1dbf4 +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Tue, 17 Oct 2017 19:15:48 +0200 +Subject: [PATCH 43/69] tools/kvm_stat: simplify line print logic + +RH-Author: David Hildenbrand +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git 5a7d11f8dc59ddb36e89dca42a2526ea25914def + +commit 5a7d11f8dc59ddb36e89dca42a2526ea25914def +Author: Stefan Raspl +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +Upstream-status: linux.git efcb521943a8df5210f16f312037c2edc3e1449f + +commit efcb521943a8df5210f16f312037c2edc3e1449f +Author: Lin Ma +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 + Signed-off-by: Paolo Bonzini + +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Miroslav Rezanina + +From: Brandon Carpenter + +Also set saved handle to zero when removing without adding a new watch. + +Signed-off-by: Brandon Carpenter +Reviewed-by: Paolo Bonzini +Reviewed-by: Daniel P. Berrange +(cherry picked from commit a75d6f07613af7ec5b016b31b117436e32ce7a5f) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +The VNC client throttling is quite subtle so will benefit from having trace +points available for live debugging. + +Signed-off-by: Daniel P. Berrange +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-13-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 6aa22a29187e1908f5db738d27c64a9efc8d0bfa) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +Trace anything related to authentication in the VNC protocol +handshake + +Signed-off-by: Daniel P. Berrange +Message-id: 20170921121528.23935-3-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 7364dbdabb7824d5bde1e341bb6d928282f01c83) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +Trace anything which opens/closes/wraps a QIOChannel in the +VNC server. + +Signed-off-by: Daniel P. Berrange +Message-id: 20170921121528.23935-2-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit ad6374c43e572e6e53020a97e72e9ea525b08334) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-5-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 3541b08475d51bddf8aded36576a0ff5a547a978) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Message-id: 20180118155254.17053-1-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 4c956bd81e2e16afd19d38d1fdeba6d9faa8a1ae) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +In this previous commit: + + commit 8f61f1c5a6bc06438a1172efa80bc7606594fa07 + Author: Daniel P. Berrange + 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 +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Eric Blake +Reviewed-by: Laszlo Ersek +Message-id: 20180201155841.27509-1-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 627ebec208a8809818589e17f4fce55a59420ad2) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-8-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 728a7ac95484a7ba5e624ccbac4c1326571576b0) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 + 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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-10-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit e2b72cb6e0443d90d7ab037858cb6834b6cca852) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 + 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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-11-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit ada8d2e4369ea49677d8672ac81bce73eefd5b54) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Jeffrey Cody +RH-Acked-by: Laszlo Ersek + +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 +Reviewed-by: Marc-André Lureau +Message-id: 20171109105154.29414-1-kraxel@redhat.com +(cherry picked from commit 777c5f1e436d334a57b650b6951c13d8d2799df0) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-7-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit fef1bbadfb2c3027208eb3d14b43e1bdb51166ca) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-14-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 30b80fd5269257f55203b7072c505b4ebaab5115) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-12-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit f887cf165db20f405cb8805c716bd363aaadf815) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-9-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 0bad834228b9ee63e4239108d02dcb94568254d0) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-4-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit b939eb89b6f320544a9328fa908d881d0024c1ee) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +There is only one caller of vnc_update_client and that always passes false +for the 'sync' parameter. + +Signed-off-by: Daniel P. Berrange +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-2-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 6af998db05aec9af95a06f84ad94f1b96785e667) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +A previous commit: + + commit 5a8be0f73d6f60ff08746377eb09ca459f39deab + Author: Gerd Hoffmann + 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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-3-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit c53df961617736f94731d94b62c2954c261d2bae) +Signed-off-by: Miroslav Rezanina +--- + 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" +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +From: "Daniel P. Berrange" + +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 +Reviewed-by: Darren Kenny +Reviewed-by: Marc-André Lureau +Message-id: 20171218191228.31018-6-berrange@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 8f61f1c5a6bc06438a1172efa80bc7606594fa07) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 9 Oct 2017 12:32:37 +0200 +Subject: [PATCH 18/34] usb: drop HOST_USB + +RH-Author: Thomas Huth +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +From: Gerd Hoffmann + +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 +Reviewed-by: Fam Zheng +Reviewed-by: Thomas Huth +Message-id: 20170908111217.21985-2-kraxel@redhat.com +(cherry picked from commit 4e5ee5b21c84fe3023a64b5cc2e12a52ab0597c1) +Signed-off-by: Miroslav Rezanina + +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 +Date: Mon, 9 Oct 2017 12:32:40 +0200 +Subject: [PATCH 21/34] usb: fix host-stub.c build race + +RH-Author: Thomas Huth +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +From: Gerd Hoffmann + +Suggested-by: Thomas Huth +Signed-off-by: Gerd Hoffmann +Reviewed-by: Thomas Huth +Message-id: 20171004125210.7817-1-kraxel@redhat.com +(cherry picked from commit eea6ae20379dca837631d603c3bed03e5128189f) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 9 Oct 2017 12:32:39 +0200 +Subject: [PATCH 20/34] usb: fix libusb config variable name. + +RH-Author: Thomas Huth +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +From: Gerd Hoffmann + +Cc: Jan Kiszka +Fixes: 4e5ee5b21c84fe3023a64b5cc2e12a52ab0597c1 +Signed-off-by: Gerd Hoffmann +Tested-by: Jan Kiszka +Message-id: 20170926063820.30773-1-kraxel@redhat.com +(cherry picked from commit 275d477a1adb084a47859507b20b05e7d65f8e8d) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +From: Gerd Hoffmann + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Fam Zheng +Reviewed-by: Thomas Huth +Tested-by: Thomas Huth +Message-id: 20170908111217.21985-3-kraxel@redhat.com +(cherry picked from commit 2041649f0b04f61869589571ddf5ecd4f0695ea2) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 29 Jan 2018 05:38:19 +0100 +Subject: [PATCH 7/8] usb-storage: Fix share-rw option parsing + +RH-Author: Fam Zheng +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 +RH-Acked-by: John Snow +RH-Acked-by: Jeffrey Cody + +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 +Reviewed-by: Darren Kenny +Message-id: 20180117005222.4781-1-famz@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 395b95395934785ca86baafd314d0c31b307d16d) +Signed-off-by: Fam Zheng +Signed-off-by: Miroslav Rezanina + +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 +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 +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 +RH-Acked-by: John Snow +RH-Acked-by: Laurent Vivier + +From: Sergio Lopez + +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 +Message-id: 20171108063447.2842-1-slp@redhat.com +Signed-off-by: Stefan Hajnoczi + +(cherry picked from commit ef6dada8b44e1e7c4bec5c1115903af9af415b50) + +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Thu, 14 Dec 2017 16:30:06 +0100 +Subject: [PATCH 6/6] vfio: Fix vfio-kvm group registration + +RH-Author: Alex Williamson +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 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina + +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 +Reviewed-by: Peter Xu +Tested-by: Peter Xu +Reviewed-by: Eric Auger +Tested-by: Eric Auger +Signed-off-by: Alex Williamson +(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 +--- + 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 +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 +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 +RH-Acked-by: Auger Eric +RH-Acked-by: Marcel Apfelbaum + +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 +(cherry picked from commit db32d0f43839627f54a1a7f8eee17baa770f52d2) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Miroslav Rezanina + +From: linzhecheng + +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 +Message-id: 20180111132724.13744-1-linzhecheng@huawei.com +Fixes: CVE-2018-5683 +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 191f59dc17396bb5a8da50f8c59b6e0a430711a4) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 20 Oct 2017 07:19:23 +0200 +Subject: [PATCH 01/19] vga: drop line_offset variable + +RH-Author: Gerd Hoffmann +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 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Laurent Vivier + +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 362f811793ff6cb4d209ab61d76cc4f841bb5e46) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +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 +Reported-by: David Buchanan +Signed-off-by: Gerd Hoffmann +Message-id: 20170828123307.15392-1-kraxel@redhat.com +(cherry picked from commit e65294157d4b69393b3f819c99f4f647452b48e3) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Fri, 20 Oct 2017 07:19:24 +0200 +Subject: [PATCH 02/19] vga: handle cirrus vbe mode wraparounds. + +RH-Author: Gerd Hoffmann +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Dr. David Alan Gilbert + +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 +Reported-by: David Buchanan +Signed-off-by: Gerd Hoffmann +Message-id: 20171010141323.14049-3-kraxel@redhat.com +(cherry picked from commit 28f77de26a4f9995458ddeb9d34bb06c0193bdc9) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Miroslav Rezanina + +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 +Reported-by: David Buchanan +Signed-off-by: Gerd Hoffmann +Message-id: 20170828122906.18993-1-kraxel@redhat.com +(cherry picked from commit 3d90c6254863693a6b13d918d2b8682e08bbc681) +Signed-off-by: Miroslav Rezanina +--- + 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 +Date: Mon, 11 Sep 2017 20:43:08 +0200 +Subject: [PATCH 01/34] vhost: Release memory references on cleanup + +RH-Author: Alex Williamson +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Auger Eric + +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 +Cc: Paolo Bonzini +Cc: qemu-stable@nongnu.org # v1.6.0+ +Signed-off-by: Alex Williamson +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit ee4c112846a0f2ac4fe5601918b0a2642ac8e2ed) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Xiao Wang + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 2ae39a113af311cb56a0c35b7f212dafcef15303) +Signed-off-by: Maxime Coquelin +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Xiao Wang + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 2d4ba6cc741df15df6fbb4feaa706a02e103083a) +Signed-off-by: Maxime Coquelin +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Marc-André Lureau + +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 +Signed-off-by: Peter Xu +Message-id: 20180131040401.3550-1-peterx@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 34e304e97576a9e17680c868c00ff524a981007b) +Signed-off-by: Peter Xu +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Thomas Huth + +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 +Reviewed-by: Marc-André Lureau +Message-id: 20170906142058.2460-1-kraxel@redhat.com +(cherry picked from commit 79d16c21a565927943486b26789caa62413ff371) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Pankaj Gupta +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 +Cc: Paolo Bonzini +Cc: Stefan Hajnoczi +Cc: Michael S. Tsirkin +Cc: qemu-stable@nongnu.org +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Jason Wang +(cherry picked from commit 70e53e6e4da3db4b2c31981191753a7e974936d0) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Laurent Vivier + +From: Alexey Kardashevskiy + +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit a93c8d828af186d9a6a1c915a1be8ba22fb89849) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + 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 ®->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 +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 +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 +RH-Acked-by: Igor Mammedov +RH-Acked-by: Paolo Bonzini + +Delete all user-creatable objects in /objects when exiting QEMU, so they +can perform cleanup actions. + +Signed-off-by: Eduardo Habkost +Message-Id: <20170824192315.5897-2-ehabkost@redhat.com> +Acked-by: Philippe Mathieu-Daudé +Tested-by: Zack Cornelius +Signed-off-by: Eduardo Habkost +(cherry picked from commit 9d5139e543e8579aacd324193680c64fd1463d89) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Seeteena Thoufeek + +Signed-off-by: Eduardo Habkost + +---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 +Signed-off-by: Seeteena Thoufeek +Message-Id: <1504511031-26834-1-git-send-email-s1seetee@linux.vnet.ibm.com> +Reviewed-by: Philippe Mathieu-Daudé +(cherry picked from commit c0dd10991903c552811d8cbe9231055b1b3a7ebd) + +Testing: Run qemu-kvm with "-smp maxcpus=-1". +Signed-off-by: Sam Bobroff +Signed-off-by: Miroslav Rezanina +--- + 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?= +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 +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 +RH-Acked-by: Andrew Jones +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Marc-André Lureau +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin + +(cherry picked from commit b948bb55dac527ae6b0c5e6dc69d00866a3a6fee) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: David Gibson +RH-Acked-by: Miroslav Rezanina + +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 +Message-Id: <1502892528-22618-1-git-send-email-thuth@redhat.com> +Reviewed-by: David Hildenbrand +Signed-off-by: Cornelia Huck +(cherry picked from commit 84ebd3e8c7d4fe955b359b9aac84395907b0412e) +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Signed-off-by: Eduardo Habkost +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 6d7023763ec8cc7999468769a0c6bf1335dc3bf4) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 +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 +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 +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Laurent Vivier + +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 +Reviewed-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 8b3d26342c4aa171e759e6392fe3b742759d4963) +Signed-off-by: Eduardo Habkost +Signed-off-by: Miroslav Rezanina +--- + 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - rhev-2.9.0-1.el7 +- Rebase to QEMU 2.9.0 + +* Wed Mar 08 2017 Miroslav Rezanina - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 ) +- 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - rhev-2.2.0-1.el7 +- rebase to qemu 2.2.0 + +* Thu Jan 08 2015 Miroslav Rezanina - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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) - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 2.0.0-1.el7ev +- Rebase to qemu 2.0.0 + +* Wed Apr 02 2014 Miroslav Rezanina - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 10:1.5.3-42 +- Mass rebuild 2014-01-24 + +* Wed Jan 22 2014 Miroslav Rezanina - 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 - 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 - 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 ) + +* Fri Jan 17 2014 Miroslav Rezanina - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 10:1.5.3-31 +- Mass rebuild 2013-12-27 + +* Wed Dec 18 2013 Michal Novotny - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - qemu-kvm-1.5.3-6.el7 +- re-enable spice +- Related: #979953 + +* Mon Sep 23 2013 Paolo Bonzini - qemu-kvm-1.5.3-5.el7 +- temporarily disable spice until libiscsi rebase is complete +- Related: #979953 + +* Thu Sep 19 2013 Michal Novotny - 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 - qemu-kvm-1.5.3-3.el7 +- Fix rhel/rhev split + +* Thu Aug 29 2013 Miroslav Rezanina - 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 - 10:1.5.3-1 +- Rebase to qemu 1.5.3 + +* Tue Aug 20 2013 Miroslav Rezanina - 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 - 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 - 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 - 10:1.5.2-1 +- Rebase to 1.5.2 + +* Tue Jul 02 2013 Miroslav Rezanina - 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 - 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 - 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 - 3:1.5.0-1 +- Rebase to 1.5.0 + +* Tue Apr 23 2013 Miroslav Rezanina - 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 - 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 - 3:1.4.0-2.1 +- Rebuild for cyrus-sasl + +* Fri Apr 05 2013 Miroslav Rezanina - 3:1.4.0-2 +- Synchronization with Fedora 19 package version 2:1.4.0-8 + +* Wed Apr 03 2013 Daniel Mach - 3:1.4.0-1.1 +- Rebuild for libseccomp + +* Thu Mar 07 2013 Miroslav Rezanina - 3:1.4.0-1 +- Rebase to 1.4.0 + +* Mon Feb 25 2013 Michal Novotny - 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 - 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 - 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 - 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 - 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 - 2:1.3.0-2 +- Rename qemu to qemu-kvm +- Move qemu-kvm to libexecdir + +* Fri Dec 07 2012 Cole Robinson - 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 - 2:1.2.0-25 +* Merge libcacard into qemu, since they both use the same sources now. + +* Thu Nov 22 2012 Paolo Bonzini - 2:1.2.0-24 +- Move vscclient to qemu-common, qemu-nbd to qemu-img + +* Tue Nov 20 2012 Alon Levy - 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 - 2:1.2.0-23 +- Backport --with separate_kvm support from EPEL branch + +* Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-22 +- Fix previous commit + +* Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-21 +- Backport commit 38f419f (configure: Fix CONFIG_QEMU_HELPERDIR generation, + 2012-10-17) + +* Thu Nov 15 2012 Paolo Bonzini - 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 - 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 - 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 - 2:1.2.0-17 +- Pull patches queued for qemu 1.2.1 + +* Fri Oct 19 2012 Paolo Bonzini - 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 - 2:1.2.0-15 +- fix build on non-kvm arches like s390(x) + +* Wed Oct 17 2012 Paolo Bonzini - 2:1.2.0-14 +- Change SLOF Requires for the new version number + +* Thu Oct 11 2012 Paolo Bonzini - 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 - 2:1.2.0-12 +- Call udevadm on post, fixing bug 860658 + +* Fri Sep 28 2012 Hans de Goede - 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 - 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 - 2:1.2.0-9 +- Sync USB and Spice patchsets with upstream + +* Sun Sep 16 2012 Richard W.M. Jones - 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 - 2:1.2.0-4 +- add versioned dependency from qemu-system-ppc to SLOF (BZ#855252) + +* Wed Sep 12 2012 Richard W.M. Jones - 2:1.2.0-3 +- Fix RHBZ#853408 which causes libguestfs failure. + +* Sat Sep 8 2012 Hans de Goede - 2:1.2.0-2 +- Fix crash on (seamless) migration +- Sync usbredir live migration patches with upstream + +* Fri Sep 7 2012 Hans de Goede - 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 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 1.2.0-0.4.rc1 +- Update to 1.2.0-rc1 + +* Mon Aug 20 2012 Richard W.M. Jones - 1.2-0.3.20120806git3e430569 +- Backport Bonzini's vhost-net fix (RHBZ#848400). + +* Tue Aug 14 2012 Cole Robinson - 1.2-0.2.20120806git3e430569 +- Bump release number, previous build forgot but the dist bump helped us out + +* Tue Aug 14 2012 Cole Robinson - 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 - 1.2-0.1.20120806git3e430569.fc18 +- Update to git snapshot + +* Sun Jul 29 2012 Cole Robinson - 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 - 2:1.1.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 10 2012 Richard W.M. Jones - 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 - 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 - 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 - 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 - 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 - 2:1.0-17 +- Fix install failure due to set -e (rhbz #815272) + +* Mon Apr 23 2012 Paolo Bonzini - 2:1.0-16 +- Fix kvm.modules to exit successfully on non-KVM capable systems (rhbz #814932) + +* Thu Apr 19 2012 Hans de Goede - 2:1.0-15 +- Add a couple of backported QXL/Spice bugfixes +- Add spice volume control patches + +* Fri Apr 6 2012 Paolo Bonzini - 2:1.0-12 +- Add back PPC and SPARC user emulators +- Update binfmt rules from upstream + +* Mon Apr 2 2012 Hans de Goede - 2:1.0-11 +- Some more USB bugfixes from upstream + +* Thu Mar 29 2012 Eduardo Habkost - 2:1.0-12 +- Fix ExclusiveArch mistake that disabled all non-x86_64 builds on Fedora + +* Wed Mar 28 2012 Eduardo Habkost - 2:1.0-11 +- Use --with variables for build-time settings + +* Wed Mar 28 2012 Daniel P. Berrange - 2:1.0-10 +- Switch to use iPXE for netboot ROMs + +* Thu Mar 22 2012 Daniel P. Berrange - 2:1.0-9 +- Remove O_NOATIME for 9p filesystems + +* Mon Mar 19 2012 Daniel P. Berrange - 2:1.0-8 +- Move udev rules to /lib/udev/rules.d (rhbz #748207) + +* Fri Mar 9 2012 Hans de Goede - 2:1.0-7 +- Add a whole bunch of USB bugfixes from upstream + +* Mon Feb 13 2012 Daniel P. Berrange - 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 - 2:1.0-5 +- Add support for virtio-scsi + +* Sun Feb 5 2012 Richard W.M. Jones - 2:1.0-4 +- Require updated ceph for latest librbd with rbd_flush symbol. + +* Tue Jan 24 2012 Justin M. Forbes - 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 - 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 - 2:1.0-1 +- Add patches from 1.0.1 queue + +* Fri Dec 16 2011 Justin M. Forbes - 2:1.0-1 +- Update to qemu 1.0 + +* Tue Nov 15 2011 Justin M. Forbes - 2:0.15.1-3 +- Enable spice for i686 users as well + +* Thu Nov 03 2011 Justin M. Forbes - 2:0.15.1-2 +- Fix POSTIN scriplet failure (#748281) + +* Fri Oct 21 2011 Justin M. Forbes - 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 +- Enable full relro and PIE (rhbz #738812) + +* Wed Oct 12 2011 Daniel P. Berrange - 2:0.15.0-6 +- Add BR on ceph-devel to enable RBD block device + +* Wed Oct 5 2011 Daniel P. Berrange - 2:0.15.0-5 +- Create a qemu-guest-agent sub-RPM for guest installation + +* Tue Sep 13 2011 Daniel P. Berrange - 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 - 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 - 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 - 2:0.15.0-1 +- Update to 0.15.0 stable release. + +* Thu Aug 04 2011 Justin M. Forbes - 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 - 2:0.15.0-0.3.2011072859fadcc +- Fix default accelerator for non-KVM builds (rhbz #724814) + +* Thu Jul 28 2011 Justin M. Forbes - 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 - 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 - 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 - 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 - 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 - 2:0.14.0-7 +- Disable qemu-ppc and qemu-sparc packages (#679179) + +* Mon Mar 28 2011 Justin M. Forbes - 2:0.14.0-6 +- Spice fixes for flow control. + +* Tue Mar 22 2011 Dan Horák - 2:0.14.0-5 +- be more careful when removing the -g flag on s390 + +* Fri Mar 18 2011 Justin M. Forbes - 2:0.14.0-4 +- Fix thinko on adding the most recent patches. + +* Wed Mar 16 2011 Justin M. Forbes - 2:0.14.0-3 +- Fix migration issue with vhost +- Fix qxl locking issues for spice + +* Wed Mar 02 2011 Justin M. Forbes - 2:0.14.0-2 +- Re-enable sparc and cris builds + +* Thu Feb 24 2011 Justin M. Forbes - 2:0.14.0-1 +- Update to 0.14.0 release + +* Fri Feb 11 2011 Justin M. Forbes - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 2:0.13.0-0.2.20100727gitb81fe95 +- add texinfo buildreq for manpages. + +* Tue Jul 27 2010 Justin M. Forbes - 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 - 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 - 2:0.12.3-7 +- Add vvfat hardening patch from upstream (#605202) + +* Fri Apr 23 2010 Justin M. Forbes - 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 - 2:0.12.3-5 +- Update virtio console patches from upstream + +* Thu Mar 11 2010 Justin M. Forbes - 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 - 2:0.12.3-3 +- Migration clear the fd in error cases (#518032) + +* Tue Mar 09 2010 Justin M. Forbes - 2:0.12.3-2 +- Allow builds --with x86only +- Add libaio-devel buildreq for aio support + +* Fri Feb 26 2010 Justin M. Forbes - 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 - 2:0.12.2-6 +- Add vhost net support. + +* Thu Feb 04 2010 Justin M. Forbes - 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 - 2:0.12.2-4 +- Remove build dependency on iasl now that we have seabios + +* Wed Jan 27 2010 Amit Shah - 2:0.12.2-3 +- Remove source target for 0.12.1.2 + +* Wed Jan 27 2010 Amit Shah - 2:0.12.2-2 +- Add virtio-console patches from upstream for the F13 VirtioSerial feature + +* Mon Jan 25 2010 Justin M. Forbes - 2:0.12.2-1 +- Update to 0.12.2 upstream + +* Sun Jan 10 2010 Justin M. Forbes - 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 - 2:0.12.1.2-2 +- Remove qcow2 virtio backing file patch + +* Mon Jan 4 2010 Justin M. Forbes - 2:0.12.1.2-1 +- Update to 0.12.1.2 upstream +- Remove patches included in upstream + +* Fri Nov 20 2009 Mark McLoughlin - 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 - 2:0.11.0-11 +- Temporarily disable preadv/pwritev support to fix data corruption (#526549) + +* Tue Nov 3 2009 Justin M. Forbes - 2:0.11.0-10 +- Default ksm and ksmtuned services on. + +* Thu Oct 29 2009 Mark McLoughlin - 2:0.11.0-9 +- Fix dropped packets with non-virtio NICs (#531419) + +* Wed Oct 21 2009 Glauber Costa - 2:0.11.0-8 +- Properly save kvm time registers (#524229) + +* Mon Oct 19 2009 Mark McLoughlin - 2:0.11.0-7 +- Fix potential segfault from too small MSR_COUNT (#528901) + +* Fri Oct 9 2009 Mark McLoughlin - 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 - 2:0.11.0-5 +- Add 'retune' verb to ksmtuned init script + +* Mon Oct 5 2009 Mark McLoughlin - 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 - 2:0.11.0-3 +- Improve error reporting on file access (#524695) + +* Mon Sep 28 2009 Mark McLoughlin - 2:0.11.0-2 +- Fix pci hotplug to not exit if supplied an invalid NIC model (#524022) + +* Mon Sep 28 2009 Mark McLoughlin - 2:0.11.0-1 +- Update to 0.11.0 release +- Drop a couple of upstreamed patches + +* Wed Sep 23 2009 Mark McLoughlin - 2:0.10.92-5 +- Fix issue causing NIC hotplug confusion when no model is specified (#524022) + +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-4 +- Fix for KSM patch from Justin Forbes + +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-3 +- Add ksmtuned, also from Dan Kenigsberg +- Use %%_initddir macro + +* Wed Sep 16 2009 Mark McLoughlin - 2:0.10.92-2 +- Add ksm control script from Dan Kenigsberg + +* Mon Sep 7 2009 Mark McLoughlin - 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 - 2:0.10.91-0.10.rc1 +- Fix MSI-X error handling on older kernels (#519787) + +* Fri Sep 4 2009 Mark McLoughlin - 2:0.10.91-0.9.rc1 +- Make pulseaudio the default audio backend (#519540, #495964, #496627) + +* Thu Aug 20 2009 Richard W.M. Jones - 2:0.10.91-0.8.rc1 +- Fix segfault when qemu-kvm is invoked inside a VM (#516543) + +* Tue Aug 18 2009 Mark McLoughlin - 2:0.10.91-0.7.rc1 +- Fix permissions on udev rules (#517571) + +* Mon Aug 17 2009 Lubomir Rintel - 2:0.10.91-0.6.rc1 +- Allow blacklisting of kvm modules (#517866) + +* Fri Aug 7 2009 Mark McLoughlin - 2:0.10.91-0.5.rc1 +- Fix virtio_net with -net user (#516022) + +* Tue Aug 4 2009 Mark McLoughlin - 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 - 2:0.10.91-0.3.rc1.rc0 +- Fix extboot checksum (bug #514899) + +* Fri Jul 31 2009 Mark McLoughlin - 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 - 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 - 2:0.10.50-14.kvm88 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 23 2009 Glauber Costa - 2:0.10.50-13.kvm88 +- Fix bug 513249, -net channel option is broken + +* Thu Jul 16 2009 Daniel P. Berrange - 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 - 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 - 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 - 2:0.10.50-9.kvm87 +- use pxe roms from gpxe, instead of etherboot package. + +* Fri Jul 3 2009 Mark McLoughlin - 2:0.10.50-8.kvm87 +- Prefer sysfs over usbfs for usb passthrough (#508326) + +* Sat Jun 27 2009 Mark McLoughlin - 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 - 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 - 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 - 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 - 2:0.10.50-3.kvm85 +- Really provide qemu-kvm as a metapackage for comps + +* Tue Apr 28 2009 Mark McLoughlin - 2:0.10.50-2.kvm85 +- Provide qemu-kvm as a metapackage for comps + +* Mon Apr 27 2009 Mark McLoughlin - 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 - 2:0.10-15 +- Fix source numbering typos caused by make-release addition + +* Thu Apr 23 2009 Mark McLoughlin - 2:0.10-14 +- Improve instructions for generating the tarball + +* Tue Apr 21 2009 Mark McLoughlin - 2:0.10-13 +- Enable pulseaudio driver to fix qemu lockup at shutdown (#495964) + +* Tue Apr 21 2009 Mark McLoughlin - 2:0.10-12 +- Another qcow2 image corruption fix (#496642) + +* Mon Apr 20 2009 Mark McLoughlin - 2:0.10-11 +- Fix qcow2 image corruption (#496642) + +* Sun Apr 19 2009 Mark McLoughlin - 2:0.10-10 +- Run sysconfig.modules from %%post on x86_64 too (#494739) + +* Sun Apr 19 2009 Mark McLoughlin - 2:0.10-9 +- Align VGA ROM to 4k boundary - fixes 'qemu-kvm -std vga' (#494376) + +* Tue Apr 14 2009 Glauber Costa - 2:0.10-8 +- Provide qemu-kvm conditional on the architecture. + +* Thu Apr 9 2009 Mark McLoughlin - 2:0.10-7 +- Add a much cleaner fix for vga segfault (#494002) + +* Sun Apr 5 2009 Glauber Costa - 2:0.10-6 +- Fixed qcow2 segfault creating disks over 2TB. #491943 + +* Fri Apr 3 2009 Mark McLoughlin - 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 - 2:0.10-4 +- Support botting gpxe roms. + +* Wed Apr 01 2009 Glauber Costa - 2:0.10-2 +- added missing patch. love for CVS. + +* Wed Apr 01 2009 Glauber Costa - 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 - 2:0.10-0.12.kvm20090323git +- BuildRequires pciutils-devel for device assignment (#492076) + +* Mon Mar 23 2009 Glauber Costa - 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 - 2:0.10-0.10.kvm20090310git +- Added extboot to files list. + +* Wed Mar 11 2009 Glauber Costa - 2:0.10-0.9.kvm20090310git +- Fix wrong reference to bochs bios. + +* Wed Mar 11 2009 Glauber Costa - 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 - 2:0.10-0.7.kvm20090310git +- modify ppc patch + +* Tue Mar 10 2009 Glauber Costa - 2:0.10-0.6.kvm20090310git +- updated to kvm20090310git +- removed sasl patches (already in this release) + +* Tue Mar 10 2009 Glauber Costa - 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 - 2:0.10-0.4.kvm20090303git +- seems Epoch does not go into the tags. So start back here. + +* Thu Mar 05 2009 Glauber Costa - 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 - 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 - 0.9.2-0.1.kvm20090303git +- missing a dot. shame on me + +* Wed Mar 04 2009 Glauber Costa - 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 - 0.10-0.3.kvm20090303git +- only execute post scripts for user package. +- added kvm tools. + +* Tue Mar 03 2009 Glauber Costa - 0.10-0.2.kvm20090303git +- put kvm.modules into cvs + +* Tue Mar 03 2009 Glauber Costa - 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 - 1.0-0.5.svn6666 +- Support VNC SASL authentication protocol +- Fix dep on bochs-bios-data + +* Tue Mar 03 2009 Glauber Costa - 1.0-0.4.svn6666 +- use bios from bochs-bios package. + +* Tue Mar 03 2009 Glauber Costa - 1.0-0.3.svn6666 +- use vgabios from vgabios package. + +* Mon Mar 02 2009 Glauber Costa - 1.0-0.2.svn6666 +- use pxe roms from etherboot package. + +* Mon Mar 02 2009 Glauber Costa - 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 - 0.9.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sun Jan 11 2009 Debarshi Ray - 0.9.1-12 +- Updated build patch. Closes Red Hat Bugzilla bug #465041. + +* Wed Dec 31 2008 Dennis Gilmore - 0.9.1-11 +- add sparcv9 and sparc64 support + +* Fri Jul 25 2008 Bill Nottingham +- Fix qemu-img summary (#456344) + +* Wed Jun 25 2008 Daniel P. Berrange - 0.9.1-10.fc10 +- Rebuild for GNU TLS ABI change + +* Wed Jun 11 2008 Daniel P. Berrange - 0.9.1-9.fc10 +- Remove bogus wildcard from files list (rhbz #450701) + +* Sat May 17 2008 Lubomir Rintel - 0.9.1-8 +- Register binary handlers also for shared libraries + +* Mon May 5 2008 Daniel P. Berrange - 0.9.1-7.fc10 +- Fix text console PTYs to be in rawmode + +* Sun Apr 27 2008 Lubomir Kundrak - 0.9.1-6 +- Register binary handler for SuperH-4 CPU + +* Wed Mar 19 2008 Daniel P. Berrange - 0.9.1-5.fc9 +- Split qemu-img tool into sub-package for smaller footprint installs + +* Wed Feb 27 2008 Daniel P. Berrange - 0.9.1-4.fc9 +- Fix block device checks for extendable disk formats (rhbz #435139) + +* Sat Feb 23 2008 Daniel P. Berrange - 0.9.1-3.fc9 +- Fix block device extents check (rhbz #433560) + +* Mon Feb 18 2008 Fedora Release Engineering - 0.9.1-2 +- Autorebuild for GCC 4.3 + +* Tue Jan 8 2008 Daniel P. Berrange - 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 - 0.9.0-5.fc8 +- Fix rtl8139 checksum calculation for Vista (rhbz #308201) + +* Tue Aug 28 2007 Daniel P. Berrange - 0.9.0-4.fc8 +- Fix debuginfo by passing -Wl,--build-id to linker + +* Tue Aug 28 2007 David Woodhouse 0.9.0-4 +- Update licence +- Fix CDROM emulation (#253542) + +* Tue Aug 28 2007 Daniel P. Berrange - 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 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 0.9.0-1 +- Update to 0.9.0 + +* Wed Jan 31 2007 David Woodhouse 0.8.2-5 +- Include licences + +* Mon Nov 13 2006 Hans de Goede 0.8.2-4 +- Backport patch to make FC6 guests work by Kevin Kofler + (bz 207843). + +* Mon Sep 11 2006 David Woodhouse 0.8.2-3 +- Rebuild + +* Thu Aug 24 2006 Matthias Saou 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 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 0.8.1-3 +- More header abuse in modify_ldt(), change BuildRoot: + +* Wed Jun 7 2006 David Woodhouse 0.8.1-2 +- Fix up kernel header abuse + +* Tue May 30 2006 David Woodhouse 0.8.1-1 +- Update to 0.8.1 + +* Sat Mar 18 2006 David Woodhouse 0.8.0-6 +- Update linker script for PPC + +* Sat Mar 18 2006 David Woodhouse 0.8.0-5 +- Just drop $RPM_OPT_FLAGS. They're too much of a PITA + +* Sat Mar 18 2006 David Woodhouse 0.8.0-4 +- Disable stack-protector options which gcc 3.2 doesn't like + +* Fri Mar 17 2006 David Woodhouse 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 0.8.0-2 +- Don't use -mtune=pentium4 on i386. GCC 3.2 doesn't like it + +* Fri Mar 17 2006 David Woodhouse 0.8.0-1 +- Update to 0.8.0 +- Resort to using compat-gcc-32 +- Enable ALSA + +* Mon May 16 2005 David Woodhouse 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 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 +- rebuilt + +* Sun Feb 13 2005 David Woodhouse 0.6.1-2 +- Package cleanup + +* Sun Nov 21 2004 David Woodhouse 0.6.1-1 +- Update to 0.6.1 + +* Tue Jul 20 2004 David Woodhouse 0.6.0-2 +- Compile fix from qemu CVS, add x86_64 host support + +* Wed May 12 2004 David Woodhouse 0.6.0-1 +- Update to 0.6.0. + +* Sat May 8 2004 David Woodhouse 0.5.5-1 +- Update to 0.5.5. + +* Sun May 2 2004 David Woodhouse 0.5.4-1 +- Update to 0.5.4. + +* Thu Apr 22 2004 David Woodhouse 0.5.3-1 +- Update to 0.5.3. Add init script. + +* Thu Jul 17 2003 Jeff Johnson 0.4.3-1 +- Create.