diff --git a/SOURCES/kvm-Disable-CONFIG_I2C-and-CONFIG_IOH3420.patch b/SOURCES/kvm-Disable-CONFIG_I2C-and-CONFIG_IOH3420.patch
new file mode 100644
index 0000000..a20255a
--- /dev/null
+++ b/SOURCES/kvm-Disable-CONFIG_I2C-and-CONFIG_IOH3420.patch
@@ -0,0 +1,44 @@
+From 23400c3067fab729fd0584e16f6fa84e1bb3c4f8 Mon Sep 17 00:00:00 2001
+From: Auger Eric <eric.auger@redhat.com>
+Date: Fri, 20 Sep 2019 17:25:08 +0100
+Subject: [PATCH 02/21] Disable CONFIG_I2C and CONFIG_IOH3420
+
+RH-Author: Auger Eric <eric.auger@redhat.com>
+Message-id: <20190920172508.16323-1-eric.auger@redhat.com>
+Patchwork-id: 90825
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH] Disable CONFIG_I2C and CONFIG_IOH3420
+Bugzilla: 1693140
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1693140
+Branch: rhel-8.2.0
+Upstream: Downstream only
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23613661
+
+Remove the I2C config which is of no use on aarch64. Also remove the
+IOH3420 to be consistent with AV content (See BZ 1627283).
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ default-configs/aarch64-softmmu.mak | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
+index 860140e..d718243 100644
+--- a/default-configs/aarch64-softmmu.mak
++++ b/default-configs/aarch64-softmmu.mak
+@@ -23,8 +23,6 @@ CONFIG_GPIO_KEY=y
+ CONFIG_ARM_V7M=y
+ CONFIG_PCIE_PORT=y
+ CONFIG_XIO3130=y
+-CONFIG_IOH3420=y
+ CONFIG_USB_XHCI=y
+ CONFIG_USB=y
+-CONFIG_I2C=y
+ CONFIG_FW_CFG_DMA=y
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Using-ip_deq-after-m_free-might-read-pointers-from-a.patch b/SOURCES/kvm-Using-ip_deq-after-m_free-might-read-pointers-from-a.patch
new file mode 100644
index 0000000..ce5cca1
--- /dev/null
+++ b/SOURCES/kvm-Using-ip_deq-after-m_free-might-read-pointers-from-a.patch
@@ -0,0 +1,61 @@
+From a4c22009a465ebe5fd0c09699e61ad0423b8849d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
+Date: Fri, 6 Sep 2019 14:00:34 +0100
+Subject: [PATCH 07/22] Using ip_deq after m_free might read pointers from an
+ allocation reuse.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-id: <20190906140034.19722-2-philmd@redhat.com>
+Patchwork-id: 90306
+O-Subject: [RHEL-7.7 qemu-kvm-ma + RHEL-7.7 qemu-kvm-rhev + RHEL-8.1.0 qemu-kvm PATCH 1/1] Using ip_deq after m_free might read pointers from an allocation reuse.
+Bugzilla: 1749724
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+This would be difficult to exploit, but that is still related with
+CVE-2019-14378 which generates fragmented IP packets that would trigger this
+issue and at least produce a DoS.
+
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+(cherry picked from libslirp commit c59279437eda91841b9d26079c70b8a540d41204)
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ slirp/ip_input.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/slirp/ip_input.c b/slirp/ip_input.c
+index 07d8808..7cf0133 100644
+--- a/slirp/ip_input.c
++++ b/slirp/ip_input.c
+@@ -300,6 +300,7 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
+ 	 */
+ 	while (q != (struct ipasfrag*)&fp->frag_link &&
+             ip->ip_off + ip->ip_len > q->ipf_off) {
++		struct ipasfrag *prev;
+ 		i = (ip->ip_off + ip->ip_len) - q->ipf_off;
+ 		if (i < q->ipf_len) {
+ 			q->ipf_len -= i;
+@@ -307,9 +308,10 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
+ 			m_adj(dtom(slirp, q), i);
+ 			break;
+ 		}
++		prev = q;
+ 		q = q->ipf_next;
+-		m_free(dtom(slirp, q->ipf_prev));
+-		ip_deq(q->ipf_prev);
++		ip_deq(prev);
++		m_free(dtom(slirp, prev));
+ 	}
+ 
+ insert:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-accel-use-g_strsplit-for-parsing-accelerator-names.patch b/SOURCES/kvm-accel-use-g_strsplit-for-parsing-accelerator-names.patch
new file mode 100644
index 0000000..f031582
--- /dev/null
+++ b/SOURCES/kvm-accel-use-g_strsplit-for-parsing-accelerator-names.patch
@@ -0,0 +1,113 @@
+From 28a766b8099f5e745dbfc18834277039643214a3 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 12 Sep 2019 13:04:58 +0100
+Subject: [PATCH 01/22] accel: use g_strsplit for parsing accelerator names
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laszlo Ersek <lersek@redhat.com>
+Message-id: <20190912130503.14094-2-lersek@redhat.com>
+Patchwork-id: 90437
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/6] accel: use g_strsplit for parsing accelerator names
+Bugzilla: 1749022
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+Instead of re-using the get_opt_name() method from QemuOpts to split a
+string on ':', just use g_strsplit().
+
+RHEL8 notes:
+
+- Fix up upstream's obviously garbled UTF8 sequences in Dan's name (Author
+  meta-datum, Signed-off-by tags).
+
+- Harmless context difference due to downstream-only commit 8b53513834e6
+  ("Use kvm by default", 2018-04-24).
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180416111743.8473-2-berrange@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 20efc49ed625585809401d8293ad9267927a6a4a)
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ accel/accel.c         | 16 +++++++---------
+ include/qemu/option.h |  1 -
+ util/qemu-option.c    |  3 ++-
+ 3 files changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/accel/accel.c b/accel/accel.c
+index 5f3d73f..57390e5 100644
+--- a/accel/accel.c
++++ b/accel/accel.c
+@@ -70,8 +70,8 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
+ 
+ void configure_accelerator(MachineState *ms)
+ {
+-    const char *accel, *p;
+-    char buf[10];
++    const char *accel;
++    char **accel_list, **tmp;
+     int ret;
+     bool accel_initialised = false;
+     bool init_failed = false;
+@@ -83,13 +83,10 @@ void configure_accelerator(MachineState *ms)
+         accel = "kvm:tcg";
+     }
+ 
+-    p = accel;
+-    while (!accel_initialised && *p != '\0') {
+-        if (*p == ':') {
+-            p++;
+-        }
+-        p = get_opt_name(buf, sizeof(buf), p, ':');
+-        acc = accel_find(buf);
++    accel_list = g_strsplit(accel, ":", 0);
++
++    for (tmp = accel_list; !accel_initialised && tmp && *tmp; tmp++) {
++        acc = accel_find(*tmp);
+         if (!acc) {
+             continue;
+         }
+@@ -107,6 +104,7 @@ void configure_accelerator(MachineState *ms)
+             accel_initialised = true;
+         }
+     }
++    g_strfreev(accel_list);
+ 
+     if (!accel_initialised) {
+         if (!init_failed) {
+diff --git a/include/qemu/option.h b/include/qemu/option.h
+index 306fdb5..1cfe5cb 100644
+--- a/include/qemu/option.h
++++ b/include/qemu/option.h
+@@ -28,7 +28,6 @@
+ 
+ #include "qemu/queue.h"
+ 
+-const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
+ const char *get_opt_value(char *buf, int buf_size, const char *p);
+ 
+ void parse_option_size(const char *name, const char *value,
+diff --git a/util/qemu-option.c b/util/qemu-option.c
+index 95e6cf4..a8db173 100644
+--- a/util/qemu-option.c
++++ b/util/qemu-option.c
+@@ -49,7 +49,8 @@
+  * The return value is the position of the delimiter/zero byte after the option
+  * name in p.
+  */
+-const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
++static const char *get_opt_name(char *buf, int buf_size, const char *p,
++                                char delim)
+ {
+     char *q;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-add-call-to-qemu_add_opts-for-overcommit-option.patch b/SOURCES/kvm-add-call-to-qemu_add_opts-for-overcommit-option.patch
new file mode 100644
index 0000000..a68e498
--- /dev/null
+++ b/SOURCES/kvm-add-call-to-qemu_add_opts-for-overcommit-option.patch
@@ -0,0 +1,45 @@
+From 490c0121b8cd1de62776c18a0843a256b7eed3e3 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 26 Nov 2019 19:36:51 +0000
+Subject: [PATCH 07/11] kvm: add call to qemu_add_opts() for -overcommit option
+
+RH-Author: plai@redhat.com
+Message-id: <1574797015-32564-4-git-send-email-plai@redhat.com>
+Patchwork-id: 92694
+O-Subject: [RHEL8.2 qemu-kvm PATCH 3/7] kvm: add call to qemu_add_opts() for -overcommit option
+Bugzilla: 1634827
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Prasad Singamsetty <prasad.singamsetty@oracle.com>
+
+qemu command fails to process -overcommit option. Add the missing
+call to qemu_add_opts() in vl.c.
+
+Signed-off-by: Prasad Singamsetty <prasad.singamsetty@oracle.com>
+Message-Id: <20180815175704.105902-1-prasad.singamsetty@oracle.com>
+Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 1fdd4748711a62d863744f42b958472509a6f202)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ vl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/vl.c b/vl.c
+index 3cee95f..932c1cf 100644
+--- a/vl.c
++++ b/vl.c
+@@ -3145,6 +3145,7 @@ int main(int argc, char **argv, char **envp)
+     qemu_add_opts(&qemu_object_opts);
+     qemu_add_opts(&qemu_tpmdev_opts);
+     qemu_add_opts(&qemu_realtime_opts);
++    qemu_add_opts(&qemu_overcommit_opts);
+     qemu_add_opts(&qemu_msg_opts);
+     qemu_add_opts(&qemu_name_opts);
+     qemu_add_opts(&qemu_numa_opts);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-ccid-Fix-dwProtocols-advertisement-of-T-0.patch b/SOURCES/kvm-ccid-Fix-dwProtocols-advertisement-of-T-0.patch
new file mode 100644
index 0000000..5af3ea1
--- /dev/null
+++ b/SOURCES/kvm-ccid-Fix-dwProtocols-advertisement-of-T-0.patch
@@ -0,0 +1,67 @@
+From e541592f0c98696276261a7c36afe074a3bdd956 Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Wed, 18 Sep 2019 18:45:52 +0100
+Subject: [PATCH 11/22] ccid: Fix dwProtocols advertisement of T=0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20190918184552.10820-2-mlevitsk@redhat.com>
+Patchwork-id: 90769
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/1] ccid: Fix dwProtocols advertisement of T=0
+Bugzilla: 1746361
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Jason Andryuk <jandryuk@gmail.com>
+
+Commit d7d218ef02d87c637d20d64da8f575d434ff6f78 attempted to change
+dwProtocols to only advertise support for T=0 and not T=1.  The change
+was incorrect as it changed 0x00000003 to 0x00010000.
+
+lsusb -v in a linux guest shows:
+"dwProtocols         65536  (Invalid values detected)", though the
+smart card could still be accessed.  Windows 7 does not detect inserted
+smart cards and logs the the following Error in the Event Logs:
+
+    Source: Smart Card Service
+    Event ID: 610
+    Smart Card Reader 'QEMU QEMU USB CCID 0' rejected IOCTL SET_PROTOCOL:
+    Incorrect function. If this error persists, your smart card or reader
+    may not be functioning correctly
+
+    Command Header: 03 00 00 00
+
+Setting to 0x00000001 fixes the Windows issue.
+
+Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
+Message-id: 20180420183219.20722-1-jandryuk@gmail.com
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 0ee86bb6c5beb6498488850104f7557c376d0bef)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/usb/dev-smartcard-reader.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
+index e646805..cabb564 100644
+--- a/hw/usb/dev-smartcard-reader.c
++++ b/hw/usb/dev-smartcard-reader.c
+@@ -329,8 +329,8 @@ static const uint8_t qemu_ccid_descriptor[] = {
+                      */
+         0x07,       /* u8  bVoltageSupport; 01h - 5.0v, 02h - 3.0, 03 - 1.8 */
+ 
+-        0x00, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/
+-        0x01, 0x00, /* PPPP: 0001h = Protocol T=0, 0002h = Protocol T=1 */
++        0x01, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/
++        0x00, 0x00, /* PPPP: 0001h = Protocol T=0, 0002h = Protocol T=1 */
+                     /* u32 dwDefaultClock; in kHZ (0x0fa0 is 4 MHz) */
+         0xa0, 0x0f, 0x00, 0x00,
+                     /* u32 dwMaximumClock; */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-clean-up-callback-when-del-virtqueue.patch b/SOURCES/kvm-clean-up-callback-when-del-virtqueue.patch
new file mode 100644
index 0000000..dc57895
--- /dev/null
+++ b/SOURCES/kvm-clean-up-callback-when-del-virtqueue.patch
@@ -0,0 +1,55 @@
+From 335e94e588ded0f1163ef20c72d78fcf725b1236 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Tue, 4 Feb 2020 18:20:04 +0000
+Subject: [PATCH 3/6] clean up callback when del virtqueue
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200204182007.183537-2-jusual@redhat.com>
+Patchwork-id: 93703
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/4] clean up callback when del virtqueue
+Bugzilla: 1708480
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: liujunjie <liujunjie23@huawei.com>
+
+Before, we did not clear callback like handle_output when delete
+the virtqueue which may result be segmentfault.
+The scene is as follows:
+1. Start a vm with multiqueue vhost-net,
+2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to
+triger multiqueue disable in this vm which will delete the virtqueue.
+In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh
+still exist.
+3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to
+notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh
+will be called and qemu will be crashed.
+
+Although the way described above is uncommon, we had better reinforce it.
+
+CC: qemu-stable@nongnu.org
+Signed-off-by: liujunjie <liujunjie23@huawei.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+(cherry picked from commit 7da2d99fb9fbf30104125c061caaff330e362d74)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/virtio/virtio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index fce199e..6356bf3 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -1609,6 +1609,8 @@ void virtio_del_queue(VirtIODevice *vdev, int n)
+ 
+     vdev->vq[n].vring.num = 0;
+     vdev->vq[n].vring.num_default = 0;
++    vdev->vq[n].handle_output = NULL;
++    vdev->vq[n].handle_aio_output = NULL;
+ }
+ 
+ static void virtio_set_isr(VirtIODevice *vdev, int value)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Check-completion-in-curl_multi_do.patch b/SOURCES/kvm-curl-Check-completion-in-curl_multi_do.patch
new file mode 100644
index 0000000..95ac20c
--- /dev/null
+++ b/SOURCES/kvm-curl-Check-completion-in-curl_multi_do.patch
@@ -0,0 +1,87 @@
+From a09766bbc8a4208fc0f62904cebec4022beba6b0 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:29:56 +0000
+Subject: [PATCH 4/8] curl: Check completion in curl_multi_do()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-4-mreitz@redhat.com>
+Patchwork-id: 92516
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 3/7] curl: Check completion in curl_multi_do()
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+While it is more likely that transfers complete after some file
+descriptor has data ready to read, we probably should not rely on it.
+Better be safe than sorry and call curl_multi_check_completion() in
+curl_multi_do(), too, just like it is done in curl_multi_read().
+
+With this change, curl_multi_do() and curl_multi_read() are actually the
+same, so drop curl_multi_read() and use curl_multi_do() as the sole FD
+handler.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20190910124136.10565-4-mreitz@redhat.com
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 948403bcb1c7e71dcbe8ab8479cf3934a0efcbb5)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index b3fe09f..8f31594 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -148,7 +148,6 @@ typedef struct BDRVCURLState {
+ 
+ static void curl_clean_state(CURLState *s);
+ static void curl_multi_do(void *arg);
+-static void curl_multi_read(void *arg);
+ 
+ #ifdef NEED_CURL_TIMER_CALLBACK
+ /* Called from curl_multi_do_locked, with s->mutex held.  */
+@@ -195,7 +194,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+     switch (action) {
+         case CURL_POLL_IN:
+             aio_set_fd_handler(s->aio_context, fd, false,
+-                               curl_multi_read, NULL, NULL, state);
++                               curl_multi_do, NULL, NULL, state);
+             break;
+         case CURL_POLL_OUT:
+             aio_set_fd_handler(s->aio_context, fd, false,
+@@ -203,7 +202,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+             break;
+         case CURL_POLL_INOUT:
+             aio_set_fd_handler(s->aio_context, fd, false,
+-                               curl_multi_read, curl_multi_do, NULL, state);
++                               curl_multi_do, curl_multi_do, NULL, state);
+             break;
+         case CURL_POLL_REMOVE:
+             aio_set_fd_handler(s->aio_context, fd, false,
+@@ -427,15 +426,6 @@ static void curl_multi_do(void *arg)
+ 
+     qemu_mutex_lock(&s->s->mutex);
+     curl_multi_do_locked(s);
+-    qemu_mutex_unlock(&s->s->mutex);
+-}
+-
+-static void curl_multi_read(void *arg)
+-{
+-    CURLState *s = (CURLState *)arg;
+-
+-    qemu_mutex_lock(&s->s->mutex);
+-    curl_multi_do_locked(s);
+     curl_multi_check_completion(s->s);
+     qemu_mutex_unlock(&s->s->mutex);
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Check-curl_multi_add_handle-s-return-code.patch b/SOURCES/kvm-curl-Check-curl_multi_add_handle-s-return-code.patch
new file mode 100644
index 0000000..859023c
--- /dev/null
+++ b/SOURCES/kvm-curl-Check-curl_multi_add_handle-s-return-code.patch
@@ -0,0 +1,54 @@
+From d8de6fc3530b5cfa05485f24e14af4ce44a8b72d Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:30:00 +0000
+Subject: [PATCH 8/8] curl: Check curl_multi_add_handle()'s return code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-8-mreitz@redhat.com>
+Patchwork-id: 92521
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 7/7] curl: Check curl_multi_add_handle()'s return code
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+If we had done that all along, debugging would have been much simpler.
+(Also, I/O errors are better than hangs.)
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20190910124136.10565-8-mreitz@redhat.com
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit c34dc07f9f01cf686e512f939aece744723072cd)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index b5899e1..5d05d30 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -891,7 +891,13 @@ static void curl_setup_preadv(BlockDriverState *bs, CURLAIOCB *acb)
+             acb->bytes, start, state->range);
+     curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
+ 
+-    curl_multi_add_handle(s->multi, state->curl);
++    if (curl_multi_add_handle(s->multi, state->curl) != CURLM_OK) {
++        state->acb[0] = NULL;
++        acb->ret = -EIO;
++
++        curl_clean_state(state);
++        goto out;
++    }
+ 
+     /* Tell curl it needs to kick things off */
+     curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Handle-success-in-multi_check_completion.patch b/SOURCES/kvm-curl-Handle-success-in-multi_check_completion.patch
new file mode 100644
index 0000000..9fe667e
--- /dev/null
+++ b/SOURCES/kvm-curl-Handle-success-in-multi_check_completion.patch
@@ -0,0 +1,162 @@
+From 23f5a846f6702c456cf7cc9490e50cfd23368910 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:29:59 +0000
+Subject: [PATCH 7/8] curl: Handle success in multi_check_completion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-7-mreitz@redhat.com>
+Patchwork-id: 92520
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 6/7] curl: Handle success in multi_check_completion
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+Background: As of cURL 7.59.0, it verifies that several functions are
+not called from within a callback.  Among these functions is
+curl_multi_add_handle().
+
+curl_read_cb() is a callback from cURL and not a coroutine.  Waking up
+acb->co will lead to entering it then and there, which means the current
+request will settle and the caller (if it runs in the same coroutine)
+may then issue the next request.  In such a case, we will enter
+curl_setup_preadv() effectively from within curl_read_cb().
+
+Calling curl_multi_add_handle() will then fail and the new request will
+not be processed.
+
+Fix this by not letting curl_read_cb() wake up acb->co.  Instead, leave
+the whole business of settling the AIOCB objects to
+curl_multi_check_completion() (which is called from our timer callback
+and our FD handler, so not from any cURL callbacks).
+
+Reported-by: Natalie Gavrielov <ngavrilo@redhat.com>
+Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1740193
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20190910124136.10565-7-mreitz@redhat.com
+Reviewed-by: John Snow <jsnow@redhat.com>
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit bfb23b480a49114315877aacf700b49453e0f9d9)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 69 +++++++++++++++++++++++++-----------------------------------
+ 1 file changed, 29 insertions(+), 40 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index f776615..b5899e1 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -238,7 +238,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
+ {
+     CURLState *s = ((CURLState*)opaque);
+     size_t realsize = size * nmemb;
+-    int i;
+ 
+     DPRINTF("CURL: Just reading %zd bytes\n", realsize);
+ 
+@@ -254,32 +253,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
+     memcpy(s->orig_buf + s->buf_off, ptr, realsize);
+     s->buf_off += realsize;
+ 
+-    for(i=0; i<CURL_NUM_ACB; i++) {
+-        CURLAIOCB *acb = s->acb[i];
+-
+-        if (!acb)
+-            continue;
+-
+-        if ((s->buf_off >= acb->end)) {
+-            size_t request_length = acb->bytes;
+-
+-            qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
+-                                acb->end - acb->start);
+-
+-            if (acb->end - acb->start < request_length) {
+-                size_t offset = acb->end - acb->start;
+-                qemu_iovec_memset(acb->qiov, offset, 0,
+-                                  request_length - offset);
+-            }
+-
+-            acb->ret = 0;
+-            s->acb[i] = NULL;
+-            qemu_mutex_unlock(&s->s->mutex);
+-            aio_co_wake(acb->co);
+-            qemu_mutex_lock(&s->s->mutex);
+-        }
+-    }
+-
+ read_end:
+     /* curl will error out if we do not return this value */
+     return size * nmemb;
+@@ -360,13 +333,14 @@ static void curl_multi_check_completion(BDRVCURLState *s)
+             break;
+ 
+         if (msg->msg == CURLMSG_DONE) {
++            int i;
+             CURLState *state = NULL;
++            bool error = msg->data.result != CURLE_OK;
++
+             curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,
+                               (char **)&state);
+ 
+-            /* ACBs for successful messages get completed in curl_read_cb */
+-            if (msg->data.result != CURLE_OK) {
+-                int i;
++            if (error) {
+                 static int errcount = 100;
+ 
+                 /* Don't lose the original error message from curl, since
+@@ -378,20 +352,35 @@ static void curl_multi_check_completion(BDRVCURLState *s)
+                         error_report("curl: further errors suppressed");
+                     }
+                 }
++            }
+ 
+-                for (i = 0; i < CURL_NUM_ACB; i++) {
+-                    CURLAIOCB *acb = state->acb[i];
++            for (i = 0; i < CURL_NUM_ACB; i++) {
++                CURLAIOCB *acb = state->acb[i];
+ 
+-                    if (acb == NULL) {
+-                        continue;
+-                    }
++                if (acb == NULL) {
++                    continue;
++                }
++
++                if (!error) {
++                    /* Assert that we have read all data */
++                    assert(state->buf_off >= acb->end);
++
++                    qemu_iovec_from_buf(acb->qiov, 0,
++                                        state->orig_buf + acb->start,
++                                        acb->end - acb->start);
+ 
+-                    acb->ret = -EIO;
+-                    state->acb[i] = NULL;
+-                    qemu_mutex_unlock(&s->mutex);
+-                    aio_co_wake(acb->co);
+-                    qemu_mutex_lock(&s->mutex);
++                    if (acb->end - acb->start < acb->bytes) {
++                        size_t offset = acb->end - acb->start;
++                        qemu_iovec_memset(acb->qiov, offset, 0,
++                                          acb->bytes - offset);
++                    }
+                 }
++
++                acb->ret = error ? -EIO : 0;
++                state->acb[i] = NULL;
++                qemu_mutex_unlock(&s->mutex);
++                aio_co_wake(acb->co);
++                qemu_mutex_lock(&s->mutex);
+             }
+ 
+             curl_clean_state(state);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Keep-pointer-to-the-CURLState-in-CURLSocket.patch b/SOURCES/kvm-curl-Keep-pointer-to-the-CURLState-in-CURLSocket.patch
new file mode 100644
index 0000000..65742ed
--- /dev/null
+++ b/SOURCES/kvm-curl-Keep-pointer-to-the-CURLState-in-CURLSocket.patch
@@ -0,0 +1,65 @@
+From 21dbedae8100710d284b79f7ce21a6b095a4c6e0 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:29:54 +0000
+Subject: [PATCH 2/8] curl: Keep pointer to the CURLState in CURLSocket
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-2-mreitz@redhat.com>
+Patchwork-id: 92515
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/7] curl: Keep pointer to the CURLState in CURLSocket
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+A follow-up patch will make curl_multi_do() and curl_multi_read() take a
+CURLSocket instead of the CURLState.  They still need the latter,
+though, so add a pointer to it to the former.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Message-id: 20190910124136.10565-2-mreitz@redhat.com
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 0487861685294660b23bc146e1ebd5304aa8bbe0)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/block/curl.c b/block/curl.c
+index f0df33a..fa602d1 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -89,6 +89,7 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
+ #define CURL_BLOCK_OPT_PROXY_PASSWORD_SECRET "proxy-password-secret"
+ 
+ struct BDRVCURLState;
++struct CURLState;
+ 
+ static bool libcurl_initialized;
+ 
+@@ -106,6 +107,7 @@ typedef struct CURLAIOCB {
+ 
+ typedef struct CURLSocket {
+     int fd;
++    struct CURLState *state;
+     QLIST_ENTRY(CURLSocket) next;
+ } CURLSocket;
+ 
+@@ -189,6 +191,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+     if (!socket) {
+         socket = g_new0(CURLSocket, 1);
+         socket->fd = fd;
++        socket->state = state;
+         QLIST_INSERT_HEAD(&state->sockets, socket, next);
+     }
+     socket = NULL;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Keep-socket-until-the-end-of-curl_sock_cb.patch b/SOURCES/kvm-curl-Keep-socket-until-the-end-of-curl_sock_cb.patch
new file mode 100644
index 0000000..1ed321a
--- /dev/null
+++ b/SOURCES/kvm-curl-Keep-socket-until-the-end-of-curl_sock_cb.patch
@@ -0,0 +1,72 @@
+From 46598620c18de69d9565e662a47d2615984cc49b Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:29:55 +0000
+Subject: [PATCH 3/8] curl: Keep *socket until the end of curl_sock_cb()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-3-mreitz@redhat.com>
+Patchwork-id: 92517
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/7] curl: Keep *socket until the end of curl_sock_cb()
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+This does not really change anything, but it makes the code a bit easier
+to follow once we use @socket as the opaque pointer for
+aio_set_fd_handler().
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20190910124136.10565-3-mreitz@redhat.com
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 007f339b1099af46a008dac438ca0943e31dba72)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index fa602d1..b3fe09f 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -181,10 +181,6 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+ 
+     QLIST_FOREACH(socket, &state->sockets, next) {
+         if (socket->fd == fd) {
+-            if (action == CURL_POLL_REMOVE) {
+-                QLIST_REMOVE(socket, next);
+-                g_free(socket);
+-            }
+             break;
+         }
+     }
+@@ -194,7 +190,6 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+         socket->state = state;
+         QLIST_INSERT_HEAD(&state->sockets, socket, next);
+     }
+-    socket = NULL;
+ 
+     DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd);
+     switch (action) {
+@@ -216,6 +211,11 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+             break;
+     }
+ 
++    if (action == CURL_POLL_REMOVE) {
++        QLIST_REMOVE(socket, next);
++        g_free(socket);
++    }
++
+     return 0;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Pass-CURLSocket-to-curl_multi_do.patch b/SOURCES/kvm-curl-Pass-CURLSocket-to-curl_multi_do.patch
new file mode 100644
index 0000000..6879fb2
--- /dev/null
+++ b/SOURCES/kvm-curl-Pass-CURLSocket-to-curl_multi_do.patch
@@ -0,0 +1,93 @@
+From 37acfe84ccbc4cc050e7be0ba9c8c4134a7b004e Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:29:57 +0000
+Subject: [PATCH 5/8] curl: Pass CURLSocket to curl_multi_do()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-5-mreitz@redhat.com>
+Patchwork-id: 92518
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 4/7] curl: Pass CURLSocket to curl_multi_do()
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+curl_multi_do_locked() currently marks all sockets as ready.  That is
+not only inefficient, but in fact unsafe (the loop is).  A follow-up
+patch will change that, but to do so, curl_multi_do_locked() needs to
+know exactly which socket is ready; and that is accomplished by this
+patch here.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20190910124136.10565-5-mreitz@redhat.com
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 9dbad87d25587ff640ef878f7b6159fc368ff541)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index 8f31594..de00ec8 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -194,15 +194,15 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
+     switch (action) {
+         case CURL_POLL_IN:
+             aio_set_fd_handler(s->aio_context, fd, false,
+-                               curl_multi_do, NULL, NULL, state);
++                               curl_multi_do, NULL, NULL, socket);
+             break;
+         case CURL_POLL_OUT:
+             aio_set_fd_handler(s->aio_context, fd, false,
+-                               NULL, curl_multi_do, NULL, state);
++                               NULL, curl_multi_do, NULL, socket);
+             break;
+         case CURL_POLL_INOUT:
+             aio_set_fd_handler(s->aio_context, fd, false,
+-                               curl_multi_do, curl_multi_do, NULL, state);
++                               curl_multi_do, curl_multi_do, NULL, socket);
+             break;
+         case CURL_POLL_REMOVE:
+             aio_set_fd_handler(s->aio_context, fd, false,
+@@ -401,9 +401,10 @@ static void curl_multi_check_completion(BDRVCURLState *s)
+ }
+ 
+ /* Called with s->mutex held.  */
+-static void curl_multi_do_locked(CURLState *s)
++static void curl_multi_do_locked(CURLSocket *ready_socket)
+ {
+     CURLSocket *socket, *next_socket;
++    CURLState *s = ready_socket->state;
+     int running;
+     int r;
+ 
+@@ -422,12 +423,13 @@ static void curl_multi_do_locked(CURLState *s)
+ 
+ static void curl_multi_do(void *arg)
+ {
+-    CURLState *s = (CURLState *)arg;
++    CURLSocket *socket = arg;
++    BDRVCURLState *s = socket->state->s;
+ 
+-    qemu_mutex_lock(&s->s->mutex);
+-    curl_multi_do_locked(s);
+-    curl_multi_check_completion(s->s);
+-    qemu_mutex_unlock(&s->s->mutex);
++    qemu_mutex_lock(&s->mutex);
++    curl_multi_do_locked(socket);
++    curl_multi_check_completion(s);
++    qemu_mutex_unlock(&s->mutex);
+ }
+ 
+ static void curl_multi_timeout_do(void *arg)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-curl-Report-only-ready-sockets.patch b/SOURCES/kvm-curl-Report-only-ready-sockets.patch
new file mode 100644
index 0000000..06db6e3
--- /dev/null
+++ b/SOURCES/kvm-curl-Report-only-ready-sockets.patch
@@ -0,0 +1,77 @@
+From 70c7a568e3c1384704228622990d6aaa2350e44e Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Tue, 19 Nov 2019 15:29:58 +0000
+Subject: [PATCH 6/8] curl: Report only ready sockets
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20191119153000.101646-6-mreitz@redhat.com>
+Patchwork-id: 92519
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 5/7] curl: Report only ready sockets
+Bugzilla: 1744602
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+Instead of reporting all sockets to cURL, only report the one that has
+caused curl_multi_do_locked() to be called.  This lets us get rid of the
+QLIST_FOREACH_SAFE() list, which was actually wrong: SAFE foreaches are
+only safe when the current element is removed in each iteration.  If it
+possible for the list to be concurrently modified, we cannot guarantee
+that only the current element will be removed.  Therefore, we must not
+use QLIST_FOREACH_SAFE() here.
+
+Fixes: ff5ca1664af85b24a4180d595ea6873fd3deac57
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-id: 20190910124136.10565-6-mreitz@redhat.com
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Reviewed-by: John Snow <jsnow@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 9abaf9fc474c3dd53e8e119326abc774c977c331)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index de00ec8..f776615 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -401,24 +401,19 @@ static void curl_multi_check_completion(BDRVCURLState *s)
+ }
+ 
+ /* Called with s->mutex held.  */
+-static void curl_multi_do_locked(CURLSocket *ready_socket)
++static void curl_multi_do_locked(CURLSocket *socket)
+ {
+-    CURLSocket *socket, *next_socket;
+-    CURLState *s = ready_socket->state;
++    BDRVCURLState *s = socket->state->s;
+     int running;
+     int r;
+ 
+-    if (!s->s->multi) {
++    if (!s->multi) {
+         return;
+     }
+ 
+-    /* Need to use _SAFE because curl_multi_socket_action() may trigger
+-     * curl_sock_cb() which might modify this list */
+-    QLIST_FOREACH_SAFE(socket, &s->sockets, next, next_socket) {
+-        do {
+-            r = curl_multi_socket_action(s->s->multi, socket->fd, 0, &running);
+-        } while (r == CURLM_CALL_MULTI_PERFORM);
+-    }
++    do {
++        r = curl_multi_socket_action(s->multi, socket->fd, 0, &running);
++    } while (r == CURLM_CALL_MULTI_PERFORM);
+ }
+ 
+ static void curl_multi_do(void *arg)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-exec-Fix-MAP_RAM-for-cached-access.patch b/SOURCES/kvm-exec-Fix-MAP_RAM-for-cached-access.patch
new file mode 100644
index 0000000..2e0849b
--- /dev/null
+++ b/SOURCES/kvm-exec-Fix-MAP_RAM-for-cached-access.patch
@@ -0,0 +1,271 @@
+From 064565e76b986a42d9cdcba72965887528cea90a Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Sun, 22 Dec 2019 11:02:06 +0100
+Subject: [PATCH 1/7] exec: Fix MAP_RAM for cached access
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20191222110207.21384-2-mlevitsk@redhat.com>
+Patchwork-id: 93207
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/2] exec: Fix MAP_RAM for cached access
+Bugzilla: 1769613
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Eric Auger <eric.auger@redhat.com>
+
+When an IOMMUMemoryRegion is in front of a virtio device,
+address_space_cache_init does not set cache->ptr as the memory
+region is not RAM. However when the device performs an access,
+we end up in glue() which performs the translation and then uses
+MAP_RAM. This latter uses the unset ptr and returns a wrong value
+which leads to a SIGSEV in address_space_lduw_internal_cached_slow,
+for instance.
+
+In slow path cache->ptr is NULL and MAP_RAM must redirect to
+qemu_map_ram_ptr((mr)->ram_block, ofs).
+
+As MAP_RAM, IS_DIRECT and INVALIDATE are the same in _cached_slow
+and non cached mode, let's remove those macros.
+
+This fixes the use cases featuring vIOMMU (Intel and ARM SMMU)
+which lead to a SIGSEV.
+
+Fixes: 48564041a73a (exec: reintroduce MemoryRegion caching)
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+
+Message-Id: <1528895946-28677-1-git-send-email-eric.auger@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit a99761d3c85679da380c0f597468acd3dc1b53b3)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ exec.c            |  6 ------
+ memory_ldst.inc.c | 47 ++++++++++++++++++++++-------------------------
+ 2 files changed, 22 insertions(+), 31 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 9112d8b..86218ef 100644
+--- a/exec.c
++++ b/exec.c
+@@ -3608,9 +3608,6 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr len,
+ #define ARG1                     as
+ #define SUFFIX
+ #define TRANSLATE(...)           address_space_translate(as, __VA_ARGS__)
+-#define IS_DIRECT(mr, is_write)  memory_access_is_direct(mr, is_write)
+-#define MAP_RAM(mr, ofs)         qemu_map_ram_ptr((mr)->ram_block, ofs)
+-#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
+ #define RCU_READ_LOCK(...)       rcu_read_lock()
+ #define RCU_READ_UNLOCK(...)     rcu_read_unlock()
+ #include "memory_ldst.inc.c"
+@@ -3643,9 +3640,6 @@ void address_space_cache_destroy(MemoryRegionCache *cache)
+ #define SUFFIX                   _cached
+ #define TRANSLATE(addr, ...)     \
+     address_space_translate(cache->as, cache->xlat + (addr), __VA_ARGS__)
+-#define IS_DIRECT(mr, is_write)  true
+-#define MAP_RAM(mr, ofs)         qemu_map_ram_ptr((mr)->ram_block, ofs)
+-#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
+ #define RCU_READ_LOCK()          rcu_read_lock()
+ #define RCU_READ_UNLOCK()        rcu_read_unlock()
+ #include "memory_ldst.inc.c"
+diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
+index 5dbff9c..a30060c 100644
+--- a/memory_ldst.inc.c
++++ b/memory_ldst.inc.c
+@@ -34,7 +34,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, false);
+-    if (l < 4 || !IS_DIRECT(mr, false)) {
++    if (l < 4 || !memory_access_is_direct(mr, false)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+         /* I/O case */
+@@ -50,7 +50,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
+ #endif
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         switch (endian) {
+         case DEVICE_LITTLE_ENDIAN:
+             val = ldl_le_p(ptr);
+@@ -128,7 +128,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, false);
+-    if (l < 8 || !IS_DIRECT(mr, false)) {
++    if (l < 8 || !memory_access_is_direct(mr, false)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+         /* I/O case */
+@@ -144,7 +144,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
+ #endif
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         switch (endian) {
+         case DEVICE_LITTLE_ENDIAN:
+             val = ldq_le_p(ptr);
+@@ -220,14 +220,14 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, false);
+-    if (!IS_DIRECT(mr, false)) {
++    if (!memory_access_is_direct(mr, false)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+         /* I/O case */
+         r = memory_region_dispatch_read(mr, addr1, &val, 1, attrs);
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         val = ldub_p(ptr);
+         r = MEMTX_OK;
+     }
+@@ -262,7 +262,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, false);
+-    if (l < 2 || !IS_DIRECT(mr, false)) {
++    if (l < 2 || !memory_access_is_direct(mr, false)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+         /* I/O case */
+@@ -278,7 +278,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
+ #endif
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         switch (endian) {
+         case DEVICE_LITTLE_ENDIAN:
+             val = lduw_le_p(ptr);
+@@ -357,12 +357,12 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, true);
+-    if (l < 4 || !IS_DIRECT(mr, true)) {
++    if (l < 4 || !memory_access_is_direct(mr, true)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+     } else {
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         stl_p(ptr, val);
+ 
+         dirty_log_mask = memory_region_get_dirty_log_mask(mr);
+@@ -400,7 +400,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, true);
+-    if (l < 4 || !IS_DIRECT(mr, true)) {
++    if (l < 4 || !memory_access_is_direct(mr, true)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+ #if defined(TARGET_WORDS_BIGENDIAN)
+@@ -415,7 +415,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
+         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         switch (endian) {
+         case DEVICE_LITTLE_ENDIAN:
+             stl_le_p(ptr, val);
+@@ -427,7 +427,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
+             stl_p(ptr, val);
+             break;
+         }
+-        INVALIDATE(mr, addr1, 4);
++        invalidate_and_set_dirty(mr, addr1, 4);
+         r = MEMTX_OK;
+     }
+     if (result) {
+@@ -490,14 +490,14 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, true);
+-    if (!IS_DIRECT(mr, true)) {
++    if (!memory_access_is_direct(mr, true)) {
+         release_lock |= prepare_mmio_access(mr);
+         r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         stb_p(ptr, val);
+-        INVALIDATE(mr, addr1, 1);
++        invalidate_and_set_dirty(mr, addr1, 1);
+         r = MEMTX_OK;
+     }
+     if (result) {
+@@ -529,7 +529,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, true);
+-    if (l < 2 || !IS_DIRECT(mr, true)) {
++    if (l < 2 || !memory_access_is_direct(mr, true)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+ #if defined(TARGET_WORDS_BIGENDIAN)
+@@ -544,7 +544,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
+         r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         switch (endian) {
+         case DEVICE_LITTLE_ENDIAN:
+             stw_le_p(ptr, val);
+@@ -556,7 +556,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
+             stw_p(ptr, val);
+             break;
+         }
+-        INVALIDATE(mr, addr1, 2);
++        invalidate_and_set_dirty(mr, addr1, 2);
+         r = MEMTX_OK;
+     }
+     if (result) {
+@@ -620,7 +620,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
+ 
+     RCU_READ_LOCK();
+     mr = TRANSLATE(addr, &addr1, &l, true);
+-    if (l < 8 || !IS_DIRECT(mr, true)) {
++    if (l < 8 || !memory_access_is_direct(mr, true)) {
+         release_lock |= prepare_mmio_access(mr);
+ 
+ #if defined(TARGET_WORDS_BIGENDIAN)
+@@ -635,7 +635,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
+         r = memory_region_dispatch_write(mr, addr1, val, 8, attrs);
+     } else {
+         /* RAM case */
+-        ptr = MAP_RAM(mr, addr1);
++        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+         switch (endian) {
+         case DEVICE_LITTLE_ENDIAN:
+             stq_le_p(ptr, val);
+@@ -647,7 +647,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
+             stq_p(ptr, val);
+             break;
+         }
+-        INVALIDATE(mr, addr1, 8);
++        invalidate_and_set_dirty(mr, addr1, 8);
+         r = MEMTX_OK;
+     }
+     if (result) {
+@@ -702,8 +702,5 @@ void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
+ #undef ARG1
+ #undef SUFFIX
+ #undef TRANSLATE
+-#undef IS_DIRECT
+-#undef MAP_RAM
+-#undef INVALIDATE
+ #undef RCU_READ_LOCK
+ #undef RCU_READ_UNLOCK
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-fw_cfg-Fix-boot-bootsplash-error-checking.patch b/SOURCES/kvm-fw_cfg-Fix-boot-bootsplash-error-checking.patch
new file mode 100644
index 0000000..c838f38
--- /dev/null
+++ b/SOURCES/kvm-fw_cfg-Fix-boot-bootsplash-error-checking.patch
@@ -0,0 +1,122 @@
+From f798645d16957453ee49a5a2945ed80eeb87cd15 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Mon, 7 Oct 2019 07:35:07 +0100
+Subject: [PATCH 14/22] fw_cfg: Fix -boot bootsplash error checking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <20191007073509.5887-3-armbru@redhat.com>
+Patchwork-id: 90980
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 2/4] fw_cfg: Fix -boot bootsplash error checking
+Bugzilla: 1607367
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Li Qiang <liq3ea@gmail.com>
+
+fw_cfg_bootsplash() gets option parameter "splash-time"
+with qemu_opt_get(), then converts it to an integer by hand.
+It neglects to check that conversion for errors. This is
+needlessly complicated and error-prone. But as "splash-time
+not specified" is not the same as "splash-time=T" for any T,
+we need use qemu_opt_get() to check if splash time exists.
+This patch also make the qemu exit when finding or loading
+splash file failed.
+
+Signed-off-by: Li Qiang <liq3ea@gmail.com>
+Reviewed-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-Id: <1542777026-2788-2-git-send-email-liq3ea@gmail.com>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+(cherry picked from commit 6912bb0b3d3b140c70d8cdfd2dff77f9890d7f12)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/nvram/fw_cfg.c | 35 +++++++++++++----------------------
+ vl.c              |  2 +-
+ 2 files changed, 14 insertions(+), 23 deletions(-)
+
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index d35ac7b..d7185ea 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -117,47 +117,38 @@ error:
+ 
+ static void fw_cfg_bootsplash(FWCfgState *s)
+ {
+-    int boot_splash_time = -1;
+     const char *boot_splash_filename = NULL;
+-    char *p;
++    const char *boot_splash_time = NULL;
+     char *filename, *file_data;
+     gsize file_size;
+     int file_type;
+-    const char *temp;
+ 
+     /* get user configuration */
+     QemuOptsList *plist = qemu_find_opts("boot-opts");
+     QemuOpts *opts = QTAILQ_FIRST(&plist->head);
+-    if (opts != NULL) {
+-        temp = qemu_opt_get(opts, "splash");
+-        if (temp != NULL) {
+-            boot_splash_filename = temp;
+-        }
+-        temp = qemu_opt_get(opts, "splash-time");
+-        if (temp != NULL) {
+-            p = (char *)temp;
+-            boot_splash_time = strtol(p, &p, 10);
+-        }
+-    }
++    boot_splash_filename = qemu_opt_get(opts, "splash");
++    boot_splash_time = qemu_opt_get(opts, "splash-time");
+ 
+     /* insert splash time if user configurated */
+-    if (boot_splash_time >= 0) {
++    if (boot_splash_time) {
++        int64_t bst_val = qemu_opt_get_number(opts, "splash-time", -1);
+         /* validate the input */
+-        if (boot_splash_time > 0xffff) {
+-            error_report("splash time is big than 65535, force it to 65535.");
+-            boot_splash_time = 0xffff;
++        if (bst_val < 0 || bst_val > 0xffff) {
++            error_report("splash-time is invalid,"
++                         "it should be a value between 0 and 65535");
++            exit(1);
+         }
+         /* use little endian format */
+-        qemu_extra_params_fw[0] = (uint8_t)(boot_splash_time & 0xff);
+-        qemu_extra_params_fw[1] = (uint8_t)((boot_splash_time >> 8) & 0xff);
++        qemu_extra_params_fw[0] = (uint8_t)(bst_val & 0xff);
++        qemu_extra_params_fw[1] = (uint8_t)((bst_val >> 8) & 0xff);
+         fw_cfg_add_file(s, "etc/boot-menu-wait", qemu_extra_params_fw, 2);
+     }
+ 
+     /* insert splash file if user configurated */
+-    if (boot_splash_filename != NULL) {
++    if (boot_splash_filename) {
+         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, boot_splash_filename);
+         if (filename == NULL) {
+-            error_report("failed to find file '%s'.", boot_splash_filename);
++            error_report("failed to find file '%s'", boot_splash_filename);
+             return;
+         }
+ 
+diff --git a/vl.c b/vl.c
+index c778594..e2212f5 100644
+--- a/vl.c
++++ b/vl.c
+@@ -364,7 +364,7 @@ static QemuOptsList qemu_boot_opts = {
+             .type = QEMU_OPT_STRING,
+         }, {
+             .name = "splash-time",
+-            .type = QEMU_OPT_STRING,
++            .type = QEMU_OPT_NUMBER,
+         }, {
+             .name = "reboot-timeout",
+             .type = QEMU_OPT_STRING,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-fw_cfg-Fix-boot-reboot-timeout-error-checking.patch b/SOURCES/kvm-fw_cfg-Fix-boot-reboot-timeout-error-checking.patch
new file mode 100644
index 0000000..188ceb4
--- /dev/null
+++ b/SOURCES/kvm-fw_cfg-Fix-boot-reboot-timeout-error-checking.patch
@@ -0,0 +1,99 @@
+From 07c499baed0c800e43cd6ec867fc465dea43567d Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Mon, 7 Oct 2019 07:35:08 +0100
+Subject: [PATCH 15/22] fw_cfg: Fix -boot reboot-timeout error checking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <20191007073509.5887-4-armbru@redhat.com>
+Patchwork-id: 90979
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 3/4] fw_cfg: Fix -boot reboot-timeout error checking
+Bugzilla: 1607367
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Li Qiang <liq3ea@gmail.com>
+
+fw_cfg_reboot() gets option parameter "reboot-timeout" with
+qemu_opt_get(), then converts it to an integer by hand. It neglects to
+check that conversion for errors, and fails to reject negative values.
+Positive values above the limit get reported and replaced by the limit.
+This patch checks for conversion errors properly, and reject all values
+outside 0...0xffff.
+
+Signed-off-by: Li Qiang <liq3ea@gmail.com>
+Reviewed-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-Id: <1542777026-2788-3-git-send-email-liq3ea@gmail.com>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+(cherry picked from commit ee5d0f89de3e53cdb0dcf51acc1502b310ed3bd2)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/nvram/fw_cfg.c | 27 +++++++++++++--------------
+ vl.c              |  2 +-
+ 2 files changed, 14 insertions(+), 15 deletions(-)
+
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index d7185ea..02ab458 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -176,26 +176,25 @@ static void fw_cfg_bootsplash(FWCfgState *s)
+ 
+ static void fw_cfg_reboot(FWCfgState *s)
+ {
+-    int reboot_timeout = -1;
+-    char *p;
+-    const char *temp;
++    const char *reboot_timeout = NULL;
++    int64_t rt_val = -1;
+ 
+     /* get user configuration */
+     QemuOptsList *plist = qemu_find_opts("boot-opts");
+     QemuOpts *opts = QTAILQ_FIRST(&plist->head);
+-    if (opts != NULL) {
+-        temp = qemu_opt_get(opts, "reboot-timeout");
+-        if (temp != NULL) {
+-            p = (char *)temp;
+-            reboot_timeout = strtol(p, &p, 10);
++    reboot_timeout = qemu_opt_get(opts, "reboot-timeout");
++
++    if (reboot_timeout) {
++        rt_val = qemu_opt_get_number(opts, "reboot-timeout", -1);
++        /* validate the input */
++        if (rt_val < 0 || rt_val > 0xffff) {
++            error_report("reboot timeout is invalid,"
++                         "it should be a value between 0 and 65535");
++            exit(1);
+         }
+     }
+-    /* validate the input */
+-    if (reboot_timeout > 0xffff) {
+-        error_report("reboot timeout is larger than 65535, force it to 65535.");
+-        reboot_timeout = 0xffff;
+-    }
+-    fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&reboot_timeout, 4), 4);
++
++    fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&rt_val, 4), 4);
+ }
+ 
+ static void fw_cfg_write(FWCfgState *s, uint8_t value)
+diff --git a/vl.c b/vl.c
+index e2212f5..3cee95f 100644
+--- a/vl.c
++++ b/vl.c
+@@ -367,7 +367,7 @@ static QemuOptsList qemu_boot_opts = {
+             .type = QEMU_OPT_NUMBER,
+         }, {
+             .name = "reboot-timeout",
+-            .type = QEMU_OPT_STRING,
++            .type = QEMU_OPT_NUMBER,
+         }, {
+             .name = "strict",
+             .type = QEMU_OPT_BOOL,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-fw_cfg-Improve-error-message-when-can-t-load-splash-.patch b/SOURCES/kvm-fw_cfg-Improve-error-message-when-can-t-load-splash-.patch
new file mode 100644
index 0000000..f9ca4b2
--- /dev/null
+++ b/SOURCES/kvm-fw_cfg-Improve-error-message-when-can-t-load-splash-.patch
@@ -0,0 +1,62 @@
+From f11136998ed22e121b0a9df26f83e252bd5918fa Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Mon, 7 Oct 2019 07:35:06 +0100
+Subject: [PATCH 13/22] fw_cfg: Improve error message when can't load splash
+ file
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <20191007073509.5887-2-armbru@redhat.com>
+Patchwork-id: 90978
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 1/4] fw_cfg: Improve error message when can't load splash file
+Bugzilla: 1607367
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Li Qiang <liq3ea@gmail.com>
+
+read_splashfile() reports "failed to read splash file" without
+further details. Get the details from g_file_get_contents(), and
+include them in the error message. Also remove unnecessary 'res'
+variable.
+
+Signed-off-by: Li Qiang <liq3ea@gmail.com>
+Reviewed-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-Id: <1541052148-28752-1-git-send-email-liq3ea@gmail.com>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+(cherry picked from commit bed66336771ecdcb788d394bdd081a78b843e509)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/nvram/fw_cfg.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index 2a0739d..d35ac7b 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -68,15 +68,14 @@ static char *read_splashfile(char *filename, gsize *file_sizep,
+                              int *file_typep)
+ {
+     GError *err = NULL;
+-    gboolean res;
+     gchar *content;
+     int file_type;
+     unsigned int filehead;
+     int bmp_bpp;
+ 
+-    res = g_file_get_contents(filename, &content, file_sizep, &err);
+-    if (res == FALSE) {
+-        error_report("failed to read splash file '%s'", filename);
++    if (!g_file_get_contents(filename, &content, file_sizep, &err)) {
++        error_report("failed to read splash file '%s': %s",
++                     filename, err->message);
+         g_error_free(err);
+         return NULL;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-nvram-fw_cfg-Store-reboot-timeout-as-little-endia.patch b/SOURCES/kvm-hw-nvram-fw_cfg-Store-reboot-timeout-as-little-endia.patch
new file mode 100644
index 0000000..058f595
--- /dev/null
+++ b/SOURCES/kvm-hw-nvram-fw_cfg-Store-reboot-timeout-as-little-endia.patch
@@ -0,0 +1,80 @@
+From 5bb1365ea92b83615937e3082a9c250728384989 Mon Sep 17 00:00:00 2001
+From: Markus Armbruster <armbru@redhat.com>
+Date: Mon, 7 Oct 2019 07:35:09 +0100
+Subject: [PATCH 16/22] hw/nvram/fw_cfg: Store 'reboot-timeout' as little
+ endian
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Markus Armbruster <armbru@redhat.com>
+Message-id: <20191007073509.5887-5-armbru@redhat.com>
+Patchwork-id: 90976
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 4/4] hw/nvram/fw_cfg: Store 'reboot-timeout' as little endian
+Bugzilla: 1607367
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Li Qiang <liq3ea@163.com>
+
+The current codebase is not specific about the endianess of the
+fw_cfg 'file' entry 'reboot-timeout'.
+
+Per docs/specs/fw_cfg.txt:
+
+  === All Other Data Items ===
+
+  Please consult the QEMU source for the most up-to-date
+  and authoritative list of selector keys and their respective
+  items' purpose, format and writeability.
+
+Checking the git history, this code was introduced in commit
+ac05f3492421, very similar to commit 3d3b8303c6f8 for the
+'boot-menu-wait' entry, which explicitely use little-endian.
+
+OVMF consumes 'boot-menu-wait' as little-endian, however it does
+not consume 'reboot-timeout'.
+
+Regarding the git history and OVMF use, we choose to explicit
+'reboot-timeout' endianess as little-endian.
+
+Signed-off-by: Li Qiang <liq3ea@163.com>
+Tested-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-Id: <20190424140643.62457-4-liq3ea@163.com>
+[PMD: Reword commit description based on review comments]
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+(cherry picked from commit 04da973501b591525ce68c2925c61c8886badd4d)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/nvram/fw_cfg.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
+index 02ab458..954de33 100644
+--- a/hw/nvram/fw_cfg.c
++++ b/hw/nvram/fw_cfg.c
+@@ -178,6 +178,7 @@ static void fw_cfg_reboot(FWCfgState *s)
+ {
+     const char *reboot_timeout = NULL;
+     int64_t rt_val = -1;
++    uint32_t rt_le32;
+ 
+     /* get user configuration */
+     QemuOptsList *plist = qemu_find_opts("boot-opts");
+@@ -194,7 +195,8 @@ static void fw_cfg_reboot(FWCfgState *s)
+         }
+     }
+ 
+-    fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&rt_val, 4), 4);
++    rt_le32 = cpu_to_le32(rt_val);
++    fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(&rt_le32, 4), 4);
+ }
+ 
+ static void fw_cfg_write(FWCfgState *s, uint8_t value)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-Add-x-force-features-option-for-testing.patch b/SOURCES/kvm-i386-Add-x-force-features-option-for-testing.patch
new file mode 100644
index 0000000..3281581
--- /dev/null
+++ b/SOURCES/kvm-i386-Add-x-force-features-option-for-testing.patch
@@ -0,0 +1,80 @@
+From d5526e43ccf3532aa3a0f592e6df5740983a94e2 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:35 +0000
+Subject: [PATCH 02/16] i386: Add x-force-features option for testing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-3-pbonzini@redhat.com>
+Patchwork-id: 92602
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 02/15] i386: Add x-force-features option for testing
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+From: Eduardo Habkost <ehabkost@redhat.com>
+
+Add a new option that can be used to disable feature flag
+filtering.  This will allow CPU model compatibility test cases to
+work without host hardware dependencies.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20190628002844.24894-3-ehabkost@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit dac1deae658539e39966e12b12378a28e3dc8441)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 8 ++++++--
+ target/i386/cpu.h | 6 ++++++
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index c69116c..8c1338f 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -5019,8 +5019,11 @@ static int x86_cpu_filter_features(X86CPU *cpu)
+         uint32_t host_feat =
+             x86_cpu_get_supported_feature_word(w, false);
+         uint32_t requested_features = env->features[w];
+-        env->features[w] &= host_feat;
+-        cpu->filtered_features[w] = requested_features & ~env->features[w];
++        uint32_t available_features = requested_features & host_feat;
++        if (!cpu->force_features) {
++            env->features[w] = available_features;
++        }
++        cpu->filtered_features[w] = requested_features & ~available_features;
+         if (cpu->filtered_features[w]) {
+             rv = 1;
+         }
+@@ -5680,6 +5683,7 @@ static Property x86_cpu_properties[] = {
+     DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
+     DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
+     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
++    DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false),
+     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
+     DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
+     DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index add8b60..1ad54bd 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -1394,6 +1394,12 @@ struct X86CPU {
+     bool hyperv_frequencies;
+     bool check_cpuid;
+     bool enforce_cpuid;
++    /*
++     * Force features to be enabled even if the host doesn't support them.
++     * This is dangerous and should be done only for testing CPUID
++     * compatibility.
++     */
++    bool force_features;
+     bool expose_kvm;
+     bool expose_tcg;
+     bool migratable;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-Don-t-print-warning-if-phys-bits-was-set-automa.patch b/SOURCES/kvm-i386-Don-t-print-warning-if-phys-bits-was-set-automa.patch
new file mode 100644
index 0000000..d64dbc9
--- /dev/null
+++ b/SOURCES/kvm-i386-Don-t-print-warning-if-phys-bits-was-set-automa.patch
@@ -0,0 +1,79 @@
+From 7e78c8e8b5a9cab9ef4604dc29eab4b4323e9b9b Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Tue, 13 Aug 2019 01:53:55 +0100
+Subject: [PATCH 01/21] i386: Don't print warning if phys-bits was set
+ automatically
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20190813015355.17556-1-ehabkost@redhat.com>
+Patchwork-id: 89946
+O-Subject: [RHEL-8.1.0 qemu-kvm PATCH] i386: Don't print warning if phys-bits was set automatically
+Bugzilla: 1719127
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1719127
+BRANCH: rhel-8.1.0
+UPSTREAM: fea306520ea4b2f189dd23c70a6afd2fc4ffafdc
+BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23026463
+
+If cpu->host_phys_bits_limit is set, QEMU will make
+cpu->phys_bits be lower than host_phys_bits on some cases.  This
+triggers a warning that was supposed to be printed only if
+phys-bits was explicitly set in the command-line.
+
+Reorder the code so the value of cpu->phys_bits is validated
+before the cpu->host_phys_bits handling.  This will avoid
+unexpected warnings when cpu->host_phys_bits_limit is set.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20190611205420.20286-1-ehabkost@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit fea306520ea4b2f189dd23c70a6afd2fc4ffafdc)
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index c8f50a7..c69116c 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -5116,15 +5116,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+             uint32_t host_phys_bits = x86_host_phys_bits();
+             static bool warned;
+ 
+-            if (cpu->host_phys_bits) {
+-                /* The user asked for us to use the host physical bits */
+-                cpu->phys_bits = host_phys_bits;
+-                if (cpu->host_phys_bits_limit &&
+-                    cpu->phys_bits > cpu->host_phys_bits_limit) {
+-                    cpu->phys_bits = cpu->host_phys_bits_limit;
+-                }
+-            }
+-
+             /* Print a warning if the user set it to a value that's not the
+              * host value.
+              */
+@@ -5136,6 +5127,15 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+                 warned = true;
+             }
+ 
++            if (cpu->host_phys_bits) {
++                /* The user asked for us to use the host physical bits */
++                cpu->phys_bits = host_phys_bits;
++                if (cpu->host_phys_bits_limit &&
++                    cpu->phys_bits > cpu->host_phys_bits_limit) {
++                    cpu->phys_bits = cpu->host_phys_bits_limit;
++                }
++            }
++
+             if (cpu->phys_bits &&
+                 (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
+                 cpu->phys_bits < 32)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-Remove-cpu64-rhel6-CPU-model.patch b/SOURCES/kvm-i386-Remove-cpu64-rhel6-CPU-model.patch
new file mode 100644
index 0000000..9358f45
--- /dev/null
+++ b/SOURCES/kvm-i386-Remove-cpu64-rhel6-CPU-model.patch
@@ -0,0 +1,77 @@
+From d52cded7f0cab801cfd59c4c97f70f48f332c1bb Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Mon, 23 Dec 2019 21:17:05 +0000
+Subject: [PATCH] i386: Remove cpu64-rhel6 CPU model
+
+RH-Author: Eduardo Habkost <ehabkost@redhat.com>
+Message-id: <20191223211705.34325-1-ehabkost@redhat.com>
+Patchwork-id: 93214
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH] i386: Remove cpu64-rhel6 CPU model
+Bugzilla: 1741346
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1741346
+BRANCH: rhel-8.2.0
+Upstream: not applicable
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=25526009
+
+We don't provide rhel6 machine types anymore, so we don't need to
+provide compatibility with RHEl6.  cpu64-rhel6 was documented as
+deprecated and scheduled for removal in 8.2, so now it's time to
+remove it.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 26 +-------------------------
+ 1 file changed, 1 insertion(+), 25 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 0717c66..33abc24 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1739,12 +1739,7 @@ static CPUCaches epyc_cache_info = {
+ 
+ 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.
+-         */
++        /* qemu64 is the default CPU model for all machine-types */
+         .name = "qemu64",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_AMD,
+@@ -2045,25 +2040,6 @@ 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_NX | CPUID_EXT2_SYSCALL,
+-        .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,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-cpu-make-cpu-host-support-monitor-mwait.patch b/SOURCES/kvm-i386-cpu-make-cpu-host-support-monitor-mwait.patch
new file mode 100644
index 0000000..19f6d86
--- /dev/null
+++ b/SOURCES/kvm-i386-cpu-make-cpu-host-support-monitor-mwait.patch
@@ -0,0 +1,132 @@
+From 91ac1f511b0414292d07688c3cb3012bed6e3649 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Fri, 22 Jun 2018 22:22:05 +0300
+Subject: [PATCH 09/11] i386/cpu: make -cpu host support monitor/mwait
+
+When guest CPU PM is enabled, and with -cpu host, expose the host CPU
+MWAIT leaf in the CPUID so guest can make good PM decisions.
+
+Note: the result is 100% CPU utilization reported by host as host
+no longer knows that the CPU is halted.
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180622192148.178309-3-mst@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ accel/tcg/user-exec-stub.c |  3 +++
+ target/i386/cpu.c          | 32 ++++++++++++++++++++++----------
+ target/i386/cpu.h          |  9 +++++++++
+ target/i386/kvm.c          |  9 +++++++++
+ 4 files changed, 43 insertions(+), 10 deletions(-)
+
+diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c
+index dbcf1ad..a32b449 100644
+--- a/accel/tcg/user-exec-stub.c
++++ b/accel/tcg/user-exec-stub.c
+@@ -2,6 +2,9 @@
+ #include "qemu-common.h"
+ #include "qom/cpu.h"
+ #include "sysemu/replay.h"
++#include "sysemu/sysemu.h"
++
++bool enable_cpu_pm = false;
+ 
+ void cpu_resume(CPUState *cpu)
+ {
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 307b629..87b0502 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -5662,11 +5662,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+         }
+         break;
+     case 5:
+-        /* mwait info: needed for Core compatibility */
+-        *eax = 0; /* Smallest monitor-line size in bytes */
+-        *ebx = 0; /* Largest monitor-line size in bytes */
+-        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+-        *edx = 0;
++        /* MONITOR/MWAIT Leaf */
++        *eax = cpu->mwait.eax; /* Smallest monitor-line size in bytes */
++        *ebx = cpu->mwait.ebx; /* Largest monitor-line size in bytes */
++        *ecx = cpu->mwait.ecx; /* flags */
++        *edx = cpu->mwait.edx; /* mwait substates */
+         break;
+     case 6:
+         /* Thermal and Power Leaf */
+@@ -6521,13 +6521,25 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+     Error *local_err = NULL;
+     static bool ht_warned;
+ 
+-    if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
+-        char *name = x86_cpu_class_get_model_name(xcc);
+-        error_setg(&local_err, "CPU model '%s' requires KVM", name);
+-        g_free(name);
+-        goto out;
++    if (xcc->host_cpuid_required) {
++        if (!accel_uses_host_cpuid()) {
++            char *name = x86_cpu_class_get_model_name(xcc);
++            error_setg(&local_err, "CPU model '%s' requires KVM", name);
++            g_free(name);
++            goto out;
++        }
++
++        if (enable_cpu_pm) {
++            host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
++                       &cpu->mwait.ecx, &cpu->mwait.edx);
++            env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
++        }
+     }
+ 
++    /* mwait extended info: needed for Core compatibility */
++    /* We always wake on interrupt even if host does not have the capability */
++    cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
++
+     if (cpu->apic_id == UNASSIGNED_APIC_ID) {
+         error_setg(errp, "apic-id property was not initialized properly");
+         return;
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index d33fa8d..7ab8ee9 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -1564,6 +1564,15 @@ struct X86CPU {
+     /* if true the CPUID code directly forward host cache leaves to the guest */
+     bool cache_info_passthrough;
+ 
++    /* if true the CPUID code directly forwards
++     * host monitor/mwait leaves to the guest */
++    struct {
++        uint32_t eax;
++        uint32_t ebx;
++        uint32_t ecx;
++        uint32_t edx;
++    } mwait;
++
+     /* Features that were filtered out because of missing host capabilities */
+     FeatureWordArray filtered_features;
+ 
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 879c3e0..ffd01f0 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -377,6 +377,15 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
+         if (!kvm_irqchip_in_kernel()) {
+             ret &= ~CPUID_EXT_X2APIC;
+         }
++
++        if (enable_cpu_pm) {
++            int disable_exits = kvm_check_extension(s,
++                                                    KVM_CAP_X86_DISABLE_EXITS);
++
++            if (disable_exits & KVM_X86_DISABLE_EXITS_MWAIT) {
++                ret |= CPUID_EXT_MONITOR;
++            }
++        }
+     } else if (function == 6 && reg == R_EAX) {
+         ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */
+     } else if (function == 7 && index == 0 && reg == R_EBX) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-display-known-CPUID-features-linewrapped-in-alp.patch b/SOURCES/kvm-i386-display-known-CPUID-features-linewrapped-in-alp.patch
new file mode 100644
index 0000000..50e63b4
--- /dev/null
+++ b/SOURCES/kvm-i386-display-known-CPUID-features-linewrapped-in-alp.patch
@@ -0,0 +1,119 @@
+From e7f11d39d1ef78f47ed6d45ecd278d51c502f131 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:37 +0000
+Subject: [PATCH 04/16] i386: display known CPUID features linewrapped, in
+ alphabetical order
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-5-pbonzini@redhat.com>
+Patchwork-id: 92605
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 04/15] i386: display known CPUID features linewrapped, in alphabetical order
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+When using '-cpu help' the list of CPUID features is grouped according
+to the internal low level CPUID grouping. The data printed results in
+very long lines too.
+
+This combines to make it hard for users to read the output and identify
+if QEMU knows about the feature they wish to use.
+
+This change gets rid of the grouping of features and treats all flags as
+single list. The list is sorted into alphabetical order and the printing
+with line wrapping at the 77th column.
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180606165527.17365-4-berrange@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit cc643b1e7898414b56f551bbd42d4ed8c2ae127a)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 41 +++++++++++++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 52f1f33..d0c48c2 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3651,17 +3651,21 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
+ 
+ /* Print all cpuid feature names in featureset
+  */
+-static void listflags(FILE *f, fprintf_function print, const char **featureset)
++static void listflags(FILE *f, fprintf_function print, GList *features)
+ {
+-    int bit;
+-    bool first = true;
+-
+-    for (bit = 0; bit < 32; bit++) {
+-        if (featureset[bit]) {
+-            print(f, "%s%s", first ? "" : " ", featureset[bit]);
+-            first = false;
++    size_t len = 0;
++    GList *tmp;
++
++    for (tmp = features; tmp; tmp = tmp->next) {
++        const char *name = tmp->data;
++        if ((len + strlen(name) + 1) >= 75) {
++            print(f, "\n");
++            len = 0;
+         }
++        print(f, "%s%s", len == 0 ? "  " : " ", name);
++        len += strlen(name) + 1;
+     }
++    print(f, "\n");
+ }
+ 
+ /* Sort alphabetically by type name, respecting X86CPUClass::ordering. */
+@@ -3708,26 +3712,35 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data)
+ /* list available CPU models and flags */
+ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+ {
+-    int i;
++    int i, j;
+     CPUListState s = {
+         .file = f,
+         .cpu_fprintf = cpu_fprintf,
+     };
+     GSList *list;
++    GList *names = NULL;
+ 
+     (*cpu_fprintf)(f, "Available CPUs:\n");
+     list = get_sorted_cpu_model_list();
+     g_slist_foreach(list, x86_cpu_list_entry, &s);
+     g_slist_free(list);
+ 
+-    (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
++    names = NULL;
+     for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
+         FeatureWordInfo *fw = &feature_word_info[i];
+-
+-        (*cpu_fprintf)(f, "  ");
+-        listflags(f, cpu_fprintf, fw->feat_names);
+-        (*cpu_fprintf)(f, "\n");
++        for (j = 0; j < 32; j++) {
++            if (fw->feat_names[j]) {
++                names = g_list_append(names, (gpointer)fw->feat_names[j]);
++            }
++        }
+     }
++
++    names = g_list_sort(names, (GCompareFunc)strcmp);
++
++    (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
++    listflags(f, cpu_fprintf, names);
++    (*cpu_fprintf)(f, "\n");
++    g_list_free(names);
+ }
+ 
+ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-fix-regression-parsing-multiboot-initrd-modules.patch b/SOURCES/kvm-i386-fix-regression-parsing-multiboot-initrd-modules.patch
new file mode 100644
index 0000000..0f80206
--- /dev/null
+++ b/SOURCES/kvm-i386-fix-regression-parsing-multiboot-initrd-modules.patch
@@ -0,0 +1,83 @@
+From dc98e8dd5c4aad2f3c480a9513ffba89540dcf3f Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 12 Sep 2019 13:05:01 +0100
+Subject: [PATCH 04/22] i386: fix regression parsing multiboot initrd modules
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laszlo Ersek <lersek@redhat.com>
+Message-id: <20190912130503.14094-5-lersek@redhat.com>
+Patchwork-id: 90434
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 4/6] i386: fix regression parsing multiboot initrd modules
+Bugzilla: 1749022
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+The logic for parsing the multiboot initrd modules was messed up in
+
+  commit 950c4e6c94b15cd0d8b63891dddd7a8dbf458e6a
+  Author: Daniel P. Berrangé <berrange@redhat.com>
+  Date:   Mon Apr 16 12:17:43 2018 +0100
+
+    opts: don't silently truncate long option values
+
+Causing the length to be undercounter, and the number of modules over
+counted. It also passes NULL to get_opt_value() which was not robust
+at accepting a NULL value.
+
+RHEL8 notes:
+
+- Context difference in "util/qemu-option.c", function get_opt_value();
+  upstream has commit 5c99fa375da1 ("cutils: Provide strchrnul",
+  2018-06-29), part of v3.0.0, but downstream lacks it. Harmless, because
+  said upstream commit only refactors get_opt_value().
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180514171913.17664-2-berrange@redhat.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Tested-by: Roman Kagan <rkagan@virtuozzo.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 6e3ad3f0e31b8e31c6c0769d0f474bcd9673e0e5)
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/multiboot.c | 3 +--
+ util/qemu-option.c  | 4 +++-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
+index 7a2953e..8e26545 100644
+--- a/hw/i386/multiboot.c
++++ b/hw/i386/multiboot.c
+@@ -292,8 +292,7 @@ int load_multiboot(FWCfgState *fw_cfg,
+     cmdline_len += strlen(kernel_cmdline) + 1;
+     if (initrd_filename) {
+         const char *r = get_opt_value(initrd_filename, NULL);
+-        cmdline_len += strlen(r) + 1;
+-        mbs.mb_mods_avail = 1;
++        cmdline_len += strlen(initrd_filename) + 1;
+         while (1) {
+             mbs.mb_mods_avail++;
+             r = get_opt_value(r, NULL);
+diff --git a/util/qemu-option.c b/util/qemu-option.c
+index ba44a08..a396d60 100644
+--- a/util/qemu-option.c
++++ b/util/qemu-option.c
+@@ -75,7 +75,9 @@ const char *get_opt_value(const char *p, char **value)
+     size_t capacity = 0, length;
+     const char *offset;
+ 
+-    *value = NULL;
++    if (value) {
++        *value = NULL;
++    }
+     while (1) {
+         offset = strchr(p, ',');
+         if (!offset) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-only-parse-the-initrd_filename-once-for-multibo.patch b/SOURCES/kvm-i386-only-parse-the-initrd_filename-once-for-multibo.patch
new file mode 100644
index 0000000..204cb8d
--- /dev/null
+++ b/SOURCES/kvm-i386-only-parse-the-initrd_filename-once-for-multibo.patch
@@ -0,0 +1,115 @@
+From b9d1e72a0910c3a0d11cb0a3c863938de344e0f5 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 12 Sep 2019 13:05:02 +0100
+Subject: [PATCH 05/22] i386: only parse the initrd_filename once for multiboot
+ modules
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laszlo Ersek <lersek@redhat.com>
+Message-id: <20190912130503.14094-6-lersek@redhat.com>
+Patchwork-id: 90438
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 5/6] i386: only parse the initrd_filename once for multiboot modules
+Bugzilla: 1749022
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+The multiboot code parses the initrd_filename twice, first to count how
+many entries there are, and second to process each entry. This changes
+the first loop to store the parse module names in a list, and the second
+loop can now use these names. This avoids having to pass NULL to the
+get_opt_value() method which means it can safely assume a non-NULL param.
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180514171913.17664-3-berrange@redhat.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Tested-by: Roman Kagan <rkagan@virtuozzo.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit f8da93a0ffa09268815c1942732cbc616a7db847)
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/multiboot.c | 32 +++++++++++++++-----------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
+index 8e26545..d519e20 100644
+--- a/hw/i386/multiboot.c
++++ b/hw/i386/multiboot.c
+@@ -161,6 +161,7 @@ int load_multiboot(FWCfgState *fw_cfg,
+     uint8_t bootinfo[MBI_SIZE];
+     uint8_t *mb_bootinfo_data;
+     uint32_t cmdline_len;
++    GList *mods = NULL;
+ 
+     /* Ok, let's see if it is a multiboot image.
+        The header is 12x32bit long, so the latest entry may be 8192 - 48. */
+@@ -291,15 +292,16 @@ int load_multiboot(FWCfgState *fw_cfg,
+     cmdline_len = strlen(kernel_filename) + 1;
+     cmdline_len += strlen(kernel_cmdline) + 1;
+     if (initrd_filename) {
+-        const char *r = get_opt_value(initrd_filename, NULL);
++        const char *r = initrd_filename;
+         cmdline_len += strlen(initrd_filename) + 1;
+-        while (1) {
++        while (*r) {
++            char *value;
++            r = get_opt_value(r, &value);
+             mbs.mb_mods_avail++;
+-            r = get_opt_value(r, NULL);
+-            if (!*r) {
+-                break;
++            mods = g_list_append(mods, value);
++            if (*r) {
++                r++;
+             }
+-            r++;
+         }
+     }
+ 
+@@ -314,20 +316,16 @@ int load_multiboot(FWCfgState *fw_cfg,
+     mbs.offset_cmdlines   = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
+     mbs.offset_bootloader = mbs.offset_cmdlines + cmdline_len;
+ 
+-    if (initrd_filename) {
+-        const char *next_initrd;
+-        char not_last;
+-        char *one_file = NULL;
+-
++    if (mods) {
++        GList *tmpl = mods;
+         mbs.offset_mods = mbs.mb_buf_size;
+ 
+-        do {
++        while (tmpl) {
+             char *next_space;
+             int mb_mod_length;
+             uint32_t offs = mbs.mb_buf_size;
++            char *one_file = tmpl->data;
+ 
+-            next_initrd = get_opt_value(initrd_filename, &one_file);
+-            not_last = *next_initrd;
+             /* if a space comes after the module filename, treat everything
+                after that as parameters */
+             hwaddr c = mb_add_cmdline(&mbs, one_file);
+@@ -352,10 +350,10 @@ int load_multiboot(FWCfgState *fw_cfg,
+             mb_debug("mod_start: %p\nmod_end:   %p\n  cmdline: "TARGET_FMT_plx,
+                      (char *)mbs.mb_buf + offs,
+                      (char *)mbs.mb_buf + offs + mb_mod_length, c);
+-            initrd_filename = next_initrd+1;
+             g_free(one_file);
+-            one_file = NULL;
+-        } while (not_last);
++            tmpl = tmpl->next;
++        }
++        g_list_free(mods);
+     }
+ 
+     /* Commandline support */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-intel_iommu-Correct-caching-mode-error-message.patch b/SOURCES/kvm-intel_iommu-Correct-caching-mode-error-message.patch
new file mode 100644
index 0000000..02b5255
--- /dev/null
+++ b/SOURCES/kvm-intel_iommu-Correct-caching-mode-error-message.patch
@@ -0,0 +1,59 @@
+From 8954b0306e2179987cd097d203057e780808b0ba Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Wed, 9 Oct 2019 12:39:43 +0100
+Subject: [PATCH 17/22] intel_iommu: Correct caching-mode error message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20191009123947.21505-2-peterx@redhat.com>
+Patchwork-id: 91350
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/5] intel_iommu: Correct caching-mode error message
+Bugzilla: 1738440
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+If we try to use the intel-iommu device with vfio-pci devices without
+caching mode enabled, we're told:
+
+  qemu-system-x86_64: We need to set caching-mode=1 for intel-iommu to enable
+  device assignment with IOMMU protection.
+
+But to enable caching mode, the option is actually "caching-mode=on".
+
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Message-Id: <155364147432.16467.15898335025013220939.stgit@gimli.home>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Reviewed-by: Laurent Vivier <laurent@vivier.eu>
+Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Signed-off-by: Alex Williamson &lt;<a href="mailto:alex.williamson@redhat.com" target="_blank" rel="noreferrer">alex.williamson@redhat.com</a>&gt;<br>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 75c5626c88a9675010018849ca9abc8d56045425)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/intel_iommu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
+index e827c5a..22d2e52 100644
+--- a/hw/i386/intel_iommu.c
++++ b/hw/i386/intel_iommu.c
+@@ -2554,7 +2554,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
+     IntelIOMMUState *s = vtd_as->iommu_state;
+ 
+     if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
+-        error_report("We need to set caching-mode=1 for intel-iommu to enable "
++        error_report("We need to set caching-mode=on for intel-iommu to enable "
+                      "device assignment with IOMMU protection.");
+         exit(1);
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-intel_iommu-Remove-the-caching-mode-check-during-fla.patch b/SOURCES/kvm-intel_iommu-Remove-the-caching-mode-check-during-fla.patch
new file mode 100644
index 0000000..1f45fc0
--- /dev/null
+++ b/SOURCES/kvm-intel_iommu-Remove-the-caching-mode-check-during-fla.patch
@@ -0,0 +1,49 @@
+From 01ab894f9d19a03aee876b0d1b468f7314765539 Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Wed, 9 Oct 2019 12:39:47 +0100
+Subject: [PATCH 21/22] intel_iommu: Remove the caching-mode check during flag
+ change
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20191009123947.21505-6-peterx@redhat.com>
+Patchwork-id: 91349
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 5/5] intel_iommu: Remove the caching-mode check during flag change
+Bugzilla: 1738440
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+
+That's never a good place to stop QEMU process... Since now we have
+both the machine done sanity check and also the hotplug handler, we
+can safely remove this to avoid that.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-Id: <20190916080718.3299-5-peterx@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit e7df189e19e86bf9f4d7aea4c6cf50ac0ebfce46)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/intel_iommu.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
+index 44d19cc..a4190bf 100644
+--- a/hw/i386/intel_iommu.c
++++ b/hw/i386/intel_iommu.c
+@@ -2561,10 +2561,6 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
+     VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
+     IntelIOMMUState *s = vtd_as->iommu_state;
+ 
+-    if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
+-        vtd_panic_require_caching_mode();
+-    }
+-
+     /* Update per-address-space notifier flags */
+     vtd_as->notifier_flags = new;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-intel_iommu-Sanity-check-vfio-pci-config-on-machine-.patch b/SOURCES/kvm-intel_iommu-Sanity-check-vfio-pci-config-on-machine-.patch
new file mode 100644
index 0000000..ed7753f
--- /dev/null
+++ b/SOURCES/kvm-intel_iommu-Sanity-check-vfio-pci-config-on-machine-.patch
@@ -0,0 +1,131 @@
+From 3a528a458d4a2ba4236e98ef3f4efe5482323972 Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Wed, 9 Oct 2019 12:39:44 +0100
+Subject: [PATCH 18/22] intel_iommu: Sanity check vfio-pci config on machine
+ init done
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20191009123947.21505-3-peterx@redhat.com>
+Patchwork-id: 91347
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/5] intel_iommu: Sanity check vfio-pci config on machine init done
+Bugzilla: 1738440
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+
+This check was previously only happened when the IOMMU is enabled in
+the guest.  It was always too late because the enabling of IOMMU
+normally only happens during the boot of guest OS.  It means that we
+can bail out and exit directly during the guest OS boots if the
+configuration of devices are not supported.  Or, if the guest didn't
+enable vIOMMU at all, then the user can use the guest normally but as
+long as it reconfigure the guest OS to enable the vIOMMU then reboot,
+the user will see the panic right after the reset when the next boot
+starts.
+
+Let's make this failure even earlier so that we force the user to use
+caching-mode for vfio-pci devices when with the vIOMMU.  So the user
+won't get surprise at least during execution of the guest, which seems
+a bit nicer.
+
+This will affect some user who didn't enable vIOMMU in the guest OS
+but was using vfio-pci and the vtd device in the past.  However I hope
+it's not a majority because not enabling vIOMMU with the device
+attached is actually meaningless.
+
+We still keep the old assertion for safety so far because the hotplug
+path could still reach it, so far.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-Id: <20190916080718.3299-2-peterx@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 28cf553afeb29b0c4f339c600171552a72a68cb7)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/intel_iommu.c | 39 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
+index 22d2e52..44d19cc 100644
+--- a/hw/i386/intel_iommu.c
++++ b/hw/i386/intel_iommu.c
+@@ -33,6 +33,7 @@
+ #include "hw/i386/x86-iommu.h"
+ #include "hw/pci-host/q35.h"
+ #include "sysemu/kvm.h"
++#include "sysemu/sysemu.h"
+ #include "hw/i386/apic_internal.h"
+ #include "kvm_i386.h"
+ #include "trace.h"
+@@ -40,6 +41,13 @@
+ static void vtd_address_space_refresh_all(IntelIOMMUState *s);
+ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
+ 
++static void vtd_panic_require_caching_mode(void)
++{
++    error_report("We need to set caching-mode=on for intel-iommu to enable "
++                 "device assignment with IOMMU protection.");
++    exit(1);
++}
++
+ static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val,
+                             uint64_t wmask, uint64_t w1cmask)
+ {
+@@ -2554,9 +2562,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
+     IntelIOMMUState *s = vtd_as->iommu_state;
+ 
+     if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
+-        error_report("We need to set caching-mode=on for intel-iommu to enable "
+-                     "device assignment with IOMMU protection.");
+-        exit(1);
++        vtd_panic_require_caching_mode();
+     }
+ 
+     /* Update per-address-space notifier flags */
+@@ -3303,6 +3309,32 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
+     return true;
+ }
+ 
++static int vtd_machine_done_notify_one(Object *child, void *unused)
++{
++    IntelIOMMUState *iommu = INTEL_IOMMU_DEVICE(x86_iommu_get_default());
++
++    /*
++     * We hard-coded here because vfio-pci is the only special case
++     * here.  Let's be more elegant in the future when we can, but so
++     * far there seems to be no better way.
++     */
++    if (object_dynamic_cast(child, "vfio-pci") && !iommu->caching_mode) {
++        vtd_panic_require_caching_mode();
++    }
++
++    return 0;
++}
++
++static void vtd_machine_done_hook(Notifier *notifier, void *unused)
++{
++    object_child_foreach_recursive(object_get_root(),
++                                   vtd_machine_done_notify_one, NULL);
++}
++
++static Notifier vtd_machine_done_notify = {
++    .notify = vtd_machine_done_hook,
++};
++
+ static void vtd_realize(DeviceState *dev, Error **errp)
+ {
+     MachineState *ms = MACHINE(qdev_get_machine());
+@@ -3333,6 +3365,7 @@ static void vtd_realize(DeviceState *dev, Error **errp)
+     pci_setup_iommu(bus, vtd_host_dma_iommu, dev);
+     /* Pseudo address space under root PCI bus. */
+     pcms->ioapic_as = vtd_host_dma_iommu(bus, s, Q35_PSEUDO_DEVFN_IOAPIC);
++    qemu_add_machine_init_done_notifier(&vtd_machine_done_notify);
+ }
+ 
+ static void vtd_class_init(ObjectClass *klass, void *data)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iscsi-Avoid-potential-for-get_status-overflow.patch b/SOURCES/kvm-iscsi-Avoid-potential-for-get_status-overflow.patch
index ed227dc..a4eddb2 100644
--- a/SOURCES/kvm-iscsi-Avoid-potential-for-get_status-overflow.patch
+++ b/SOURCES/kvm-iscsi-Avoid-potential-for-get_status-overflow.patch
@@ -1,16 +1,16 @@
-From f8e55fd069eea72105e104534aa7560d8df03bf7 Mon Sep 17 00:00:00 2001
+From 242abde4b0152142787bd3200de5cc35863da59a Mon Sep 17 00:00:00 2001
 From: jmaloy <jmaloy@redhat.com>
-Date: Wed, 29 Jan 2020 21:14:31 +0000
-Subject: [PATCH 4/5] iscsi: Avoid potential for get_status overflow
+Date: Wed, 29 Jan 2020 21:41:14 +0000
+Subject: [PATCH 1/6] iscsi: Avoid potential for get_status overflow
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
 
 RH-Author: jmaloy <jmaloy@redhat.com>
-Message-id: <20200129211432.11592-2-jmaloy@redhat.com>
-Patchwork-id: 93584
-O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 1/2] iscsi: Avoid potential for get_status overflow
-Bugzilla: 1794500
+Message-id: <20200129214115.19979-2-jmaloy@redhat.com>
+Patchwork-id: 93587
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/2] iscsi: Avoid potential for get_status overflow
+Bugzilla: 1794501
 RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
 RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
 RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
diff --git a/SOURCES/kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch b/SOURCES/kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
index a65452b..ae34541 100644
--- a/SOURCES/kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
+++ b/SOURCES/kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
@@ -1,17 +1,17 @@
-From 66a75a069b944ba4392129a6488206631c581167 Mon Sep 17 00:00:00 2001
+From 7dd9696a1b288746bac6fa0fe4f1d212be4f8f82 Mon Sep 17 00:00:00 2001
 From: jmaloy <jmaloy@redhat.com>
-Date: Wed, 29 Jan 2020 21:14:32 +0000
-Subject: [PATCH 5/5] iscsi: Cap block count from GET LBA STATUS
+Date: Wed, 29 Jan 2020 21:41:15 +0000
+Subject: [PATCH 2/6] iscsi: Cap block count from GET LBA STATUS
  (CVE-2020-1711)
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
 
 RH-Author: jmaloy <jmaloy@redhat.com>
-Message-id: <20200129211432.11592-3-jmaloy@redhat.com>
-Patchwork-id: 93583
-O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 2/2] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711)
-Bugzilla: 1794500
+Message-id: <20200129214115.19979-3-jmaloy@redhat.com>
+Patchwork-id: 93585
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/2] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711)
+Bugzilla: 1794501
 RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
 RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
 RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
diff --git a/SOURCES/kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch b/SOURCES/kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch
new file mode 100644
index 0000000..c3f4fa9
--- /dev/null
+++ b/SOURCES/kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch
@@ -0,0 +1,174 @@
+From e69f257e657473ba59f48692d387e292a24892bb Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 20 Aug 2019 16:12:50 +0100
+Subject: [PATCH 03/11] mmap-alloc: fix hugetlbfs misaligned length in ppc64
+
+RH-Author: plai@redhat.com
+Message-id: <1566317571-5697-4-git-send-email-plai@redhat.com>
+Patchwork-id: 90082
+O-Subject: [RHEL8.2 qemu-kvm PATCH 3/4] mmap-alloc: fix hugetlbfs misaligned length in ppc64
+Bugzilla: 1539282
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
+
+The commit 7197fb4058bcb68986bae2bb2c04d6370f3e7218 ("util/mmap-alloc:
+fix hugetlb support on ppc64") fixed Huge TLB mappings on ppc64.
+
+However, we still need to consider the underlying huge page size
+during munmap() because it requires that both address and length be a
+multiple of the underlying huge page size for Huge TLB mappings.
+Quote from "Huge page (Huge TLB) mappings" paragraph under NOTES
+section of the munmap(2) manual:
+
+  "For munmap(), addr and length must both be a multiple of the
+  underlying huge page size."
+
+On ppc64, the munmap() in qemu_ram_munmap() does not work for Huge TLB
+mappings because the mapped segment can be aligned with the underlying
+huge page size, not aligned with the native system page size, as
+returned by getpagesize().
+
+This has the side effect of not releasing huge pages back to the pool
+after a hugetlbfs file-backed memory device is hot-unplugged.
+
+This patch fixes the situation in qemu_ram_mmap() and
+qemu_ram_munmap() by considering the underlying page size on ppc64.
+
+After this patch, memory hot-unplug releases huge pages back to the
+pool.
+
+Fixes: 7197fb4058bcb68986bae2bb2c04d6370f3e7218
+Signed-off-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 53adb9d43e1abba187387a51f238e878e934c647)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ exec.c                    |  4 ++--
+ include/qemu/mmap-alloc.h |  2 +-
+ util/mmap-alloc.c         | 22 ++++++++++++++++------
+ util/oslib-posix.c        |  2 +-
+ 4 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index a79eaa3..9112d8b 100644
+--- a/exec.c
++++ b/exec.c
+@@ -1679,7 +1679,7 @@ static void *file_ram_alloc(RAMBlock *block,
+     if (mem_prealloc) {
+         os_mem_prealloc(fd, area, memory, smp_cpus, errp);
+         if (errp && *errp) {
+-            qemu_ram_munmap(area, memory);
++            qemu_ram_munmap(fd, area, memory);
+             return NULL;
+         }
+     }
+@@ -2200,7 +2200,7 @@ static void reclaim_ramblock(RAMBlock *block)
+         xen_invalidate_map_cache_entry(block->host);
+ #ifndef _WIN32
+     } else if (block->fd >= 0) {
+-        qemu_ram_munmap(block->host, block->max_length);
++        qemu_ram_munmap(block->fd, block->host, block->max_length);
+         close(block->fd);
+ #endif
+     } else {
+diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
+index 190688a..eec98d8 100644
+--- a/include/qemu/mmap-alloc.h
++++ b/include/qemu/mmap-alloc.h
+@@ -28,6 +28,6 @@ void *qemu_ram_mmap(int fd,
+                     bool shared,
+                     bool is_pmem);
+ 
+-void qemu_ram_munmap(void *ptr, size_t size);
++void qemu_ram_munmap(int fd, void *ptr, size_t size);
+ 
+ #endif
+diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
+index b29fcee..bbd9077 100644
+--- a/util/mmap-alloc.c
++++ b/util/mmap-alloc.c
+@@ -82,6 +82,7 @@ void *qemu_ram_mmap(int fd,
+     int flags;
+     int guardfd;
+     size_t offset;
++    size_t pagesize;
+     size_t total;
+     void *guardptr;
+     void *ptr;
+@@ -102,7 +103,8 @@ void *qemu_ram_mmap(int fd,
+      * anonymous memory is OK.
+      */
+     flags = MAP_PRIVATE;
+-    if (fd == -1 || qemu_fd_getpagesize(fd) == getpagesize()) {
++    pagesize = qemu_fd_getpagesize(fd);
++    if (fd == -1 || pagesize == getpagesize()) {
+         guardfd = -1;
+         flags |= MAP_ANONYMOUS;
+     } else {
+@@ -111,6 +113,7 @@ void *qemu_ram_mmap(int fd,
+     }
+ #else
+     guardfd = -1;
++    pagesize = getpagesize();
+     flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ #endif
+ 
+@@ -122,7 +125,7 @@ void *qemu_ram_mmap(int fd,
+ 
+     assert(is_power_of_2(align));
+     /* Always align to host page size */
+-    assert(align >= getpagesize());
++    assert(align >= pagesize);
+ 
+     flags = MAP_FIXED;
+     flags |= fd == -1 ? MAP_ANONYMOUS : 0;
+@@ -145,17 +148,24 @@ void *qemu_ram_mmap(int fd,
+      * a guard page guarding against potential buffer overflows.
+      */
+     total -= offset;
+-    if (total > size + getpagesize()) {
+-        munmap(ptr + size + getpagesize(), total - size - getpagesize());
++    if (total > size + pagesize) {
++        munmap(ptr + size + pagesize, total - size - pagesize);
+     }
+ 
+     return ptr;
+ }
+ 
+-void qemu_ram_munmap(void *ptr, size_t size)
++void qemu_ram_munmap(int fd, void *ptr, size_t size)
+ {
++    size_t pagesize;
++
+     if (ptr) {
+         /* Unmap both the RAM block and the guard page */
+-        munmap(ptr, size + getpagesize());
++#if defined(__powerpc64__) && defined(__linux__)
++        pagesize = qemu_fd_getpagesize(fd);
++#else
++        pagesize = getpagesize();
++#endif
++        munmap(ptr, size + pagesize);
+     }
+ }
+diff --git a/util/oslib-posix.c b/util/oslib-posix.c
+index c36b2bb..7b6db04 100644
+--- a/util/oslib-posix.c
++++ b/util/oslib-posix.c
+@@ -153,7 +153,7 @@ void qemu_vfree(void *ptr)
+ void qemu_anon_ram_free(void *ptr, size_t size)
+ {
+     trace_qemu_anon_ram_free(ptr, size);
+-    qemu_ram_munmap(ptr, size);
++    qemu_ram_munmap(-1, ptr, size);
+ }
+ 
+ void qemu_set_block(int fd)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-mmap-alloc-unfold-qemu_ram_mmap.patch b/SOURCES/kvm-mmap-alloc-unfold-qemu_ram_mmap.patch
new file mode 100644
index 0000000..fdc21ec
--- /dev/null
+++ b/SOURCES/kvm-mmap-alloc-unfold-qemu_ram_mmap.patch
@@ -0,0 +1,139 @@
+From 6b3478bb8b5718d86cb04f41043a8e0cce4df24c Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 20 Aug 2019 16:12:49 +0100
+Subject: [PATCH 02/11] mmap-alloc: unfold qemu_ram_mmap()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: plai@redhat.com
+Message-id: <1566317571-5697-3-git-send-email-plai@redhat.com>
+Patchwork-id: 90083
+O-Subject: [RHEL8.2 qemu-kvm PATCH 2/4] mmap-alloc: unfold qemu_ram_mmap()
+Bugzilla: 1539282
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
+
+Unfold parts of qemu_ram_mmap() for the sake of understanding, moving
+declarations to the top, and keeping architecture-specifics in the
+ifdef-else blocks.  No changes in the function behaviour.
+
+Give ptr and ptr1 meaningful names:
+  ptr  -> guardptr : pointer to the PROT_NONE guard region
+  ptr1 -> ptr      : pointer to the mapped memory returned to caller
+
+Signed-off-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 2044c3e7116eeac0449dcb4a4130cc8f8b9310da)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ util/mmap-alloc.c | 53 ++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 34 insertions(+), 19 deletions(-)
+
+diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
+index 55d1890..b29fcee 100644
+--- a/util/mmap-alloc.c
++++ b/util/mmap-alloc.c
+@@ -79,11 +79,19 @@ void *qemu_ram_mmap(int fd,
+                     bool shared,
+                     bool is_pmem)
+ {
++    int flags;
++    int guardfd;
++    size_t offset;
++    size_t total;
++    void *guardptr;
++    void *ptr;
++
+     /*
+      * Note: this always allocates at least one extra page of virtual address
+      * space, even if size is already aligned.
+      */
+-    size_t total = size + align;
++    total = size + align;
++
+ #if defined(__powerpc64__) && defined(__linux__)
+     /* On ppc64 mappings in the same segment (aka slice) must share the same
+      * page size. Since we will be re-allocating part of this segment
+@@ -93,16 +101,22 @@ void *qemu_ram_mmap(int fd,
+      * We do this unless we are using the system page size, in which case
+      * anonymous memory is OK.
+      */
+-    int anonfd = fd == -1 || qemu_fd_getpagesize(fd) == getpagesize() ? -1 : fd;
+-    int flags = anonfd == -1 ? MAP_ANONYMOUS : MAP_NORESERVE;
+-    void *ptr = mmap(0, total, PROT_NONE, flags | MAP_PRIVATE, anonfd, 0);
++    flags = MAP_PRIVATE;
++    if (fd == -1 || qemu_fd_getpagesize(fd) == getpagesize()) {
++        guardfd = -1;
++        flags |= MAP_ANONYMOUS;
++    } else {
++        guardfd = fd;
++        flags |= MAP_NORESERVE;
++    }
+ #else
+-    void *ptr = mmap(0, total, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
++    guardfd = -1;
++    flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ #endif
+-    size_t offset;
+-    void *ptr1;
+ 
+-    if (ptr == MAP_FAILED) {
++    guardptr = mmap(0, total, PROT_NONE, flags, guardfd, 0);
++
++    if (guardptr == MAP_FAILED) {
+         return MAP_FAILED;
+     }
+ 
+@@ -110,19 +124,20 @@ void *qemu_ram_mmap(int fd,
+     /* Always align to host page size */
+     assert(align >= getpagesize());
+ 
+-    offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
+-    ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE,
+-                MAP_FIXED |
+-                (fd == -1 ? MAP_ANONYMOUS : 0) |
+-                (shared ? MAP_SHARED : MAP_PRIVATE),
+-                fd, 0);
+-    if (ptr1 == MAP_FAILED) {
+-        munmap(ptr, total);
++    flags = MAP_FIXED;
++    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
++    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
++    offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
++
++    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, flags, fd, 0);
++
++    if (ptr == MAP_FAILED) {
++        munmap(guardptr, total);
+         return MAP_FAILED;
+     }
+ 
+     if (offset > 0) {
+-        munmap(ptr, offset);
++        munmap(guardptr, offset);
+     }
+ 
+     /*
+@@ -131,10 +146,10 @@ void *qemu_ram_mmap(int fd,
+      */
+     total -= offset;
+     if (total > size + getpagesize()) {
+-        munmap(ptr1 + size + getpagesize(), total - size - getpagesize());
++        munmap(ptr + size + getpagesize(), total - size - getpagesize());
+     }
+ 
+-    return ptr1;
++    return ptr;
+ }
+ 
+ void qemu_ram_munmap(void *ptr, size_t size)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-opts-don-t-silently-truncate-long-option-values.patch b/SOURCES/kvm-opts-don-t-silently-truncate-long-option-values.patch
new file mode 100644
index 0000000..f338282
--- /dev/null
+++ b/SOURCES/kvm-opts-don-t-silently-truncate-long-option-values.patch
@@ -0,0 +1,398 @@
+From 6abc65aaa666bf41070fa772293982cb0d1ae835 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 12 Sep 2019 13:05:00 +0100
+Subject: [PATCH 03/22] opts: don't silently truncate long option values
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laszlo Ersek <lersek@redhat.com>
+Message-id: <20190912130503.14094-4-lersek@redhat.com>
+Patchwork-id: 90436
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 3/6] opts: don't silently truncate long option values
+Bugzilla: 1749022
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+The existing QemuOpts parsing code uses a fixed size 1024 byte buffer
+for storing the option values. If a value exceeded this size it was
+silently truncated and no error reported to the user. Long option values
+is not a common scenario, but it is conceivable that they will happen.
+eg if the user has a very deeply nested filesystem it would be possible
+to come up with a disk path that was > 1024 bytes. Most of the time if
+such data was silently truncated, the user would get an error about
+opening a non-existant disk. If they're unlucky though, QEMU might use a
+completely different disk image from another VM, which could be
+considered a security issue. Another example program was in using the
+-smbios command line arg with very large data blobs. In this case the
+silent truncation will be providing semantically incorrect data to the
+guest OS for SMBIOS tables.
+
+If the operating system didn't limit the user's argv when spawning QEMU,
+the code should honour whatever length arguments were given without
+imposing its own length restrictions. This patch thus changes the code
+to use a heap allocated buffer for storing the values during parsing,
+lifting the arbitrary length restriction.
+
+RHEL8 notes:
+
+- Fix up upstream's obviously garbled UTF8 sequences in Dan's name (Author
+  meta-datum, Signed-off-by tags).
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180416111743.8473-4-berrange@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 950c4e6c94b15cd0d8b63891dddd7a8dbf458e6a)
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/multiboot.c   |  33 +++++++++------
+ include/qemu/option.h |   2 +-
+ util/qemu-option.c    | 111 +++++++++++++++++++++++++++-----------------------
+ 3 files changed, 81 insertions(+), 65 deletions(-)
+
+diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
+index 5bc0a2c..7a2953e 100644
+--- a/hw/i386/multiboot.c
++++ b/hw/i386/multiboot.c
+@@ -291,12 +291,16 @@ int load_multiboot(FWCfgState *fw_cfg,
+     cmdline_len = strlen(kernel_filename) + 1;
+     cmdline_len += strlen(kernel_cmdline) + 1;
+     if (initrd_filename) {
+-        const char *r = initrd_filename;
++        const char *r = get_opt_value(initrd_filename, NULL);
+         cmdline_len += strlen(r) + 1;
+         mbs.mb_mods_avail = 1;
+-        while (*(r = get_opt_value(NULL, 0, r))) {
+-           mbs.mb_mods_avail++;
+-           r++;
++        while (1) {
++            mbs.mb_mods_avail++;
++            r = get_opt_value(r, NULL);
++            if (!*r) {
++                break;
++            }
++            r++;
+         }
+     }
+ 
+@@ -313,7 +317,8 @@ int load_multiboot(FWCfgState *fw_cfg,
+ 
+     if (initrd_filename) {
+         const char *next_initrd;
+-        char not_last, tmpbuf[strlen(initrd_filename) + 1];
++        char not_last;
++        char *one_file = NULL;
+ 
+         mbs.offset_mods = mbs.mb_buf_size;
+ 
+@@ -322,24 +327,26 @@ int load_multiboot(FWCfgState *fw_cfg,
+             int mb_mod_length;
+             uint32_t offs = mbs.mb_buf_size;
+ 
+-            next_initrd = get_opt_value(tmpbuf, sizeof(tmpbuf), initrd_filename);
++            next_initrd = get_opt_value(initrd_filename, &one_file);
+             not_last = *next_initrd;
+             /* if a space comes after the module filename, treat everything
+                after that as parameters */
+-            hwaddr c = mb_add_cmdline(&mbs, tmpbuf);
+-            if ((next_space = strchr(tmpbuf, ' ')))
++            hwaddr c = mb_add_cmdline(&mbs, one_file);
++            next_space = strchr(one_file, ' ');
++            if (next_space) {
+                 *next_space = '\0';
+-            mb_debug("multiboot loading module: %s", tmpbuf);
+-            mb_mod_length = get_image_size(tmpbuf);
++            }
++            mb_debug("multiboot loading module: %s", one_file);
++            mb_mod_length = get_image_size(one_file);
+             if (mb_mod_length < 0) {
+-                error_report("Failed to open file '%s'", tmpbuf);
++                error_report("Failed to open file '%s'", one_file);
+                 exit(1);
+             }
+ 
+             mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size);
+             mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
+ 
+-            load_image(tmpbuf, (unsigned char *)mbs.mb_buf + offs);
++            load_image(one_file, (unsigned char *)mbs.mb_buf + offs);
+             mb_add_mod(&mbs, mbs.mb_buf_phys + offs,
+                        mbs.mb_buf_phys + offs + mb_mod_length, c);
+ 
+@@ -347,6 +354,8 @@ int load_multiboot(FWCfgState *fw_cfg,
+                      (char *)mbs.mb_buf + offs,
+                      (char *)mbs.mb_buf + offs + mb_mod_length, c);
+             initrd_filename = next_initrd+1;
++            g_free(one_file);
++            one_file = NULL;
+         } while (not_last);
+     }
+ 
+diff --git a/include/qemu/option.h b/include/qemu/option.h
+index 1cfe5cb..3dfb449 100644
+--- a/include/qemu/option.h
++++ b/include/qemu/option.h
+@@ -28,7 +28,7 @@
+ 
+ #include "qemu/queue.h"
+ 
+-const char *get_opt_value(char *buf, int buf_size, const char *p);
++const char *get_opt_value(const char *p, char **value);
+ 
+ void parse_option_size(const char *name, const char *value,
+                        uint64_t *ret, Error **errp);
+diff --git a/util/qemu-option.c b/util/qemu-option.c
+index b99568f..ba44a08 100644
+--- a/util/qemu-option.c
++++ b/util/qemu-option.c
+@@ -70,25 +70,37 @@ static const char *get_opt_name(const char *p, char **option, char delim)
+  * delimiter is fixed to be comma which starts a new option. To specify an
+  * option value that contains commas, double each comma.
+  */
+-const char *get_opt_value(char *buf, int buf_size, const char *p)
++const char *get_opt_value(const char *p, char **value)
+ {
+-    char *q;
++    size_t capacity = 0, length;
++    const char *offset;
++
++    *value = NULL;
++    while (1) {
++        offset = strchr(p, ',');
++        if (!offset) {
++            offset = p + strlen(p);
++        }
+ 
+-    q = buf;
+-    while (*p != '\0') {
+-        if (*p == ',') {
+-            if (*(p + 1) != ',')
+-                break;
+-            p++;
++        length = offset - p;
++        if (*offset != '\0' && *(offset + 1) == ',') {
++            length++;
++        }
++        if (value) {
++            *value = g_renew(char, *value, capacity + length + 1);
++            strncpy(*value + capacity, p, length);
++            (*value)[capacity + length] = '\0';
++        }
++        capacity += length;
++        if (*offset == '\0' ||
++            *(offset + 1) != ',') {
++            break;
+         }
+-        if (q && (q - buf) < buf_size - 1)
+-            *q++ = *p;
+-        p++;
++
++        p += (offset - p) + 2;
+     }
+-    if (q)
+-        *q = '\0';
+ 
+-    return p;
++    return offset;
+ }
+ 
+ static void parse_option_bool(const char *name, const char *value, bool *ret,
+@@ -162,50 +174,43 @@ void parse_option_size(const char *name, const char *value,
+ 
+ bool has_help_option(const char *param)
+ {
+-    size_t buflen = strlen(param) + 1;
+-    char *buf = g_malloc(buflen);
+     const char *p = param;
+     bool result = false;
+ 
+-    while (*p) {
+-        p = get_opt_value(buf, buflen, p);
++    while (*p && !result) {
++        char *value;
++
++        p = get_opt_value(p, &value);
+         if (*p) {
+             p++;
+         }
+ 
+-        if (is_help_option(buf)) {
+-            result = true;
+-            goto out;
+-        }
++        result = is_help_option(value);
++        g_free(value);
+     }
+ 
+-out:
+-    g_free(buf);
+     return result;
+ }
+ 
+-bool is_valid_option_list(const char *param)
++bool is_valid_option_list(const char *p)
+ {
+-    size_t buflen = strlen(param) + 1;
+-    char *buf = g_malloc(buflen);
+-    const char *p = param;
+-    bool result = true;
++    char *value = NULL;
++    bool result = false;
+ 
+     while (*p) {
+-        p = get_opt_value(buf, buflen, p);
+-        if (*p && !*++p) {
+-            result = false;
++        p = get_opt_value(p, &value);
++        if ((*p && !*++p) ||
++            (!*value || *value == ',')) {
+             goto out;
+         }
+ 
+-        if (!*buf || *buf == ',') {
+-            result = false;
+-            goto out;
+-        }
++        g_free(value);
++        value = NULL;
+     }
+ 
++    result = true;
+ out:
+-    g_free(buf);
++    g_free(value);
+     return result;
+ }
+ 
+@@ -486,7 +491,7 @@ int qemu_opt_unset(QemuOpts *opts, const char *name)
+     }
+ }
+ 
+-static void opt_set(QemuOpts *opts, const char *name, const char *value,
++static void opt_set(QemuOpts *opts, const char *name, char *value,
+                     bool prepend, Error **errp)
+ {
+     QemuOpt *opt;
+@@ -495,6 +500,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
+ 
+     desc = find_desc_by_name(opts->list->desc, name);
+     if (!desc && !opts_accepts_any(opts)) {
++        g_free(value);
+         error_setg(errp, QERR_INVALID_PARAMETER, name);
+         return;
+     }
+@@ -508,8 +514,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
+         QTAILQ_INSERT_TAIL(&opts->head, opt, next);
+     }
+     opt->desc = desc;
+-    opt->str = g_strdup(value);
+-    assert(opt->str);
++    opt->str = value;
+     qemu_opt_parse(opt, &local_err);
+     if (local_err) {
+         error_propagate(errp, local_err);
+@@ -520,7 +525,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
+ void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
+                   Error **errp)
+ {
+-    opt_set(opts, name, value, false, errp);
++    opt_set(opts, name, g_strdup(value), false, errp);
+ }
+ 
+ void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
+@@ -754,7 +759,7 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+                           const char *firstname, bool prepend, Error **errp)
+ {
+     char *option = NULL;
+-    char value[1024];
++    char *value = NULL;
+     const char *p,*pe,*pc;
+     Error *local_err = NULL;
+ 
+@@ -766,15 +771,15 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+             if (p == params && firstname) {
+                 /* implicitly named first option */
+                 option = g_strdup(firstname);
+-                p = get_opt_value(value, sizeof(value), p);
++                p = get_opt_value(p, &value);
+             } else {
+                 /* option without value, probably a flag */
+                 p = get_opt_name(p, &option, ',');
+                 if (strncmp(option, "no", 2) == 0) {
+                     memmove(option, option+2, strlen(option+2)+1);
+-                    pstrcpy(value, sizeof(value), "off");
++                    value = g_strdup("off");
+                 } else {
+-                    pstrcpy(value, sizeof(value), "on");
++                    value = g_strdup("on");
+                 }
+             }
+         } else {
+@@ -782,11 +787,12 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+             p = get_opt_name(p, &option, '=');
+             assert(*p == '=');
+             p++;
+-            p = get_opt_value(value, sizeof(value), p);
++            p = get_opt_value(p, &value);
+         }
+         if (strcmp(option, "id") != 0) {
+             /* store and parse */
+             opt_set(opts, option, value, prepend, &local_err);
++            value = NULL;
+             if (local_err) {
+                 error_propagate(errp, local_err);
+                 goto cleanup;
+@@ -796,11 +802,13 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+             break;
+         }
+         g_free(option);
+-        option = NULL;
++        g_free(value);
++        option = value = NULL;
+     }
+ 
+  cleanup:
+     g_free(option);
++    g_free(value);
+ }
+ 
+ /**
+@@ -819,7 +827,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
+                             bool permit_abbrev, bool defaults, Error **errp)
+ {
+     const char *firstname;
+-    char value[1024], *id = NULL;
++    char *id = NULL;
+     const char *p;
+     QemuOpts *opts;
+     Error *local_err = NULL;
+@@ -828,11 +836,9 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
+     firstname = permit_abbrev ? list->implied_opt_name : NULL;
+ 
+     if (strncmp(params, "id=", 3) == 0) {
+-        get_opt_value(value, sizeof(value), params+3);
+-        id = value;
++        get_opt_value(params + 3, &id);
+     } else if ((p = strstr(params, ",id=")) != NULL) {
+-        get_opt_value(value, sizeof(value), p+4);
+-        id = value;
++        get_opt_value(p + 4, &id);
+     }
+ 
+     /*
+@@ -844,6 +850,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
+      */
+     assert(!defaults || list->merge_lists);
+     opts = qemu_opts_create(list, id, !defaults, &local_err);
++    g_free(id);
+     if (opts == NULL) {
+         error_propagate(errp, local_err);
+         return NULL;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-opts-don-t-silently-truncate-long-parameter-keys.patch b/SOURCES/kvm-opts-don-t-silently-truncate-long-parameter-keys.patch
new file mode 100644
index 0000000..00cd2ae
--- /dev/null
+++ b/SOURCES/kvm-opts-don-t-silently-truncate-long-parameter-keys.patch
@@ -0,0 +1,198 @@
+From 5fe3c58c3a57a04254b3083b070fdf99fba82c93 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 12 Sep 2019 13:04:59 +0100
+Subject: [PATCH 02/22] opts: don't silently truncate long parameter keys
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laszlo Ersek <lersek@redhat.com>
+Message-id: <20190912130503.14094-3-lersek@redhat.com>
+Patchwork-id: 90435
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/6] opts: don't silently truncate long parameter keys
+Bugzilla: 1749022
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+The existing QemuOpts parsing code uses a fixed size 128 byte buffer
+for storing the parameter keys. If a key exceeded this size it was
+silently truncate and no error reported to the user. This behaviour was
+reasonable & harmless because traditionally the key names are all
+statically declared, and it was known that no code was declaring a key
+longer than 127 bytes. This assumption, however, ceased to be valid once
+the block layer added support for dot-separate compound keys. This
+syntax allows for keys that can be arbitrarily long, limited only by the
+number of block drivers you can stack up. With this usage, silently
+truncating the key name can never lead to correct behaviour.
+
+Hopefully such truncation would turn into an error, when the block code
+then tried to extract options later, but there's no guarantee that will
+happen. It is conceivable that an option specified by the user may be
+truncated and then ignored. This could have serious consequences,
+possibly even leading to security problems if the ignored option set a
+security relevant parameter.
+
+If the operating system didn't limit the user's argv when spawning QEMU,
+the code should honour whatever length arguments were given without
+imposing its own length restrictions. This patch thus changes the code
+to use a heap allocated buffer for storing the keys during parsing,
+lifting the arbitrary length restriction.
+
+RHEL8 notes:
+
+- Fix up upstream's obviously garbled UTF8 sequences in Dan's name (Author
+  meta-datum, Signed-off-by tags).
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180416111743.8473-3-berrange@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit e652714f98f22e8882e88e3d563b025c5b00feec)
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/test-qemu-opts.c | 18 ------------------
+ util/qemu-option.c     | 44 ++++++++++++++++++++++----------------------
+ 2 files changed, 22 insertions(+), 40 deletions(-)
+
+diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
+index 77dd72b..7092e21 100644
+--- a/tests/test-qemu-opts.c
++++ b/tests/test-qemu-opts.c
+@@ -459,8 +459,6 @@ static void test_opts_parse(void)
+ {
+     Error *err = NULL;
+     QemuOpts *opts;
+-    char long_key[129];
+-    char *params;
+ 
+     /* Nothing */
+     opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
+@@ -471,22 +469,6 @@ static void test_opts_parse(void)
+     g_assert_cmpuint(opts_count(opts), ==, 1);
+     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
+ 
+-    /* Long key */
+-    memset(long_key, 'a', 127);
+-    long_key[127] = 'z';
+-    long_key[128] = 0;
+-    params = g_strdup_printf("%s=v", long_key);
+-    opts = qemu_opts_parse(&opts_list_03, params + 1, NULL, &error_abort);
+-    g_assert_cmpuint(opts_count(opts), ==, 1);
+-    g_assert_cmpstr(qemu_opt_get(opts, long_key + 1), ==, "v");
+-
+-    /* Overlong key gets truncated */
+-    opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort);
+-    g_assert(opts_count(opts) == 1);
+-    long_key[127] = 0;
+-    g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v");
+-    g_free(params);
+-
+     /* Multiple keys, last one wins */
+     opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
+                            false, &error_abort);
+diff --git a/util/qemu-option.c b/util/qemu-option.c
+index a8db173..b99568f 100644
+--- a/util/qemu-option.c
++++ b/util/qemu-option.c
+@@ -43,27 +43,23 @@
+  * first byte of the option name)
+  *
+  * The option name is delimited by delim (usually , or =) or the string end
+- * and is copied into buf. If the option name is longer than buf_size, it is
+- * truncated. buf is always zero terminated.
++ * and is copied into option. The caller is responsible for free'ing option
++ * when no longer required.
+  *
+  * The return value is the position of the delimiter/zero byte after the option
+  * name in p.
+  */
+-static const char *get_opt_name(char *buf, int buf_size, const char *p,
+-                                char delim)
++static const char *get_opt_name(const char *p, char **option, char delim)
+ {
+-    char *q;
++    char *offset = strchr(p, delim);
+ 
+-    q = buf;
+-    while (*p != '\0' && *p != delim) {
+-        if (q && (q - buf) < buf_size - 1)
+-            *q++ = *p;
+-        p++;
++    if (offset) {
++        *option = g_strndup(p, offset - p);
++        return offset;
++    } else {
++        *option = g_strdup(p);
++        return p + strlen(p);
+     }
+-    if (q)
+-        *q = '\0';
+-
+-    return p;
+ }
+ 
+ /*
+@@ -757,7 +753,8 @@ void qemu_opts_print(QemuOpts *opts, const char *separator)
+ static void opts_do_parse(QemuOpts *opts, const char *params,
+                           const char *firstname, bool prepend, Error **errp)
+ {
+-    char option[128], value[1024];
++    char *option = NULL;
++    char value[1024];
+     const char *p,*pe,*pc;
+     Error *local_err = NULL;
+ 
+@@ -768,11 +765,11 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+             /* found "foo,more" */
+             if (p == params && firstname) {
+                 /* implicitly named first option */
+-                pstrcpy(option, sizeof(option), firstname);
++                option = g_strdup(firstname);
+                 p = get_opt_value(value, sizeof(value), p);
+             } else {
+                 /* option without value, probably a flag */
+-                p = get_opt_name(option, sizeof(option), p, ',');
++                p = get_opt_name(p, &option, ',');
+                 if (strncmp(option, "no", 2) == 0) {
+                     memmove(option, option+2, strlen(option+2)+1);
+                     pstrcpy(value, sizeof(value), "off");
+@@ -782,10 +779,8 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+             }
+         } else {
+             /* found "foo=bar,more" */
+-            p = get_opt_name(option, sizeof(option), p, '=');
+-            if (*p != '=') {
+-                break;
+-            }
++            p = get_opt_name(p, &option, '=');
++            assert(*p == '=');
+             p++;
+             p = get_opt_value(value, sizeof(value), p);
+         }
+@@ -794,13 +789,18 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
+             opt_set(opts, option, value, prepend, &local_err);
+             if (local_err) {
+                 error_propagate(errp, local_err);
+-                return;
++                goto cleanup;
+             }
+         }
+         if (*p != ',') {
+             break;
+         }
++        g_free(option);
++        option = NULL;
+     }
++
++ cleanup:
++    g_free(option);
+ }
+ 
+ /**
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-opts-remove-redundant-check-for-NULL-parameter.patch b/SOURCES/kvm-opts-remove-redundant-check-for-NULL-parameter.patch
new file mode 100644
index 0000000..7130abe
--- /dev/null
+++ b/SOURCES/kvm-opts-remove-redundant-check-for-NULL-parameter.patch
@@ -0,0 +1,74 @@
+From 1906ff6940bb9f84f0f6a66980354e66b5124558 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Thu, 12 Sep 2019 13:05:03 +0100
+Subject: [PATCH 06/22] opts: remove redundant check for NULL parameter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laszlo Ersek <lersek@redhat.com>
+Message-id: <20190912130503.14094-7-lersek@redhat.com>
+Patchwork-id: 90432
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 6/6] opts: remove redundant check for NULL parameter
+Bugzilla: 1749022
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Daniel P. Berrangé <berrange@redhat.com>
+
+No callers of get_opt_value() pass in a NULL for the "value" parameter,
+so the check is redundant.
+
+RHEL8 notes:
+
+- Context difference in "util/qemu-option.c", function get_opt_value();
+  upstream has commit 5c99fa375da1 ("cutils: Provide strchrnul",
+  2018-06-29), part of v3.0.0, but downstream lacks it. Harmless, because
+  said upstream commit only refactors get_opt_value().
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20180514171913.17664-4-berrange@redhat.com>
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Tested-by: Roman Kagan <rkagan@virtuozzo.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 0c2f6e7ee99517449b4ed6cf333c2d9456d8fe35)
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ util/qemu-option.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/util/qemu-option.c b/util/qemu-option.c
+index a396d60..940f7a3 100644
+--- a/util/qemu-option.c
++++ b/util/qemu-option.c
+@@ -75,9 +75,7 @@ const char *get_opt_value(const char *p, char **value)
+     size_t capacity = 0, length;
+     const char *offset;
+ 
+-    if (value) {
+-        *value = NULL;
+-    }
++    *value = NULL;
+     while (1) {
+         offset = strchr(p, ',');
+         if (!offset) {
+@@ -88,11 +86,9 @@ const char *get_opt_value(const char *p, char **value)
+         if (*offset != '\0' && *(offset + 1) == ',') {
+             length++;
+         }
+-        if (value) {
+-            *value = g_renew(char, *value, capacity + length + 1);
+-            strncpy(*value + capacity, p, length);
+-            (*value)[capacity + length] = '\0';
+-        }
++        *value = g_renew(char, *value, capacity + length + 1);
++        strncpy(*value + capacity, p, length);
++        (*value)[capacity + length] = '\0';
+         capacity += length;
+         if (*offset == '\0' ||
+             *(offset + 1) != ',') {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-bios-s390-ccw-define-loadparm-length.patch b/SOURCES/kvm-pc-bios-s390-ccw-define-loadparm-length.patch
new file mode 100644
index 0000000..3f12d5a
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390-ccw-define-loadparm-length.patch
@@ -0,0 +1,122 @@
+From ad3b92699ba5e2280950fa9866f79673cecdb695 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:29 +0100
+Subject: [PATCH 04/21] pc-bios/s390-ccw: define loadparm length
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-2-thuth@redhat.com>
+Patchwork-id: 91780
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 01/17] pc-bios/s390-ccw: define loadparm length
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Collin Walling <walling@linux.ibm.com>
+
+Loadparm is defined by the s390 architecture to be 8 bytes
+in length. Let's define this size in the s390-ccw bios.
+
+Suggested-by: Laszlo Ersek <lersek@redhat.com>
+Signed-off-by: Collin Walling <walling@linux.ibm.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit a0e11b617b9ef41cefe8739dff4d6a7b01ca967f)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/iplb.h | 4 +++-
+ pc-bios/s390-ccw/main.c | 8 ++++----
+ pc-bios/s390-ccw/sclp.c | 2 +-
+ pc-bios/s390-ccw/sclp.h | 2 +-
+ 4 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
+index ded20c8..772d5c5 100644
+--- a/pc-bios/s390-ccw/iplb.h
++++ b/pc-bios/s390-ccw/iplb.h
+@@ -12,6 +12,8 @@
+ #ifndef IPLB_H
+ #define IPLB_H
+ 
++#define LOADPARM_LEN    8
++
+ struct IplBlockCcw {
+     uint8_t  reserved0[85];
+     uint8_t  ssid;
+@@ -61,7 +63,7 @@ struct IplParameterBlock {
+     uint8_t  pbt;
+     uint8_t  flags;
+     uint16_t reserved01;
+-    uint8_t  loadparm[8];
++    uint8_t  loadparm[LOADPARM_LEN];
+     union {
+         IplBlockCcw ccw;
+         IplBlockFcp fcp;
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index 26f9adf..544851d 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -15,7 +15,7 @@
+ char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+ static SubChannelId blk_schid = { .one = 1 };
+ IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
+-static char loadparm_str[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
++static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ QemuIplParameters qipl;
+ 
+ #define LOADPARM_PROMPT "PROMPT  "
+@@ -80,13 +80,13 @@ static bool find_dev(Schib *schib, int dev_no)
+ 
+ static void menu_setup(void)
+ {
+-    if (memcmp(loadparm_str, LOADPARM_PROMPT, 8) == 0) {
++    if (memcmp(loadparm_str, LOADPARM_PROMPT, LOADPARM_LEN) == 0) {
+         menu_set_parms(QIPL_FLAG_BM_OPTS_CMD, 0);
+         return;
+     }
+ 
+     /* If loadparm was set to any other value, then do not enable menu */
+-    if (memcmp(loadparm_str, LOADPARM_EMPTY, 8) != 0) {
++    if (memcmp(loadparm_str, LOADPARM_EMPTY, LOADPARM_LEN) != 0) {
+         return;
+     }
+ 
+@@ -117,7 +117,7 @@ static void virtio_setup(void)
+     enable_mss_facility();
+ 
+     sclp_get_loadparm_ascii(loadparm_str);
+-    memcpy(ldp + 10, loadparm_str, 8);
++    memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
+     sclp_print(ldp);
+ 
+     memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+diff --git a/pc-bios/s390-ccw/sclp.c b/pc-bios/s390-ccw/sclp.c
+index 3836cb4..c0223fa 100644
+--- a/pc-bios/s390-ccw/sclp.c
++++ b/pc-bios/s390-ccw/sclp.c
+@@ -114,7 +114,7 @@ void sclp_get_loadparm_ascii(char *loadparm)
+     memset((char *)_sccb, 0, sizeof(ReadInfo));
+     sccb->h.length = sizeof(ReadInfo);
+     if (!sclp_service_call(SCLP_CMDW_READ_SCP_INFO, sccb)) {
+-        ebcdic_to_ascii((char *) sccb->loadparm, loadparm, 8);
++        ebcdic_to_ascii((char *) sccb->loadparm, loadparm, LOADPARM_LEN);
+     }
+ }
+ 
+diff --git a/pc-bios/s390-ccw/sclp.h b/pc-bios/s390-ccw/sclp.h
+index 0dd987f..8450161 100644
+--- a/pc-bios/s390-ccw/sclp.h
++++ b/pc-bios/s390-ccw/sclp.h
+@@ -56,7 +56,7 @@ typedef struct ReadInfo {
+     uint16_t rnmax;
+     uint8_t rnsize;
+     uint8_t reserved[13];
+-    uint8_t loadparm[8];
++    uint8_t loadparm[LOADPARM_LEN];
+ } __attribute__((packed)) ReadInfo;
+ 
+ typedef struct SCCB {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-bios-s390-ccw-net-Use-diag308-to-reset-machine-be.patch b/SOURCES/kvm-pc-bios-s390-ccw-net-Use-diag308-to-reset-machine-be.patch
new file mode 100644
index 0000000..54d102d
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390-ccw-net-Use-diag308-to-reset-machine-be.patch
@@ -0,0 +1,328 @@
+From 2f0454ccd0dd12429e8c204933cafe71a248d4eb Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:30 +0100
+Subject: [PATCH 05/21] pc-bios/s390-ccw/net: Use diag308 to reset machine
+ before jumping to the OS
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-3-thuth@redhat.com>
+Patchwork-id: 91777
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 02/17] pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+The netboot firmware so far simply jumped directly into the OS kernel
+after the download has been completed. This, however, bears the risk
+that the virtio-net device still might be active in the background and
+incoming packets are still placed into the buffers - which could destroy
+memory of the now-running Linux kernel in case it did not take over the
+device fast enough. Also the SCLP console is not put into a well-defined
+state here. We should hand over the system in a clean state when jumping
+into the kernel, so let's use the same mechanism as it's done in the
+main s390-ccw firmware and reset the machine with diag308 into a clean
+state before jumping into the OS kernel code. To be able to share the
+code with the main s390-ccw firmware, the related functions are now
+extracted from bootmap.c into a new file called jump2ipl.c.
+
+Since we now also set the boot device schid at address 184 for the network
+boot device, this patch also slightly changes the way how we detect the
+entry points for non-ELF binary images: The code now looks for the "S390EP"
+magic first and then jumps to 0x10000 in case it has been found. This is
+necessary for booting from network devices, since the normal kernel code
+(where the PSW at ddress 0 points to) tries to do a block load from the
+boot device. This of course fails for a virtio-net device and causes the
+kernel to abort with a panic-PSW silently.
+
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 9a848adf45d6732e62551decb3c0255173090767)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/Makefile    |  4 +-
+ pc-bios/s390-ccw/bootmap.c   | 63 +-----------------------------
+ pc-bios/s390-ccw/bootmap.h   |  4 --
+ pc-bios/s390-ccw/jump2ipl.c  | 91 ++++++++++++++++++++++++++++++++++++++++++++
+ pc-bios/s390-ccw/netboot.mak |  3 +-
+ pc-bios/s390-ccw/netmain.c   | 11 +++++-
+ pc-bios/s390-ccw/s390-ccw.h  |  4 ++
+ 7 files changed, 111 insertions(+), 69 deletions(-)
+ create mode 100644 pc-bios/s390-ccw/jump2ipl.c
+
+diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
+index 1712c2d..439e3cc 100644
+--- a/pc-bios/s390-ccw/Makefile
++++ b/pc-bios/s390-ccw/Makefile
+@@ -9,7 +9,9 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
+ 
+ .PHONY : all clean build-all
+ 
+-OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o menu.o
++OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
++	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o
++
+ QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
+ QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
+ QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing
+diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
+index ffbf671..d13b7cb 100644
+--- a/pc-bios/s390-ccw/bootmap.c
++++ b/pc-bios/s390-ccw/bootmap.c
+@@ -29,14 +29,6 @@
+ /* Scratch space */
+ static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE)));
+ 
+-typedef struct ResetInfo {
+-    uint32_t ipl_mask;
+-    uint32_t ipl_addr;
+-    uint32_t ipl_continue;
+-} ResetInfo;
+-
+-static ResetInfo save;
+-
+ const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
+                                   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+ 
+@@ -57,53 +49,6 @@ static inline bool is_iso_vd_valid(IsoVolDesc *vd)
+            vd->type <= VOL_DESC_TYPE_PARTITION;
+ }
+ 
+-static void jump_to_IPL_2(void)
+-{
+-    ResetInfo *current = 0;
+-
+-    void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
+-    *current = save;
+-    ipl(); /* should not return */
+-}
+-
+-static void jump_to_IPL_code(uint64_t address)
+-{
+-    /* store the subsystem information _after_ the bootmap was loaded */
+-    write_subsystem_identification();
+-
+-    /* prevent unknown IPL types in the guest */
+-    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
+-        iplb.pbt = S390_IPL_TYPE_CCW;
+-        set_iplb(&iplb);
+-    }
+-
+-    /*
+-     * The IPL PSW is at address 0. We also must not overwrite the
+-     * content of non-BIOS memory after we loaded the guest, so we
+-     * save the original content and restore it in jump_to_IPL_2.
+-     */
+-    ResetInfo *current = 0;
+-
+-    save = *current;
+-    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
+-    current->ipl_continue = address & 0x7fffffff;
+-
+-    debug_print_int("set IPL addr to", current->ipl_continue);
+-
+-    /* Ensure the guest output starts fresh */
+-    sclp_print("\n");
+-
+-    /*
+-     * HACK ALERT.
+-     * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
+-     * can then use r15 as its stack pointer.
+-     */
+-    asm volatile("lghi 1,1\n\t"
+-                 "diag 1,1,0x308\n\t"
+-                 : : : "1", "memory");
+-    panic("\n! IPL returns !\n");
+-}
+-
+ /***********************************************************************
+  * IPL an ECKD DASD (CDL or LDL/CMS format)
+  */
+@@ -744,13 +689,7 @@ static void load_iso_bc_entry(IsoBcSection *load)
+                         (void *)((uint64_t)bswap16(s.load_segment)),
+                         blks_to_load);
+ 
+-    /* Trying to get PSW at zero address */
+-    if (*((uint64_t *)0) & IPL_PSW_MASK) {
+-        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
+-    }
+-
+-    /* Try default linux start address */
+-    jump_to_IPL_code(KERN_IMAGE_START);
++    jump_to_low_kernel();
+ }
+ 
+ static uint32_t find_iso_bc(void)
+diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
+index f1ce423..94f53a5 100644
+--- a/pc-bios/s390-ccw/bootmap.h
++++ b/pc-bios/s390-ccw/bootmap.h
+@@ -355,10 +355,6 @@ static inline uint32_t iso_733_to_u32(uint64_t x)
+ #define ISO_SECTOR_SIZE 2048
+ /* El Torito specifies boot image size in 512 byte blocks */
+ #define ET_SECTOR_SHIFT 2
+-#define KERN_IMAGE_START 0x010000UL
+-#define PSW_MASK_64 0x0000000100000000ULL
+-#define PSW_MASK_32 0x0000000080000000ULL
+-#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
+ 
+ #define ISO_PRIMARY_VD_SECTOR 16
+ 
+diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
+new file mode 100644
+index 0000000..266f150
+--- /dev/null
++++ b/pc-bios/s390-ccw/jump2ipl.c
+@@ -0,0 +1,91 @@
++/*
++ * QEMU s390-ccw firmware - jump to IPL code
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++#include "libc.h"
++#include "s390-ccw.h"
++
++#define KERN_IMAGE_START 0x010000UL
++#define PSW_MASK_64 0x0000000100000000ULL
++#define PSW_MASK_32 0x0000000080000000ULL
++#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
++
++typedef struct ResetInfo {
++    uint32_t ipl_mask;
++    uint32_t ipl_addr;
++    uint32_t ipl_continue;
++} ResetInfo;
++
++static ResetInfo save;
++
++static void jump_to_IPL_2(void)
++{
++    ResetInfo *current = 0;
++
++    void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
++    *current = save;
++    ipl(); /* should not return */
++}
++
++void jump_to_IPL_code(uint64_t address)
++{
++    /* store the subsystem information _after_ the bootmap was loaded */
++    write_subsystem_identification();
++
++    /* prevent unknown IPL types in the guest */
++    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
++        iplb.pbt = S390_IPL_TYPE_CCW;
++        set_iplb(&iplb);
++    }
++
++    /*
++     * The IPL PSW is at address 0. We also must not overwrite the
++     * content of non-BIOS memory after we loaded the guest, so we
++     * save the original content and restore it in jump_to_IPL_2.
++     */
++    ResetInfo *current = 0;
++
++    save = *current;
++    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
++    current->ipl_continue = address & 0x7fffffff;
++
++    debug_print_int("set IPL addr to", current->ipl_continue);
++
++    /* Ensure the guest output starts fresh */
++    sclp_print("\n");
++
++    /*
++     * HACK ALERT.
++     * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
++     * can then use r15 as its stack pointer.
++     */
++    asm volatile("lghi 1,1\n\t"
++                 "diag 1,1,0x308\n\t"
++                 : : : "1", "memory");
++    panic("\n! IPL returns !\n");
++}
++
++void jump_to_low_kernel(void)
++{
++    /*
++     * If it looks like a Linux binary, i.e. there is the "S390EP" magic from
++     * arch/s390/kernel/head.S here, then let's jump to the well-known Linux
++     * kernel start address (when jumping to the PSW-at-zero address instead,
++     * the kernel startup code fails when we booted from a network device).
++     */
++    if (!memcmp((char *)0x10008, "S390EP", 6)) {
++        jump_to_IPL_code(KERN_IMAGE_START);
++    }
++
++    /* Trying to get PSW at zero address */
++    if (*((uint64_t *)0) & IPL_PSW_MASK) {
++        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
++    }
++
++    /* No other option left, so use the Linux kernel start address */
++    jump_to_IPL_code(KERN_IMAGE_START);
++}
+diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
+index a25d238..4f64128 100644
+--- a/pc-bios/s390-ccw/netboot.mak
++++ b/pc-bios/s390-ccw/netboot.mak
+@@ -1,7 +1,8 @@
+ 
+ SLOF_DIR := $(SRC_PATH)/roms/SLOF
+ 
+-NETOBJS := start.o sclp.o virtio.o virtio-net.o netmain.o libnet.a libc.a
++NETOBJS := start.o sclp.o virtio.o virtio-net.o jump2ipl.o netmain.o \
++	   libnet.a libc.a
+ 
+ LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include
+ LIBNET_INC := -I$(SLOF_DIR)/lib/libnet
+diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
+index d86d46b..d60e84f 100644
+--- a/pc-bios/s390-ccw/netmain.c
++++ b/pc-bios/s390-ccw/netmain.c
+@@ -281,6 +281,15 @@ void panic(const char *string)
+     }
+ }
+ 
++void write_subsystem_identification(void)
++{
++    SubChannelId *schid = (SubChannelId *) 184;
++    uint32_t *zeroes = (uint32_t *) 188;
++
++    *schid = net_schid;
++    *zeroes = 0;
++}
++
+ static bool find_net_dev(Schib *schib, int dev_no)
+ {
+     int i, r;
+@@ -354,7 +363,7 @@ void main(void)
+     rc = net_load(NULL, (long)_start);
+     if (rc > 0) {
+         sclp_print("Network loading done, starting kernel...\n");
+-        asm volatile (" lpsw 0(%0) " : : "r"(0) : "memory");
++        jump_to_low_kernel();
+     }
+ 
+     panic("Failed to load OS from network\n");
+diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
+index a1bdb4c..9828aa2 100644
+--- a/pc-bios/s390-ccw/s390-ccw.h
++++ b/pc-bios/s390-ccw/s390-ccw.h
+@@ -87,6 +87,10 @@ ulong get_second(void);
+ /* bootmap.c */
+ void zipl_load(void);
+ 
++/* jump2ipl.c */
++void jump_to_IPL_code(uint64_t address);
++void jump_to_low_kernel(void);
++
+ /* menu.c */
+ void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout);
+ int menu_get_zipl_boot_index(const char *menu_data);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-q35-Disallow-vfio-pci-hotplug-without-VT-d-cachin.patch b/SOURCES/kvm-pc-q35-Disallow-vfio-pci-hotplug-without-VT-d-cachin.patch
new file mode 100644
index 0000000..adcf327
--- /dev/null
+++ b/SOURCES/kvm-pc-q35-Disallow-vfio-pci-hotplug-without-VT-d-cachin.patch
@@ -0,0 +1,87 @@
+From f117f5fb216e45796a32579c03673c1d79164037 Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Wed, 9 Oct 2019 12:39:46 +0100
+Subject: [PATCH 20/22] pc/q35: Disallow vfio-pci hotplug without VT-d caching
+ mode
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20191009123947.21505-5-peterx@redhat.com>
+Patchwork-id: 91352
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 4/5] pc/q35: Disallow vfio-pci hotplug without VT-d caching mode
+Bugzilla: 1738440
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+
+  hw/i386/pc.c: context differs on quite a few places in
+    pc_machine_class_init(), but none of them is really relevant to
+    current change.
+
+Instead of bailing out when trying to hotplug a vfio-pci device with
+below configuration:
+
+  -device intel-iommu,caching-mode=off
+
+With this we can return a warning message to the user via QMP/HMP and
+the VM will continue to work after failing the hotplug:
+
+  (qemu) device_add vfio-pci,bus=root.3,host=05:00.0,id=vfio1
+  Error: Device assignment is not allowed without enabling caching-mode=on for Intel IOMMU.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-Id: <20190916080718.3299-4-peterx@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit c6cbc29d36fe8df078776ed715c37cebac582238)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/i386/pc.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/hw/i386/pc.c b/hw/i386/pc.c
+index 9e1e6ae..d6c4050 100644
+--- a/hw/i386/pc.c
++++ b/hw/i386/pc.c
+@@ -2340,6 +2340,26 @@ static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
+     }
+ }
+ 
++
++static bool pc_hotplug_allowed(MachineState *ms, DeviceState *dev, Error **errp)
++{
++    X86IOMMUState *iommu = x86_iommu_get_default();
++    IntelIOMMUState *intel_iommu;
++
++    if (iommu &&
++        object_dynamic_cast((Object *)iommu, TYPE_INTEL_IOMMU_DEVICE) &&
++        object_dynamic_cast((Object *)dev, "vfio-pci")) {
++        intel_iommu = INTEL_IOMMU_DEVICE(iommu);
++        if (!intel_iommu->caching_mode) {
++            error_setg(errp, "Device assignment is not allowed without "
++                       "enabling caching-mode=on for Intel IOMMU.");
++            return false;
++        }
++    }
++
++    return true;
++}
++
+ static void pc_machine_class_init(ObjectClass *oc, void *data)
+ {
+     MachineClass *mc = MACHINE_CLASS(oc);
+@@ -2369,6 +2389,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
+      */
+     mc->async_pf_vmexit_disable = true;
+     mc->get_hotplug_handler = pc_get_hotpug_handler;
++    mc->hotplug_allowed = pc_hotplug_allowed;
+     mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
+     mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
+     mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pseries-do-not-allow-memory-less-cpu-less-NUMA-node.patch b/SOURCES/kvm-pseries-do-not-allow-memory-less-cpu-less-NUMA-node.patch
new file mode 100644
index 0000000..93fa9f7
--- /dev/null
+++ b/SOURCES/kvm-pseries-do-not-allow-memory-less-cpu-less-NUMA-node.patch
@@ -0,0 +1,108 @@
+From 7ab2261eebf90ea8a3cf5701fa177d181fe665d1 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Thu, 10 Oct 2019 07:34:38 +0100
+Subject: [PATCH 22/22] pseries: do not allow memory-less/cpu-less NUMA node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20191010073438.16478-1-lvivier@redhat.com>
+Patchwork-id: 91379
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH] pseries: do not allow memory-less/cpu-less NUMA node
+Bugzilla: 1651474
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+When we hotplug a CPU on memory-less/cpu-less node, the linux kernel
+crashes.
+
+This happens because linux kernel needs to know the NUMA topology at
+start to be able to initialize the distance lookup table.
+
+On pseries, the topology is provided by the firmware via the existing
+CPUs and memory information. Thus a node without memory and CPU cannot be
+discovered by the kernel.
+
+To avoid the kernel crash, do not allow to start pseries with empty
+nodes.
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Message-Id: <20190830161345.22436-1-lvivier@redhat.com>
+[dwg: Rework to cope with movement of numa state from globals to MachineState]
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 58c46efa451caa3935224223f950216872e2eee3)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+
+Conflicts in the context:
+	hw/ppc/spapr.c
+because of missing downstream commits:
+  0550b1206a91 ("spapr: don't advertise radix GTSE if max-compat-cpu < power9")
+  ad99d04c76de ("target/ppc: Allow cpu compatiblity checks based on type, not instance")
+
+because of missing donwtream commit:
+
+  7e721e7b10e1 ("numa: move numa global variable numa_info into MachineState")
+
+replaced numa_state by numa_info (revert dwg rework), back to original
+patch I sent:
+
+  https://patchew.org/QEMU/20190830161345.22436-1-lvivier@redhat.com/
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1651474
+BRANCH: rhel-8.2.0
+UPSTREAM: merged
+BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23924908
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/ppc/spapr.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 1a2f0d9..b4c9993 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -2527,6 +2527,39 @@ static void spapr_machine_init(MachineState *machine)
+     /* init CPUs */
+     spapr_init_cpus(spapr);
+ 
++    /*
++     * check we don't have a memory-less/cpu-less NUMA node
++     * Firmware relies on the existing memory/cpu topology to provide the
++     * NUMA topology to the kernel.
++     * And the linux kernel needs to know the NUMA topology at start
++     * to be able to hotplug CPUs later.
++     */
++    if (nb_numa_nodes) {
++        for (i = 0; i < nb_numa_nodes; ++i) {
++            /* check for memory-less node */
++            if (numa_info[i].node_mem == 0) {
++                CPUState *cs;
++                int found = 0;
++                /* check for cpu-less node */
++                CPU_FOREACH(cs) {
++                    PowerPCCPU *cpu = POWERPC_CPU(cs);
++                    if (cpu->node_id == i) {
++                        found = 1;
++                        break;
++                    }
++                }
++                /* memory-less and cpu-less node */
++                if (!found) {
++                    error_report(
++                       "Memory-less/cpu-less nodes are not supported (node %d)",
++                                 i);
++                    exit(1);
++                }
++            }
++        }
++
++    }
++
+     if (kvm_enabled()) {
+         /* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */
+         kvmppc_enable_logical_ci_hcalls();
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qapi-fill-in-CpuInfoFast.arch-in-query-cpus-fast.patch b/SOURCES/kvm-qapi-fill-in-CpuInfoFast.arch-in-query-cpus-fast.patch
new file mode 100644
index 0000000..b506221
--- /dev/null
+++ b/SOURCES/kvm-qapi-fill-in-CpuInfoFast.arch-in-query-cpus-fast.patch
@@ -0,0 +1,116 @@
+From 9000286ea20abb4e03c76ab8f873a6e9eb708377 Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Thu, 14 Nov 2019 08:20:41 +0000
+Subject: [PATCH 1/8] qapi: fill in CpuInfoFast.arch in query-cpus-fast
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20191114082041.20840-2-mlevitsk@redhat.com>
+Patchwork-id: 92245
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 1/1] qapi: fill in CpuInfoFast.arch in query-cpus-fast
+Bugzilla: 1730969
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+
+From: Laszlo Ersek <lersek@redhat.com>
+
+* Commit ca230ff33f89 added the @arch field to @CpuInfoFast, but it failed
+  to set the new field in qmp_query_cpus_fast(), when TARGET_S390X was not
+  defined. The updated @query-cpus-fast example in "qapi-schema.json"
+  showed "arch":"x86" only because qmp_query_cpus_fast() calls g_malloc0()
+  to allocate @CpuInfoFast, and the CPU_INFO_ARCH_X86 enum constant is
+  generated with value 0.
+
+  All @arch values other than @s390 implied the @CpuInfoOther sub-struct
+  for @CpuInfoFast -- at the time of writing the patch --, thus no fields
+  other than @arch needed to be set when TARGET_S390X was not defined. Set
+  @arch now, by copying the corresponding assignments from
+  qmp_query_cpus().
+
+* Commit 25fa194b7b11 added the @riscv enum constant to @CpuInfoArch (used
+  in both @CpuInfo and @CpuInfoFast -- the return types of the @query-cpus
+  and @query-cpus-fast commands, respectively), and assigned, in both
+  return structures, the @CpuInfoRISCV sub-structure to the new enum
+  value.
+
+  However, qmp_query_cpus_fast() would not populate either the @arch field
+  or the @CpuInfoRISCV sub-structure, when TARGET_RISCV was defined; only
+  qmp_query_cpus() would.
+
+  Assign @CpuInfoOther to the @riscv enum constant in @CpuInfoFast, and
+  populate only the @arch field in qmp_query_cpus_fast(). Getting CPU
+  state without interrupting KVM is an exceptional thing that only S390X
+  does currently. Quoting Cornelia Huck <cohuck@redhat.com>, "s390x is
+  exceptional in that it has state in QEMU that is actually interesting
+  for upper layers and can be retrieved without performance penalty". See
+  also
+  <https://www.redhat.com/archives/libvir-list/2018-February/msg00121.html>.
+
+Cc: Cornelia Huck <cohuck@redhat.com>
+Cc: Eric Blake <eblake@redhat.com>
+Cc: Markus Armbruster <armbru@redhat.com>
+Cc: Viktor VM Mihajlovski <mihajlov@linux.vnet.ibm.com>
+Cc: qemu-stable@nongnu.org
+Fixes: ca230ff33f89bf7102cbfbc2328716da6750aaed
+Fixes: 25fa194b7b11901561532e435beb83d046899f7a
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Markus Armbruster <armbru@redhat.com>
+Message-Id: <20180427192852.15013-2-lersek@redhat.com>
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+(cherry picked from commit 96054f56396eaa0b9b5c681fc3e42a0004b17ade)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ cpus.c         | 16 +++++++++++++++-
+ qapi/misc.json |  2 +-
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/cpus.c b/cpus.c
+index 6100089..cea42f9 100644
+--- a/cpus.c
++++ b/cpus.c
+@@ -2218,11 +2218,25 @@ CpuInfoFastList *qmp_query_cpus_fast(Error **errp)
+             info->value->props = props;
+         }
+ 
+-#if defined(TARGET_S390X)
++#if defined(TARGET_I386)
++        info->value->arch = CPU_INFO_ARCH_X86;
++#elif defined(TARGET_PPC)
++        info->value->arch = CPU_INFO_ARCH_PPC;
++#elif defined(TARGET_SPARC)
++        info->value->arch = CPU_INFO_ARCH_SPARC;
++#elif defined(TARGET_MIPS)
++        info->value->arch = CPU_INFO_ARCH_MIPS;
++#elif defined(TARGET_TRICORE)
++        info->value->arch = CPU_INFO_ARCH_TRICORE;
++#elif defined(TARGET_S390X)
+         s390_cpu = S390_CPU(cpu);
+         env = &s390_cpu->env;
+         info->value->arch = CPU_INFO_ARCH_S390;
+         info->value->u.s390.cpu_state = env->cpu_state;
++#elif defined(TARGET_RISCV)
++        info->value->arch = CPU_INFO_ARCH_RISCV;
++#else
++        info->value->arch = CPU_INFO_ARCH_OTHER;
+ #endif
+         if (!cur_item) {
+             head = cur_item = info;
+diff --git a/qapi/misc.json b/qapi/misc.json
+index 5636f4a..104d013 100644
+--- a/qapi/misc.json
++++ b/qapi/misc.json
+@@ -573,7 +573,7 @@
+             'mips': 'CpuInfoOther',
+             'tricore': 'CpuInfoOther',
+             's390': 'CpuInfoS390',
+-            'riscv': 'CpuInfoRISCV',
++            'riscv': 'CpuInfoOther',
+             'other': 'CpuInfoOther' } }
+ 
+ ##
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qdev-machine-Introduce-hotplug_allowed-hook.patch b/SOURCES/kvm-qdev-machine-Introduce-hotplug_allowed-hook.patch
new file mode 100644
index 0000000..22575fe
--- /dev/null
+++ b/SOURCES/kvm-qdev-machine-Introduce-hotplug_allowed-hook.patch
@@ -0,0 +1,135 @@
+From 6a2ee1fd8d36ed8407b403a7307de1633462759c Mon Sep 17 00:00:00 2001
+From: Peter Xu <peterx@redhat.com>
+Date: Wed, 9 Oct 2019 12:39:45 +0100
+Subject: [PATCH 19/22] qdev/machine: Introduce hotplug_allowed hook
+
+RH-Author: Peter Xu <peterx@redhat.com>
+Message-id: <20191009123947.21505-4-peterx@redhat.com>
+Patchwork-id: 91351
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 3/5] qdev/machine: Introduce hotplug_allowed hook
+Bugzilla: 1738440
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+
+  hw/core/qdev.c: don't have 14405c274e86e ("qdev: Provide
+    qdev_get_bus_hotplug_handler()")
+
+  include/hw/boards: plenty of new things missing in
+    MachineClass (kvm_type, numa_mem_supported, smp_parse)
+
+  include/hw/qdev-core.h: don't have 17cc0128da3 ("qdev: Let machine
+    hotplug handler to override bus hotplug handler")
+
+Introduce this new per-machine hook to give any machine class a chance
+to do a sanity check on the to-be-hotplugged device as a sanity test.
+This will be used for x86 to try to detect some illegal configuration
+of devices, e.g., possible conflictions between vfio-pci and x86
+vIOMMU.
+
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Message-Id: <20190916080718.3299-3-peterx@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit d2321d31ff98b75b652c2b1594f00a4cfd48102a)
+Signed-off-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/core/qdev.c         | 17 +++++++++++++++++
+ include/hw/boards.h    |  9 +++++++++
+ include/hw/qdev-core.h |  1 +
+ qdev-monitor.c         |  7 +++++++
+ 4 files changed, 34 insertions(+)
+
+diff --git a/hw/core/qdev.c b/hw/core/qdev.c
+index 24f1ae7..5971242 100644
+--- a/hw/core/qdev.c
++++ b/hw/core/qdev.c
+@@ -259,6 +259,23 @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
+     return NULL;
+ }
+ 
++bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
++{
++    MachineState *machine;
++    MachineClass *mc;
++    Object *m_obj = qdev_get_machine();
++
++    if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
++        machine = MACHINE(m_obj);
++        mc = MACHINE_GET_CLASS(machine);
++        if (mc->hotplug_allowed) {
++            return mc->hotplug_allowed(machine, dev, errp);
++        }
++    }
++
++    return true;
++}
++
+ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
+ {
+     HotplugHandler *hotplug_ctrl;
+diff --git a/include/hw/boards.h b/include/hw/boards.h
+index 9b4a69b..e568a3c 100644
+--- a/include/hw/boards.h
++++ b/include/hw/boards.h
+@@ -156,6 +156,13 @@ typedef struct {
+  *    should instead use "unimplemented-device" for all memory ranges where
+  *    the guest will attempt to probe for a device that QEMU doesn't
+  *    implement and a stub device is required.
++ * @hotplug_allowed:
++ *    If the hook is provided, then it'll be called for each device
++ *    hotplug to check whether the device hotplug is allowed.  Return
++ *    true to grant allowance or false to reject the hotplug.  When
++ *    false is returned, an error must be set to show the reason of
++ *    the rejection.  If the hook is not provided, all hotplug will be
++ *    allowed.
+  */
+ struct MachineClass {
+     /*< private >*/
+@@ -210,6 +217,8 @@ struct MachineClass {
+ 
+     HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
+                                            DeviceState *dev);
++    bool (*hotplug_allowed)(MachineState *state, DeviceState *dev,
++                            Error **errp);
+     CpuInstanceProperties (*cpu_index_to_instance_props)(MachineState *machine,
+                                                          unsigned cpu_index);
+     const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
+diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
+index 9453588..b8d1cac 100644
+--- a/include/hw/qdev-core.h
++++ b/include/hw/qdev-core.h
+@@ -286,6 +286,7 @@ void qdev_init_nofail(DeviceState *dev);
+ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
+                                  int required_for_version);
+ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
++bool qdev_hotplug_allowed(DeviceState *dev, Error **errp);
+ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev);
+ void qdev_unplug(DeviceState *dev, Error **errp);
+ void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
+diff --git a/qdev-monitor.c b/qdev-monitor.c
+index f439b83..70bce8f 100644
+--- a/qdev-monitor.c
++++ b/qdev-monitor.c
+@@ -606,6 +606,13 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
+     /* create device */
+     dev = DEVICE(object_new(driver));
+ 
++    /* Check whether the hotplug is allowed by the machine */
++    if (qdev_hotplug && !qdev_hotplug_allowed(dev, &err)) {
++        /* Error must be set in the machine hook */
++        assert(err);
++        goto err_del_dev;
++    }
++
+     if (bus) {
+         qdev_set_parent_bus(dev, bus);
+     } else if (qdev_hotplug && !qdev_get_machine_hotplug_handler(dev)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-PCI-fix-IOMMU-region-init.patch b/SOURCES/kvm-s390-PCI-fix-IOMMU-region-init.patch
index b058d08..d6822b8 100644
--- a/SOURCES/kvm-s390-PCI-fix-IOMMU-region-init.patch
+++ b/SOURCES/kvm-s390-PCI-fix-IOMMU-region-init.patch
@@ -1,26 +1,19 @@
-From 8c8c1a97b07700a2115bf23986fb402fc842bfe1 Mon Sep 17 00:00:00 2001
-From: Cornelia Huck <cohuck@redhat.com>
-Date: Tue, 5 Nov 2019 12:54:41 +0000
-Subject: [PATCH] s390: PCI: fix IOMMU region init
-
-RH-Author: Cornelia Huck <cohuck@redhat.com>
-Message-id: <20191105125441.19477-1-cohuck@redhat.com>
-Patchwork-id: 92032
-O-Subject: [RHEL-8.1.0.z qemu-kvm PATCH] s390: PCI: fix IOMMU region init
-Bugzilla: 1764829
+From 324a0ffc5140c4ece5b720708da2c673a8d1b9cc Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 1 Oct 2019 06:02:58 +0100
+Subject: [PATCH 12/22] s390: PCI: fix IOMMU region init
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191001060258.28206-2-thuth@redhat.com>
+Patchwork-id: 90929
+O-Subject: [RHEL-8.2.0/RHEL-8.1.z qemu-kvm PATCH 1/1] s390: PCI: fix IOMMU region init
+Bugzilla: 1754643
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
 RH-Acked-by: David Hildenbrand <david@redhat.com>
 RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
-RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
-RH-Acked-by: Thomas Huth <thuth@redhat.com>
 
 From: Matthew Rosato <mjrosato@linux.ibm.com>
 
-BUGZILLA: https://bugzilla.redhat.com/show_bug.cgi?id=1764829
-BRANCH: rhel-8.1.0
-UPSTREAM: 7df1dac5f1c85312474df9cb3a8fcae72303da62
-BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=24461099
-TESTED: only sanity checked, as we lack PCI hardware
-
 The fix in dbe9cf606c shrinks the IOMMU memory region to a size
 that seems reasonable on the surface, however is actually too
 small as it is based against a 0-mapped address space.  This
@@ -29,7 +22,6 @@ causes breakage with small guests as they can overrun the IOMMU window.
 Let's go back to the prior method of initializing iommu for now.
 
 Fixes: dbe9cf606c ("s390x/pci: Set the iommu region size mpcifc request")
-Cc: qemu-stable@nongnu.org
 Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
 Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
 Tested-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
@@ -38,7 +30,6 @@ Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
 Message-Id: <1569507036-15314-1-git-send-email-mjrosato@linux.ibm.com>
 Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
 (cherry picked from commit 7df1dac5f1c85312474df9cb3a8fcae72303da62)
-Signed-off-by: Cornelia Huck <cohuck@redhat.com>
 Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
 ---
  hw/s390x/s390-pci-bus.c | 7 ++++++-
diff --git a/SOURCES/kvm-s390-bios-Add-channel-command-codes-structs-needed-f.patch b/SOURCES/kvm-s390-bios-Add-channel-command-codes-structs-needed-f.patch
new file mode 100644
index 0000000..9c02f2d
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Add-channel-command-codes-structs-needed-f.patch
@@ -0,0 +1,88 @@
+From 81d722eaf6284d55e2da0ba6cc4874bfd262a7e2 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:43 +0100
+Subject: [PATCH 18/21] s390-bios: Add channel command codes/structs needed for
+ dasd-ipl
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-16-thuth@redhat.com>
+Patchwork-id: 91792
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 15/17] s390-bios: Add channel command codes/structs needed for dasd-ipl
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+The dasd IPL procedure needs to execute a few previously unused
+channel commands. Let's define them and their associated data
+structures.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+Acked-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-15-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 69333c36dc85b84b021766747cffc2b53df93ae8)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/cio.h | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
+index 1637e32..aaa432d 100644
+--- a/pc-bios/s390-ccw/cio.h
++++ b/pc-bios/s390-ccw/cio.h
+@@ -200,11 +200,14 @@ typedef struct ccw1 {
+ #define CCW_FLAG_IDA             0x04
+ #define CCW_FLAG_SUSPEND         0x02
+ 
++/* Common CCW commands */
++#define CCW_CMD_READ_IPL         0x02
+ #define CCW_CMD_NOOP             0x03
+ #define CCW_CMD_BASIC_SENSE      0x04
+ #define CCW_CMD_TIC              0x08
+ #define CCW_CMD_SENSE_ID         0xe4
+ 
++/* Virtio CCW commands */
+ #define CCW_CMD_SET_VQ           0x13
+ #define CCW_CMD_VDEV_RESET       0x33
+ #define CCW_CMD_READ_FEAT        0x12
+@@ -216,6 +219,12 @@ typedef struct ccw1 {
+ #define CCW_CMD_SET_CONF_IND     0x53
+ #define CCW_CMD_READ_VQ_CONF     0x32
+ 
++/* DASD CCW commands */
++#define CCW_CMD_DASD_READ             0x06
++#define CCW_CMD_DASD_SEEK             0x07
++#define CCW_CMD_DASD_SEARCH_ID_EQ     0x31
++#define CCW_CMD_DASD_READ_MT          0x86
++
+ /*
+  * Command-mode operation request block
+  */
+@@ -333,6 +342,20 @@ typedef struct irb {
+     __u32 emw[8];
+ }  __attribute__ ((packed, aligned(4))) Irb;
+ 
++/* Used for SEEK ccw commands */
++typedef struct CcwSeekData {
++    uint16_t reserved;
++    uint16_t cyl;
++    uint16_t head;
++} __attribute__((packed)) CcwSeekData;
++
++/* Used for SEARCH ID ccw commands */
++typedef struct CcwSearchIdData {
++    uint16_t cyl;
++    uint16_t head;
++    uint8_t record;
++} __attribute__((packed)) CcwSearchIdData;
++
+ int enable_mss_facility(void);
+ void enable_subchannel(SubChannelId schid);
+ uint16_t cu_type(SubChannelId schid);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Clean-up-cio.h.patch b/SOURCES/kvm-s390-bios-Clean-up-cio.h.patch
new file mode 100644
index 0000000..7dd990a
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Clean-up-cio.h.patch
@@ -0,0 +1,251 @@
+From fc07c126ddd0796c1996b2e527e69486c9c848b9 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:33 +0100
+Subject: [PATCH 08/21] s390-bios: Clean up cio.h
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-6-thuth@redhat.com>
+Patchwork-id: 91782
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 05/17] s390-bios: Clean up cio.h
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Add proper typedefs to all structs and modify all bit fields to use consistent
+formatting.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Collin Walling <walling@linux.ibm.com>
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-5-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit d96c5db77f1058ee9509554f43b945c66b3aa7c9)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/cio.h      | 114 ++++++++++++++++++++++----------------------
+ pc-bios/s390-ccw/s390-ccw.h |   8 ----
+ 2 files changed, 57 insertions(+), 65 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
+index 1a0795f..ed5b2cb 100644
+--- a/pc-bios/s390-ccw/cio.h
++++ b/pc-bios/s390-ccw/cio.h
+@@ -17,35 +17,35 @@
+  * path management control word
+  */
+ struct pmcw {
+-    __u32 intparm;        /* interruption parameter */
+-    __u32 qf      : 1;    /* qdio facility */
+-    __u32 w       : 1;
+-    __u32 isc     : 3;    /* interruption sublass */
+-    __u32 res5    : 3;    /* reserved zeros */
+-    __u32 ena     : 1;    /* enabled */
+-    __u32 lm      : 2;    /* limit mode */
+-    __u32 mme     : 2;    /* measurement-mode enable */
+-    __u32 mp      : 1;    /* multipath mode */
+-    __u32 tf      : 1;    /* timing facility */
+-    __u32 dnv     : 1;    /* device number valid */
+-    __u32 dev     : 16;   /* device number */
+-    __u8  lpm;            /* logical path mask */
+-    __u8  pnom;           /* path not operational mask */
+-    __u8  lpum;           /* last path used mask */
+-    __u8  pim;            /* path installed mask */
+-    __u16 mbi;            /* measurement-block index */
+-    __u8  pom;            /* path operational mask */
+-    __u8  pam;            /* path available mask */
+-    __u8  chpid[8];       /* CHPID 0-7 (if available) */
+-    __u32 unused1 : 8;    /* reserved zeros */
+-    __u32 st      : 3;    /* subchannel type */
+-    __u32 unused2 : 18;   /* reserved zeros */
+-    __u32 mbfc    : 1;    /* measurement block format control */
+-    __u32 xmwme   : 1;    /* extended measurement word mode enable */
+-    __u32 csense  : 1;    /* concurrent sense; can be enabled ...*/
+-                /*  ... per MSCH, however, if facility */
+-                /*  ... is not installed, this results */
+-                /*  ... in an operand exception.       */
++    __u32 intparm;      /* interruption parameter */
++    __u32 qf:1;         /* qdio facility */
++    __u32 w:1;
++    __u32 isc:3;        /* interruption sublass */
++    __u32 res5:3;       /* reserved zeros */
++    __u32 ena:1;        /* enabled */
++    __u32 lm:2;         /* limit mode */
++    __u32 mme:2;        /* measurement-mode enable */
++    __u32 mp:1;         /* multipath mode */
++    __u32 tf:1;         /* timing facility */
++    __u32 dnv:1;        /* device number valid */
++    __u32 dev:16;       /* device number */
++    __u8  lpm;          /* logical path mask */
++    __u8  pnom;         /* path not operational mask */
++    __u8  lpum;         /* last path used mask */
++    __u8  pim;          /* path installed mask */
++    __u16 mbi;          /* measurement-block index */
++    __u8  pom;          /* path operational mask */
++    __u8  pam;          /* path available mask */
++    __u8  chpid[8];     /* CHPID 0-7 (if available) */
++    __u32 unused1:8;    /* reserved zeros */
++    __u32 st:3;         /* subchannel type */
++    __u32 unused2:18;   /* reserved zeros */
++    __u32 mbfc:1;       /* measurement block format control */
++    __u32 xmwme:1;      /* extended measurement word mode enable */
++    __u32 csense:1;     /* concurrent sense; can be enabled ...*/
++                        /*  ... per MSCH, however, if facility */
++                        /*  ... is not installed, this results */
++                        /*  ... in an operand exception.       */
+ } __attribute__ ((packed));
+ 
+ /* Target SCHIB configuration. */
+@@ -77,28 +77,28 @@ struct scsw {
+ /*
+  * subchannel information block
+  */
+-struct schib {
++typedef struct schib {
+     struct pmcw pmcw;     /* path management control word */
+     struct scsw scsw;     /* subchannel status word */
+     __u64 mba;            /* measurement block address */
+     __u8 mda[4];          /* model dependent area */
+-} __attribute__ ((packed,aligned(4)));
+-
+-struct subchannel_id {
+-        __u32 cssid  : 8;
+-        __u32        : 4;
+-        __u32 m      : 1;
+-        __u32 ssid   : 2;
+-        __u32 one    : 1;
+-        __u32 sch_no : 16;
+-} __attribute__ ((packed, aligned(4)));
++} __attribute__ ((packed, aligned(4))) Schib;
++
++typedef struct subchannel_id {
++        __u32 cssid:8;
++        __u32:4;
++        __u32 m:1;
++        __u32 ssid:2;
++        __u32 one:1;
++        __u32 sch_no:16;
++} __attribute__ ((packed, aligned(4))) SubChannelId;
+ 
+ struct chsc_header {
+     __u16 length;
+     __u16 code;
+ } __attribute__((packed));
+ 
+-struct chsc_area_sda {
++typedef struct chsc_area_sda {
+     struct chsc_header request;
+     __u8 reserved1:4;
+     __u8 format:4;
+@@ -111,29 +111,29 @@ struct chsc_area_sda {
+     __u32 reserved5:4;
+     __u32 format2:4;
+     __u32 reserved6:24;
+-} __attribute__((packed));
++} __attribute__((packed)) ChscAreaSda;
+ 
+ /*
+  * TPI info structure
+  */
+ struct tpi_info {
+     struct subchannel_id schid;
+-    __u32 intparm;         /* interruption parameter */
+-    __u32 adapter_IO : 1;
+-    __u32 reserved2  : 1;
+-    __u32 isc        : 3;
+-    __u32 reserved3  : 12;
+-    __u32 int_type   : 3;
+-    __u32 reserved4  : 12;
++    __u32 intparm;      /* interruption parameter */
++    __u32 adapter_IO:1;
++    __u32 reserved2:1;
++    __u32 isc:3;
++    __u32 reserved3:12;
++    __u32 int_type:3;
++    __u32 reserved4:12;
+ } __attribute__ ((packed, aligned(4)));
+ 
+ /* channel command word (type 1) */
+-struct ccw1 {
++typedef struct ccw1 {
+     __u8 cmd_code;
+     __u8 flags;
+     __u16 count;
+     __u32 cda;
+-} __attribute__ ((packed, aligned(8)));
++} __attribute__ ((packed, aligned(8))) Ccw1;
+ 
+ #define CCW_FLAG_DC              0x80
+ #define CCW_FLAG_CC              0x40
+@@ -162,7 +162,7 @@ struct ccw1 {
+ /*
+  * Command-mode operation request block
+  */
+-struct cmd_orb {
++typedef struct cmd_orb {
+     __u32 intparm;    /* interruption parameter */
+     __u32 key:4;      /* flags, like key, suspend control, etc. */
+     __u32 spnd:1;     /* suspend control */
+@@ -182,7 +182,7 @@ struct cmd_orb {
+     __u32 zero:6;     /* reserved zeros */
+     __u32 orbx:1;     /* ORB extension control */
+     __u32 cpa;    /* channel program address */
+-}  __attribute__ ((packed, aligned(4)));
++}  __attribute__ ((packed, aligned(4))) CmdOrb;
+ 
+ struct ciw {
+     __u8 type;
+@@ -193,7 +193,7 @@ struct ciw {
+ /*
+  * sense-id response buffer layout
+  */
+-struct senseid {
++typedef struct senseid {
+     /* common part */
+     __u8  reserved;   /* always 0x'FF' */
+     __u16 cu_type;    /* control unit type */
+@@ -203,15 +203,15 @@ struct senseid {
+     __u8  unused;     /* padding byte */
+     /* extended part */
+     struct ciw ciw[62];
+-}  __attribute__ ((packed, aligned(4)));
++}  __attribute__ ((packed, aligned(4))) SenseId;
+ 
+ /* interruption response block */
+-struct irb {
++typedef struct irb {
+     struct scsw scsw;
+     __u32 esw[5];
+     __u32 ecw[8];
+     __u32 emw[8];
+-}  __attribute__ ((packed, aligned(4)));
++}  __attribute__ ((packed, aligned(4))) Irb;
+ 
+ /*
+  * Some S390 specific IO instructions as inline
+diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
+index 9828aa2..241c6d0 100644
+--- a/pc-bios/s390-ccw/s390-ccw.h
++++ b/pc-bios/s390-ccw/s390-ccw.h
+@@ -49,14 +49,6 @@ typedef unsigned long long __u64;
+ #include "cio.h"
+ #include "iplb.h"
+ 
+-typedef struct irb Irb;
+-typedef struct ccw1 Ccw1;
+-typedef struct cmd_orb CmdOrb;
+-typedef struct schib Schib;
+-typedef struct chsc_area_sda ChscAreaSda;
+-typedef struct senseid SenseId;
+-typedef struct subchannel_id SubChannelId;
+-
+ /* start.s */
+ void disabled_wait(void);
+ void consume_sclp_int(void);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Decouple-channel-i-o-logic-from-virtio.patch b/SOURCES/kvm-s390-bios-Decouple-channel-i-o-logic-from-virtio.patch
new file mode 100644
index 0000000..4e8b917
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Decouple-channel-i-o-logic-from-virtio.patch
@@ -0,0 +1,226 @@
+From 9fa5a139c303dd7cedabafda03bcd79807b01086 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:34 +0100
+Subject: [PATCH 09/21] s390-bios: Decouple channel i/o logic from virtio
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-7-thuth@redhat.com>
+Patchwork-id: 91779
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 06/17] s390-bios: Decouple channel i/o logic from virtio
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Create a separate library for channel i/o related code. This decouples
+channel i/o operations from virtio and allows us to make use of them for
+the real dasd boot path.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-6-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 120d04103e3f870d0fcd2a23c2ada0a4a4f036cc)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/Makefile    |  2 +-
+ pc-bios/s390-ccw/cio.c       | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ pc-bios/s390-ccw/cio.h       |  3 +++
+ pc-bios/s390-ccw/main.c      |  1 +
+ pc-bios/s390-ccw/netboot.mak |  2 +-
+ pc-bios/s390-ccw/netmain.c   |  1 +
+ pc-bios/s390-ccw/s390-ccw.h  |  1 -
+ pc-bios/s390-ccw/virtio.c    | 27 ++-------------------------
+ 8 files changed, 53 insertions(+), 28 deletions(-)
+ create mode 100644 pc-bios/s390-ccw/cio.c
+
+diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
+index 439e3cc..acca961 100644
+--- a/pc-bios/s390-ccw/Makefile
++++ b/pc-bios/s390-ccw/Makefile
+@@ -10,7 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
+ .PHONY : all clean build-all
+ 
+ OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
+-	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o
++	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o
+ 
+ QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
+ QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
+diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
+new file mode 100644
+index 0000000..87c6b34
+--- /dev/null
++++ b/pc-bios/s390-ccw/cio.c
+@@ -0,0 +1,44 @@
++/*
++ * S390 Channel I/O
++ *
++ * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
++ * Copyright (c) 2019 IBM Corp.
++ *
++ * Author(s): Jason J. Herne <jjherne@us.ibm.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++#include "libc.h"
++#include "s390-ccw.h"
++#include "cio.h"
++
++static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
++
++int enable_mss_facility(void)
++{
++    int ret;
++    ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page;
++
++    memset(sda_area, 0, PAGE_SIZE);
++    sda_area->request.length = 0x0400;
++    sda_area->request.code = 0x0031;
++    sda_area->operation_code = 0x2;
++
++    ret = chsc(sda_area);
++    if ((ret == 0) && (sda_area->response.code == 0x0001)) {
++        return 0;
++    }
++    return -EIO;
++}
++
++void enable_subchannel(SubChannelId schid)
++{
++    Schib schib;
++
++    stsch_err(schid, &schib);
++    schib.pmcw.ena = 1;
++    msch(schid, &schib);
++}
+diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
+index ed5b2cb..218fd96 100644
+--- a/pc-bios/s390-ccw/cio.h
++++ b/pc-bios/s390-ccw/cio.h
+@@ -213,6 +213,9 @@ typedef struct irb {
+     __u32 emw[8];
+ }  __attribute__ ((packed, aligned(4))) Irb;
+ 
++int enable_mss_facility(void);
++void enable_subchannel(SubChannelId schid);
++
+ /*
+  * Some S390 specific IO instructions as inline
+  */
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index 67df421..10f04c6 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -10,6 +10,7 @@
+ 
+ #include "libc.h"
+ #include "s390-ccw.h"
++#include "cio.h"
+ #include "virtio.h"
+ 
+ char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
+index 4f64128..d17b424 100644
+--- a/pc-bios/s390-ccw/netboot.mak
++++ b/pc-bios/s390-ccw/netboot.mak
+@@ -1,7 +1,7 @@
+ 
+ SLOF_DIR := $(SRC_PATH)/roms/SLOF
+ 
+-NETOBJS := start.o sclp.o virtio.o virtio-net.o jump2ipl.o netmain.o \
++NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o \
+ 	   libnet.a libc.a
+ 
+ LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include
+diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
+index d60e84f..4e1b8cf 100644
+--- a/pc-bios/s390-ccw/netmain.c
++++ b/pc-bios/s390-ccw/netmain.c
+@@ -32,6 +32,7 @@
+ #include <time.h>
+ 
+ #include "s390-ccw.h"
++#include "cio.h"
+ #include "virtio.h"
+ 
+ #define DEFAULT_BOOT_RETRIES 10
+diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
+index 241c6d0..b39ee5d 100644
+--- a/pc-bios/s390-ccw/s390-ccw.h
++++ b/pc-bios/s390-ccw/s390-ccw.h
+@@ -72,7 +72,6 @@ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2,
+ bool virtio_is_supported(SubChannelId schid);
+ void virtio_blk_setup_device(SubChannelId schid);
+ int virtio_read(ulong sector, void *load_addr);
+-int enable_mss_facility(void);
+ u64 get_clock(void);
+ ulong get_second(void);
+ 
+diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
+index cdb66f4..aa9da72 100644
+--- a/pc-bios/s390-ccw/virtio.c
++++ b/pc-bios/s390-ccw/virtio.c
+@@ -10,6 +10,7 @@
+ 
+ #include "libc.h"
+ #include "s390-ccw.h"
++#include "cio.h"
+ #include "virtio.h"
+ #include "virtio-scsi.h"
+ #include "bswap.h"
+@@ -20,8 +21,6 @@ static VRing block[VIRTIO_MAX_VQS];
+ static char ring_area[VIRTIO_RING_SIZE * VIRTIO_MAX_VQS]
+                      __attribute__((__aligned__(PAGE_SIZE)));
+ 
+-static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+-
+ static VDev vdev = {
+     .nr_vqs = 1,
+     .vrings = block,
+@@ -94,14 +93,9 @@ static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
+ {
+     Ccw1 ccw = {};
+     CmdOrb orb = {};
+-    Schib schib;
+     int r;
+ 
+-    /* start command processing */
+-    stsch_err(vdev->schid, &schib);
+-    /* enable the subchannel for IPL device */
+-    schib.pmcw.ena = 1;
+-    msch(vdev->schid, &schib);
++    enable_subchannel(vdev->schid);
+ 
+     /* start subchannel command */
+     orb.fmt = 1;
+@@ -343,20 +337,3 @@ bool virtio_is_supported(SubChannelId schid)
+     }
+     return false;
+ }
+-
+-int enable_mss_facility(void)
+-{
+-    int ret;
+-    ChscAreaSda *sda_area = (ChscAreaSda *) chsc_page;
+-
+-    memset(sda_area, 0, PAGE_SIZE);
+-    sda_area->request.length = 0x0400;
+-    sda_area->request.code = 0x0031;
+-    sda_area->operation_code = 0x2;
+-
+-    ret = chsc(sda_area);
+-    if ((ret == 0) && (sda_area->response.code == 0x0001)) {
+-        return 0;
+-    }
+-    return -EIO;
+-}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Extend-find_dev-for-non-virtio-devices.patch b/SOURCES/kvm-s390-bios-Extend-find_dev-for-non-virtio-devices.patch
new file mode 100644
index 0000000..eb8c504
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Extend-find_dev-for-non-virtio-devices.patch
@@ -0,0 +1,72 @@
+From edf2dd4c4eda49957b845ea90a084dde0951f92a Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:39 +0100
+Subject: [PATCH 14/21] s390-bios: Extend find_dev() for non-virtio devices
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-12-thuth@redhat.com>
+Patchwork-id: 91784
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 11/17] s390-bios: Extend find_dev() for non-virtio devices
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+We need a method for finding the subchannel of a dasd device. Let's
+modify find_dev to handle this since it mostly does what we need. Up to
+this point find_dev has been specific to only virtio devices.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <1554388475-18329-11-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 930072d2bf30986e57dac5c5945a32492f288944)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index e403b5f..d04ea89 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -52,6 +52,12 @@ unsigned int get_loadparm_index(void)
+     return atoui(loadparm_str);
+ }
+ 
++/*
++ * Find the subchannel connected to the given device (dev_no) and fill in the
++ * subchannel information block (schib) with the connected subchannel's info.
++ * NOTE: The global variable blk_schid is updated to contain the subchannel
++ * information.
++ */
+ static bool find_dev(Schib *schib, int dev_no)
+ {
+     int i, r;
+@@ -65,15 +71,15 @@ static bool find_dev(Schib *schib, int dev_no)
+         if (!schib->pmcw.dnv) {
+             continue;
+         }
+-        if (!virtio_is_supported(blk_schid)) {
+-            continue;
+-        }
++
+         /* Skip net devices since no IPLB is created and therefore no
+-         * no network bootloader has been loaded
++         * network bootloader has been loaded
+          */
+-        if (virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
++        if (virtio_is_supported(blk_schid) &&
++            virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
+             continue;
+         }
++
+         if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
+             return true;
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Factor-finding-boot-device-out-of-virtio-c.patch b/SOURCES/kvm-s390-bios-Factor-finding-boot-device-out-of-virtio-c.patch
new file mode 100644
index 0000000..3d82337
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Factor-finding-boot-device-out-of-virtio-c.patch
@@ -0,0 +1,201 @@
+From e9b154b1297ac5aff8737dde61b6793fcd7c0a69 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:40 +0100
+Subject: [PATCH 15/21] s390-bios: Factor finding boot device out of virtio
+ code path
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-13-thuth@redhat.com>
+Patchwork-id: 91789
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 12/17] s390-bios: Factor finding boot device out of virtio code path
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Make a new routine find_boot_device to locate the boot device for all
+cases, not just virtio.
+
+The error message for the case where no boot device has been specified
+and a suitable boot device cannot be auto detected was specific to
+virtio devices. We update this message to remove virtio specific wording.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <1554388475-18329-12-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 7b361db37b18a75860decc0a85e0194936401d66)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	tests/boot-serial-test.c
+	(we're missing commit 052888f043ba in downstream)
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c  | 85 ++++++++++++++++++++++++++----------------------
+ tests/boot-serial-test.c |  2 +-
+ 2 files changed, 47 insertions(+), 40 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index d04ea89..d3a161c 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -58,17 +58,18 @@ unsigned int get_loadparm_index(void)
+  * NOTE: The global variable blk_schid is updated to contain the subchannel
+  * information.
+  */
+-static bool find_dev(Schib *schib, int dev_no)
++static bool find_subch(int dev_no)
+ {
++    Schib schib;
+     int i, r;
+ 
+     for (i = 0; i < 0x10000; i++) {
+         blk_schid.sch_no = i;
+-        r = stsch_err(blk_schid, schib);
++        r = stsch_err(blk_schid, &schib);
+         if ((r == 3) || (r == -EIO)) {
+             break;
+         }
+-        if (!schib->pmcw.dnv) {
++        if (!schib.pmcw.dnv) {
+             continue;
+         }
+ 
+@@ -80,7 +81,7 @@ static bool find_dev(Schib *schib, int dev_no)
+             continue;
+         }
+ 
+-        if ((dev_no < 0) || (schib->pmcw.dev == dev_no)) {
++        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
+             return true;
+         }
+     }
+@@ -136,56 +137,61 @@ static void boot_setup(void)
+     have_iplb = store_iplb(&iplb);
+ }
+ 
+-static void virtio_setup(void)
++static void find_boot_device(void)
+ {
+-    Schib schib;
+-    int ssid;
+-    bool found = false;
+-    uint16_t dev_no;
+     VDev *vdev = virtio_get_device();
+-    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+-
+-    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
++    int ssid;
++    bool found;
+ 
+-    if (have_iplb) {
+-        switch (iplb.pbt) {
+-        case S390_IPL_TYPE_CCW:
+-            dev_no = iplb.ccw.devno;
+-            debug_print_int("device no. ", dev_no);
+-            blk_schid.ssid = iplb.ccw.ssid & 0x3;
+-            debug_print_int("ssid ", blk_schid.ssid);
+-            found = find_dev(&schib, dev_no);
+-            break;
+-        case S390_IPL_TYPE_QEMU_SCSI:
+-            vdev->scsi_device_selected = true;
+-            vdev->selected_scsi_device.channel = iplb.scsi.channel;
+-            vdev->selected_scsi_device.target = iplb.scsi.target;
+-            vdev->selected_scsi_device.lun = iplb.scsi.lun;
+-            blk_schid.ssid = iplb.scsi.ssid & 0x3;
+-            found = find_dev(&schib, iplb.scsi.devno);
+-            break;
+-        default:
+-            panic("List-directed IPL not supported yet!\n");
+-        }
+-        menu_setup();
+-    } else {
++    if (!have_iplb) {
+         for (ssid = 0; ssid < 0x3; ssid++) {
+             blk_schid.ssid = ssid;
+-            found = find_dev(&schib, -1);
++            found = find_subch(-1);
+             if (found) {
+-                break;
++                return;
+             }
+         }
++        panic("Could not find a suitable boot device (none specified)\n");
++    }
++
++    switch (iplb.pbt) {
++    case S390_IPL_TYPE_CCW:
++        debug_print_int("device no. ", iplb.ccw.devno);
++        blk_schid.ssid = iplb.ccw.ssid & 0x3;
++        debug_print_int("ssid ", blk_schid.ssid);
++        found = find_subch(iplb.ccw.devno);
++        break;
++    case S390_IPL_TYPE_QEMU_SCSI:
++        vdev->scsi_device_selected = true;
++        vdev->selected_scsi_device.channel = iplb.scsi.channel;
++        vdev->selected_scsi_device.target = iplb.scsi.target;
++        vdev->selected_scsi_device.lun = iplb.scsi.lun;
++        blk_schid.ssid = iplb.scsi.ssid & 0x3;
++        found = find_subch(iplb.scsi.devno);
++        break;
++    default:
++        panic("List-directed IPL not supported yet!\n");
+     }
+ 
+-    IPL_assert(found, "No virtio device found");
++    IPL_assert(found, "Boot device not found\n");
++}
++
++static void virtio_setup(void)
++{
++    VDev *vdev = virtio_get_device();
++    QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
++
++    memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
++
++    if (have_iplb) {
++        menu_setup();
++    }
+ 
+     if (virtio_get_device_type() == VIRTIO_ID_NET) {
+         sclp_print("Network boot device detected\n");
+         vdev->netboot_start_addr = qipl.netboot_start_addr;
+     } else {
+         virtio_blk_setup_device(blk_schid);
+-
+         IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected");
+     }
+ }
+@@ -195,8 +201,9 @@ int main(void)
+     sclp_setup();
+     css_setup();
+     boot_setup();
+-    virtio_setup();
++    find_boot_device();
+ 
++    virtio_setup();
+     zipl_load(); /* no return */
+ 
+     panic("Failed to load OS from hard disk\n");
+diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
+index dc682c1..fe52668 100644
+--- a/tests/boot-serial-test.c
++++ b/tests/boot-serial-test.c
+@@ -97,7 +97,7 @@ static testdef_t tests[] = {
+     { "sparc", "SS-600MP", "", "TMS390Z55" },
+     { "sparc64", "sun4u", "", "UltraSPARC" },
+     { "s390x", "s390-ccw-virtio",
+-      "-nodefaults -device sclpconsole,chardev=serial0", "virtio device" },
++      "-nodefaults -device sclpconsole,chardev=serial0", "device" },
+     { "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
+     { "microblaze", "petalogix-s3adsp1800", "", "TT",
+       sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Map-low-core-memory.patch b/SOURCES/kvm-s390-bios-Map-low-core-memory.patch
new file mode 100644
index 0000000..51cf633
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Map-low-core-memory.patch
@@ -0,0 +1,152 @@
+From 256d99ee0acedd9ca8f21c9ebec83eee5e905c9d Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:35 +0100
+Subject: [PATCH 10/21] s390-bios: Map low core memory
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-8-thuth@redhat.com>
+Patchwork-id: 91786
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 07/17] s390-bios: Map low core memory
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Create a new header for basic architecture specific definitions and add a
+mapping of low core memory. This mapping will be used by the real dasd boot
+process.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-7-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit c95df3d108028ff5a709ee3aefdb14401b07cb39)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c      |  2 +
+ pc-bios/s390-ccw/s390-arch.h | 90 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 92 insertions(+)
+ create mode 100644 pc-bios/s390-ccw/s390-arch.h
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index 10f04c6..e403b5f 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -9,6 +9,7 @@
+  */
+ 
+ #include "libc.h"
++#include "s390-arch.h"
+ #include "s390-ccw.h"
+ #include "cio.h"
+ #include "virtio.h"
+@@ -19,6 +20,7 @@ static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ QemuIplParameters qipl;
+ IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
+ static bool have_iplb;
++LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
+ 
+ #define LOADPARM_PROMPT "PROMPT  "
+ #define LOADPARM_EMPTY  "        "
+diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
+new file mode 100644
+index 0000000..5e92c7a
+--- /dev/null
++++ b/pc-bios/s390-ccw/s390-arch.h
+@@ -0,0 +1,90 @@
++/*
++ * S390 Basic Architecture
++ *
++ * Copyright (c) 2019 Jason J. Herne <jjherne@us.ibm.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++#ifndef S390_ARCH_H
++#define S390_ARCH_H
++
++typedef struct PSW {
++    uint64_t mask;
++    uint64_t addr;
++} __attribute__ ((aligned(8))) PSW;
++_Static_assert(sizeof(struct PSW) == 16, "PSW size incorrect");
++
++/* Older PSW format used by LPSW instruction */
++typedef struct PSWLegacy {
++    uint32_t mask;
++    uint32_t addr;
++} __attribute__ ((aligned(8))) PSWLegacy;
++_Static_assert(sizeof(struct PSWLegacy) == 8, "PSWLegacy size incorrect");
++
++/* s390 psw bit masks */
++#define PSW_MASK_IOINT      0x0200000000000000ULL
++#define PSW_MASK_WAIT       0x0002000000000000ULL
++#define PSW_MASK_EAMODE     0x0000000100000000ULL
++#define PSW_MASK_BAMODE     0x0000000080000000ULL
++#define PSW_MASK_ZMODE      (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
++
++/* Low core mapping */
++typedef struct LowCore {
++    /* prefix area: defined by architecture */
++    PSWLegacy       ipl_psw;                  /* 0x000 */
++    uint32_t        ccw1[2];                  /* 0x008 */
++    uint32_t        ccw2[2];                  /* 0x010 */
++    uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
++    uint32_t        ext_params;               /* 0x080 */
++    uint16_t        cpu_addr;                 /* 0x084 */
++    uint16_t        ext_int_code;             /* 0x086 */
++    uint16_t        svc_ilen;                 /* 0x088 */
++    uint16_t        svc_code;                 /* 0x08a */
++    uint16_t        pgm_ilen;                 /* 0x08c */
++    uint16_t        pgm_code;                 /* 0x08e */
++    uint32_t        data_exc_code;            /* 0x090 */
++    uint16_t        mon_class_num;            /* 0x094 */
++    uint16_t        per_perc_atmid;           /* 0x096 */
++    uint64_t        per_address;              /* 0x098 */
++    uint8_t         exc_access_id;            /* 0x0a0 */
++    uint8_t         per_access_id;            /* 0x0a1 */
++    uint8_t         op_access_id;             /* 0x0a2 */
++    uint8_t         ar_access_id;             /* 0x0a3 */
++    uint8_t         pad2[0xA8 - 0xA4];        /* 0x0a4 */
++    uint64_t        trans_exc_code;           /* 0x0a8 */
++    uint64_t        monitor_code;             /* 0x0b0 */
++    uint16_t        subchannel_id;            /* 0x0b8 */
++    uint16_t        subchannel_nr;            /* 0x0ba */
++    uint32_t        io_int_parm;              /* 0x0bc */
++    uint32_t        io_int_word;              /* 0x0c0 */
++    uint8_t         pad3[0xc8 - 0xc4];        /* 0x0c4 */
++    uint32_t        stfl_fac_list;            /* 0x0c8 */
++    uint8_t         pad4[0xe8 - 0xcc];        /* 0x0cc */
++    uint64_t        mcic;                     /* 0x0e8 */
++    uint8_t         pad5[0xf4 - 0xf0];        /* 0x0f0 */
++    uint32_t        external_damage_code;     /* 0x0f4 */
++    uint64_t        failing_storage_address;  /* 0x0f8 */
++    uint8_t         pad6[0x110 - 0x100];      /* 0x100 */
++    uint64_t        per_breaking_event_addr;  /* 0x110 */
++    uint8_t         pad7[0x120 - 0x118];      /* 0x118 */
++    PSW             restart_old_psw;          /* 0x120 */
++    PSW             external_old_psw;         /* 0x130 */
++    PSW             svc_old_psw;              /* 0x140 */
++    PSW             program_old_psw;          /* 0x150 */
++    PSW             mcck_old_psw;             /* 0x160 */
++    PSW             io_old_psw;               /* 0x170 */
++    uint8_t         pad8[0x1a0 - 0x180];      /* 0x180 */
++    PSW             restart_new_psw;          /* 0x1a0 */
++    PSW             external_new_psw;         /* 0x1b0 */
++    PSW             svc_new_psw;              /* 0x1c0 */
++    PSW             program_new_psw;          /* 0x1d0 */
++    PSW             mcck_new_psw;             /* 0x1e0 */
++    PSW             io_new_psw;               /* 0x1f0 */
++} __attribute__((packed, aligned(8192))) LowCore;
++
++extern LowCore const *lowcore;
++
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Refactor-virtio-to-run-channel-programs-vi.patch b/SOURCES/kvm-s390-bios-Refactor-virtio-to-run-channel-programs-vi.patch
new file mode 100644
index 0000000..ba8e222
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Refactor-virtio-to-run-channel-programs-vi.patch
@@ -0,0 +1,159 @@
+From 776fe22777dd348073449622797cfd9d12058f38 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:41 +0100
+Subject: [PATCH 16/21] s390-bios: Refactor virtio to run channel programs via
+ cio
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-14-thuth@redhat.com>
+Patchwork-id: 91793
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 13/17] s390-bios: Refactor virtio to run channel programs via cio
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Now that we have a Channel I/O library let's modify virtio boot code to
+make use of it for running channel programs.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Acked-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-13-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 9de6cbb152bee3917e58ad00633eddafb40d6678)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/virtio.c | 57 ++++++++++++++++++++++-------------------------
+ 1 file changed, 27 insertions(+), 30 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
+index aa9da72..35278eae 100644
+--- a/pc-bios/s390-ccw/virtio.c
++++ b/pc-bios/s390-ccw/virtio.c
+@@ -14,6 +14,7 @@
+ #include "virtio.h"
+ #include "virtio-scsi.h"
+ #include "bswap.h"
++#include "helper.h"
+ 
+ #define VRING_WAIT_REPLY_TIMEOUT 30
+ 
+@@ -89,33 +90,20 @@ int drain_irqs(SubChannelId schid)
+     }
+ }
+ 
+-static int run_ccw(VDev *vdev, int cmd, void *ptr, int len)
++static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
+ {
+     Ccw1 ccw = {};
+-    CmdOrb orb = {};
+-    int r;
+-
+-    enable_subchannel(vdev->schid);
+-
+-    /* start subchannel command */
+-    orb.fmt = 1;
+-    orb.cpa = (u32)(long)&ccw;
+-    orb.lpm = 0x80;
+ 
+     ccw.cmd_code = cmd;
+     ccw.cda = (long)ptr;
+     ccw.count = len;
+ 
+-    r = ssch(vdev->schid, &orb);
+-    /*
+-     * XXX Wait until device is done processing the CCW. For now we can
+-     *     assume that a simple tsch will have finished the CCW processing,
+-     *     but the architecture allows for asynchronous operation
+-     */
+-    if (!r) {
+-        r = drain_irqs(vdev->schid);
++    if (sli) {
++        ccw.flags |= CCW_FLAG_SLI;
+     }
+-    return r;
++
++    enable_subchannel(vdev->schid);
++    return do_cio(vdev->schid, vdev->senseid.cu_type, ptr2u32(&ccw), CCW_FMT1);
+ }
+ 
+ static void vring_init(VRing *vr, VqInfo *info)
+@@ -257,7 +245,7 @@ void virtio_setup_ccw(VDev *vdev)
+     vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */
+     vdev->guessed_disk_nature = VIRTIO_GDN_NONE;
+ 
+-    run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0);
++    run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false);
+ 
+     switch (vdev->senseid.cu_model) {
+     case VIRTIO_ID_NET:
+@@ -278,18 +266,19 @@ void virtio_setup_ccw(VDev *vdev)
+     default:
+         panic("Unsupported virtio device\n");
+     }
+-    IPL_assert(run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size) == 0,
+-               "Could not get block device configuration");
++    IPL_assert(
++        run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false) == 0,
++       "Could not get block device configuration");
+ 
+     /* Feature negotiation */
+     for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) {
+         feats.features = 0;
+         feats.index = i;
+-        rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats));
++        rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false);
+         IPL_assert(rc == 0, "Could not get features bits");
+         vdev->guest_features[i] &= bswap32(feats.features);
+         feats.features = bswap32(vdev->guest_features[i]);
+-        rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats));
++        rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false);
+         IPL_assert(rc == 0, "Could not set features bits");
+     }
+ 
+@@ -306,16 +295,17 @@ void virtio_setup_ccw(VDev *vdev)
+         };
+ 
+         IPL_assert(
+-            run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config)) == 0,
++            run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), false) == 0,
+             "Could not get block device VQ configuration");
+         info.num = config.num;
+         vring_init(&vdev->vrings[i], &info);
+         vdev->vrings[i].schid = vdev->schid;
+-        IPL_assert(run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info)) == 0,
+-                   "Cannot set VQ info");
++        IPL_assert(
++            run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false) == 0,
++            "Cannot set VQ info");
+     }
+     IPL_assert(
+-        run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status)) == 0,
++        run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false) == 0,
+         "Could not write status to host");
+ }
+ 
+@@ -323,8 +313,15 @@ bool virtio_is_supported(SubChannelId schid)
+ {
+     vdev.schid = schid;
+     memset(&vdev.senseid, 0, sizeof(vdev.senseid));
+-    /* run sense id command */
+-    if (run_ccw(&vdev, CCW_CMD_SENSE_ID, &vdev.senseid, sizeof(vdev.senseid))) {
++
++    /*
++     * Run sense id command.
++     * The size of the senseid data differs between devices (notably,
++     * between virtio devices and dasds), so specify the largest possible
++     * size and suppress the incorrect length indication for smaller sizes.
++     */
++    if (run_ccw(&vdev, CCW_CMD_SENSE_ID, &vdev.senseid, sizeof(vdev.senseid),
++                true)) {
+         return false;
+     }
+     if (vdev.senseid.cu_type == 0x3832) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Support-booting-from-real-dasd-device.patch b/SOURCES/kvm-s390-bios-Support-booting-from-real-dasd-device.patch
new file mode 100644
index 0000000..86522dc
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Support-booting-from-real-dasd-device.patch
@@ -0,0 +1,520 @@
+From 2267eadd85126ea711cc8314c7df45a70486651c Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:44 +0100
+Subject: [PATCH 19/21] s390-bios: Support booting from real dasd device
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-17-thuth@redhat.com>
+Patchwork-id: 91791
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 16/17] s390-bios: Support booting from real dasd device
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Allows guest to boot from a vfio configured real dasd device.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <1554388475-18329-16-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit efa47d36da89f4b23c315a7cc085fab0d15eb47c)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	MAINTAINERS
+	(simple contextual conflict due to missing downstream commits)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ MAINTAINERS                  |   3 +-
+ docs/devel/s390-dasd-ipl.txt | 133 ++++++++++++++++++++++++
+ pc-bios/s390-ccw/Makefile    |   2 +-
+ pc-bios/s390-ccw/dasd-ipl.c  | 235 +++++++++++++++++++++++++++++++++++++++++++
+ pc-bios/s390-ccw/dasd-ipl.h  |  16 +++
+ pc-bios/s390-ccw/main.c      |   5 +
+ pc-bios/s390-ccw/s390-arch.h |  13 +++
+ 7 files changed, 405 insertions(+), 2 deletions(-)
+ create mode 100644 docs/devel/s390-dasd-ipl.txt
+ create mode 100644 pc-bios/s390-ccw/dasd-ipl.c
+ create mode 100644 pc-bios/s390-ccw/dasd-ipl.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 9b74756..770885a 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -896,7 +896,8 @@ M: Thomas Huth <thuth@redhat.com>
+ S: Supported
+ F: pc-bios/s390-ccw/
+ F: pc-bios/s390-ccw.img
+-T: git git://github.com/borntraeger/qemu.git s390-next
++F: docs/devel/s390-dasd-ipl.txt
++T: git https://github.com/borntraeger/qemu.git s390-next
+ L: qemu-s390x@nongnu.org
+ 
+ UniCore32 Machines
+diff --git a/docs/devel/s390-dasd-ipl.txt b/docs/devel/s390-dasd-ipl.txt
+new file mode 100644
+index 0000000..9107e04
+--- /dev/null
++++ b/docs/devel/s390-dasd-ipl.txt
+@@ -0,0 +1,133 @@
++*****************************
++***** s390 hardware IPL *****
++*****************************
++
++The s390 hardware IPL process consists of the following steps.
++
++1. A READ IPL ccw is constructed in memory location 0x0.
++    This ccw, by definition, reads the IPL1 record which is located on the disk
++    at cylinder 0 track 0 record 1. Note that the chain flag is on in this ccw
++    so when it is complete another ccw will be fetched and executed from memory
++    location 0x08.
++
++2. Execute the Read IPL ccw at 0x00, thereby reading IPL1 data into 0x00.
++    IPL1 data is 24 bytes in length and consists of the following pieces of
++    information: [psw][read ccw][tic ccw]. When the machine executes the Read
++    IPL ccw it read the 24-bytes of IPL1 to be read into memory starting at
++    location 0x0. Then the ccw program at 0x08 which consists of a read
++    ccw and a tic ccw is automatically executed because of the chain flag from
++    the original READ IPL ccw. The read ccw will read the IPL2 data into memory
++    and the TIC (Transfer In Channel) will transfer control to the channel
++    program contained in the IPL2 data. The TIC channel command is the
++    equivalent of a branch/jump/goto instruction for channel programs.
++    NOTE: The ccws in IPL1 are defined by the architecture to be format 0.
++
++3. Execute IPL2.
++    The TIC ccw instruction at the end of the IPL1 channel program will begin
++    the execution of the IPL2 channel program. IPL2 is stage-2 of the boot
++    process and will contain a larger channel program than IPL1. The point of
++    IPL2 is to find and load either the operating system or a small program that
++    loads the operating system from disk. At the end of this step all or some of
++    the real operating system is loaded into memory and we are ready to hand
++    control over to the guest operating system. At this point the guest
++    operating system is entirely responsible for loading any more data it might
++    need to function. NOTE: The IPL2 channel program might read data into memory
++    location 0 thereby overwriting the IPL1 psw and channel program. This is ok
++    as long as the data placed in location 0 contains a psw whose instruction
++    address points to the guest operating system code to execute at the end of
++    the IPL/boot process.
++    NOTE: The ccws in IPL2 are defined by the architecture to be format 0.
++
++4. Start executing the guest operating system.
++    The psw that was loaded into memory location 0 as part of the ipl process
++    should contain the needed flags for the operating system we have loaded. The
++    psw's instruction address will point to the location in memory where we want
++    to start executing the operating system. This psw is loaded (via LPSW
++    instruction) causing control to be passed to the operating system code.
++
++In a non-virtualized environment this process, handled entirely by the hardware,
++is kicked off by the user initiating a "Load" procedure from the hardware
++management console. This "Load" procedure crafts a special "Read IPL" ccw in
++memory location 0x0 that reads IPL1. It then executes this ccw thereby kicking
++off the reading of IPL1 data. Since the channel program from IPL1 will be
++written immediately after the special "Read IPL" ccw, the IPL1 channel program
++will be executed immediately (the special read ccw has the chaining bit turned
++on). The TIC at the end of the IPL1 channel program will cause the IPL2 channel
++program to be executed automatically. After this sequence completes the "Load"
++procedure then loads the psw from 0x0.
++
++**********************************************************
++***** How this all pertains to QEMU (and the kernel) *****
++**********************************************************
++
++In theory we should merely have to do the following to IPL/boot a guest
++operating system from a DASD device:
++
++1. Place a "Read IPL" ccw into memory location 0x0 with chaining bit on.
++2. Execute channel program at 0x0.
++3. LPSW 0x0.
++
++However, our emulation of the machine's channel program logic within the kernel
++is missing one key feature that is required for this process to work:
++non-prefetch of ccw data.
++
++When we start a channel program we pass the channel subsystem parameters via an
++ORB (Operation Request Block). One of those parameters is a prefetch bit. If the
++bit is on then the vfio-ccw kernel driver is allowed to read the entire channel
++program from guest memory before it starts executing it. This means that any
++channel commands that read additional channel commands will not work as expected
++because the newly read commands will only exist in guest memory and NOT within
++the kernel's channel subsystem memory. The kernel vfio-ccw driver currently
++requires this bit to be on for all channel programs. This is a problem because
++the IPL process consists of transferring control from the "Read IPL" ccw
++immediately to the IPL1 channel program that was read by "Read IPL".
++
++Not being able to turn off prefetch will also prevent the TIC at the end of the
++IPL1 channel program from transferring control to the IPL2 channel program.
++
++Lastly, in some cases (the zipl bootloader for example) the IPL2 program also
++transfers control to another channel program segment immediately after reading
++it from the disk. So we need to be able to handle this case.
++
++**************************
++***** What QEMU does *****
++**************************
++
++Since we are forced to live with prefetch we cannot use the very simple IPL
++procedure we defined in the preceding section. So we compensate by doing the
++following.
++
++1. Place "Read IPL" ccw into memory location 0x0, but turn off chaining bit.
++2. Execute "Read IPL" at 0x0.
++
++   So now IPL1's psw is at 0x0 and IPL1's channel program is at 0x08.
++
++4. Write a custom channel program that will seek to the IPL2 record and then
++   execute the READ and TIC ccws from IPL1.  Normally the seek is not required
++   because after reading the IPL1 record the disk is automatically positioned
++   to read the very next record which will be IPL2. But since we are not reading
++   both IPL1 and IPL2 as part of the same channel program we must manually set
++   the position.
++
++5. Grab the target address of the TIC instruction from the IPL1 channel program.
++   This address is where the IPL2 channel program starts.
++
++   Now IPL2 is loaded into memory somewhere, and we know the address.
++
++6. Execute the IPL2 channel program at the address obtained in step #5.
++
++   Because this channel program can be dynamic, we must use a special algorithm
++   that detects a READ immediately followed by a TIC and breaks the ccw chain
++   by turning off the chain bit in the READ ccw. When control is returned from
++   the kernel/hardware to the QEMU bios code we immediately issue another start
++   subchannel to execute the remaining TIC instruction. This causes the entire
++   channel program (starting from the TIC) and all needed data to be refetched
++   thereby stepping around the limitation that would otherwise prevent this
++   channel program from executing properly.
++
++   Now the operating system code is loaded somewhere in guest memory and the psw
++   in memory location 0x0 will point to entry code for the guest operating
++   system.
++
++7. LPSW 0x0.
++   LPSW transfers control to the guest operating system and we're done.
+diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
+index acca961..d6a6e18 100644
+--- a/pc-bios/s390-ccw/Makefile
++++ b/pc-bios/s390-ccw/Makefile
+@@ -10,7 +10,7 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
+ .PHONY : all clean build-all
+ 
+ OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
+-	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o
++	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o dasd-ipl.o
+ 
+ QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
+ QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
+diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c
+new file mode 100644
+index 0000000..0fc879b
+--- /dev/null
++++ b/pc-bios/s390-ccw/dasd-ipl.c
+@@ -0,0 +1,235 @@
++/*
++ * S390 IPL (boot) from a real DASD device via vfio framework.
++ *
++ * Copyright (c) 2019 Jason J. Herne <jjherne@us.ibm.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++#include "libc.h"
++#include "s390-ccw.h"
++#include "s390-arch.h"
++#include "dasd-ipl.h"
++#include "helper.h"
++
++static char prefix_page[PAGE_SIZE * 2]
++            __attribute__((__aligned__(PAGE_SIZE * 2)));
++
++static void enable_prefixing(void)
++{
++    memcpy(&prefix_page, lowcore, 4096);
++    set_prefix(ptr2u32(&prefix_page));
++}
++
++static void disable_prefixing(void)
++{
++    set_prefix(0);
++    /* Copy io interrupt info back to low core */
++    memcpy((void *)&lowcore->subchannel_id, prefix_page + 0xB8, 12);
++}
++
++static bool is_read_tic_ccw_chain(Ccw0 *ccw)
++{
++    Ccw0 *next_ccw = ccw + 1;
++
++    return ((ccw->cmd_code == CCW_CMD_DASD_READ ||
++            ccw->cmd_code == CCW_CMD_DASD_READ_MT) &&
++            ccw->chain && next_ccw->cmd_code == CCW_CMD_TIC);
++}
++
++static bool dynamic_cp_fixup(uint32_t ccw_addr, uint32_t  *next_cpa)
++{
++    Ccw0 *cur_ccw = (Ccw0 *)(uint64_t)ccw_addr;
++    Ccw0 *tic_ccw;
++
++    while (true) {
++        /* Skip over inline TIC (it might not have the chain bit on)  */
++        if (cur_ccw->cmd_code == CCW_CMD_TIC &&
++            cur_ccw->cda == ptr2u32(cur_ccw) - 8) {
++            cur_ccw += 1;
++            continue;
++        }
++
++        if (!cur_ccw->chain) {
++            break;
++        }
++        if (is_read_tic_ccw_chain(cur_ccw)) {
++            /*
++             * Breaking a chain of CCWs may alter the semantics or even the
++             * validity of a channel program. The heuristic implemented below
++             * seems to work well in practice for the channel programs
++             * generated by zipl.
++             */
++            tic_ccw = cur_ccw + 1;
++            *next_cpa = tic_ccw->cda;
++            cur_ccw->chain = 0;
++            return true;
++        }
++        cur_ccw += 1;
++    }
++    return false;
++}
++
++static int run_dynamic_ccw_program(SubChannelId schid, uint16_t cutype,
++                                   uint32_t cpa)
++{
++    bool has_next;
++    uint32_t next_cpa = 0;
++    int rc;
++
++    do {
++        has_next = dynamic_cp_fixup(cpa, &next_cpa);
++
++        print_int("executing ccw chain at ", cpa);
++        enable_prefixing();
++        rc = do_cio(schid, cutype, cpa, CCW_FMT0);
++        disable_prefixing();
++
++        if (rc) {
++            break;
++        }
++        cpa = next_cpa;
++    } while (has_next);
++
++    return rc;
++}
++
++static void make_readipl(void)
++{
++    Ccw0 *ccwIplRead = (Ccw0 *)0x00;
++
++    /* Create Read IPL ccw at address 0 */
++    ccwIplRead->cmd_code = CCW_CMD_READ_IPL;
++    ccwIplRead->cda = 0x00; /* Read into address 0x00 in main memory */
++    ccwIplRead->chain = 0; /* Chain flag */
++    ccwIplRead->count = 0x18; /* Read 0x18 bytes of data */
++}
++
++static void run_readipl(SubChannelId schid, uint16_t cutype)
++{
++    if (do_cio(schid, cutype, 0x00, CCW_FMT0)) {
++        panic("dasd-ipl: Failed to run Read IPL channel program\n");
++    }
++}
++
++/*
++ * The architecture states that IPL1 data should consist of a psw followed by
++ * format-0 READ and TIC CCWs. Let's sanity check.
++ */
++static void check_ipl1(void)
++{
++    Ccw0 *ccwread = (Ccw0 *)0x08;
++    Ccw0 *ccwtic = (Ccw0 *)0x10;
++
++    if (ccwread->cmd_code != CCW_CMD_DASD_READ ||
++        ccwtic->cmd_code != CCW_CMD_TIC) {
++        panic("dasd-ipl: IPL1 data invalid. Is this disk really bootable?\n");
++    }
++}
++
++static void check_ipl2(uint32_t ipl2_addr)
++{
++    Ccw0 *ccw = u32toptr(ipl2_addr);
++
++    if (ipl2_addr == 0x00) {
++        panic("IPL2 address invalid. Is this disk really bootable?\n");
++    }
++    if (ccw->cmd_code == 0x00) {
++        panic("IPL2 ccw data invalid. Is this disk really bootable?\n");
++    }
++}
++
++static uint32_t read_ipl2_addr(void)
++{
++    Ccw0 *ccwtic = (Ccw0 *)0x10;
++
++    return ccwtic->cda;
++}
++
++static void ipl1_fixup(void)
++{
++    Ccw0 *ccwSeek = (Ccw0 *) 0x08;
++    Ccw0 *ccwSearchID = (Ccw0 *) 0x10;
++    Ccw0 *ccwSearchTic = (Ccw0 *) 0x18;
++    Ccw0 *ccwRead = (Ccw0 *) 0x20;
++    CcwSeekData *seekData = (CcwSeekData *) 0x30;
++    CcwSearchIdData *searchData = (CcwSearchIdData *) 0x38;
++
++    /* move IPL1 CCWs to make room for CCWs needed to locate record 2 */
++    memcpy(ccwRead, (void *)0x08, 16);
++
++    /* Disable chaining so we don't TIC to IPL2 channel program */
++    ccwRead->chain = 0x00;
++
++    ccwSeek->cmd_code = CCW_CMD_DASD_SEEK;
++    ccwSeek->cda = ptr2u32(seekData);
++    ccwSeek->chain = 1;
++    ccwSeek->count = sizeof(*seekData);
++    seekData->reserved = 0x00;
++    seekData->cyl = 0x00;
++    seekData->head = 0x00;
++
++    ccwSearchID->cmd_code = CCW_CMD_DASD_SEARCH_ID_EQ;
++    ccwSearchID->cda = ptr2u32(searchData);
++    ccwSearchID->chain = 1;
++    ccwSearchID->count = sizeof(*searchData);
++    searchData->cyl = 0;
++    searchData->head = 0;
++    searchData->record = 2;
++
++    /* Go back to Search CCW if correct record not yet found */
++    ccwSearchTic->cmd_code = CCW_CMD_TIC;
++    ccwSearchTic->cda = ptr2u32(ccwSearchID);
++}
++
++static void run_ipl1(SubChannelId schid, uint16_t cutype)
++ {
++    uint32_t startAddr = 0x08;
++
++    if (do_cio(schid, cutype, startAddr, CCW_FMT0)) {
++        panic("dasd-ipl: Failed to run IPL1 channel program\n");
++    }
++}
++
++static void run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr)
++{
++    if (run_dynamic_ccw_program(schid, cutype, addr)) {
++        panic("dasd-ipl: Failed to run IPL2 channel program\n");
++    }
++}
++
++/*
++ * Limitations in vfio-ccw support complicate the IPL process. Details can
++ * be found in docs/devel/s390-dasd-ipl.txt
++ */
++void dasd_ipl(SubChannelId schid, uint16_t cutype)
++{
++    PSWLegacy *pswl = (PSWLegacy *) 0x00;
++    uint32_t ipl2_addr;
++
++    /* Construct Read IPL CCW and run it to read IPL1 from boot disk */
++    make_readipl();
++    run_readipl(schid, cutype);
++    ipl2_addr = read_ipl2_addr();
++    check_ipl1();
++
++    /*
++     * Fixup IPL1 channel program to account for vfio-ccw limitations, then run
++     * it to read IPL2 channel program from boot disk.
++     */
++    ipl1_fixup();
++    run_ipl1(schid, cutype);
++    check_ipl2(ipl2_addr);
++
++    /*
++     * Run IPL2 channel program to read operating system code from boot disk
++     */
++    run_ipl2(schid, cutype, ipl2_addr);
++
++    /* Transfer control to the guest operating system */
++    pswl->mask |= PSW_MASK_EAMODE;   /* Force z-mode */
++    pswl->addr |= PSW_MASK_BAMODE;   /* ...          */
++    jump_to_low_kernel();
++}
+diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h
+new file mode 100644
+index 0000000..c394828
+--- /dev/null
++++ b/pc-bios/s390-ccw/dasd-ipl.h
+@@ -0,0 +1,16 @@
++/*
++ * S390 IPL (boot) from a real DASD device via vfio framework.
++ *
++ * Copyright (c) 2019 Jason J. Herne <jjherne@us.ibm.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++#ifndef DASD_IPL_H
++#define DASD_IPL_H
++
++void dasd_ipl(SubChannelId schid, uint16_t cutype);
++
++#endif /* DASD_IPL_H */
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index 57a1013..3c449ad 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -13,6 +13,7 @@
+ #include "s390-ccw.h"
+ #include "cio.h"
+ #include "virtio.h"
++#include "dasd-ipl.h"
+ 
+ char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+ static SubChannelId blk_schid = { .one = 1 };
+@@ -209,6 +210,10 @@ int main(void)
+ 
+     cutype = cu_type(blk_schid);
+     switch (cutype) {
++    case CU_TYPE_DASD_3990:
++    case CU_TYPE_DASD_2107:
++        dasd_ipl(blk_schid, cutype); /* no return */
++        break;
+     case CU_TYPE_VIRTIO:
+         virtio_setup();
+         zipl_load(); /* no return */
+diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
+index 5e92c7a..504fc7c 100644
+--- a/pc-bios/s390-ccw/s390-arch.h
++++ b/pc-bios/s390-ccw/s390-arch.h
+@@ -87,4 +87,17 @@ typedef struct LowCore {
+ 
+ extern LowCore const *lowcore;
+ 
++static inline void set_prefix(uint32_t address)
++{
++    asm volatile("spx %0" : : "m" (address) : "memory");
++}
++
++static inline uint32_t store_prefix(void)
++{
++    uint32_t address;
++
++    asm volatile("stpx %0" : "=m" (address));
++    return address;
++}
++
+ #endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Support-for-running-format-0-1-channel-pro.patch b/SOURCES/kvm-s390-bios-Support-for-running-format-0-1-channel-pro.patch
new file mode 100644
index 0000000..eb6a65d
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Support-for-running-format-0-1-channel-pro.patch
@@ -0,0 +1,445 @@
+From 363d844cccb965c9eb0e0e6b5ca100e9532a2f0a Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:37 +0100
+Subject: [PATCH 12/21] s390-bios: Support for running format-0/1 channel
+ programs
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-10-thuth@redhat.com>
+Patchwork-id: 91783
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 09/17] s390-bios: Support for running format-0/1 channel programs
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Introduce a library function for executing format-0 and format-1
+channel programs and waiting for their completion before continuing
+execution.
+
+Add cu_type() to channel io library. This will be used to query control
+unit type which is used to determine if we are booting a virtio device or a
+real dasd device.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Message-Id: <1554388475-18329-9-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 3083a1bbb8716e9052fe375f68f330107ee13127)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/cio.c      | 144 ++++++++++++++++++++++++++++++++++++++++++++
+ pc-bios/s390-ccw/cio.h      | 130 ++++++++++++++++++++++++++++++++++++++-
+ pc-bios/s390-ccw/s390-ccw.h |   1 +
+ pc-bios/s390-ccw/start.S    |  29 +++++++++
+ 4 files changed, 301 insertions(+), 3 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
+index 87c6b34..c43e50b 100644
+--- a/pc-bios/s390-ccw/cio.c
++++ b/pc-bios/s390-ccw/cio.c
+@@ -13,10 +13,14 @@
+ 
+ #include "libc.h"
+ #include "s390-ccw.h"
++#include "s390-arch.h"
++#include "helper.h"
+ #include "cio.h"
+ 
+ static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+ 
++static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb);
++
+ int enable_mss_facility(void)
+ {
+     int ret;
+@@ -42,3 +46,143 @@ void enable_subchannel(SubChannelId schid)
+     schib.pmcw.ena = 1;
+     msch(schid, &schib);
+ }
++
++uint16_t cu_type(SubChannelId schid)
++{
++    Ccw1 sense_id_ccw;
++    SenseId sense_data;
++
++    sense_id_ccw.cmd_code = CCW_CMD_SENSE_ID;
++    sense_id_ccw.cda = ptr2u32(&sense_data);
++    sense_id_ccw.count = sizeof(sense_data);
++    sense_id_ccw.flags |= CCW_FLAG_SLI;
++
++    if (do_cio(schid, CU_TYPE_UNKNOWN, ptr2u32(&sense_id_ccw), CCW_FMT1)) {
++        panic("Failed to run SenseID CCw\n");
++    }
++
++    return sense_data.cu_type;
++}
++
++int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
++                 uint16_t data_size)
++{
++    Ccw1 senseCcw;
++    Irb irb;
++
++    senseCcw.cmd_code = CCW_CMD_BASIC_SENSE;
++    senseCcw.cda = ptr2u32(sense_data);
++    senseCcw.count = data_size;
++
++    return __do_cio(schid, ptr2u32(&senseCcw), CCW_FMT1, &irb);
++}
++
++static bool irb_error(Irb *irb)
++{
++    if (irb->scsw.cstat) {
++        return true;
++    }
++    return irb->scsw.dstat != (SCSW_DSTAT_DEVEND | SCSW_DSTAT_CHEND);
++}
++
++/*
++ * Handles executing ssch, tsch and returns the irb obtained from tsch.
++ * Returns 0 on success, -1 if unexpected status pending and we need to retry,
++ * otherwise returns condition code from ssch/tsch for error cases.
++ */
++static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb)
++{
++    CmdOrb orb = {};
++    int rc;
++
++    IPL_assert(fmt == 0 || fmt == 1, "Invalid ccw format");
++
++    /* ccw_addr must be <= 24 bits and point to at least one whole ccw. */
++    if (fmt == 0) {
++        IPL_assert(ccw_addr <= 0xFFFFFF - 8, "Invalid ccw address");
++    }
++
++    orb.fmt = fmt;
++    orb.pfch = 1;  /* QEMU's cio implementation requires prefetch */
++    orb.c64 = 1;   /* QEMU's cio implementation requires 64-bit idaws */
++    orb.lpm = 0xFF; /* All paths allowed */
++    orb.cpa = ccw_addr;
++
++    rc = ssch(schid, &orb);
++    if (rc == 1 || rc == 2) {
++        /* Subchannel status pending or busy. Eat status and ask for retry. */
++        tsch(schid, irb);
++        return -1;
++    }
++    if (rc) {
++        print_int("ssch failed with cc=", rc);
++        return rc;
++    }
++
++    consume_io_int();
++
++    /* collect status */
++    rc = tsch(schid, irb);
++    if (rc) {
++        print_int("tsch failed with cc=", rc);
++    }
++
++    return rc;
++}
++
++/*
++ * Executes a channel program at a given subchannel. The request to run the
++ * channel program is sent to the subchannel, we then wait for the interrupt
++ * signaling completion of the I/O operation(s) performed by the channel
++ * program. Lastly we verify that the i/o operation completed without error and
++ * that the interrupt we received was for the subchannel used to run the
++ * channel program.
++ *
++ * Note: This function assumes it is running in an environment where no other
++ * cpus are generating or receiving I/O interrupts. So either run it in a
++ * single-cpu environment or make sure all other cpus are not doing I/O and
++ * have I/O interrupts masked off. We also assume that only one device is
++ * active (generating i/o interrupts).
++ *
++ * Returns non-zero on error.
++ */
++int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt)
++{
++    Irb irb = {};
++    SenseDataEckdDasd sd;
++    int rc, retries = 0;
++
++    while (true) {
++        rc = __do_cio(schid, ccw_addr, fmt, &irb);
++
++        if (rc == -1) {
++            retries++;
++            continue;
++        }
++        if (rc) {
++            /* ssch/tsch error. Message already reported by __do_cio */
++            break;
++        }
++
++        if (!irb_error(&irb)) {
++            break;
++        }
++
++        /*
++         * Unexpected unit check, or interface-control-check. Use sense to
++         * clear (unit check only) then retry.
++         */
++        if ((unit_check(&irb) || iface_ctrl_check(&irb)) && retries <= 2) {
++            if (unit_check(&irb)) {
++                basic_sense(schid, cutype, &sd, sizeof(sd));
++            }
++            retries++;
++            continue;
++        }
++
++        rc = -1;
++        break;
++    }
++
++    return rc;
++}
+diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
+index 218fd96..1637e32 100644
+--- a/pc-bios/s390-ccw/cio.h
++++ b/pc-bios/s390-ccw/cio.h
+@@ -70,9 +70,46 @@ struct scsw {
+     __u16 count;
+ } __attribute__ ((packed));
+ 
+-#define SCSW_FCTL_CLEAR_FUNC 0x1000
+-#define SCSW_FCTL_HALT_FUNC 0x2000
++/* Function Control */
+ #define SCSW_FCTL_START_FUNC 0x4000
++#define SCSW_FCTL_HALT_FUNC 0x2000
++#define SCSW_FCTL_CLEAR_FUNC 0x1000
++
++/* Activity Control */
++#define SCSW_ACTL_RESUME_PEND   0x0800
++#define SCSW_ACTL_START_PEND    0x0400
++#define SCSW_ACTL_HALT_PEND     0x0200
++#define SCSW_ACTL_CLEAR_PEND    0x0100
++#define SCSW_ACTL_CH_ACTIVE     0x0080
++#define SCSW_ACTL_DEV_ACTIVE    0x0040
++#define SCSW_ACTL_SUSPENDED     0x0020
++
++/* Status Control */
++#define SCSW_SCTL_ALERT         0x0010
++#define SCSW_SCTL_INTERMED      0x0008
++#define SCSW_SCTL_PRIMARY       0x0004
++#define SCSW_SCTL_SECONDARY     0x0002
++#define SCSW_SCTL_STATUS_PEND   0x0001
++
++/* SCSW Device Status Flags */
++#define SCSW_DSTAT_ATTN     0x80
++#define SCSW_DSTAT_STATMOD  0x40
++#define SCSW_DSTAT_CUEND    0x20
++#define SCSW_DSTAT_BUSY     0x10
++#define SCSW_DSTAT_CHEND    0x08
++#define SCSW_DSTAT_DEVEND   0x04
++#define SCSW_DSTAT_UCHK     0x02
++#define SCSW_DSTAT_UEXCP    0x01
++
++/* SCSW Subchannel Status Flags */
++#define SCSW_CSTAT_PCINT    0x80
++#define SCSW_CSTAT_BADLEN   0x40
++#define SCSW_CSTAT_PROGCHK  0x20
++#define SCSW_CSTAT_PROTCHK  0x10
++#define SCSW_CSTAT_CHDCHK   0x08
++#define SCSW_CSTAT_CHCCHK   0x04
++#define SCSW_CSTAT_ICCHK    0x02
++#define SCSW_CSTAT_CHAINCHK 0x01
+ 
+ /*
+  * subchannel information block
+@@ -127,7 +164,23 @@ struct tpi_info {
+     __u32 reserved4:12;
+ } __attribute__ ((packed, aligned(4)));
+ 
+-/* channel command word (type 1) */
++/* channel command word (format 0) */
++typedef struct ccw0 {
++    __u8 cmd_code;
++    __u32 cda:24;
++    __u32 chainData:1;
++    __u32 chain:1;
++    __u32 sli:1;
++    __u32 skip:1;
++    __u32 pci:1;
++    __u32 ida:1;
++    __u32 suspend:1;
++    __u32 mida:1;
++    __u8 reserved;
++    __u16 count;
++} __attribute__ ((packed, aligned(8))) Ccw0;
++
++/* channel command word (format 1) */
+ typedef struct ccw1 {
+     __u8 cmd_code;
+     __u8 flags;
+@@ -135,6 +188,10 @@ typedef struct ccw1 {
+     __u32 cda;
+ } __attribute__ ((packed, aligned(8))) Ccw1;
+ 
++/* do_cio() CCW formats */
++#define CCW_FMT0                 0x00
++#define CCW_FMT1                 0x01
++
+ #define CCW_FLAG_DC              0x80
+ #define CCW_FLAG_CC              0x40
+ #define CCW_FLAG_SLI             0x20
+@@ -190,6 +247,11 @@ struct ciw {
+     __u16 count;
+ };
+ 
++#define CU_TYPE_UNKNOWN         0x0000
++#define CU_TYPE_DASD_2107       0x2107
++#define CU_TYPE_VIRTIO          0x3832
++#define CU_TYPE_DASD_3990       0x3990
++
+ /*
+  * sense-id response buffer layout
+  */
+@@ -205,6 +267,64 @@ typedef struct senseid {
+     struct ciw ciw[62];
+ }  __attribute__ ((packed, aligned(4))) SenseId;
+ 
++/*
++ * architected values for first sense byte - common_status. Bits 0-5 of this
++ * field are common to all device types.
++ */
++#define SNS_STAT0_CMD_REJECT         0x80
++#define SNS_STAT0_INTERVENTION_REQ   0x40
++#define SNS_STAT0_BUS_OUT_CHECK      0x20
++#define SNS_STAT0_EQUIPMENT_CHECK    0x10
++#define SNS_STAT0_DATA_CHECK         0x08
++#define SNS_STAT0_OVERRUN            0x04
++#define SNS_STAT0_INCOMPL_DOMAIN     0x01
++
++/* ECKD DASD status[0] byte */
++#define SNS_STAT1_PERM_ERR           0x80
++#define SNS_STAT1_INV_TRACK_FORMAT   0x40
++#define SNS_STAT1_EOC                0x20
++#define SNS_STAT1_MESSAGE_TO_OPER    0x10
++#define SNS_STAT1_NO_REC_FOUND       0x08
++#define SNS_STAT1_FILE_PROTECTED     0x04
++#define SNS_STAT1_WRITE_INHIBITED    0x02
++#define SNS_STAT1_IMPRECISE_END      0x01
++
++/* ECKD DASD status[1] byte */
++#define SNS_STAT2_REQ_INH_WRITE      0x80
++#define SNS_STAT2_CORRECTABLE        0x40
++#define SNS_STAT2_FIRST_LOG_ERR      0x20
++#define SNS_STAT2_ENV_DATA_PRESENT   0x10
++#define SNS_STAT2_IMPRECISE_END      0x04
++
++/* ECKD DASD 24-byte Sense fmt_msg codes */
++#define SENSE24_FMT_PROG_SYS    0x0
++#define SENSE24_FMT_EQUIPMENT   0x2
++#define SENSE24_FMT_CONTROLLER  0x3
++#define SENSE24_FMT_MISC        0xF
++
++/* basic sense response buffer layout */
++typedef struct SenseDataEckdDasd {
++    uint8_t common_status;
++    uint8_t status[2];
++    uint8_t res_count;
++    uint8_t phys_drive_id;
++    uint8_t low_cyl_addr;
++    uint8_t head_high_cyl_addr;
++    uint8_t fmt_msg;
++    uint64_t fmt_dependent_info[2];
++    uint8_t reserved;
++    uint8_t program_action_code;
++    uint16_t config_info;
++    uint8_t mcode_hicyl;
++    uint8_t cyl_head_addr[3];
++}  __attribute__ ((packed, aligned(4))) SenseDataEckdDasd;
++
++#define ECKD_SENSE24_GET_FMT(sd)     (sd->fmt_msg & 0xF0 >> 4)
++#define ECKD_SENSE24_GET_MSG(sd)     (sd->fmt_msg & 0x0F)
++
++#define unit_check(irb)         ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
++#define iface_ctrl_check(irb)   ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
++
+ /* interruption response block */
+ typedef struct irb {
+     struct scsw scsw;
+@@ -215,6 +335,10 @@ typedef struct irb {
+ 
+ int enable_mss_facility(void);
+ void enable_subchannel(SubChannelId schid);
++uint16_t cu_type(SubChannelId schid);
++int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
++                 uint16_t data_size);
++int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt);
+ 
+ /*
+  * Some S390 specific IO instructions as inline
+diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
+index b39ee5d..11bce7d 100644
+--- a/pc-bios/s390-ccw/s390-ccw.h
++++ b/pc-bios/s390-ccw/s390-ccw.h
+@@ -52,6 +52,7 @@ typedef unsigned long long __u64;
+ /* start.s */
+ void disabled_wait(void);
+ void consume_sclp_int(void);
++void consume_io_int(void);
+ 
+ /* main.c */
+ void panic(const char *string);
+diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
+index eb8d024..fe2a4c3 100644
+--- a/pc-bios/s390-ccw/start.S
++++ b/pc-bios/s390-ccw/start.S
+@@ -71,6 +71,26 @@ consume_sclp_int:
+         larl %r1, enabled_wait_psw
+         lpswe 0(%r1)
+ 
++/*
++ * void consume_io_int(void)
++ *
++ * eats one I/O interrupt
++ */
++        .globl consume_io_int
++consume_io_int:
++        /* enable I/O interrupts in cr6 */
++        stctg %c6,%c6,0(%r15)
++        oi    4(%r15), 0xff
++        lctlg %c6,%c6,0(%r15)
++        /* prepare i/o call handler */
++        larl  %r1, io_new_code
++        stg   %r1, 0x1f8
++        larl  %r1, io_new_mask
++        mvc   0x1f0(8),0(%r1)
++        /* load enabled wait PSW */
++        larl  %r1, enabled_wait_psw
++        lpswe 0(%r1)
++
+ external_new_code:
+         /* disable service interrupts in cr0 */
+         stctg 0,0,0(15)
+@@ -78,6 +98,13 @@ external_new_code:
+         lctlg 0,0,0(15)
+         br 14
+ 
++io_new_code:
++        /* disable I/O interrupts in cr6 */
++        stctg %c6,%c6,0(%r15)
++        ni    4(%r15), 0x00
++        lctlg %c6,%c6,0(%r15)
++        br    %r14
++
+         .align  8
+ disabled_wait_psw:
+         .quad   0x0002000180000000,0x0000000000000000
+@@ -85,3 +112,5 @@ enabled_wait_psw:
+         .quad   0x0302000180000000,0x0000000000000000
+ external_new_mask:
+         .quad   0x0000000180000000
++io_new_mask:
++        .quad   0x0000000180000000
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Use-control-unit-type-to-determine-boot-me.patch b/SOURCES/kvm-s390-bios-Use-control-unit-type-to-determine-boot-me.patch
new file mode 100644
index 0000000..d9daa9c
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Use-control-unit-type-to-determine-boot-me.patch
@@ -0,0 +1,106 @@
+From 4b0f36b50e79fe6d345c85f60f12508c17c44f1d Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:42 +0100
+Subject: [PATCH 17/21] s390-bios: Use control unit type to determine boot
+ method
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-15-thuth@redhat.com>
+Patchwork-id: 91785
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 14/17] s390-bios: Use control unit type to determine boot method
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+The boot method is different depending on which device type we are
+booting from. Let's examine the control unit type to determine if we're
+a virtio device. We'll eventually add a case to check for a real dasd device
+here as well.
+
+Since we have to call enable_subchannel() in main now, might as well
+remove that call from virtio.c : run_ccw(). This requires adding some
+additional enable_subchannel calls to not break calls to
+virtio_is_supported().
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-14-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 3668cb7ce864ee9351d5d20a1ec6b427cd0b3be4)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c    | 16 ++++++++++++++--
+ pc-bios/s390-ccw/netmain.c |  1 +
+ pc-bios/s390-ccw/virtio.c  |  1 -
+ 3 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index d3a161c..57a1013 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -76,6 +76,7 @@ static bool find_subch(int dev_no)
+         /* Skip net devices since no IPLB is created and therefore no
+          * network bootloader has been loaded
+          */
++        enable_subchannel(blk_schid);
+         if (virtio_is_supported(blk_schid) &&
+             virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
+             continue;
+@@ -198,13 +199,24 @@ static void virtio_setup(void)
+ 
+ int main(void)
+ {
++    uint16_t cutype;
++
+     sclp_setup();
+     css_setup();
+     boot_setup();
+     find_boot_device();
++    enable_subchannel(blk_schid);
+ 
+-    virtio_setup();
+-    zipl_load(); /* no return */
++    cutype = cu_type(blk_schid);
++    switch (cutype) {
++    case CU_TYPE_VIRTIO:
++        virtio_setup();
++        zipl_load(); /* no return */
++        break;
++    default:
++        print_int("Attempting to boot from unexpected device type", cutype);
++        panic("");
++    }
+ 
+     panic("Failed to load OS from hard disk\n");
+     return 0; /* make compiler happy */
+diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
+index 4e1b8cf..69cf59d 100644
+--- a/pc-bios/s390-ccw/netmain.c
++++ b/pc-bios/s390-ccw/netmain.c
+@@ -304,6 +304,7 @@ static bool find_net_dev(Schib *schib, int dev_no)
+         if (!schib->pmcw.dnv) {
+             continue;
+         }
++        enable_subchannel(net_schid);
+         if (!virtio_is_supported(net_schid)) {
+             continue;
+         }
+diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
+index 35278eae..fb40ca9 100644
+--- a/pc-bios/s390-ccw/virtio.c
++++ b/pc-bios/s390-ccw/virtio.c
+@@ -102,7 +102,6 @@ static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
+         ccw.flags |= CCW_FLAG_SLI;
+     }
+ 
+-    enable_subchannel(vdev->schid);
+     return do_cio(vdev->schid, vdev->senseid.cu_type, ptr2u32(&ccw), CCW_FMT1);
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-Use-control-unit-type-to-find-bootable-dev.patch b/SOURCES/kvm-s390-bios-Use-control-unit-type-to-find-bootable-dev.patch
new file mode 100644
index 0000000..296f273
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-Use-control-unit-type-to-find-bootable-dev.patch
@@ -0,0 +1,127 @@
+From cdc1df196d9e1cf5e6f6fe2900637b78d606ee85 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:45 +0100
+Subject: [PATCH 20/21] s390-bios: Use control unit type to find bootable
+ devices
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-18-thuth@redhat.com>
+Patchwork-id: 91790
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 17/17] s390-bios: Use control unit type to find bootable devices
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+When the user does not specify which device to boot from then we end
+up guessing. Instead of simply grabbing the first available device let's
+be a little bit smarter and only choose devices that might be bootable
+like disk, and not console devices.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Message-Id: <1554388475-18329-17-git-send-email-jjherne@linux.ibm.com>
+[thuth: Added fix for virtio_is_supported() not being called anymore]
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 2880469c95e42f8a5b0acbe8c4808255cc6c9e5b)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c | 45 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 35 insertions(+), 10 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index 3c449ad..a69c733 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -21,6 +21,7 @@ static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ QemuIplParameters qipl;
+ IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
+ static bool have_iplb;
++static uint16_t cutype;
+ LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
+ 
+ #define LOADPARM_PROMPT "PROMPT  "
+@@ -58,11 +59,15 @@ unsigned int get_loadparm_index(void)
+  * subchannel information block (schib) with the connected subchannel's info.
+  * NOTE: The global variable blk_schid is updated to contain the subchannel
+  * information.
++ *
++ * If the caller gives dev_no=-1 then the user did not specify a boot device.
++ * In this case we'll just use the first potentially bootable device we find.
+  */
+ static bool find_subch(int dev_no)
+ {
+     Schib schib;
+     int i, r;
++    bool is_virtio;
+ 
+     for (i = 0; i < 0x10000; i++) {
+         blk_schid.sch_no = i;
+@@ -74,16 +79,39 @@ static bool find_subch(int dev_no)
+             continue;
+         }
+ 
+-        /* Skip net devices since no IPLB is created and therefore no
+-         * network bootloader has been loaded
+-         */
+         enable_subchannel(blk_schid);
+-        if (virtio_is_supported(blk_schid) &&
+-            virtio_get_device_type() == VIRTIO_ID_NET && dev_no < 0) {
+-            continue;
++        cutype = cu_type(blk_schid);
++
++        /*
++         * Note: we always have to run virtio_is_supported() here to make
++         * sure that the vdev.senseid data gets pre-initialized correctly
++         */
++        is_virtio = virtio_is_supported(blk_schid);
++
++        /* No specific devno given, just return 1st possibly bootable device */
++        if (dev_no < 0) {
++            switch (cutype) {
++            case CU_TYPE_VIRTIO:
++                if (is_virtio) {
++                    /*
++                     * Skip net devices since no IPLB is created and therefore
++                     * no network bootloader has been loaded
++                     */
++                    if (virtio_get_device_type() != VIRTIO_ID_NET) {
++                        return true;
++                    }
++                }
++                continue;
++            case CU_TYPE_DASD_3990:
++            case CU_TYPE_DASD_2107:
++                return true;
++            default:
++                continue;
++            }
+         }
+ 
+-        if ((dev_no < 0) || (schib.pmcw.dev == dev_no)) {
++        /* Caller asked for a specific devno */
++        if (schib.pmcw.dev == dev_no) {
+             return true;
+         }
+     }
+@@ -200,15 +228,12 @@ static void virtio_setup(void)
+ 
+ int main(void)
+ {
+-    uint16_t cutype;
+-
+     sclp_setup();
+     css_setup();
+     boot_setup();
+     find_boot_device();
+     enable_subchannel(blk_schid);
+ 
+-    cutype = cu_type(blk_schid);
+     switch (cutype) {
+     case CU_TYPE_DASD_3990:
+     case CU_TYPE_DASD_2107:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-cio-error-handling.patch b/SOURCES/kvm-s390-bios-cio-error-handling.patch
new file mode 100644
index 0000000..f7bf350
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-cio-error-handling.patch
@@ -0,0 +1,341 @@
+From f7d509d82aeb0af595c6dcfade7904b248ed180b Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:38 +0100
+Subject: [PATCH 13/21] s390-bios: cio error handling
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-11-thuth@redhat.com>
+Patchwork-id: 91787
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 10/17] s390-bios: cio error handling
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Add verbose error output for when unexpected i/o errors happen. This eases the
+burden of debugging and reporting i/o errors. No error information is printed
+in the success case, here is an example of what is output on error:
+
+cio device error
+  ssid  : 0x0000000000000000
+  cssid : 0x0000000000000000
+  sch_no: 0x0000000000000000
+
+Interrupt Response Block Data:
+    Function Ctrl : [Start]
+    Activity Ctrl : [Start-Pending]
+    Status Ctrl : [Alert] [Primary] [Secondary] [Status-Pending]
+    Device Status : [Unit-Check]
+    Channel Status :
+    cpa=: 0x000000007f8d6038
+    prev_ccw=: 0x0000000000000000
+    this_ccw=: 0x0000000000000000
+Eckd Dasd Sense Data (fmt 32-bytes):
+    Sense Condition Flags :
+    Residual Count     =: 0x0000000000000000
+    Phys Drive ID      =: 0x000000000000009e
+    low cyl address    =: 0x0000000000000000
+    head addr & hi cyl =: 0x0000000000000000
+    format/message     =: 0x0000000000000008
+    fmt-dependent[0-7] =: 0x0000000000000004
+    fmt-dependent[8-15]=: 0xe561282305082fff
+    prog action code   =: 0x0000000000000016
+    Configuration info =: 0x00000000000040e0
+    mcode / hi-cyl     =: 0x0000000000000000
+    cyl & head addr [0]=: 0x0000000000000000
+    cyl & head addr [1]=: 0x0000000000000000
+    cyl & head addr [2]=: 0x0000000000000000
+
+The Sense Data section is currently only printed for ECKD DASD.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <1554388475-18329-10-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 86c58705bb186cfa73a03851047da2c2c37b9418)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/cio.c  | 235 ++++++++++++++++++++++++++++++++++++++++++++++++
+ pc-bios/s390-ccw/libc.h |  11 +++
+ 2 files changed, 246 insertions(+)
+
+diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
+index c43e50b..339ec5f 100644
+--- a/pc-bios/s390-ccw/cio.c
++++ b/pc-bios/s390-ccw/cio.c
+@@ -85,6 +85,228 @@ static bool irb_error(Irb *irb)
+     return irb->scsw.dstat != (SCSW_DSTAT_DEVEND | SCSW_DSTAT_CHEND);
+ }
+ 
++static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd)
++{
++    char msgline[512];
++
++    if (sd->config_info & 0x8000) {
++        sclp_print("Eckd Dasd Sense Data (fmt 24-bytes):\n");
++    } else {
++        sclp_print("Eckd Dasd Sense Data (fmt 32-bytes):\n");
++    }
++
++    strcat(msgline, "    Sense Condition Flags :");
++    if (sd->common_status & SNS_STAT0_CMD_REJECT) {
++        strcat(msgline, " [Cmd-Reject]");
++    }
++    if (sd->common_status & SNS_STAT0_INTERVENTION_REQ) {
++        strcat(msgline, " [Intervention-Required]");
++    }
++    if (sd->common_status & SNS_STAT0_BUS_OUT_CHECK) {
++        strcat(msgline, " [Bus-Out-Parity-Check]");
++    }
++    if (sd->common_status & SNS_STAT0_EQUIPMENT_CHECK) {
++        strcat(msgline, " [Equipment-Check]");
++    }
++    if (sd->common_status & SNS_STAT0_DATA_CHECK) {
++        strcat(msgline, " [Data-Check]");
++    }
++    if (sd->common_status & SNS_STAT0_OVERRUN) {
++        strcat(msgline, " [Overrun]");
++    }
++    if (sd->common_status & SNS_STAT0_INCOMPL_DOMAIN) {
++        strcat(msgline, " [Incomplete-Domain]");
++    }
++
++    if (sd->status[0] & SNS_STAT1_PERM_ERR) {
++        strcat(msgline, " [Permanent-Error]");
++    }
++    if (sd->status[0] & SNS_STAT1_INV_TRACK_FORMAT) {
++        strcat(msgline, " [Invalid-Track-Fmt]");
++    }
++    if (sd->status[0] & SNS_STAT1_EOC) {
++        strcat(msgline, " [End-of-Cyl]");
++    }
++    if (sd->status[0] & SNS_STAT1_MESSAGE_TO_OPER) {
++        strcat(msgline, " [Operator-Msg]");
++    }
++    if (sd->status[0] & SNS_STAT1_NO_REC_FOUND) {
++        strcat(msgline, " [No-Record-Found]");
++    }
++    if (sd->status[0] & SNS_STAT1_FILE_PROTECTED) {
++        strcat(msgline, " [File-Protected]");
++    }
++    if (sd->status[0] & SNS_STAT1_WRITE_INHIBITED) {
++        strcat(msgline, " [Write-Inhibited]");
++    }
++    if (sd->status[0] & SNS_STAT1_IMPRECISE_END) {
++        strcat(msgline, " [Imprecise-Ending]");
++    }
++
++    if (sd->status[1] & SNS_STAT2_REQ_INH_WRITE) {
++        strcat(msgline, " [Req-Inhibit-Write]");
++    }
++    if (sd->status[1] & SNS_STAT2_CORRECTABLE) {
++        strcat(msgline, " [Correctable-Data-Check]");
++    }
++    if (sd->status[1] & SNS_STAT2_FIRST_LOG_ERR) {
++        strcat(msgline, " [First-Error-Log]");
++    }
++    if (sd->status[1] & SNS_STAT2_ENV_DATA_PRESENT) {
++        strcat(msgline, " [Env-Data-Present]");
++    }
++    if (sd->status[1] & SNS_STAT2_IMPRECISE_END) {
++        strcat(msgline, " [Imprecise-End]");
++    }
++    strcat(msgline, "\n");
++    sclp_print(msgline);
++
++    print_int("    Residual Count     =", sd->res_count);
++    print_int("    Phys Drive ID      =", sd->phys_drive_id);
++    print_int("    low cyl address    =", sd->low_cyl_addr);
++    print_int("    head addr & hi cyl =", sd->head_high_cyl_addr);
++    print_int("    format/message     =", sd->fmt_msg);
++    print_int("    fmt-dependent[0-7] =", sd->fmt_dependent_info[0]);
++    print_int("    fmt-dependent[8-15]=", sd->fmt_dependent_info[1]);
++    print_int("    prog action code   =", sd->program_action_code);
++    print_int("    Configuration info =", sd->config_info);
++    print_int("    mcode / hi-cyl     =", sd->mcode_hicyl);
++    print_int("    cyl & head addr [0]=", sd->cyl_head_addr[0]);
++    print_int("    cyl & head addr [1]=", sd->cyl_head_addr[1]);
++    print_int("    cyl & head addr [2]=", sd->cyl_head_addr[2]);
++}
++
++static void print_irb_err(Irb *irb)
++{
++    uint64_t this_ccw = *(uint64_t *)u32toptr(irb->scsw.cpa);
++    uint64_t prev_ccw = *(uint64_t *)u32toptr(irb->scsw.cpa - 8);
++    char msgline[256];
++
++    sclp_print("Interrupt Response Block Data:\n");
++
++    strcat(msgline, "    Function Ctrl :");
++    if (irb->scsw.ctrl & SCSW_FCTL_START_FUNC) {
++        strcat(msgline, " [Start]");
++    }
++    if (irb->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
++        strcat(msgline, " [Halt]");
++    }
++    if (irb->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
++        strcat(msgline, " [Clear]");
++    }
++    strcat(msgline, "\n");
++    sclp_print(msgline);
++
++    msgline[0] = '\0';
++    strcat(msgline, "    Activity Ctrl :");
++    if (irb->scsw.ctrl & SCSW_ACTL_RESUME_PEND) {
++        strcat(msgline, " [Resume-Pending]");
++    }
++    if (irb->scsw.ctrl & SCSW_ACTL_START_PEND) {
++        strcat(msgline, " [Start-Pending]");
++    }
++    if (irb->scsw.ctrl & SCSW_ACTL_HALT_PEND) {
++        strcat(msgline, " [Halt-Pending]");
++    }
++    if (irb->scsw.ctrl & SCSW_ACTL_CLEAR_PEND) {
++        strcat(msgline, " [Clear-Pending]");
++    }
++    if (irb->scsw.ctrl & SCSW_ACTL_CH_ACTIVE) {
++        strcat(msgline, " [Channel-Active]");
++    }
++    if (irb->scsw.ctrl & SCSW_ACTL_DEV_ACTIVE) {
++        strcat(msgline, " [Device-Active]");
++    }
++    if (irb->scsw.ctrl & SCSW_ACTL_SUSPENDED) {
++        strcat(msgline, " [Suspended]");
++    }
++    strcat(msgline, "\n");
++    sclp_print(msgline);
++
++    msgline[0] = '\0';
++    strcat(msgline, "    Status Ctrl :");
++    if (irb->scsw.ctrl & SCSW_SCTL_ALERT) {
++        strcat(msgline, " [Alert]");
++    }
++    if (irb->scsw.ctrl & SCSW_SCTL_INTERMED) {
++        strcat(msgline, " [Intermediate]");
++    }
++    if (irb->scsw.ctrl & SCSW_SCTL_PRIMARY) {
++        strcat(msgline, " [Primary]");
++    }
++    if (irb->scsw.ctrl & SCSW_SCTL_SECONDARY) {
++        strcat(msgline, " [Secondary]");
++    }
++    if (irb->scsw.ctrl & SCSW_SCTL_STATUS_PEND) {
++        strcat(msgline, " [Status-Pending]");
++    }
++
++    strcat(msgline, "\n");
++    sclp_print(msgline);
++
++    msgline[0] = '\0';
++    strcat(msgline, "    Device Status :");
++    if (irb->scsw.dstat & SCSW_DSTAT_ATTN) {
++        strcat(msgline, " [Attention]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_STATMOD) {
++        strcat(msgline, " [Status-Modifier]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_CUEND) {
++        strcat(msgline, " [Ctrl-Unit-End]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_BUSY) {
++        strcat(msgline, " [Busy]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_CHEND) {
++        strcat(msgline, " [Channel-End]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_DEVEND) {
++        strcat(msgline, " [Device-End]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_UCHK) {
++        strcat(msgline, " [Unit-Check]");
++    }
++    if (irb->scsw.dstat & SCSW_DSTAT_UEXCP) {
++        strcat(msgline, " [Unit-Exception]");
++    }
++    strcat(msgline, "\n");
++    sclp_print(msgline);
++
++    msgline[0] = '\0';
++    strcat(msgline, "    Channel Status :");
++    if (irb->scsw.cstat & SCSW_CSTAT_PCINT) {
++        strcat(msgline, " [Program-Ctrl-Interruption]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_BADLEN) {
++        strcat(msgline, " [Incorrect-Length]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_PROGCHK) {
++        strcat(msgline, " [Program-Check]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_PROTCHK) {
++        strcat(msgline, " [Protection-Check]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_CHDCHK) {
++        strcat(msgline, " [Channel-Data-Check]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_CHCCHK) {
++        strcat(msgline, " [Channel-Ctrl-Check]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_ICCHK) {
++        strcat(msgline, " [Interface-Ctrl-Check]");
++    }
++    if (irb->scsw.cstat & SCSW_CSTAT_CHAINCHK) {
++        strcat(msgline, " [Chaining-Check]");
++    }
++    strcat(msgline, "\n");
++    sclp_print(msgline);
++
++    print_int("    cpa=", irb->scsw.cpa);
++    print_int("    prev_ccw=", prev_ccw);
++    print_int("    this_ccw=", this_ccw);
++}
++
+ /*
+  * Handles executing ssch, tsch and returns the irb obtained from tsch.
+  * Returns 0 on success, -1 if unexpected status pending and we need to retry,
+@@ -180,6 +402,19 @@ int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt)
+             continue;
+         }
+ 
++        sclp_print("cio device error\n");
++        print_int("  ssid  ", schid.ssid);
++        print_int("  cssid ", schid.cssid);
++        print_int("  sch_no", schid.sch_no);
++        print_int("  ctrl-unit type", cutype);
++        sclp_print("\n");
++        print_irb_err(&irb);
++        if (cutype == CU_TYPE_DASD_3990 || cutype == CU_TYPE_DASD_2107 ||
++            cutype == CU_TYPE_UNKNOWN) {
++            if (!basic_sense(schid, cutype, &sd, sizeof(sd))) {
++                print_eckd_dasd_sense_data(&sd);
++            }
++        }
+         rc = -1;
+         break;
+     }
+diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h
+index 818517f..bcdc457 100644
+--- a/pc-bios/s390-ccw/libc.h
++++ b/pc-bios/s390-ccw/libc.h
+@@ -67,6 +67,17 @@ static inline size_t strlen(const char *str)
+     return i;
+ }
+ 
++static inline char *strcat(char *dest, const char *src)
++{
++    int i;
++    char *dest_end = dest + strlen(dest);
++
++    for (i = 0; i <= strlen(src); i++) {
++        dest_end[i] = src[i];
++    }
++    return dest;
++}
++
+ static inline int isdigit(int c)
+ {
+     return (c >= '0') && (c <= '9');
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-decouple-cio-setup-from-virtio.patch b/SOURCES/kvm-s390-bios-decouple-cio-setup-from-virtio.patch
new file mode 100644
index 0000000..f51a3a0
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-decouple-cio-setup-from-virtio.patch
@@ -0,0 +1,82 @@
+From 19b96c7f412b9b8d893ec9ebd2603565d6afa178 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:31 +0100
+Subject: [PATCH 06/21] s390-bios: decouple cio setup from virtio
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-4-thuth@redhat.com>
+Patchwork-id: 91776
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 03/17] s390-bios: decouple cio setup from virtio
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Move channel i/o setup code out to a separate function. This decouples cio
+setup from the virtio code path and allows us to make use of it for booting
+dasd devices.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reviewed-by: Collin Walling <walling@linux.ibm.com>
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <1554388475-18329-3-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 87f910c142d5589ef937ac216f92c6dcddae955e)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index 544851d..e82fe2c 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -99,6 +99,18 @@ static void menu_setup(void)
+     }
+ }
+ 
++/*
++ * Initialize the channel I/O subsystem so we can talk to our ipl/boot device.
++ */
++static void css_setup(void)
++{
++    /*
++     * Unconditionally enable mss support. In every sane configuration this
++     * will succeed; and even if it doesn't, stsch_err() can handle it.
++     */
++    enable_mss_facility();
++}
++
+ static void virtio_setup(void)
+ {
+     Schib schib;
+@@ -109,13 +121,6 @@ static void virtio_setup(void)
+     VDev *vdev = virtio_get_device();
+     QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+ 
+-    /*
+-     * We unconditionally enable mss support. In every sane configuration,
+-     * this will succeed; and even if it doesn't, stsch_err() can deal
+-     * with the consequences.
+-     */
+-    enable_mss_facility();
+-
+     sclp_get_loadparm_ascii(loadparm_str);
+     memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
+     sclp_print(ldp);
+@@ -168,6 +173,7 @@ static void virtio_setup(void)
+ int main(void)
+ {
+     sclp_setup();
++    css_setup();
+     virtio_setup();
+ 
+     zipl_load(); /* no return */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-decouple-common-boot-logic-from-virtio.patch b/SOURCES/kvm-s390-bios-decouple-common-boot-logic-from-virtio.patch
new file mode 100644
index 0000000..cf40956
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-decouple-common-boot-logic-from-virtio.patch
@@ -0,0 +1,110 @@
+From 59ef4d9a3358627fbd7001028903cd89e061a216 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:32 +0100
+Subject: [PATCH 07/21] s390-bios: decouple common boot logic from virtio
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-5-thuth@redhat.com>
+Patchwork-id: 91778
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 04/17] s390-bios: decouple common boot logic from virtio
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Create a boot_setup function to handle getting boot information from
+the machine/hypervisor. This decouples common boot logic from the
+virtio code path and allows us to make use of it for the real dasd boot
+scenario.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Acked-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Reviewed-by: Collin Walling <walling@linux.ibm.com
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <1554388475-18329-4-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit a5f6e0975b1f1b79f446c8323e62fd0534408da6)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/main.c | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index e82fe2c..67df421 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -14,16 +14,17 @@
+ 
+ char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+ static SubChannelId blk_schid = { .one = 1 };
+-IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
+ static char loadparm_str[LOADPARM_LEN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ QemuIplParameters qipl;
++IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
++static bool have_iplb;
+ 
+ #define LOADPARM_PROMPT "PROMPT  "
+ #define LOADPARM_EMPTY  "        "
+ #define BOOT_MENU_FLAG_MASK (QIPL_FLAG_BM_OPTS_CMD | QIPL_FLAG_BM_OPTS_ZIPL)
+ 
+ /*
+- * Priniciples of Operations (SA22-7832-09) chapter 17 requires that
++ * Principles of Operations (SA22-7832-09) chapter 17 requires that
+  * a subsystem-identification is at 184-187 and bytes 188-191 are zero
+  * after list-directed-IPL and ccw-IPL.
+  */
+@@ -111,23 +112,33 @@ static void css_setup(void)
+     enable_mss_facility();
+ }
+ 
++/*
++ * Collect various pieces of information from the hypervisor/hardware that
++ * we'll use to determine exactly how we'll boot.
++ */
++static void boot_setup(void)
++{
++    char lpmsg[] = "LOADPARM=[________]\n";
++
++    sclp_get_loadparm_ascii(loadparm_str);
++    memcpy(lpmsg + 10, loadparm_str, 8);
++    sclp_print(lpmsg);
++
++    have_iplb = store_iplb(&iplb);
++}
++
+ static void virtio_setup(void)
+ {
+     Schib schib;
+     int ssid;
+     bool found = false;
+     uint16_t dev_no;
+-    char ldp[] = "LOADPARM=[________]\n";
+     VDev *vdev = virtio_get_device();
+     QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+ 
+-    sclp_get_loadparm_ascii(loadparm_str);
+-    memcpy(ldp + 10, loadparm_str, LOADPARM_LEN);
+-    sclp_print(ldp);
+-
+     memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+ 
+-    if (store_iplb(&iplb)) {
++    if (have_iplb) {
+         switch (iplb.pbt) {
+         case S390_IPL_TYPE_CCW:
+             dev_no = iplb.ccw.devno;
+@@ -174,6 +185,7 @@ int main(void)
+ {
+     sclp_setup();
+     css_setup();
++    boot_setup();
+     virtio_setup();
+ 
+     zipl_load(); /* no return */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-bios-ptr2u32-and-u32toptr.patch b/SOURCES/kvm-s390-bios-ptr2u32-and-u32toptr.patch
new file mode 100644
index 0000000..b34c971
--- /dev/null
+++ b/SOURCES/kvm-s390-bios-ptr2u32-and-u32toptr.patch
@@ -0,0 +1,72 @@
+From d032dae613dc006c91ad8581f203af1bd4bdbf9c Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Mon, 14 Oct 2019 10:06:36 +0100
+Subject: [PATCH 11/21] s390-bios: ptr2u32 and u32toptr
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191014100645.22862-9-thuth@redhat.com>
+Patchwork-id: 91788
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH v2 08/17] s390-bios: ptr2u32 and u32toptr
+Bugzilla: 1664376
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: "Jason J. Herne" <jjherne@linux.ibm.com>
+
+Introduce inline functions to convert between pointers and unsigned 32-bit
+ints. These are used to hide the ugliness required to  avoid compiler
+warnings.
+
+Signed-off-by: Jason J. Herne <jjherne@linux.ibm.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <1554388475-18329-8-git-send-email-jjherne@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 1fb3e5cde8dcd9b5917aea9a0b2918e16be8be1e)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/helper.h | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+ create mode 100644 pc-bios/s390-ccw/helper.h
+
+diff --git a/pc-bios/s390-ccw/helper.h b/pc-bios/s390-ccw/helper.h
+new file mode 100644
+index 0000000..78d5bc7
+--- /dev/null
++++ b/pc-bios/s390-ccw/helper.h
+@@ -0,0 +1,31 @@
++/*
++ * Helper Functions
++ *
++ * Copyright (c) 2019 IBM Corp.
++ *
++ * Author(s): Jason J. Herne <jjherne@us.ibm.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++#ifndef S390_CCW_HELPER_H
++#define S390_CCW_HELPER_H
++
++#include "s390-ccw.h"
++
++/* Avoids compiler warnings when casting a pointer to a u32 */
++static inline uint32_t ptr2u32(void *ptr)
++{
++    IPL_assert((uint64_t)ptr <= 0xffffffff, "ptr2u32: ptr too large");
++    return (uint32_t)(uint64_t)ptr;
++}
++
++/* Avoids compiler warnings when casting a u32 to a pointer */
++static inline void *u32toptr(uint32_t n)
++{
++    return (void *)(uint64_t)n;
++}
++
++#endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-cpumodel-Rework-CPU-feature-definition.patch b/SOURCES/kvm-s390x-cpumodel-Rework-CPU-feature-definition.patch
new file mode 100644
index 0000000..f1fbf6f
--- /dev/null
+++ b/SOURCES/kvm-s390x-cpumodel-Rework-CPU-feature-definition.patch
@@ -0,0 +1,1168 @@
+From 7d9350b6ad9f0b5dcdd098092eb3760bdbcf9d54 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Wed, 18 Sep 2019 14:35:48 +0100
+Subject: [PATCH 09/22] s390x/cpumodel: Rework CPU feature definition
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20190918143549.16340-2-thuth@redhat.com>
+Patchwork-id: 90759
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/2] s390x/cpumodel: Rework CPU feature definition
+Bugzilla: 1660909
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+Let's define features at a single spot and make it less error prone to
+define new features.
+
+Acked-by: Janosch Frank <frankja@linux.ibm.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: David Hildenbrand <david@redhat.com>
+(cherry picked from commit 220ae9002f33480fa30050140c852847677b3c06)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+    The "vxpdeh" line needed adaption due to out-of-order backported commits:
+
+    d05be57ddc2e1722f527aa4c20d84dfd15c840ec
+    s390: cpumodel: fix description for the new vector facility
+
+    0d4cb295db7503fbac2f5bb3e878a56630231fed
+    s390x/cpumodel: also change name of vxbeh
+
+    5d8866c89817998a3d9c3055d5dc2b5a8e78658a
+    s390x/cpumodel: change internal name of vxpdeh to match description
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu_features.c         | 352 ++--------------------------------
+ target/s390x/cpu_features_def.h     | 352 +---------------------------------
+ target/s390x/cpu_features_def.inc.h | 369 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 386 insertions(+), 687 deletions(-)
+ create mode 100644 target/s390x/cpu_features_def.inc.h
+
+diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
+index 065db76..9f817e3 100644
+--- a/target/s390x/cpu_features.c
++++ b/target/s390x/cpu_features.c
+@@ -2,8 +2,9 @@
+  * CPU features/facilities for s390x
+  *
+  * Copyright IBM Corp. 2016, 2018
++ * Copyright Red Hat, Inc. 2019
+  *
+- * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
++ * Author(s): David Hildenbrand <david@redhat.com>
+  *
+  * This work is licensed under the terms of the GNU GPL, version 2 or (at
+  * your option) any later version. See the COPYING file in the top-level
+@@ -14,346 +15,17 @@
+ #include "qemu/module.h"
+ #include "cpu_features.h"
+ 
+-#define FEAT_INIT(_name, _type, _bit, _desc) \
+-    {                                                \
+-        .name = _name,                               \
+-        .type = _type,                               \
+-        .bit = _bit,                                 \
+-        .desc = _desc,                               \
+-    }
+-
+-/* S390FeatDef.bit is not applicable as there is no feature block. */
+-#define FEAT_INIT_MISC(_name, _desc)                 \
+-            FEAT_INIT(_name, S390_FEAT_TYPE_MISC, 0, _desc)
+-
+-/* indexed by feature number for easy lookup */
+-static const S390FeatDef s390_features[] = {
+-    FEAT_INIT("esan3", S390_FEAT_TYPE_STFL, 0, "Instructions marked as n3"),
+-    FEAT_INIT("zarch", S390_FEAT_TYPE_STFL, 1, "z/Architecture architectural mode"),
+-    FEAT_INIT("dateh", S390_FEAT_TYPE_STFL, 3, "DAT-enhancement facility"),
+-    FEAT_INIT("idtes", S390_FEAT_TYPE_STFL, 4, "IDTE selective TLB segment-table clearing"),
+-    FEAT_INIT("idter", S390_FEAT_TYPE_STFL, 5, "IDTE selective TLB region-table clearing"),
+-    FEAT_INIT("asnlxr", S390_FEAT_TYPE_STFL, 6, "ASN-and-LX reuse facility"),
+-    FEAT_INIT("stfle", S390_FEAT_TYPE_STFL, 7, "Store-facility-list-extended facility"),
+-    FEAT_INIT("edat", S390_FEAT_TYPE_STFL, 8, "Enhanced-DAT facility"),
+-    FEAT_INIT("srs", S390_FEAT_TYPE_STFL, 9, "Sense-running-status facility"),
+-    FEAT_INIT("csske", S390_FEAT_TYPE_STFL, 10, "Conditional-SSKE facility"),
+-    FEAT_INIT("ctop", S390_FEAT_TYPE_STFL, 11, "Configuration-topology facility"),
+-    FEAT_INIT("apqci", S390_FEAT_TYPE_STFL, 12, "Query AP Configuration Information facility"),
+-    FEAT_INIT("ipter", S390_FEAT_TYPE_STFL, 13, "IPTE-range facility"),
+-    FEAT_INIT("nonqks", S390_FEAT_TYPE_STFL, 14, "Nonquiescing key-setting facility"),
+-    FEAT_INIT("apft", S390_FEAT_TYPE_STFL, 15, "AP Facilities Test facility"),
+-    FEAT_INIT("etf2", S390_FEAT_TYPE_STFL, 16, "Extended-translation facility 2"),
+-    FEAT_INIT("msa-base", S390_FEAT_TYPE_STFL, 17, "Message-security-assist facility (excluding subfunctions)"),
+-    FEAT_INIT("ldisp", S390_FEAT_TYPE_STFL, 18, "Long-displacement facility"),
+-    FEAT_INIT("ldisphp", S390_FEAT_TYPE_STFL, 19, "Long-displacement facility has high performance"),
+-    FEAT_INIT("hfpm", S390_FEAT_TYPE_STFL, 20, "HFP-multiply-add/subtract facility"),
+-    FEAT_INIT("eimm", S390_FEAT_TYPE_STFL, 21, "Extended-immediate facility"),
+-    FEAT_INIT("etf3", S390_FEAT_TYPE_STFL, 22, "Extended-translation facility 3"),
+-    FEAT_INIT("hfpue", S390_FEAT_TYPE_STFL, 23, "HFP-unnormalized-extension facility"),
+-    FEAT_INIT("etf2eh", S390_FEAT_TYPE_STFL, 24, "ETF2-enhancement facility"),
+-    FEAT_INIT("stckf", S390_FEAT_TYPE_STFL, 25, "Store-clock-fast facility"),
+-    FEAT_INIT("parseh", S390_FEAT_TYPE_STFL, 26, "Parsing-enhancement facility"),
+-    FEAT_INIT("mvcos", S390_FEAT_TYPE_STFL, 27, "Move-with-optional-specification facility"),
+-    FEAT_INIT("tods-base", S390_FEAT_TYPE_STFL, 28, "TOD-clock-steering facility (excluding subfunctions)"),
+-    FEAT_INIT("etf3eh", S390_FEAT_TYPE_STFL, 30, "ETF3-enhancement facility"),
+-    FEAT_INIT("ectg", S390_FEAT_TYPE_STFL, 31, "Extract-CPU-time facility"),
+-    FEAT_INIT("csst", S390_FEAT_TYPE_STFL, 32, "Compare-and-swap-and-store facility"),
+-    FEAT_INIT("csst2", S390_FEAT_TYPE_STFL, 33, "Compare-and-swap-and-store facility 2"),
+-    FEAT_INIT("ginste", S390_FEAT_TYPE_STFL, 34, "General-instructions-extension facility"),
+-    FEAT_INIT("exrl", S390_FEAT_TYPE_STFL, 35, "Execute-extensions facility"),
+-    FEAT_INIT("emon", S390_FEAT_TYPE_STFL, 36, "Enhanced-monitor facility"),
+-    FEAT_INIT("fpe", S390_FEAT_TYPE_STFL, 37, "Floating-point extension facility"),
+-    FEAT_INIT("opc", S390_FEAT_TYPE_STFL, 38, "Order Preserving Compression facility"),
+-    FEAT_INIT("sprogp", S390_FEAT_TYPE_STFL, 40, "Set-program-parameters facility"),
+-    FEAT_INIT("fpseh", S390_FEAT_TYPE_STFL, 41, "Floating-point-support-enhancement facilities"),
+-    FEAT_INIT("dfp", S390_FEAT_TYPE_STFL, 42, "DFP (decimal-floating-point) facility"),
+-    FEAT_INIT("dfphp", S390_FEAT_TYPE_STFL, 43, "DFP (decimal-floating-point) facility has high performance"),
+-    FEAT_INIT("pfpo", S390_FEAT_TYPE_STFL, 44, "PFPO instruction"),
+-    FEAT_INIT("stfle45", S390_FEAT_TYPE_STFL, 45, "Various facilities introduced with z196"),
+-    FEAT_INIT("cmpsceh", S390_FEAT_TYPE_STFL, 47, "CMPSC-enhancement facility"),
+-    FEAT_INIT("dfpzc", S390_FEAT_TYPE_STFL, 48, "Decimal-floating-point zoned-conversion facility"),
+-    FEAT_INIT("stfle49", S390_FEAT_TYPE_STFL, 49, "Various facilities introduced with zEC12"),
+-    FEAT_INIT("cte", S390_FEAT_TYPE_STFL, 50, "Constrained transactional-execution facility"),
+-    FEAT_INIT("ltlbc", S390_FEAT_TYPE_STFL, 51, "Local-TLB-clearing facility"),
+-    FEAT_INIT("iacc2", S390_FEAT_TYPE_STFL, 52, "Interlocked-access facility 2"),
+-    FEAT_INIT("stfle53", S390_FEAT_TYPE_STFL, 53, "Various facilities introduced with z13"),
+-    FEAT_INIT("eec", S390_FEAT_TYPE_STFL, 54, "Entropy encoding compression facility"),
+-    FEAT_INIT("msa5-base", S390_FEAT_TYPE_STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)"),
+-    FEAT_INIT("minste2", S390_FEAT_TYPE_STFL, 58, "Miscellaneous-instruction-extensions facility 2"),
+-    FEAT_INIT("sema", S390_FEAT_TYPE_STFL, 59, "Semaphore-assist facility"),
+-    FEAT_INIT("tsi", S390_FEAT_TYPE_STFL, 60, "Time-slice Instrumentation facility"),
+-    FEAT_INIT("minste3", S390_FEAT_TYPE_STFL, 61, "Miscellaneous-Instruction-Extensions Facility 3"),
+-    FEAT_INIT("ri", S390_FEAT_TYPE_STFL, 64, "CPU runtime-instrumentation facility"),
+-    FEAT_INIT("zpci", S390_FEAT_TYPE_STFL, 69, "z/PCI facility"),
+-    FEAT_INIT("aen", S390_FEAT_TYPE_STFL, 71, "General-purpose-adapter-event-notification facility"),
+-    FEAT_INIT("ais", S390_FEAT_TYPE_STFL, 72, "General-purpose-adapter-interruption-suppression facility"),
+-    FEAT_INIT("te", S390_FEAT_TYPE_STFL, 73, "Transactional-execution facility"),
+-    FEAT_INIT("sthyi", S390_FEAT_TYPE_STFL, 74, "Store-hypervisor-information facility"),
+-    FEAT_INIT("aefsi", S390_FEAT_TYPE_STFL, 75, "Access-exception-fetch/store-indication facility"),
+-    FEAT_INIT("msa3-base", S390_FEAT_TYPE_STFL, 76, "Message-security-assist-extension-3 facility (excluding subfunctions)"),
+-    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"),
+-    FEAT_INIT("sea_esop2", S390_FEAT_TYPE_STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2"),
+-    FEAT_INIT("gs", S390_FEAT_TYPE_STFL, 133, "Guarded-storage facility"),
+-    FEAT_INIT("vxpd", S390_FEAT_TYPE_STFL, 134, "Vector packed decimal facility"),
+-    FEAT_INIT("vxeh", S390_FEAT_TYPE_STFL, 135, "Vector enhancements facility"),
+-    FEAT_INIT("mepoch", S390_FEAT_TYPE_STFL, 139, "Multiple-epoch facility"),
+-    FEAT_INIT("tpei", S390_FEAT_TYPE_STFL, 144, "Test-pending-external-interruption facility"),
+-    FEAT_INIT("irbm", S390_FEAT_TYPE_STFL, 145, "Insert-reference-bits-multiple facility"),
+-    FEAT_INIT("msa8-base", S390_FEAT_TYPE_STFL, 146, "Message-security-assist-extension-8 facility (excluding subfunctions)"),
+-    FEAT_INIT("cmmnt", S390_FEAT_TYPE_STFL, 147, "CMM: ESSA-enhancement (no translate) facility"),
+-    FEAT_INIT("vxeh2", S390_FEAT_TYPE_STFL, 148, "Vector Enhancements facility 2"),
+-    FEAT_INIT("esort-base", S390_FEAT_TYPE_STFL, 150, "Enhanced-sort facility (excluding subfunctions)"),
+-    FEAT_INIT("deflate-base", S390_FEAT_TYPE_STFL, 151, "Deflate-conversion facility (excluding subfunctions)"),
+-    FEAT_INIT("vxpdeh", S390_FEAT_TYPE_STFL, 152, "Vector-Packed-Decimal-Enhancement Facility"),
+-    FEAT_INIT("msa9-base", S390_FEAT_TYPE_STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)"),
+-    FEAT_INIT("etoken", S390_FEAT_TYPE_STFL, 156, "Etoken facility"),
+-
+-    /* SCLP SCCB Byte 80 - 98  (bit numbers relative to byte-80) */
+-    FEAT_INIT("gsls", S390_FEAT_TYPE_SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility"),
+-    FEAT_INIT("esop", S390_FEAT_TYPE_SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility"),
+-    FEAT_INIT("hpma2", S390_FEAT_TYPE_SCLP_CONF_CHAR, 90, "Host page management assist 2 Facility"), /* 91-2 */
+-    FEAT_INIT("kss", S390_FEAT_TYPE_SCLP_CONF_CHAR, 151, "SIE: Keyless-subset facility"),  /* 98-7 */
+-
+-    /* SCLP SCCB Byte 116 - 119 (bit numbers relative to byte-116) */
+-    FEAT_INIT("64bscao", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility"),
+-    FEAT_INIT("cmma", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist"),
+-    FEAT_INIT("pfmfi", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility"),
+-    FEAT_INIT("ibs", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 10, "SIE: Interlock-and-broadcast-suppression facility"),
+-
+-    FEAT_INIT("sief2", S390_FEAT_TYPE_SCLP_CPU, 4, "SIE: interception format 2 (Virtual SIE)"),
+-    FEAT_INIT("skey", S390_FEAT_TYPE_SCLP_CPU, 5, "SIE: Storage-key facility"),
+-    FEAT_INIT("gpereh", S390_FEAT_TYPE_SCLP_CPU, 10, "SIE: Guest-PER enhancement facility"),
+-    FEAT_INIT("siif", S390_FEAT_TYPE_SCLP_CPU, 11, "SIE: Shared IPTE-interlock facility"),
+-    FEAT_INIT("sigpif", S390_FEAT_TYPE_SCLP_CPU, 12, "SIE: SIGP interpretation facility"),
+-    FEAT_INIT("ib", S390_FEAT_TYPE_SCLP_CPU, 42, "SIE: Intervention bypass facility"),
+-    FEAT_INIT("cei", S390_FEAT_TYPE_SCLP_CPU, 43, "SIE: Conditional-external-interception facility"),
+-
+-    FEAT_INIT_MISC("dateh2", "DAT-enhancement facility 2"),
+-    FEAT_INIT_MISC("cmm", "Collaborative-memory-management facility"),
+-    FEAT_INIT_MISC("ap", "AP instructions installed"),
+-
+-    FEAT_INIT("plo-cl", S390_FEAT_TYPE_PLO, 0, "PLO Compare and load (32 bit in general registers)"),
+-    FEAT_INIT("plo-clg", S390_FEAT_TYPE_PLO, 1, "PLO Compare and load (64 bit in parameter list)"),
+-    FEAT_INIT("plo-clgr", S390_FEAT_TYPE_PLO, 2, "PLO Compare and load (32 bit in general registers)"),
+-    FEAT_INIT("plo-clx", S390_FEAT_TYPE_PLO, 3, "PLO Compare and load (128 bit in parameter list)"),
+-    FEAT_INIT("plo-cs", S390_FEAT_TYPE_PLO, 4, "PLO Compare and swap (32 bit in general registers)"),
+-    FEAT_INIT("plo-csg", S390_FEAT_TYPE_PLO, 5, "PLO Compare and swap (64 bit in parameter list)"),
+-    FEAT_INIT("plo-csgr", S390_FEAT_TYPE_PLO, 6, "PLO Compare and swap (32 bit in general registers)"),
+-    FEAT_INIT("plo-csx", S390_FEAT_TYPE_PLO, 7, "PLO Compare and swap (128 bit in parameter list)"),
+-    FEAT_INIT("plo-dcs", S390_FEAT_TYPE_PLO, 8, "PLO Double compare and swap (32 bit in general registers)"),
+-    FEAT_INIT("plo-dcsg", S390_FEAT_TYPE_PLO, 9, "PLO Double compare and swap (64 bit in parameter list)"),
+-    FEAT_INIT("plo-dcsgr", S390_FEAT_TYPE_PLO, 10, "PLO Double compare and swap (32 bit in general registers)"),
+-    FEAT_INIT("plo-dcsx", S390_FEAT_TYPE_PLO, 11, "PLO Double compare and swap (128 bit in parameter list)"),
+-    FEAT_INIT("plo-csst", S390_FEAT_TYPE_PLO, 12, "PLO Compare and swap and store (32 bit in general registers)"),
+-    FEAT_INIT("plo-csstg", S390_FEAT_TYPE_PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)"),
+-    FEAT_INIT("plo-csstgr", S390_FEAT_TYPE_PLO, 14, "PLO Compare and swap and store (32 bit in general registers)"),
+-    FEAT_INIT("plo-csstx", S390_FEAT_TYPE_PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)"),
+-    FEAT_INIT("plo-csdst", S390_FEAT_TYPE_PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)"),
+-    FEAT_INIT("plo-csdstg", S390_FEAT_TYPE_PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)"),
+-    FEAT_INIT("plo-csdstgr", S390_FEAT_TYPE_PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)"),
+-    FEAT_INIT("plo-csdstx", S390_FEAT_TYPE_PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)"),
+-    FEAT_INIT("plo-cstst", S390_FEAT_TYPE_PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)"),
+-    FEAT_INIT("plo-cststg", S390_FEAT_TYPE_PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)"),
+-    FEAT_INIT("plo-cststgr", S390_FEAT_TYPE_PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)"),
+-    FEAT_INIT("plo-cststx", S390_FEAT_TYPE_PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)"),
+-
+-    FEAT_INIT("ptff-qto", S390_FEAT_TYPE_PTFF, 1, "PTFF Query TOD Offset"),
+-    FEAT_INIT("ptff-qsi", S390_FEAT_TYPE_PTFF, 2, "PTFF Query Steering Information"),
+-    FEAT_INIT("ptff-qpc", S390_FEAT_TYPE_PTFF, 3, "PTFF Query Physical Clock"),
+-    FEAT_INIT("ptff-qui", S390_FEAT_TYPE_PTFF, 4, "PTFF Query UTC Information"),
+-    FEAT_INIT("ptff-qtou", S390_FEAT_TYPE_PTFF, 5, "PTFF Query TOD Offset User"),
+-    FEAT_INIT("ptff-qsie", S390_FEAT_TYPE_PTFF, 10, "PTFF Query Steering Information Extended"),
+-    FEAT_INIT("ptff-qtoue", S390_FEAT_TYPE_PTFF, 13, "PTFF Query TOD Offset User Extended"),
+-    FEAT_INIT("ptff-sto", S390_FEAT_TYPE_PTFF, 65, "PTFF Set TOD Offset"),
+-    FEAT_INIT("ptff-stou", S390_FEAT_TYPE_PTFF, 69, "PTFF Set TOD Offset User"),
+-    FEAT_INIT("ptff-stoe", S390_FEAT_TYPE_PTFF, 73, "PTFF Set TOD Offset Extended"),
+-    FEAT_INIT("ptff-stoue", S390_FEAT_TYPE_PTFF, 77, "PTFF Set TOD Offset User Extended"),
+-
+-    FEAT_INIT("kmac-dea", S390_FEAT_TYPE_KMAC, 1, "KMAC DEA"),
+-    FEAT_INIT("kmac-tdea-128", S390_FEAT_TYPE_KMAC, 2, "KMAC TDEA-128"),
+-    FEAT_INIT("kmac-tdea-192", S390_FEAT_TYPE_KMAC, 3, "KMAC TDEA-192"),
+-    FEAT_INIT("kmac-edea", S390_FEAT_TYPE_KMAC, 9, "KMAC Encrypted-DEA"),
+-    FEAT_INIT("kmac-etdea-128", S390_FEAT_TYPE_KMAC, 10, "KMAC Encrypted-TDEA-128"),
+-    FEAT_INIT("kmac-etdea-192", S390_FEAT_TYPE_KMAC, 11, "KMAC Encrypted-TDEA-192"),
+-    FEAT_INIT("kmac-aes-128", S390_FEAT_TYPE_KMAC, 18, "KMAC AES-128"),
+-    FEAT_INIT("kmac-aes-192", S390_FEAT_TYPE_KMAC, 19, "KMAC AES-192"),
+-    FEAT_INIT("kmac-aes-256", S390_FEAT_TYPE_KMAC, 20, "KMAC AES-256"),
+-    FEAT_INIT("kmac-eaes-128", S390_FEAT_TYPE_KMAC, 26, "KMAC Encrypted-AES-128"),
+-    FEAT_INIT("kmac-eaes-192", S390_FEAT_TYPE_KMAC, 27, "KMAC Encrypted-AES-192"),
+-    FEAT_INIT("kmac-eaes-256", S390_FEAT_TYPE_KMAC, 28, "KMAC Encrypted-AES-256"),
+-
+-    FEAT_INIT("kmc-dea", S390_FEAT_TYPE_KMC, 1, "KMC DEA"),
+-    FEAT_INIT("kmc-tdea-128", S390_FEAT_TYPE_KMC, 2, "KMC TDEA-128"),
+-    FEAT_INIT("kmc-tdea-192", S390_FEAT_TYPE_KMC, 3, "KMC TDEA-192"),
+-    FEAT_INIT("kmc-edea", S390_FEAT_TYPE_KMC, 9, "KMC Encrypted-DEA"),
+-    FEAT_INIT("kmc-etdea-128", S390_FEAT_TYPE_KMC, 10, "KMC Encrypted-TDEA-128"),
+-    FEAT_INIT("kmc-etdea-192", S390_FEAT_TYPE_KMC, 11, "KMC Encrypted-TDEA-192"),
+-    FEAT_INIT("kmc-aes-128", S390_FEAT_TYPE_KMC, 18, "KMC AES-128"),
+-    FEAT_INIT("kmc-aes-192", S390_FEAT_TYPE_KMC, 19, "KMC AES-192"),
+-    FEAT_INIT("kmc-aes-256", S390_FEAT_TYPE_KMC, 20, "KMC AES-256"),
+-    FEAT_INIT("kmc-eaes-128", S390_FEAT_TYPE_KMC, 26, "KMC Encrypted-AES-128"),
+-    FEAT_INIT("kmc-eaes-192", S390_FEAT_TYPE_KMC, 27, "KMC Encrypted-AES-192"),
+-    FEAT_INIT("kmc-eaes-256", S390_FEAT_TYPE_KMC, 28, "KMC Encrypted-AES-256"),
+-    FEAT_INIT("kmc-prng", S390_FEAT_TYPE_KMC, 67, "KMC PRNG"),
+-
+-    FEAT_INIT("km-dea", S390_FEAT_TYPE_KM, 1, "KM DEA"),
+-    FEAT_INIT("km-tdea-128", S390_FEAT_TYPE_KM, 2, "KM TDEA-128"),
+-    FEAT_INIT("km-tdea-192", S390_FEAT_TYPE_KM, 3, "KM TDEA-192"),
+-    FEAT_INIT("km-edea", S390_FEAT_TYPE_KM, 9, "KM Encrypted-DEA"),
+-    FEAT_INIT("km-etdea-128", S390_FEAT_TYPE_KM, 10, "KM Encrypted-TDEA-128"),
+-    FEAT_INIT("km-etdea-192", S390_FEAT_TYPE_KM, 11, "KM Encrypted-TDEA-192"),
+-    FEAT_INIT("km-aes-128", S390_FEAT_TYPE_KM, 18, "KM AES-128"),
+-    FEAT_INIT("km-aes-192", S390_FEAT_TYPE_KM, 19, "KM AES-192"),
+-    FEAT_INIT("km-aes-256", S390_FEAT_TYPE_KM, 20, "KM AES-256"),
+-    FEAT_INIT("km-eaes-128", S390_FEAT_TYPE_KM, 26, "KM Encrypted-AES-128"),
+-    FEAT_INIT("km-eaes-192", S390_FEAT_TYPE_KM, 27, "KM Encrypted-AES-192"),
+-    FEAT_INIT("km-eaes-256", S390_FEAT_TYPE_KM, 28, "KM Encrypted-AES-256"),
+-    FEAT_INIT("km-xts-aes-128", S390_FEAT_TYPE_KM, 50, "KM XTS-AES-128"),
+-    FEAT_INIT("km-xts-aes-256", S390_FEAT_TYPE_KM, 52, "KM XTS-AES-256"),
+-    FEAT_INIT("km-xts-eaes-128", S390_FEAT_TYPE_KM, 58, "KM XTS-Encrypted-AES-128"),
+-    FEAT_INIT("km-xts-eaes-256", S390_FEAT_TYPE_KM, 60, "KM XTS-Encrypted-AES-256"),
+-
+-    FEAT_INIT("kimd-sha-1", S390_FEAT_TYPE_KIMD, 1, "KIMD SHA-1"),
+-    FEAT_INIT("kimd-sha-256", S390_FEAT_TYPE_KIMD, 2, "KIMD SHA-256"),
+-    FEAT_INIT("kimd-sha-512", S390_FEAT_TYPE_KIMD, 3, "KIMD SHA-512"),
+-    FEAT_INIT("kimd-sha3-224", S390_FEAT_TYPE_KIMD, 32, "KIMD SHA3-224"),
+-    FEAT_INIT("kimd-sha3-256", S390_FEAT_TYPE_KIMD, 33, "KIMD SHA3-256"),
+-    FEAT_INIT("kimd-sha3-384", S390_FEAT_TYPE_KIMD, 34, "KIMD SHA3-384"),
+-    FEAT_INIT("kimd-sha3-512", S390_FEAT_TYPE_KIMD, 35, "KIMD SHA3-512"),
+-    FEAT_INIT("kimd-shake-128", S390_FEAT_TYPE_KIMD, 36, "KIMD SHAKE-128"),
+-    FEAT_INIT("kimd-shake-256", S390_FEAT_TYPE_KIMD, 37, "KIMD SHAKE-256"),
+-    FEAT_INIT("kimd-ghash", S390_FEAT_TYPE_KIMD, 65, "KIMD GHASH"),
+-
+-    FEAT_INIT("klmd-sha-1", S390_FEAT_TYPE_KLMD, 1, "KLMD SHA-1"),
+-    FEAT_INIT("klmd-sha-256", S390_FEAT_TYPE_KLMD, 2, "KLMD SHA-256"),
+-    FEAT_INIT("klmd-sha-512", S390_FEAT_TYPE_KLMD, 3, "KLMD SHA-512"),
+-    FEAT_INIT("klmd-sha3-224", S390_FEAT_TYPE_KLMD, 32, "KLMD SHA3-224"),
+-    FEAT_INIT("klmd-sha3-256", S390_FEAT_TYPE_KLMD, 33, "KLMD SHA3-256"),
+-    FEAT_INIT("klmd-sha3-384", S390_FEAT_TYPE_KLMD, 34, "KLMD SHA3-384"),
+-    FEAT_INIT("klmd-sha3-512", S390_FEAT_TYPE_KLMD, 35, "KLMD SHA3-512"),
+-    FEAT_INIT("klmd-shake-128", S390_FEAT_TYPE_KLMD, 36, "KLMD SHAKE-128"),
+-    FEAT_INIT("klmd-shake-256", S390_FEAT_TYPE_KLMD, 37, "KLMD SHAKE-256"),
+-
+-    FEAT_INIT("pckmo-edea", S390_FEAT_TYPE_PCKMO, 1, "PCKMO Encrypted-DEA-Key"),
+-    FEAT_INIT("pckmo-etdea-128", S390_FEAT_TYPE_PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key"),
+-    FEAT_INIT("pckmo-etdea-192", S390_FEAT_TYPE_PCKMO, 3, "PCKMO Encrypted-TDEA-192-Key"),
+-    FEAT_INIT("pckmo-aes-128", S390_FEAT_TYPE_PCKMO, 18, "PCKMO Encrypted-AES-128-Key"),
+-    FEAT_INIT("pckmo-aes-192", S390_FEAT_TYPE_PCKMO, 19, "PCKMO Encrypted-AES-192-Key"),
+-    FEAT_INIT("pckmo-aes-256", S390_FEAT_TYPE_PCKMO, 20, "PCKMO Encrypted-AES-256-Key"),
+-    FEAT_INIT("pckmo-ecc-p256", S390_FEAT_TYPE_PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key"),
+-    FEAT_INIT("pckmo-ecc-p384", S390_FEAT_TYPE_PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key"),
+-    FEAT_INIT("pckmo-ecc-p521", S390_FEAT_TYPE_PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key"),
+-    FEAT_INIT("pckmo-ecc-ed25519", S390_FEAT_TYPE_PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key"),
+-    FEAT_INIT("pckmo-ecc-ed448", S390_FEAT_TYPE_PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key"),
+-
+-    FEAT_INIT("kmctr-dea", S390_FEAT_TYPE_KMCTR, 1, "KMCTR DEA"),
+-    FEAT_INIT("kmctr-tdea-128", S390_FEAT_TYPE_KMCTR, 2, "KMCTR TDEA-128"),
+-    FEAT_INIT("kmctr-tdea-192", S390_FEAT_TYPE_KMCTR, 3, "KMCTR TDEA-192"),
+-    FEAT_INIT("kmctr-edea", S390_FEAT_TYPE_KMCTR, 9, "KMCTR Encrypted-DEA"),
+-    FEAT_INIT("kmctr-etdea-128", S390_FEAT_TYPE_KMCTR, 10, "KMCTR Encrypted-TDEA-128"),
+-    FEAT_INIT("kmctr-etdea-192", S390_FEAT_TYPE_KMCTR, 11, "KMCTR Encrypted-TDEA-192"),
+-    FEAT_INIT("kmctr-aes-128", S390_FEAT_TYPE_KMCTR, 18, "KMCTR AES-128"),
+-    FEAT_INIT("kmctr-aes-192", S390_FEAT_TYPE_KMCTR, 19, "KMCTR AES-192"),
+-    FEAT_INIT("kmctr-aes-256", S390_FEAT_TYPE_KMCTR, 20, "KMCTR AES-256"),
+-    FEAT_INIT("kmctr-eaes-128", S390_FEAT_TYPE_KMCTR, 26, "KMCTR Encrypted-AES-128"),
+-    FEAT_INIT("kmctr-eaes-192", S390_FEAT_TYPE_KMCTR, 27, "KMCTR Encrypted-AES-192"),
+-    FEAT_INIT("kmctr-eaes-256", S390_FEAT_TYPE_KMCTR, 28, "KMCTR Encrypted-AES-256"),
+-
+-    FEAT_INIT("kmf-dea", S390_FEAT_TYPE_KMF, 1, "KMF DEA"),
+-    FEAT_INIT("kmf-tdea-128", S390_FEAT_TYPE_KMF, 2, "KMF TDEA-128"),
+-    FEAT_INIT("kmf-tdea-192", S390_FEAT_TYPE_KMF, 3, "KMF TDEA-192"),
+-    FEAT_INIT("kmf-edea", S390_FEAT_TYPE_KMF, 9, "KMF Encrypted-DEA"),
+-    FEAT_INIT("kmf-etdea-128", S390_FEAT_TYPE_KMF, 10, "KMF Encrypted-TDEA-128"),
+-    FEAT_INIT("kmf-etdea-192", S390_FEAT_TYPE_KMF, 11, "KMF Encrypted-TDEA-192"),
+-    FEAT_INIT("kmf-aes-128", S390_FEAT_TYPE_KMF, 18, "KMF AES-128"),
+-    FEAT_INIT("kmf-aes-192", S390_FEAT_TYPE_KMF, 19, "KMF AES-192"),
+-    FEAT_INIT("kmf-aes-256", S390_FEAT_TYPE_KMF, 20, "KMF AES-256"),
+-    FEAT_INIT("kmf-eaes-128", S390_FEAT_TYPE_KMF, 26, "KMF Encrypted-AES-128"),
+-    FEAT_INIT("kmf-eaes-192", S390_FEAT_TYPE_KMF, 27, "KMF Encrypted-AES-192"),
+-    FEAT_INIT("kmf-eaes-256", S390_FEAT_TYPE_KMF, 28, "KMF Encrypted-AES-256"),
+-
+-    FEAT_INIT("kmo-dea", S390_FEAT_TYPE_KMO, 1, "KMO DEA"),
+-    FEAT_INIT("kmo-tdea-128", S390_FEAT_TYPE_KMO, 2, "KMO TDEA-128"),
+-    FEAT_INIT("kmo-tdea-192", S390_FEAT_TYPE_KMO, 3, "KMO TDEA-192"),
+-    FEAT_INIT("kmo-edea", S390_FEAT_TYPE_KMO, 9, "KMO Encrypted-DEA"),
+-    FEAT_INIT("kmo-etdea-128", S390_FEAT_TYPE_KMO, 10, "KMO Encrypted-TDEA-128"),
+-    FEAT_INIT("kmo-etdea-192", S390_FEAT_TYPE_KMO, 11, "KMO Encrypted-TDEA-192"),
+-    FEAT_INIT("kmo-aes-128", S390_FEAT_TYPE_KMO, 18, "KMO AES-128"),
+-    FEAT_INIT("kmo-aes-192", S390_FEAT_TYPE_KMO, 19, "KMO AES-192"),
+-    FEAT_INIT("kmo-aes-256", S390_FEAT_TYPE_KMO, 20, "KMO AES-256"),
+-    FEAT_INIT("kmo-eaes-128", S390_FEAT_TYPE_KMO, 26, "KMO Encrypted-AES-128"),
+-    FEAT_INIT("kmo-eaes-192", S390_FEAT_TYPE_KMO, 27, "KMO Encrypted-AES-192"),
+-    FEAT_INIT("kmo-eaes-256", S390_FEAT_TYPE_KMO, 28, "KMO Encrypted-AES-256"),
+-
+-    FEAT_INIT("pcc-cmac-dea", S390_FEAT_TYPE_PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA"),
+-    FEAT_INIT("pcc-cmac-tdea-128", S390_FEAT_TYPE_PCC, 2, "PCC Compute-Last-Block-CMAC-Using-TDEA-128"),
+-    FEAT_INIT("pcc-cmac-tdea-192", S390_FEAT_TYPE_PCC, 3, "PCC Compute-Last-Block-CMAC-Using-TDEA-192"),
+-    FEAT_INIT("pcc-cmac-edea", S390_FEAT_TYPE_PCC, 9, "PCC Compute-Last-Block-CMAC-Using-Encrypted-DEA"),
+-    FEAT_INIT("pcc-cmac-etdea-128", S390_FEAT_TYPE_PCC, 10, "PCC Compute-Last-Block-CMAC-Using-Encrypted-TDEA-128"),
+-    FEAT_INIT("pcc-cmac-etdea-192", S390_FEAT_TYPE_PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192"),
+-    FEAT_INIT("pcc-cmac-aes-128", S390_FEAT_TYPE_PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128"),
+-    FEAT_INIT("pcc-cmac-aes-192", S390_FEAT_TYPE_PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192"),
+-    FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256"),
+-    FEAT_INIT("pcc-cmac-eaes-128", S390_FEAT_TYPE_PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128"),
+-    FEAT_INIT("pcc-cmac-eaes-192", S390_FEAT_TYPE_PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192"),
+-    FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256"),
+-    FEAT_INIT("pcc-xts-aes-128", S390_FEAT_TYPE_PCC, 50, "PCC Compute-XTS-Parameter-Using-AES-128"),
+-    FEAT_INIT("pcc-xts-aes-256", S390_FEAT_TYPE_PCC, 52, "PCC Compute-XTS-Parameter-Using-AES-256"),
+-    FEAT_INIT("pcc-xts-eaes-128", S390_FEAT_TYPE_PCC, 58, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-128"),
+-    FEAT_INIT("pcc-xts-eaes-256", S390_FEAT_TYPE_PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256"),
+-    FEAT_INIT("pcc-scalar-mult-p256", S390_FEAT_TYPE_PCC, 64, "PCC Scalar-Multiply-P256"),
+-    FEAT_INIT("pcc-scalar-mult-p384", S390_FEAT_TYPE_PCC, 65, "PCC Scalar-Multiply-P384"),
+-    FEAT_INIT("pcc-scalar-mult-p521", S390_FEAT_TYPE_PCC, 66, "PCC Scalar-Multiply-P521"),
+-    FEAT_INIT("pcc-scalar-mult-ed25519", S390_FEAT_TYPE_PCC, 72, "PCC Scalar-Multiply-Ed25519"),
+-    FEAT_INIT("pcc-scalar-mult-ed448", S390_FEAT_TYPE_PCC, 73, "PCC Scalar-Multiply-Ed448"),
+-    FEAT_INIT("pcc-scalar-mult-x25519", S390_FEAT_TYPE_PCC, 80, "PCC Scalar-Multiply-X25519"),
+-    FEAT_INIT("pcc-scalar-mult-x448", S390_FEAT_TYPE_PCC, 81, "PCC Scalar-Multiply-X448"),
+-
+-    FEAT_INIT("ppno-sha-512-drng", S390_FEAT_TYPE_PPNO, 3, "PPNO SHA-512-DRNG"),
+-    FEAT_INIT("prno-trng-qrtcr", S390_FEAT_TYPE_PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio"),
+-    FEAT_INIT("prno-trng", S390_FEAT_TYPE_PPNO, 114, "PRNO TRNG"),
+-
+-    FEAT_INIT("kma-gcm-aes-128", S390_FEAT_TYPE_KMA, 18, "KMA GCM-AES-128"),
+-    FEAT_INIT("kma-gcm-aes-192", S390_FEAT_TYPE_KMA, 19, "KMA GCM-AES-192"),
+-    FEAT_INIT("kma-gcm-aes-256", S390_FEAT_TYPE_KMA, 20, "KMA GCM-AES-256"),
+-    FEAT_INIT("kma-gcm-eaes-128", S390_FEAT_TYPE_KMA, 26, "KMA GCM-Encrypted-AES-128"),
+-    FEAT_INIT("kma-gcm-eaes-192", S390_FEAT_TYPE_KMA, 27, "KMA GCM-Encrypted-AES-192"),
+-    FEAT_INIT("kma-gcm-eaes-256", S390_FEAT_TYPE_KMA, 28, "KMA GCM-Encrypted-AES-256"),
+-
+-    FEAT_INIT("kdsa-ecdsa-verify-p256", S390_FEAT_TYPE_KDSA, 1, "KDSA ECDSA-Verify-P256"),
+-    FEAT_INIT("kdsa-ecdsa-verify-p384", S390_FEAT_TYPE_KDSA, 2, "KDSA ECDSA-Verify-P384"),
+-    FEAT_INIT("kdsa-ecdsa-verify-p521", S390_FEAT_TYPE_KDSA, 3, "KDSA ECDSA-Verify-P521"),
+-    FEAT_INIT("kdsa-ecdsa-sign-p256", S390_FEAT_TYPE_KDSA, 9, "KDSA ECDSA-Sign-P256"),
+-    FEAT_INIT("kdsa-ecdsa-sign-p384", S390_FEAT_TYPE_KDSA, 10, "KDSA ECDSA-Sign-P384"),
+-    FEAT_INIT("kdsa-ecdsa-sign-p521", S390_FEAT_TYPE_KDSA, 11, "KDSA ECDSA-Sign-P521"),
+-    FEAT_INIT("kdsa-eecdsa-sign-p256", S390_FEAT_TYPE_KDSA, 17, "KDSA Encrypted-ECDSA-Sign-P256"),
+-    FEAT_INIT("kdsa-eecdsa-sign-p384", S390_FEAT_TYPE_KDSA, 18, "KDSA Encrypted-ECDSA-Sign-P384"),
+-    FEAT_INIT("kdsa-eecdsa-sign-p521", S390_FEAT_TYPE_KDSA, 19, "KDSA Encrypted-ECDSA-Sign-P521"),
+-    FEAT_INIT("kdsa-eddsa-verify-ed25519", S390_FEAT_TYPE_KDSA, 32, "KDSA EdDSA-Verify-Ed25519"),
+-    FEAT_INIT("kdsa-eddsa-verify-ed448", S390_FEAT_TYPE_KDSA, 36, "KDSA EdDSA-Verify-Ed448"),
+-    FEAT_INIT("kdsa-eddsa-sign-ed25519", S390_FEAT_TYPE_KDSA, 40, "KDSA EdDSA-Sign-Ed25519"),
+-    FEAT_INIT("kdsa-eddsa-sign-ed448", S390_FEAT_TYPE_KDSA, 44, "KDSA EdDSA-Sign-Ed448"),
+-    FEAT_INIT("kdsa-eeddsa-sign-ed25519", S390_FEAT_TYPE_KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519"),
+-    FEAT_INIT("kdsa-eeddsa-sign-ed448", S390_FEAT_TYPE_KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448"),
+-
+-    FEAT_INIT("sortl-sflr", S390_FEAT_TYPE_SORTL, 1, "SORTL SFLR"),
+-    FEAT_INIT("sortl-svlr", S390_FEAT_TYPE_SORTL, 2, "SORTL SVLR"),
+-    FEAT_INIT("sortl-32", S390_FEAT_TYPE_SORTL, 130, "SORTL 32 input lists"),
+-    FEAT_INIT("sortl-128", S390_FEAT_TYPE_SORTL, 132, "SORTL 128 input lists"),
+-    FEAT_INIT("sortl-f0", S390_FEAT_TYPE_SORTL, 192, "SORTL format 0 parameter-block"),
+-
+-    FEAT_INIT("dfltcc-gdht", S390_FEAT_TYPE_DFLTCC, 1, "DFLTCC GDHT"),
+-    FEAT_INIT("dfltcc-cmpr", S390_FEAT_TYPE_DFLTCC, 2, "DFLTCC CMPR"),
+-    FEAT_INIT("dfltcc-xpnd", S390_FEAT_TYPE_DFLTCC, 4, "DFLTCC XPND"),
+-    FEAT_INIT("dfltcc-f0", S390_FEAT_TYPE_DFLTCC, 192, "DFLTCC format 0 parameter-block"),
++#define DEF_FEAT(_FEAT, _NAME, _TYPE, _BIT, _DESC) \
++    [S390_FEAT_##_FEAT] = {                        \
++        .name = _NAME,                             \
++        .type = S390_FEAT_TYPE_##_TYPE,            \
++        .bit = _BIT,                               \
++        .desc = _DESC,                             \
++    },
++static const S390FeatDef s390_features[S390_FEAT_MAX] = {
++    #include "cpu_features_def.inc.h"
+ };
++#undef DEF_FEAT
+ 
+ const S390FeatDef *s390_feat_def(S390Feat feat)
+ {
+diff --git a/target/s390x/cpu_features_def.h b/target/s390x/cpu_features_def.h
+index a7abe4d..412d356 100644
+--- a/target/s390x/cpu_features_def.h
++++ b/target/s390x/cpu_features_def.h
+@@ -2,9 +2,10 @@
+  * CPU features/facilities for s390
+  *
+  * Copyright IBM Corp. 2016, 2018
++ * Copyright Red Hat, Inc. 2019
+  *
+  * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+- *            David Hildenbrand <dahi@linux.vnet.ibm.com>
++ *            David Hildenbrand <david@redhat.com>
+  *
+  * This work is licensed under the terms of the GNU GPL, version 2 or (at
+  * your option) any later version. See the COPYING file in the top-level
+@@ -14,354 +15,11 @@
+ #ifndef TARGET_S390X_CPU_FEATURES_DEF_H
+ #define TARGET_S390X_CPU_FEATURES_DEF_H
+ 
++#define DEF_FEAT(_FEAT, ...) S390_FEAT_##_FEAT,
+ typedef enum {
+-    /* Stfle */
+-    S390_FEAT_ESAN3 = 0,
+-    S390_FEAT_ZARCH,
+-    S390_FEAT_DAT_ENH,
+-    S390_FEAT_IDTE_SEGMENT,
+-    S390_FEAT_IDTE_REGION,
+-    S390_FEAT_ASN_LX_REUSE,
+-    S390_FEAT_STFLE,
+-    S390_FEAT_EDAT,
+-    S390_FEAT_SENSE_RUNNING_STATUS,
+-    S390_FEAT_CONDITIONAL_SSKE,
+-    S390_FEAT_CONFIGURATION_TOPOLOGY,
+-    S390_FEAT_AP_QUERY_CONFIG_INFO,
+-    S390_FEAT_IPTE_RANGE,
+-    S390_FEAT_NONQ_KEY_SETTING,
+-    S390_FEAT_AP_FACILITIES_TEST,
+-    S390_FEAT_EXTENDED_TRANSLATION_2,
+-    S390_FEAT_MSA,
+-    S390_FEAT_LONG_DISPLACEMENT,
+-    S390_FEAT_LONG_DISPLACEMENT_FAST,
+-    S390_FEAT_HFP_MADDSUB,
+-    S390_FEAT_EXTENDED_IMMEDIATE,
+-    S390_FEAT_EXTENDED_TRANSLATION_3,
+-    S390_FEAT_HFP_UNNORMALIZED_EXT,
+-    S390_FEAT_ETF2_ENH,
+-    S390_FEAT_STORE_CLOCK_FAST,
+-    S390_FEAT_PARSING_ENH,
+-    S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
+-    S390_FEAT_TOD_CLOCK_STEERING,
+-    S390_FEAT_ETF3_ENH,
+-    S390_FEAT_EXTRACT_CPU_TIME,
+-    S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
+-    S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
+-    S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
+-    S390_FEAT_EXECUTE_EXT,
+-    S390_FEAT_ENHANCED_MONITOR,
+-    S390_FEAT_FLOATING_POINT_EXT,
+-    S390_FEAT_ORDER_PRESERVING_COMPRESSION,
+-    S390_FEAT_SET_PROGRAM_PARAMETERS,
+-    S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
+-    S390_FEAT_DFP,
+-    S390_FEAT_DFP_FAST,
+-    S390_FEAT_PFPO,
+-    S390_FEAT_STFLE_45,
+-    S390_FEAT_CMPSC_ENH,
+-    S390_FEAT_DFP_ZONED_CONVERSION,
+-    S390_FEAT_STFLE_49,
+-    S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
+-    S390_FEAT_LOCAL_TLB_CLEARING,
+-    S390_FEAT_INTERLOCKED_ACCESS_2,
+-    S390_FEAT_STFLE_53,
+-    S390_FEAT_ENTROPY_ENC_COMP,
+-    S390_FEAT_MSA_EXT_5,
+-    S390_FEAT_MISC_INSTRUCTION_EXT,
+-    S390_FEAT_SEMAPHORE_ASSIST,
+-    S390_FEAT_TIME_SLICE_INSTRUMENTATION,
+-    S390_FEAT_MISC_INSTRUCTION_EXT3,
+-    S390_FEAT_RUNTIME_INSTRUMENTATION,
+-    S390_FEAT_ZPCI,
+-    S390_FEAT_ADAPTER_EVENT_NOTIFICATION,
+-    S390_FEAT_ADAPTER_INT_SUPPRESSION,
+-    S390_FEAT_TRANSACTIONAL_EXE,
+-    S390_FEAT_STORE_HYPERVISOR_INFO,
+-    S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
+-    S390_FEAT_MSA_EXT_3,
+-    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,
+-    S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
+-    S390_FEAT_GUARDED_STORAGE,
+-    S390_FEAT_VECTOR_PACKED_DECIMAL,
+-    S390_FEAT_VECTOR_ENH,
+-    S390_FEAT_MULTIPLE_EPOCH,
+-    S390_FEAT_TEST_PENDING_EXT_INTERRUPTION,
+-    S390_FEAT_INSERT_REFERENCE_BITS_MULT,
+-    S390_FEAT_MSA_EXT_8,
+-    S390_FEAT_CMM_NT,
+-    S390_FEAT_VECTOR_ENH2,
+-    S390_FEAT_ESORT_BASE,
+-    S390_FEAT_DEFLATE_BASE,
+-    S390_FEAT_VECTOR_PACKED_DECIMAL_ENH,
+-    S390_FEAT_MSA_EXT_9,
+-    S390_FEAT_ETOKEN,
+-
+-    /* Sclp Conf Char */
+-    S390_FEAT_SIE_GSLS,
+-    S390_FEAT_ESOP,
+-    S390_FEAT_HPMA2,
+-    S390_FEAT_SIE_KSS,
+-
+-    /* Sclp Conf Char Ext */
+-    S390_FEAT_SIE_64BSCAO,
+-    S390_FEAT_SIE_CMMA,
+-    S390_FEAT_SIE_PFMFI,
+-    S390_FEAT_SIE_IBS,
+-
+-    /* Sclp Cpu */
+-    S390_FEAT_SIE_F2,
+-    S390_FEAT_SIE_SKEY,
+-    S390_FEAT_SIE_GPERE,
+-    S390_FEAT_SIE_SIIF,
+-    S390_FEAT_SIE_SIGPIF,
+-    S390_FEAT_SIE_IB,
+-    S390_FEAT_SIE_CEI,
+-
+-    /* Misc */
+-    S390_FEAT_DAT_ENH_2,
+-    S390_FEAT_CMM,
+-    S390_FEAT_AP,
+-
+-    /* PLO */
+-    S390_FEAT_PLO_CL,
+-    S390_FEAT_PLO_CLG,
+-    S390_FEAT_PLO_CLGR,
+-    S390_FEAT_PLO_CLX,
+-    S390_FEAT_PLO_CS,
+-    S390_FEAT_PLO_CSG,
+-    S390_FEAT_PLO_CSGR,
+-    S390_FEAT_PLO_CSX,
+-    S390_FEAT_PLO_DCS,
+-    S390_FEAT_PLO_DCSG,
+-    S390_FEAT_PLO_DCSGR,
+-    S390_FEAT_PLO_DCSX,
+-    S390_FEAT_PLO_CSST,
+-    S390_FEAT_PLO_CSSTG,
+-    S390_FEAT_PLO_CSSTGR,
+-    S390_FEAT_PLO_CSSTX,
+-    S390_FEAT_PLO_CSDST,
+-    S390_FEAT_PLO_CSDSTG,
+-    S390_FEAT_PLO_CSDSTGR,
+-    S390_FEAT_PLO_CSDSTX,
+-    S390_FEAT_PLO_CSTST,
+-    S390_FEAT_PLO_CSTSTG,
+-    S390_FEAT_PLO_CSTSTGR,
+-    S390_FEAT_PLO_CSTSTX,
+-
+-    /* PTFF */
+-    S390_FEAT_PTFF_QTO,
+-    S390_FEAT_PTFF_QSI,
+-    S390_FEAT_PTFF_QPT,
+-    S390_FEAT_PTFF_QUI,
+-    S390_FEAT_PTFF_QTOU,
+-    S390_FEAT_PTFF_QSIE,
+-    S390_FEAT_PTFF_QTOUE,
+-    S390_FEAT_PTFF_STO,
+-    S390_FEAT_PTFF_STOU,
+-    S390_FEAT_PTFF_STOE,
+-    S390_FEAT_PTFF_STOUE,
+-
+-    /* KMAC */
+-    S390_FEAT_KMAC_DEA,
+-    S390_FEAT_KMAC_TDEA_128,
+-    S390_FEAT_KMAC_TDEA_192,
+-    S390_FEAT_KMAC_EDEA,
+-    S390_FEAT_KMAC_ETDEA_128,
+-    S390_FEAT_KMAC_ETDEA_192,
+-    S390_FEAT_KMAC_AES_128,
+-    S390_FEAT_KMAC_AES_192,
+-    S390_FEAT_KMAC_AES_256,
+-    S390_FEAT_KMAC_EAES_128,
+-    S390_FEAT_KMAC_EAES_192,
+-    S390_FEAT_KMAC_EAES_256,
+-
+-    /* KMC */
+-    S390_FEAT_KMC_DEA,
+-    S390_FEAT_KMC_TDEA_128,
+-    S390_FEAT_KMC_TDEA_192,
+-    S390_FEAT_KMC_EDEA,
+-    S390_FEAT_KMC_ETDEA_128,
+-    S390_FEAT_KMC_ETDEA_192,
+-    S390_FEAT_KMC_AES_128,
+-    S390_FEAT_KMC_AES_192,
+-    S390_FEAT_KMC_AES_256,
+-    S390_FEAT_KMC_EAES_128,
+-    S390_FEAT_KMC_EAES_192,
+-    S390_FEAT_KMC_EAES_256,
+-    S390_FEAT_KMC_PRNG,
+-
+-    /* KM */
+-    S390_FEAT_KM_DEA,
+-    S390_FEAT_KM_TDEA_128,
+-    S390_FEAT_KM_TDEA_192,
+-    S390_FEAT_KM_EDEA,
+-    S390_FEAT_KM_ETDEA_128,
+-    S390_FEAT_KM_ETDEA_192,
+-    S390_FEAT_KM_AES_128,
+-    S390_FEAT_KM_AES_192,
+-    S390_FEAT_KM_AES_256,
+-    S390_FEAT_KM_EAES_128,
+-    S390_FEAT_KM_EAES_192,
+-    S390_FEAT_KM_EAES_256,
+-    S390_FEAT_KM_XTS_AES_128,
+-    S390_FEAT_KM_XTS_AES_256,
+-    S390_FEAT_KM_XTS_EAES_128,
+-    S390_FEAT_KM_XTS_EAES_256,
+-
+-    /* KIMD */
+-    S390_FEAT_KIMD_SHA_1,
+-    S390_FEAT_KIMD_SHA_256,
+-    S390_FEAT_KIMD_SHA_512,
+-    S390_FEAT_KIMD_SHA3_224,
+-    S390_FEAT_KIMD_SHA3_256,
+-    S390_FEAT_KIMD_SHA3_384,
+-    S390_FEAT_KIMD_SHA3_512,
+-    S390_FEAT_KIMD_SHAKE_128,
+-    S390_FEAT_KIMD_SHAKE_256,
+-    S390_FEAT_KIMD_GHASH,
+-
+-    /* KLMD */
+-    S390_FEAT_KLMD_SHA_1,
+-    S390_FEAT_KLMD_SHA_256,
+-    S390_FEAT_KLMD_SHA_512,
+-    S390_FEAT_KLMD_SHA3_224,
+-    S390_FEAT_KLMD_SHA3_256,
+-    S390_FEAT_KLMD_SHA3_384,
+-    S390_FEAT_KLMD_SHA3_512,
+-    S390_FEAT_KLMD_SHAKE_128,
+-    S390_FEAT_KLMD_SHAKE_256,
+-
+-    /* PCKMO */
+-    S390_FEAT_PCKMO_EDEA,
+-    S390_FEAT_PCKMO_ETDEA_128,
+-    S390_FEAT_PCKMO_ETDEA_256,
+-    S390_FEAT_PCKMO_AES_128,
+-    S390_FEAT_PCKMO_AES_192,
+-    S390_FEAT_PCKMO_AES_256,
+-    S390_FEAT_PCKMO_ECC_P256,
+-    S390_FEAT_PCKMO_ECC_P384,
+-    S390_FEAT_PCKMO_ECC_P521,
+-    S390_FEAT_PCKMO_ECC_ED25519,
+-    S390_FEAT_PCKMO_ECC_ED448,
+-
+-    /* KMCTR */
+-    S390_FEAT_KMCTR_DEA,
+-    S390_FEAT_KMCTR_TDEA_128,
+-    S390_FEAT_KMCTR_TDEA_192,
+-    S390_FEAT_KMCTR_EDEA,
+-    S390_FEAT_KMCTR_ETDEA_128,
+-    S390_FEAT_KMCTR_ETDEA_192,
+-    S390_FEAT_KMCTR_AES_128,
+-    S390_FEAT_KMCTR_AES_192,
+-    S390_FEAT_KMCTR_AES_256,
+-    S390_FEAT_KMCTR_EAES_128,
+-    S390_FEAT_KMCTR_EAES_192,
+-    S390_FEAT_KMCTR_EAES_256,
+-
+-    /* KMF */
+-    S390_FEAT_KMF_DEA,
+-    S390_FEAT_KMF_TDEA_128,
+-    S390_FEAT_KMF_TDEA_192,
+-    S390_FEAT_KMF_EDEA,
+-    S390_FEAT_KMF_ETDEA_128,
+-    S390_FEAT_KMF_ETDEA_192,
+-    S390_FEAT_KMF_AES_128,
+-    S390_FEAT_KMF_AES_192,
+-    S390_FEAT_KMF_AES_256,
+-    S390_FEAT_KMF_EAES_128,
+-    S390_FEAT_KMF_EAES_192,
+-    S390_FEAT_KMF_EAES_256,
+-
+-    /* KMO */
+-    S390_FEAT_KMO_DEA,
+-    S390_FEAT_KMO_TDEA_128,
+-    S390_FEAT_KMO_TDEA_192,
+-    S390_FEAT_KMO_EDEA,
+-    S390_FEAT_KMO_ETDEA_128,
+-    S390_FEAT_KMO_ETDEA_192,
+-    S390_FEAT_KMO_AES_128,
+-    S390_FEAT_KMO_AES_192,
+-    S390_FEAT_KMO_AES_256,
+-    S390_FEAT_KMO_EAES_128,
+-    S390_FEAT_KMO_EAES_192,
+-    S390_FEAT_KMO_EAES_256,
+-
+-    /* PCC */
+-    S390_FEAT_PCC_CMAC_DEA,
+-    S390_FEAT_PCC_CMAC_TDEA_128,
+-    S390_FEAT_PCC_CMAC_TDEA_192,
+-    S390_FEAT_PCC_CMAC_ETDEA_128,
+-    S390_FEAT_PCC_CMAC_ETDEA_192,
+-    S390_FEAT_PCC_CMAC_TDEA,
+-    S390_FEAT_PCC_CMAC_AES_128,
+-    S390_FEAT_PCC_CMAC_AES_192,
+-    S390_FEAT_PCC_CMAC_AES_256,
+-    S390_FEAT_PCC_CMAC_EAES_128,
+-    S390_FEAT_PCC_CMAC_EAES_192,
+-    S390_FEAT_PCC_CMAC_EAES_256,
+-    S390_FEAT_PCC_XTS_AES_128,
+-    S390_FEAT_PCC_XTS_AES_256,
+-    S390_FEAT_PCC_XTS_EAES_128,
+-    S390_FEAT_PCC_XTS_EAES_256,
+-    S390_FEAT_PCC_SCALAR_MULT_P256,
+-    S390_FEAT_PCC_SCALAR_MULT_P384,
+-    S390_FEAT_PCC_SCALAR_MULT_P512,
+-    S390_FEAT_PCC_SCALAR_MULT_ED25519,
+-    S390_FEAT_PCC_SCALAR_MULT_ED448,
+-    S390_FEAT_PCC_SCALAR_MULT_X25519,
+-    S390_FEAT_PCC_SCALAR_MULT_X448,
+-
+-    /* PPNO/PRNO */
+-    S390_FEAT_PPNO_SHA_512_DRNG,
+-    S390_FEAT_PRNO_TRNG_QRTCR,
+-    S390_FEAT_PRNO_TRNG,
+-
+-    /* KMA */
+-    S390_FEAT_KMA_GCM_AES_128,
+-    S390_FEAT_KMA_GCM_AES_192,
+-    S390_FEAT_KMA_GCM_AES_256 ,
+-    S390_FEAT_KMA_GCM_EAES_128,
+-    S390_FEAT_KMA_GCM_EAES_192,
+-    S390_FEAT_KMA_GCM_EAES_256,
+-
+-    /* KDSA */
+-    S390_FEAT_ECDSA_VERIFY_P256,
+-    S390_FEAT_ECDSA_VERIFY_P384,
+-    S390_FEAT_ECDSA_VERIFY_P512,
+-    S390_FEAT_ECDSA_SIGN_P256,
+-    S390_FEAT_ECDSA_SIGN_P384,
+-    S390_FEAT_ECDSA_SIGN_P512,
+-    S390_FEAT_EECDSA_SIGN_P256,
+-    S390_FEAT_EECDSA_SIGN_P384,
+-    S390_FEAT_EECDSA_SIGN_P512,
+-    S390_FEAT_EDDSA_VERIFY_ED25519,
+-    S390_FEAT_EDDSA_VERIFY_ED448,
+-    S390_FEAT_EDDSA_SIGN_ED25519,
+-    S390_FEAT_EDDSA_SIGN_ED448,
+-    S390_FEAT_EEDDSA_SIGN_ED25519,
+-    S390_FEAT_EEDDSA_SIGN_ED448,
+-
+-    /* SORTL */
+-    S390_FEAT_SORTL_SFLR,
+-    S390_FEAT_SORTL_SVLR,
+-    S390_FEAT_SORTL_32,
+-    S390_FEAT_SORTL_128,
+-    S390_FEAT_SORTL_F0,
+-
+-    /* DEFLATE */
+-    S390_FEAT_DEFLATE_GHDT,
+-    S390_FEAT_DEFLATE_CMPR,
+-    S390_FEAT_DEFLATE_XPND,
+-    S390_FEAT_DEFLATE_F0,
+-
++    #include "cpu_features_def.inc.h"
+     S390_FEAT_MAX,
+ } S390Feat;
++#undef DEF_FEAT
+ 
+ #endif /* TARGET_S390X_CPU_FEATURES_DEF_H */
+diff --git a/target/s390x/cpu_features_def.inc.h b/target/s390x/cpu_features_def.inc.h
+new file mode 100644
+index 0000000..011ce4d
+--- /dev/null
++++ b/target/s390x/cpu_features_def.inc.h
+@@ -0,0 +1,369 @@
++/*
++ * RAW s390x CPU feature definitions:
++ *
++ * DEF_FEAT(_FEAT, _NAME, _TYPE, _BIT, _DESC):
++ * - _FEAT: Feature (enum) name used internally (S390_FEAT_##_FEAT)
++ * - _NAME: Feature name exposed to the user.
++ * - _TYPE: Feature type (S390_FEAT_TYPE_##_TYPE).
++ * - _BIT: Feature bit number within feature type block (unused for MISC).
++ * - _DESC: Feature description, exposed to the user.
++ *
++ * Copyright IBM Corp. 2016, 2018
++ * Copyright Red Hat, Inc. 2019
++ *
++ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
++ *            David Hildenbrand <david@redhat.com>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or (at
++ * your option) any later version. See the COPYING file in the top-level
++ * directory.
++ */
++
++/* Features exposed via the STFL(E) instruction. */
++DEF_FEAT(ESAN3, "esan3", STFL, 0, "Instructions marked as n3")
++DEF_FEAT(ZARCH, "zarch", STFL, 1, "z/Architecture architectural mode")
++DEF_FEAT(DAT_ENH, "dateh", STFL, 3, "DAT-enhancement facility")
++DEF_FEAT(IDTE_SEGMENT, "idtes", STFL, 4, "IDTE selective TLB segment-table clearing")
++DEF_FEAT(IDTE_REGION, "idter", STFL, 5, "IDTE selective TLB region-table clearing")
++DEF_FEAT(ASN_LX_REUSE, "asnlxr", STFL, 6, "ASN-and-LX reuse facility")
++DEF_FEAT(STFLE, "stfle", STFL, 7, "Store-facility-list-extended facility")
++DEF_FEAT(EDAT, "edat", STFL, 8, "Enhanced-DAT facility")
++DEF_FEAT(SENSE_RUNNING_STATUS, "srs", STFL, 9, "Sense-running-status facility")
++DEF_FEAT(CONDITIONAL_SSKE, "csske", STFL, 10, "Conditional-SSKE facility")
++DEF_FEAT(CONFIGURATION_TOPOLOGY, "ctop", STFL, 11, "Configuration-topology facility")
++DEF_FEAT(AP_QUERY_CONFIG_INFO, "apqci", STFL, 12, "Query AP Configuration Information facility")
++DEF_FEAT(IPTE_RANGE, "ipter", STFL, 13, "IPTE-range facility")
++DEF_FEAT(NONQ_KEY_SETTING, "nonqks", STFL, 14, "Nonquiescing key-setting facility")
++DEF_FEAT(AP_FACILITIES_TEST, "apft", STFL, 15, "AP Facilities Test facility")
++DEF_FEAT(EXTENDED_TRANSLATION_2, "etf2", STFL, 16, "Extended-translation facility 2")
++DEF_FEAT(MSA, "msa-base", STFL, 17, "Message-security-assist facility (excluding subfunctions)")
++DEF_FEAT(LONG_DISPLACEMENT, "ldisp", STFL, 18, "Long-displacement facility")
++DEF_FEAT(LONG_DISPLACEMENT_FAST, "ldisphp", STFL, 19, "Long-displacement facility has high performance")
++DEF_FEAT(HFP_MADDSUB, "hfpm", STFL, 20, "HFP-multiply-add/subtract facility")
++DEF_FEAT(EXTENDED_IMMEDIATE, "eimm", STFL, 21, "Extended-immediate facility")
++DEF_FEAT(EXTENDED_TRANSLATION_3, "etf3", STFL, 22, "Extended-translation facility 3")
++DEF_FEAT(HFP_UNNORMALIZED_EXT, "hfpue", STFL, 23, "HFP-unnormalized-extension facility")
++DEF_FEAT(ETF2_ENH, "etf2eh", STFL, 24, "ETF2-enhancement facility")
++DEF_FEAT(STORE_CLOCK_FAST, "stckf", STFL, 25, "Store-clock-fast facility")
++DEF_FEAT(PARSING_ENH, "parseh", STFL, 26, "Parsing-enhancement facility")
++DEF_FEAT(MOVE_WITH_OPTIONAL_SPEC, "mvcos", STFL, 27, "Move-with-optional-specification facility")
++DEF_FEAT(TOD_CLOCK_STEERING, "tods-base", STFL, 28, "TOD-clock-steering facility (excluding subfunctions)")
++DEF_FEAT(ETF3_ENH, "etf3eh", STFL, 30, "ETF3-enhancement facility")
++DEF_FEAT(EXTRACT_CPU_TIME, "ectg", STFL, 31, "Extract-CPU-time facility")
++DEF_FEAT(COMPARE_AND_SWAP_AND_STORE, "csst", STFL, 32, "Compare-and-swap-and-store facility")
++DEF_FEAT(COMPARE_AND_SWAP_AND_STORE_2, "csst2", STFL, 33, "Compare-and-swap-and-store facility 2")
++DEF_FEAT(GENERAL_INSTRUCTIONS_EXT, "ginste", STFL, 34, "General-instructions-extension facility")
++DEF_FEAT(EXECUTE_EXT, "exrl", STFL, 35, "Execute-extensions facility")
++DEF_FEAT(ENHANCED_MONITOR, "emon", STFL, 36, "Enhanced-monitor facility")
++DEF_FEAT(FLOATING_POINT_EXT, "fpe", STFL, 37, "Floating-point extension facility")
++DEF_FEAT(ORDER_PRESERVING_COMPRESSION, "opc", STFL, 38, "Order Preserving Compression facility")
++DEF_FEAT(SET_PROGRAM_PARAMETERS, "sprogp", STFL, 40, "Set-program-parameters facility")
++DEF_FEAT(FLOATING_POINT_SUPPPORT_ENH, "fpseh", STFL, 41, "Floating-point-support-enhancement facilities")
++DEF_FEAT(DFP, "dfp", STFL, 42, "DFP (decimal-floating-point) facility")
++DEF_FEAT(DFP_FAST, "dfphp", STFL, 43, "DFP (decimal-floating-point) facility has high performance")
++DEF_FEAT(PFPO, "pfpo", STFL, 44, "PFPO instruction")
++DEF_FEAT(STFLE_45, "stfle45", STFL, 45, "Various facilities introduced with z196")
++DEF_FEAT(CMPSC_ENH, "cmpsceh", STFL, 47, "CMPSC-enhancement facility")
++DEF_FEAT(DFP_ZONED_CONVERSION, "dfpzc", STFL, 48, "Decimal-floating-point zoned-conversion facility")
++DEF_FEAT(STFLE_49, "stfle49", STFL, 49, "Various facilities introduced with zEC12")
++DEF_FEAT(CONSTRAINT_TRANSACTIONAL_EXE, "cte", STFL, 50, "Constrained transactional-execution facility")
++DEF_FEAT(LOCAL_TLB_CLEARING, "ltlbc", STFL, 51, "Local-TLB-clearing facility")
++DEF_FEAT(INTERLOCKED_ACCESS_2, "iacc2", STFL, 52, "Interlocked-access facility 2")
++DEF_FEAT(STFLE_53, "stfle53", STFL, 53, "Various facilities introduced with z13")
++DEF_FEAT(ENTROPY_ENC_COMP, "eec", STFL, 54, "Entropy encoding compression facility")
++DEF_FEAT(MSA_EXT_5, "msa5-base", STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)")
++DEF_FEAT(MISC_INSTRUCTION_EXT, "minste2", STFL, 58, "Miscellaneous-instruction-extensions facility 2")
++DEF_FEAT(SEMAPHORE_ASSIST, "sema", STFL, 59, "Semaphore-assist facility")
++DEF_FEAT(TIME_SLICE_INSTRUMENTATION, "tsi", STFL, 60, "Time-slice Instrumentation facility")
++DEF_FEAT(MISC_INSTRUCTION_EXT3, "minste3", STFL, 61, "Miscellaneous-Instruction-Extensions Facility 3")
++DEF_FEAT(RUNTIME_INSTRUMENTATION, "ri", STFL, 64, "CPU runtime-instrumentation facility")
++DEF_FEAT(ZPCI, "zpci", STFL, 69, "z/PCI facility")
++DEF_FEAT(ADAPTER_EVENT_NOTIFICATION, "aen", STFL, 71, "General-purpose-adapter-event-notification facility")
++DEF_FEAT(ADAPTER_INT_SUPPRESSION, "ais", STFL, 72, "General-purpose-adapter-interruption-suppression facility")
++DEF_FEAT(TRANSACTIONAL_EXE, "te", STFL, 73, "Transactional-execution facility")
++DEF_FEAT(STORE_HYPERVISOR_INFO, "sthyi", STFL, 74, "Store-hypervisor-information facility")
++DEF_FEAT(ACCESS_EXCEPTION_FS_INDICATION, "aefsi", STFL, 75, "Access-exception-fetch/store-indication facility")
++DEF_FEAT(MSA_EXT_3, "msa3-base", STFL, 76, "Message-security-assist-extension-3 facility (excluding subfunctions)")
++DEF_FEAT(MSA_EXT_4, "msa4-base", STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)")
++DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2")
++DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility")
++DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed")
++DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking")
++DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility")
++DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility")
++DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2")
++DEF_FEAT(GUARDED_STORAGE, "gs", STFL, 133, "Guarded-storage facility")
++DEF_FEAT(VECTOR_PACKED_DECIMAL, "vxpd", STFL, 134, "Vector packed decimal facility")
++DEF_FEAT(VECTOR_ENH, "vxeh", STFL, 135, "Vector enhancements facility")
++DEF_FEAT(MULTIPLE_EPOCH, "mepoch", STFL, 139, "Multiple-epoch facility")
++DEF_FEAT(TEST_PENDING_EXT_INTERRUPTION, "tpei", STFL, 144, "Test-pending-external-interruption facility")
++DEF_FEAT(INSERT_REFERENCE_BITS_MULT, "irbm", STFL, 145, "Insert-reference-bits-multiple facility")
++DEF_FEAT(MSA_EXT_8, "msa8-base", STFL, 146, "Message-security-assist-extension-8 facility (excluding subfunctions)")
++DEF_FEAT(CMM_NT, "cmmnt", STFL, 147, "CMM: ESSA-enhancement (no translate) facility")
++DEF_FEAT(VECTOR_ENH2, "vxeh2", STFL, 148, "Vector Enhancements facility 2")
++DEF_FEAT(ESORT_BASE, "esort-base", STFL, 150, "Enhanced-sort facility (excluding subfunctions)")
++DEF_FEAT(DEFLATE_BASE, "deflate-base", STFL, 151, "Deflate-conversion facility (excluding subfunctions)")
++DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH, "vxpdeh", STFL, 152, "Vector-Packed-Decimal-Enhancement Facility")
++DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)")
++DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility")
++
++/* Features exposed via SCLP SCCB Byte 80 - 98  (bit numbers relative to byte-80) */
++DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility")
++DEF_FEAT(ESOP, "esop", SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility")
++DEF_FEAT(HPMA2, "hpma2", SCLP_CONF_CHAR, 90, "Host page management assist 2 Facility") /* 91-2 */
++DEF_FEAT(SIE_KSS, "kss", SCLP_CONF_CHAR, 151, "SIE: Keyless-subset facility")  /* 98-7 */
++
++/* Features exposed via SCLP SCCB Byte 116 - 119 (bit numbers relative to byte-116) */
++DEF_FEAT(SIE_64BSCAO, "64bscao", SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility")
++DEF_FEAT(SIE_CMMA, "cmma", SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist")
++DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility")
++DEF_FEAT(SIE_IBS, "ibs", SCLP_CONF_CHAR_EXT, 10, "SIE: Interlock-and-broadcast-suppression facility")
++
++/* Features exposed via SCLP CPU info. */
++DEF_FEAT(SIE_F2, "sief2", SCLP_CPU, 4, "SIE: interception format 2 (Virtual SIE)")
++DEF_FEAT(SIE_SKEY, "skey", SCLP_CPU, 5, "SIE: Storage-key facility")
++DEF_FEAT(SIE_GPERE, "gpereh", SCLP_CPU, 10, "SIE: Guest-PER enhancement facility")
++DEF_FEAT(SIE_SIIF, "siif", SCLP_CPU, 11, "SIE: Shared IPTE-interlock facility")
++DEF_FEAT(SIE_SIGPIF, "sigpif", SCLP_CPU, 12, "SIE: SIGP interpretation facility")
++DEF_FEAT(SIE_IB, "ib", SCLP_CPU, 42, "SIE: Intervention bypass facility")
++DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: Conditional-external-interception facility")
++
++/*
++ * Features exposed via no feature bit (but e.g., instruction sensing)
++ * -> the feature bit number is irrelavant
++ */
++DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2")
++DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility")
++DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed")
++
++/* Features exposed via the PLO instruction. */
++DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general registers)")
++DEF_FEAT(PLO_CLG, "plo-clg", PLO, 1, "PLO Compare and load (64 bit in parameter list)")
++DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (32 bit in general registers)")
++DEF_FEAT(PLO_CLX, "plo-clx", PLO, 3, "PLO Compare and load (128 bit in parameter list)")
++DEF_FEAT(PLO_CS, "plo-cs", PLO, 4, "PLO Compare and swap (32 bit in general registers)")
++DEF_FEAT(PLO_CSG, "plo-csg", PLO, 5, "PLO Compare and swap (64 bit in parameter list)")
++DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (32 bit in general registers)")
++DEF_FEAT(PLO_CSX, "plo-csx", PLO, 7, "PLO Compare and swap (128 bit in parameter list)")
++DEF_FEAT(PLO_DCS, "plo-dcs", PLO, 8, "PLO Double compare and swap (32 bit in general registers)")
++DEF_FEAT(PLO_DCSG, "plo-dcsg", PLO, 9, "PLO Double compare and swap (64 bit in parameter list)")
++DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (32 bit in general registers)")
++DEF_FEAT(PLO_DCSX, "plo-dcsx", PLO, 11, "PLO Double compare and swap (128 bit in parameter list)")
++DEF_FEAT(PLO_CSST, "plo-csst", PLO, 12, "PLO Compare and swap and store (32 bit in general registers)")
++DEF_FEAT(PLO_CSSTG, "plo-csstg", PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)")
++DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (32 bit in general registers)")
++DEF_FEAT(PLO_CSSTX, "plo-csstx", PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)")
++DEF_FEAT(PLO_CSDST, "plo-csdst", PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)")
++DEF_FEAT(PLO_CSDSTG, "plo-csdstg", PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)")
++DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)")
++DEF_FEAT(PLO_CSDSTX, "plo-csdstx", PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)")
++DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)")
++DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)")
++DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)")
++DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)")
++
++/* Features exposed via the PTFF instruction. */
++DEF_FEAT(PTFF_QTO, "ptff-qto", PTFF, 1, "PTFF Query TOD Offset")
++DEF_FEAT(PTFF_QSI, "ptff-qsi", PTFF, 2, "PTFF Query Steering Information")
++DEF_FEAT(PTFF_QPT, "ptff-qpc", PTFF, 3, "PTFF Query Physical Clock")
++DEF_FEAT(PTFF_QUI, "ptff-qui", PTFF, 4, "PTFF Query UTC Information")
++DEF_FEAT(PTFF_QTOU, "ptff-qtou", PTFF, 5, "PTFF Query TOD Offset User")
++DEF_FEAT(PTFF_QSIE, "ptff-qsie", PTFF, 10, "PTFF Query Steering Information Extended")
++DEF_FEAT(PTFF_QTOUE, "ptff-qtoue", PTFF, 13, "PTFF Query TOD Offset User Extended")
++DEF_FEAT(PTFF_STO, "ptff-sto", PTFF, 65, "PTFF Set TOD Offset")
++DEF_FEAT(PTFF_STOU, "ptff-stou", PTFF, 69, "PTFF Set TOD Offset User")
++DEF_FEAT(PTFF_STOE, "ptff-stoe", PTFF, 73, "PTFF Set TOD Offset Extended")
++DEF_FEAT(PTFF_STOUE, "ptff-stoue", PTFF, 77, "PTFF Set TOD Offset User Extended")
++
++/* Features exposed via the KMAC instruction. */
++DEF_FEAT(KMAC_DEA, "kmac-dea", KMAC, 1, "KMAC DEA")
++DEF_FEAT(KMAC_TDEA_128, "kmac-tdea-128", KMAC, 2, "KMAC TDEA-128")
++DEF_FEAT(KMAC_TDEA_192, "kmac-tdea-192", KMAC, 3, "KMAC TDEA-192")
++DEF_FEAT(KMAC_EDEA, "kmac-edea", KMAC, 9, "KMAC Encrypted-DEA")
++DEF_FEAT(KMAC_ETDEA_128, "kmac-etdea-128", KMAC, 10, "KMAC Encrypted-TDEA-128")
++DEF_FEAT(KMAC_ETDEA_192, "kmac-etdea-192", KMAC, 11, "KMAC Encrypted-TDEA-192")
++DEF_FEAT(KMAC_AES_128, "kmac-aes-128", KMAC, 18, "KMAC AES-128")
++DEF_FEAT(KMAC_AES_192, "kmac-aes-192", KMAC, 19, "KMAC AES-192")
++DEF_FEAT(KMAC_AES_256, "kmac-aes-256", KMAC, 20, "KMAC AES-256")
++DEF_FEAT(KMAC_EAES_128, "kmac-eaes-128", KMAC, 26, "KMAC Encrypted-AES-128")
++DEF_FEAT(KMAC_EAES_192, "kmac-eaes-192", KMAC, 27, "KMAC Encrypted-AES-192")
++DEF_FEAT(KMAC_EAES_256, "kmac-eaes-256", KMAC, 28, "KMAC Encrypted-AES-256")
++
++/* Features exposed via the KMC instruction. */
++DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA")
++DEF_FEAT(KMC_TDEA_128, "kmc-tdea-128", KMC, 2, "KMC TDEA-128")
++DEF_FEAT(KMC_TDEA_192, "kmc-tdea-192", KMC, 3, "KMC TDEA-192")
++DEF_FEAT(KMC_EDEA, "kmc-edea", KMC, 9, "KMC Encrypted-DEA")
++DEF_FEAT(KMC_ETDEA_128, "kmc-etdea-128", KMC, 10, "KMC Encrypted-TDEA-128")
++DEF_FEAT(KMC_ETDEA_192, "kmc-etdea-192", KMC, 11, "KMC Encrypted-TDEA-192")
++DEF_FEAT(KMC_AES_128, "kmc-aes-128", KMC, 18, "KMC AES-128")
++DEF_FEAT(KMC_AES_192, "kmc-aes-192", KMC, 19, "KMC AES-192")
++DEF_FEAT(KMC_AES_256, "kmc-aes-256", KMC, 20, "KMC AES-256")
++DEF_FEAT(KMC_EAES_128, "kmc-eaes-128", KMC, 26, "KMC Encrypted-AES-128")
++DEF_FEAT(KMC_EAES_192, "kmc-eaes-192", KMC, 27, "KMC Encrypted-AES-192")
++DEF_FEAT(KMC_EAES_256, "kmc-eaes-256", KMC, 28, "KMC Encrypted-AES-256")
++DEF_FEAT(KMC_PRNG, "kmc-prng", KMC, 67, "KMC PRNG")
++
++/* Features exposed via the KM instruction. */
++DEF_FEAT(KM_DEA, "km-dea", KM, 1, "KM DEA")
++DEF_FEAT(KM_TDEA_128, "km-tdea-128", KM, 2, "KM TDEA-128")
++DEF_FEAT(KM_TDEA_192, "km-tdea-192", KM, 3, "KM TDEA-192")
++DEF_FEAT(KM_EDEA, "km-edea", KM, 9, "KM Encrypted-DEA")
++DEF_FEAT(KM_ETDEA_128, "km-etdea-128", KM, 10, "KM Encrypted-TDEA-128")
++DEF_FEAT(KM_ETDEA_192, "km-etdea-192", KM, 11, "KM Encrypted-TDEA-192")
++DEF_FEAT(KM_AES_128, "km-aes-128", KM, 18, "KM AES-128")
++DEF_FEAT(KM_AES_192, "km-aes-192", KM, 19, "KM AES-192")
++DEF_FEAT(KM_AES_256, "km-aes-256", KM, 20, "KM AES-256")
++DEF_FEAT(KM_EAES_128, "km-eaes-128", KM, 26, "KM Encrypted-AES-128")
++DEF_FEAT(KM_EAES_192, "km-eaes-192", KM, 27, "KM Encrypted-AES-192")
++DEF_FEAT(KM_EAES_256, "km-eaes-256", KM, 28, "KM Encrypted-AES-256")
++DEF_FEAT(KM_XTS_AES_128, "km-xts-aes-128", KM, 50, "KM XTS-AES-128")
++DEF_FEAT(KM_XTS_AES_256, "km-xts-aes-256", KM, 52, "KM XTS-AES-256")
++DEF_FEAT(KM_XTS_EAES_128, "km-xts-eaes-128", KM, 58, "KM XTS-Encrypted-AES-128")
++DEF_FEAT(KM_XTS_EAES_256, "km-xts-eaes-256", KM, 60, "KM XTS-Encrypted-AES-256")
++
++/* Features exposed via the KIMD instruction. */
++DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1")
++DEF_FEAT(KIMD_SHA_256, "kimd-sha-256", KIMD, 2, "KIMD SHA-256")
++DEF_FEAT(KIMD_SHA_512, "kimd-sha-512", KIMD, 3, "KIMD SHA-512")
++DEF_FEAT(KIMD_SHA3_224, "kimd-sha3-224", KIMD, 32, "KIMD SHA3-224")
++DEF_FEAT(KIMD_SHA3_256, "kimd-sha3-256", KIMD, 33, "KIMD SHA3-256")
++DEF_FEAT(KIMD_SHA3_384, "kimd-sha3-384", KIMD, 34, "KIMD SHA3-384")
++DEF_FEAT(KIMD_SHA3_512, "kimd-sha3-512", KIMD, 35, "KIMD SHA3-512")
++DEF_FEAT(KIMD_SHAKE_128, "kimd-shake-128", KIMD, 36, "KIMD SHAKE-128")
++DEF_FEAT(KIMD_SHAKE_256, "kimd-shake-256", KIMD, 37, "KIMD SHAKE-256")
++DEF_FEAT(KIMD_GHASH, "kimd-ghash", KIMD, 65, "KIMD GHASH")
++
++/* Features exposed via the KLMD instruction. */
++DEF_FEAT(KLMD_SHA_1, "klmd-sha-1", KLMD, 1, "KLMD SHA-1")
++DEF_FEAT(KLMD_SHA_256, "klmd-sha-256", KLMD, 2, "KLMD SHA-256")
++DEF_FEAT(KLMD_SHA_512, "klmd-sha-512", KLMD, 3, "KLMD SHA-512")
++DEF_FEAT(KLMD_SHA3_224, "klmd-sha3-224", KLMD, 32, "KLMD SHA3-224")
++DEF_FEAT(KLMD_SHA3_256, "klmd-sha3-256", KLMD, 33, "KLMD SHA3-256")
++DEF_FEAT(KLMD_SHA3_384, "klmd-sha3-384", KLMD, 34, "KLMD SHA3-384")
++DEF_FEAT(KLMD_SHA3_512, "klmd-sha3-512", KLMD, 35, "KLMD SHA3-512")
++DEF_FEAT(KLMD_SHAKE_128, "klmd-shake-128", KLMD, 36, "KLMD SHAKE-128")
++DEF_FEAT(KLMD_SHAKE_256, "klmd-shake-256", KLMD, 37, "KLMD SHAKE-256")
++
++/* Features exposed via the PCKMO instruction. */
++DEF_FEAT(PCKMO_EDEA, "pckmo-edea", PCKMO, 1, "PCKMO Encrypted-DEA-Key")
++DEF_FEAT(PCKMO_ETDEA_128, "pckmo-etdea-128", PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key")
++DEF_FEAT(PCKMO_ETDEA_256, "pckmo-etdea-192", PCKMO, 3, "PCKMO Encrypted-TDEA-192-Key")
++DEF_FEAT(PCKMO_AES_128, "pckmo-aes-128", PCKMO, 18, "PCKMO Encrypted-AES-128-Key")
++DEF_FEAT(PCKMO_AES_192, "pckmo-aes-192", PCKMO, 19, "PCKMO Encrypted-AES-192-Key")
++DEF_FEAT(PCKMO_AES_256, "pckmo-aes-256", PCKMO, 20, "PCKMO Encrypted-AES-256-Key")
++DEF_FEAT(PCKMO_ECC_P256, "pckmo-ecc-p256", PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key")
++DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key")
++DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key")
++DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key")
++DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key")
++
++/* Features exposed via the KMCTR instruction. */
++DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA")
++DEF_FEAT(KMCTR_TDEA_128, "kmctr-tdea-128", KMCTR, 2, "KMCTR TDEA-128")
++DEF_FEAT(KMCTR_TDEA_192, "kmctr-tdea-192", KMCTR, 3, "KMCTR TDEA-192")
++DEF_FEAT(KMCTR_EDEA, "kmctr-edea", KMCTR, 9, "KMCTR Encrypted-DEA")
++DEF_FEAT(KMCTR_ETDEA_128, "kmctr-etdea-128", KMCTR, 10, "KMCTR Encrypted-TDEA-128")
++DEF_FEAT(KMCTR_ETDEA_192, "kmctr-etdea-192", KMCTR, 11, "KMCTR Encrypted-TDEA-192")
++DEF_FEAT(KMCTR_AES_128, "kmctr-aes-128", KMCTR, 18, "KMCTR AES-128")
++DEF_FEAT(KMCTR_AES_192, "kmctr-aes-192", KMCTR, 19, "KMCTR AES-192")
++DEF_FEAT(KMCTR_AES_256, "kmctr-aes-256", KMCTR, 20, "KMCTR AES-256")
++DEF_FEAT(KMCTR_EAES_128, "kmctr-eaes-128", KMCTR, 26, "KMCTR Encrypted-AES-128")
++DEF_FEAT(KMCTR_EAES_192, "kmctr-eaes-192", KMCTR, 27, "KMCTR Encrypted-AES-192")
++DEF_FEAT(KMCTR_EAES_256, "kmctr-eaes-256", KMCTR, 28, "KMCTR Encrypted-AES-256")
++
++/* Features exposed via the KMF instruction. */
++DEF_FEAT(KMF_DEA, "kmf-dea", KMF, 1, "KMF DEA")
++DEF_FEAT(KMF_TDEA_128, "kmf-tdea-128", KMF, 2, "KMF TDEA-128")
++DEF_FEAT(KMF_TDEA_192, "kmf-tdea-192", KMF, 3, "KMF TDEA-192")
++DEF_FEAT(KMF_EDEA, "kmf-edea", KMF, 9, "KMF Encrypted-DEA")
++DEF_FEAT(KMF_ETDEA_128, "kmf-etdea-128", KMF, 10, "KMF Encrypted-TDEA-128")
++DEF_FEAT(KMF_ETDEA_192, "kmf-etdea-192", KMF, 11, "KMF Encrypted-TDEA-192")
++DEF_FEAT(KMF_AES_128, "kmf-aes-128", KMF, 18, "KMF AES-128")
++DEF_FEAT(KMF_AES_192, "kmf-aes-192", KMF, 19, "KMF AES-192")
++DEF_FEAT(KMF_AES_256, "kmf-aes-256", KMF, 20, "KMF AES-256")
++DEF_FEAT(KMF_EAES_128, "kmf-eaes-128", KMF, 26, "KMF Encrypted-AES-128")
++DEF_FEAT(KMF_EAES_192, "kmf-eaes-192", KMF, 27, "KMF Encrypted-AES-192")
++DEF_FEAT(KMF_EAES_256, "kmf-eaes-256", KMF, 28, "KMF Encrypted-AES-256")
++
++/* Features exposed via the KMO instruction. */
++DEF_FEAT(KMO_DEA, "kmo-dea", KMO, 1, "KMO DEA")
++DEF_FEAT(KMO_TDEA_128, "kmo-tdea-128", KMO, 2, "KMO TDEA-128")
++DEF_FEAT(KMO_TDEA_192, "kmo-tdea-192", KMO, 3, "KMO TDEA-192")
++DEF_FEAT(KMO_EDEA, "kmo-edea", KMO, 9, "KMO Encrypted-DEA")
++DEF_FEAT(KMO_ETDEA_128, "kmo-etdea-128", KMO, 10, "KMO Encrypted-TDEA-128")
++DEF_FEAT(KMO_ETDEA_192, "kmo-etdea-192", KMO, 11, "KMO Encrypted-TDEA-192")
++DEF_FEAT(KMO_AES_128, "kmo-aes-128", KMO, 18, "KMO AES-128")
++DEF_FEAT(KMO_AES_192, "kmo-aes-192", KMO, 19, "KMO AES-192")
++DEF_FEAT(KMO_AES_256, "kmo-aes-256", KMO, 20, "KMO AES-256")
++DEF_FEAT(KMO_EAES_128, "kmo-eaes-128", KMO, 26, "KMO Encrypted-AES-128")
++DEF_FEAT(KMO_EAES_192, "kmo-eaes-192", KMO, 27, "KMO Encrypted-AES-192")
++DEF_FEAT(KMO_EAES_256, "kmo-eaes-256", KMO, 28, "KMO Encrypted-AES-256")
++
++/* Features exposed via the PCC instruction. */
++DEF_FEAT(PCC_CMAC_DEA, "pcc-cmac-dea", PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA")
++DEF_FEAT(PCC_CMAC_TDEA_128, "pcc-cmac-tdea-128", PCC, 2, "PCC Compute-Last-Block-CMAC-Using-TDEA-128")
++DEF_FEAT(PCC_CMAC_TDEA_192, "pcc-cmac-tdea-192", PCC, 3, "PCC Compute-Last-Block-CMAC-Using-TDEA-192")
++DEF_FEAT(PCC_CMAC_ETDEA_128, "pcc-cmac-edea", PCC, 9, "PCC Compute-Last-Block-CMAC-Using-Encrypted-DEA")
++DEF_FEAT(PCC_CMAC_ETDEA_192, "pcc-cmac-etdea-128", PCC, 10, "PCC Compute-Last-Block-CMAC-Using-Encrypted-TDEA-128")
++DEF_FEAT(PCC_CMAC_TDEA, "pcc-cmac-etdea-192", PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192")
++DEF_FEAT(PCC_CMAC_AES_128, "pcc-cmac-aes-128", PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128")
++DEF_FEAT(PCC_CMAC_AES_192, "pcc-cmac-aes-192", PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192")
++DEF_FEAT(PCC_CMAC_AES_256, "pcc-cmac-eaes-256", PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256")
++DEF_FEAT(PCC_CMAC_EAES_128, "pcc-cmac-eaes-128", PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128")
++DEF_FEAT(PCC_CMAC_EAES_192, "pcc-cmac-eaes-192", PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192")
++DEF_FEAT(PCC_CMAC_EAES_256, "pcc-cmac-eaes-256", PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256")
++DEF_FEAT(PCC_XTS_AES_128, "pcc-xts-aes-128", PCC, 50, "PCC Compute-XTS-Parameter-Using-AES-128")
++DEF_FEAT(PCC_XTS_AES_256, "pcc-xts-aes-256", PCC, 52, "PCC Compute-XTS-Parameter-Using-AES-256")
++DEF_FEAT(PCC_XTS_EAES_128, "pcc-xts-eaes-128", PCC, 58, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-128")
++DEF_FEAT(PCC_XTS_EAES_256, "pcc-xts-eaes-256", PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256")
++DEF_FEAT(PCC_SCALAR_MULT_P256, "pcc-scalar-mult-p256", PCC, 64, "PCC Scalar-Multiply-P256")
++DEF_FEAT(PCC_SCALAR_MULT_P384, "pcc-scalar-mult-p384", PCC, 65, "PCC Scalar-Multiply-P384")
++DEF_FEAT(PCC_SCALAR_MULT_P512, "pcc-scalar-mult-p521", PCC, 66, "PCC Scalar-Multiply-P521")
++DEF_FEAT(PCC_SCALAR_MULT_ED25519, "pcc-scalar-mult-ed25519", PCC, 72, "PCC Scalar-Multiply-Ed25519")
++DEF_FEAT(PCC_SCALAR_MULT_ED448, "pcc-scalar-mult-ed448", PCC, 73, "PCC Scalar-Multiply-Ed448")
++DEF_FEAT(PCC_SCALAR_MULT_X25519, "pcc-scalar-mult-x25519", PCC, 80, "PCC Scalar-Multiply-X25519")
++DEF_FEAT(PCC_SCALAR_MULT_X448, "pcc-scalar-mult-x448", PCC, 81, "PCC Scalar-Multiply-X448")
++
++/* Features exposed via the PPNO/PRNO instruction. */
++DEF_FEAT(PPNO_SHA_512_DRNG, "ppno-sha-512-drng", PPNO, 3, "PPNO SHA-512-DRNG")
++DEF_FEAT(PRNO_TRNG_QRTCR, "prno-trng-qrtcr", PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio")
++DEF_FEAT(PRNO_TRNG, "prno-trng", PPNO, 114, "PRNO TRNG")
++
++/* Features exposed via the KMA instruction. */
++DEF_FEAT(KMA_GCM_AES_128, "kma-gcm-aes-128", KMA, 18, "KMA GCM-AES-128")
++DEF_FEAT(KMA_GCM_AES_192, "kma-gcm-aes-192", KMA, 19, "KMA GCM-AES-192")
++DEF_FEAT(KMA_GCM_AES_256, "kma-gcm-aes-256", KMA, 20, "KMA GCM-AES-256")
++DEF_FEAT(KMA_GCM_EAES_128, "kma-gcm-eaes-128", KMA, 26, "KMA GCM-Encrypted-AES-128")
++DEF_FEAT(KMA_GCM_EAES_192, "kma-gcm-eaes-192", KMA, 27, "KMA GCM-Encrypted-AES-192")
++DEF_FEAT(KMA_GCM_EAES_256, "kma-gcm-eaes-256", KMA, 28, "KMA GCM-Encrypted-AES-256")
++
++/* Features exposed via the KDSA instruction. */
++DEF_FEAT(ECDSA_VERIFY_P256, "kdsa-ecdsa-verify-p256", KDSA, 1, "KDSA ECDSA-Verify-P256")
++DEF_FEAT(ECDSA_VERIFY_P384, "kdsa-ecdsa-verify-p384", KDSA, 2, "KDSA ECDSA-Verify-P384")
++DEF_FEAT(ECDSA_VERIFY_P512, "kdsa-ecdsa-verify-p521", KDSA, 3, "KDSA ECDSA-Verify-P521")
++DEF_FEAT(ECDSA_SIGN_P256, "kdsa-ecdsa-sign-p256", KDSA, 9, "KDSA ECDSA-Sign-P256")
++DEF_FEAT(ECDSA_SIGN_P384, "kdsa-ecdsa-sign-p384", KDSA, 10, "KDSA ECDSA-Sign-P384")
++DEF_FEAT(ECDSA_SIGN_P512, "kdsa-ecdsa-sign-p521", KDSA, 11, "KDSA ECDSA-Sign-P521")
++DEF_FEAT(EECDSA_SIGN_P256, "kdsa-eecdsa-sign-p256", KDSA, 17, "KDSA Encrypted-ECDSA-Sign-P256")
++DEF_FEAT(EECDSA_SIGN_P384, "kdsa-eecdsa-sign-p384", KDSA, 18, "KDSA Encrypted-ECDSA-Sign-P384")
++DEF_FEAT(EECDSA_SIGN_P512, "kdsa-eecdsa-sign-p521", KDSA, 19, "KDSA Encrypted-ECDSA-Sign-P521")
++DEF_FEAT(EDDSA_VERIFY_ED25519, "kdsa-eddsa-verify-ed25519", KDSA, 32, "KDSA EdDSA-Verify-Ed25519")
++DEF_FEAT(EDDSA_VERIFY_ED448, "kdsa-eddsa-verify-ed448", KDSA, 36, "KDSA EdDSA-Verify-Ed448")
++DEF_FEAT(EDDSA_SIGN_ED25519, "kdsa-eddsa-sign-ed25519", KDSA, 40, "KDSA EdDSA-Sign-Ed25519")
++DEF_FEAT(EDDSA_SIGN_ED448, "kdsa-eddsa-sign-ed448", KDSA, 44, "KDSA EdDSA-Sign-Ed448")
++DEF_FEAT(EEDDSA_SIGN_ED25519, "kdsa-eeddsa-sign-ed25519", KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519")
++DEF_FEAT(EEDDSA_SIGN_ED448, "kdsa-eeddsa-sign-ed448", KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448")
++
++/* Features exposed via the SORTL instruction. */
++DEF_FEAT(SORTL_SFLR, "sortl-sflr", SORTL, 1, "SORTL SFLR")
++DEF_FEAT(SORTL_SVLR, "sortl-svlr", SORTL, 2, "SORTL SVLR")
++DEF_FEAT(SORTL_32, "sortl-32", SORTL, 130, "SORTL 32 input lists")
++DEF_FEAT(SORTL_128, "sortl-128", SORTL, 132, "SORTL 128 input lists")
++DEF_FEAT(SORTL_F0, "sortl-f0", SORTL, 192, "SORTL format 0 parameter-block")
++
++/* Features exposed via the DEFLATE instruction. */
++DEF_FEAT(DEFLATE_GHDT, "dfltcc-gdht", DFLTCC, 1, "DFLTCC GDHT")
++DEF_FEAT(DEFLATE_CMPR, "dfltcc-cmpr", DFLTCC, 2, "DFLTCC CMPR")
++DEF_FEAT(DEFLATE_XPND, "dfltcc-xpnd", DFLTCC, 4, "DFLTCC XPND")
++DEF_FEAT(DEFLATE_F0, "dfltcc-f0", DFLTCC, 192, "DFLTCC format 0 parameter-block")
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-cpumodel-Set-up-CPU-model-for-AQIC-interceptio.patch b/SOURCES/kvm-s390x-cpumodel-Set-up-CPU-model-for-AQIC-interceptio.patch
new file mode 100644
index 0000000..7ef39c4
--- /dev/null
+++ b/SOURCES/kvm-s390x-cpumodel-Set-up-CPU-model-for-AQIC-interceptio.patch
@@ -0,0 +1,96 @@
+From ad53e96559cfe9d5f1b5518c3c925618e7e1bcc7 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Wed, 18 Sep 2019 14:35:49 +0100
+Subject: [PATCH 10/22] s390x/cpumodel: Set up CPU model for AQIC interception
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20190918143549.16340-3-thuth@redhat.com>
+Patchwork-id: 90760
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/2] s390x/cpumodel: Set up CPU model for AQIC interception
+Bugzilla: 1660909
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
+
+From: Pierre Morel <pmorel@linux.ibm.com>
+
+Let's add support for the AP-Queue interruption facility to the CPU
+model.
+
+The S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL, CPU facility indicates
+whether the PQAP instruction with the AQIC command is available
+to the guest.
+This feature will be enabled only if the AP instructions are
+available on the linux host and AQIC facility is installed on
+the host.
+
+This feature must be turned on from userspace to intercept AP
+instructions on the KVM guest. The QEMU command line to turn
+this feature on looks something like this:
+
+    qemu-system-s390x ... -cpu xxx,apqi=on ...
+or
+    ... -cpu host
+
+Right now AP pass-through devices do not support migration,
+which means that we do not have to take care of migrating
+the interrupt data:
+virsh migrate apguest --live qemu+ssh://root@target.lan/system
+error: Requested operation is not valid: domain has assigned non-USB host devices
+
+Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
+Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+[rebase to newest qemu and fixup description]
+Message-Id: <20190705153249.12525-1-borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 9ef2d19e5f5dfdebc9877c77951c28f25c74e000)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu_features_def.inc.h | 1 +
+ target/s390x/cpu_models.c           | 1 +
+ target/s390x/gen-features.c         | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/target/s390x/cpu_features_def.inc.h b/target/s390x/cpu_features_def.inc.h
+index 011ce4d..dead061 100644
+--- a/target/s390x/cpu_features_def.inc.h
++++ b/target/s390x/cpu_features_def.inc.h
+@@ -77,6 +77,7 @@ DEF_FEAT(SEMAPHORE_ASSIST, "sema", STFL, 59, "Semaphore-assist facility")
+ DEF_FEAT(TIME_SLICE_INSTRUMENTATION, "tsi", STFL, 60, "Time-slice Instrumentation facility")
+ DEF_FEAT(MISC_INSTRUCTION_EXT3, "minste3", STFL, 61, "Miscellaneous-Instruction-Extensions Facility 3")
+ DEF_FEAT(RUNTIME_INSTRUMENTATION, "ri", STFL, 64, "CPU runtime-instrumentation facility")
++DEF_FEAT(AP_QUEUE_INTERRUPT_CONTROL, "apqi", STFL, 65, "AP-Queue interruption facility")
+ DEF_FEAT(ZPCI, "zpci", STFL, 69, "z/PCI facility")
+ DEF_FEAT(ADAPTER_EVENT_NOTIFICATION, "aen", STFL, 71, "General-purpose-adapter-event-notification facility")
+ DEF_FEAT(ADAPTER_INT_SUPPRESSION, "ais", STFL, 72, "General-purpose-adapter-interruption-suppression facility")
+diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
+index 91afc6b..f16ef64 100644
+--- a/target/s390x/cpu_models.c
++++ b/target/s390x/cpu_models.c
+@@ -792,6 +792,7 @@ static void check_consistency(const S390CPUModel *model)
+         { S390_FEAT_PTFF_QTOUE, S390_FEAT_MULTIPLE_EPOCH },
+         { S390_FEAT_PTFF_STOE, S390_FEAT_MULTIPLE_EPOCH },
+         { S390_FEAT_PTFF_STOUE, S390_FEAT_MULTIPLE_EPOCH },
++        { S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL, S390_FEAT_AP },
+     };
+     int i;
+ 
+diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
+index 24d78e9..17bb04e 100644
+--- a/target/s390x/gen-features.c
++++ b/target/s390x/gen-features.c
+@@ -519,6 +519,7 @@ static uint16_t full_GEN12_GA1[] = {
+     S390_FEAT_EDAT_2,
+     S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
+     S390_FEAT_AP_QUERY_CONFIG_INFO,
++    S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL,
+     S390_FEAT_AP_FACILITIES_TEST,
+     S390_FEAT_AP,
+ };
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390x-vfio-ap-Implement-hot-plug-unplug-of-vfio-ap-d.patch b/SOURCES/kvm-s390x-vfio-ap-Implement-hot-plug-unplug-of-vfio-ap-d.patch
new file mode 100644
index 0000000..af41a46
--- /dev/null
+++ b/SOURCES/kvm-s390x-vfio-ap-Implement-hot-plug-unplug-of-vfio-ap-d.patch
@@ -0,0 +1,153 @@
+From e855a53f491f73e05e2b6542fb556ad80d45f89e Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Thu, 17 Oct 2019 08:43:01 +0100
+Subject: [PATCH 21/21] s390x/vfio-ap: Implement hot plug/unplug of vfio-ap
+ device
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20191017084301.8658-2-thuth@redhat.com>
+Patchwork-id: 91819
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/1] s390x/vfio-ap: Implement hot plug/unplug of vfio-ap device
+Bugzilla: 1660906
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+
+From: Tony Krowiak <akrowiak@linux.ibm.com>
+
+Introduces hot plug/unplug support for the vfio-ap device.
+
+To hot plug a vfio-ap device using the QEMU device_add command:
+
+	(qemu) device_add vfio-ap,sysfsdev=$path-to-mdev
+
+	Where $path-to-mdev is the absolute path to the mediated matrix device
+	to which AP resources to be used by the guest have been assigned.
+
+A vfio-ap device can be hot plugged only if:
+
+1. A vfio-ap device has not been attached to the virtual machine's ap-bus
+   via the QEMU command line or a prior hot plug action.
+
+2. The guest was started with the CPU model feature for AP enabled
+   (e.g., -cpu host,ap=on)
+
+To hot unplug a vfio-ap device using the QEMU device_del command:
+
+	(qemu) device_del vfio-ap,sysfsdev=$path-to-mdev
+
+	Where $path-to-mdev is the absolute path to the mediated matrix device
+	specified when the vfio-ap device was attached to the virtual machine's
+	ap-bus.
+
+A vfio-ap device can be hot unplugged only if:
+
+1. A vfio-ap device has been attached to the virtual machine's ap-bus
+   via the QEMU command line or a prior hot plug action.
+
+2. The guest was started with the CPU model feature for AP enabled
+   (e.g., -cpu host,ap=on)
+
+Please note that a hot plug handler is not necessary for the vfio-ap device
+because the AP matrix configuration for the guest is performed by the
+kernel device driver when the vfio-ap device is realized. The vfio-ap device
+represents a VFIO mediated device created in the host sysfs for use by a guest.
+The mdev device is configured with an AP matrix (i.e., adapters and domains) via
+its sysfs attribute interfaces prior to starting the guest or plugging a vfio-ap
+device in. When the device is realized, a file descriptor is opened on the mdev
+device which results in a callback to the vfio_ap kernel device driver. The
+device driver then configures the AP matrix in the guest's SIE state description
+from the AP matrix assigned via the mdev device's sysfs interfaces. The AP
+devices will be created for the guest when the AP bus running on the guest
+subsequently performs its periodic scan for AP devices.
+
+The qdev_simple_device_unplug_cb() callback function is used for the same
+reaons; namely, the vfio_ap kernel device driver will perform the AP resource
+de-configuration for the guest when the vfio-ap device is unplugged. When the
+vfio-ap device is unrealized, the mdev device file descriptor is closed which
+results in a callback to the vfio_ap kernel device driver. The device driver
+then clears the AP matrix configuration in the guest's SIE state description
+and resets all of the affected queues. The AP devices created for the guest
+will be removed when the AP bus running on the guest subsequently performs
+its periodic scan and finds there are no longer any AP resources assigned to the
+guest.
+
+Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com>
+Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
+Tested-by: Pierre Morel <pmorel@linux.ibm.com>
+Message-Id: <1550519397-25359-2-git-send-email-akrowiak@linux.ibm.com>
+[CH: adapt to changed qbus_set_hotplug_handler() signature]
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 374b78e37029b05f7ee2f40d0d0aabf5b5b03ce0)
+
+Changed the qbus_set_hotplug_handler() line for RHEL: We do no have
+commit 94d1cc5f03a in downstream, so no need for the OBJECT() cast here.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ap-bridge.c | 12 +++++++++++-
+ hw/vfio/ap.c         |  2 +-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/hw/s390x/ap-bridge.c b/hw/s390x/ap-bridge.c
+index 3795d30..25a0341 100644
+--- a/hw/s390x/ap-bridge.c
++++ b/hw/s390x/ap-bridge.c
+@@ -39,6 +39,7 @@ static const TypeInfo ap_bus_info = {
+ void s390_init_ap(void)
+ {
+     DeviceState *dev;
++    BusState *bus;
+ 
+     /* If no AP instructions then no need for AP bridge */
+     if (!s390_has_feat(S390_FEAT_AP)) {
+@@ -52,13 +53,18 @@ void s390_init_ap(void)
+     qdev_init_nofail(dev);
+ 
+     /* Create bus on bridge device */
+-    qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS);
++    bus = qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS);
++
++    /* Enable hotplugging */
++    qbus_set_hotplug_handler(bus, dev, &error_abort);
+  }
+ 
+ static void ap_bridge_class_init(ObjectClass *oc, void *data)
+ {
+     DeviceClass *dc = DEVICE_CLASS(oc);
++    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ 
++    hc->unplug = qdev_simple_device_unplug_cb;
+     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+ }
+ 
+@@ -67,6 +73,10 @@ static const TypeInfo ap_bridge_info = {
+     .parent        = TYPE_SYS_BUS_DEVICE,
+     .instance_size = 0,
+     .class_init    = ap_bridge_class_init,
++    .interfaces = (InterfaceInfo[]) {
++        { TYPE_HOTPLUG_HANDLER },
++        { }
++    }
+ };
+ 
+ static void ap_register(void)
+diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
+index 3962bb7..a899f8e 100644
+--- a/hw/vfio/ap.c
++++ b/hw/vfio/ap.c
+@@ -161,7 +161,7 @@ static void vfio_ap_class_init(ObjectClass *klass, void *data)
+     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+     dc->realize = vfio_ap_realize;
+     dc->unrealize = vfio_ap_unrealize;
+-    dc->hotpluggable = false;
++    dc->hotpluggable = true;
+     dc->reset = vfio_ap_reset;
+     dc->bus_type = TYPE_AP_BUS;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-slirp-disable-tcp_emu.patch b/SOURCES/kvm-slirp-disable-tcp_emu.patch
new file mode 100644
index 0000000..aa807b1
--- /dev/null
+++ b/SOURCES/kvm-slirp-disable-tcp_emu.patch
@@ -0,0 +1,70 @@
+From 3bb5804776e5141690ff6fbb5b07b2a0307391ee Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Tue, 28 Jan 2020 13:32:53 +0000
+Subject: [PATCH 1/2] slirp: disable tcp_emu()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20200128133253.794107-2-marcandre.lureau@redhat.com>
+Patchwork-id: 93569
+O-Subject: [RHEL-8.2.0 qemu-kvm + RHEL-7.7 qemu-kvm + RHEL-6.11 qemu-kvm PATCH 1/1] slirp: disable tcp_emu()
+Bugzilla: 1791677
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+Since libslirp 4.1, tcp_emu() is disabled by default because it is
+known to cause several CVEs and is not useful today in most
+cases. Qemu upstream doesn't have an option to enable it back at this
+point, it's not clear if we ever want to expose that option anyway.
+
+See also upstream commit 07c2a44b67e ("emu: disable by default")
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1791677
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ slirp/tcp_subr.c | 4 ++--
+ slirp/udp.c      | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
+index b95ba23..ac14366 100644
+--- a/slirp/tcp_subr.c
++++ b/slirp/tcp_subr.c
+@@ -568,7 +568,7 @@ tcp_tos(struct socket *so)
+ 	while(tcptos[i].tos) {
+ 		if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) ||
+ 		    (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) {
+-			so->so_emu = tcptos[i].emu;
++			so->so_emu = 0; /* disabled */
+ 			return tcptos[i].tos;
+ 		}
+ 		i++;
+@@ -578,7 +578,7 @@ tcp_tos(struct socket *so)
+ 	for (emup = tcpemu; emup; emup = emup->next) {
+ 		if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) ||
+ 		    (emup->lport && (ntohs(so->so_lport) == emup->lport))) {
+-			so->so_emu = emup->emu;
++			so->so_emu = 0; /* disabled */
+ 			return emup->tos;
+ 		}
+ 	}
+diff --git a/slirp/udp.c b/slirp/udp.c
+index 227d779..f5f5548 100644
+--- a/slirp/udp.c
++++ b/slirp/udp.c
+@@ -313,7 +313,7 @@ udp_tos(struct socket *so)
+ 	while(udptos[i].tos) {
+ 		if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) ||
+ 		    (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) {
+-		    	so->so_emu = udptos[i].emu;
++			so->so_emu = 0; /* disabled */
+ 			return udptos[i].tos;
+ 		}
+ 		i++;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch b/SOURCES/kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch
index c0f0dd7..01a32e2 100644
--- a/SOURCES/kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch
+++ b/SOURCES/kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch
@@ -1,7 +1,7 @@
-From 25ac3224ae8ffe35efdd6bfc5db289e469dc6864 Mon Sep 17 00:00:00 2001
+From 64f43842f5685d5b1290d4a1bf4eba8e1e738a8d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
-Date: Fri, 17 Jan 2020 11:49:41 +0000
-Subject: [PATCH 2/5] slirp: use correct size while emulating IRC commands
+Date: Fri, 17 Jan 2020 11:49:41 +0100
+Subject: [PATCH 6/7] slirp: use correct size while emulating IRC commands
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
@@ -10,10 +10,10 @@ RH-Author: Philippe Mathieu-Daudé <philmd@redhat.com>
 Message-id: <20200117114942.12236-3-philmd@redhat.com>
 Patchwork-id: 93392
 O-Subject: [RHEL-7.7.z qemu-kvm-rhev + RHEL-7.8 qemu-kvm-rhev + RHEL-7.9 qemu-kvm-rhev + RHEL-8.1.0 qemu-kvm + RHEL-8.2.0 qemu-kvm + RHEL-7.7.z qemu-kvm-ma + RHEL-7.8 qemu-kvm-ma + RHEL-7.9 qemu-kvm-ma PATCH 2/3] slirp: use correct size while emulating IRC commands
-Bugzilla: 1791565
-RH-Acked-by: Thomas Huth <thuth@redhat.com>
-RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+Bugzilla: 1791566
 RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
 
 From: Prasad J Pandit <pjp@fedoraproject.org>
 
@@ -30,7 +30,7 @@ Message-Id: <20200109094228.79764-2-ppandit@redhat.com>
 (cherry picked from libslirp commit ce131029d6d4a405cb7d3ac6716d03e58fb4a5d9)
 Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
 
-Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
 ---
  slirp/tcp_subr.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/SOURCES/kvm-slirp-use-correct-size-while-emulating-commands.patch b/SOURCES/kvm-slirp-use-correct-size-while-emulating-commands.patch
index 5372146..58aba08 100644
--- a/SOURCES/kvm-slirp-use-correct-size-while-emulating-commands.patch
+++ b/SOURCES/kvm-slirp-use-correct-size-while-emulating-commands.patch
@@ -1,7 +1,7 @@
-From 149a200018dd40ec0f1c494c959a3c03ea60c897 Mon Sep 17 00:00:00 2001
+From cfba2381aaea94b4be5f36ea7b95d42f1c283982 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
-Date: Fri, 17 Jan 2020 11:49:42 +0000
-Subject: [PATCH 3/5] slirp: use correct size while emulating commands
+Date: Fri, 17 Jan 2020 11:49:42 +0100
+Subject: [PATCH 7/7] slirp: use correct size while emulating commands
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
@@ -10,10 +10,10 @@ RH-Author: Philippe Mathieu-Daudé <philmd@redhat.com>
 Message-id: <20200117114942.12236-4-philmd@redhat.com>
 Patchwork-id: 93391
 O-Subject: [RHEL-7.7.z qemu-kvm-rhev + RHEL-7.8 qemu-kvm-rhev + RHEL-7.9 qemu-kvm-rhev + RHEL-8.1.0 qemu-kvm + RHEL-8.2.0 qemu-kvm + RHEL-7.7.z qemu-kvm-ma + RHEL-7.8 qemu-kvm-ma + RHEL-7.9 qemu-kvm-ma PATCH 3/3] slirp: use correct size while emulating commands
-Bugzilla: 1791565
-RH-Acked-by: Thomas Huth <thuth@redhat.com>
-RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+Bugzilla: 1791566
 RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
 
 From: Prasad J Pandit <pjp@fedoraproject.org>
 
@@ -27,7 +27,7 @@ Message-Id: <20200109094228.79764-3-ppandit@redhat.com>
 (cherry picked from libslirp commit 82ebe9c370a0e2970fb5695aa19aa5214a6a1c80)
 Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
 
-Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
 ---
  slirp/tcp_subr.c | 8 ++++----
  1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/SOURCES/kvm-support-overcommit-cpu-pm-on-off.patch b/SOURCES/kvm-support-overcommit-cpu-pm-on-off.patch
new file mode 100644
index 0000000..3da6e68
--- /dev/null
+++ b/SOURCES/kvm-support-overcommit-cpu-pm-on-off.patch
@@ -0,0 +1,181 @@
+From 1cfbcbeebc6d9ca1f1f7656fff572bf6ac50de76 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 26 Nov 2019 19:36:52 +0000
+Subject: [PATCH 08/11] kvm: support -overcommit cpu-pm=on|off
+
+RH-Author: plai@redhat.com
+Message-id: <1574797015-32564-5-git-send-email-plai@redhat.com>
+Patchwork-id: 92697
+O-Subject: [RHEL8.2 qemu-kvm PATCH 4/7] kvm: support -overcommit cpu-pm=on|off
+Bugzilla: 1634827
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+With this flag, kvm allows guest to control host CPU power state.  This
+increases latency for other processes using same host CPU in an
+unpredictable way, but if decreases idle entry/exit times for the
+running VCPU, so to use it QEMU needs a hint about whether host CPU is
+overcommitted, hence the flag name.
+
+Follow-up patches will expose this capability to guest
+(using mwait leaf).
+
+Based on a patch by Wanpeng Li <kernellwp@gmail.com> .
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20180622192148.178309-2-mst@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 6f131f13e68d648a8e4f083c667ab1acd88ce4cd)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ include/sysemu/sysemu.h |  1 +
+ qemu-options.hx         | 24 ++++++++++++++++++++++++
+ target/i386/kvm.c       | 23 +++++++++++++++++++++++
+ vl.c                    | 32 +++++++++++++++++++++++++++++++-
+ 4 files changed, 79 insertions(+), 1 deletion(-)
+
+diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
+index f20e4f5..f38fad0 100644
+--- a/include/sysemu/sysemu.h
++++ b/include/sysemu/sysemu.h
+@@ -131,6 +131,7 @@ extern bool boot_strict;
+ extern uint8_t *boot_splash_filedata;
+ extern size_t boot_splash_filedata_size;
+ extern bool enable_mlock;
++extern bool enable_cpu_pm;
+ extern uint8_t qemu_extra_params_fw[2];
+ extern QEMUClockType rtc_clock;
+ extern const char *mem_path;
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 1243057..99933a0 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -3331,6 +3331,30 @@ mlocking qemu-kvm and guest memory can be enabled via @option{mlock=on}
+ (enabled by default).
+ ETEXI
+ 
++DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
++    "--overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
++    "                run qemu with overcommit hints\n"
++    "                mem-lock=on|off controls memory lock support (default: off)\n"
++    "                cpu-pm=on|off controls cpu power management (default: off)\n",
++    QEMU_ARCH_ALL)
++STEXI
++@item -overcommit mem-lock=on|off
++@item -overcommit cpu-pm=on|off
++@findex -overcommit
++Run qemu with hints about host resource overcommit. The default is
++to assume that host overcommits all resources.
++
++Locking qemu and guest memory can be enabled via @option{mem-lock=on} (disabled
++by default).  This works when host memory is not overcommitted and reduces the
++worst-case latency for guest.  This is equivalent to @option{realtime}.
++
++Guest ability to manage power state of host cpus (increasing latency for other
++processes on the same host cpu, but decreasing latency for guest) can be
++enabled via @option{cpu-pm=on} (disabled by default).  This works best when
++host CPU is not overcommitted. When used, host estimates of CPU cycle and power
++utilization will be incorrect, not taking into account guest idle time.
++ETEXI
++
+ DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
+     "-gdb dev        wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
+ STEXI
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 107c53b..879c3e0 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -1606,6 +1606,29 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+         smram_machine_done.notify = register_smram_listener;
+         qemu_add_machine_init_done_notifier(&smram_machine_done);
+     }
++
++    if (enable_cpu_pm) {
++        int disable_exits = kvm_check_extension(s, KVM_CAP_X86_DISABLE_EXITS);
++        int ret;
++
++/* Work around for kernel header with a typo. TODO: fix header and drop. */
++#if defined(KVM_X86_DISABLE_EXITS_HTL) && !defined(KVM_X86_DISABLE_EXITS_HLT)
++#define KVM_X86_DISABLE_EXITS_HLT KVM_X86_DISABLE_EXITS_HTL
++#endif
++        if (disable_exits) {
++            disable_exits &= (KVM_X86_DISABLE_EXITS_MWAIT |
++                              KVM_X86_DISABLE_EXITS_HLT |
++                              KVM_X86_DISABLE_EXITS_PAUSE);
++        }
++
++        ret = kvm_vm_enable_cap(s, KVM_CAP_X86_DISABLE_EXITS, 0,
++                                disable_exits);
++        if (ret < 0) {
++            error_report("kvm: guest stopping CPU not supported: %s",
++                         strerror(-ret));
++        }
++    }
++
+     return 0;
+ }
+ 
+diff --git a/vl.c b/vl.c
+index 932c1cf..aa08ab5 100644
+--- a/vl.c
++++ b/vl.c
+@@ -150,6 +150,7 @@ ram_addr_t ram_size;
+ const char *mem_path = NULL;
+ int mem_prealloc = 0; /* force preallocation of physical target memory */
+ bool enable_mlock = false;
++bool enable_cpu_pm = false;
+ int nb_nics;
+ NICInfo nd_table[MAX_NICS];
+ int autostart;
+@@ -428,6 +429,22 @@ static QemuOptsList qemu_realtime_opts = {
+     },
+ };
+ 
++static QemuOptsList qemu_overcommit_opts = {
++    .name = "overcommit",
++    .head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
++    .desc = {
++        {
++            .name = "mem-lock",
++            .type = QEMU_OPT_BOOL,
++        },
++        {
++            .name = "cpu-pm",
++            .type = QEMU_OPT_BOOL,
++        },
++        { /* end of list */ }
++    },
++};
++
+ static QemuOptsList qemu_msg_opts = {
+     .name = "msg",
+     .head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
+@@ -4089,7 +4106,20 @@ int main(int argc, char **argv, char **envp)
+                 if (!opts) {
+                     exit(1);
+                 }
+-                enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
++                /* Don't override the -overcommit option if set */
++                enable_mlock = enable_mlock ||
++                    qemu_opt_get_bool(opts, "mlock", true);
++                break;
++            case QEMU_OPTION_overcommit:
++                opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
++                                               optarg, false);
++                if (!opts) {
++                    exit(1);
++                }
++                /* Don't override the -realtime option if set */
++                enable_mlock = enable_mlock ||
++                    qemu_opt_get_bool(opts, "mem-lock", false);
++                enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
+                 break;
+             case QEMU_OPTION_msg:
+                 opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-Add-support-for-save-load-IA32_UMWAIT_CO.patch b/SOURCES/kvm-target-i386-Add-support-for-save-load-IA32_UMWAIT_CO.patch
new file mode 100644
index 0000000..da6cbe9
--- /dev/null
+++ b/SOURCES/kvm-target-i386-Add-support-for-save-load-IA32_UMWAIT_CO.patch
@@ -0,0 +1,147 @@
+From 9c3757a2d7302918456da459a8d188bb41299891 Mon Sep 17 00:00:00 2001
+From: Tao Xu <tao3.xu@intel.com>
+Date: Fri, 11 Oct 2019 15:41:03 +0800
+Subject: [PATCH 11/11] target/i386: Add support for save/load
+ IA32_UMWAIT_CONTROL MSR
+
+RH-Author: plai@redhat.com
+Message-id: <1574797015-32564-8-git-send-email-plai@redhat.com>
+Patchwork-id: 92693
+O-Subject: [RHEL8.2 qemu-kvm PATCH 7/7] target/i386: Add support for save/load IA32_UMWAIT_CONTROL MSR
+Bugzilla: 1634827
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+UMWAIT and TPAUSE instructions use 32bits IA32_UMWAIT_CONTROL at MSR
+index E1H to determines the maximum time in TSC-quanta that the processor
+can reside in either C0.1 or C0.2.
+
+This patch is to Add support for save/load IA32_UMWAIT_CONTROL MSR in
+guest.
+
+Co-developed-by: Jingqi Liu <jingqi.liu@intel.com>
+Signed-off-by: Jingqi Liu <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191011074103.30393-3-tao3.xu@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.h     |  2 ++
+ target/i386/kvm.c     | 13 +++++++++++++
+ target/i386/machine.c | 20 ++++++++++++++++++++
+ 3 files changed, 35 insertions(+)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index fac98aa..ecbe4f0 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -461,6 +461,7 @@ typedef enum X86Seg {
+ 
+ #define MSR_IA32_BNDCFGS                0x00000d90
+ #define MSR_IA32_XSS                    0x00000da0
++#define MSR_IA32_UMWAIT_CONTROL         0xe1
+ 
+ #define MSR_IA32_VMX_BASIC              0x00000480
+ #define MSR_IA32_VMX_PINBASED_CTLS      0x00000481
+@@ -1510,6 +1511,7 @@ typedef struct CPUX86State {
+     uint16_t fpregs_format_vmstate;
+ 
+     uint64_t xss;
++    uint32_t umwait;
+ 
+     TPRAccess tpr_access_type;
+ } CPUX86State;
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 0fd5650..ad58bfb 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_umwait;
+ static bool has_msr_spec_ctrl;
+ static bool has_msr_tsx_ctrl;
+ static bool has_msr_virt_ssbd;
+@@ -1450,6 +1451,9 @@ static int kvm_get_supported_msrs(KVMState *s)
+             case MSR_IA32_XSS:
+                 has_msr_xss = true;
+                 break;
++            case MSR_IA32_UMWAIT_CONTROL:
++                has_msr_umwait = true;
++                break;
+             case HV_X64_MSR_CRASH_CTL:
+                 has_msr_hv_crash = true;
+                 break;
+@@ -2134,6 +2138,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_umwait) {
++        kvm_msr_entry_add(cpu, MSR_IA32_UMWAIT_CONTROL, env->umwait);
++    }
+     if (has_msr_spec_ctrl) {
+         kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, env->spec_ctrl);
+     }
+@@ -2533,6 +2540,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+     if (has_msr_xss) {
+         kvm_msr_entry_add(cpu, MSR_IA32_XSS, 0);
+     }
++    if (has_msr_umwait) {
++        kvm_msr_entry_add(cpu, MSR_IA32_UMWAIT_CONTROL, 0);
++    }
+     if (has_msr_spec_ctrl) {
+         kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, 0);
+     }
+@@ -2780,6 +2790,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+         case MSR_IA32_XSS:
+             env->xss = msrs[i].data;
+             break;
++        case MSR_IA32_UMWAIT_CONTROL:
++            env->umwait = msrs[i].data;
++            break;
+         default:
+             if (msrs[i].index >= MSR_MC0_CTL &&
+                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
+diff --git a/target/i386/machine.c b/target/i386/machine.c
+index 76b173c..960cb51 100644
+--- a/target/i386/machine.c
++++ b/target/i386/machine.c
+@@ -894,6 +894,25 @@ static const VMStateDescription vmstate_xss = {
+     }
+ };
+ 
++static bool umwait_needed(void *opaque)
++{
++    X86CPU *cpu = opaque;
++    CPUX86State *env = &cpu->env;
++
++    return env->umwait != 0;
++}
++
++static const VMStateDescription vmstate_umwait = {
++    .name = "cpu/umwait",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .needed = umwait_needed,
++    .fields = (VMStateField[]) {
++        VMSTATE_UINT32(env.umwait, X86CPU),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
+ #ifdef TARGET_X86_64
+ static bool pkru_needed(void *opaque)
+ {
+@@ -1360,6 +1379,7 @@ VMStateDescription vmstate_x86_cpu = {
+         &vmstate_msr_hyperv_stimer,
+         &vmstate_avx512,
+         &vmstate_xss,
++        &vmstate_umwait,
+         &vmstate_tsc_khz,
+         &vmstate_msr_smi_count,
+ #ifdef TARGET_X86_64
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-Export-TAA_NO-bit-to-guests.patch b/SOURCES/kvm-target-i386-Export-TAA_NO-bit-to-guests.patch
index f40021e..e3eaa99 100644
--- a/SOURCES/kvm-target-i386-Export-TAA_NO-bit-to-guests.patch
+++ b/SOURCES/kvm-target-i386-Export-TAA_NO-bit-to-guests.patch
@@ -1,13 +1,13 @@
-From 89c4aa9839e314a3ed45b377c8fb9a3b3fd78147 Mon Sep 17 00:00:00 2001
+From 3048f38859988e7b6d63099350769ecb9ac0e76f Mon Sep 17 00:00:00 2001
 From: Eduardo Habkost <ehabkost@redhat.com>
-Date: Tue, 3 Dec 2019 22:51:40 +0000
+Date: Tue, 3 Dec 2019 23:53:07 +0000
 Subject: [PATCH 1/2] target/i386: Export TAA_NO bit to guests
 
 RH-Author: Eduardo Habkost <ehabkost@redhat.com>
-Message-id: <20191203225141.501191-2-ehabkost@redhat.com>
-Patchwork-id: 92842
-O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 1/2] target/i386: Export TAA_NO bit to guests
-Bugzilla: 1771970
+Message-id: <20191203235308.590845-2-ehabkost@redhat.com>
+Patchwork-id: 92851
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/2] target/i386: Export TAA_NO bit to guests
+Bugzilla: 1771971
 RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
 RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
 RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
@@ -31,10 +31,10 @@ Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/target/i386/cpu.c b/target/i386/cpu.c
-index c8f50a7..7baa5d2 100644
+index 3effcf3..68fe865 100644
 --- a/target/i386/cpu.c
 +++ b/target/i386/cpu.c
-@@ -1148,7 +1148,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+@@ -1144,7 +1144,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
          .feat_names = {
              "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
              "ssb-no", "mds-no", NULL, NULL,
diff --git a/SOURCES/kvm-target-i386-add-VMX-definitions.patch b/SOURCES/kvm-target-i386-add-VMX-definitions.patch
new file mode 100644
index 0000000..3d70b4d
--- /dev/null
+++ b/SOURCES/kvm-target-i386-add-VMX-definitions.patch
@@ -0,0 +1,177 @@
+From 968d0586936c356ca19f6f3b659ab094a2825374 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:42 +0000
+Subject: [PATCH 09/16] target/i386: add VMX definitions
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-10-pbonzini@redhat.com>
+Patchwork-id: 92604
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 09/15] target/i386: add VMX definitions
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+These will be used to compile the list of VMX features for named
+CPU models, and/or by the code that sets up the VMX MSRs.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 704798add83be4ac868ffcb495480065fb665794)
+
+RHEL: context
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.h | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 130 insertions(+)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index edba84e..2d1f247 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -459,6 +459,25 @@ typedef enum X86Seg {
+ #define MSR_IA32_BNDCFGS                0x00000d90
+ #define MSR_IA32_XSS                    0x00000da0
+ 
++#define MSR_IA32_VMX_BASIC              0x00000480
++#define MSR_IA32_VMX_PINBASED_CTLS      0x00000481
++#define MSR_IA32_VMX_PROCBASED_CTLS     0x00000482
++#define MSR_IA32_VMX_EXIT_CTLS          0x00000483
++#define MSR_IA32_VMX_ENTRY_CTLS         0x00000484
++#define MSR_IA32_VMX_MISC               0x00000485
++#define MSR_IA32_VMX_CR0_FIXED0         0x00000486
++#define MSR_IA32_VMX_CR0_FIXED1         0x00000487
++#define MSR_IA32_VMX_CR4_FIXED0         0x00000488
++#define MSR_IA32_VMX_CR4_FIXED1         0x00000489
++#define MSR_IA32_VMX_VMCS_ENUM          0x0000048a
++#define MSR_IA32_VMX_PROCBASED_CTLS2    0x0000048b
++#define MSR_IA32_VMX_EPT_VPID_CAP       0x0000048c
++#define MSR_IA32_VMX_TRUE_PINBASED_CTLS  0x0000048d
++#define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048e
++#define MSR_IA32_VMX_TRUE_EXIT_CTLS      0x0000048f
++#define MSR_IA32_VMX_TRUE_ENTRY_CTLS     0x00000490
++#define MSR_IA32_VMX_VMFUNC             0x00000491
++
+ #define XSTATE_FP_BIT                   0
+ #define XSTATE_SSE_BIT                  1
+ #define XSTATE_YMM_BIT                  2
+@@ -749,6 +768,117 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ 
+ #define MSR_CORE_CAP_SPLIT_LOCK_DETECT  (1U << 5)
+ 
++/* VMX MSR features */
++#define MSR_VMX_BASIC_VMCS_REVISION_MASK             0x7FFFFFFFull
++#define MSR_VMX_BASIC_VMXON_REGION_SIZE_MASK         (0x00001FFFull << 32)
++#define MSR_VMX_BASIC_VMCS_MEM_TYPE_MASK             (0x003C0000ull << 32)
++#define MSR_VMX_BASIC_DUAL_MONITOR                   (1ULL << 49)
++#define MSR_VMX_BASIC_INS_OUTS                       (1ULL << 54)
++#define MSR_VMX_BASIC_TRUE_CTLS                      (1ULL << 55)
++
++#define MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK     0x1Full
++#define MSR_VMX_MISC_STORE_LMA                       (1ULL << 5)
++#define MSR_VMX_MISC_ACTIVITY_HLT                    (1ULL << 6)
++#define MSR_VMX_MISC_ACTIVITY_SHUTDOWN               (1ULL << 7)
++#define MSR_VMX_MISC_ACTIVITY_WAIT_SIPI              (1ULL << 8)
++#define MSR_VMX_MISC_MAX_MSR_LIST_SIZE_MASK          0x0E000000ull
++#define MSR_VMX_MISC_VMWRITE_VMEXIT                  (1ULL << 29)
++#define MSR_VMX_MISC_ZERO_LEN_INJECT                 (1ULL << 30)
++
++#define MSR_VMX_EPT_EXECONLY                         (1ULL << 0)
++#define MSR_VMX_EPT_PAGE_WALK_LENGTH_4               (1ULL << 6)
++#define MSR_VMX_EPT_PAGE_WALK_LENGTH_5               (1ULL << 7)
++#define MSR_VMX_EPT_UC                               (1ULL << 8)
++#define MSR_VMX_EPT_WB                               (1ULL << 14)
++#define MSR_VMX_EPT_2MB                              (1ULL << 16)
++#define MSR_VMX_EPT_1GB                              (1ULL << 17)
++#define MSR_VMX_EPT_INVEPT                           (1ULL << 20)
++#define MSR_VMX_EPT_AD_BITS                          (1ULL << 21)
++#define MSR_VMX_EPT_ADVANCED_VMEXIT_INFO             (1ULL << 22)
++#define MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT            (1ULL << 25)
++#define MSR_VMX_EPT_INVEPT_ALL_CONTEXT               (1ULL << 26)
++#define MSR_VMX_EPT_INVVPID                          (1ULL << 32)
++#define MSR_VMX_EPT_INVVPID_SINGLE_ADDR              (1ULL << 40)
++#define MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT           (1ULL << 41)
++#define MSR_VMX_EPT_INVVPID_ALL_CONTEXT              (1ULL << 42)
++#define MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS (1ULL << 43)
++
++#define MSR_VMX_VMFUNC_EPT_SWITCHING                 (1ULL << 0)
++
++
++/* VMX controls */
++#define VMX_CPU_BASED_VIRTUAL_INTR_PENDING          0x00000004
++#define VMX_CPU_BASED_USE_TSC_OFFSETING             0x00000008
++#define VMX_CPU_BASED_HLT_EXITING                   0x00000080
++#define VMX_CPU_BASED_INVLPG_EXITING                0x00000200
++#define VMX_CPU_BASED_MWAIT_EXITING                 0x00000400
++#define VMX_CPU_BASED_RDPMC_EXITING                 0x00000800
++#define VMX_CPU_BASED_RDTSC_EXITING                 0x00001000
++#define VMX_CPU_BASED_CR3_LOAD_EXITING              0x00008000
++#define VMX_CPU_BASED_CR3_STORE_EXITING             0x00010000
++#define VMX_CPU_BASED_CR8_LOAD_EXITING              0x00080000
++#define VMX_CPU_BASED_CR8_STORE_EXITING             0x00100000
++#define VMX_CPU_BASED_TPR_SHADOW                    0x00200000
++#define VMX_CPU_BASED_VIRTUAL_NMI_PENDING           0x00400000
++#define VMX_CPU_BASED_MOV_DR_EXITING                0x00800000
++#define VMX_CPU_BASED_UNCOND_IO_EXITING             0x01000000
++#define VMX_CPU_BASED_USE_IO_BITMAPS                0x02000000
++#define VMX_CPU_BASED_MONITOR_TRAP_FLAG             0x08000000
++#define VMX_CPU_BASED_USE_MSR_BITMAPS               0x10000000
++#define VMX_CPU_BASED_MONITOR_EXITING               0x20000000
++#define VMX_CPU_BASED_PAUSE_EXITING                 0x40000000
++#define VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS   0x80000000
++
++#define VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
++#define VMX_SECONDARY_EXEC_ENABLE_EPT               0x00000002
++#define VMX_SECONDARY_EXEC_DESC                     0x00000004
++#define VMX_SECONDARY_EXEC_RDTSCP                   0x00000008
++#define VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE   0x00000010
++#define VMX_SECONDARY_EXEC_ENABLE_VPID              0x00000020
++#define VMX_SECONDARY_EXEC_WBINVD_EXITING           0x00000040
++#define VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST       0x00000080
++#define VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT       0x00000100
++#define VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY    0x00000200
++#define VMX_SECONDARY_EXEC_PAUSE_LOOP_EXITING       0x00000400
++#define VMX_SECONDARY_EXEC_RDRAND_EXITING           0x00000800
++#define VMX_SECONDARY_EXEC_ENABLE_INVPCID           0x00001000
++#define VMX_SECONDARY_EXEC_ENABLE_VMFUNC            0x00002000
++#define VMX_SECONDARY_EXEC_SHADOW_VMCS              0x00004000
++#define VMX_SECONDARY_EXEC_ENCLS_EXITING            0x00008000
++#define VMX_SECONDARY_EXEC_RDSEED_EXITING           0x00010000
++#define VMX_SECONDARY_EXEC_ENABLE_PML               0x00020000
++#define VMX_SECONDARY_EXEC_XSAVES                   0x00100000
++
++#define VMX_PIN_BASED_EXT_INTR_MASK                 0x00000001
++#define VMX_PIN_BASED_NMI_EXITING                   0x00000008
++#define VMX_PIN_BASED_VIRTUAL_NMIS                  0x00000020
++#define VMX_PIN_BASED_VMX_PREEMPTION_TIMER          0x00000040
++#define VMX_PIN_BASED_POSTED_INTR                   0x00000080
++
++#define VMX_VM_EXIT_SAVE_DEBUG_CONTROLS             0x00000004
++#define VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE            0x00000200
++#define VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL      0x00001000
++#define VMX_VM_EXIT_ACK_INTR_ON_EXIT                0x00008000
++#define VMX_VM_EXIT_SAVE_IA32_PAT                   0x00040000
++#define VMX_VM_EXIT_LOAD_IA32_PAT                   0x00080000
++#define VMX_VM_EXIT_SAVE_IA32_EFER                  0x00100000
++#define VMX_VM_EXIT_LOAD_IA32_EFER                  0x00200000
++#define VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER       0x00400000
++#define VMX_VM_EXIT_CLEAR_BNDCFGS                   0x00800000
++#define VMX_VM_EXIT_PT_CONCEAL_PIP                  0x01000000
++#define VMX_VM_EXIT_CLEAR_IA32_RTIT_CTL             0x02000000
++
++#define VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS            0x00000004
++#define VMX_VM_ENTRY_IA32E_MODE                     0x00000200
++#define VMX_VM_ENTRY_SMM                            0x00000400
++#define VMX_VM_ENTRY_DEACT_DUAL_MONITOR             0x00000800
++#define VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL     0x00002000
++#define VMX_VM_ENTRY_LOAD_IA32_PAT                  0x00004000
++#define VMX_VM_ENTRY_LOAD_IA32_EFER                 0x00008000
++#define VMX_VM_ENTRY_LOAD_BNDCFGS                   0x00010000
++#define VMX_VM_ENTRY_PT_CONCEAL_PIP                 0x00020000
++#define VMX_VM_ENTRY_LOAD_IA32_RTIT_CTL             0x00040000
++
+ #ifndef HYPERV_SPINLOCK_NEVER_RETRY
+ #define HYPERV_SPINLOCK_NEVER_RETRY             0xFFFFFFFF
+ #endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-add-VMX-features-to-named-CPU-models-RHE.patch b/SOURCES/kvm-target-i386-add-VMX-features-to-named-CPU-models-RHE.patch
new file mode 100644
index 0000000..3d1cb0c
--- /dev/null
+++ b/SOURCES/kvm-target-i386-add-VMX-features-to-named-CPU-models-RHE.patch
@@ -0,0 +1,654 @@
+From 1163b93bcdbef8e11c276722014d39c3619dbd1b Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:48 +0000
+Subject: [PATCH 15/16] target/i386: add VMX features to named CPU models (RHEL
+ only)
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-16-pbonzini@redhat.com>
+Patchwork-id: 92614
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 15/15] target/i386: add VMX features to named CPU models (RHEL only)
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+Upstream has switched to versioned CPU models in order to provide the
+noTSX and IBRS variants.  In 2.12, VMX features have to be duplicated by
+hand.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 538 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 538 insertions(+)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 36c9252..3effcf3 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -2212,6 +2212,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)",
+     },
+@@ -2307,6 +2347,47 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_7_0_EDX_SPEC_CTRL,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST,
+         .xlevel = 0x80000008,
+         .model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)",
+     },
+@@ -2412,6 +2493,47 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)",
+     },
+@@ -2526,6 +2648,50 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)",
+     },
+@@ -2562,6 +2728,52 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Haswell, no TSX)",
+     },
+@@ -2600,6 +2812,52 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Haswell, no TSX, IBRS)",
+     },
+@@ -2722,6 +2980,52 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Haswell, IBRS)",
+     },
+@@ -2760,6 +3064,53 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Broadwell, no TSX)",
+     },
+@@ -2800,6 +3151,53 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Broadwell, no TSX, IBRS)",
+     },
+@@ -2925,6 +3323,53 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Broadwell, IBRS)",
+     },
+@@ -3062,6 +3507,51 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Skylake, IBRS)",
+     },
+@@ -3208,6 +3698,54 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon Processor (Skylake, IBRS)",
+     },
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-add-VMX-features-to-named-CPU-models.patch b/SOURCES/kvm-target-i386-add-VMX-features-to-named-CPU-models.patch
new file mode 100644
index 0000000..3ca0136
--- /dev/null
+++ b/SOURCES/kvm-target-i386-add-VMX-features-to-named-CPU-models.patch
@@ -0,0 +1,891 @@
+From a958a54a1072e201d209fd54e3fd0b55a331c5da Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:47 +0000
+Subject: [PATCH 14/16] target/i386: add VMX features to named CPU models
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-15-pbonzini@redhat.com>
+Patchwork-id: 92613
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 14/15] target/i386: add VMX features to named CPU models
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+This allows using "-cpu Haswell,+vmx", which we did not really want to
+support in QEMU but was produced by Libvirt when using the "host-model"
+CPU model.  Without this patch, no VMX feature is _actually_ supported
+(only the basic instruction set extensions are) and KVM fails to load
+in the guest.
+
+This was produced from the output of scripts/kvm/vmxcap using the following
+very ugly Python script:
+
+    bits = {
+            'INS/OUTS instruction information': ['FEAT_VMX_BASIC', 'MSR_VMX_BASIC_INS_OUTS'],
+            'IA32_VMX_TRUE_*_CTLS support': ['FEAT_VMX_BASIC', 'MSR_VMX_BASIC_TRUE_CTLS'],
+            'External interrupt exiting': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_EXT_INTR_MASK'],
+            'NMI exiting': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_NMI_EXITING'],
+            'Virtual NMIs': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_VIRTUAL_NMIS'],
+            'Activate VMX-preemption timer': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_VMX_PREEMPTION_TIMER'],
+            'Process posted interrupts': ['FEAT_VMX_PINBASED_CTLS', 'VMX_PIN_BASED_POSTED_INTR'],
+            'Interrupt window exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_VIRTUAL_INTR_PENDING'],
+            'Use TSC offsetting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_USE_TSC_OFFSETING'],
+            'HLT exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_HLT_EXITING'],
+            'INVLPG exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_INVLPG_EXITING'],
+            'MWAIT exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MWAIT_EXITING'],
+            'RDPMC exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_RDPMC_EXITING'],
+            'RDTSC exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_RDTSC_EXITING'],
+            'CR3-load exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR3_LOAD_EXITING'],
+            'CR3-store exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR3_STORE_EXITING'],
+            'CR8-load exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR8_LOAD_EXITING'],
+            'CR8-store exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_CR8_STORE_EXITING'],
+            'Use TPR shadow': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_TPR_SHADOW'],
+            'NMI-window exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_VIRTUAL_NMI_PENDING'],
+            'MOV-DR exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MOV_DR_EXITING'],
+            'Unconditional I/O exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_UNCOND_IO_EXITING'],
+            'Use I/O bitmaps': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_USE_IO_BITMAPS'],
+            'Monitor trap flag': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MONITOR_TRAP_FLAG'],
+            'Use MSR bitmaps': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_USE_MSR_BITMAPS'],
+            'MONITOR exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_MONITOR_EXITING'],
+            'PAUSE exiting': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_PAUSE_EXITING'],
+            'Activate secondary control': ['FEAT_VMX_PROCBASED_CTLS', 'VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS'],
+            'Virtualize APIC accesses': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES'],
+            'Enable EPT': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_EPT'],
+            'Descriptor-table exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_DESC'],
+            'Enable RDTSCP': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_RDTSCP'],
+            'Virtualize x2APIC mode': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE'],
+            'Enable VPID': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_VPID'],
+            'WBINVD exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_WBINVD_EXITING'],
+            'Unrestricted guest': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST'],
+            'APIC register emulation': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT'],
+            'Virtual interrupt delivery': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY'],
+            'PAUSE-loop exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_PAUSE_LOOP_EXITING'],
+            'RDRAND exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_RDRAND_EXITING'],
+            'Enable INVPCID': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_INVPCID'],
+            'Enable VM functions': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_VMFUNC'],
+            'VMCS shadowing': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_SHADOW_VMCS'],
+            'RDSEED exiting': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_RDSEED_EXITING'],
+            'Enable PML': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_ENABLE_PML'],
+            'Enable XSAVES/XRSTORS': ['FEAT_VMX_SECONDARY_CTLS', 'VMX_SECONDARY_EXEC_XSAVES'],
+            'Save debug controls': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_DEBUG_CONTROLS'],
+            'Load IA32_PERF_GLOBAL_CTRL': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL'],
+            'Acknowledge interrupt on exit': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_ACK_INTR_ON_EXIT'],
+            'Save IA32_PAT': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_IA32_PAT'],
+            'Load IA32_PAT': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_LOAD_IA32_PAT'],
+            'Save IA32_EFER': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_IA32_EFER'],
+            'Load IA32_EFER': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_LOAD_IA32_EFER'],
+            'Save VMX-preemption timer value': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER'],
+            'Clear IA32_BNDCFGS': ['FEAT_VMX_EXIT_CTLS', 'VMX_VM_EXIT_CLEAR_BNDCFGS'],
+            'Load debug controls': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS'],
+            'IA-32e mode guest': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_IA32E_MODE'],
+            'Load IA32_PERF_GLOBAL_CTRL': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL'],
+            'Load IA32_PAT': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_IA32_PAT'],
+            'Load IA32_EFER': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_IA32_EFER'],
+            'Load IA32_BNDCFGS': ['FEAT_VMX_ENTRY_CTLS', 'VMX_VM_ENTRY_LOAD_BNDCFGS'],
+            'Store EFER.LMA into IA-32e mode guest control': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_STORE_LMA'],
+            'HLT activity state': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_ACTIVITY_HLT'],
+            'VMWRITE to VM-exit information fields': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_VMWRITE_VMEXIT'],
+            'Inject event with insn length=0': ['FEAT_VMX_MISC', 'MSR_VMX_MISC_ZERO_LEN_INJECT'],
+            'Execute-only EPT translations': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_EXECONLY'],
+            'Page-walk length 4': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_PAGE_WALK_LENGTH_4'],
+            'Paging-structure memory type WB': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_WB'],
+            '2MB EPT pages': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB'],
+            'INVEPT supported': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVEPT'],
+            'EPT accessed and dirty flags': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_AD_BITS'],
+            'Single-context INVEPT': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT'],
+            'All-context INVEPT': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVEPT_ALL_CONTEXT'],
+            'INVVPID supported': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID'],
+            'Individual-address INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_SINGLE_ADDR'],
+            'Single-context INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT'],
+            'All-context INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_ALL_CONTEXT'],
+            'Single-context-retaining-globals INVVPID': ['FEAT_VMX_EPT_VPID_CAPS', 'MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS'],
+            'EPTP Switching': ['FEAT_VMX_VMFUNC', 'MSR_VMX_VMFUNC_EPT_SWITCHING']
+    }
+
+    import sys
+    import textwrap
+
+    out = {}
+    for l in sys.stdin.readlines():
+        l = l.rstrip()
+        if l.endswith('!!'):
+            l = l[:-2].rstrip()
+        if l.startswith('    ') and (l.endswith('default') or l.endswith('yes')):
+            l = l[4:]
+            for key, value in bits.items():
+                if l.startswith(key):
+                    ctl, bit = value
+                    if ctl in out:
+                        out[ctl] = out[ctl] + ' | '
+                    else:
+                        out[ctl] = '    [%s] = ' % ctl
+                    out[ctl] = out[ctl] + bit
+
+    for x in sorted(out.keys()):
+        print("\n         ".join(textwrap.wrap(out[x] + ",")))
+
+Note that the script has a bug in that some keys apply to both VM entry
+and VM exit controls ("load IA32_PERF_GLOBAL_CTRL", "load IA32_EFER",
+"load IA32_PAT".  Those have to be fixed by hand.
+
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 0723cc8a5558c94388db75ae1f4991314914edd3)
+
+RHEL: no Denverton and Snowridge
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 617 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 617 insertions(+)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 9074a2e..36c9252 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1689,6 +1689,34 @@ static CPUCaches epyc_cache_info = {
+     },
+ };
+ 
++/* The following VMX features are not supported by KVM and are left out in the
++ * CPU definitions:
++ *
++ *  Dual-monitor support (all processors)
++ *  Entry to SMM
++ *  Deactivate dual-monitor treatment
++ *  Number of CR3-target values
++ *  Shutdown activity state
++ *  Wait-for-SIPI activity state
++ *  PAUSE-loop exiting (Westmere and newer)
++ *  EPT-violation #VE (Broadwell and newer)
++ *  Inject event with insn length=0 (Skylake and newer)
++ *  Conceal non-root operation from PT
++ *  Conceal VM exits from PT
++ *  Conceal VM entries from PT
++ *  Enable ENCLS exiting
++ *  Mode-based execute control (XS/XU)
++ s  TSC scaling (Skylake Server and newer)
++ *  GPA translation for PT (IceLake and newer)
++ *  User wait and pause
++ *  ENCLV exiting
++ *  Load IA32_RTIT_CTL
++ *  Clear IA32_RTIT_CTL
++ *  Advanced VM-exit information for EPT violations
++ *  Sub-page write permissions
++ *  PT in VMX operation
++ */
++
+ static X86CPUDefinition builtin_x86_defs[] = {
+     {
+         /* qemu64 is the default CPU model for all *-rhel7.* machine-types.
+@@ -1769,6 +1797,24 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
++        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES,
+         .xlevel = 0x80000008,
+         .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
+     },
+@@ -1796,6 +1842,20 @@ static X86CPUDefinition builtin_x86_defs[] = {
+                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
+         .features[FEAT_8000_0001_ECX] =
+             0,
++        /* VMX features from Cedar Mill/Prescott */
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
++        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING,
+         .xlevel = 0x80000008,
+         .model_id = "Common KVM processor"
+     },
+@@ -1827,6 +1887,19 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT_SSE3,
+         .features[FEAT_8000_0001_ECX] =
+             0,
++        /* VMX features from Yonah */
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
++        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING |
++             VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING |
++             VMX_CPU_BASED_PAUSE_EXITING | VMX_CPU_BASED_USE_MSR_BITMAPS,
+         .xlevel = 0x80000008,
+         .model_id = "Common 32-bit KVM processor"
+     },
+@@ -1848,6 +1921,18 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
+         .features[FEAT_8000_0001_EDX] =
+             CPUID_EXT2_NX,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
++        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING |
++             VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING |
++             VMX_CPU_BASED_PAUSE_EXITING | VMX_CPU_BASED_USE_MSR_BITMAPS,
+         .xlevel = 0x80000008,
+         .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
+     },
+@@ -1977,6 +2062,24 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
++        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
+     },
+@@ -2000,6 +2103,27 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
++        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
+     },
+@@ -2023,6 +2147,46 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+         .features[FEAT_8000_0001_ECX] =
+             CPUID_EXT3_LAHF_LM,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
+     },
+@@ -2074,6 +2238,47 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_EXT3_LAHF_LM,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST,
+         .xlevel = 0x80000008,
+         .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
+     },
+@@ -2133,6 +2338,47 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon E312xx (Sandy Bridge)",
+     },
+@@ -2200,6 +2446,50 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
+     },
+@@ -2347,6 +2637,52 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Haswell)",
+     },
+@@ -2502,6 +2838,53 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XSAVEOPT,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Broadwell)",
+     },
+@@ -2587,6 +2970,51 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Skylake)",
+     },
+@@ -2682,6 +3110,54 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon Processor (Skylake)",
+     },
+@@ -2785,6 +3261,54 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon Processor (Cascadelake)",
+     },
+@@ -2840,6 +3364,51 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Core Processor (Icelake)",
+     },
+@@ -2898,6 +3467,54 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_XSAVE_XGETBV1,
+         .features[FEAT_6_EAX] =
+             CPUID_6_EAX_ARAT,
++        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
++        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
++             MSR_VMX_BASIC_TRUE_CTLS,
++        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
++             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
++             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
++        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
++             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
++             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
++             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
++             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
++        .features[FEAT_VMX_EXIT_CTLS] =
++             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
++             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
++             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
++             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
++             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
++        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
++             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
++        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
++             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
++             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
++        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
++             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
++             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
++             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
++             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
++             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
++             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
++             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
++             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
++             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
++             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
++             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
++        .features[FEAT_VMX_SECONDARY_CTLS] =
++             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
++             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
++             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
++             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
++             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
++             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
++             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
++             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
++             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
++             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
++        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
+         .xlevel = 0x80000008,
+         .model_id = "Intel Xeon Processor (Icelake)",
+     },
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-add-VMX-features.patch b/SOURCES/kvm-target-i386-add-VMX-features.patch
new file mode 100644
index 0000000..7bbb35a
--- /dev/null
+++ b/SOURCES/kvm-target-i386-add-VMX-features.patch
@@ -0,0 +1,503 @@
+From 88ab13cec526a16cb02bf1af51bdd33230308d36 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:44 +0000
+Subject: [PATCH 11/16] target/i386: add VMX features
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-12-pbonzini@redhat.com>
+Patchwork-id: 92608
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 11/15] target/i386: add VMX features
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+Add code to convert the VMX feature words back into MSR values,
+allowing the user to enable/disable VMX features as they wish.  The same
+infrastructure enables support for limiting VMX features in named
+CPU models.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 20a78b02d31534ae478779c2f2816c273601e869)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ target/i386/cpu.h |   9 +++
+ target/i386/kvm.c | 162 ++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 394 insertions(+), 2 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 3e77830..9074a2e 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1171,6 +1171,163 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             .index = MSR_IA32_CORE_CAPABILITY,
+         },
+     },
++
++    [FEAT_VMX_PROCBASED_CTLS] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            NULL, NULL, "vmx-vintr-pending", "vmx-tsc-offset",
++            NULL, NULL, NULL, "vmx-hlt-exit",
++            NULL, "vmx-invlpg-exit", "vmx-mwait-exit", "vmx-rdpmc-exit",
++            "vmx-rdtsc-exit", NULL, NULL, "vmx-cr3-load-noexit",
++            "vmx-cr3-store-noexit", NULL, NULL, "vmx-cr8-load-exit",
++            "vmx-cr8-store-exit", "vmx-flexpriority", "vmx-vnmi-pending", "vmx-movdr-exit",
++            "vmx-io-exit", "vmx-io-bitmap", NULL, "vmx-mtf",
++            "vmx-msr-bitmap", "vmx-monitor-exit", "vmx-pause-exit", "vmx-secondary-ctls",
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
++        }
++    },
++
++    [FEAT_VMX_SECONDARY_CTLS] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            "vmx-apicv-xapic", "vmx-ept", "vmx-desc-exit", "vmx-rdtscp-exit",
++            "vmx-apicv-x2apic", "vmx-vpid", "vmx-wbinvd-exit", "vmx-unrestricted-guest",
++            "vmx-apicv-register", "vmx-apicv-vid", "vmx-ple", "vmx-rdrand-exit",
++            "vmx-invpcid-exit", "vmx-vmfunc", "vmx-shadow-vmcs", "vmx-encls-exit",
++            "vmx-rdseed-exit", "vmx-pml", NULL, NULL,
++            "vmx-xsaves", NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_PROCBASED_CTLS2,
++        }
++    },
++
++    [FEAT_VMX_PINBASED_CTLS] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            "vmx-intr-exit", NULL, NULL, "vmx-nmi-exit",
++            NULL, "vmx-vnmi", "vmx-preemption-timer", "vmx-posted-intr",
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
++        }
++    },
++
++    [FEAT_VMX_EXIT_CTLS] = {
++        .type = MSR_FEATURE_WORD,
++        /*
++         * VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE is copied from
++         * the LM CPUID bit.
++         */
++        .feat_names = {
++            NULL, NULL, "vmx-exit-nosave-debugctl", NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL /* vmx-exit-host-addr-space-size */, NULL, NULL,
++            "vmx-exit-load-perf-global-ctrl", NULL, NULL, "vmx-exit-ack-intr",
++            NULL, NULL, "vmx-exit-save-pat", "vmx-exit-load-pat",
++            "vmx-exit-save-efer", "vmx-exit-load-efer",
++                "vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
++            NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
++        }
++    },
++
++    [FEAT_VMX_ENTRY_CTLS] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            NULL, NULL, "vmx-entry-noload-debugctl", NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, "vmx-entry-ia32e-mode", NULL, NULL,
++            NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer",
++            "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
++        }
++    },
++
++    [FEAT_VMX_MISC] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            NULL, NULL, NULL, NULL,
++            NULL, "vmx-store-lma", "vmx-activity-hlt", "vmx-activity-shutdown",
++            "vmx-activity-wait-sipi", NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, "vmx-vmwrite-vmexit-fields", "vmx-zero-len-inject", NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_MISC,
++        }
++    },
++
++    [FEAT_VMX_EPT_VPID_CAPS] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            "vmx-ept-execonly", NULL, NULL, NULL,
++            NULL, NULL, "vmx-page-walk-4", "vmx-page-walk-5",
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            "vmx-ept-2mb", "vmx-ept-1gb", NULL, NULL,
++            "vmx-invept", "vmx-eptad", "vmx-ept-advanced-exitinfo", NULL,
++            NULL, "vmx-invept-single-context", "vmx-invept-all-context", NULL,
++            NULL, NULL, NULL, NULL,
++            "vmx-invvpid", NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            "vmx-invvpid-single-addr", "vmx-invept-single-context",
++                "vmx-invvpid-all-context", "vmx-invept-single-context-noglobals",
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_EPT_VPID_CAP,
++        }
++    },
++
++    [FEAT_VMX_BASIC] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            [54] = "vmx-ins-outs",
++            [55] = "vmx-true-ctls",
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_BASIC,
++        },
++        /* Just to be safe - we don't support setting the MSEG version field.  */
++        .no_autoenable_flags = MSR_VMX_BASIC_DUAL_MONITOR,
++    },
++
++    [FEAT_VMX_VMFUNC] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            [0] = "vmx-eptp-switching",
++        },
++        .msr = {
++            .index = MSR_IA32_VMX_VMFUNC,
++        }
++    },
++
+ };
+ 
+ typedef struct FeatureMask {
+@@ -1191,6 +1348,74 @@ static FeatureDep feature_dependencies[] = {
+         .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_CORE_CAPABILITY },
+         .to = { FEAT_CORE_CAPABILITY,       ~0ull },
+     },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
++        .to = { FEAT_VMX_PROCBASED_CTLS,    ~0ull },
++    },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
++        .to = { FEAT_VMX_PINBASED_CTLS,     ~0ull },
++    },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
++        .to = { FEAT_VMX_EXIT_CTLS,         ~0ull },
++    },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
++        .to = { FEAT_VMX_ENTRY_CTLS,        ~0ull },
++    },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
++        .to = { FEAT_VMX_MISC,              ~0ull },
++    },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
++        .to = { FEAT_VMX_BASIC,             ~0ull },
++    },
++    {
++        .from = { FEAT_8000_0001_EDX,       CPUID_EXT2_LM },
++        .to = { FEAT_VMX_ENTRY_CTLS,        VMX_VM_ENTRY_IA32E_MODE },
++    },
++    {
++        .from = { FEAT_VMX_PROCBASED_CTLS,  VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    ~0ull },
++    },
++    {
++        .from = { FEAT_XSAVE,               CPUID_XSAVE_XSAVES },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_XSAVES },
++    },
++    {
++        .from = { FEAT_1_ECX,               CPUID_EXT_RDRAND },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_RDRAND_EXITING },
++    },
++    {
++        .from = { FEAT_7_0_EBX,             CPUID_7_0_EBX_INVPCID },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_ENABLE_INVPCID },
++    },
++    {
++        .from = { FEAT_7_0_EBX,             CPUID_7_0_EBX_RDSEED },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_RDSEED_EXITING },
++    },
++    {
++        .from = { FEAT_8000_0001_EDX,       CPUID_EXT2_RDTSCP },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_RDTSCP },
++    },
++    {
++        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_EPT },
++        .to = { FEAT_VMX_EPT_VPID_CAPS,     0xffffffffull },
++    },
++    {
++        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_EPT },
++        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST },
++    },
++    {
++        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_VPID },
++        .to = { FEAT_VMX_EPT_VPID_CAPS,     0xffffffffull << 32 },
++    },
++    {
++        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_VMFUNC },
++        .to = { FEAT_VMX_VMFUNC,            ~0ull },
++    },
+ };
+ 
+ typedef struct X86RegisterInfo32 {
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 2d1f247..386e821 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -522,6 +522,15 @@ typedef enum FeatureWord {
+     FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
+     FEAT_ARCH_CAPABILITIES,
+     FEAT_CORE_CAPABILITY,
++    FEAT_VMX_PROCBASED_CTLS,
++    FEAT_VMX_SECONDARY_CTLS,
++    FEAT_VMX_PINBASED_CTLS,
++    FEAT_VMX_EXIT_CTLS,
++    FEAT_VMX_ENTRY_CTLS,
++    FEAT_VMX_MISC,
++    FEAT_VMX_EPT_VPID_CAPS,
++    FEAT_VMX_BASIC,
++    FEAT_VMX_VMFUNC,
+     FEATURE_WORDS,
+ } FeatureWord;
+ 
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 85abd37..512d7d5 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -96,6 +96,7 @@ static bool has_msr_virt_ssbd;
+ static bool has_msr_smi_count;
+ static bool has_msr_arch_capabs;
+ static bool has_msr_core_capabs;
++static bool has_msr_vmx_vmfunc;
+ 
+ static uint32_t has_architectural_pmu_version;
+ static uint32_t num_architectural_pmu_gp_counters;
+@@ -429,7 +430,8 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+         struct kvm_msrs info;
+         struct kvm_msr_entry entries[1];
+     } msr_data;
+-    uint32_t ret;
++    uint64_t value;
++    uint32_t ret, can_be_one, must_be_one;
+ 
+     if (kvm_feature_msrs == NULL) { /* Host doesn't support feature MSRs */
+         return 0;
+@@ -455,7 +457,25 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+         exit(1);
+     }
+ 
+-    return msr_data.entries[0].data;
++    value = msr_data.entries[0].data;
++    switch (index) {
++    case MSR_IA32_VMX_PROCBASED_CTLS2:
++    case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
++    case MSR_IA32_VMX_TRUE_PROCBASED_CTLS:
++    case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
++    case MSR_IA32_VMX_TRUE_EXIT_CTLS:
++        /*
++         * Return true for bits that can be one, but do not have to be one.
++         * The SDM tells us which bits could have a "must be one" setting,
++         * so we can do the opposite transformation in make_vmx_msr_value.
++         */
++        must_be_one = (uint32_t)value;
++        can_be_one = (uint32_t)(value >> 32);
++        return can_be_one & ~must_be_one;
++
++    default:
++        return value;
++    }
+ }
+ 
+ 
+@@ -1430,6 +1450,9 @@ static int kvm_get_supported_msrs(KVMState *s)
+             case MSR_IA32_CORE_CAPABILITY:
+                 has_msr_core_capabs = true;
+                 break;
++            case MSR_IA32_VMX_VMFUNC:
++                has_msr_vmx_vmfunc = true;
++                break;
+             }
+         }
+     }
+@@ -1886,6 +1909,132 @@ static int kvm_put_msr_feature_control(X86CPU *cpu)
+     return 0;
+ }
+ 
++static uint64_t make_vmx_msr_value(uint32_t index, uint32_t features)
++{
++    uint32_t default1, can_be_one, can_be_zero;
++    uint32_t must_be_one;
++
++    switch (index) {
++    case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
++        default1 = 0x00000016;
++        break;
++    case MSR_IA32_VMX_TRUE_PROCBASED_CTLS:
++        default1 = 0x0401e172;
++        break;
++    case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
++        default1 = 0x000011ff;
++        break;
++    case MSR_IA32_VMX_TRUE_EXIT_CTLS:
++        default1 = 0x00036dff;
++        break;
++    case MSR_IA32_VMX_PROCBASED_CTLS2:
++        default1 = 0;
++        break;
++    default:
++        abort();
++    }
++
++    /* If a feature bit is set, the control can be either set or clear.
++     * Otherwise the value is limited to either 0 or 1 by default1.
++     */
++    can_be_one = features | default1;
++    can_be_zero = features | ~default1;
++    must_be_one = ~can_be_zero;
++
++    /*
++     * Bit 0:31 -> 0 if the control bit can be zero (i.e. 1 if it must be one).
++     * Bit 32:63 -> 1 if the control bit can be one.
++     */
++    return must_be_one | (((uint64_t)can_be_one) << 32);
++}
++
++#define VMCS12_MAX_FIELD_INDEX (0x17)
++
++static void kvm_msr_entry_add_vmx(X86CPU *cpu, FeatureWordArray f)
++{
++    uint64_t kvm_vmx_basic =
++        kvm_arch_get_supported_msr_feature(kvm_state,
++                                           MSR_IA32_VMX_BASIC);
++    uint64_t kvm_vmx_misc =
++        kvm_arch_get_supported_msr_feature(kvm_state,
++                                           MSR_IA32_VMX_MISC);
++    uint64_t kvm_vmx_ept_vpid =
++        kvm_arch_get_supported_msr_feature(kvm_state,
++                                           MSR_IA32_VMX_EPT_VPID_CAP);
++
++    /*
++     * If the guest is 64-bit, a value of 1 is allowed for the host address
++     * space size vmexit control.
++     */
++    uint64_t fixed_vmx_exit = f[FEAT_8000_0001_EDX] & CPUID_EXT2_LM
++        ? (uint64_t)VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE << 32 : 0;
++
++    /*
++     * Bits 0-30, 32-44 and 50-53 come from the host.  KVM should
++     * not change them for backwards compatibility.
++     */
++    uint64_t fixed_vmx_basic = kvm_vmx_basic &
++        (MSR_VMX_BASIC_VMCS_REVISION_MASK |
++         MSR_VMX_BASIC_VMXON_REGION_SIZE_MASK |
++         MSR_VMX_BASIC_VMCS_MEM_TYPE_MASK);
++
++    /*
++     * Same for bits 0-4 and 25-27.  Bits 16-24 (CR3 target count) can
++     * change in the future but are always zero for now, clear them to be
++     * future proof.  Bits 32-63 in theory could change, though KVM does
++     * not support dual-monitor treatment and probably never will; mask
++     * them out as well.
++     */
++    uint64_t fixed_vmx_misc = kvm_vmx_misc &
++        (MSR_VMX_MISC_PREEMPTION_TIMER_SHIFT_MASK |
++         MSR_VMX_MISC_MAX_MSR_LIST_SIZE_MASK);
++
++    /*
++     * EPT memory types should not change either, so we do not bother
++     * adding features for them.
++     */
++    uint64_t fixed_vmx_ept_mask =
++            (f[FEAT_VMX_SECONDARY_CTLS] & VMX_SECONDARY_EXEC_ENABLE_EPT ?
++             MSR_VMX_EPT_UC | MSR_VMX_EPT_WB : 0);
++    uint64_t fixed_vmx_ept_vpid = kvm_vmx_ept_vpid & fixed_vmx_ept_mask;
++
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
++                      make_vmx_msr_value(MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
++                                         f[FEAT_VMX_PROCBASED_CTLS]));
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_PINBASED_CTLS,
++                      make_vmx_msr_value(MSR_IA32_VMX_TRUE_PINBASED_CTLS,
++                                         f[FEAT_VMX_PINBASED_CTLS]));
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_EXIT_CTLS,
++                      make_vmx_msr_value(MSR_IA32_VMX_TRUE_EXIT_CTLS,
++                                         f[FEAT_VMX_EXIT_CTLS]) | fixed_vmx_exit);
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_TRUE_ENTRY_CTLS,
++                      make_vmx_msr_value(MSR_IA32_VMX_TRUE_ENTRY_CTLS,
++                                         f[FEAT_VMX_ENTRY_CTLS]));
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_PROCBASED_CTLS2,
++                      make_vmx_msr_value(MSR_IA32_VMX_PROCBASED_CTLS2,
++                                         f[FEAT_VMX_SECONDARY_CTLS]));
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_EPT_VPID_CAP,
++                      f[FEAT_VMX_EPT_VPID_CAPS] | fixed_vmx_ept_vpid);
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_BASIC,
++                      f[FEAT_VMX_BASIC] | fixed_vmx_basic);
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_MISC,
++                      f[FEAT_VMX_MISC] | fixed_vmx_misc);
++    if (has_msr_vmx_vmfunc) {
++        kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMFUNC, f[FEAT_VMX_VMFUNC]);
++    }
++
++    /*
++     * Just to be safe, write these with constant values.  The CRn_FIXED1
++     * MSRs are generated by KVM based on the vCPU's CPUID.
++     */
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_CR0_FIXED0,
++                      CR0_PE_MASK | CR0_PG_MASK | CR0_NE_MASK);
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_CR4_FIXED0,
++                      CR4_VMXE_MASK);
++    kvm_msr_entry_add(cpu, MSR_IA32_VMX_VMCS_ENUM,
++                      VMCS12_MAX_FIELD_INDEX << 1);
++}
++
+ static int kvm_put_msrs(X86CPU *cpu, int level)
+ {
+     CPUX86State *env = &cpu->env;
+@@ -2112,7 +2261,16 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+ 
+         /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
+          *       kvm_put_msr_feature_control. */
++
++        /*
++         * Older kernels do not include VMX MSRs in KVM_GET_MSR_INDEX_LIST, but
++         * all kernels with MSR features should have them.
++         */
++        if (kvm_feature_msrs && cpu_has_vmx(env)) {
++            kvm_msr_entry_add_vmx(cpu, env->features);
++        }
+     }
++
+     if (env->mcg_cap) {
+         int i;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch b/SOURCES/kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch
index 395e481..fab9b64 100644
--- a/SOURCES/kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch
+++ b/SOURCES/kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch
@@ -1,13 +1,13 @@
-From 4adba22c823ecc91cca5aeb835834b3393d5f50b Mon Sep 17 00:00:00 2001
+From 39c3a18b4b956d0533e07de2640be064e07e3c97 Mon Sep 17 00:00:00 2001
 From: Eduardo Habkost <ehabkost@redhat.com>
-Date: Tue, 3 Dec 2019 22:51:41 +0000
+Date: Tue, 3 Dec 2019 23:53:08 +0000
 Subject: [PATCH 2/2] target/i386: add support for MSR_IA32_TSX_CTRL
 
 RH-Author: Eduardo Habkost <ehabkost@redhat.com>
-Message-id: <20191203225141.501191-3-ehabkost@redhat.com>
-Patchwork-id: 92841
-O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 2/2] target/i386: add support for MSR_IA32_TSX_CTRL
-Bugzilla: 1771970
+Message-id: <20191203235308.590845-3-ehabkost@redhat.com>
+Patchwork-id: 92850
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/2] target/i386: add support for MSR_IA32_TSX_CTRL
+Bugzilla: 1771971
 RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
 RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
 RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
@@ -32,10 +32,10 @@ Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
  4 files changed, 38 insertions(+), 1 deletion(-)
 
 diff --git a/target/i386/cpu.c b/target/i386/cpu.c
-index 7baa5d2..591ebf3 100644
+index 68fe865..ef6b958 100644
 --- a/target/i386/cpu.c
 +++ b/target/i386/cpu.c
-@@ -1147,7 +1147,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+@@ -1143,7 +1143,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
          .type = MSR_FEATURE_WORD,
          .feat_names = {
              "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
@@ -45,12 +45,12 @@ index 7baa5d2..591ebf3 100644
              NULL, NULL, NULL, NULL,
              NULL, NULL, NULL, NULL,
 diff --git a/target/i386/cpu.h b/target/i386/cpu.h
-index 273c90b..b6bef27 100644
+index 386e821..8d8814e 100644
 --- a/target/i386/cpu.h
 +++ b/target/i386/cpu.h
-@@ -354,6 +354,9 @@ typedef enum X86Seg {
- #define MSR_VIRT_SSBD                   0xc001011f
+@@ -355,6 +355,9 @@ typedef enum X86Seg {
  #define MSR_IA32_PRED_CMD               0x49
+ #define MSR_IA32_CORE_CAPABILITY        0xcf
  #define MSR_IA32_ARCH_CAPABILITIES      0x10a
 +#define ARCH_CAP_TSX_CTRL_MSR		(1<<7)
 +
@@ -58,7 +58,7 @@ index 273c90b..b6bef27 100644
  #define MSR_IA32_TSCDEADLINE            0x6e0
  
  #define FEATURE_CONTROL_LOCKED                    (1<<0)
-@@ -1229,6 +1232,7 @@ typedef struct CPUX86State {
+@@ -1373,6 +1376,7 @@ typedef struct CPUX86State {
      uint64_t msr_smi_count;
  
      uint32_t pkru;
@@ -67,7 +67,7 @@ index 273c90b..b6bef27 100644
      uint64_t spec_ctrl;
      uint64_t virt_ssbd;
 diff --git a/target/i386/kvm.c b/target/i386/kvm.c
-index da5f07e..06144f0 100644
+index 6366172..107c53b 100644
 --- a/target/i386/kvm.c
 +++ b/target/i386/kvm.c
 @@ -92,6 +92,7 @@ static bool has_msr_hv_stimer;
@@ -78,17 +78,17 @@ index da5f07e..06144f0 100644
  static bool has_msr_virt_ssbd;
  static bool has_msr_smi_count;
  static bool has_msr_arch_capabs;
-@@ -1422,6 +1423,9 @@ static int kvm_get_supported_msrs(KVMState *s)
-                 case MSR_IA32_SPEC_CTRL:
-                     has_msr_spec_ctrl = true;
-                     break;
-+                case MSR_IA32_TSX_CTRL:
-+                    has_msr_tsx_ctrl = true;
-+                    break;
-                 case MSR_VIRT_SSBD:
-                     has_msr_virt_ssbd = true;
-                     break;
-@@ -1928,6 +1932,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+@@ -1458,6 +1459,9 @@ static int kvm_get_supported_msrs(KVMState *s)
+             case MSR_IA32_SPEC_CTRL:
+                 has_msr_spec_ctrl = true;
+                 break;
++            case MSR_IA32_TSX_CTRL:
++                has_msr_tsx_ctrl = true;
++                break;
+             case MSR_VIRT_SSBD:
+                 has_msr_virt_ssbd = true;
+                 break;
+@@ -2095,6 +2099,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
      if (has_msr_spec_ctrl) {
          kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, env->spec_ctrl);
      }
@@ -98,7 +98,7 @@ index da5f07e..06144f0 100644
      if (has_msr_virt_ssbd) {
          kvm_msr_entry_add(cpu, MSR_VIRT_SSBD, env->virt_ssbd);
      }
-@@ -2310,6 +2317,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+@@ -2491,6 +2498,9 @@ static int kvm_get_msrs(X86CPU *cpu)
      if (has_msr_spec_ctrl) {
          kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, 0);
      }
@@ -108,7 +108,7 @@ index da5f07e..06144f0 100644
      if (has_msr_virt_ssbd) {
          kvm_msr_entry_add(cpu, MSR_VIRT_SSBD, 0);
      }
-@@ -2681,6 +2691,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+@@ -2862,6 +2872,9 @@ static int kvm_get_msrs(X86CPU *cpu)
          case MSR_IA32_SPEC_CTRL:
              env->spec_ctrl = msrs[i].data;
              break;
diff --git a/SOURCES/kvm-target-i386-adjust-for-missing-VMX-features.patch b/SOURCES/kvm-target-i386-adjust-for-missing-VMX-features.patch
new file mode 100644
index 0000000..c193e7f
--- /dev/null
+++ b/SOURCES/kvm-target-i386-adjust-for-missing-VMX-features.patch
@@ -0,0 +1,49 @@
+From 76abda27a42dfe08598b38582210f7aeb31e6685 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:46 +0000
+Subject: [PATCH 13/16] target/i386: adjust for missing VMX features
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-14-pbonzini@redhat.com>
+Patchwork-id: 92611
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 13/15] target/i386: adjust for missing VMX features
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+vmx-exit-load-perf-global-ctrl and vmx-entry-load-perf-global-ctrl
+have only been added to kernel 5.4, so disable them in RHEL until
+we add them to the kernel.  At that point, they could be added back
+to a new machine type.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ include/hw/i386/pc.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
+index 88ffd40..b546aed 100644
+--- a/include/hw/i386/pc.h
++++ b/include/hw/i386/pc.h
+@@ -968,6 +968,16 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
+ #define PC_RHEL_COMPAT \
+         { /* PC_RHEL_COMPAT */ \
+             .driver = TYPE_X86_CPU,\
++            .property = "vmx-exit-load-perf-global-ctrl",\
++            .value = "off",\
++        },\
++        { /* PC_RHEL_COMPAT */ \
++            .driver = TYPE_X86_CPU,\
++            .property = "vmx-entry-load-perf-global-ctrl",\
++            .value = "off",\
++        },\
++        { /* PC_RHEL_COMPAT */ \
++            .driver = TYPE_X86_CPU,\
+             .property = "host-phys-bits",\
+             .value = "on",\
+         },\
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-define-a-new-MSR-based-feature-word-FEAT.patch b/SOURCES/kvm-target-i386-define-a-new-MSR-based-feature-word-FEAT.patch
new file mode 100644
index 0000000..5654ec6
--- /dev/null
+++ b/SOURCES/kvm-target-i386-define-a-new-MSR-based-feature-word-FEAT.patch
@@ -0,0 +1,152 @@
+From 127410386296459cf3eec4b12d7451afc50d2503 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:36 +0000
+Subject: [PATCH 03/16] target/i386: define a new MSR based feature word -
+ FEAT_CORE_CAPABILITY
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-4-pbonzini@redhat.com>
+Patchwork-id: 92603
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 03/15] target/i386: define a new MSR based feature word - FEAT_CORE_CAPABILITY
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+From: Xiaoyao Li <xiaoyao.li@linux.intel.com>
+
+MSR IA32_CORE_CAPABILITY is a feature-enumerating MSR, which only
+enumerates the feature split lock detection (via bit 5) by now.
+
+The existence of MSR IA32_CORE_CAPABILITY is enumerated by CPUID.7_0:EDX[30].
+
+The latest kernel patches about them can be found here:
+https://lkml.org/lkml/2019/4/24/1909
+
+Signed-off-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
+Message-Id: <20190617153654.916-1-xiaoyao.li@linux.intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 597360c0d8ebda9ca6f239db724a25bddec62b2f)
+
+RHEL: context
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 22 +++++++++++++++++++++-
+ target/i386/cpu.h |  5 +++++
+ target/i386/kvm.c |  9 +++++++++
+ 3 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 8c1338f..52f1f33 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1045,7 +1045,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, "spec-ctrl", "stibp",
+-            NULL, "arch-capabilities", NULL, "ssbd",
++            NULL, "arch-capabilities", "core-capability", "ssbd",
+         },
+         .cpuid = {
+             .eax = 7,
+@@ -1163,6 +1163,26 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             }
+         },
+     },
++    [FEAT_CORE_CAPABILITY] = {
++        .type = MSR_FEATURE_WORD,
++        .feat_names = {
++            NULL, NULL, NULL, NULL,
++            NULL, "split-lock-detect", NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .msr = {
++            .index = MSR_IA32_CORE_CAPABILITY,
++            .cpuid_dep = {
++                FEAT_7_0_EDX,
++                CPUID_7_0_EDX_CORE_CAPABILITY,
++            },
++        },
++    },
+ };
+ 
+ typedef struct X86RegisterInfo32 {
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 1ad54bd..f9b93be 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -353,6 +353,7 @@ typedef enum X86Seg {
+ #define MSR_IA32_SPEC_CTRL              0x48
+ #define MSR_VIRT_SSBD                   0xc001011f
+ #define MSR_IA32_PRED_CMD               0x49
++#define MSR_IA32_CORE_CAPABILITY        0xcf
+ #define MSR_IA32_ARCH_CAPABILITIES      0x10a
+ #define MSR_IA32_TSCDEADLINE            0x6e0
+ 
+@@ -501,6 +502,7 @@ typedef enum FeatureWord {
+     FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
+     FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
+     FEAT_ARCH_CAPABILITIES,
++    FEAT_CORE_CAPABILITY,
+     FEATURE_WORDS,
+ } FeatureWord;
+ 
+@@ -690,6 +692,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */
+ #define CPUID_7_0_EDX_SPEC_CTRL     (1U << 26) /* Speculation Control */
+ #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
++#define CPUID_7_0_EDX_CORE_CAPABILITY   (1U << 30)  /*Core Capability*/
+ #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass Disable */
+ 
+ #define KVM_HINTS_DEDICATED (1U << 0)
+@@ -744,6 +747,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
+ #define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
+ #define MSR_ARCH_CAP_SSB_NO     (1U << 4)
+ 
++#define MSR_CORE_CAP_SPLIT_LOCK_DETECT  (1U << 5)
++
+ #ifndef HYPERV_SPINLOCK_NEVER_RETRY
+ #define HYPERV_SPINLOCK_NEVER_RETRY             0xFFFFFFFF
+ #endif
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index da5f07e..849a11a 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -95,6 +95,7 @@ static bool has_msr_spec_ctrl;
+ static bool has_msr_virt_ssbd;
+ static bool has_msr_smi_count;
+ static bool has_msr_arch_capabs;
++static bool has_msr_core_capabs;
+ 
+ static uint32_t has_architectural_pmu_version;
+ static uint32_t num_architectural_pmu_gp_counters;
+@@ -1428,6 +1429,9 @@ static int kvm_get_supported_msrs(KVMState *s)
+                 case MSR_IA32_ARCH_CAPABILITIES:
+                     has_msr_arch_capabs = true;
+                     break;
++                case MSR_IA32_CORE_CAPABILITY:
++                    has_msr_core_capabs = true;
++                    break;
+                 }
+             }
+         }
+@@ -1947,6 +1951,11 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+                           env->features[FEAT_ARCH_CAPABILITIES]);
+     }
+ 
++    if (has_msr_core_capabs) {
++        kvm_msr_entry_add(cpu, MSR_IA32_CORE_CAPABILITY,
++                          env->features[FEAT_CORE_CAPABILITY]);
++    }
++
+     /*
+      * The following MSRs have side effects on the guest or are too heavy
+      * for normal writeback. Limit them to reset or full state updates.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-expand-feature-words-to-64-bits.patch b/SOURCES/kvm-target-i386-expand-feature-words-to-64-bits.patch
new file mode 100644
index 0000000..11e064e
--- /dev/null
+++ b/SOURCES/kvm-target-i386-expand-feature-words-to-64-bits.patch
@@ -0,0 +1,306 @@
+From a31ce6a9fa171f677bf52dd0b0076e7b92d9ae33 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:41 +0000
+Subject: [PATCH 08/16] target/i386: expand feature words to 64 bits
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-9-pbonzini@redhat.com>
+Patchwork-id: 92612
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 08/15] target/i386: expand feature words to 64 bits
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+VMX requires 64-bit feature words for the IA32_VMX_EPT_VPID_CAP
+and IA32_VMX_BASIC MSRs.  (The VMX control MSRs are 64-bit wide but
+actually have only 32 bits of information).
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit ede146c2e720b670350c7ef5e9af44e80a73fe97)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ include/sysemu/kvm.h |  2 +-
+ target/i386/cpu.c    | 71 +++++++++++++++++++++++++++-------------------------
+ target/i386/cpu.h    |  2 +-
+ target/i386/kvm.c    |  2 +-
+ 4 files changed, 40 insertions(+), 37 deletions(-)
+
+diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
+index 3cf04cf..2c7f841 100644
+--- a/include/sysemu/kvm.h
++++ b/include/sysemu/kvm.h
+@@ -466,7 +466,7 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension);
+ 
+ uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
+                                       uint32_t index, int reg);
+-uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
++uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
+ 
+ 
+ void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index a7360b3..3e77830 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -785,7 +785,7 @@ typedef struct FeatureWordInfo {
+      * In cases of disagreement between feature naming conventions,
+      * aliases may be added.
+      */
+-    const char *feat_names[32];
++    const char *feat_names[64];
+     union {
+         /* If type==CPUID_FEATURE_WORD */
+         struct {
+@@ -799,11 +799,11 @@ typedef struct FeatureWordInfo {
+             uint32_t index;
+         } msr;
+     };
+-    uint32_t tcg_features; /* Feature flags supported by TCG */
+-    uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
+-    uint32_t migratable_flags; /* Feature flags known to be migratable */
++    uint64_t tcg_features; /* Feature flags supported by TCG */
++    uint64_t unmigratable_flags; /* Feature flags known to be unmigratable */
++    uint64_t migratable_flags; /* Feature flags known to be migratable */
+     /* Features that shouldn't be auto-enabled by "-cpu host" */
+-    uint32_t no_autoenable_flags;
++    uint64_t no_autoenable_flags;
+ } FeatureWordInfo;
+ 
+ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+@@ -1175,7 +1175,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+ 
+ typedef struct FeatureMask {
+     FeatureWord index;
+-    uint32_t mask;
++    uint64_t mask;
+ } FeatureMask;
+ 
+ typedef struct FeatureDep {
+@@ -1185,11 +1185,11 @@ typedef struct FeatureDep {
+ static FeatureDep feature_dependencies[] = {
+     {
+         .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_ARCH_CAPABILITIES },
+-        .to = { FEAT_ARCH_CAPABILITIES,     ~0u },
++        .to = { FEAT_ARCH_CAPABILITIES,     ~0ull },
+     },
+     {
+         .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_CORE_CAPABILITY },
+-        .to = { FEAT_CORE_CAPABILITY,       ~0u },
++        .to = { FEAT_CORE_CAPABILITY,       ~0ull },
+     },
+ };
+ 
+@@ -1301,14 +1301,14 @@ const char *get_register_name_32(unsigned int reg)
+  * Returns the set of feature flags that are supported and migratable by
+  * QEMU, for a given FeatureWord.
+  */
+-static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
++static uint64_t x86_cpu_get_migratable_flags(FeatureWord w)
+ {
+     FeatureWordInfo *wi = &feature_word_info[w];
+-    uint32_t r = 0;
++    uint64_t r = 0;
+     int i;
+ 
+-    for (i = 0; i < 32; i++) {
+-        uint32_t f = 1U << i;
++    for (i = 0; i < 64; i++) {
++        uint64_t f = 1ULL << i;
+ 
+         /* If the feature name is known, it is implicitly considered migratable,
+          * unless it is explicitly set in unmigratable_flags */
+@@ -2948,7 +2948,7 @@ void x86_cpu_change_kvm_default(const char *prop, const char *value)
+     assert(pv->prop);
+ }
+ 
+-static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
++static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
+                                                    bool migratable_only);
+ 
+ static bool lmce_supported(void)
+@@ -3142,7 +3142,7 @@ static bool x86_cpu_have_filtered_features(X86CPU *cpu)
+     return false;
+ }
+ 
+-static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask,
++static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask,
+                                       const char *verbose_prefix)
+ {
+     CPUX86State *env = &cpu->env;
+@@ -3159,8 +3159,8 @@ static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask,
+         return;
+     }
+ 
+-    for (i = 0; i < 32; ++i) {
+-        if ((1UL << i) & mask) {
++    for (i = 0; i < 64; ++i) {
++        if ((1ULL << i) & mask) {
+             feat_word_str = feature_word_description(f, i);
+             warn_report("%s: %s%s%s [bit %d]",
+                         verbose_prefix,
+@@ -3403,7 +3403,7 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
+                                       const char *name, void *opaque,
+                                       Error **errp)
+ {
+-    uint32_t *array = (uint32_t *)opaque;
++    uint64_t *array = (uint64_t *)opaque;
+     FeatureWord w;
+     X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
+     X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
+@@ -3487,6 +3487,7 @@ static inline void feat2prop(char *s)
+ /* Return the feature property name for a feature flag bit */
+ static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
+ {
++    const char *name;
+     /* XSAVE components are automatically enabled by other features,
+      * so return the original feature name instead
+      */
+@@ -3500,9 +3501,11 @@ static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
+         }
+     }
+ 
+-    assert(bitnr < 32);
++    assert(bitnr < 64);
+     assert(w < FEATURE_WORDS);
+-    return feature_word_info[w].feat_names[bitnr];
++    name = feature_word_info[w].feat_names[bitnr];
++    assert(bitnr < 32 || !(name && feature_word_info[w].type == CPUID_FEATURE_WORD));
++    return name;
+ }
+ 
+ /* Compatibily hack to maintain legacy +-feat semantic,
+@@ -3619,10 +3622,10 @@ static void x86_cpu_list_feature_names(FeatureWordArray features,
+     strList **next = feat_names;
+ 
+     for (w = 0; w < FEATURE_WORDS; w++) {
+-        uint32_t filtered = features[w];
++        uint64_t filtered = features[w];
+         int i;
+-        for (i = 0; i < 32; i++) {
+-            if (filtered & (1UL << i)) {
++        for (i = 0; i < 64; i++) {
++            if (filtered & (1ULL << i)) {
+                 strList *new = g_new0(strList, 1);
+                 new->value = g_strdup(x86_cpu_feature_name(w, i));
+                 *next = new;
+@@ -3760,7 +3763,7 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+     names = NULL;
+     for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
+         FeatureWordInfo *fw = &feature_word_info[i];
+-        for (j = 0; j < 32; j++) {
++        for (j = 0; j < 64; j++) {
+             if (fw->feat_names[j]) {
+                 names = g_list_append(names, (gpointer)fw->feat_names[j]);
+             }
+@@ -3807,11 +3810,11 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+     return cpu_list;
+ }
+ 
+-static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
++static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
+                                                    bool migratable_only)
+ {
+     FeatureWordInfo *wi = &feature_word_info[w];
+-    uint32_t r = 0;
++    uint64_t r = 0;
+ 
+     if (kvm_enabled()) {
+         switch (wi->type) {
+@@ -3950,7 +3953,7 @@ static QDict *x86_cpu_static_props(void)
+     for (w = 0; w < FEATURE_WORDS; w++) {
+         FeatureWordInfo *fi = &feature_word_info[w];
+         int bit;
+-        for (bit = 0; bit < 32; bit++) {
++        for (bit = 0; bit < 64; bit++) {
+             if (!fi->feat_names[bit]) {
+                 continue;
+             }
+@@ -5015,7 +5018,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+     for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
+         FeatureDep *d = &feature_dependencies[i];
+         if (!(env->features[d->from.index] & d->from.mask)) {
+-            uint32_t unavailable_features = env->features[d->to.index] & d->to.mask;
++            uint64_t unavailable_features = env->features[d->to.index] & d->to.mask;
+ 
+             /* Not an error unless the dependent feature was added explicitly.  */
+             mark_unavailable_features(cpu, d->to.index,
+@@ -5094,10 +5097,10 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
+     }
+ 
+     for (w = 0; w < FEATURE_WORDS; w++) {
+-        uint32_t host_feat =
++        uint64_t host_feat =
+             x86_cpu_get_supported_feature_word(w, false);
+-        uint32_t requested_features = env->features[w];
+-        uint32_t unavailable_features = requested_features & ~host_feat;
++        uint64_t requested_features = env->features[w];
++        uint64_t unavailable_features = requested_features & ~host_feat;
+         mark_unavailable_features(cpu, w, unavailable_features, prefix);
+     }
+ 
+@@ -5380,7 +5383,7 @@ static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
+ 
+ typedef struct BitProperty {
+     FeatureWord w;
+-    uint32_t mask;
++    uint64_t mask;
+ } BitProperty;
+ 
+ static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
+@@ -5388,7 +5391,7 @@ static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
+ {
+     X86CPU *cpu = X86_CPU(obj);
+     BitProperty *fp = opaque;
+-    uint32_t f = cpu->env.features[fp->w];
++    uint64_t f = cpu->env.features[fp->w];
+     bool value = (f & fp->mask) == fp->mask;
+     visit_type_bool(v, name, &value, errp);
+ }
+@@ -5441,7 +5444,7 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu,
+ {
+     BitProperty *fp;
+     ObjectProperty *op;
+-    uint32_t mask = (1UL << bitnr);
++    uint64_t mask = (1ULL << bitnr);
+ 
+     op = object_property_find(OBJECT(cpu), prop_name, NULL);
+     if (op) {
+@@ -5577,7 +5580,7 @@ static void x86_cpu_initfn(Object *obj)
+     for (w = 0; w < FEATURE_WORDS; w++) {
+         int bitnr;
+ 
+-        for (bitnr = 0; bitnr < 32; bitnr++) {
++        for (bitnr = 0; bitnr < 64; bitnr++) {
+             x86_cpu_register_feature_bit_props(cpu, w, bitnr);
+         }
+     }
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index f9b93be..edba84e 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -506,7 +506,7 @@ typedef enum FeatureWord {
+     FEATURE_WORDS,
+ } FeatureWord;
+ 
+-typedef uint32_t FeatureWordArray[FEATURE_WORDS];
++typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ 
+ /* cpuid_features bits */
+ #define CPUID_FP87 (1U << 0)
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 2290c5d..85abd37 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -423,7 +423,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
+     return ret;
+ }
+ 
+-uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
++uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+ {
+     struct {
+         struct kvm_msrs info;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-handle-filtered_features-in-a-new-functi.patch b/SOURCES/kvm-target-i386-handle-filtered_features-in-a-new-functi.patch
new file mode 100644
index 0000000..f48b1d1
--- /dev/null
+++ b/SOURCES/kvm-target-i386-handle-filtered_features-in-a-new-functi.patch
@@ -0,0 +1,187 @@
+From d7362c761ef55b7f665c4dff61d9e58b153ff11c Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:39 +0000
+Subject: [PATCH 06/16] target/i386: handle filtered_features in a new function
+ mark_unavailable_features
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-7-pbonzini@redhat.com>
+Patchwork-id: 92600
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 06/15] target/i386: handle filtered_features in a new function mark_unavailable_features
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+The next patch will add a different reason for filtering features, unrelated
+to host feature support.  Extract a new function that takes care of disabling
+the features and optionally reporting them.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 245edd0cfb1481b7a0398cce45df23db50f00034)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 87 ++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 48 insertions(+), 39 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index d0c48c2..b06ce9d 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3121,17 +3121,41 @@ static char *feature_word_description(FeatureWordInfo *f, uint32_t bit)
+     return NULL;
+ }
+ 
+-static void report_unavailable_features(FeatureWord w, uint32_t mask)
++static bool x86_cpu_have_filtered_features(X86CPU *cpu)
+ {
++    FeatureWord w;
++
++    for (w = 0; w < FEATURE_WORDS; w++) {
++        if (cpu->filtered_features[w]) {
++            return true;
++        }
++    }
++
++    return false;
++}
++
++static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint32_t mask,
++                                      const char *verbose_prefix)
++{
++    CPUX86State *env = &cpu->env;
+     FeatureWordInfo *f = &feature_word_info[w];
+     int i;
+     char *feat_word_str;
+ 
++    if (!cpu->force_features) {
++        env->features[w] &= ~mask;
++    }
++    cpu->filtered_features[w] |= mask;
++
++    if (!verbose_prefix) {
++        return;
++    }
++
+     for (i = 0; i < 32; ++i) {
+         if ((1UL << i) & mask) {
+             feat_word_str = feature_word_description(f, i);
+-            warn_report("%s doesn't support requested feature: %s%s%s [bit %d]",
+-                        accel_uses_host_cpuid() ? "host" : "TCG",
++            warn_report("%s: %s%s%s [bit %d]",
++                        verbose_prefix,
+                         feat_word_str,
+                         f->feat_names[i] ? "." : "",
+                         f->feat_names[i] ? f->feat_names[i] : "", i);
+@@ -3577,7 +3601,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
+ }
+ 
+ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp);
+-static int x86_cpu_filter_features(X86CPU *cpu);
++static void x86_cpu_filter_features(X86CPU *cpu, bool verbose);
+ 
+ /* Build a list with the name of all features on a feature word array */
+ static void x86_cpu_list_feature_names(FeatureWordArray features,
+@@ -3642,7 +3666,7 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
+         next = &new->next;
+     }
+ 
+-    x86_cpu_filter_features(xc);
++    x86_cpu_filter_features(xc, false);
+ 
+     x86_cpu_list_feature_names(xc->filtered_features, next);
+ 
+@@ -3811,15 +3835,6 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
+     return r;
+ }
+ 
+-static void x86_cpu_report_filtered_features(X86CPU *cpu)
+-{
+-    FeatureWord w;
+-
+-    for (w = 0; w < FEATURE_WORDS; w++) {
+-        report_unavailable_features(w, cpu->filtered_features[w]);
+-    }
+-}
+-
+ static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
+ {
+     PropValue *pv;
+@@ -5042,24 +5057,24 @@ out:
+  *
+  * Returns: 0 if all flags are supported by the host, non-zero otherwise.
+  */
+-static int x86_cpu_filter_features(X86CPU *cpu)
++static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
+ {
+     CPUX86State *env = &cpu->env;
+     FeatureWord w;
+-    int rv = 0;
++    const char *prefix = NULL;
++
++    if (verbose) {
++        prefix = accel_uses_host_cpuid()
++                 ? "host doesn't support requested feature"
++                 : "TCG doesn't support requested feature";
++    }
+ 
+     for (w = 0; w < FEATURE_WORDS; w++) {
+         uint32_t host_feat =
+             x86_cpu_get_supported_feature_word(w, false);
+         uint32_t requested_features = env->features[w];
+-        uint32_t available_features = requested_features & host_feat;
+-        if (!cpu->force_features) {
+-            env->features[w] = available_features;
+-        }
+-        cpu->filtered_features[w] = requested_features & ~available_features;
+-        if (cpu->filtered_features[w]) {
+-            rv = 1;
+-        }
++        uint32_t unavailable_features = requested_features & ~host_feat;
++        mark_unavailable_features(cpu, w, unavailable_features, prefix);
+     }
+ 
+     if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
+@@ -5085,13 +5100,9 @@ static int x86_cpu_filter_features(X86CPU *cpu)
+              * host can't emulate the capabilities we report on
+              * cpu_x86_cpuid(), intel-pt can't be enabled on the current host.
+              */
+-            env->features[FEAT_7_0_EBX] &= ~CPUID_7_0_EBX_INTEL_PT;
+-            cpu->filtered_features[FEAT_7_0_EBX] |= CPUID_7_0_EBX_INTEL_PT;
+-            rv = 1;
++            mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix);
+         }
+     }
+-
+-    return rv;
+ }
+ 
+ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+@@ -5120,16 +5131,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
+         goto out;
+     }
+ 
+-    if (x86_cpu_filter_features(cpu) &&
+-        (cpu->check_cpuid || cpu->enforce_cpuid)) {
+-        x86_cpu_report_filtered_features(cpu);
+-        if (cpu->enforce_cpuid) {
+-            error_setg(&local_err,
+-                       accel_uses_host_cpuid() ?
+-                           "Host doesn't support requested features" :
+-                           "TCG doesn't support requested features");
+-            goto out;
+-        }
++    x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid);
++
++    if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) {
++        error_setg(&local_err,
++                   accel_uses_host_cpuid() ?
++                       "Host doesn't support requested features" :
++                       "TCG doesn't support requested features");
++        goto out;
+     }
+ 
+     /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-introduce-generic-feature-dependency-mec.patch b/SOURCES/kvm-target-i386-introduce-generic-feature-dependency-mec.patch
new file mode 100644
index 0000000..e3bf334
--- /dev/null
+++ b/SOURCES/kvm-target-i386-introduce-generic-feature-dependency-mec.patch
@@ -0,0 +1,158 @@
+From 98145bfcdcee809e370d65eb3a97a9529670ec06 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:40 +0000
+Subject: [PATCH 07/16] target/i386: introduce generic feature dependency
+ mechanism
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-8-pbonzini@redhat.com>
+Patchwork-id: 92610
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 07/15] target/i386: introduce generic feature dependency mechanism
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+Sometimes a CPU feature does not make sense unless another is
+present.  In the case of VMX features, KVM does not even allow
+setting the VMX controls to some invalid combinations.
+
+Therefore, this patch adds a generic mechanism that looks for bits
+that the user explicitly cleared, and uses them to remove other bits
+from the expanded CPU definition.  If these dependent bits were also
+explicitly *set* by the user, this will be a warning for "-cpu check"
+and an error for "-cpu enforce".  If not, then the dependent bits are
+cleared silently, for convenience.
+
+With VMX features, this will be used so that for example
+"-cpu host,-rdrand" will also hide support for RDRAND exiting.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 99e24dbdaa682c7b9d0bb5b463638c585bcee1c3)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 72 ++++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 48 insertions(+), 24 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index b06ce9d..a7360b3 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -797,10 +797,6 @@ typedef struct FeatureWordInfo {
+         /* If type==MSR_FEATURE_WORD */
+         struct {
+             uint32_t index;
+-            struct {   /*CPUID that enumerate this MSR*/
+-                FeatureWord cpuid_class;
+-                uint32_t    cpuid_flag;
+-            } cpuid_dep;
+         } msr;
+     };
+     uint32_t tcg_features; /* Feature flags supported by TCG */
+@@ -1157,10 +1153,6 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         },
+         .msr = {
+             .index = MSR_IA32_ARCH_CAPABILITIES,
+-            .cpuid_dep = {
+-                FEAT_7_0_EDX,
+-                CPUID_7_0_EDX_ARCH_CAPABILITIES
+-            }
+         },
+     },
+     [FEAT_CORE_CAPABILITY] = {
+@@ -1177,14 +1169,30 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         },
+         .msr = {
+             .index = MSR_IA32_CORE_CAPABILITY,
+-            .cpuid_dep = {
+-                FEAT_7_0_EDX,
+-                CPUID_7_0_EDX_CORE_CAPABILITY,
+-            },
+         },
+     },
+ };
+ 
++typedef struct FeatureMask {
++    FeatureWord index;
++    uint32_t mask;
++} FeatureMask;
++
++typedef struct FeatureDep {
++    FeatureMask from, to;
++} FeatureDep;
++
++static FeatureDep feature_dependencies[] = {
++    {
++        .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_ARCH_CAPABILITIES },
++        .to = { FEAT_ARCH_CAPABILITIES,     ~0u },
++    },
++    {
++        .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_CORE_CAPABILITY },
++        .to = { FEAT_CORE_CAPABILITY,       ~0u },
++    },
++};
++
+ typedef struct X86RegisterInfo32 {
+     /* Name of register */
+     const char *name;
+@@ -4967,9 +4975,26 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+ {
+     CPUX86State *env = &cpu->env;
+     FeatureWord w;
++    int i;
+     GList *l;
+     Error *local_err = NULL;
+ 
++    for (l = plus_features; l; l = l->next) {
++        const char *prop = l->data;
++        object_property_set_bool(OBJECT(cpu), true, prop, &local_err);
++        if (local_err) {
++            goto out;
++        }
++    }
++
++    for (l = minus_features; l; l = l->next) {
++        const char *prop = l->data;
++        object_property_set_bool(OBJECT(cpu), false, prop, &local_err);
++        if (local_err) {
++            goto out;
++        }
++    }
++
+     /*TODO: Now cpu->max_features doesn't overwrite features
+      * set using QOM properties, and we can convert
+      * plus_features & minus_features to global properties
+@@ -4987,19 +5012,18 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+         }
+     }
+ 
+-    for (l = plus_features; l; l = l->next) {
+-        const char *prop = l->data;
+-        object_property_set_bool(OBJECT(cpu), true, prop, &local_err);
+-        if (local_err) {
+-            goto out;
+-        }
+-    }
++    for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
++        FeatureDep *d = &feature_dependencies[i];
++        if (!(env->features[d->from.index] & d->from.mask)) {
++            uint32_t unavailable_features = env->features[d->to.index] & d->to.mask;
+ 
+-    for (l = minus_features; l; l = l->next) {
+-        const char *prop = l->data;
+-        object_property_set_bool(OBJECT(cpu), false, prop, &local_err);
+-        if (local_err) {
+-            goto out;
++            /* Not an error unless the dependent feature was added explicitly.  */
++            mark_unavailable_features(cpu, d->to.index,
++                                      unavailable_features & env->user_features[d->to.index],
++                                      "This feature depends on other features that were not requested");
++
++            env->user_features[d->to.index] |= unavailable_features;
++            env->features[d->to.index] &= ~unavailable_features;
+         }
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-kvm-initialize-feature-MSRs-very-early.patch b/SOURCES/kvm-target-i386-kvm-initialize-feature-MSRs-very-early.patch
new file mode 100644
index 0000000..d715457
--- /dev/null
+++ b/SOURCES/kvm-target-i386-kvm-initialize-feature-MSRs-very-early.patch
@@ -0,0 +1,176 @@
+From c4660f9a4e2ffde711294ee7c5959f17735fd863 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 6 Feb 2020 23:51:16 +0000
+Subject: [PATCH 2/2] target/i386: kvm: initialize feature MSRs very early
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20200206235116.19421-2-pbonzini@redhat.com>
+Patchwork-id: 93733
+O-Subject: [PATCH 1/1] target/i386: kvm: initialize feature MSRs very early
+Bugzilla: 1790308
+RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+Some read-only MSRs affect the behavior of ioctls such as
+KVM_SET_NESTED_STATE.  We can initialize them once and for all
+right after the CPU is realized, since they will never be modified
+by the guest.
+
+Reported-by: Qingua Cheng <qcheng@redhat.com>
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-Id: <1579544504-3616-2-git-send-email-pbonzini@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 420ae1fc51c99abfd03b1c590f55617edd2a2bed)
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/kvm.c      | 81 ++++++++++++++++++++++++++++++--------------------
+ target/i386/kvm_i386.h |  1 +
+ 2 files changed, 49 insertions(+), 33 deletions(-)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 92eda8d..e43bcd3 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -65,6 +65,8 @@
+  * 255 kvm_msr_entry structs */
+ #define MSR_BUF_SIZE 4096
+ 
++static void kvm_init_msrs(X86CPU *cpu);
++
+ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+     KVM_CAP_INFO(SET_TSS_ADDR),
+     KVM_CAP_INFO(EXT_CPUID),
+@@ -1296,6 +1298,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
+         has_msr_tsc_aux = false;
+     }
+ 
++    kvm_init_msrs(cpu);
++
+     return 0;
+ 
+  fail:
+@@ -2099,11 +2103,53 @@ static void kvm_msr_entry_add_vmx(X86CPU *cpu, FeatureWordArray f)
+                       VMCS12_MAX_FIELD_INDEX << 1);
+ }
+ 
++static int kvm_buf_set_msrs(X86CPU *cpu)
++{
++    int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
++    if (ret < 0) {
++        return ret;
++    }
++
++    if (ret < cpu->kvm_msr_buf->nmsrs) {
++        struct kvm_msr_entry *e = &cpu->kvm_msr_buf->entries[ret];
++        error_report("error: failed to set MSR 0x%" PRIx32 " to 0x%" PRIx64,
++                     (uint32_t)e->index, (uint64_t)e->data);
++    }
++
++    assert(ret == cpu->kvm_msr_buf->nmsrs);
++    return 0;
++}
++
++static void kvm_init_msrs(X86CPU *cpu)
++{
++    CPUX86State *env = &cpu->env;
++
++    kvm_msr_buf_reset(cpu);
++    if (has_msr_arch_capabs) {
++        kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
++                          env->features[FEAT_ARCH_CAPABILITIES]);
++    }
++
++    if (has_msr_core_capabs) {
++        kvm_msr_entry_add(cpu, MSR_IA32_CORE_CAPABILITY,
++                          env->features[FEAT_CORE_CAPABILITY]);
++    }
++
++    /*
++     * Older kernels do not include VMX MSRs in KVM_GET_MSR_INDEX_LIST, but
++     * all kernels with MSR features should have them.
++     */
++    if (kvm_feature_msrs && cpu_has_vmx(env)) {
++        kvm_msr_entry_add_vmx(cpu, env->features);
++    }
++
++    assert(kvm_buf_set_msrs(cpu) == 0);
++}
++
+ static int kvm_put_msrs(X86CPU *cpu, int level)
+ {
+     CPUX86State *env = &cpu->env;
+     int i;
+-    int ret;
+ 
+     kvm_msr_buf_reset(cpu);
+ 
+@@ -2161,17 +2207,6 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+     }
+ #endif
+ 
+-    /* If host supports feature MSR, write down. */
+-    if (has_msr_arch_capabs) {
+-        kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
+-                          env->features[FEAT_ARCH_CAPABILITIES]);
+-    }
+-
+-    if (has_msr_core_capabs) {
+-        kvm_msr_entry_add(cpu, MSR_IA32_CORE_CAPABILITY,
+-                          env->features[FEAT_CORE_CAPABILITY]);
+-    }
+-
+     /*
+      * The following MSRs have side effects on the guest or are too heavy
+      * for normal writeback. Limit them to reset or full state updates.
+@@ -2331,14 +2366,6 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+ 
+         /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
+          *       kvm_put_msr_feature_control. */
+-
+-        /*
+-         * Older kernels do not include VMX MSRs in KVM_GET_MSR_INDEX_LIST, but
+-         * all kernels with MSR features should have them.
+-         */
+-        if (kvm_feature_msrs && cpu_has_vmx(env)) {
+-            kvm_msr_entry_add_vmx(cpu, env->features);
+-        }
+     }
+ 
+     if (env->mcg_cap) {
+@@ -2354,19 +2381,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
+         }
+     }
+ 
+-    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
+-    if (ret < 0) {
+-        return ret;
+-    }
+-
+-    if (ret < cpu->kvm_msr_buf->nmsrs) {
+-        struct kvm_msr_entry *e = &cpu->kvm_msr_buf->entries[ret];
+-        error_report("error: failed to set MSR 0x%" PRIx32 " to 0x%" PRIx64,
+-                     (uint32_t)e->index, (uint64_t)e->data);
+-    }
+-
+-    assert(ret == cpu->kvm_msr_buf->nmsrs);
+-    return 0;
++    return kvm_buf_set_msrs(cpu);
+ }
+ 
+ 
+diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
+index df9bbf3..5748337 100644
+--- a/target/i386/kvm_i386.h
++++ b/target/i386/kvm_i386.h
+@@ -70,4 +70,5 @@ void kvm_put_apicbase(X86CPU *cpu, uint64_t value);
+ 
+ bool kvm_enable_x2apic(void);
+ bool kvm_has_x2apic_api(void);
++
+ #endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-kvm-kvm_get_supported_msrs-cleanup.patch b/SOURCES/kvm-target-i386-kvm-kvm_get_supported_msrs-cleanup.patch
new file mode 100644
index 0000000..3fffb50
--- /dev/null
+++ b/SOURCES/kvm-target-i386-kvm-kvm_get_supported_msrs-cleanup.patch
@@ -0,0 +1,231 @@
+From 07cb338d84e4f439b0a62fbdcbe2162936e3728a Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:38 +0000
+Subject: [PATCH 05/16] target-i386: kvm: 'kvm_get_supported_msrs' cleanup
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-6-pbonzini@redhat.com>
+Patchwork-id: 92606
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 05/15] target-i386: kvm: 'kvm_get_supported_msrs' cleanup
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+From: Li Qiang <liq3ea@163.com>
+
+Function 'kvm_get_supported_msrs' is only called once
+now, get rid of the static variable 'kvm_supported_msrs'.
+
+Signed-off-by: Li Qiang <liq3ea@163.com>
+Message-Id: <20190725151639.21693-1-liq3ea@163.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit de428cead63a958137ee63efcc3cceaf75f6c125)
+
+RHEL: no HV_X64_MSR_REENLIGHTENMENT_CONTROL
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/kvm.c | 179 +++++++++++++++++++++++++++---------------------------
+ 1 file changed, 88 insertions(+), 91 deletions(-)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 849a11a..2290c5d 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -1340,105 +1340,102 @@ static int kvm_get_supported_feature_msrs(KVMState *s)
+ 
+ static int kvm_get_supported_msrs(KVMState *s)
+ {
+-    static int kvm_supported_msrs;
+     int ret = 0;
++    struct kvm_msr_list msr_list, *kvm_msr_list;
+ 
+-    /* first time */
+-    if (kvm_supported_msrs == 0) {
+-        struct kvm_msr_list msr_list, *kvm_msr_list;
++    /*
++     *  Obtain MSR list from KVM.  These are the MSRs that we must
++     *  save/restore.
++     */
++    msr_list.nmsrs = 0;
++    ret = kvm_ioctl(s, KVM_GET_MSR_INDEX_LIST, &msr_list);
++    if (ret < 0 && ret != -E2BIG) {
++        return ret;
++    }
++    /*
++     * Old kernel modules had a bug and could write beyond the provided
++     * memory. Allocate at least a safe amount of 1K.
++     */
++    kvm_msr_list = g_malloc0(MAX(1024, sizeof(msr_list) +
++                                          msr_list.nmsrs *
++                                          sizeof(msr_list.indices[0])));
+ 
+-        kvm_supported_msrs = -1;
++    kvm_msr_list->nmsrs = msr_list.nmsrs;
++    ret = kvm_ioctl(s, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
++    if (ret >= 0) {
++        int i;
+ 
+-        /* Obtain MSR list from KVM.  These are the MSRs that we must
+-         * save/restore */
+-        msr_list.nmsrs = 0;
+-        ret = kvm_ioctl(s, KVM_GET_MSR_INDEX_LIST, &msr_list);
+-        if (ret < 0 && ret != -E2BIG) {
+-            return ret;
+-        }
+-        /* Old kernel modules had a bug and could write beyond the provided
+-           memory. Allocate at least a safe amount of 1K. */
+-        kvm_msr_list = g_malloc0(MAX(1024, sizeof(msr_list) +
+-                                              msr_list.nmsrs *
+-                                              sizeof(msr_list.indices[0])));
+-
+-        kvm_msr_list->nmsrs = msr_list.nmsrs;
+-        ret = kvm_ioctl(s, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
+-        if (ret >= 0) {
+-            int i;
+-
+-            for (i = 0; i < kvm_msr_list->nmsrs; i++) {
+-                switch (kvm_msr_list->indices[i]) {
+-                case MSR_STAR:
+-                    has_msr_star = true;
+-                    break;
+-                case MSR_VM_HSAVE_PA:
+-                    has_msr_hsave_pa = true;
+-                    break;
+-                case MSR_TSC_AUX:
+-                    has_msr_tsc_aux = true;
+-                    break;
+-                case MSR_TSC_ADJUST:
+-                    has_msr_tsc_adjust = true;
+-                    break;
+-                case MSR_IA32_TSCDEADLINE:
+-                    has_msr_tsc_deadline = true;
+-                    break;
+-                case MSR_IA32_SMBASE:
+-                    has_msr_smbase = true;
+-                    break;
+-                case MSR_SMI_COUNT:
+-                    has_msr_smi_count = true;
+-                    break;
+-                case MSR_IA32_MISC_ENABLE:
+-                    has_msr_misc_enable = true;
+-                    break;
+-                case MSR_IA32_BNDCFGS:
+-                    has_msr_bndcfgs = true;
+-                    break;
+-                case MSR_IA32_XSS:
+-                    has_msr_xss = true;
+-                    break;
+-                case HV_X64_MSR_CRASH_CTL:
+-                    has_msr_hv_crash = true;
+-                    break;
+-                case HV_X64_MSR_RESET:
+-                    has_msr_hv_reset = true;
+-                    break;
+-                case HV_X64_MSR_VP_INDEX:
+-                    has_msr_hv_vpindex = true;
+-                    break;
+-                case HV_X64_MSR_VP_RUNTIME:
+-                    has_msr_hv_runtime = true;
+-                    break;
+-                case HV_X64_MSR_SCONTROL:
+-                    has_msr_hv_synic = true;
+-                    break;
+-                case HV_X64_MSR_STIMER0_CONFIG:
+-                    has_msr_hv_stimer = true;
+-                    break;
+-                case HV_X64_MSR_TSC_FREQUENCY:
+-                    has_msr_hv_frequencies = true;
+-                    break;
+-                case MSR_IA32_SPEC_CTRL:
+-                    has_msr_spec_ctrl = true;
+-                    break;
+-                case MSR_VIRT_SSBD:
+-                    has_msr_virt_ssbd = true;
+-                    break;
+-                case MSR_IA32_ARCH_CAPABILITIES:
+-                    has_msr_arch_capabs = true;
+-                    break;
+-                case MSR_IA32_CORE_CAPABILITY:
+-                    has_msr_core_capabs = true;
+-                    break;
+-                }
++        for (i = 0; i < kvm_msr_list->nmsrs; i++) {
++            switch (kvm_msr_list->indices[i]) {
++            case MSR_STAR:
++                has_msr_star = true;
++                break;
++            case MSR_VM_HSAVE_PA:
++                has_msr_hsave_pa = true;
++                break;
++            case MSR_TSC_AUX:
++                has_msr_tsc_aux = true;
++                break;
++            case MSR_TSC_ADJUST:
++                has_msr_tsc_adjust = true;
++                break;
++            case MSR_IA32_TSCDEADLINE:
++                has_msr_tsc_deadline = true;
++                break;
++            case MSR_IA32_SMBASE:
++                has_msr_smbase = true;
++                break;
++            case MSR_SMI_COUNT:
++                has_msr_smi_count = true;
++                break;
++            case MSR_IA32_MISC_ENABLE:
++                has_msr_misc_enable = true;
++                break;
++            case MSR_IA32_BNDCFGS:
++                has_msr_bndcfgs = true;
++                break;
++            case MSR_IA32_XSS:
++                has_msr_xss = true;
++                break;
++            case HV_X64_MSR_CRASH_CTL:
++                has_msr_hv_crash = true;
++                break;
++            case HV_X64_MSR_RESET:
++                has_msr_hv_reset = true;
++                break;
++            case HV_X64_MSR_VP_INDEX:
++                has_msr_hv_vpindex = true;
++                break;
++            case HV_X64_MSR_VP_RUNTIME:
++                has_msr_hv_runtime = true;
++                break;
++            case HV_X64_MSR_SCONTROL:
++                has_msr_hv_synic = true;
++                break;
++            case HV_X64_MSR_STIMER0_CONFIG:
++                has_msr_hv_stimer = true;
++                break;
++            case HV_X64_MSR_TSC_FREQUENCY:
++                has_msr_hv_frequencies = true;
++                break;
++            case MSR_IA32_SPEC_CTRL:
++                has_msr_spec_ctrl = true;
++                break;
++            case MSR_VIRT_SSBD:
++                has_msr_virt_ssbd = true;
++                break;
++            case MSR_IA32_ARCH_CAPABILITIES:
++                has_msr_arch_capabs = true;
++                break;
++            case MSR_IA32_CORE_CAPABILITY:
++                has_msr_core_capabs = true;
++                break;
+             }
+         }
+-
+-        g_free(kvm_msr_list);
+     }
+ 
++    g_free(kvm_msr_list);
++
+     return ret;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch b/SOURCES/kvm-target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch
new file mode 100644
index 0000000..94e6eb6
--- /dev/null
+++ b/SOURCES/kvm-target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch
@@ -0,0 +1,60 @@
+From 92fad7ff756d40b231399a1eeedb7caca9ab321e Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:45 +0000
+Subject: [PATCH 12/16] target/i386: work around KVM_GET_MSRS bug for secondary
+ execution controls
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-13-pbonzini@redhat.com>
+Patchwork-id: 92609
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 12/15] target/i386: work around KVM_GET_MSRS bug for secondary execution controls
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+Some secondary controls are automatically enabled/disabled based on the CPUID
+values that are set for the guest.  However, they are still available at a
+global level and therefore should be present when KVM_GET_MSRS is sent to
+/dev/kvm.
+
+Unfortunately KVM forgot to include those, so fix that.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 048c95163b472ed737a2f0dca4f4e23a82ac2f8a)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/kvm.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index 512d7d5..6366172 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -460,6 +460,23 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+     value = msr_data.entries[0].data;
+     switch (index) {
+     case MSR_IA32_VMX_PROCBASED_CTLS2:
++        /* KVM forgot to add these bits for some time, do this ourselves.  */
++        if (kvm_arch_get_supported_cpuid(s, 0xD, 1, R_ECX) & CPUID_XSAVE_XSAVES) {
++            value |= (uint64_t)VMX_SECONDARY_EXEC_XSAVES << 32;
++        }
++        if (kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX) & CPUID_EXT_RDRAND) {
++            value |= (uint64_t)VMX_SECONDARY_EXEC_RDRAND_EXITING << 32;
++        }
++        if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & CPUID_7_0_EBX_INVPCID) {
++            value |= (uint64_t)VMX_SECONDARY_EXEC_ENABLE_INVPCID << 32;
++        }
++        if (kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX) & CPUID_7_0_EBX_RDSEED) {
++            value |= (uint64_t)VMX_SECONDARY_EXEC_RDSEED_EXITING << 32;
++        }
++        if (kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX) & CPUID_EXT2_RDTSCP) {
++            value |= (uint64_t)VMX_SECONDARY_EXEC_RDTSCP << 32;
++        }
++        /* fall through */
+     case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
+     case MSR_IA32_VMX_TRUE_PROCBASED_CTLS:
+     case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tcp_emu-Fix-oob-access.patch b/SOURCES/kvm-tcp_emu-Fix-oob-access.patch
index 5eae2ce..2c947c0 100644
--- a/SOURCES/kvm-tcp_emu-Fix-oob-access.patch
+++ b/SOURCES/kvm-tcp_emu-Fix-oob-access.patch
@@ -1,7 +1,7 @@
-From 8cf51a309acf37f2d03ed5a0a31737b884ace3f0 Mon Sep 17 00:00:00 2001
+From a0b2e40bae795bfcf58492e0081665a29a2cc9e2 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
-Date: Fri, 17 Jan 2020 11:49:40 +0000
-Subject: [PATCH 1/5] tcp_emu: Fix oob access
+Date: Fri, 17 Jan 2020 11:49:40 +0100
+Subject: [PATCH 5/7] tcp_emu: Fix oob access
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
@@ -10,10 +10,10 @@ RH-Author: Philippe Mathieu-Daudé <philmd@redhat.com>
 Message-id: <20200117114942.12236-2-philmd@redhat.com>
 Patchwork-id: 93393
 O-Subject: [RHEL-7.7.z qemu-kvm-rhev + RHEL-7.8 qemu-kvm-rhev + RHEL-7.9 qemu-kvm-rhev + RHEL-8.1.0 qemu-kvm + RHEL-8.2.0 qemu-kvm + RHEL-7.7.z qemu-kvm-ma + RHEL-7.8 qemu-kvm-ma + RHEL-7.9 qemu-kvm-ma PATCH 1/3] tcp_emu: Fix oob access
-Bugzilla: 1791565
-RH-Acked-by: Thomas Huth <thuth@redhat.com>
-RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+Bugzilla: 1791566
 RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
 
 From: Samuel Thibault <samuel.thibault@ens-lyon.org>
 
@@ -25,7 +25,7 @@ need two bytes.
       CHANGELOG.md absent in downstream]
 Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
 
-Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
 ---
  slirp/tcp_subr.c | 7 +++++++
  1 file changed, 7 insertions(+)
diff --git a/SOURCES/kvm-usb-drop-unnecessary-usb_device_post_load-checks.patch b/SOURCES/kvm-usb-drop-unnecessary-usb_device_post_load-checks.patch
new file mode 100644
index 0000000..60e2d2e
--- /dev/null
+++ b/SOURCES/kvm-usb-drop-unnecessary-usb_device_post_load-checks.patch
@@ -0,0 +1,127 @@
+From 24ca1010222cadbfc3c734406b665e6a9775d9d9 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 1 Oct 2019 18:49:25 +0100
+Subject: [PATCH 03/21] usb: drop unnecessary usb_device_post_load checks
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20191001184925.29912-2-dgilbert@redhat.com>
+Patchwork-id: 90933
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/1] usb: drop unnecessary usb_device_post_load checks
+Bugzilla: 1757482
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Jonathan Davies <jonathan.davies@nutanix.com>
+
+In usb_device_post_load, certain values of dev->setup_len or
+dev->setup_index can cause -EINVAL to be returned. One example is when
+setup_len exceeds 4096, the hard-coded value of sizeof(dev->data_buf).
+This can happen through legitimate guest activity and will cause all
+subsequent attempts to migrate the guest to fail in vmstate_load_state.
+
+The values of these variables can be set by USB packets originating in
+the guest. There are two ways in which they can be set: in
+do_token_setup and in do_parameter in hw/usb/core.c.
+
+It is easy to craft a USB packet in a guest that causes do_token_setup
+to set setup_len to a value larger than 4096. When this has been done
+once, all subsequent attempts to migrate the VM will fail in
+usb_device_post_load until the VM is next power-cycled or a
+smaller-sized USB packet is sent to the device.
+
+Sample code for achieving this in a VM started with "-device usb-tablet"
+running Linux with CONFIG_HIDRAW=y and HID_MAX_BUFFER_SIZE > 4096:
+
+  #include <sys/types.h>
+  #include <sys/stat.h>
+  #include <fcntl.h>
+  #include <unistd.h>
+
+  int main() {
+           char buf[4097];
+           int fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK);
+
+           buf[0] = 0x1;
+           write(fd, buf, 4097);
+
+           return 0;
+  }
+
+When this code is run in the VM, qemu will output:
+
+  usb_generic_handle_packet: ctrl buffer too small (4097 > 4096)
+
+A subsequent attempt to migrate the VM will fail and output the
+following on the destination host:
+
+  qemu-kvm: error while loading state for instance 0x0 of device '0000:00:06.7/1/usb-ptr'
+  qemu-kvm: load of migration failed: Invalid argument
+
+The idea behind checking the values of setup_len and setup_index before
+they are used is correct, but doing it in usb_device_post_load feels
+arbitrary, and will cause unnecessary migration failures. Indeed, none
+of the commit messages for c60174e8, 9f8e9895 and 719ffe1f justify why
+post_load is the right place to do these checks. They correctly point
+out that the important thing to protect is the usb_packet_copy.
+
+Instead, the right place to do the checks is in do_token_setup and
+do_parameter. Indeed, there are already some checks here. We can examine
+each of the disjuncts currently tested in usb_device_post_load to see
+whether any need adding to do_token_setup or do_parameter to improve
+safety there:
+
+  * dev->setup_index < 0
+     - This test is not needed because setup_index is explicitly set to
+0 in do_token_setup and do_parameter.
+
+  * dev->setup_len < 0
+     - In both do_token_setup and do_parameter, the value of setup_len
+is computed by (s->setup_buf[7] << 8) | s->setup_buf[6]. Since
+s->setup_buf is a byte array and setup_len is an int32_t, it's
+impossible for this arithmetic to set setup_len's top bit, so it can
+never be negative.
+
+  * dev->setup_index > dev->setup_len
+     - Since setup_index is 0, this is equivalent to the previous test,
+so is redundant.
+
+  * dev->setup_len > sizeof(dev->data_buf)
+     - This condition is already explicitly checked in both
+do_token_setup and do_parameter.
+
+Hence there is no need to bolster the existing checks in do_token_setup
+or do_parameter, and we can safely remove these checks from
+usb_device_post_load without reducing safety but allowing migrations to
+proceed regardless of what USB packets have been generated by the guest.
+
+Signed-off-by: Jonathan Davies <jonathan.davies@nutanix.com>
+Message-Id: <20190107175117.23769-1-jonathan.davies@nutanix.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit f30815390adb1ec153327c3832ab378e8bce9808)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/usb/bus.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/hw/usb/bus.c b/hw/usb/bus.c
+index 11f7720..5499810 100644
+--- a/hw/usb/bus.c
++++ b/hw/usb/bus.c
+@@ -59,12 +59,6 @@ static int usb_device_post_load(void *opaque, int version_id)
+     } else {
+         dev->attached = true;
+     }
+-    if (dev->setup_index < 0 ||
+-        dev->setup_len < 0 ||
+-        dev->setup_index > dev->setup_len ||
+-        dev->setup_len > sizeof(dev->data_buf)) {
+-        return -EINVAL;
+-    }
+     return 0;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-usbredir-Prevent-recursion-in-usbredir_write.patch b/SOURCES/kvm-usbredir-Prevent-recursion-in-usbredir_write.patch
new file mode 100644
index 0000000..b919808
--- /dev/null
+++ b/SOURCES/kvm-usbredir-Prevent-recursion-in-usbredir_write.patch
@@ -0,0 +1,106 @@
+From 155e3ab0c8a7886781755ba44849c77048815025 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 15 Jan 2020 12:07:41 +0100
+Subject: [PATCH 3/7] usbredir: Prevent recursion in usbredir_write
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20200115120742.19583-2-dgilbert@redhat.com>
+Patchwork-id: 93352
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 1/2] usbredir: Prevent recursion in usbredir_write
+Bugzilla: 1752320
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+
+I've got a case where usbredir_write manages to call back into itself
+via spice; this patch causes the recursion to fail (0 bytes) the write;
+this seems to avoid the deadlock I was previously seeing.
+
+I can't say I fully understand the interaction of usbredir and spice;
+but there are a few similar guards in spice and usbredir
+to catch other cases especially onces also related to spice_server_char_device_wakeup
+
+This case seems to be triggered by repeated migration+repeated
+reconnection of the viewer; but my debugging suggests the migration
+finished before this hits.
+
+The backtrace of the hang looks like:
+  reds_handle_ticket
+  reds_handle_other_links
+  reds_channel_do_link
+  red_channel_connect
+  spicevmc_connect
+  usbredir_create_parser
+  usbredirparser_do_write
+  usbredir_write
+  qemu_chr_fe_write
+  qemu_chr_write
+  qemu_chr_write_buffer
+  spice_chr_write
+  spice_server_char_device_wakeup
+  red_char_device_wakeup
+  red_char_device_write_to_device
+  vmc_write
+  usbredirparser_do_write
+  usbredir_write
+  qemu_chr_fe_write
+  qemu_chr_write
+  qemu_chr_write_buffer
+  qemu_mutex_lock_impl
+
+and we fail as we land through qemu_chr_write_buffer's lock
+twice.
+
+Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1752320
+
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-Id: <20191218113012.13331-1-dgilbert@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 394642a8d3742c885e397d5bb5ee0ec40743cdc6)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/usb/redirect.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 65a9196..3dcf76e 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -107,6 +107,7 @@ struct USBRedirDevice {
+     /* Properties */
+     CharBackend cs;
+     bool enable_streams;
++    bool in_write;
+     uint8_t debug;
+     int32_t bootindex;
+     char *filter_str;
+@@ -284,6 +285,13 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+         return 0;
+     }
+ 
++    /* Recursion check */
++    if (dev->in_write) {
++        DPRINTF("usbredir_write recursion\n");
++        return 0;
++    }
++    dev->in_write = true;
++
+     r = qemu_chr_fe_write(&dev->cs, data, count);
+     if (r < count) {
+         if (!dev->watch) {
+@@ -294,6 +302,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+             r = 0;
+         }
+     }
++    dev->in_write = false;
+     return r;
+ }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-util-mmap-alloc-Add-a-is_pmem-parameter-to-qemu_ram_.patch b/SOURCES/kvm-util-mmap-alloc-Add-a-is_pmem-parameter-to-qemu_ram_.patch
new file mode 100644
index 0000000..ec01556
--- /dev/null
+++ b/SOURCES/kvm-util-mmap-alloc-Add-a-is_pmem-parameter-to-qemu_ram_.patch
@@ -0,0 +1,120 @@
+From 5e258b59991284cf2e6bfcac04ff2de01dc83005 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 20 Aug 2019 16:12:48 +0100
+Subject: [PATCH 01/11] util/mmap-alloc: Add a 'is_pmem' parameter to
+ qemu_ram_mmap
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: plai@redhat.com
+Message-id: <1566317571-5697-2-git-send-email-plai@redhat.com>
+Patchwork-id: 90084
+O-Subject: [RHEL8.2 qemu-kvm PATCH 1/4] util/mmap-alloc: Add a 'is_pmem' parameter to qemu_ram_mmap
+Bugzilla: 1539282
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Zhang Yi <yi.z.zhang@linux.intel.com>
+
+besides the existing 'shared' flags, we are going to add
+'is_pmem' to qemu_ram_mmap(), which indicated the memory backend
+file is a persist memory.
+
+Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
+Signed-off-by: Zhang Yi <yi.z.zhang@linux.intel.com>
+Reviewed-by: Pankaj Gupta <pagupta@redhat.com>
+Message-Id: <786c46862cfeb253ee0ea2f44d62ffe76edb7fa4.1549555521.git.yi.z.zhang@linux.intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Pankaj Gupta <pagupta@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 2ac0f1621c9be59eebc844fa10361a84fd726185)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ exec.c                    |  2 +-
+ include/qemu/mmap-alloc.h | 21 ++++++++++++++++++++-
+ util/mmap-alloc.c         |  6 +++++-
+ util/oslib-posix.c        |  2 +-
+ 4 files changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 9028700..a79eaa3 100644
+--- a/exec.c
++++ b/exec.c
+@@ -1669,7 +1669,7 @@ static void *file_ram_alloc(RAMBlock *block,
+     }
+ 
+     area = qemu_ram_mmap(fd, memory, block->mr->align,
+-                         block->flags & RAM_SHARED);
++                         block->flags & RAM_SHARED, block->flags & RAM_PMEM);
+     if (area == MAP_FAILED) {
+         error_setg_errno(errp, errno,
+                          "unable to map backing store for guest RAM");
+diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
+index 50385e3..190688a 100644
+--- a/include/qemu/mmap-alloc.h
++++ b/include/qemu/mmap-alloc.h
+@@ -7,7 +7,26 @@ size_t qemu_fd_getpagesize(int fd);
+ 
+ size_t qemu_mempath_getpagesize(const char *mem_path);
+ 
+-void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared);
++/**
++ * qemu_ram_mmap: mmap the specified file or device.
++ *
++ * Parameters:
++ *  @fd: the file or the device to mmap
++ *  @size: the number of bytes to be mmaped
++ *  @align: if not zero, specify the alignment of the starting mapping address;
++ *          otherwise, the alignment in use will be determined by QEMU.
++ *  @shared: map has RAM_SHARED flag.
++ *  @is_pmem: map has RAM_PMEM flag.
++ *
++ * Return:
++ *  On success, return a pointer to the mapped area.
++ *  On failure, return MAP_FAILED.
++ */
++void *qemu_ram_mmap(int fd,
++                    size_t size,
++                    size_t align,
++                    bool shared,
++                    bool is_pmem);
+ 
+ void qemu_ram_munmap(void *ptr, size_t size);
+ 
+diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
+index 2fd8cbc..55d1890 100644
+--- a/util/mmap-alloc.c
++++ b/util/mmap-alloc.c
+@@ -73,7 +73,11 @@ size_t qemu_mempath_getpagesize(const char *mem_path)
+     return getpagesize();
+ }
+ 
+-void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared)
++void *qemu_ram_mmap(int fd,
++                    size_t size,
++                    size_t align,
++                    bool shared,
++                    bool is_pmem)
+ {
+     /*
+      * Note: this always allocates at least one extra page of virtual address
+diff --git a/util/oslib-posix.c b/util/oslib-posix.c
+index 13b6f8d..c36b2bb 100644
+--- a/util/oslib-posix.c
++++ b/util/oslib-posix.c
+@@ -130,7 +130,7 @@ void *qemu_memalign(size_t alignment, size_t size)
+ void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared)
+ {
+     size_t align = QEMU_VMALLOC_ALIGN;
+-    void *ptr = qemu_ram_mmap(-1, size, align, shared);
++    void *ptr = qemu_ram_mmap(-1, size, align, shared, false);
+ 
+     if (ptr == MAP_FAILED) {
+         return NULL;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-util-mmap-alloc-support-MAP_SYNC-in-qemu_ram_mmap.patch b/SOURCES/kvm-util-mmap-alloc-support-MAP_SYNC-in-qemu_ram_mmap.patch
new file mode 100644
index 0000000..dbbcec5
--- /dev/null
+++ b/SOURCES/kvm-util-mmap-alloc-support-MAP_SYNC-in-qemu_ram_mmap.patch
@@ -0,0 +1,176 @@
+From 4438710f7aa42f55d189d1b6adb09b1c0471495e Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 20 Aug 2019 16:12:51 +0100
+Subject: [PATCH 04/11] util/mmap-alloc: support MAP_SYNC in qemu_ram_mmap()
+
+RH-Author: plai@redhat.com
+Message-id: <1566317571-5697-5-git-send-email-plai@redhat.com>
+Patchwork-id: 90085
+O-Subject: [RHEL8.2 qemu-kvm PATCH 4/4] util/mmap-alloc: support MAP_SYNC in qemu_ram_mmap()
+Bugzilla: 1539282
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Zhang Yi <yi.z.zhang@linux.intel.com>
+
+When a file supporting DAX is used as vNVDIMM backend, mmap it with
+MAP_SYNC flag in addition which can ensure file system metadata
+synced in each guest writes to the backend file, without other QEMU
+actions (e.g., periodic fsync() by QEMU).
+
+Current, We have below different possible use cases:
+
+1. pmem=on is set, shared=on is set, MAP_SYNC supported:
+   a: backend is a dax supporting file.
+    - MAP_SYNC will active.
+   b: backend is not a dax supporting file.
+    - mmap will trigger a warning. then MAP_SYNC flag will be ignored
+
+2. The rest of cases:
+   - we will never pass the MAP_SYNC to mmap2
+
+Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
+Signed-off-by: Zhang Yi <yi.z.zhang@linux.intel.com>
+[ehabkost: Rebased patch to latest code on master]
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
+Tested-by: Wei Yang <richardw.yang@linux.intel.com>
+Message-Id: <20190422004849.26463-2-richardw.yang@linux.intel.com>
+[ehabkost: squashed documentation patch]
+Message-Id: <20190422004849.26463-3-richardw.yang@linux.intel.com>
+[ehabkost: documentation fixup]
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Pankaj Gupta <pagupta@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+
+(cherry picked from commit 119906afa5ca610adb87c55ab0d8e53c9104bfc3)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ docs/nvdimm.txt   | 22 +++++++++++++++++++---
+ qemu-options.hx   |  5 +++++
+ util/mmap-alloc.c | 41 ++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 64 insertions(+), 4 deletions(-)
+
+diff --git a/docs/nvdimm.txt b/docs/nvdimm.txt
+index 5f158a6..33ce9aa 100644
+--- a/docs/nvdimm.txt
++++ b/docs/nvdimm.txt
+@@ -143,9 +143,25 @@ Guest Data Persistence
+ ----------------------
+ 
+ Though QEMU supports multiple types of vNVDIMM backends on Linux,
+-currently the only one that can guarantee the guest write persistence
+-is the device DAX on the real NVDIMM device (e.g., /dev/dax0.0), to
+-which all guest access do not involve any host-side kernel cache.
++the only backend that can guarantee the guest write persistence is:
++
++A. DAX device (e.g., /dev/dax0.0, ) or
++B. DAX file(mounted with dax option)
++
++When using B (A file supporting direct mapping of persistent memory)
++as a backend, write persistence is guaranteed if the host kernel has
++support for the MAP_SYNC flag in the mmap system call (available
++since Linux 4.15 and on certain distro kernels) and additionally
++both 'pmem' and 'share' flags are set to 'on' on the backend.
++
++If these conditions are not satisfied i.e. if either 'pmem' or 'share'
++are not set, if the backend file does not support DAX or if MAP_SYNC
++is not supported by the host kernel, write persistence is not
++guaranteed after a system crash. For compatibility reasons, these
++conditions are ignored if not satisfied. Currently, no way is
++provided to test for them.
++For more details, please reference mmap(2) man page:
++http://man7.org/linux/man-pages/man2/mmap.2.html.
+ 
+ When using other types of backends, it's suggested to set 'unarmed'
+ option of '-device nvdimm' to 'on', which sets the unarmed flag of the
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 1b6786b..1243057 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -4057,6 +4057,11 @@ using the SNIA NVM programming model (e.g. Intel NVDIMM).
+ If @option{pmem} is set to 'on', QEMU will take necessary operations to
+ guarantee the persistence of its own writes to @option{mem-path}
+ (e.g. in vNVDIMM label emulation and live migration).
++Also, we will map the backend-file with MAP_SYNC flag, which ensures the
++file metadata is in sync for @option{mem-path} in case of host crash
++or a power failure. MAP_SYNC requires support from both the host kernel
++(since Linux kernel 4.15) and the filesystem of @option{mem-path} mounted
++with DAX option.
+ 
+ @item -object memory-backend-ram,id=@var{id},merge=@var{on|off},dump=@var{on|off},share=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave}
+ 
+diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
+index bbd9077..4873984 100644
+--- a/util/mmap-alloc.c
++++ b/util/mmap-alloc.c
+@@ -10,6 +10,13 @@
+  * later.  See the COPYING file in the top-level directory.
+  */
+ 
++#ifdef CONFIG_LINUX
++#include <linux/mman.h>
++#else  /* !CONFIG_LINUX */
++#define MAP_SYNC              0x0
++#define MAP_SHARED_VALIDATE   0x0
++#endif /* CONFIG_LINUX */
++
+ #include "qemu/osdep.h"
+ #include "qemu/mmap-alloc.h"
+ #include "qemu/host-utils.h"
+@@ -80,6 +87,7 @@ void *qemu_ram_mmap(int fd,
+                     bool is_pmem)
+ {
+     int flags;
++    int map_sync_flags = 0;
+     int guardfd;
+     size_t offset;
+     size_t pagesize;
+@@ -130,9 +138,40 @@ void *qemu_ram_mmap(int fd,
+     flags = MAP_FIXED;
+     flags |= fd == -1 ? MAP_ANONYMOUS : 0;
+     flags |= shared ? MAP_SHARED : MAP_PRIVATE;
++    if (shared && is_pmem) {
++        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
++    }
++
+     offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
+ 
+-    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, flags, fd, 0);
++    ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE,
++               flags | map_sync_flags, fd, 0);
++
++    if (ptr == MAP_FAILED && map_sync_flags) {
++        if (errno == ENOTSUP) {
++            char *proc_link, *file_name;
++            int len;
++            proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
++            file_name = g_malloc0(PATH_MAX);
++            len = readlink(proc_link, file_name, PATH_MAX - 1);
++            if (len < 0) {
++                len = 0;
++            }
++            file_name[len] = '\0';
++            fprintf(stderr, "Warning: requesting persistence across crashes "
++                    "for backend file %s failed. Proceeding without "
++                    "persistence, data might become corrupted in case of host "
++                    "crash.\n", file_name);
++            g_free(proc_link);
++            g_free(file_name);
++        }
++        /*
++         * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC,
++         * we will remove these flags to handle compatibility.
++         */
++        ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE,
++                   flags, fd, 0);
++    }
+ 
+     if (ptr == MAP_FAILED) {
+         munmap(guardptr, total);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vhost-fix-vhost_log-size-overflow-during-migration.patch b/SOURCES/kvm-vhost-fix-vhost_log-size-overflow-during-migration.patch
new file mode 100644
index 0000000..b18a29e
--- /dev/null
+++ b/SOURCES/kvm-vhost-fix-vhost_log-size-overflow-during-migration.patch
@@ -0,0 +1,81 @@
+From 8c80943cfe6e8e50f0a18cc2b4f09f9eefed47dc Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 26 Nov 2019 16:29:02 +0000
+Subject: [PATCH 16/16] vhost: fix vhost_log size overflow during migration
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20191126162902.46145-2-dgilbert@redhat.com>
+Patchwork-id: 92689
+O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 1/1] vhost: fix vhost_log size overflow during migration
+Bugzilla: 1776808
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Li Hangjing <lihangjing@baidu.com>
+
+When a guest which doesn't support multiqueue is migrated with a multi queues
+vhost-user-blk deivce, a crash will occur like:
+
+0 qemu_memfd_alloc (name=<value optimized out>, size=562949953421312, seals=<value optimized out>, fd=0x7f87171fe8b4, errp=0x7f87171fe8a8) at util/memfd.c:153
+1 0x00007f883559d7cf in vhost_log_alloc (size=70368744177664, share=true) at hw/virtio/vhost.c:186
+2 0x00007f88355a0758 in vhost_log_get (listener=0x7f8838bd7940, enable=1) at qemu-2-12/hw/virtio/vhost.c:211
+3 vhost_dev_log_resize (listener=0x7f8838bd7940, enable=1) at hw/virtio/vhost.c:263
+4 vhost_migration_log (listener=0x7f8838bd7940, enable=1) at hw/virtio/vhost.c:787
+5 0x00007f88355463d6 in memory_global_dirty_log_start () at memory.c:2503
+6 0x00007f8835550577 in ram_init_bitmaps (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2173
+7 ram_init_all (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2192
+8 ram_save_setup (f=0x7f88384ce600, opaque=0x7f8836024098) at migration/ram.c:2219
+9 0x00007f88357a419d in qemu_savevm_state_setup (f=0x7f88384ce600) at migration/savevm.c:1002
+10 0x00007f883579fc3e in migration_thread (opaque=0x7f8837530400) at migration/migration.c:2382
+11 0x00007f8832447893 in start_thread () from /lib64/libpthread.so.0
+12 0x00007f8832178bfd in clone () from /lib64/libc.so.6
+
+This is because vhost_get_log_size() returns a overflowed vhost-log size.
+In this function, it uses the uninitialized variable vqs->used_phys and
+vqs->used_size to get the vhost-log size.
+
+Signed-off-by: Li Hangjing <lihangjing@baidu.com>
+Reviewed-by: Xie Yongji <xieyongji@baidu.com>
+Reviewed-by: Chai Wen <chaiwen@baidu.com>
+Message-Id: <20190603061524.24076-1-lihangjing@baidu.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 240e647a14df9677b3a501f7b8b870e40aac3fd5)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/virtio/vhost.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
+index 1ae68ff..7bdc9c4 100644
+--- a/hw/virtio/vhost.c
++++ b/hw/virtio/vhost.c
+@@ -131,6 +131,11 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
+     }
+     for (i = 0; i < dev->nvqs; ++i) {
+         struct vhost_virtqueue *vq = dev->vqs + i;
++
++        if (!vq->used_phys && !vq->used_size) {
++            continue;
++        }
++
+         vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys,
+                               range_get_last(vq->used_phys, vq->used_size));
+     }
+@@ -168,6 +173,11 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
+     }
+     for (i = 0; i < dev->nvqs; ++i) {
+         struct vhost_virtqueue *vq = dev->vqs + i;
++
++        if (!vq->used_phys && !vq->used_size) {
++            continue;
++        }
++
+         uint64_t last = vq->used_phys + vq->used_size - 1;
+         log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1);
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-Return-true-from-virtio_queue_empty-if-broken.patch b/SOURCES/kvm-virtio-Return-true-from-virtio_queue_empty-if-broken.patch
new file mode 100644
index 0000000..675af20
--- /dev/null
+++ b/SOURCES/kvm-virtio-Return-true-from-virtio_queue_empty-if-broken.patch
@@ -0,0 +1,104 @@
+From 5bcbdfefff3209a194168dbe772c7e2f45d248f7 Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Sun, 22 Dec 2019 11:02:07 +0100
+Subject: [PATCH 2/7] virtio: Return true from virtio_queue_empty if broken
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20191222110207.21384-3-mlevitsk@redhat.com>
+Patchwork-id: 93208
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/2] virtio: Return true from virtio_queue_empty if broken
+Bugzilla: 1769613
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Fam Zheng <famz@redhat.com>
+
+Both virtio-blk and virtio-scsi use virtio_queue_empty() as the
+loop condition in VQ handlers (virtio_blk_handle_vq,
+virtio_scsi_handle_cmd_vq). When a device is marked broken in
+virtqueue_pop, for example if a vIOMMU address translation failed, we
+want to break out of the loop.
+
+This fixes a hanging problem when booting a CentOS 3.10.0-862.el7.x86_64
+kernel with ATS enabled:
+
+  $ qemu-system-x86_64 \
+    ... \
+    -device intel-iommu,intremap=on,caching-mode=on,eim=on,device-iotlb=on \
+    -device virtio-scsi-pci,iommu_platform=on,ats=on,id=scsi0,bus=pci.4,addr=0x0
+
+The dead loop happens immediately when the kernel boots and initializes
+the device, where virtio_scsi_data_plane_handle_cmd will not return:
+
+    > ...
+    > #13 0x00005586602b7793 in virtio_scsi_handle_cmd_vq
+    > #14 0x00005586602b8d66 in virtio_scsi_data_plane_handle_cmd
+    > #15 0x00005586602ddab7 in virtio_queue_notify_aio_vq
+    > #16 0x00005586602dfc9f in virtio_queue_host_notifier_aio_poll
+    > #17 0x00005586607885da in run_poll_handlers_once
+    > #18 0x000055866078880e in try_poll_mode
+    > #19 0x00005586607888eb in aio_poll
+    > #20 0x0000558660784561 in aio_wait_bh_oneshot
+    > #21 0x00005586602b9582 in virtio_scsi_dataplane_stop
+    > #22 0x00005586605a7110 in virtio_bus_stop_ioeventfd
+    > #23 0x00005586605a9426 in virtio_pci_stop_ioeventfd
+    > #24 0x00005586605ab808 in virtio_pci_common_write
+    > #25 0x0000558660242396 in memory_region_write_accessor
+    > #26 0x00005586602425ab in access_with_adjusted_size
+    > #27 0x0000558660245281 in memory_region_dispatch_write
+    > #28 0x00005586601e008e in flatview_write_continue
+    > #29 0x00005586601e01d8 in flatview_write
+    > #30 0x00005586601e04de in address_space_write
+    > #31 0x00005586601e052f in address_space_rw
+    > #32 0x00005586602607f2 in kvm_cpu_exec
+    > #33 0x0000558660227148 in qemu_kvm_cpu_thread_fn
+    > #34 0x000055866078bde7 in qemu_thread_start
+    > #35 0x00007f5784906594 in start_thread
+    > #36 0x00007f5784639e6f in clone
+
+With this patch, virtio_queue_empty will now return 1 as soon as the
+vdev is marked as broken, after a "virtio: zero sized buffers are not
+allowed" error.
+
+To be consistent, update virtio_queue_empty_rcu as well.
+
+Signed-off-by: Fam Zheng <famz@redhat.com>
+Message-Id: <20180910145616.8598-2-famz@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 2d1df8591022737b8ef19d681ff74eda389f5198)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/virtio/virtio.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 1debb01..fce199e 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -344,6 +344,10 @@ int virtio_queue_ready(VirtQueue *vq)
+  * Called within rcu_read_lock().  */
+ static int virtio_queue_empty_rcu(VirtQueue *vq)
+ {
++    if (unlikely(vq->vdev->broken)) {
++        return 1;
++    }
++
+     if (unlikely(!vq->vring.avail)) {
+         return 1;
+     }
+@@ -359,6 +363,10 @@ int virtio_queue_empty(VirtQueue *vq)
+ {
+     bool empty;
+ 
++    if (unlikely(vq->vdev->broken)) {
++        return 1;
++    }
++
+     if (unlikely(!vq->vring.avail)) {
+         return 1;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-add-ability-to-delete-vq-through-a-pointer.patch b/SOURCES/kvm-virtio-add-ability-to-delete-vq-through-a-pointer.patch
new file mode 100644
index 0000000..64b13b2
--- /dev/null
+++ b/SOURCES/kvm-virtio-add-ability-to-delete-vq-through-a-pointer.patch
@@ -0,0 +1,74 @@
+From 0f56ff85e38a3925ba8c63af9fcf6a0708f0d10f Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Tue, 4 Feb 2020 18:20:05 +0000
+Subject: [PATCH 4/6] virtio: add ability to delete vq through a pointer
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200204182007.183537-3-jusual@redhat.com>
+Patchwork-id: 93705
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/4] virtio: add ability to delete vq through a pointer
+Bugzilla: 1708480
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+Devices tend to maintain vq pointers, allow deleting them trough a vq pointer.
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+(cherry picked from commit 722f8c51d8af223751dfb1d02de40043e8ba067e)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/virtio/virtio.c         | 13 +++++++++----
+ include/hw/virtio/virtio.h |  2 ++
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 6356bf3..624f6e2 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -1601,16 +1601,21 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
+     return &vdev->vq[i];
+ }
+ 
++void virtio_delete_queue(VirtQueue *vq)
++{
++    vq->vring.num = 0;
++    vq->vring.num_default = 0;
++    vq->handle_output = NULL;
++    vq->handle_aio_output = NULL;
++}
++
+ void virtio_del_queue(VirtIODevice *vdev, int n)
+ {
+     if (n < 0 || n >= VIRTIO_QUEUE_MAX) {
+         abort();
+     }
+ 
+-    vdev->vq[n].vring.num = 0;
+-    vdev->vq[n].vring.num_default = 0;
+-    vdev->vq[n].handle_output = NULL;
+-    vdev->vq[n].handle_aio_output = NULL;
++    virtio_delete_queue(&vdev->vq[n]);
+ }
+ 
+ static void virtio_set_isr(VirtIODevice *vdev, int value)
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index 9c1fa07..90471a1 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -163,6 +163,8 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
+ 
+ void virtio_del_queue(VirtIODevice *vdev, int n);
+ 
++void virtio_delete_queue(VirtQueue *vq);
++
+ void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
+                     unsigned int len);
+ void virtqueue_flush(VirtQueue *vq, unsigned int count);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch b/SOURCES/kvm-virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch
new file mode 100644
index 0000000..4f86110
--- /dev/null
+++ b/SOURCES/kvm-virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch
@@ -0,0 +1,92 @@
+From 93a7832d5dfd83f170119e7130f3968fe37fa8e6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
+Date: Fri, 13 Sep 2019 14:16:25 +0100
+Subject: [PATCH 08/22] virtio-blk: Cancel the pending BH when the dataplane is
+ reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-id: <20190913141625.12521-2-philmd@redhat.com>
+Patchwork-id: 90453
+O-Subject: [RHEL-7.7.z qemu-kvm-rhev + RHEL-8.1.0 qemu-kvm + RHEL-AV-8.1.0 qemu-kvm PATCH v2 1/1] virtio-blk: Cancel the pending BH when the dataplane is reset
+Bugzilla: 1708459
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+
+When 'system_reset' is called, the main loop clear the memory
+region cache before the BH has a chance to execute. Later when
+the deferred function is called, some assumptions that were
+made when scheduling them are no longer true when they actually
+execute.
+
+This is what happens using a virtio-blk device (fresh RHEL7.8 install):
+
+ $ (sleep 12.3; echo system_reset; sleep 12.3; echo system_reset; sleep 1; echo q) \
+   | qemu-system-x86_64 -m 4G -smp 8 -boot menu=on \
+     -device virtio-blk-pci,id=image1,drive=drive_image1 \
+     -drive file=/var/lib/libvirt/images/rhel78.qcow2,if=none,id=drive_image1,format=qcow2,cache=none \
+     -device virtio-net-pci,netdev=net0,id=nic0,mac=52:54:00:c4:e7:84 \
+     -netdev tap,id=net0,script=/bin/true,downscript=/bin/true,vhost=on \
+     -monitor stdio -serial null -nographic
+  (qemu) system_reset
+  (qemu) system_reset
+  (qemu) qemu-system-x86_64: hw/virtio/virtio.c:225: vring_get_region_caches: Assertion `caches != NULL' failed.
+  Aborted
+
+  (gdb) bt
+  Thread 1 (Thread 0x7f109c17b680 (LWP 10939)):
+  #0  0x00005604083296d1 in vring_get_region_caches (vq=0x56040a24bdd0) at hw/virtio/virtio.c:227
+  #1  0x000056040832972b in vring_avail_flags (vq=0x56040a24bdd0) at hw/virtio/virtio.c:235
+  #2  0x000056040832d13d in virtio_should_notify (vdev=0x56040a240630, vq=0x56040a24bdd0) at hw/virtio/virtio.c:1648
+  #3  0x000056040832d1f8 in virtio_notify_irqfd (vdev=0x56040a240630, vq=0x56040a24bdd0) at hw/virtio/virtio.c:1662
+  #4  0x00005604082d213d in notify_guest_bh (opaque=0x56040a243ec0) at hw/block/dataplane/virtio-blk.c:75
+  #5  0x000056040883dc35 in aio_bh_call (bh=0x56040a243f10) at util/async.c:90
+  #6  0x000056040883dccd in aio_bh_poll (ctx=0x560409161980) at util/async.c:118
+  #7  0x0000560408842af7 in aio_dispatch (ctx=0x560409161980) at util/aio-posix.c:460
+  #8  0x000056040883e068 in aio_ctx_dispatch (source=0x560409161980, callback=0x0, user_data=0x0) at util/async.c:261
+  #9  0x00007f10a8fca06d in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
+  #10 0x0000560408841445 in glib_pollfds_poll () at util/main-loop.c:215
+  #11 0x00005604088414bf in os_host_main_loop_wait (timeout=0) at util/main-loop.c:238
+  #12 0x00005604088415c4 in main_loop_wait (nonblocking=0) at util/main-loop.c:514
+  #13 0x0000560408416b1e in main_loop () at vl.c:1923
+  #14 0x000056040841e0e8 in main (argc=20, argv=0x7ffc2c3f9c58, envp=0x7ffc2c3f9d00) at vl.c:4578
+
+Fix this by cancelling the BH when the virtio dataplane is stopped.
+
+[This is version of the patch was modified as discussed with Philippe on
+the mailing list thread.
+--Stefan]
+
+Reported-by: Yihuang Yu <yihyu@redhat.com>
+Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
+Fixes: https://bugs.launchpad.net/qemu/+bug/1839428
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-Id: <20190816171503.24761-1-philmd@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit ebb6ff25cd888a52a64a9adc3692541c6d1d9a42)
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/block/dataplane/virtio-blk.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
+index 101f32c..23e4022 100644
+--- a/hw/block/dataplane/virtio-blk.c
++++ b/hw/block/dataplane/virtio-blk.c
+@@ -292,6 +292,9 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
+         virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
+     }
+ 
++    qemu_bh_cancel(s->bh);
++    notify_guest_bh(s); /* final chance to notify guest */
++
+     /* Clean up guest notifier (irq) */
+     k->set_guest_notifiers(qbus->parent, nvqs, false);
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-gpu-block-both-2d-and-3d-rendering.patch b/SOURCES/kvm-virtio-gpu-block-both-2d-and-3d-rendering.patch
new file mode 100644
index 0000000..3a7861a
--- /dev/null
+++ b/SOURCES/kvm-virtio-gpu-block-both-2d-and-3d-rendering.patch
@@ -0,0 +1,152 @@
+From 6bf01418f12a88167ec2a3244ca7b245a53c60ae Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Wed, 16 Oct 2019 13:53:27 +0100
+Subject: [PATCH 1/2] virtio-gpu: block both 2d and 3d rendering
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: <20191016135327.23601-1-marcandre.lureau@redhat.com>
+Patchwork-id: 91814
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH] virtio-gpu: block both 2d and 3d rendering
+Bugzilla: 1674324
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1674324
+BRANCH: rhel-8.2.0
+UPSTREAM: ad341aacbf4b119a88e0f9d5a1f753d6ed0fdd86
+BREW: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=24095898
+
+Now that 2d commands are translated to 3d rendering, qemu must stop
+sending 3d updates (from 2d) to Spice as well.
+
+Fixes:
+https://bugzilla.redhat.com/show_bug.cgi?id=1674324
+
+Cc: cfergeau@redhat.com
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Christophe Fergeau <cfergeau@redhat.com>
+Tested-by: Christophe Fergeau <cfergeau@redhat.com>
+Message-id: 20190221114330.17968-4-marcandre.lureau@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+
+(cherry picked from commit ad341aacbf4b119a88e0f9d5a1f753d6ed0fdd86)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/display/virtio-gpu-3d.c     | 21 ---------------------
+ hw/display/virtio-gpu.c        | 27 ++++++++++++++++++++++-----
+ include/hw/virtio/virtio-gpu.h |  1 -
+ 3 files changed, 22 insertions(+), 27 deletions(-)
+
+diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
+index 55d7640..9654c04 100644
+--- a/hw/display/virtio-gpu-3d.c
++++ b/hw/display/virtio-gpu-3d.c
+@@ -404,11 +404,6 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
+ {
+     VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
+ 
+-    cmd->waiting = g->renderer_blocked;
+-    if (cmd->waiting) {
+-        return;
+-    }
+-
+     virgl_renderer_force_ctx_0();
+     switch (cmd->cmd_hdr.type) {
+     case VIRTIO_GPU_CMD_CTX_CREATE:
+@@ -604,22 +599,6 @@ void virtio_gpu_virgl_reset(VirtIOGPU *g)
+     }
+ }
+ 
+-void virtio_gpu_gl_block(void *opaque, bool block)
+-{
+-    VirtIOGPU *g = opaque;
+-
+-    if (block) {
+-        g->renderer_blocked++;
+-    } else {
+-        g->renderer_blocked--;
+-    }
+-    assert(g->renderer_blocked >= 0);
+-
+-    if (g->renderer_blocked == 0) {
+-        virtio_gpu_process_cmdq(g);
+-    }
+-}
+-
+ int virtio_gpu_virgl_init(VirtIOGPU *g)
+ {
+     int ret;
+diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
+index 07712d0..416ef80 100644
+--- a/hw/display/virtio-gpu.c
++++ b/hw/display/virtio-gpu.c
+@@ -888,12 +888,15 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g)
+     while (!QTAILQ_EMPTY(&g->cmdq)) {
+         cmd = QTAILQ_FIRST(&g->cmdq);
+ 
+-        /* process command */
+-        VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd,
+-              g, cmd);
++        cmd->waiting = g->renderer_blocked;
+         if (cmd->waiting) {
+             break;
+         }
++
++        /* process command */
++        VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd,
++              g, cmd);
++
+         QTAILQ_REMOVE(&g->cmdq, cmd, next);
+         if (virtio_gpu_stats_enabled(g->conf)) {
+             g->stats.requests++;
+@@ -1029,14 +1032,28 @@ static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
+     return 0;
+ }
+ 
++static void virtio_gpu_gl_block(void *opaque, bool block)
++{
++    VirtIOGPU *g = opaque;
++
++    if (block) {
++        g->renderer_blocked++;
++    } else {
++        g->renderer_blocked--;
++    }
++    assert(g->renderer_blocked >= 0);
++
++    if (g->renderer_blocked == 0) {
++        virtio_gpu_process_cmdq(g);
++    }
++}
++
+ const GraphicHwOps virtio_gpu_ops = {
+     .invalidate = virtio_gpu_invalidate_display,
+     .gfx_update = virtio_gpu_update_display,
+     .text_update = virtio_gpu_text_update,
+     .ui_info = virtio_gpu_ui_info,
+-#ifdef CONFIG_VIRGL
+     .gl_block = virtio_gpu_gl_block,
+-#endif
+ };
+ 
+ static const VMStateDescription vmstate_virtio_gpu_scanout = {
+diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
+index f95f8ce..bbeddd7 100644
+--- a/include/hw/virtio/virtio-gpu.h
++++ b/include/hw/virtio/virtio-gpu.h
+@@ -171,7 +171,6 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
+                                   struct virtio_gpu_ctrl_command *cmd);
+ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
+ void virtio_gpu_virgl_reset(VirtIOGPU *g);
+-void virtio_gpu_gl_block(void *opaque, bool block);
+ int virtio_gpu_virgl_init(VirtIOGPU *g);
+ int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
+ #endif
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-net-delete-also-control-queue-when-TX-RX-dele.patch b/SOURCES/kvm-virtio-net-delete-also-control-queue-when-TX-RX-dele.patch
new file mode 100644
index 0000000..4483a5c
--- /dev/null
+++ b/SOURCES/kvm-virtio-net-delete-also-control-queue-when-TX-RX-dele.patch
@@ -0,0 +1,52 @@
+From bbfbeacbeb992bd85c4aeab2566782f551097d18 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Tue, 4 Feb 2020 18:20:07 +0000
+Subject: [PATCH 6/6] virtio-net: delete also control queue when TX/RX deleted
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200204182007.183537-5-jusual@redhat.com>
+Patchwork-id: 93702
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 4/4] virtio-net: delete also control queue when TX/RX deleted
+Bugzilla: 1708480
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Yuri Benditovich <yuri.benditovich@daynix.com>
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1708480
+If the control queue is not deleted together with TX/RX, it
+later will be ignored in freeing cache resources and hot
+unplug will not be completed.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
+Message-Id: <20191226043649.14481-3-yuri.benditovich@daynix.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit d945d9f1731244ef341f74ede93120fc9de35913)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/virtio-net.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 90502fc..c489618 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -2100,8 +2100,12 @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
+         virtio_net_del_queue(n, i);
+     }
+ 
++    /* delete also control vq */
++    virtio_del_queue(vdev, max_queues * 2);
++
+     timer_del(n->announce_timer);
+     timer_free(n->announce_timer);
++
+     g_free(n->vqs);
+     qemu_del_nic(n->nic);
+     virtio_cleanup(vdev);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtio-reset-region-cache-when-on-queue-deletion.patch b/SOURCES/kvm-virtio-reset-region-cache-when-on-queue-deletion.patch
new file mode 100644
index 0000000..a2d1ff2
--- /dev/null
+++ b/SOURCES/kvm-virtio-reset-region-cache-when-on-queue-deletion.patch
@@ -0,0 +1,46 @@
+From 83da09b513ecdc9225188de859f4d35184094522 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Tue, 4 Feb 2020 18:20:06 +0000
+Subject: [PATCH 5/6] virtio: reset region cache when on queue deletion
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200204182007.183537-4-jusual@redhat.com>
+Patchwork-id: 93704
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 3/4] virtio: reset region cache when on queue deletion
+Bugzilla: 1708480
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Yuri Benditovich <yuri.benditovich@daynix.com>
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1708480
+Fix leak of region reference that prevents complete
+device deletion on hot unplug.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
+Message-Id: <20191226043649.14481-2-yuri.benditovich@daynix.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 421afd2fe8dd4603216cbf36081877c391f5a2a4)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/virtio/virtio.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 624f6e2..c105873 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -1607,6 +1607,7 @@ void virtio_delete_queue(VirtQueue *vq)
+     vq->vring.num_default = 0;
+     vq->handle_output = NULL;
+     vq->handle_aio_output = NULL;
++    virtio_virtqueue_reset_region_cache(vq);
+ }
+ 
+ void virtio_del_queue(VirtIODevice *vdev, int n)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vmxcap-correct-the-name-of-the-variables.patch b/SOURCES/kvm-vmxcap-correct-the-name-of-the-variables.patch
new file mode 100644
index 0000000..074f148
--- /dev/null
+++ b/SOURCES/kvm-vmxcap-correct-the-name-of-the-variables.patch
@@ -0,0 +1,55 @@
+From 0d087d9d5276866b7a7c17cdb23e71b5636dc529 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:43 +0000
+Subject: [PATCH 10/16] vmxcap: correct the name of the variables
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-11-pbonzini@redhat.com>
+Patchwork-id: 92607
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 10/15] vmxcap: correct the name of the variables
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+The low bits are 1 if the control must be one, the high bits
+are 1 if the control can be one.  Correct the variable names
+as they are very confusing.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 49d51b8927a9ea7267f4677a2e92f5046ce74025)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ scripts/kvm/vmxcap | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap
+index 99a8146..2db6832 100755
+--- a/scripts/kvm/vmxcap
++++ b/scripts/kvm/vmxcap
+@@ -51,15 +51,15 @@ class Control(object):
+         return (val & 0xffffffff, val >> 32)
+     def show(self):
+         print(self.name)
+-        mbz, mb1 = self.read2(self.cap_msr)
+-        tmbz, tmb1 = 0, 0
++        mb1, cb1 = self.read2(self.cap_msr)
++        tmb1, tcb1 = 0, 0
+         if self.true_cap_msr:
+-            tmbz, tmb1 = self.read2(self.true_cap_msr)
++            tmb1, tcb1 = self.read2(self.true_cap_msr)
+         for bit in sorted(self.bits.keys()):
+-            zero = not (mbz & (1 << bit))
+-            one = mb1 & (1 << bit)
+-            true_zero = not (tmbz & (1 << bit))
+-            true_one = tmb1 & (1 << bit)
++            zero = not (mb1 & (1 << bit))
++            one = cb1 & (1 << bit)
++            true_zero = not (tmb1 & (1 << bit))
++            true_one = tcb1 & (1 << bit)
+             s= '?'
+             if (self.true_cap_msr and true_zero and true_one
+                 and one and not zero):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-x86-Intel-AVX512_BF16-feature-enabling.patch b/SOURCES/kvm-x86-Intel-AVX512_BF16-feature-enabling.patch
new file mode 100644
index 0000000..ec27c93
--- /dev/null
+++ b/SOURCES/kvm-x86-Intel-AVX512_BF16-feature-enabling.patch
@@ -0,0 +1,201 @@
+From b6b9ed9623f87d1a2b574c8010685e68ac4cd669 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Mon, 4 Nov 2019 17:35:19 +0000
+Subject: [PATCH 2/2] x86: Intel AVX512_BF16 feature enabling
+
+RH-Author: plai@redhat.com
+Message-id: <1572888919-16839-1-git-send-email-plai@redhat.com>
+Patchwork-id: 92026
+O-Subject: [RHEL8.2 qemu-kvm PATCH] x86: Intel AVX512_BF16 feature enabling
+Bugzilla: 1642541
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Jing Liu <jing2.liu@linux.intel.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1642541
+Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=23221805
+Branch: rhel-8.2.0
+
+---
+
+Intel CooperLake cpu adds AVX512_BF16 instruction, defining as
+CPUID.(EAX=7,ECX=1):EAX[bit 05].
+
+The patch adds a property for setting the subleaf of CPUID leaf 7 in
+case that people would like to specify it.
+
+The release spec link as follows,
+https://software.intel.com/sites/default/files/managed/c5/15/\
+architecture-instruction-set-extensions-programming-reference.pdf
+
+Signed-off-by: Jing Liu <jing2.liu@linux.intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 80db491da4ce8b199e0e8d1e23943b20aab82f69)
+Signed-off-by: Paul Lai <plai@redhat.com>
+
+Resovled Conflicts:
+	target/i386/cpu.h
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 39 ++++++++++++++++++++++++++++++++++++++-
+ target/i386/cpu.h |  6 ++++++
+ target/i386/kvm.c |  3 ++-
+ 3 files changed, 46 insertions(+), 2 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 7d2afc7..0717c66 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -767,6 +767,7 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
+ #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | \
+           CPUID_7_0_ECX_LA57)
+ #define TCG_7_0_EDX_FEATURES 0
++#define TCG_7_1_EAX_FEATURES 0
+ #define TCG_APM_FEATURES 0
+ #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
+ #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
+@@ -1050,6 +1051,25 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         },
+         .tcg_features = TCG_7_0_EDX_FEATURES,
+     },
++    [FEAT_7_1_EAX] = {
++        .type = CPUID_FEATURE_WORD,
++        .feat_names = {
++            NULL, NULL, NULL, NULL,
++            NULL, "avx512-bf16", NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++            NULL, NULL, NULL, NULL,
++        },
++        .cpuid = {
++            .eax = 7,
++            .needs_ecx = true, .ecx = 1,
++            .reg = R_EAX,
++        },
++        .tcg_features = TCG_7_1_EAX_FEATURES,
++    },
+     [FEAT_8000_0007_EDX] = {
+         .type = CPUID_FEATURE_WORD,
+         .feat_names = {
+@@ -5678,13 +5698,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+     case 7:
+         /* Structured Extended Feature Flags Enumeration Leaf */
+         if (count == 0) {
+-            *eax = 0; /* Maximum ECX value for sub-leaves */
++            /* Maximum ECX value for sub-leaves */
++            *eax = env->cpuid_level_func7;
+             *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
+             *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
+             if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
+                 *ecx |= CPUID_7_0_ECX_OSPKE;
+             }
+             *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
++        } else if (count == 1) {
++            *eax = env->features[FEAT_7_1_EAX];
++            *ebx = 0;
++            *ecx = 0;
++            *edx = 0;
+         } else {
+             *eax = 0;
+             *ebx = 0;
+@@ -6289,6 +6315,11 @@ static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w)
+         x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel2, eax);
+     break;
+     }
++
++    if (eax == 7) {
++        x86_cpu_adjust_level(cpu, &env->cpuid_min_level_func7,
++                             fi->cpuid.ecx);
++    }
+ }
+ 
+ /* Calculate XSAVE components based on the configured CPU feature flags */
+@@ -6423,6 +6454,7 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+         x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX);
+         x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
+         x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
++        x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX);
+         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);
+@@ -6442,6 +6474,9 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+     }
+ 
+     /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */
++    if (env->cpuid_level_func7 == UINT32_MAX) {
++        env->cpuid_level_func7 = env->cpuid_min_level_func7;
++    }
+     if (env->cpuid_level == UINT32_MAX) {
+         env->cpuid_level = env->cpuid_min_level;
+     }
+@@ -7150,6 +7185,8 @@ static Property x86_cpu_properties[] = {
+     DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
+     DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0),
+     DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
++    DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7,
++                       UINT32_MAX),
+     DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
+     DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, UINT32_MAX),
+     DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, UINT32_MAX),
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index ecbe4f0..43a5ae0 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -509,6 +509,7 @@ typedef enum FeatureWord {
+     FEAT_7_0_EBX,       /* CPUID[EAX=7,ECX=0].EBX */
+     FEAT_7_0_ECX,       /* CPUID[EAX=7,ECX=0].ECX */
+     FEAT_7_0_EDX,       /* CPUID[EAX=7,ECX=0].EDX */
++    FEAT_7_1_EAX,       /* CPUID[EAX=7,ECX=1].EAX */
+     FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
+     FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+     FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
+@@ -732,6 +733,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass Disable */
+ 
+ #define KVM_HINTS_DEDICATED (1U << 0)
++#define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) /* AVX512 BFloat16 Instruction */
+ 
+ #define CPUID_8000_0008_EBX_WBNOINVD  (1U << 9)  /* Write back and
+                                                                              do not invalidate cache */
+@@ -1451,6 +1453,10 @@ typedef struct CPUX86State {
+     /* Fields after CPU_COMMON are preserved across CPU reset. */
+ 
+     /* processor features (e.g. for CPUID insn) */
++    /* Minimum cpuid leaf 7 value */
++    uint32_t cpuid_level_func7;
++    /* Actual cpuid leaf 7 value */
++    uint32_t cpuid_min_level_func7;
+     /* Minimum level/xlevel/xlevel2, based on CPU model + features */
+     uint32_t cpuid_min_level, cpuid_min_xlevel, cpuid_min_xlevel2;
+     /* Maximum level/xlevel/xlevel2 value for auto-assignment: */
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index ad58bfb..92eda8d 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -1058,6 +1058,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
+                 c = &cpuid_data.entries[cpuid_i++];
+             }
+             break;
++        case 0x7:
+         case 0x14: {
+             uint32_t times;
+ 
+@@ -1070,7 +1071,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
+             for (j = 1; j <= times; ++j) {
+                 if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
+                     fprintf(stderr, "cpuid_data is full, no space for "
+-                                "cpuid(eax:0x14,ecx:0x%x)\n", j);
++                                "cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
+                     abort();
+                 }
+                 c = &cpuid_data.entries[cpuid_i++];
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-x86-cpu-Add-support-for-UMONITOR-UMWAIT-TPAUSE.patch b/SOURCES/kvm-x86-cpu-Add-support-for-UMONITOR-UMWAIT-TPAUSE.patch
new file mode 100644
index 0000000..b8d255a
--- /dev/null
+++ b/SOURCES/kvm-x86-cpu-Add-support-for-UMONITOR-UMWAIT-TPAUSE.patch
@@ -0,0 +1,108 @@
+From 7e7c5dab29ed99bda0fb5d810db6f12ae4aa2608 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 26 Nov 2019 18:36:54 +0000
+Subject: [PATCH 10/11] x86/cpu: Add support for UMONITOR/UMWAIT/TPAUSE
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+x86/cpu: Add support for UMONITOR/UMWAIT/TPAUSE
+
+RH-Author: plai@redhat.com
+Message-id: <1574797015-32564-7-git-send-email-plai@redhat.com>
+Patchwork-id: 92695
+O-Subject: [RHEL8.2 qemu-kvm PATCH 6/7] x86/cpu: Add support for UMONITOR/UMWAIT/TPAUSE
+Bugzilla: 1634827
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Tao Xu <tao3.xu@intel.com>
+
+UMONITOR, UMWAIT and TPAUSE are a set of user wait instructions.
+This patch adds support for user wait instructions in KVM. Availability
+of the user wait instructions is indicated by the presence of the CPUID
+feature flag WAITPKG CPUID.0x07.0x0:ECX[5]. User wait instructions may
+be executed at any privilege level, and use IA32_UMWAIT_CONTROL MSR to
+set the maximum time.
+
+The patch enable the umonitor, umwait and tpause features in KVM.
+Because umwait and tpause can put a (psysical) CPU into a power saving
+state, by default we dont't expose it to kvm and enable it only when
+guest CPUID has it. And use QEMU command-line "-overcommit cpu-pm=on"
+(enable_cpu_pm is enabled), a VM can use UMONITOR, UMWAIT and TPAUSE
+instructions. If the instruction causes a delay, the amount of time
+delayed is called here the physical delay. The physical delay is first
+computed by determining the virtual delay (the time to delay relative to
+the VM’s timestamp counter). Otherwise, UMONITOR, UMWAIT and TPAUSE cause
+an invalid-opcode exception(#UD).
+
+The release document ref below link:
+https://software.intel.com/sites/default/files/\
+managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf
+
+Co-developed-by: Jingqi Liu <jingqi.liu@intel.com>
+Signed-off-by: Jingqi Liu <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191011074103.30393-2-tao3.xu@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 67192a298f5bf98f96e5516c3b6474c49e4853cd)
+Signed-off-by: Paul Lai <plai@redhat.com>
+
+Resolved Conflicts:
+	target/i386/cpu.c
+	target/i386/cpu.h
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 2 +-
+ target/i386/cpu.h | 2 ++
+ target/i386/kvm.c | 6 ++++++
+ 3 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 87b0502..7d2afc7 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1016,7 +1016,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         .type = CPUID_FEATURE_WORD,
+         .feat_names = {
+             NULL, "avx512vbmi", "umip", "pku",
+-            "ospke", NULL, "avx512vbmi2", NULL,
++            "ospke", "waitpkg", "avx512vbmi2", NULL,
+             "gfni", "vaes", "vpclmulqdq", "avx512vnni",
+             "avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
+             "la57", NULL, NULL, NULL,
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 7ab8ee9..fac98aa 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -708,6 +708,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_ECX_UMIP     (1U << 2)
+ #define CPUID_7_0_ECX_PKU      (1U << 3)
+ #define CPUID_7_0_ECX_OSPKE    (1U << 4)
++/* UMONITOR/UMWAIT/TPAUSE Instructions */
++#define CPUID_7_0_ECX_WAITPKG  (1U << 5)
+ #define CPUID_7_0_ECX_VBMI2    (1U << 6) /* Additional VBMI Instrs */
+ #define CPUID_7_0_ECX_GFNI     (1U << 8)
+ #define CPUID_7_0_ECX_VAES     (1U << 9)
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index ffd01f0..0fd5650 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -392,6 +392,12 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
+         if (host_tsx_blacklisted()) {
+             ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE);
+         }
++    } else if (function == 7 && index == 0 && reg == R_ECX) {
++        if (enable_cpu_pm) {
++            ret |= CPUID_7_0_ECX_WAITPKG;
++        } else {
++            ret &= ~CPUID_7_0_ECX_WAITPKG;
++        }
+     } else if (function == 7 && index == 0 && reg == R_EDX) {
+         /*
+          * Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-x86-cpu-Enable-MOVDIR64B-cpu-feature.patch b/SOURCES/kvm-x86-cpu-Enable-MOVDIR64B-cpu-feature.patch
new file mode 100644
index 0000000..005f5df
--- /dev/null
+++ b/SOURCES/kvm-x86-cpu-Enable-MOVDIR64B-cpu-feature.patch
@@ -0,0 +1,71 @@
+From 04387fbe913b26a3819d711ea91b99be6faa8616 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 26 Nov 2019 19:36:50 +0000
+Subject: [PATCH 06/11] x86/cpu: Enable MOVDIR64B cpu feature
+
+RH-Author: plai@redhat.com
+Message-id: <1574797015-32564-3-git-send-email-plai@redhat.com>
+Patchwork-id: 92691
+O-Subject: [RHEL8.2 qemu-kvm PATCH 2/7] x86/cpu: Enable MOVDIR64B cpu feature
+Bugzilla: 1634827
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+MOVDIR64B moves 64-bytes as direct-store with 64-bytes write atomicity.
+Direct store is implemented by using write combining (WC) for writing
+data directly into memory without caching the data.
+
+The bit definition:
+CPUID.(EAX=7,ECX=0):ECX[bit 28] MOVDIR64B
+
+The release document ref below link:
+https://software.intel.com/sites/default/files/managed/c5/15/\
+architecture-instruction-set-extensions-programming-reference.pdf
+
+Cc: Xu Tao <tao3.xu@intel.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Message-Id: <1541488407-17045-3-git-send-email-jingqi.liu@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 1c65775ffc2dbd276a8bffe592feba0e186a151c)
+Signed-off-by: Paul Lai <plai@redhat.com>
+
+Resolved Conflicts:
+	target/i386/cpu.c
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 2 +-
+ target/i386/cpu.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index f2ab558..307b629 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1022,7 +1022,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             "la57", NULL, NULL, NULL,
+             NULL, NULL, "rdpid", NULL,
+             NULL, "cldemote", NULL, "movdiri",
+-            NULL, NULL, NULL, NULL,
++            "movdir64b", NULL, NULL, NULL,
+         },
+         .cpuid = {
+             .eax = 7,
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 6ba0b1e..d33fa8d 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -719,6 +719,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_ECX_RDPID    (1U << 22)
+ #define CPUID_7_0_ECX_CLDEMOTE (1U << 25)  /* CLDEMOTE Instruction */
+ #define CPUID_7_0_ECX_MOVDIRI  (1U << 27)  /* MOVDIRI Instruction */
++#define CPUID_7_0_ECX_MOVDIR64B (1U << 28) /* MOVDIR64B Instruction */
+ 
+ #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 */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-x86-cpu-Enable-MOVDIRI-cpu-feature.patch b/SOURCES/kvm-x86-cpu-Enable-MOVDIRI-cpu-feature.patch
new file mode 100644
index 0000000..da10be4
--- /dev/null
+++ b/SOURCES/kvm-x86-cpu-Enable-MOVDIRI-cpu-feature.patch
@@ -0,0 +1,72 @@
+From a2765b13bbe4a4d5978cd25f451b35dbb137ab6e Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Tue, 26 Nov 2019 19:36:49 +0000
+Subject: [PATCH 05/11] x86/cpu: Enable MOVDIRI cpu feature
+
+RH-Author: plai@redhat.com
+Message-id: <1574797015-32564-2-git-send-email-plai@redhat.com>
+Patchwork-id: 92696
+O-Subject: [RHEL8.2 qemu-kvm PATCH 1/7] x86/cpu: Enable MOVDIRI cpu feature
+Bugzilla: 1634827
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+MOVDIRI moves doubleword or quadword from register to memory through
+direct store which is implemented by using write combining (WC) for
+writing data directly into memory without caching the data.
+
+The bit definition:
+CPUID.(EAX=7,ECX=0):ECX[bit 27] MOVDIRI
+
+The release document ref below link:
+https://software.intel.com/sites/default/files/managed/c5/15/\
+architecture-instruction-set-extensions-programming-reference.pdf
+
+Cc: Xu Tao <tao3.xu@intel.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Message-Id: <1541488407-17045-2-git-send-email-jingqi.liu@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 24261de4916596d8ab5f5fee67e9e7a19e8325a5)
+Signed-off-by: Paul Lai <plai@redhat.com>
+
+Resolved Conflicts:
+	target/i386/cpu.c
+	target/i386/cpu.h
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 2 +-
+ target/i386/cpu.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index ef6b958..f2ab558 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1021,7 +1021,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             "avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
+             "la57", NULL, NULL, NULL,
+             NULL, NULL, "rdpid", NULL,
+-            NULL, "cldemote", NULL, NULL,
++            NULL, "cldemote", NULL, "movdiri",
+             NULL, NULL, NULL, NULL,
+         },
+         .cpuid = {
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 8d8814e..6ba0b1e 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -718,6 +718,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_ECX_LA57     (1U << 16)
+ #define CPUID_7_0_ECX_RDPID    (1U << 22)
+ #define CPUID_7_0_ECX_CLDEMOTE (1U << 25)  /* CLDEMOTE Instruction */
++#define CPUID_7_0_ECX_MOVDIRI  (1U << 27)  /* MOVDIRI Instruction */
+ 
+ #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 */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-x86-cpu-use-FeatureWordArray-to-define-filtered_feat.patch b/SOURCES/kvm-x86-cpu-use-FeatureWordArray-to-define-filtered_feat.patch
new file mode 100644
index 0000000..65cceca
--- /dev/null
+++ b/SOURCES/kvm-x86-cpu-use-FeatureWordArray-to-define-filtered_feat.patch
@@ -0,0 +1,44 @@
+From 8caf8808acc4b95a0bde03430b214a298da3a71a Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Fri, 22 Nov 2019 11:53:34 +0000
+Subject: [PATCH 01/16] x86/cpu: use FeatureWordArray to define
+ filtered_features
+
+RH-Author: Paolo Bonzini <pbonzini@redhat.com>
+Message-id: <20191122115348.25000-2-pbonzini@redhat.com>
+Patchwork-id: 92599
+O-Subject: [RHEL8.2/rhel qemu-kvm PATCH 01/15] x86/cpu: use FeatureWordArray to define filtered_features
+Bugzilla: 1689270
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
+
+From: Wei Yang <richardw.yang@linux.intel.com>
+
+Use the same definition as features/user_features in CPUX86State.
+
+Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
+Message-Id: <20190620023746.9869-1-richardw.yang@linux.intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit f69ecddb4a02b5071297427b4ebb3d8f0cea7323)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 273c90b..add8b60 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -1409,7 +1409,7 @@ struct X86CPU {
+     bool cache_info_passthrough;
+ 
+     /* Features that were filtered out because of missing host capabilities */
+-    uint32_t filtered_features[FEATURE_WORDS];
++    FeatureWordArray filtered_features;
+ 
+     /* Enable PMU CPUID bits. This can't be enabled by default yet because
+      * it doesn't have ABI stability guarantees, as it passes all PMU CPUID
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-xhci-recheck-slot-status.patch b/SOURCES/kvm-xhci-recheck-slot-status.patch
new file mode 100644
index 0000000..0fa6716
--- /dev/null
+++ b/SOURCES/kvm-xhci-recheck-slot-status.patch
@@ -0,0 +1,77 @@
+From 1406157e5944e023b07a644d5a8377db708134e8 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 15 Jan 2020 12:07:42 +0100
+Subject: [PATCH 4/7] xhci: recheck slot status
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20200115120742.19583-3-dgilbert@redhat.com>
+Patchwork-id: 93353
+O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/2] xhci: recheck slot status
+Bugzilla: 1752320
+RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+Factor out slot status check into a helper function.  Add an additional
+check after completing transfers.  This is needed in case a guest
+queues multiple transfers in a row and a device unplug happens while
+qemu processes them.
+
+Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1786413
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-id: 20200107083606.12393-1-kraxel@redhat.com
+(cherry picked from commit 236846a019c4f7aa3111026fc9a1fe09684c8978)
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ hw/usb/hcd-xhci.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
+index 45fcce3..e63a603 100644
+--- a/hw/usb/hcd-xhci.c
++++ b/hw/usb/hcd-xhci.c
+@@ -1853,6 +1853,13 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
+     xhci_kick_epctx(epctx, streamid);
+ }
+ 
++static bool xhci_slot_ok(XHCIState *xhci, int slotid)
++{
++    return (xhci->slots[slotid - 1].uport &&
++            xhci->slots[slotid - 1].uport->dev &&
++            xhci->slots[slotid - 1].uport->dev->attached);
++}
++
+ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
+ {
+     XHCIState *xhci = epctx->xhci;
+@@ -1870,9 +1877,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
+ 
+     /* If the device has been detached, but the guest has not noticed this
+        yet the 2 above checks will succeed, but we must NOT continue */
+-    if (!xhci->slots[epctx->slotid - 1].uport ||
+-        !xhci->slots[epctx->slotid - 1].uport->dev ||
+-        !xhci->slots[epctx->slotid - 1].uport->dev->attached) {
++    if (!xhci_slot_ok(xhci, epctx->slotid)) {
+         return;
+     }
+ 
+@@ -1968,6 +1973,10 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
+         } else {
+             xhci_fire_transfer(xhci, xfer, epctx);
+         }
++        if (!xhci_slot_ok(xhci, epctx->slotid)) {
++            /* surprise removal -> stop processing */
++            break;
++        }
+         if (xfer->complete) {
+             /* update ring dequeue ptr */
+             xhci_set_ep_state(xhci, epctx, stctx, epctx->state);
+-- 
+1.8.3.1
+
diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec
index 7075b63..90638d7 100644
--- a/SPECS/qemu-kvm.spec
+++ b/SPECS/qemu-kvm.spec
@@ -67,7 +67,7 @@ Obsoletes: %1-rhev
 Summary: QEMU is a machine emulator and virtualizer
 Name: qemu-kvm
 Version: 2.12.0
-Release: 88%{?dist}.3
+Release: 99%{?dist}
 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
 Epoch: 15
 License: GPLv2 and GPLv2+ and CC-BY
@@ -1681,22 +1681,201 @@ Patch820: kvm-iotests-Filter-175-s-allocation-information.patch
 Patch821: kvm-block-posix-Always-allocate-the-first-block.patch
 # For bz#1738839 - I/O error when virtio-blk disk is backed by a raw image on 4k disk
 Patch822: kvm-iotests-Test-allocate_first_block-with-O_DIRECT.patch
-# For bz#1764829 - RHEL8.1 Snapshot3 - Passthrough PCI card goes into error state if used in domain (kvm) [rhel-8.1.0.z]
-Patch823: kvm-s390-PCI-fix-IOMMU-region-init.patch
-# For bz#1771970 - CVE-2019-11135 virt:rhel/qemu-kvm: hw: TSX Transaction Asynchronous Abort (TAA) [rhel-8.1.0.z]
-Patch824: kvm-target-i386-Export-TAA_NO-bit-to-guests.patch
-# For bz#1771970 - CVE-2019-11135 virt:rhel/qemu-kvm: hw: TSX Transaction Asynchronous Abort (TAA) [rhel-8.1.0.z]
-Patch825: kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch
-# For bz#1791565 - CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.1.0.z]
-Patch826: kvm-tcp_emu-Fix-oob-access.patch
-# For bz#1791565 - CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.1.0.z]
-Patch827: kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch
-# For bz#1791565 - CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.1.0.z]
-Patch828: kvm-slirp-use-correct-size-while-emulating-commands.patch
-# For bz#1794500 - CVE-2020-1711 qemu-kvm: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-8.1.0.z]
-Patch829: kvm-iscsi-Avoid-potential-for-get_status-overflow.patch
-# For bz#1794500 - CVE-2020-1711 qemu-kvm: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-8.1.0.z]
-Patch830: kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
+# For bz#1749022 - Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09)
+Patch823: kvm-accel-use-g_strsplit-for-parsing-accelerator-names.patch
+# For bz#1749022 - Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09)
+Patch824: kvm-opts-don-t-silently-truncate-long-parameter-keys.patch
+# For bz#1749022 - Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09)
+Patch825: kvm-opts-don-t-silently-truncate-long-option-values.patch
+# For bz#1749022 - Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09)
+Patch826: kvm-i386-fix-regression-parsing-multiboot-initrd-modules.patch
+# For bz#1749022 - Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09)
+Patch827: kvm-i386-only-parse-the-initrd_filename-once-for-multibo.patch
+# For bz#1749022 - Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09)
+Patch828: kvm-opts-remove-redundant-check-for-NULL-parameter.patch
+# For bz#1749724 - CVE-2019-15890 qemu-kvm: QEMU: Slirp: use-after-free during packet reassembly [rhel-8]
+Patch829: kvm-Using-ip_deq-after-m_free-might-read-pointers-from-a.patch
+# For bz#1708459 - qemu-kvm core dumped when repeat "system_reset" multiple times during guest boot
+Patch830: kvm-virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch
+# For bz#1660909 - [IBM 8.2 FEAT] KVM s390x: Crypto Passthrough Interrupt Support - qemu part
+Patch831: kvm-s390x-cpumodel-Rework-CPU-feature-definition.patch
+# For bz#1660909 - [IBM 8.2 FEAT] KVM s390x: Crypto Passthrough Interrupt Support - qemu part
+Patch832: kvm-s390x-cpumodel-Set-up-CPU-model-for-AQIC-interceptio.patch
+# For bz#1746361 - ccid: Fix incorrect dwProtocol advertisement of T=0
+Patch833: kvm-ccid-Fix-dwProtocols-advertisement-of-T-0.patch
+# For bz#1754643 - RHEL8.1 Snapshot3 - Passthrough PCI card goes into error state if used in domain (kvm)
+Patch834: kvm-s390-PCI-fix-IOMMU-region-init.patch
+# For bz#1607367 - After boot failed, guest should not reboot when set reboot-timeout < -1
+Patch835: kvm-fw_cfg-Improve-error-message-when-can-t-load-splash-.patch
+# For bz#1607367 - After boot failed, guest should not reboot when set reboot-timeout < -1
+Patch836: kvm-fw_cfg-Fix-boot-bootsplash-error-checking.patch
+# For bz#1607367 - After boot failed, guest should not reboot when set reboot-timeout < -1
+Patch837: kvm-fw_cfg-Fix-boot-reboot-timeout-error-checking.patch
+# For bz#1607367 - After boot failed, guest should not reboot when set reboot-timeout < -1
+Patch838: kvm-hw-nvram-fw_cfg-Store-reboot-timeout-as-little-endia.patch
+# For bz#1738440 - For intel-iommu, qemu shows conflict behaviors between booting a guest with vfio and hot plugging vfio device
+Patch839: kvm-intel_iommu-Correct-caching-mode-error-message.patch
+# For bz#1738440 - For intel-iommu, qemu shows conflict behaviors between booting a guest with vfio and hot plugging vfio device
+Patch840: kvm-intel_iommu-Sanity-check-vfio-pci-config-on-machine-.patch
+# For bz#1738440 - For intel-iommu, qemu shows conflict behaviors between booting a guest with vfio and hot plugging vfio device
+Patch841: kvm-qdev-machine-Introduce-hotplug_allowed-hook.patch
+# For bz#1738440 - For intel-iommu, qemu shows conflict behaviors between booting a guest with vfio and hot plugging vfio device
+Patch842: kvm-pc-q35-Disallow-vfio-pci-hotplug-without-VT-d-cachin.patch
+# For bz#1738440 - For intel-iommu, qemu shows conflict behaviors between booting a guest with vfio and hot plugging vfio device
+Patch843: kvm-intel_iommu-Remove-the-caching-mode-check-during-fla.patch
+# For bz#1651474 - RHEL8.0 Beta - [4.18.0-32.el8.ppc64le] Guest VM crashes during vcpu hotplug with specific numa configuration (kvm)
+Patch844: kvm-pseries-do-not-allow-memory-less-cpu-less-NUMA-node.patch
+# For bz#1719127 - [Intel 8.2 Bug] warning shown when boot VM with “–cpu host” or “–cpu other mode” on ICX platform (physical)
+Patch845: kvm-i386-Don-t-print-warning-if-phys-bits-was-set-automa.patch
+# For bz#1693140 - aarch64: qemu: remove smbus_eeprom and i2c from config
+Patch846: kvm-Disable-CONFIG_I2C-and-CONFIG_IOH3420.patch
+# For bz#1757482 - Fail to migrate a rhel6.10-mt7.6 guest with dimm device
+Patch847: kvm-usb-drop-unnecessary-usb_device_post_load-checks.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch848: kvm-pc-bios-s390-ccw-define-loadparm-length.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch849: kvm-pc-bios-s390-ccw-net-Use-diag308-to-reset-machine-be.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch850: kvm-s390-bios-decouple-cio-setup-from-virtio.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch851: kvm-s390-bios-decouple-common-boot-logic-from-virtio.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch852: kvm-s390-bios-Clean-up-cio.h.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch853: kvm-s390-bios-Decouple-channel-i-o-logic-from-virtio.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch854: kvm-s390-bios-Map-low-core-memory.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch855: kvm-s390-bios-ptr2u32-and-u32toptr.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch856: kvm-s390-bios-Support-for-running-format-0-1-channel-pro.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch857: kvm-s390-bios-cio-error-handling.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch858: kvm-s390-bios-Extend-find_dev-for-non-virtio-devices.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch859: kvm-s390-bios-Factor-finding-boot-device-out-of-virtio-c.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch860: kvm-s390-bios-Refactor-virtio-to-run-channel-programs-vi.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch861: kvm-s390-bios-Use-control-unit-type-to-determine-boot-me.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch862: kvm-s390-bios-Add-channel-command-codes-structs-needed-f.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch863: kvm-s390-bios-Support-booting-from-real-dasd-device.patch
+# For bz#1664376 - [IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part
+Patch864: kvm-s390-bios-Use-control-unit-type-to-find-bootable-dev.patch
+# For bz#1660906 - [IBM 8.2 FEAT] KVM s390x: Crypto Passthrough Hotplug - qemu part
+Patch865: kvm-s390x-vfio-ap-Implement-hot-plug-unplug-of-vfio-ap-d.patch
+# For bz#1730969 - [ppc] qmp: The 'arch' value returned by the command 'query-cpus-fast' does not match
+Patch866: kvm-qapi-fill-in-CpuInfoFast.arch-in-query-cpus-fast.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch867: kvm-curl-Keep-pointer-to-the-CURLState-in-CURLSocket.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch868: kvm-curl-Keep-socket-until-the-end-of-curl_sock_cb.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch869: kvm-curl-Check-completion-in-curl_multi_do.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch870: kvm-curl-Pass-CURLSocket-to-curl_multi_do.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch871: kvm-curl-Report-only-ready-sockets.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch872: kvm-curl-Handle-success-in-multi_check_completion.patch
+# For bz#1744602 - qemu-img gets stuck when stream-converting from http
+Patch873: kvm-curl-Check-curl_multi_add_handle-s-return-code.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch874: kvm-x86-cpu-use-FeatureWordArray-to-define-filtered_feat.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch875: kvm-i386-Add-x-force-features-option-for-testing.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch876: kvm-target-i386-define-a-new-MSR-based-feature-word-FEAT.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch877: kvm-i386-display-known-CPUID-features-linewrapped-in-alp.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch878: kvm-target-i386-kvm-kvm_get_supported_msrs-cleanup.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch879: kvm-target-i386-handle-filtered_features-in-a-new-functi.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch880: kvm-target-i386-introduce-generic-feature-dependency-mec.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch881: kvm-target-i386-expand-feature-words-to-64-bits.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch882: kvm-target-i386-add-VMX-definitions.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch883: kvm-vmxcap-correct-the-name-of-the-variables.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch884: kvm-target-i386-add-VMX-features.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch885: kvm-target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch886: kvm-target-i386-adjust-for-missing-VMX-features.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch887: kvm-target-i386-add-VMX-features-to-named-CPU-models.patch
+# For bz#1689270 - Nested KVM: limit VMX features according to CPU models - Slow Train
+Patch888: kvm-target-i386-add-VMX-features-to-named-CPU-models-RHE.patch
+# For bz#1776808 - qemu-kvm crashes when Windows VM is migrated with multiqueue
+Patch889: kvm-vhost-fix-vhost_log-size-overflow-during-migration.patch
+# For bz#1771971 - CVE-2019-11135 virt:rhel/qemu-kvm: hw: TSX Transaction Asynchronous Abort (TAA) [rhel-8.2.0]
+Patch890: kvm-target-i386-Export-TAA_NO-bit-to-guests.patch
+# For bz#1771971 - CVE-2019-11135 virt:rhel/qemu-kvm: hw: TSX Transaction Asynchronous Abort (TAA) [rhel-8.2.0]
+Patch891: kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch
+# For bz#1539282 - [Intel 8.2 Feature][Crystal Ridge] Support MAP_SYNC  - qemu-kvm
+Patch892: kvm-util-mmap-alloc-Add-a-is_pmem-parameter-to-qemu_ram_.patch
+# For bz#1539282 - [Intel 8.2 Feature][Crystal Ridge] Support MAP_SYNC  - qemu-kvm
+Patch893: kvm-mmap-alloc-unfold-qemu_ram_mmap.patch
+# For bz#1539282 - [Intel 8.2 Feature][Crystal Ridge] Support MAP_SYNC  - qemu-kvm
+Patch894: kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch
+# For bz#1539282 - [Intel 8.2 Feature][Crystal Ridge] Support MAP_SYNC  - qemu-kvm
+Patch895: kvm-util-mmap-alloc-support-MAP_SYNC-in-qemu_ram_mmap.patch
+# For bz#1634827 - [Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu
+Patch896: kvm-x86-cpu-Enable-MOVDIRI-cpu-feature.patch
+# For bz#1634827 - [Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu
+Patch897: kvm-x86-cpu-Enable-MOVDIR64B-cpu-feature.patch
+# For bz#1634827 - [Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu
+Patch898: kvm-add-call-to-qemu_add_opts-for-overcommit-option.patch
+# For bz#1634827 - [Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu
+Patch899: kvm-support-overcommit-cpu-pm-on-off.patch
+Patch900: kvm-i386-cpu-make-cpu-host-support-monitor-mwait.patch
+# For bz#1634827 - [Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu
+Patch901: kvm-x86-cpu-Add-support-for-UMONITOR-UMWAIT-TPAUSE.patch
+# For bz#1634827 - [Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu
+Patch902: kvm-target-i386-Add-support-for-save-load-IA32_UMWAIT_CO.patch
+# For bz#1674324 - With <graphics type='spice'><gl enable='on'/>, qemu either refuses to start completely or spice-server crashes afterwards
+Patch903: kvm-virtio-gpu-block-both-2d-and-3d-rendering.patch
+# For bz#1642541 - [Intel 8.2 Feature] qemu-kvm Enable BFloat16 data type support
+Patch904: kvm-x86-Intel-AVX512_BF16-feature-enabling.patch
+# For bz#1741346 - Remove the "cpu64-rhel6" CPU from qemu-kvm
+Patch905: kvm-i386-Remove-cpu64-rhel6-CPU-model.patch
+# For bz#1769613 - [SEV] kexec mays hang at "[sda] Synchronizing SCSI cache " before switching to new kernel
+Patch906: kvm-exec-Fix-MAP_RAM-for-cached-access.patch
+# For bz#1769613 - [SEV] kexec mays hang at "[sda] Synchronizing SCSI cache " before switching to new kernel
+Patch907: kvm-virtio-Return-true-from-virtio_queue_empty-if-broken.patch
+# For bz#1752320 - vm gets stuck when migrate vm back and forth with remote-viewer trying to connect
+Patch908: kvm-usbredir-Prevent-recursion-in-usbredir_write.patch
+# For bz#1752320 - vm gets stuck when migrate vm back and forth with remote-viewer trying to connect
+Patch909: kvm-xhci-recheck-slot-status.patch
+# For bz#1791566 - CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.2.0]
+Patch910: kvm-tcp_emu-Fix-oob-access.patch
+# For bz#1791566 - CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.2.0]
+Patch911: kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch
+# For bz#1791566 - CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.2.0]
+Patch912: kvm-slirp-use-correct-size-while-emulating-commands.patch
+# For bz#1794501 - CVE-2020-1711 qemu-kvm: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-8.2.0]
+Patch913: kvm-iscsi-Avoid-potential-for-get_status-overflow.patch
+# For bz#1794501 - CVE-2020-1711 qemu-kvm: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-8.2.0]
+Patch914: kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch
+# For bz#1708480 - [Q35] No "DEVICE_DELETED" event in qmp after unplug virtio-net-pci device
+Patch915: kvm-clean-up-callback-when-del-virtqueue.patch
+# For bz#1708480 - [Q35] No "DEVICE_DELETED" event in qmp after unplug virtio-net-pci device
+Patch916: kvm-virtio-add-ability-to-delete-vq-through-a-pointer.patch
+# For bz#1708480 - [Q35] No "DEVICE_DELETED" event in qmp after unplug virtio-net-pci device
+Patch917: kvm-virtio-reset-region-cache-when-on-queue-deletion.patch
+# For bz#1708480 - [Q35] No "DEVICE_DELETED" event in qmp after unplug virtio-net-pci device
+Patch918: kvm-virtio-net-delete-also-control-queue-when-TX-RX-dele.patch
+# For bz#1791677 - QEMU: Slirp: disable emulation of tcp programs like ftp IRC etc. [rhel-8]
+Patch919: kvm-slirp-disable-tcp_emu.patch
+# For bz#1790308 - qemu-kvm core dump when do L1 guest live migration with L2 guest running
+Patch920: kvm-target-i386-kvm-initialize-feature-MSRs-very-early.patch
 
 BuildRequires: zlib-devel
 BuildRequires: glib2-devel
@@ -2583,27 +2762,187 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
 
 
 %changelog
-* Tue Feb 11 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-88.el8_1_0.3
-- kvm-tcp_emu-Fix-oob-access.patch [bz#1791565]
-- kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch [bz#1791565]
-- kvm-slirp-use-correct-size-while-emulating-commands.patch [bz#1791565]
-- kvm-iscsi-Avoid-potential-for-get_status-overflow.patch [bz#1794500]
-- kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch [bz#1794500]
-- Resolves: bz#1791565
-  (CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.1.0.z])
-- Resolves: bz#1794500
-  (CVE-2020-1711 qemu-kvm: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-8.1.0.z])
-
-* Tue Dec 10 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-88.el8_1_0.2
-- kvm-target-i386-Export-TAA_NO-bit-to-guests.patch [bz#1771970]
-- kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch [bz#1771970]
-- Resolves: bz#1771970
-  (CVE-2019-11135 virt:rhel/qemu-kvm: hw: TSX Transaction Asynchronous Abort (TAA) [rhel-8.1.0.z])
-
-* Mon Dec 02 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-88.el8_1_0.1
-- kvm-s390-PCI-fix-IOMMU-region-init.patch [bz#1764829]
-- Resolves: bz#1764829
-  (RHEL8.1 Snapshot3 - Passthrough PCI card goes into error state if used in domain (kvm) [rhel-8.1.0.z])
+* Fri Feb 21 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-99.el8
+- kvm-slirp-disable-tcp_emu.patch [bz#1791677]
+- kvm-target-i386-kvm-initialize-feature-MSRs-very-early.patch [bz#1790308]
+- Resolves: bz#1790308
+  (qemu-kvm core dump when do L1 guest live migration with L2 guest running)
+- Resolves: bz#1791677
+  (QEMU: Slirp: disable emulation of tcp programs like ftp IRC etc. [rhel-8])
+
+* Mon Feb 10 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-98.el8
+- kvm-iscsi-Avoid-potential-for-get_status-overflow.patch [bz#1794501]
+- kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch [bz#1794501]
+- kvm-clean-up-callback-when-del-virtqueue.patch [bz#1708480]
+- kvm-virtio-add-ability-to-delete-vq-through-a-pointer.patch [bz#1708480]
+- kvm-virtio-reset-region-cache-when-on-queue-deletion.patch [bz#1708480]
+- kvm-virtio-net-delete-also-control-queue-when-TX-RX-dele.patch [bz#1708480]
+- Resolves: bz#1708480
+  ([Q35] No "DEVICE_DELETED" event in qmp after unplug virtio-net-pci device)
+- Resolves: bz#1794501
+  (CVE-2020-1711 qemu-kvm: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-8.2.0])
+
+* Fri Jan 24 2020 Miroslav Rezanina <mrezanin@redhat.com> - 2.12.0-97.el8
+- kvm-exec-Fix-MAP_RAM-for-cached-access.patch [bz#1769613]
+- kvm-virtio-Return-true-from-virtio_queue_empty-if-broken.patch [bz#1769613]
+- kvm-usbredir-Prevent-recursion-in-usbredir_write.patch [bz#1752320]
+- kvm-xhci-recheck-slot-status.patch [bz#1752320]
+- kvm-tcp_emu-Fix-oob-access.patch [bz#1791566]
+- kvm-slirp-use-correct-size-while-emulating-IRC-commands.patch [bz#1791566]
+- kvm-slirp-use-correct-size-while-emulating-commands.patch [bz#1791566]
+- Resolves: bz#1752320
+  (vm gets stuck when migrate vm back and forth with remote-viewer trying to connect)
+- Resolves: bz#1769613
+  ([SEV] kexec mays hang at "[sda] Synchronizing SCSI cache " before switching to new kernel)
+- Resolves: bz#1791566
+  (CVE-2020-7039 virt:rhel/qemu-kvm: QEMU: slirp: OOB buffer access while emulating tcp protocols in tcp_emu() [rhel-8.2.0])
+
+* Tue Jan 07 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-96.el8
+- kvm-i386-Remove-cpu64-rhel6-CPU-model.patch [bz#1741346]
+- Resolves: bz#1741346
+  (Remove the "cpu64-rhel6" CPU from qemu-kvm)
+
+* Thu Jan 02 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-95.el8
+- kvm-virtio-gpu-block-both-2d-and-3d-rendering.patch [bz#1674324]
+- kvm-x86-Intel-AVX512_BF16-feature-enabling.patch [bz#1642541]
+- Resolves: bz#1642541
+  ([Intel 8.2 Feature] qemu-kvm Enable BFloat16 data type support)
+- Resolves: bz#1674324
+  (With <graphics type='spice'><gl enable='on'/>, qemu either refuses to start completely or spice-server crashes afterwards)
+
+* Wed Dec 18 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-94.el8
+- kvm-util-mmap-alloc-Add-a-is_pmem-parameter-to-qemu_ram_.patch [bz#1539282]
+- kvm-mmap-alloc-unfold-qemu_ram_mmap.patch [bz#1539282]
+- kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch [bz#1539282]
+- kvm-util-mmap-alloc-support-MAP_SYNC-in-qemu_ram_mmap.patch [bz#1539282]
+- kvm-x86-cpu-Enable-MOVDIRI-cpu-feature.patch [bz#1634827]
+- kvm-x86-cpu-Enable-MOVDIR64B-cpu-feature.patch [bz#1634827]
+- kvm-add-call-to-qemu_add_opts-for-overcommit-option.patch [bz#1634827]
+- kvm-support-overcommit-cpu-pm-on-off.patch [bz#1634827]
+- kvm-i386-cpu-make-cpu-host-support-monitor-mwait.patch []
+- kvm-x86-cpu-Add-support-for-UMONITOR-UMWAIT-TPAUSE.patch [bz#1634827]
+- kvm-target-i386-Add-support-for-save-load-IA32_UMWAIT_CO.patch [bz#1634827]
+- Resolves: bz#1539282
+  ([Intel 8.2 Feature][Crystal Ridge] Support MAP_SYNC  - qemu-kvm)
+- Resolves: bz#1634827
+  ([Intel 8.2 Feat] KVM Enable SnowRidge Accelerator Interface Architecture (AIA) - qemu)
+
+* Wed Dec 11 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-93.el8
+- kvm-target-i386-Export-TAA_NO-bit-to-guests.patch [bz#1771971]
+- kvm-target-i386-add-support-for-MSR_IA32_TSX_CTRL.patch [bz#1771971]
+- Resolves: bz#1771971
+  (CVE-2019-11135 virt:rhel/qemu-kvm: hw: TSX Transaction Asynchronous Abort (TAA) [rhel-8.2.0])
+
+* Mon Dec 02 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-92.el8
+- kvm-x86-cpu-use-FeatureWordArray-to-define-filtered_feat.patch [bz#1689270]
+- kvm-i386-Add-x-force-features-option-for-testing.patch [bz#1689270]
+- kvm-target-i386-define-a-new-MSR-based-feature-word-FEAT.patch [bz#1689270]
+- kvm-i386-display-known-CPUID-features-linewrapped-in-alp.patch [bz#1689270]
+- kvm-target-i386-kvm-kvm_get_supported_msrs-cleanup.patch [bz#1689270]
+- kvm-target-i386-handle-filtered_features-in-a-new-functi.patch [bz#1689270]
+- kvm-target-i386-introduce-generic-feature-dependency-mec.patch [bz#1689270]
+- kvm-target-i386-expand-feature-words-to-64-bits.patch [bz#1689270]
+- kvm-target-i386-add-VMX-definitions.patch [bz#1689270]
+- kvm-vmxcap-correct-the-name-of-the-variables.patch [bz#1689270]
+- kvm-target-i386-add-VMX-features.patch [bz#1689270]
+- kvm-target-i386-work-around-KVM_GET_MSRS-bug-for-seconda.patch [bz#1689270]
+- kvm-target-i386-adjust-for-missing-VMX-features.patch [bz#1689270]
+- kvm-target-i386-add-VMX-features-to-named-CPU-models.patch [bz#1689270]
+- kvm-target-i386-add-VMX-features-to-named-CPU-models-RHE.patch [bz#1689270]
+- kvm-vhost-fix-vhost_log-size-overflow-during-migration.patch [bz#1776808]
+- Resolves: bz#1689270
+  (Nested KVM: limit VMX features according to CPU models - Slow Train)
+- Resolves: bz#1776808
+  (qemu-kvm crashes when Windows VM is migrated with multiqueue)
+
+* Wed Nov 27 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-91.el8
+- kvm-qapi-fill-in-CpuInfoFast.arch-in-query-cpus-fast.patch [bz#1730969]
+- kvm-curl-Keep-pointer-to-the-CURLState-in-CURLSocket.patch [bz#1744602]
+- kvm-curl-Keep-socket-until-the-end-of-curl_sock_cb.patch [bz#1744602]
+- kvm-curl-Check-completion-in-curl_multi_do.patch [bz#1744602]
+- kvm-curl-Pass-CURLSocket-to-curl_multi_do.patch [bz#1744602]
+- kvm-curl-Report-only-ready-sockets.patch [bz#1744602]
+- kvm-curl-Handle-success-in-multi_check_completion.patch [bz#1744602]
+- kvm-curl-Check-curl_multi_add_handle-s-return-code.patch [bz#1744602]
+- Resolves: bz#1730969
+  ([ppc] qmp: The 'arch' value returned by the command 'query-cpus-fast' does not match)
+- Resolves: bz#1744602
+  (qemu-img gets stuck when stream-converting from http)
+
+* Tue Nov 12 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-90.el8
+- kvm-i386-Don-t-print-warning-if-phys-bits-was-set-automa.patch [bz#1719127]
+- kvm-Disable-CONFIG_I2C-and-CONFIG_IOH3420.patch [bz#1693140]
+- kvm-usb-drop-unnecessary-usb_device_post_load-checks.patch [bz#1757482]
+- kvm-pc-bios-s390-ccw-define-loadparm-length.patch [bz#1664376]
+- kvm-pc-bios-s390-ccw-net-Use-diag308-to-reset-machine-be.patch [bz#1664376]
+- kvm-s390-bios-decouple-cio-setup-from-virtio.patch [bz#1664376]
+- kvm-s390-bios-decouple-common-boot-logic-from-virtio.patch [bz#1664376]
+- kvm-s390-bios-Clean-up-cio.h.patch [bz#1664376]
+- kvm-s390-bios-Decouple-channel-i-o-logic-from-virtio.patch [bz#1664376]
+- kvm-s390-bios-Map-low-core-memory.patch [bz#1664376]
+- kvm-s390-bios-ptr2u32-and-u32toptr.patch [bz#1664376]
+- kvm-s390-bios-Support-for-running-format-0-1-channel-pro.patch [bz#1664376]
+- kvm-s390-bios-cio-error-handling.patch [bz#1664376]
+- kvm-s390-bios-Extend-find_dev-for-non-virtio-devices.patch [bz#1664376]
+- kvm-s390-bios-Factor-finding-boot-device-out-of-virtio-c.patch [bz#1664376]
+- kvm-s390-bios-Refactor-virtio-to-run-channel-programs-vi.patch [bz#1664376]
+- kvm-s390-bios-Use-control-unit-type-to-determine-boot-me.patch [bz#1664376]
+- kvm-s390-bios-Add-channel-command-codes-structs-needed-f.patch [bz#1664376]
+- kvm-s390-bios-Support-booting-from-real-dasd-device.patch [bz#1664376]
+- kvm-s390-bios-Use-control-unit-type-to-find-bootable-dev.patch [bz#1664376]
+- kvm-s390x-vfio-ap-Implement-hot-plug-unplug-of-vfio-ap-d.patch [bz#1660906]
+- Resolves: bz#1660906
+  ([IBM 8.2 FEAT] KVM s390x: Crypto Passthrough Hotplug - qemu part)
+- Resolves: bz#1664376
+  ([IBM 8.2 FEAT] CCW IPL Support (kvm) - qemu part)
+- Resolves: bz#1693140
+  (aarch64: qemu: remove smbus_eeprom and i2c from config)
+- Resolves: bz#1719127
+  ([Intel 8.2 Bug] warning shown when boot VM with “–cpu host” or “–cpu other mode” on ICX platform (physical))
+- Resolves: bz#1757482
+  (Fail to migrate a rhel6.10-mt7.6 guest with dimm device)
+
+* Mon Oct 14 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-89.el8
+- kvm-accel-use-g_strsplit-for-parsing-accelerator-names.patch [bz#1749022]
+- kvm-opts-don-t-silently-truncate-long-parameter-keys.patch [bz#1749022]
+- kvm-opts-don-t-silently-truncate-long-option-values.patch [bz#1749022]
+- kvm-i386-fix-regression-parsing-multiboot-initrd-modules.patch [bz#1749022]
+- kvm-i386-only-parse-the-initrd_filename-once-for-multibo.patch [bz#1749022]
+- kvm-opts-remove-redundant-check-for-NULL-parameter.patch [bz#1749022]
+- kvm-Using-ip_deq-after-m_free-might-read-pointers-from-a.patch [bz#1749724]
+- kvm-virtio-blk-Cancel-the-pending-BH-when-the-dataplane-.patch [bz#1708459]
+- kvm-s390x-cpumodel-Rework-CPU-feature-definition.patch [bz#1660909]
+- kvm-s390x-cpumodel-Set-up-CPU-model-for-AQIC-interceptio.patch [bz#1660909]
+- kvm-ccid-Fix-dwProtocols-advertisement-of-T-0.patch [bz#1746361]
+- kvm-s390-PCI-fix-IOMMU-region-init.patch [bz#1754643]
+- kvm-fw_cfg-Improve-error-message-when-can-t-load-splash-.patch [bz#1607367]
+- kvm-fw_cfg-Fix-boot-bootsplash-error-checking.patch [bz#1607367]
+- kvm-fw_cfg-Fix-boot-reboot-timeout-error-checking.patch [bz#1607367]
+- kvm-hw-nvram-fw_cfg-Store-reboot-timeout-as-little-endia.patch [bz#1607367]
+- kvm-intel_iommu-Correct-caching-mode-error-message.patch [bz#1738440]
+- kvm-intel_iommu-Sanity-check-vfio-pci-config-on-machine-.patch [bz#1738440]
+- kvm-qdev-machine-Introduce-hotplug_allowed-hook.patch [bz#1738440]
+- kvm-pc-q35-Disallow-vfio-pci-hotplug-without-VT-d-cachin.patch [bz#1738440]
+- kvm-intel_iommu-Remove-the-caching-mode-check-during-fla.patch [bz#1738440]
+- kvm-pseries-do-not-allow-memory-less-cpu-less-NUMA-node.patch [bz#1651474]
+- Resolves: bz#1607367
+  (After boot failed, guest should not reboot when set reboot-timeout < -1)
+- Resolves: bz#1651474
+  (RHEL8.0 Beta - [4.18.0-32.el8.ppc64le] Guest VM crashes during vcpu hotplug with specific numa configuration (kvm))
+- Resolves: bz#1660909
+  ([IBM 8.2 FEAT] KVM s390x: Crypto Passthrough Interrupt Support - qemu part)
+- Resolves: bz#1708459
+  (qemu-kvm core dumped when repeat "system_reset" multiple times during guest boot)
+- Resolves: bz#1738440
+  (For intel-iommu, qemu shows conflict behaviors between booting a guest with vfio and hot plugging vfio device)
+- Resolves: bz#1746361
+  (ccid: Fix incorrect dwProtocol advertisement of T=0)
+- Resolves: bz#1749022
+  (Please backport 950c4e6c94b1 ("opts: don't silently truncate long option values", 2018-05-09))
+- Resolves: bz#1749724
+  (CVE-2019-15890 qemu-kvm: QEMU: Slirp: use-after-free during packet reassembly [rhel-8])
+- Resolves: bz#1754643
+  (RHEL8.1 Snapshot3 - Passthrough PCI card goes into error state if used in domain (kvm))
 
 * Fri Sep 13 2019 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 2.12.0-88.el8
 - Revert fix for bz#1749724 - this got delayed to 8.2