diff --git a/SOURCES/kvm-ACPI-add-expected-files-for-HMAT-tests-acpihmat.patch b/SOURCES/kvm-ACPI-add-expected-files-for-HMAT-tests-acpihmat.patch
new file mode 100644
index 0000000..7310f17
--- /dev/null
+++ b/SOURCES/kvm-ACPI-add-expected-files-for-HMAT-tests-acpihmat.patch
@@ -0,0 +1,41 @@
+From ff8529dcbf86b3a086d64dd630cf6a687603c571 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:55 +0100
+Subject: [PATCH 12/12] ACPI: add expected files for HMAT tests (acpihmat)
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-12-plai@redhat.com>
+Patchwork-id: 96742
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 11/11] ACPI: add expected files for HMAT tests (acpihmat)
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 48892c6c8def6624a0ed57e2bd6c2a0a9878b973)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/bios-tables-test-allowed-diff.h | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
+index 3c9e0c9..dfb8523 100644
+--- a/tests/bios-tables-test-allowed-diff.h
++++ b/tests/bios-tables-test-allowed-diff.h
+@@ -1,9 +1 @@
+ /* List of comma-separated changed AML files to ignore */
+-"tests/data/acpi/pc/APIC.acpihmat",
+-"tests/data/acpi/pc/SRAT.acpihmat",
+-"tests/data/acpi/pc/HMAT.acpihmat",
+-"tests/data/acpi/pc/DSDT.acpihmat",
+-"tests/data/acpi/q35/APIC.acpihmat",
+-"tests/data/acpi/q35/SRAT.acpihmat",
+-"tests/data/acpi/q35/HMAT.acpihmat",
+-"tests/data/acpi/q35/DSDT.acpihmat",
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Don-t-leak-memory-when-reallocation-fails.patch b/SOURCES/kvm-Don-t-leak-memory-when-reallocation-fails.patch
new file mode 100644
index 0000000..5747672
--- /dev/null
+++ b/SOURCES/kvm-Don-t-leak-memory-when-reallocation-fails.patch
@@ -0,0 +1,58 @@
+From bcb6107f98d7b1edf687d7afd552a4528b7e673b Mon Sep 17 00:00:00 2001
+From: jmaloy <jmaloy@redhat.com>
+Date: Tue, 12 May 2020 21:15:13 +0100
+Subject: [PATCH 2/7] Don't leak memory when reallocation fails.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: jmaloy <jmaloy@redhat.com>
+Message-id: <20200512211514.1398384-2-jmaloy@redhat.com>
+Patchwork-id: 96412
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/2] Don't leak memory when reallocation fails.
+Bugzilla: 1749737
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: Jindrich Novy <jnovy@redhat.com>
+
+Signed-off-by: Jindrich Novy <jnovy@redhat.com>
+[ Marc-André - modified to use a temporary variable ]
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+(cherry picked from libslirp commit d171af3732a0610a25334b06b77fa547bd677918)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ slirp/src/sbuf.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/slirp/src/sbuf.c b/slirp/src/sbuf.c
+index abced48..0569c34 100644
+--- a/slirp/src/sbuf.c
++++ b/slirp/src/sbuf.c
+@@ -39,13 +39,16 @@ void sbreserve(struct sbuf *sb, int size)
+     if (sb->sb_data) {
+         /* Already alloced, realloc if necessary */
+         if (sb->sb_datalen != size) {
+-            sb->sb_wptr = sb->sb_rptr = sb->sb_data =
+-                (char *)realloc(sb->sb_data, size);
++            char *new = realloc(sb->sb_data, size);
+             sb->sb_cc = 0;
+-            if (sb->sb_wptr)
++            if (new) {
++                sb->sb_data = sb->sb_wptr = sb->sb_rptr = new;
+                 sb->sb_datalen = size;
+-            else
++            } else {
++                free(sb->sb_data);
++                sb->sb_data = sb->sb_wptr = sb->sb_rptr = NULL;
+                 sb->sb_datalen = 0;
++            }
+         }
+     } else {
+         sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Fix-use-afte-free-in-ip_reass-CVE-2020-1983.patch b/SOURCES/kvm-Fix-use-afte-free-in-ip_reass-CVE-2020-1983.patch
new file mode 100644
index 0000000..535c3af
--- /dev/null
+++ b/SOURCES/kvm-Fix-use-afte-free-in-ip_reass-CVE-2020-1983.patch
@@ -0,0 +1,60 @@
+From a33ea192428d9c9307f1140f3e25631a6ef7657c Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Sat, 20 Jun 2020 15:02:59 -0400
+Subject: [PATCH 12/12] Fix use-afte-free in ip_reass() (CVE-2020-1983)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20200620150259.3352467-2-jmaloy@redhat.com>
+Patchwork-id: 97678
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 1/1] Fix use-afte-free in ip_reass() (CVE-2020-1983)
+Bugzilla: 1838070
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+The q pointer is updated when the mbuf data is moved from m_dat to
+m_ext.
+
+m_ext buffer may also be realloc()'ed and moved during m_cat():
+q should also be updated in this case.
+
+Reported-by: Aviv Sasson <asasson@paloaltonetworks.com>
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+(cherry picked from libslirp commit 9bd6c5913271eabcb7768a58197ed3301fe19f2d)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ slirp/src/ip_input.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c
+index df1c846ade..0f5d522ec1 100644
+--- a/slirp/src/ip_input.c
++++ b/slirp/src/ip_input.c
+@@ -329,7 +329,7 @@ insert:
+     q = fp->frag_link.next;
+     m = dtom(slirp, q);
+ 
+-    int was_ext = m->m_flags & M_EXT;
++    int delta = (char *)q - (m->m_flags & M_EXT ? m->m_ext : m->m_dat);
+ 
+     q = (struct ipasfrag *)q->ipf_next;
+     while (q != (struct ipasfrag *)&fp->frag_link) {
+@@ -353,8 +353,7 @@ insert:
+      * the old buffer (in the mbuf), so we must point ip
+      * into the new buffer.
+      */
+-    if (!was_ext && m->m_flags & M_EXT) {
+-        int delta = (char *)q - m->m_dat;
++    if (m->m_flags & M_EXT) {
+         q = (struct ipasfrag *)(m->m_ext + delta);
+     }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-MAINTAINERS-fix-qcow2-bitmap.c-under-Dirty-Bitmaps-h.patch b/SOURCES/kvm-MAINTAINERS-fix-qcow2-bitmap.c-under-Dirty-Bitmaps-h.patch
new file mode 100644
index 0000000..dce89d9
--- /dev/null
+++ b/SOURCES/kvm-MAINTAINERS-fix-qcow2-bitmap.c-under-Dirty-Bitmaps-h.patch
@@ -0,0 +1,55 @@
+From e3bec8c83459a68ae0c08e2ae0f1dbef24872d59 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:09 +0100
+Subject: [PATCH 04/26] MAINTAINERS: fix qcow2-bitmap.c under Dirty Bitmaps
+ header
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-2-eblake@redhat.com>
+Patchwork-id: 97068
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 01/12] MAINTAINERS: fix qcow2-bitmap.c under Dirty Bitmaps header
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+
+Somehow I wrote not full path to the file. Fix that.
+
+Also, while being here, rearrange entries, so that includes go first,
+then block, than migration, than util.
+
+Fixes: 052db8e71444d
+Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 00637c6b0b67694127cc01dd75f3626da23acdaa)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ MAINTAINERS | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index d1b3e26..3a81ac9 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1873,12 +1873,12 @@ M: John Snow <jsnow@redhat.com>
+ R: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+ L: qemu-block@nongnu.org
+ S: Supported
+-F: util/hbitmap.c
+-F: block/dirty-bitmap.c
+ F: include/qemu/hbitmap.h
+ F: include/block/dirty-bitmap.h
+-F: qcow2-bitmap.c
++F: block/dirty-bitmap.c
++F: block/qcow2-bitmap.c
+ F: migration/block-dirty-bitmap.c
++F: util/hbitmap.c
+ F: tests/test-hbitmap.c
+ F: docs/interop/bitmaps.rst
+ T: git https://github.com/jnsnow/qemu.git bitmaps
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Replace-remaining-malloc-free-user-with-glib.patch b/SOURCES/kvm-Replace-remaining-malloc-free-user-with-glib.patch
new file mode 100644
index 0000000..71e6e47
--- /dev/null
+++ b/SOURCES/kvm-Replace-remaining-malloc-free-user-with-glib.patch
@@ -0,0 +1,118 @@
+From c012dc9b501d96a2ff54a8a7a182726043b69aeb Mon Sep 17 00:00:00 2001
+From: jmaloy <jmaloy@redhat.com>
+Date: Tue, 12 May 2020 21:15:14 +0100
+Subject: [PATCH 3/7] Replace remaining malloc/free user with glib
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: jmaloy <jmaloy@redhat.com>
+Message-id: <20200512211514.1398384-3-jmaloy@redhat.com>
+Patchwork-id: 96413
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] Replace remaining malloc/free user with glib
+Bugzilla: 1749737
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+glib mem functions are already used in various places. Let's not mix
+the two, and instead abort on OOM conditions.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+(cherry picked from libslirp commit 3a494648526be4eb96cba739a816a60e933ffd14)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ slirp/src/sbuf.c     | 21 ++++++---------------
+ slirp/src/socket.c   |  2 +-
+ slirp/src/tcp_subr.c |  8 ++------
+ 3 files changed, 9 insertions(+), 22 deletions(-)
+
+diff --git a/slirp/src/sbuf.c b/slirp/src/sbuf.c
+index 0569c34..eab87f3 100644
+--- a/slirp/src/sbuf.c
++++ b/slirp/src/sbuf.c
+@@ -9,7 +9,7 @@ static void sbappendsb(struct sbuf *sb, struct mbuf *m);
+ 
+ void sbfree(struct sbuf *sb)
+ {
+-    free(sb->sb_data);
++    g_free(sb->sb_data);
+ }
+ 
+ bool sbdrop(struct sbuf *sb, int num)
+@@ -39,24 +39,15 @@ void sbreserve(struct sbuf *sb, int size)
+     if (sb->sb_data) {
+         /* Already alloced, realloc if necessary */
+         if (sb->sb_datalen != size) {
+-            char *new = realloc(sb->sb_data, size);
++            char *new = g_realloc(sb->sb_data, size);
+             sb->sb_cc = 0;
+-            if (new) {
+-                sb->sb_data = sb->sb_wptr = sb->sb_rptr = new;
+-                sb->sb_datalen = size;
+-            } else {
+-                free(sb->sb_data);
+-                sb->sb_data = sb->sb_wptr = sb->sb_rptr = NULL;
+-                sb->sb_datalen = 0;
+-            }
++            sb->sb_data = sb->sb_wptr = sb->sb_rptr = new;
++            sb->sb_datalen = size;
+         }
+     } else {
+-        sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
++        sb->sb_wptr = sb->sb_rptr = sb->sb_data = g_malloc(size);
+         sb->sb_cc = 0;
+-        if (sb->sb_wptr)
+-            sb->sb_datalen = size;
+-        else
+-            sb->sb_datalen = 0;
++        sb->sb_datalen = size;
+     }
+ }
+ 
+diff --git a/slirp/src/socket.c b/slirp/src/socket.c
+index 34daffc..ace18bf 100644
+--- a/slirp/src/socket.c
++++ b/slirp/src/socket.c
+@@ -95,7 +95,7 @@ void sofree(struct socket *so)
+         remque(so); /* crashes if so is not in a queue */
+ 
+     if (so->so_tcpcb) {
+-        free(so->so_tcpcb);
++        g_free(so->so_tcpcb);
+     }
+     g_free(so);
+ }
+diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c
+index 26d4ead..4e5a801 100644
+--- a/slirp/src/tcp_subr.c
++++ b/slirp/src/tcp_subr.c
+@@ -255,11 +255,7 @@ struct tcpcb *tcp_newtcpcb(struct socket *so)
+ {
+     register struct tcpcb *tp;
+ 
+-    tp = (struct tcpcb *)malloc(sizeof(*tp));
+-    if (tp == NULL)
+-        return ((struct tcpcb *)0);
+-
+-    memset((char *)tp, 0, sizeof(struct tcpcb));
++    tp = g_new0(struct tcpcb, 1);
+     tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
+     tp->t_maxseg = (so->so_ffamily == AF_INET) ? TCP_MSS : TCP6_MSS;
+ 
+@@ -330,7 +326,7 @@ struct tcpcb *tcp_close(struct tcpcb *tp)
+         remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
+         m_free(m);
+     }
+-    free(tp);
++    g_free(tp);
+     so->so_tcpcb = NULL;
+     /* clobber input socket cache if we're closing the cached connection */
+     if (so == slirp->tcp_last_so)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-Revert-RHEL-disable-hostmem-memfd.patch b/SOURCES/kvm-Revert-RHEL-disable-hostmem-memfd.patch
new file mode 100644
index 0000000..f959752
--- /dev/null
+++ b/SOURCES/kvm-Revert-RHEL-disable-hostmem-memfd.patch
@@ -0,0 +1,58 @@
+From 559d5899473dea180ced39a32bfbfbf2310c6e04 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Mon, 25 May 2020 15:33:06 +0100
+Subject: [PATCH 4/7] Revert "RHEL: disable hostmem-memfd"
+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: <20200525153306.15373-1-marcandre.lureau@redhat.com>
+Patchwork-id: 96747
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH] Revert "RHEL: disable hostmem-memfd"
+Bugzilla: 1839030
+RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1839030
+BRANCH: rhel-av-8.2.1
+UPSTREAM: RHEL-only
+BREW: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=28817132
+
+This reverts commit f7587ddb9a2731bf678a24156b6285dda79a4b2b.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ backends/Makefile.objs | 3 +--
+ util/memfd.c           | 2 +-
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/backends/Makefile.objs b/backends/Makefile.objs
+index f328d40..f069111 100644
+--- a/backends/Makefile.objs
++++ b/backends/Makefile.objs
+@@ -16,5 +16,4 @@ endif
+ 
+ common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_VIRTIO)) += vhost-user.o
+ 
+-# RHEL: disable memfd
+-# common-obj-$(CONFIG_LINUX) += hostmem-memfd.o
++common-obj-$(CONFIG_LINUX) += hostmem-memfd.o
+diff --git a/util/memfd.c b/util/memfd.c
+index 3303ec9..4a3c07e 100644
+--- a/util/memfd.c
++++ b/util/memfd.c
+@@ -193,7 +193,7 @@ bool qemu_memfd_alloc_check(void)
+  */
+ bool qemu_memfd_check(unsigned int flags)
+ {
+-#if 0 /* RHEL: memfd support disabled */
++#ifdef CONFIG_LINUX
+     int mfd = memfd_create("test", flags | MFD_CLOEXEC);
+ 
+     if (mfd >= 0) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-backup-Improve-error-for-bdrv_getlength-failure.patch b/SOURCES/kvm-backup-Improve-error-for-bdrv_getlength-failure.patch
new file mode 100644
index 0000000..8fa2629
--- /dev/null
+++ b/SOURCES/kvm-backup-Improve-error-for-bdrv_getlength-failure.patch
@@ -0,0 +1,51 @@
+From fba183faf8ce819262a1a47f8531ea68051cdce7 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:19 +0100
+Subject: [PATCH 20/26] backup: Improve error for bdrv_getlength() failure
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-6-kwolf@redhat.com>
+Patchwork-id: 97103
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 05/11] backup: Improve error for bdrv_getlength() failure
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+bdrv_get_device_name() will be an empty string with modern management
+tools that don't use -drive. Use bdrv_get_device_or_node_name() instead
+so that the node name is used if the BlockBackend is anonymous.
+
+While at it, start with upper case to make the message consistent with
+the rest of the function.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Message-Id: <20200430142755.315494-3-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 58226634c4b02af7b10862f7fbd3610a344bfb7f)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/backup.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block/backup.c b/block/backup.c
+index ec50946..7c6ddd2 100644
+--- a/block/backup.c
++++ b/block/backup.c
+@@ -408,8 +408,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+ 
+     len = bdrv_getlength(bs);
+     if (len < 0) {
+-        error_setg_errno(errp, -len, "unable to get length for '%s'",
+-                         bdrv_get_device_name(bs));
++        error_setg_errno(errp, -len, "Unable to get length for '%s'",
++                         bdrv_get_device_or_node_name(bs));
+         goto error;
+     }
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-backup-Make-sure-that-source-and-target-size-match.patch b/SOURCES/kvm-backup-Make-sure-that-source-and-target-size-match.patch
new file mode 100644
index 0000000..05b5d10
--- /dev/null
+++ b/SOURCES/kvm-backup-Make-sure-that-source-and-target-size-match.patch
@@ -0,0 +1,124 @@
+From e56abd782be8bb41bb07c0317d008f95ec9a8ee5 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:20 +0100
+Subject: [PATCH 21/26] backup: Make sure that source and target size match
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-7-kwolf@redhat.com>
+Patchwork-id: 97107
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 06/11] backup: Make sure that source and target size match
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+Since the introduction of a backup filter node in commit 00e30f05d, the
+backup block job crashes when the target image is smaller than the
+source image because it will try to write after the end of the target
+node without having BLK_PERM_RESIZE. (Previously, the BlockBackend layer
+would have caught this and errored out gracefully.)
+
+We can fix this and even do better than the old behaviour: Check that
+source and target have the same image size at the start of the block job
+and unshare BLK_PERM_RESIZE. (This permission was already unshared
+before the same commit 00e30f05d, but the BlockBackend that was used to
+make the restriction was removed without a replacement.) This will
+immediately error out when starting the job instead of only when writing
+to a block that doesn't exist in the target.
+
+Longer target than source would technically work because we would never
+write to blocks that don't exist, but semantically these are invalid,
+too, because a backup is supposed to create a copy, not just an image
+that starts with a copy.
+
+Fixes: 00e30f05de1d19586345ec373970ef4c192c6270
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1778593
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200430142755.315494-4-kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 958a04bd32af18d9a207bcc78046e56a202aebc2)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/backup-top.c | 14 +++++++++-----
+ block/backup.c     | 14 +++++++++++++-
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/block/backup-top.c b/block/backup-top.c
+index b8d863f..6756091 100644
+--- a/block/backup-top.c
++++ b/block/backup-top.c
+@@ -143,8 +143,10 @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
+          *
+          * Share write to target (child_file), to not interfere
+          * with guest writes to its disk which may be in target backing chain.
++         * Can't resize during a backup block job because we check the size
++         * only upfront.
+          */
+-        *nshared = BLK_PERM_ALL;
++        *nshared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
+         *nperm = BLK_PERM_WRITE;
+     } else {
+         /* Source child */
+@@ -154,7 +156,7 @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
+         if (perm & BLK_PERM_WRITE) {
+             *nperm = *nperm | BLK_PERM_CONSISTENT_READ;
+         }
+-        *nshared &= ~BLK_PERM_WRITE;
++        *nshared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
+     }
+ }
+ 
+@@ -187,10 +189,12 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
+ {
+     Error *local_err = NULL;
+     BDRVBackupTopState *state;
+-    BlockDriverState *top = bdrv_new_open_driver(&bdrv_backup_top_filter,
+-                                                 filter_node_name,
+-                                                 BDRV_O_RDWR, errp);
++    BlockDriverState *top;
++
++    assert(source->total_sectors == target->total_sectors);
+ 
++    top = bdrv_new_open_driver(&bdrv_backup_top_filter, filter_node_name,
++                               BDRV_O_RDWR, errp);
+     if (!top) {
+         return NULL;
+     }
+diff --git a/block/backup.c b/block/backup.c
+index 7c6ddd2..821c9fb 100644
+--- a/block/backup.c
++++ b/block/backup.c
+@@ -348,7 +348,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+                   BlockCompletionFunc *cb, void *opaque,
+                   JobTxn *txn, Error **errp)
+ {
+-    int64_t len;
++    int64_t len, target_len;
+     BackupBlockJob *job = NULL;
+     int64_t cluster_size;
+     BdrvRequestFlags write_flags;
+@@ -413,6 +413,18 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+         goto error;
+     }
+ 
++    target_len = bdrv_getlength(target);
++    if (target_len < 0) {
++        error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
++                         bdrv_get_device_or_node_name(bs));
++        goto error;
++    }
++
++    if (target_len != len) {
++        error_setg(errp, "Source and target image have different sizes");
++        goto error;
++    }
++
+     cluster_size = backup_calculate_cluster_size(target, errp);
+     if (cluster_size < 0) {
+         goto error;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Add-flags-to-BlockDriver.bdrv_co_truncate.patch b/SOURCES/kvm-block-Add-flags-to-BlockDriver.bdrv_co_truncate.patch
new file mode 100644
index 0000000..bc67279
--- /dev/null
+++ b/SOURCES/kvm-block-Add-flags-to-BlockDriver.bdrv_co_truncate.patch
@@ -0,0 +1,283 @@
+From 13e2076f5c4adbc9a3f96c8978150aa5e423e14a Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:30 +0100
+Subject: [PATCH 02/17] block: Add flags to BlockDriver.bdrv_co_truncate()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-2-kwolf@redhat.com>
+Patchwork-id: 97448
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 01/11] block: Add flags to BlockDriver.bdrv_co_truncate()
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
+driver callbacks, and a supported_truncate_flags field in
+BlockDriverState that allows drivers to advertise support for request
+flags in the context of truncate.
+
+For now, we always pass 0 and no drivers declare support for any flag.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 92b92799dc8662b6f71809100a4aabc1ae408ebb)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/crypto.c              |  3 ++-
+ block/file-posix.c          |  2 +-
+ block/file-win32.c          |  2 +-
+ block/gluster.c             |  1 +
+ block/io.c                  |  8 +++++++-
+ block/iscsi.c               |  2 +-
+ block/nfs.c                 |  3 ++-
+ block/qcow2.c               |  2 +-
+ block/qed.c                 |  1 +
+ block/raw-format.c          |  2 +-
+ block/rbd.c                 |  1 +
+ block/sheepdog.c            |  4 ++--
+ block/ssh.c                 |  2 +-
+ include/block/block_int.h   | 10 +++++++++-
+ tests/test-block-iothread.c |  3 ++-
+ 15 files changed, 33 insertions(+), 13 deletions(-)
+
+diff --git a/block/crypto.c b/block/crypto.c
+index 5e3b15c..6e4b726 100644
+--- a/block/crypto.c
++++ b/block/crypto.c
+@@ -299,7 +299,8 @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
+ 
+ static int coroutine_fn
+ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
+-                         PreallocMode prealloc, Error **errp)
++                         PreallocMode prealloc, BdrvRequestFlags flags,
++                         Error **errp)
+ {
+     BlockCrypto *crypto = bs->opaque;
+     uint64_t payload_offset =
+diff --git a/block/file-posix.c b/block/file-posix.c
+index 1609598..7551e8d 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -2021,7 +2021,7 @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
+ 
+ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
+                                         bool exact, PreallocMode prealloc,
+-                                        Error **errp)
++                                        BdrvRequestFlags flags, Error **errp)
+ {
+     BDRVRawState *s = bs->opaque;
+     struct stat st;
+diff --git a/block/file-win32.c b/block/file-win32.c
+index 1585983..a6b0dda 100644
+--- a/block/file-win32.c
++++ b/block/file-win32.c
+@@ -469,7 +469,7 @@ static void raw_close(BlockDriverState *bs)
+ 
+ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
+                                         bool exact, PreallocMode prealloc,
+-                                        Error **errp)
++                                        BdrvRequestFlags flags, Error **errp)
+ {
+     BDRVRawState *s = bs->opaque;
+     LONG low, high;
+diff --git a/block/gluster.c b/block/gluster.c
+index 0aa1f2c..d06df90 100644
+--- a/block/gluster.c
++++ b/block/gluster.c
+@@ -1228,6 +1228,7 @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
+                                                  int64_t offset,
+                                                  bool exact,
+                                                  PreallocMode prealloc,
++                                                 BdrvRequestFlags flags,
+                                                  Error **errp)
+ {
+     BDRVGlusterState *s = bs->opaque;
+diff --git a/block/io.c b/block/io.c
+index f75777f..549e5a4 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -3320,6 +3320,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
+     BlockDriverState *bs = child->bs;
+     BlockDriver *drv = bs->drv;
+     BdrvTrackedRequest req;
++    BdrvRequestFlags flags = 0;
+     int64_t old_size, new_bytes;
+     int ret;
+ 
+@@ -3370,7 +3371,12 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
+     }
+ 
+     if (drv->bdrv_co_truncate) {
+-        ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
++        if (flags & ~bs->supported_truncate_flags) {
++            error_setg(errp, "Block driver does not support requested flags");
++            ret = -ENOTSUP;
++            goto out;
++        }
++        ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
+     } else if (bs->file && drv->is_filter) {
+         ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
+     } else {
+diff --git a/block/iscsi.c b/block/iscsi.c
+index 16b0716..0bea2d3 100644
+--- a/block/iscsi.c
++++ b/block/iscsi.c
+@@ -2125,7 +2125,7 @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
+ 
+ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
+                                           bool exact, PreallocMode prealloc,
+-                                          Error **errp)
++                                          BdrvRequestFlags flags, Error **errp)
+ {
+     IscsiLun *iscsilun = bs->opaque;
+     int64_t cur_length;
+diff --git a/block/nfs.c b/block/nfs.c
+index cc2413d..2393fbf 100644
+--- a/block/nfs.c
++++ b/block/nfs.c
+@@ -755,7 +755,8 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
+ 
+ static int coroutine_fn
+ nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
+-                     PreallocMode prealloc, Error **errp)
++                     PreallocMode prealloc, BdrvRequestFlags flags,
++                     Error **errp)
+ {
+     NFSClient *client = bs->opaque;
+     int ret;
+diff --git a/block/qcow2.c b/block/qcow2.c
+index dbd870a..977445e 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3948,7 +3948,7 @@ fail:
+ 
+ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
+                                           bool exact, PreallocMode prealloc,
+-                                          Error **errp)
++                                          BdrvRequestFlags flags, Error **errp)
+ {
+     BDRVQcow2State *s = bs->opaque;
+     uint64_t old_length;
+diff --git a/block/qed.c b/block/qed.c
+index 1af9b3c..fb6100b 100644
+--- a/block/qed.c
++++ b/block/qed.c
+@@ -1467,6 +1467,7 @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
+                                              int64_t offset,
+                                              bool exact,
+                                              PreallocMode prealloc,
++                                             BdrvRequestFlags flags,
+                                              Error **errp)
+ {
+     BDRVQEDState *s = bs->opaque;
+diff --git a/block/raw-format.c b/block/raw-format.c
+index 4bb54f4..f994c4a 100644
+--- a/block/raw-format.c
++++ b/block/raw-format.c
+@@ -371,7 +371,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
+ 
+ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
+                                         bool exact, PreallocMode prealloc,
+-                                        Error **errp)
++                                        BdrvRequestFlags flags, Error **errp)
+ {
+     BDRVRawState *s = bs->opaque;
+ 
+diff --git a/block/rbd.c b/block/rbd.c
+index 8847259..fcdb60a 100644
+--- a/block/rbd.c
++++ b/block/rbd.c
+@@ -1090,6 +1090,7 @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
+                                              int64_t offset,
+                                              bool exact,
+                                              PreallocMode prealloc,
++                                             BdrvRequestFlags flags,
+                                              Error **errp)
+ {
+     int r;
+diff --git a/block/sheepdog.c b/block/sheepdog.c
+index a8a7e32..077aed8 100644
+--- a/block/sheepdog.c
++++ b/block/sheepdog.c
+@@ -2288,7 +2288,7 @@ static int64_t sd_getlength(BlockDriverState *bs)
+ 
+ static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
+                                        bool exact, PreallocMode prealloc,
+-                                       Error **errp)
++                                       BdrvRequestFlags flags, Error **errp)
+ {
+     BDRVSheepdogState *s = bs->opaque;
+     int ret, fd;
+@@ -2604,7 +2604,7 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
+ 
+     assert(!flags);
+     if (offset > s->inode.vdi_size) {
+-        ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
++        ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
+         if (ret < 0) {
+             return ret;
+         }
+diff --git a/block/ssh.c b/block/ssh.c
+index 84e9282..9eb33df 100644
+--- a/block/ssh.c
++++ b/block/ssh.c
+@@ -1298,7 +1298,7 @@ static int64_t ssh_getlength(BlockDriverState *bs)
+ 
+ static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
+                                         bool exact, PreallocMode prealloc,
+-                                        Error **errp)
++                                        BdrvRequestFlags flags, Error **errp)
+ {
+     BDRVSSHState *s = bs->opaque;
+ 
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index 876a83d..41f13ec 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -356,7 +356,7 @@ struct BlockDriver {
+      */
+     int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
+                                          bool exact, PreallocMode prealloc,
+-                                         Error **errp);
++                                         BdrvRequestFlags flags, Error **errp);
+ 
+     int64_t (*bdrv_getlength)(BlockDriverState *bs);
+     bool has_variable_length;
+@@ -849,6 +849,14 @@ struct BlockDriverState {
+     /* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
+      * BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
+     unsigned int supported_zero_flags;
++    /*
++     * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
++     *
++     * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
++     * that any added space reads as all zeros. If this can't be guaranteed,
++     * the operation must fail.
++     */
++    unsigned int supported_truncate_flags;
+ 
+     /* the following member gives a name to every node on the bs graph. */
+     char node_name[32];
+diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
+index 0c86180..2f3b763 100644
+--- a/tests/test-block-iothread.c
++++ b/tests/test-block-iothread.c
+@@ -46,7 +46,8 @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
+ 
+ static int coroutine_fn
+ bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
+-                      PreallocMode prealloc, Error **errp)
++                      PreallocMode prealloc, BdrvRequestFlags flags,
++                      Error **errp)
+ {
+     return 0;
+ }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Add-flags-to-bdrv-_co-_truncate.patch b/SOURCES/kvm-block-Add-flags-to-bdrv-_co-_truncate.patch
new file mode 100644
index 0000000..3da05ff
--- /dev/null
+++ b/SOURCES/kvm-block-Add-flags-to-bdrv-_co-_truncate.patch
@@ -0,0 +1,353 @@
+From 50127f0ff9e13a15fd5bfeb2662e2404ff20f364 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:31 +0100
+Subject: [PATCH 03/17] block: Add flags to bdrv(_co)_truncate()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-3-kwolf@redhat.com>
+Patchwork-id: 97445
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 02/11] block: Add flags to bdrv(_co)_truncate()
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+Now that block drivers can support flags for .bdrv_co_truncate, expose
+the parameter in the node level interfaces bdrv_co_truncate() and
+bdrv_truncate().
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 7b8e4857426f2e2de2441749996c6161b550bada)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/block-backend.c       |  2 +-
+ block/crypto.c              |  2 +-
+ block/io.c                  | 12 +++++++-----
+ block/parallels.c           |  6 +++---
+ block/qcow.c                |  4 ++--
+ block/qcow2-refcount.c      |  2 +-
+ block/qcow2.c               | 15 +++++++++------
+ block/raw-format.c          |  2 +-
+ block/vhdx-log.c            |  2 +-
+ block/vhdx.c                |  2 +-
+ block/vmdk.c                |  2 +-
+ include/block/block.h       |  5 +++--
+ tests/test-block-iothread.c |  6 +++---
+ 13 files changed, 34 insertions(+), 28 deletions(-)
+
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 38ae413..8be2006 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -2144,7 +2144,7 @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
+         return -ENOMEDIUM;
+     }
+ 
+-    return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
++    return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
+ }
+ 
+ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
+diff --git a/block/crypto.c b/block/crypto.c
+index 6e4b726..fcb4a97 100644
+--- a/block/crypto.c
++++ b/block/crypto.c
+@@ -313,7 +313,7 @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
+ 
+     offset += payload_offset;
+ 
+-    return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
++    return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
+ }
+ 
+ static void block_crypto_close(BlockDriverState *bs)
+diff --git a/block/io.c b/block/io.c
+index 549e5a4..3235ce5 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -3315,12 +3315,12 @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
+  * 'offset' bytes in length.
+  */
+ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
+-                                  PreallocMode prealloc, Error **errp)
++                                  PreallocMode prealloc, BdrvRequestFlags flags,
++                                  Error **errp)
+ {
+     BlockDriverState *bs = child->bs;
+     BlockDriver *drv = bs->drv;
+     BdrvTrackedRequest req;
+-    BdrvRequestFlags flags = 0;
+     int64_t old_size, new_bytes;
+     int ret;
+ 
+@@ -3378,7 +3378,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
+         }
+         ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
+     } else if (bs->file && drv->is_filter) {
+-        ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
++        ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
+     } else {
+         error_setg(errp, "Image format driver does not support resize");
+         ret = -ENOTSUP;
+@@ -3411,6 +3411,7 @@ typedef struct TruncateCo {
+     int64_t offset;
+     bool exact;
+     PreallocMode prealloc;
++    BdrvRequestFlags flags;
+     Error **errp;
+     int ret;
+ } TruncateCo;
+@@ -3419,12 +3420,12 @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
+ {
+     TruncateCo *tco = opaque;
+     tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
+-                                tco->prealloc, tco->errp);
++                                tco->prealloc, tco->flags, tco->errp);
+     aio_wait_kick();
+ }
+ 
+ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
+-                  PreallocMode prealloc, Error **errp)
++                  PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
+ {
+     Coroutine *co;
+     TruncateCo tco = {
+@@ -3432,6 +3433,7 @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
+         .offset     = offset,
+         .exact      = exact,
+         .prealloc   = prealloc,
++        .flags      = flags,
+         .errp       = errp,
+         .ret        = NOT_DONE,
+     };
+diff --git a/block/parallels.c b/block/parallels.c
+index 6d4ed77..2be92cf 100644
+--- a/block/parallels.c
++++ b/block/parallels.c
+@@ -203,7 +203,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
+         } else {
+             ret = bdrv_truncate(bs->file,
+                                 (s->data_end + space) << BDRV_SECTOR_BITS,
+-                                false, PREALLOC_MODE_OFF, NULL);
++                                false, PREALLOC_MODE_OFF, 0, NULL);
+         }
+         if (ret < 0) {
+             return ret;
+@@ -493,7 +493,7 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
+              * That means we have to pass exact=true.
+              */
+             ret = bdrv_truncate(bs->file, res->image_end_offset, true,
+-                                PREALLOC_MODE_OFF, &local_err);
++                                PREALLOC_MODE_OFF, 0, &local_err);
+             if (ret < 0) {
+                 error_report_err(local_err);
+                 res->check_errors++;
+@@ -889,7 +889,7 @@ static void parallels_close(BlockDriverState *bs)
+ 
+         /* errors are ignored, so we might as well pass exact=true */
+         bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
+-                      PREALLOC_MODE_OFF, NULL);
++                      PREALLOC_MODE_OFF, 0, NULL);
+     }
+ 
+     g_free(s->bat_dirty_bmap);
+diff --git a/block/qcow.c b/block/qcow.c
+index 8973e4e..6b5f226 100644
+--- a/block/qcow.c
++++ b/block/qcow.c
+@@ -480,7 +480,7 @@ static int get_cluster_offset(BlockDriverState *bs,
+                     return -E2BIG;
+                 }
+                 ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
+-                                    false, PREALLOC_MODE_OFF, NULL);
++                                    false, PREALLOC_MODE_OFF, 0, NULL);
+                 if (ret < 0) {
+                     return ret;
+                 }
+@@ -1035,7 +1035,7 @@ static int qcow_make_empty(BlockDriverState *bs)
+             l1_length) < 0)
+         return -1;
+     ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
+-                        PREALLOC_MODE_OFF, NULL);
++                        PREALLOC_MODE_OFF, 0, NULL);
+     if (ret < 0)
+         return ret;
+ 
+diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
+index f67ac6b..3a90d75 100644
+--- a/block/qcow2-refcount.c
++++ b/block/qcow2-refcount.c
+@@ -2017,7 +2017,7 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
+                 }
+ 
+                 ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
+-                                    PREALLOC_MODE_OFF, &local_err);
++                                    PREALLOC_MODE_OFF, 0, &local_err);
+                 if (ret < 0) {
+                     error_report_err(local_err);
+                     goto resize_fail;
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 977445e..c0fdcb9 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3082,7 +3082,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
+             mode = PREALLOC_MODE_OFF;
+         }
+         ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
+-                               mode, errp);
++                               mode, 0, errp);
+         if (ret < 0) {
+             return ret;
+         }
+@@ -4044,7 +4044,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
+              * always fulfilled, so there is no need to pass it on.)
+              */
+             bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
+-                             false, PREALLOC_MODE_OFF, &local_err);
++                             false, PREALLOC_MODE_OFF, 0, &local_err);
+             if (local_err) {
+                 warn_reportf_err(local_err,
+                                  "Failed to truncate the tail of the image: ");
+@@ -4066,7 +4066,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
+              * file should be resized to the exact target size, too,
+              * so we pass @exact here.
+              */
+-            ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
++            ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
++                                   errp);
+             if (ret < 0) {
+                 goto fail;
+             }
+@@ -4152,7 +4153,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
+         new_file_size = allocation_start +
+                         nb_new_data_clusters * s->cluster_size;
+         /* Image file grows, so @exact does not matter */
+-        ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
++        ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
++                               errp);
+         if (ret < 0) {
+             error_prepend(errp, "Failed to resize underlying file: ");
+             qcow2_free_clusters(bs, allocation_start,
+@@ -4255,7 +4257,8 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
+         if (len < 0) {
+             return len;
+         }
+-        return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
++        return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
++                                NULL);
+     }
+ 
+     if (offset_into_cluster(s, offset)) {
+@@ -4493,7 +4496,7 @@ static int make_completely_empty(BlockDriverState *bs)
+     }
+ 
+     ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
+-                        PREALLOC_MODE_OFF, &local_err);
++                        PREALLOC_MODE_OFF, 0, &local_err);
+     if (ret < 0) {
+         error_report_err(local_err);
+         goto fail;
+diff --git a/block/raw-format.c b/block/raw-format.c
+index f994c4a..c3acf9a 100644
+--- a/block/raw-format.c
++++ b/block/raw-format.c
+@@ -387,7 +387,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
+ 
+     s->size = offset;
+     offset += s->offset;
+-    return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
++    return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
+ }
+ 
+ static void raw_eject(BlockDriverState *bs, bool eject_flag)
+diff --git a/block/vhdx-log.c b/block/vhdx-log.c
+index 13a49c2..404fb5f 100644
+--- a/block/vhdx-log.c
++++ b/block/vhdx-log.c
+@@ -558,7 +558,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
+                     goto exit;
+                 }
+                 ret = bdrv_truncate(bs->file, new_file_size, false,
+-                                    PREALLOC_MODE_OFF, NULL);
++                                    PREALLOC_MODE_OFF, 0, NULL);
+                 if (ret < 0) {
+                     goto exit;
+                 }
+diff --git a/block/vhdx.c b/block/vhdx.c
+index 33e57cd..5dfbb20 100644
+--- a/block/vhdx.c
++++ b/block/vhdx.c
+@@ -1264,7 +1264,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
+     }
+ 
+     return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
+-                         PREALLOC_MODE_OFF, NULL);
++                         PREALLOC_MODE_OFF, 0, NULL);
+ }
+ 
+ /*
+diff --git a/block/vmdk.c b/block/vmdk.c
+index eb726f2..1bbf937 100644
+--- a/block/vmdk.c
++++ b/block/vmdk.c
+@@ -2077,7 +2077,7 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
+             }
+             length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
+             ret = bdrv_truncate(s->extents[i].file, length, false,
+-                                PREALLOC_MODE_OFF, NULL);
++                                PREALLOC_MODE_OFF, 0, NULL);
+             if (ret < 0) {
+                 return ret;
+             }
+diff --git a/include/block/block.h b/include/block/block.h
+index b2a3074..4913596 100644
+--- a/include/block/block.h
++++ b/include/block/block.h
+@@ -348,9 +348,10 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
+ void bdrv_refresh_filename(BlockDriverState *bs);
+ 
+ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
+-                                  PreallocMode prealloc, Error **errp);
++                                  PreallocMode prealloc, BdrvRequestFlags flags,
++                                  Error **errp);
+ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
+-                  PreallocMode prealloc, Error **errp);
++                  PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
+ 
+ int64_t bdrv_nb_sectors(BlockDriverState *bs);
+ int64_t bdrv_getlength(BlockDriverState *bs);
+diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
+index 2f3b763..71e9bce 100644
+--- a/tests/test-block-iothread.c
++++ b/tests/test-block-iothread.c
+@@ -186,18 +186,18 @@ static void test_sync_op_truncate(BdrvChild *c)
+     int ret;
+ 
+     /* Normal success path */
+-    ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
++    ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
+     g_assert_cmpint(ret, ==, 0);
+ 
+     /* Early error: Negative offset */
+-    ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
++    ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
+     g_assert_cmpint(ret, ==, -EINVAL);
+ 
+     /* Error: Read-only image */
+     c->bs->read_only = true;
+     c->bs->open_flags &= ~BDRV_O_RDWR;
+ 
+-    ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
++    ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
+     g_assert_cmpint(ret, ==, -EACCES);
+ 
+     c->bs->read_only = false;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-Call-attention-to-truncation-of-long-NBD-expor.patch b/SOURCES/kvm-block-Call-attention-to-truncation-of-long-NBD-expor.patch
new file mode 100644
index 0000000..190826f
--- /dev/null
+++ b/SOURCES/kvm-block-Call-attention-to-truncation-of-long-NBD-expor.patch
@@ -0,0 +1,105 @@
+From c8ecaea34f03b8ddda7d2b41b0d6f397469c8959 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Wed, 10 Jun 2020 18:32:02 -0400
+Subject: [PATCH 2/2] block: Call attention to truncation of long NBD exports
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200610183202.3780750-3-eblake@redhat.com>
+Patchwork-id: 97495
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] block: Call attention to truncation of long NBD exports
+Bugzilla: 1845384
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+Commit 93676c88 relaxed our NBD client code to request export names up
+to the NBD protocol maximum of 4096 bytes without NUL terminator, even
+though the block layer can't store anything longer than 4096 bytes
+including NUL terminator for display to the user.  Since this means
+there are some export names where we have to truncate things, we can
+at least try to make the truncation a bit more obvious for the user.
+Note that in spite of the truncated display name, we can still
+communicate with an NBD server using such a long export name; this was
+deemed nicer than refusing to even connect to such a server (since the
+server may not be under our control, and since determining our actual
+length limits gets tricky when nbd://host:port/export and
+nbd+unix:///export?socket=/path are themselves variable-length
+expansions beyond the export name but count towards the block layer
+name length).
+
+Reported-by: Xueqiang Wei <xuwei@redhat.com>
+Fixes: https://bugzilla.redhat.com/1843684
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200610163741.3745251-3-eblake@redhat.com>
+(cherry picked from commit 5c86bdf1208916ece0b87e1151c9b48ee54faa3e)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+---
+ block.c     |  7 +++++--
+ block/nbd.c | 21 +++++++++++++--------
+ 2 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/block.c b/block.c
+index 12c8941879..57740d312e 100644
+--- a/block.c
++++ b/block.c
+@@ -6683,8 +6683,11 @@ void bdrv_refresh_filename(BlockDriverState *bs)
+         pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
+     } else {
+         QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
+-        snprintf(bs->filename, sizeof(bs->filename), "json:%s",
+-                 qstring_get_str(json));
++        if (snprintf(bs->filename, sizeof(bs->filename), "json:%s",
++                     qstring_get_str(json)) >= sizeof(bs->filename)) {
++            /* Give user a hint if we truncated things. */
++            strcpy(bs->filename + sizeof(bs->filename) - 4, "...");
++        }
+         qobject_unref(json);
+     }
+ }
+diff --git a/block/nbd.c b/block/nbd.c
+index 927915d93d..5bb154017d 100644
+--- a/block/nbd.c
++++ b/block/nbd.c
+@@ -1978,6 +1978,7 @@ static void nbd_refresh_filename(BlockDriverState *bs)
+ {
+     BDRVNBDState *s = bs->opaque;
+     const char *host = NULL, *port = NULL, *path = NULL;
++    size_t len = 0;
+ 
+     if (s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
+         const InetSocketAddress *inet = &s->saddr->u.inet;
+@@ -1990,17 +1991,21 @@ static void nbd_refresh_filename(BlockDriverState *bs)
+     } /* else can't represent as pseudo-filename */
+ 
+     if (path && s->export) {
+-        snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+-                 "nbd+unix:///%s?socket=%s", s->export, path);
++        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
++                       "nbd+unix:///%s?socket=%s", s->export, path);
+     } else if (path && !s->export) {
+-        snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+-                 "nbd+unix://?socket=%s", path);
++        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
++                       "nbd+unix://?socket=%s", path);
+     } else if (host && s->export) {
+-        snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+-                 "nbd://%s:%s/%s", host, port, s->export);
++        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
++                       "nbd://%s:%s/%s", host, port, s->export);
+     } else if (host && !s->export) {
+-        snprintf(bs->exact_filename, sizeof(bs->exact_filename),
+-                 "nbd://%s:%s", host, port);
++        len = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
++                       "nbd://%s:%s", host, port);
++    }
++    if (len > sizeof(bs->exact_filename)) {
++        /* Name is too long to represent exactly, so leave it empty. */
++        bs->exact_filename[0] = '\0';
+     }
+ }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-block-Make-it-easier-to-learn-which-BDS-support-bitm.patch b/SOURCES/kvm-block-Make-it-easier-to-learn-which-BDS-support-bitm.patch
new file mode 100644
index 0000000..0d4a000
--- /dev/null
+++ b/SOURCES/kvm-block-Make-it-easier-to-learn-which-BDS-support-bitm.patch
@@ -0,0 +1,145 @@
+From 41d6c207c482093df8669f7cdcdb49bb25dba741 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:12 +0100
+Subject: [PATCH 07/26] block: Make it easier to learn which BDS support
+ bitmaps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-5-eblake@redhat.com>
+Patchwork-id: 97071
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 04/12] block: Make it easier to learn which BDS support bitmaps
+Bugzilla: 1779893 1779904
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Upcoming patches will enhance bitmap support in qemu-img, but in doing
+so, it turns out to be nice to suppress output when persistent bitmaps
+make no sense (such as on a qcow2 v2 image).  Add a hook to make this
+easier to query.
+
+This patch adds a new callback .bdrv_supports_persistent_dirty_bitmap,
+rather than trying to shoehorn the answer in via existing callbacks.
+In particular, while it might have been possible to overload
+.bdrv_co_can_store_new_dirty_bitmap to special-case a NULL input to
+answer whether any persistent bitmaps are supported, that is at odds
+with whether a particular bitmap can be stored (for example, even on
+an image that supports persistent bitmaps but has currently filled up
+the maximum number of bitmaps, attempts to store another one should
+fail); and the new functionality doesn't require coroutine safety.
+Similarly, we could have added one more piece of information to
+.bdrv_get_info, but then again, most callers to that function tend to
+already discard extraneous information, and making it a catch-all
+rather than a series of dedicated scalar queries hasn't really
+simplified life.
+
+In the future, when we improve the ability to look up bitmaps through
+a filter, we will probably also want to teach the block layer to
+automatically let filters pass this request on through.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200513011648.166876-4-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit ef893b5c84f3199d777e33966dc28839f71b1a5c)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/dirty-bitmap.c         | 9 +++++++++
+ block/qcow2-bitmap.c         | 7 +++++++
+ block/qcow2.c                | 2 ++
+ block/qcow2.h                | 1 +
+ include/block/block_int.h    | 1 +
+ include/block/dirty-bitmap.h | 1 +
+ 6 files changed, 21 insertions(+)
+
+diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
+index 7039e82..2f96acc 100644
+--- a/block/dirty-bitmap.c
++++ b/block/dirty-bitmap.c
+@@ -478,6 +478,15 @@ int bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
+     }
+ }
+ 
++bool
++bdrv_supports_persistent_dirty_bitmap(BlockDriverState *bs)
++{
++    if (bs->drv && bs->drv->bdrv_supports_persistent_dirty_bitmap) {
++        return bs->drv->bdrv_supports_persistent_dirty_bitmap(bs);
++    }
++    return false;
++}
++
+ static bool coroutine_fn
+ bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
+                                    uint32_t granularity, Error **errp)
+diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
+index c6c8ebb..cbac905 100644
+--- a/block/qcow2-bitmap.c
++++ b/block/qcow2-bitmap.c
+@@ -1759,3 +1759,10 @@ fail:
+                   name, bdrv_get_device_or_node_name(bs));
+     return false;
+ }
++
++bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs)
++{
++    BDRVQcow2State *s = bs->opaque;
++
++    return s->qcow_version >= 3;
++}
+diff --git a/block/qcow2.c b/block/qcow2.c
+index af0ad4a..36b0f7d 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -5551,6 +5551,8 @@ BlockDriver bdrv_qcow2 = {
+     .bdrv_detach_aio_context  = qcow2_detach_aio_context,
+     .bdrv_attach_aio_context  = qcow2_attach_aio_context,
+ 
++    .bdrv_supports_persistent_dirty_bitmap =
++            qcow2_supports_persistent_dirty_bitmap,
+     .bdrv_co_can_store_new_dirty_bitmap = qcow2_co_can_store_new_dirty_bitmap,
+     .bdrv_co_remove_persistent_dirty_bitmap =
+             qcow2_co_remove_persistent_dirty_bitmap,
+diff --git a/block/qcow2.h b/block/qcow2.h
+index 0942126..ceb1ceb 100644
+--- a/block/qcow2.h
++++ b/block/qcow2.h
+@@ -767,6 +767,7 @@ bool qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
+ int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
+                                             const char *name,
+                                             Error **errp);
++bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
+ 
+ ssize_t coroutine_fn
+ qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index 562dca1..cc18e8d 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -568,6 +568,7 @@ struct BlockDriver {
+                              uint64_t parent_perm, uint64_t parent_shared,
+                              uint64_t *nperm, uint64_t *nshared);
+ 
++    bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
+     bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs,
+                                                const char *name,
+                                                uint32_t granularity,
+diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
+index e2b20ec..f6e9a38 100644
+--- a/include/block/dirty-bitmap.h
++++ b/include/block/dirty-bitmap.h
+@@ -16,6 +16,7 @@ typedef enum BitmapCheckFlags {
+ 
+ #define BDRV_BITMAP_MAX_NAME_SIZE 1023
+ 
++bool bdrv_supports_persistent_dirty_bitmap(BlockDriverState *bs);
+ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
+                                           uint32_t granularity,
+                                           const char *name,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-always-fill-entire-LUKS-header-space-with-zero.patch b/SOURCES/kvm-block-always-fill-entire-LUKS-header-space-with-zero.patch
new file mode 100644
index 0000000..d1511d2
--- /dev/null
+++ b/SOURCES/kvm-block-always-fill-entire-LUKS-header-space-with-zero.patch
@@ -0,0 +1,308 @@
+From 67f36d057aa71ca56ebc17ef28a7cb70bac6c6b6 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange@redhat.com>
+Date: Tue, 5 May 2020 16:46:01 +0100
+Subject: [PATCH 01/12] block: always fill entire LUKS header space with zeros
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Daniel P. Berrange <berrange@redhat.com>
+Message-id: <20200505164601.1059974-2-berrange@redhat.com>
+Patchwork-id: 96277
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/1] block: always fill entire LUKS header space with zeros
+Bugzilla: 1775462
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+When initializing the LUKS header the size with default encryption
+parameters will currently be 2068480 bytes. This is rounded up to
+a multiple of the cluster size, 2081792, with 64k sectors. If the
+end of the header is not the same as the end of the cluster we fill
+the extra space with zeros. This was forgetting that not even the
+space allocated for the header will be fully initialized, as we
+only write key material for the first key slot. The space left
+for the other 7 slots is never written to.
+
+An optimization to the ref count checking code:
+
+  commit a5fff8d4b4d928311a5005efa12d0991fe3b66f9 (refs/bisect/bad)
+  Author: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+  Date:   Wed Feb 27 16:14:30 2019 +0300
+
+    qcow2-refcount: avoid eating RAM
+
+made the assumption that every cluster which was allocated would
+have at least some data written to it. This was violated by way
+the LUKS header is only partially written, with much space simply
+reserved for future use.
+
+Depending on the cluster size this problem was masked by the
+logic which wrote zeros between the end of the LUKS header and
+the end of the cluster.
+
+$ qemu-img create --object secret,id=cluster_encrypt0,data=123456 \
+   -f qcow2 -o cluster_size=2k,encrypt.iter-time=1,\
+               encrypt.format=luks,encrypt.key-secret=cluster_encrypt0 \
+               cluster_size_check.qcow2 100M
+  Formatting 'cluster_size_check.qcow2', fmt=qcow2 size=104857600
+    encrypt.format=luks encrypt.key-secret=cluster_encrypt0
+    encrypt.iter-time=1 cluster_size=2048 lazy_refcounts=off refcount_bits=16
+
+$ qemu-img check --object secret,id=cluster_encrypt0,data=redhat \
+    'json:{"driver": "qcow2", "encrypt.format": "luks", \
+           "encrypt.key-secret": "cluster_encrypt0", \
+           "file.driver": "file", "file.filename": "cluster_size_check.qcow2"}'
+ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x2000 size 0x1f9000
+Leaked cluster 4 refcount=1 reference=0
+...snip...
+Leaked cluster 130 refcount=1 reference=0
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+
+127 leaked clusters were found on the image.
+This means waste of disk space, but no harm to data.
+Image end offset: 268288
+
+The problem only exists when the disk image is entirely empty. Writing
+data to the disk image payload will solve the problem by causing the
+end of the file to be extended further.
+
+The change fixes it by ensuring that the entire allocated LUKS header
+region is fully initialized with zeros. The qemu-img check will still
+fail for any pre-existing disk images created prior to this change,
+unless at least 1 byte of the payload is written to.
+
+Fully writing zeros to the entire LUKS header is a good idea regardless
+as it ensures that space has been allocated on the host filesystem (or
+whatever block storage backend is used).
+
+Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
+Message-Id: <20200207135520.2669430-1-berrange@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 087ab8e775f48766068e65de1bc99d03b40d1670)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	tests/qemu-iotests/group: no test 283 in downstream
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/qcow2.c              | 11 ++++--
+ tests/qemu-iotests/284     | 97 ++++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/284.out | 62 +++++++++++++++++++++++++++++
+ tests/qemu-iotests/group   |  1 +
+ 4 files changed, 167 insertions(+), 4 deletions(-)
+ create mode 100755 tests/qemu-iotests/284
+ create mode 100644 tests/qemu-iotests/284.out
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 71067c6..af0ad4a 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -135,13 +135,16 @@ static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen,
+     s->crypto_header.length = headerlen;
+     s->crypto_header.offset = ret;
+ 
+-    /* Zero fill remaining space in cluster so it has predictable
+-     * content in case of future spec changes */
++    /*
++     * Zero fill all space in cluster so it has predictable
++     * content, as we may not initialize some regions of the
++     * header (eg only 1 out of 8 key slots will be initialized)
++     */
+     clusterlen = size_to_clusters(s, headerlen) * s->cluster_size;
+     assert(qcow2_pre_write_overlap_check(bs, 0, ret, clusterlen, false) == 0);
+     ret = bdrv_pwrite_zeroes(bs->file,
+-                             ret + headerlen,
+-                             clusterlen - headerlen, 0);
++                             ret,
++                             clusterlen, 0);
+     if (ret < 0) {
+         error_setg_errno(errp, -ret, "Could not zero fill encryption header");
+         return -1;
+diff --git a/tests/qemu-iotests/284 b/tests/qemu-iotests/284
+new file mode 100755
+index 0000000..071e89b
+--- /dev/null
++++ b/tests/qemu-iotests/284
+@@ -0,0 +1,97 @@
++#!/usr/bin/env bash
++#
++# Test ref count checks on encrypted images
++#
++# Copyright (C) 2019 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++
++# creator
++owner=berrange@redhat.com
++
++seq=`basename $0`
++echo "QA output created by $seq"
++
++status=1        # failure is the default!
++
++_cleanup()
++{
++        _cleanup_test_img
++}
++trap "_cleanup; exit \$status" 0 1 2 3 15
++
++# get standard environment, filters and checks
++. ./common.rc
++. ./common.filter
++
++_supported_fmt qcow2
++_supported_proto generic
++_supported_os Linux
++
++
++size=1M
++
++SECRET="secret,id=sec0,data=astrochicken"
++
++IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
++QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
++
++_run_test()
++{
++        IMGOPTSSYNTAX=true
++        OLD_TEST_IMG="$TEST_IMG"
++        TEST_IMG="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
++        QEMU_IMG_EXTRA_ARGS="--image-opts --object $SECRET"
++
++        echo
++        echo "== cluster size $csize"
++        echo "== checking image refcounts =="
++        _check_test_img
++
++        echo
++        echo "== writing some data =="
++        $QEMU_IO -c "write -P 0x9 0 1"  $QEMU_IMG_EXTRA_ARGS $TEST_IMG | _filter_qemu_io | _filter_testdir
++        echo
++        echo "== rechecking image refcounts =="
++        _check_test_img
++
++        echo
++        echo "== writing some more data =="
++        $QEMU_IO -c "write -P 0x9 $csize 1" $QEMU_IMG_EXTRA_ARGS $TEST_IMG | _filter_qemu_io | _filter_testdir
++        echo
++        echo "== rechecking image refcounts =="
++        _check_test_img
++
++        TEST_IMG="$OLD_TEST_IMG"
++        QEMU_IMG_EXTRA_ARGS=
++        IMGOPTSSYNTAX=
++}
++
++
++echo
++echo "testing LUKS qcow2 encryption"
++echo
++
++for csize in 512 2048 32768
++do
++  _make_test_img --object $SECRET -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=$csize" $size
++  _run_test
++  _cleanup_test_img
++done
++
++# success, all done
++echo "*** done"
++rm -f $seq.full
++status=0
+diff --git a/tests/qemu-iotests/284.out b/tests/qemu-iotests/284.out
+new file mode 100644
+index 0000000..48216f5
+--- /dev/null
++++ b/tests/qemu-iotests/284.out
+@@ -0,0 +1,62 @@
++QA output created by 284
++
++testing LUKS qcow2 encryption
++
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
++
++== cluster size 512
++== checking image refcounts ==
++No errors were found on the image.
++
++== writing some data ==
++wrote 1/1 bytes at offset 0
++1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== rechecking image refcounts ==
++No errors were found on the image.
++
++== writing some more data ==
++wrote 1/1 bytes at offset 512
++1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== rechecking image refcounts ==
++No errors were found on the image.
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
++
++== cluster size 2048
++== checking image refcounts ==
++No errors were found on the image.
++
++== writing some data ==
++wrote 1/1 bytes at offset 0
++1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== rechecking image refcounts ==
++No errors were found on the image.
++
++== writing some more data ==
++wrote 1/1 bytes at offset 2048
++1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== rechecking image refcounts ==
++No errors were found on the image.
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
++
++== cluster size 32768
++== checking image refcounts ==
++No errors were found on the image.
++
++== writing some data ==
++wrote 1/1 bytes at offset 0
++1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== rechecking image refcounts ==
++No errors were found on the image.
++
++== writing some more data ==
++wrote 1/1 bytes at offset 32768
++1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== rechecking image refcounts ==
++No errors were found on the image.
++*** done
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index e47cbfc..9c565cf 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -289,3 +289,4 @@
+ 277 rw quick
+ 280 rw migration quick
+ 281 rw quick
++284 rw
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-backend-Add-flags-to-blk_truncate.patch b/SOURCES/kvm-block-backend-Add-flags-to-blk_truncate.patch
new file mode 100644
index 0000000..5b212fc
--- /dev/null
+++ b/SOURCES/kvm-block-backend-Add-flags-to-blk_truncate.patch
@@ -0,0 +1,294 @@
+From 07a93e74efa4861f54dd3d4bec01885f7af2fee3 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 17:01:32 +0200
+Subject: [PATCH 04/17] block-backend: Add flags to blk_truncate()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-4-kwolf@redhat.com>
+Patchwork-id: 97450
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 03/11] block-backend: Add flags to blk_truncate()
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+Now that node level interface bdrv_truncate() supports passing request
+flags to the block driver, expose this on the BlockBackend level, too.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 8c6242b6f383e43fd11d2c50f8bcdd2bba1100fc)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block.c                        | 3 ++-
+ block/block-backend.c          | 4 ++--
+ block/commit.c                 | 4 ++--
+ block/crypto.c                 | 2 +-
+ block/mirror.c                 | 2 +-
+ block/qcow2.c                  | 4 ++--
+ block/qed.c                    | 2 +-
+ block/vdi.c                    | 2 +-
+ block/vhdx.c                   | 4 ++--
+ block/vmdk.c                   | 6 +++---
+ block/vpc.c                    | 2 +-
+ blockdev.c                     | 2 +-
+ include/sysemu/block-backend.h | 2 +-
+ qemu-img.c                     | 2 +-
+ qemu-io-cmds.c                 | 2 +-
+ 15 files changed, 22 insertions(+), 21 deletions(-)
+
+diff --git a/block.c b/block.c
+index d6a05da..12c8941 100644
+--- a/block.c
++++ b/block.c
+@@ -547,7 +547,8 @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
+     int64_t size;
+     int ret;
+ 
+-    ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
++    ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
++                       &local_err);
+     if (ret < 0 && ret != -ENOTSUP) {
+         error_propagate(errp, local_err);
+         return ret;
+diff --git a/block/block-backend.c b/block/block-backend.c
+index 8be2006..17ed6d8 100644
+--- a/block/block-backend.c
++++ b/block/block-backend.c
+@@ -2137,14 +2137,14 @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
+ }
+ 
+ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
+-                 PreallocMode prealloc, Error **errp)
++                 PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
+ {
+     if (!blk_is_available(blk)) {
+         error_setg(errp, "No medium inserted");
+         return -ENOMEDIUM;
+     }
+ 
+-    return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
++    return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
+ }
+ 
+ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
+diff --git a/block/commit.c b/block/commit.c
+index 23c90b3..075ebf8 100644
+--- a/block/commit.c
++++ b/block/commit.c
+@@ -155,7 +155,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
+     }
+ 
+     if (base_len < len) {
+-        ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
++        ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
+         if (ret) {
+             goto out;
+         }
+@@ -471,7 +471,7 @@ int bdrv_commit(BlockDriverState *bs)
+      * grow the backing file image if possible.  If not possible,
+      * we must return an error */
+     if (length > backing_length) {
+-        ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
++        ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
+                            &local_err);
+         if (ret < 0) {
+             error_report_err(local_err);
+diff --git a/block/crypto.c b/block/crypto.c
+index fcb4a97..83a8fc0 100644
+--- a/block/crypto.c
++++ b/block/crypto.c
+@@ -115,7 +115,7 @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
+      * which will be used by the crypto header
+      */
+     return blk_truncate(data->blk, data->size + headerlen, false,
+-                        data->prealloc, errp);
++                        data->prealloc, 0, errp);
+ }
+ 
+ 
+diff --git a/block/mirror.c b/block/mirror.c
+index 0d32fca..c8028cd 100644
+--- a/block/mirror.c
++++ b/block/mirror.c
+@@ -886,7 +886,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
+     if (s->base == blk_bs(s->target)) {
+         if (s->bdev_length > target_length) {
+             ret = blk_truncate(s->target, s->bdev_length, false,
+-                               PREALLOC_MODE_OFF, NULL);
++                               PREALLOC_MODE_OFF, 0, NULL);
+             if (ret < 0) {
+                 goto immediate_exit;
+             }
+diff --git a/block/qcow2.c b/block/qcow2.c
+index c0fdcb9..86aa74a 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -3497,7 +3497,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
+ 
+     /* Okay, now that we have a valid image, let's give it the right size */
+     ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
+-                       errp);
++                       0, errp);
+     if (ret < 0) {
+         error_prepend(errp, "Could not resize image: ");
+         goto out;
+@@ -5347,7 +5347,7 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
+          * Amending image options should ensure that the image has
+          * exactly the given new values, so pass exact=true here.
+          */
+-        ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
++        ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
+         blk_unref(blk);
+         if (ret < 0) {
+             return ret;
+diff --git a/block/qed.c b/block/qed.c
+index fb6100b..b0fdb8f 100644
+--- a/block/qed.c
++++ b/block/qed.c
+@@ -677,7 +677,7 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
+      * The QED format associates file length with allocation status,
+      * so a new file (which is empty) must have a length of 0.
+      */
+-    ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
++    ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
+     if (ret < 0) {
+         goto out;
+     }
+diff --git a/block/vdi.c b/block/vdi.c
+index e1a11f2..0c7835a 100644
+--- a/block/vdi.c
++++ b/block/vdi.c
+@@ -875,7 +875,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
+ 
+     if (image_type == VDI_TYPE_STATIC) {
+         ret = blk_truncate(blk, offset + blocks * block_size, false,
+-                           PREALLOC_MODE_OFF, errp);
++                           PREALLOC_MODE_OFF, 0, errp);
+         if (ret < 0) {
+             error_prepend(errp, "Failed to statically allocate file");
+             goto exit;
+diff --git a/block/vhdx.c b/block/vhdx.c
+index 5dfbb20..21497f7 100644
+--- a/block/vhdx.c
++++ b/block/vhdx.c
+@@ -1703,13 +1703,13 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
+         /* All zeroes, so we can just extend the file - the end of the BAT
+          * is the furthest thing we have written yet */
+         ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
+-                           errp);
++                           0, errp);
+         if (ret < 0) {
+             goto exit;
+         }
+     } else if (type == VHDX_TYPE_FIXED) {
+         ret = blk_truncate(blk, data_file_offset + image_size, false,
+-                           PREALLOC_MODE_OFF, errp);
++                           PREALLOC_MODE_OFF, 0, errp);
+         if (ret < 0) {
+             goto exit;
+         }
+diff --git a/block/vmdk.c b/block/vmdk.c
+index 1bbf937..1bd3991 100644
+--- a/block/vmdk.c
++++ b/block/vmdk.c
+@@ -2118,7 +2118,7 @@ static int vmdk_init_extent(BlockBackend *blk,
+     int gd_buf_size;
+ 
+     if (flat) {
+-        ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
++        ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
+         goto exit;
+     }
+     magic = cpu_to_be32(VMDK4_MAGIC);
+@@ -2182,7 +2182,7 @@ static int vmdk_init_extent(BlockBackend *blk,
+     }
+ 
+     ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
+-                       PREALLOC_MODE_OFF, errp);
++                       PREALLOC_MODE_OFF, 0, errp);
+     if (ret < 0) {
+         goto exit;
+     }
+@@ -2523,7 +2523,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
+     /* bdrv_pwrite write padding zeros to align to sector, we don't need that
+      * for description file */
+     if (desc_offset == 0) {
+-        ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
++        ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
+         if (ret < 0) {
+             goto exit;
+         }
+diff --git a/block/vpc.c b/block/vpc.c
+index 6df75e2..d5e7dc8 100644
+--- a/block/vpc.c
++++ b/block/vpc.c
+@@ -898,7 +898,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
+     /* Add footer to total size */
+     total_size += HEADER_SIZE;
+ 
+-    ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
++    ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
+     if (ret < 0) {
+         return ret;
+     }
+diff --git a/blockdev.c b/blockdev.c
+index 5128c9b..6dde52a 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -3055,7 +3055,7 @@ void qmp_block_resize(bool has_device, const char *device,
+     }
+ 
+     bdrv_drained_begin(bs);
+-    ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
++    ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
+     bdrv_drained_end(bs);
+ 
+ out:
+diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
+index 9bbdbd6..34de7fa 100644
+--- a/include/sysemu/block-backend.h
++++ b/include/sysemu/block-backend.h
+@@ -237,7 +237,7 @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
+                           int bytes);
+ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
+-                 PreallocMode prealloc, Error **errp);
++                 PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
+ int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
+ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
+                      int64_t pos, int size);
+diff --git a/qemu-img.c b/qemu-img.c
+index 6dc881b..a27ad70 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -3939,7 +3939,7 @@ static int img_resize(int argc, char **argv)
+      * resizing, so pass @exact=true.  It is of no use to report
+      * success when the image has not actually been resized.
+      */
+-    ret = blk_truncate(blk, total_size, true, prealloc, &err);
++    ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
+     if (!ret) {
+         qprintf(quiet, "Image resized.\n");
+     } else {
+diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
+index 1b7e700..851f07e 100644
+--- a/qemu-io-cmds.c
++++ b/qemu-io-cmds.c
+@@ -1715,7 +1715,7 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
+      * exact=true.  It is better to err on the "emit more errors" side
+      * than to be overly permissive.
+      */
+-    ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
++    ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
+     if (ret < 0) {
+         error_report_err(local_err);
+         return ret;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-curl-HTTP-header-field-names-are-case-insensit.patch b/SOURCES/kvm-block-curl-HTTP-header-field-names-are-case-insensit.patch
new file mode 100644
index 0000000..a974a18
--- /dev/null
+++ b/SOURCES/kvm-block-curl-HTTP-header-field-names-are-case-insensit.patch
@@ -0,0 +1,55 @@
+From 5e5ca17e1e09cfe9a780c556528bbde23c93fc4e Mon Sep 17 00:00:00 2001
+From: Richard Jones <rjones@redhat.com>
+Date: Thu, 28 May 2020 14:27:37 +0100
+Subject: [PATCH 03/26] block/curl: HTTP header field names are case
+ insensitive
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Richard Jones <rjones@redhat.com>
+Message-id: <20200528142737.17318-3-rjones@redhat.com>
+Patchwork-id: 96895
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] block/curl: HTTP header field names are case insensitive
+Bugzilla: 1841038
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: David Edmondson <david.edmondson@oracle.com>
+
+RFC 7230 section 3.2 indicates that HTTP header field names are case
+insensitive.
+
+Signed-off-by: David Edmondson <david.edmondson@oracle.com>
+Message-Id: <20200224101310.101169-3-david.edmondson@oracle.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 69032253c33ae1774233c63cedf36d32242a85fc)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index f9ffb7f..6e32590 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -216,11 +216,12 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
+     size_t realsize = size * nmemb;
+     const char *header = (char *)ptr;
+     const char *end = header + realsize;
+-    const char *accept_ranges = "Accept-Ranges:";
++    const char *accept_ranges = "accept-ranges:";
+     const char *bytes = "bytes";
+ 
+     if (realsize >= strlen(accept_ranges)
+-        && strncmp(header, accept_ranges, strlen(accept_ranges)) == 0) {
++        && g_ascii_strncasecmp(header, accept_ranges,
++                               strlen(accept_ranges)) == 0) {
+ 
+         char *p = strchr(header, ':') + 1;
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-curl-HTTP-header-fields-allow-whitespace-aroun.patch b/SOURCES/kvm-block-curl-HTTP-header-fields-allow-whitespace-aroun.patch
new file mode 100644
index 0000000..c09a1e2
--- /dev/null
+++ b/SOURCES/kvm-block-curl-HTTP-header-fields-allow-whitespace-aroun.patch
@@ -0,0 +1,76 @@
+From e5ac775de83d3d22f13c74ab198780b8b579f684 Mon Sep 17 00:00:00 2001
+From: Richard Jones <rjones@redhat.com>
+Date: Thu, 28 May 2020 14:27:36 +0100
+Subject: [PATCH 02/26] block/curl: HTTP header fields allow whitespace around
+ values
+
+RH-Author: Richard Jones <rjones@redhat.com>
+Message-id: <20200528142737.17318-2-rjones@redhat.com>
+Patchwork-id: 96894
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/2] block/curl: HTTP header fields allow whitespace around values
+Bugzilla: 1841038
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+
+From: David Edmondson <david.edmondson@oracle.com>
+
+RFC 7230 section 3.2 indicates that whitespace is permitted between
+the field name and field value and after the field value.
+
+Signed-off-by: David Edmondson <david.edmondson@oracle.com>
+Message-Id: <20200224101310.101169-2-david.edmondson@oracle.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 7788a319399f17476ff1dd43164c869e320820a2)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/curl.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index f862993..f9ffb7f 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -214,11 +214,34 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
+ {
+     BDRVCURLState *s = opaque;
+     size_t realsize = size * nmemb;
+-    const char *accept_line = "Accept-Ranges: bytes";
++    const char *header = (char *)ptr;
++    const char *end = header + realsize;
++    const char *accept_ranges = "Accept-Ranges:";
++    const char *bytes = "bytes";
+ 
+-    if (realsize >= strlen(accept_line)
+-        && strncmp((char *)ptr, accept_line, strlen(accept_line)) == 0) {
+-        s->accept_range = true;
++    if (realsize >= strlen(accept_ranges)
++        && strncmp(header, accept_ranges, strlen(accept_ranges)) == 0) {
++
++        char *p = strchr(header, ':') + 1;
++
++        /* Skip whitespace between the header name and value. */
++        while (p < end && *p && g_ascii_isspace(*p)) {
++            p++;
++        }
++
++        if (end - p >= strlen(bytes)
++            && strncmp(p, bytes, strlen(bytes)) == 0) {
++
++            /* Check that there is nothing but whitespace after the value. */
++            p += strlen(bytes);
++            while (p < end && *p && g_ascii_isspace(*p)) {
++                p++;
++            }
++
++            if (p == end || !*p) {
++                s->accept_range = true;
++            }
++        }
+     }
+ 
+     return realsize;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-introducing-bdrv_co_delete_file-interface.patch b/SOURCES/kvm-block-introducing-bdrv_co_delete_file-interface.patch
new file mode 100644
index 0000000..9d5e659
--- /dev/null
+++ b/SOURCES/kvm-block-introducing-bdrv_co_delete_file-interface.patch
@@ -0,0 +1,99 @@
+From 9581770f48911cbe68cfa1a7fa125df2a0a27d02 Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Sun, 31 May 2020 16:40:33 +0100
+Subject: [PATCH 5/7] block: introducing 'bdrv_co_delete_file' interface
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20200531164035.34188-2-mlevitsk@redhat.com>
+Patchwork-id: 97057
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/3] block: introducing 'bdrv_co_delete_file' interface
+Bugzilla: 1827630
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb413@gmail.com>
+
+Adding to Block Drivers the capability of being able to clean up
+its created files can be useful in certain situations. For the
+LUKS driver, for instance, a failure in one of its authentication
+steps can leave files in the host that weren't there before.
+
+This patch adds the 'bdrv_co_delete_file' interface to block
+drivers and add it to the 'file' driver in file-posix.c. The
+implementation is given by 'raw_co_delete_file'.
+
+Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
+Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Message-Id: <20200130213907.2830642-2-danielhb413@gmail.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 9bffae14df879255329473a7bd578643af2d4c9c)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/file-posix.c        | 23 +++++++++++++++++++++++
+ include/block/block_int.h |  4 ++++
+ 2 files changed, 27 insertions(+)
+
+diff --git a/block/file-posix.c b/block/file-posix.c
+index dd18d40..1609598 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -2388,6 +2388,28 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+     return raw_co_create(&options, errp);
+ }
+ 
++static int coroutine_fn raw_co_delete_file(BlockDriverState *bs,
++                                           Error **errp)
++{
++    struct stat st;
++    int ret;
++
++    if (!(stat(bs->filename, &st) == 0) || !S_ISREG(st.st_mode)) {
++        error_setg_errno(errp, ENOENT, "%s is not a regular file",
++                         bs->filename);
++        return -ENOENT;
++    }
++
++    ret = unlink(bs->filename);
++    if (ret < 0) {
++        ret = -errno;
++        error_setg_errno(errp, -ret, "Error when deleting file %s",
++                         bs->filename);
++    }
++
++    return ret;
++}
++
+ /*
+  * Find allocation range in @bs around offset @start.
+  * May change underlying file descriptor's file offset.
+@@ -3019,6 +3041,7 @@ BlockDriver bdrv_file = {
+     .bdrv_co_block_status = raw_co_block_status,
+     .bdrv_co_invalidate_cache = raw_co_invalidate_cache,
+     .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
++    .bdrv_co_delete_file = raw_co_delete_file,
+ 
+     .bdrv_co_preadv         = raw_co_preadv,
+     .bdrv_co_pwritev        = raw_co_pwritev,
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index 529f153..562dca1 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -316,6 +316,10 @@ struct BlockDriver {
+      */
+     int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
+ 
++    /* Delete a created file. */
++    int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs,
++                                            Error **errp);
++
+     /*
+      * Flushes all data that was already written to the OS all the way down to
+      * the disk (for example file-posix.c calls fsync()).
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block-truncate-Don-t-make-backing-file-data-visible.patch b/SOURCES/kvm-block-truncate-Don-t-make-backing-file-data-visible.patch
new file mode 100644
index 0000000..114e1b7
--- /dev/null
+++ b/SOURCES/kvm-block-truncate-Don-t-make-backing-file-data-visible.patch
@@ -0,0 +1,94 @@
+From d84b9b93755ece6618ed98fa84386beeb1a0e40b Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:36 +0100
+Subject: [PATCH 08/17] block: truncate: Don't make backing file data visible
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-8-kwolf@redhat.com>
+Patchwork-id: 97454
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 07/11] block: truncate: Don't make backing file data visible
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+When extending the size of an image that has a backing file larger than
+its old size, make sure that the backing file data doesn't become
+visible in the guest, but the added area is properly zeroed out.
+
+Consider the following scenario where the overlay is shorter than its
+backing file:
+
+    base.qcow2:     AAAAAAAA
+    overlay.qcow2:  BBBB
+
+When resizing (extending) overlay.qcow2, the new blocks should not stay
+unallocated and make the additional As from base.qcow2 visible like
+before this patch, but zeros should be read.
+
+A similar case happens with the various variants of a commit job when an
+intermediate file is short (- for unallocated):
+
+    base.qcow2:     A-A-AAAA
+    mid.qcow2:      BB-B
+    top.qcow2:      C--C--C-
+
+After commit top.qcow2 to mid.qcow2, the following happens:
+
+    mid.qcow2:      CB-C00C0 (correct result)
+    mid.qcow2:      CB-C--C- (before this fix)
+
+Without the fix, blocks that previously read as zeros on top.qcow2
+suddenly turn into A.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 955c7d6687fefcd903900a1e597fcbc896c661cd)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/io.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/block/io.c b/block/io.c
+index 3235ce5..6c70b56 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -3370,6 +3370,31 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
+         goto out;
+     }
+ 
++    /*
++     * If the image has a backing file that is large enough that it would
++     * provide data for the new area, we cannot leave it unallocated because
++     * then the backing file content would become visible. Instead, zero-fill
++     * the new area.
++     *
++     * Note that if the image has a backing file, but was opened without the
++     * backing file, taking care of keeping things consistent with that backing
++     * file is the user's responsibility.
++     */
++    if (new_bytes && bs->backing) {
++        int64_t backing_len;
++
++        backing_len = bdrv_getlength(backing_bs(bs));
++        if (backing_len < 0) {
++            ret = backing_len;
++            error_setg_errno(errp, -ret, "Could not get backing file size");
++            goto out;
++        }
++
++        if (backing_len > old_size) {
++            flags |= BDRV_REQ_ZERO_WRITE;
++        }
++    }
++
+     if (drv->bdrv_co_truncate) {
+         if (flags & ~bs->supported_truncate_flags) {
+             error_setg(errp, "Block driver does not support requested flags");
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-block.c-adding-bdrv_co_delete_file.patch b/SOURCES/kvm-block.c-adding-bdrv_co_delete_file.patch
new file mode 100644
index 0000000..91c3cd1
--- /dev/null
+++ b/SOURCES/kvm-block.c-adding-bdrv_co_delete_file.patch
@@ -0,0 +1,92 @@
+From 23b92512d7f11b3a38cf24a5c2fe7848f1e550e8 Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Sun, 31 May 2020 16:40:34 +0100
+Subject: [PATCH 6/7] block.c: adding bdrv_co_delete_file
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20200531164035.34188-3-mlevitsk@redhat.com>
+Patchwork-id: 97058
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/3] block.c: adding bdrv_co_delete_file
+Bugzilla: 1827630
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb413@gmail.com>
+
+Using the new 'bdrv_co_delete_file' interface, a pure co_routine function
+'bdrv_co_delete_file' inside block.c can can be used in a way similar of
+the existing bdrv_create_file to to clean up a created file.
+
+We're creating a pure co_routine because the only caller of
+'bdrv_co_delete_file' will be already in co_routine context, thus there
+is no need to add all the machinery to check for qemu_in_coroutine() and
+create a separated co_routine to do the job.
+
+Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
+Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Message-Id: <20200130213907.2830642-3-danielhb413@gmail.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit e1d7f8bb1ec0c6911dcea81641ce6139dbded02d)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block.c               | 26 ++++++++++++++++++++++++++
+ include/block/block.h |  1 +
+ 2 files changed, 27 insertions(+)
+
+diff --git a/block.c b/block.c
+index ba3b40d7..d6a05da 100644
+--- a/block.c
++++ b/block.c
+@@ -672,6 +672,32 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
+     return bdrv_create(drv, filename, opts, errp);
+ }
+ 
++int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
++{
++    Error *local_err = NULL;
++    int ret;
++
++    assert(bs != NULL);
++
++    if (!bs->drv) {
++        error_setg(errp, "Block node '%s' is not opened", bs->filename);
++        return -ENOMEDIUM;
++    }
++
++    if (!bs->drv->bdrv_co_delete_file) {
++        error_setg(errp, "Driver '%s' does not support image deletion",
++                   bs->drv->format_name);
++        return -ENOTSUP;
++    }
++
++    ret = bs->drv->bdrv_co_delete_file(bs, &local_err);
++    if (ret < 0) {
++        error_propagate(errp, local_err);
++    }
++
++    return ret;
++}
++
+ /**
+  * Try to get @bs's logical and physical block size.
+  * On success, store them in @bsz struct and return 0.
+diff --git a/include/block/block.h b/include/block/block.h
+index 92685d2..b2a3074 100644
+--- a/include/block/block.h
++++ b/include/block/block.h
+@@ -373,6 +373,7 @@ bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
+ int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
+                               Error **errp);
+ void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
++int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
+ 
+ 
+ typedef struct BdrvCheckResult {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockdev-Promote-several-bitmap-functions-to-non-sta.patch b/SOURCES/kvm-blockdev-Promote-several-bitmap-functions-to-non-sta.patch
new file mode 100644
index 0000000..8cb1700
--- /dev/null
+++ b/SOURCES/kvm-blockdev-Promote-several-bitmap-functions-to-non-sta.patch
@@ -0,0 +1,179 @@
+From 0c8ba0a96a7d0cbf371f1a5fbee543e8b2cb2595 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:13 +0100
+Subject: [PATCH 08/26] blockdev: Promote several bitmap functions to
+ non-static
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-6-eblake@redhat.com>
+Patchwork-id: 97077
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 05/12] blockdev: Promote several bitmap functions to non-static
+Bugzilla: 1779893 1779904
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+The next patch will split blockdev.c, which will require accessing
+some previously-static functions from more than one .c file.  But part
+of promoting a function to public is picking a naming scheme that does
+not reek of exposing too many internals (two of the three functions
+were named starting with 'do_').  To make future code motion easier,
+perform the function rename and non-static promotion into its own
+patch.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200513011648.166876-5-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit c6996cf9a6c759c29919642be9a73ac64b38301b)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ blockdev.c                | 47 +++++++++++++++++++----------------------------
+ include/block/block_int.h | 12 ++++++++++++
+ 2 files changed, 31 insertions(+), 28 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 86eb115..3958058 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1262,10 +1262,10 @@ out_aio_context:
+  *
+  * @return: A bitmap object on success, or NULL on failure.
+  */
+-static BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
+-                                                  const char *name,
+-                                                  BlockDriverState **pbs,
+-                                                  Error **errp)
++BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
++                                           const char *name,
++                                           BlockDriverState **pbs,
++                                           Error **errp)
+ {
+     BlockDriverState *bs;
+     BdrvDirtyBitmap *bitmap;
+@@ -2241,11 +2241,6 @@ static void block_dirty_bitmap_disable_abort(BlkActionState *common)
+     }
+ }
+ 
+-static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(
+-        const char *node, const char *target,
+-        BlockDirtyBitmapMergeSourceList *bitmaps,
+-        HBitmap **backup, Error **errp);
+-
+ static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
+                                              Error **errp)
+ {
+@@ -2259,15 +2254,11 @@ static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
+ 
+     action = common->action->u.block_dirty_bitmap_merge.data;
+ 
+-    state->bitmap = do_block_dirty_bitmap_merge(action->node, action->target,
+-                                                action->bitmaps, &state->backup,
+-                                                errp);
++    state->bitmap = block_dirty_bitmap_merge(action->node, action->target,
++                                             action->bitmaps, &state->backup,
++                                             errp);
+ }
+ 
+-static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
+-        const char *node, const char *name, bool release,
+-        BlockDriverState **bitmap_bs, Error **errp);
+-
+ static void block_dirty_bitmap_remove_prepare(BlkActionState *common,
+                                               Error **errp)
+ {
+@@ -2281,8 +2272,8 @@ static void block_dirty_bitmap_remove_prepare(BlkActionState *common,
+ 
+     action = common->action->u.block_dirty_bitmap_remove.data;
+ 
+-    state->bitmap = do_block_dirty_bitmap_remove(action->node, action->name,
+-                                                 false, &state->bs, errp);
++    state->bitmap = block_dirty_bitmap_remove(action->node, action->name,
++                                              false, &state->bs, errp);
+     if (state->bitmap) {
+         bdrv_dirty_bitmap_skip_store(state->bitmap, true);
+         bdrv_dirty_bitmap_set_busy(state->bitmap, true);
+@@ -3046,9 +3037,10 @@ out:
+     aio_context_release(aio_context);
+ }
+ 
+-static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
+-        const char *node, const char *name, bool release,
+-        BlockDriverState **bitmap_bs, Error **errp)
++BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
++                                           bool release,
++                                           BlockDriverState **bitmap_bs,
++                                           Error **errp)
+ {
+     BlockDriverState *bs;
+     BdrvDirtyBitmap *bitmap;
+@@ -3090,7 +3082,7 @@ static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
+ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
+                                    Error **errp)
+ {
+-    do_block_dirty_bitmap_remove(node, name, true, NULL, errp);
++    block_dirty_bitmap_remove(node, name, true, NULL, errp);
+ }
+ 
+ /**
+@@ -3151,10 +3143,9 @@ void qmp_block_dirty_bitmap_disable(const char *node, const char *name,
+     bdrv_disable_dirty_bitmap(bitmap);
+ }
+ 
+-static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(
+-        const char *node, const char *target,
+-        BlockDirtyBitmapMergeSourceList *bitmaps,
+-        HBitmap **backup, Error **errp)
++BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
++                                          BlockDirtyBitmapMergeSourceList *bms,
++                                          HBitmap **backup, Error **errp)
+ {
+     BlockDriverState *bs;
+     BdrvDirtyBitmap *dst, *src, *anon;
+@@ -3172,7 +3163,7 @@ static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(
+         return NULL;
+     }
+ 
+-    for (lst = bitmaps; lst; lst = lst->next) {
++    for (lst = bms; lst; lst = lst->next) {
+         switch (lst->value->type) {
+             const char *name, *node;
+         case QTYPE_QSTRING:
+@@ -3217,7 +3208,7 @@ void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
+                                   BlockDirtyBitmapMergeSourceList *bitmaps,
+                                   Error **errp)
+ {
+-    do_block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
++    block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
+ }
+ 
+ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index cc18e8d..876a83d 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -1341,4 +1341,16 @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
+                                             Error **errp);
+ extern QemuOptsList bdrv_create_opts_simple;
+ 
++BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
++                                           const char *name,
++                                           BlockDriverState **pbs,
++                                           Error **errp);
++BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
++                                          BlockDirtyBitmapMergeSourceList *bms,
++                                          HBitmap **backup, Error **errp);
++BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
++                                           bool release,
++                                           BlockDriverState **bitmap_bs,
++                                           Error **errp);
++
+ #endif /* BLOCK_INT_H */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-blockdev-Split-off-basic-bitmap-operations-for-qemu-.patch b/SOURCES/kvm-blockdev-Split-off-basic-bitmap-operations-for-qemu-.patch
new file mode 100644
index 0000000..d977922
--- /dev/null
+++ b/SOURCES/kvm-blockdev-Split-off-basic-bitmap-operations-for-qemu-.patch
@@ -0,0 +1,720 @@
+From 2afa718d59ef86879a9e34b4601a1f2658afa9ba Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:14 +0100
+Subject: [PATCH 09/26] blockdev: Split off basic bitmap operations for
+ qemu-img
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-7-eblake@redhat.com>
+Patchwork-id: 97073
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 06/12] blockdev: Split off basic bitmap operations for qemu-img
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Upcoming patches want to add some basic bitmap manipulation abilities
+to qemu-img.  But blockdev.o is too heavyweight to link into qemu-img
+(among other things, it would drag in block jobs and transaction
+support - qemu-img does offline manipulation, where atomicity is less
+important because there are no concurrent modifications to compete
+with), so it's time to split off the bare bones of what we will need
+into a new file block/monitor/bitmap-qmp-cmds.o.
+
+This is sufficient to expose 6 QMP commands for use by qemu-img (add,
+remove, clear, enable, disable, merge), as well as move the three
+helper functions touched in the previous patch.  Regarding
+MAINTAINERS, the new file is automatically part of block core, but
+also makes sense as related to other dirty bitmap files.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200513011648.166876-6-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit bb4e58c6137e80129b955789dd4b66c1504f20dc)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	Makefile.objs - comment context
+	block/monitor/Makefile.objs - context: a2dde2f2 not backported
+	blockdev.c - context
+Signed-off-by: Eric Blake <eblake@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ MAINTAINERS                     |   1 +
+ Makefile.objs                   |   3 +-
+ block/monitor/Makefile.objs     |   1 +
+ block/monitor/bitmap-qmp-cmds.c | 321 ++++++++++++++++++++++++++++++++++++++++
+ blockdev.c                      | 284 -----------------------------------
+ 5 files changed, 324 insertions(+), 286 deletions(-)
+ create mode 100644 block/monitor/Makefile.objs
+ create mode 100644 block/monitor/bitmap-qmp-cmds.c
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 3a81ac9..49d5d44 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1875,6 +1875,7 @@ L: qemu-block@nongnu.org
+ S: Supported
+ F: include/qemu/hbitmap.h
+ F: include/block/dirty-bitmap.h
++F: block/monitor/bitmap-qmp-cmds.c
+ F: block/dirty-bitmap.c
+ F: block/qcow2-bitmap.c
+ F: migration/block-dirty-bitmap.c
+diff --git a/Makefile.objs b/Makefile.objs
+index 1a8f288..7404ef0 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -13,9 +13,8 @@ authz-obj-y = authz/
+ #######################################################################
+ # block-obj-y is code used by both qemu system emulation and qemu-img
+ 
+-block-obj-y = nbd/
++block-obj-y = block/ block/monitor/ nbd/ scsi/
+ block-obj-y += block.o blockjob.o job.o
+-block-obj-y += block/ scsi/
+ block-obj-y += qemu-io-cmds.o
+ block-obj-$(CONFIG_REPLICATION) += replication.o
+ 
+diff --git a/block/monitor/Makefile.objs b/block/monitor/Makefile.objs
+new file mode 100644
+index 0000000..f0c7642
+--- /dev/null
++++ b/block/monitor/Makefile.objs
+@@ -0,0 +1 @@
++block-obj-y += bitmap-qmp-cmds.o
+diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c
+new file mode 100644
+index 0000000..9f11dee
+--- /dev/null
++++ b/block/monitor/bitmap-qmp-cmds.c
+@@ -0,0 +1,321 @@
++/*
++ * QEMU block dirty bitmap QMP commands
++ *
++ * Copyright (c) 2003-2008 Fabrice Bellard
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or
++ * later.  See the COPYING file in the top-level directory.
++ *
++ * This file incorporates work covered by the following copyright and
++ * permission notice:
++ *
++ * Copyright (c) 2003-2008 Fabrice Bellard
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++
++#include "qemu/osdep.h"
++
++#include "block/block_int.h"
++#include "qapi/qapi-commands-block.h"
++#include "qapi/error.h"
++
++/**
++ * block_dirty_bitmap_lookup:
++ * Return a dirty bitmap (if present), after validating
++ * the node reference and bitmap names.
++ *
++ * @node: The name of the BDS node to search for bitmaps
++ * @name: The name of the bitmap to search for
++ * @pbs: Output pointer for BDS lookup, if desired. Can be NULL.
++ * @errp: Output pointer for error information. Can be NULL.
++ *
++ * @return: A bitmap object on success, or NULL on failure.
++ */
++BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
++                                           const char *name,
++                                           BlockDriverState **pbs,
++                                           Error **errp)
++{
++    BlockDriverState *bs;
++    BdrvDirtyBitmap *bitmap;
++
++    if (!node) {
++        error_setg(errp, "Node cannot be NULL");
++        return NULL;
++    }
++    if (!name) {
++        error_setg(errp, "Bitmap name cannot be NULL");
++        return NULL;
++    }
++    bs = bdrv_lookup_bs(node, node, NULL);
++    if (!bs) {
++        error_setg(errp, "Node '%s' not found", node);
++        return NULL;
++    }
++
++    bitmap = bdrv_find_dirty_bitmap(bs, name);
++    if (!bitmap) {
++        error_setg(errp, "Dirty bitmap '%s' not found", name);
++        return NULL;
++    }
++
++    if (pbs) {
++        *pbs = bs;
++    }
++
++    return bitmap;
++}
++
++void qmp_block_dirty_bitmap_add(const char *node, const char *name,
++                                bool has_granularity, uint32_t granularity,
++                                bool has_persistent, bool persistent,
++                                bool has_disabled, bool disabled,
++                                Error **errp)
++{
++    BlockDriverState *bs;
++    BdrvDirtyBitmap *bitmap;
++    AioContext *aio_context;
++
++    if (!name || name[0] == '\0') {
++        error_setg(errp, "Bitmap name cannot be empty");
++        return;
++    }
++
++    bs = bdrv_lookup_bs(node, node, errp);
++    if (!bs) {
++        return;
++    }
++
++    aio_context = bdrv_get_aio_context(bs);
++    aio_context_acquire(aio_context);
++
++    if (has_granularity) {
++        if (granularity < 512 || !is_power_of_2(granularity)) {
++            error_setg(errp, "Granularity must be power of 2 "
++                             "and at least 512");
++            goto out;
++        }
++    } else {
++        /* Default to cluster size, if available: */
++        granularity = bdrv_get_default_bitmap_granularity(bs);
++    }
++
++    if (!has_persistent) {
++        persistent = false;
++    }
++
++    if (!has_disabled) {
++        disabled = false;
++    }
++
++    if (persistent &&
++        !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
++    {
++        goto out;
++    }
++
++    bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
++    if (bitmap == NULL) {
++        goto out;
++    }
++
++    if (disabled) {
++        bdrv_disable_dirty_bitmap(bitmap);
++    }
++
++    bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
++
++out:
++    aio_context_release(aio_context);
++}
++
++BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
++                                           bool release,
++                                           BlockDriverState **bitmap_bs,
++                                           Error **errp)
++{
++    BlockDriverState *bs;
++    BdrvDirtyBitmap *bitmap;
++    AioContext *aio_context;
++
++    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
++    if (!bitmap || !bs) {
++        return NULL;
++    }
++
++    aio_context = bdrv_get_aio_context(bs);
++    aio_context_acquire(aio_context);
++
++    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO,
++                                errp)) {
++        aio_context_release(aio_context);
++        return NULL;
++    }
++
++    if (bdrv_dirty_bitmap_get_persistence(bitmap) &&
++        bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0)
++    {
++        aio_context_release(aio_context);
++        return NULL;
++    }
++
++    if (release) {
++        bdrv_release_dirty_bitmap(bitmap);
++    }
++
++    if (bitmap_bs) {
++        *bitmap_bs = bs;
++    }
++
++    aio_context_release(aio_context);
++    return release ? NULL : bitmap;
++}
++
++void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
++                                   Error **errp)
++{
++    block_dirty_bitmap_remove(node, name, true, NULL, errp);
++}
++
++/**
++ * Completely clear a bitmap, for the purposes of synchronizing a bitmap
++ * immediately after a full backup operation.
++ */
++void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
++                                  Error **errp)
++{
++    BdrvDirtyBitmap *bitmap;
++    BlockDriverState *bs;
++
++    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
++    if (!bitmap || !bs) {
++        return;
++    }
++
++    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) {
++        return;
++    }
++
++    bdrv_clear_dirty_bitmap(bitmap, NULL);
++}
++
++void qmp_block_dirty_bitmap_enable(const char *node, const char *name,
++                                   Error **errp)
++{
++    BlockDriverState *bs;
++    BdrvDirtyBitmap *bitmap;
++
++    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
++    if (!bitmap) {
++        return;
++    }
++
++    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
++        return;
++    }
++
++    bdrv_enable_dirty_bitmap(bitmap);
++}
++
++void qmp_block_dirty_bitmap_disable(const char *node, const char *name,
++                                    Error **errp)
++{
++    BlockDriverState *bs;
++    BdrvDirtyBitmap *bitmap;
++
++    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
++    if (!bitmap) {
++        return;
++    }
++
++    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
++        return;
++    }
++
++    bdrv_disable_dirty_bitmap(bitmap);
++}
++
++BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
++                                          BlockDirtyBitmapMergeSourceList *bms,
++                                          HBitmap **backup, Error **errp)
++{
++    BlockDriverState *bs;
++    BdrvDirtyBitmap *dst, *src, *anon;
++    BlockDirtyBitmapMergeSourceList *lst;
++    Error *local_err = NULL;
++
++    dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
++    if (!dst) {
++        return NULL;
++    }
++
++    anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
++                                    NULL, errp);
++    if (!anon) {
++        return NULL;
++    }
++
++    for (lst = bms; lst; lst = lst->next) {
++        switch (lst->value->type) {
++            const char *name, *node;
++        case QTYPE_QSTRING:
++            name = lst->value->u.local;
++            src = bdrv_find_dirty_bitmap(bs, name);
++            if (!src) {
++                error_setg(errp, "Dirty bitmap '%s' not found", name);
++                dst = NULL;
++                goto out;
++            }
++            break;
++        case QTYPE_QDICT:
++            node = lst->value->u.external.node;
++            name = lst->value->u.external.name;
++            src = block_dirty_bitmap_lookup(node, name, NULL, errp);
++            if (!src) {
++                dst = NULL;
++                goto out;
++            }
++            break;
++        default:
++            abort();
++        }
++
++        bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err);
++        if (local_err) {
++            error_propagate(errp, local_err);
++            dst = NULL;
++            goto out;
++        }
++    }
++
++    /* Merge into dst; dst is unchanged on failure. */
++    bdrv_merge_dirty_bitmap(dst, anon, backup, errp);
++
++ out:
++    bdrv_release_dirty_bitmap(anon);
++    return dst;
++}
++
++void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
++                                  BlockDirtyBitmapMergeSourceList *bitmaps,
++                                  Error **errp)
++{
++    block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
++}
+diff --git a/blockdev.c b/blockdev.c
+index 3958058..5128c9b 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -1250,53 +1250,6 @@ out_aio_context:
+     return NULL;
+ }
+ 
+-/**
+- * block_dirty_bitmap_lookup:
+- * Return a dirty bitmap (if present), after validating
+- * the node reference and bitmap names.
+- *
+- * @node: The name of the BDS node to search for bitmaps
+- * @name: The name of the bitmap to search for
+- * @pbs: Output pointer for BDS lookup, if desired. Can be NULL.
+- * @errp: Output pointer for error information. Can be NULL.
+- *
+- * @return: A bitmap object on success, or NULL on failure.
+- */
+-BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
+-                                           const char *name,
+-                                           BlockDriverState **pbs,
+-                                           Error **errp)
+-{
+-    BlockDriverState *bs;
+-    BdrvDirtyBitmap *bitmap;
+-
+-    if (!node) {
+-        error_setg(errp, "Node cannot be NULL");
+-        return NULL;
+-    }
+-    if (!name) {
+-        error_setg(errp, "Bitmap name cannot be NULL");
+-        return NULL;
+-    }
+-    bs = bdrv_lookup_bs(node, node, NULL);
+-    if (!bs) {
+-        error_setg(errp, "Node '%s' not found", node);
+-        return NULL;
+-    }
+-
+-    bitmap = bdrv_find_dirty_bitmap(bs, name);
+-    if (!bitmap) {
+-        error_setg(errp, "Dirty bitmap '%s' not found", name);
+-        return NULL;
+-    }
+-
+-    if (pbs) {
+-        *pbs = bs;
+-    }
+-
+-    return bitmap;
+-}
+-
+ /* New and old BlockDriverState structs for atomic group operations */
+ 
+ typedef struct BlkActionState BlkActionState;
+@@ -2974,243 +2927,6 @@ out:
+     aio_context_release(aio_context);
+ }
+ 
+-void qmp_block_dirty_bitmap_add(const char *node, const char *name,
+-                                bool has_granularity, uint32_t granularity,
+-                                bool has_persistent, bool persistent,
+-                                bool has_disabled, bool disabled,
+-                                Error **errp)
+-{
+-    BlockDriverState *bs;
+-    BdrvDirtyBitmap *bitmap;
+-    AioContext *aio_context;
+-
+-    if (!name || name[0] == '\0') {
+-        error_setg(errp, "Bitmap name cannot be empty");
+-        return;
+-    }
+-
+-    bs = bdrv_lookup_bs(node, node, errp);
+-    if (!bs) {
+-        return;
+-    }
+-
+-    aio_context = bdrv_get_aio_context(bs);
+-    aio_context_acquire(aio_context);
+-
+-    if (has_granularity) {
+-        if (granularity < 512 || !is_power_of_2(granularity)) {
+-            error_setg(errp, "Granularity must be power of 2 "
+-                             "and at least 512");
+-            goto out;
+-        }
+-    } else {
+-        /* Default to cluster size, if available: */
+-        granularity = bdrv_get_default_bitmap_granularity(bs);
+-    }
+-
+-    if (!has_persistent) {
+-        persistent = false;
+-    }
+-
+-    if (!has_disabled) {
+-        disabled = false;
+-    }
+-
+-    if (persistent &&
+-        !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
+-    {
+-        goto out;
+-    }
+-
+-    bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
+-    if (bitmap == NULL) {
+-        goto out;
+-    }
+-
+-    if (disabled) {
+-        bdrv_disable_dirty_bitmap(bitmap);
+-    }
+-
+-    bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
+-
+-out:
+-    aio_context_release(aio_context);
+-}
+-
+-BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
+-                                           bool release,
+-                                           BlockDriverState **bitmap_bs,
+-                                           Error **errp)
+-{
+-    BlockDriverState *bs;
+-    BdrvDirtyBitmap *bitmap;
+-    AioContext *aio_context;
+-
+-    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
+-    if (!bitmap || !bs) {
+-        return NULL;
+-    }
+-
+-    aio_context = bdrv_get_aio_context(bs);
+-    aio_context_acquire(aio_context);
+-
+-    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO,
+-                                errp)) {
+-        aio_context_release(aio_context);
+-        return NULL;
+-    }
+-
+-    if (bdrv_dirty_bitmap_get_persistence(bitmap) &&
+-        bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0)
+-    {
+-        aio_context_release(aio_context);
+-        return NULL;
+-    }
+-
+-    if (release) {
+-        bdrv_release_dirty_bitmap(bitmap);
+-    }
+-
+-    if (bitmap_bs) {
+-        *bitmap_bs = bs;
+-    }
+-
+-    aio_context_release(aio_context);
+-    return release ? NULL : bitmap;
+-}
+-
+-void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
+-                                   Error **errp)
+-{
+-    block_dirty_bitmap_remove(node, name, true, NULL, errp);
+-}
+-
+-/**
+- * Completely clear a bitmap, for the purposes of synchronizing a bitmap
+- * immediately after a full backup operation.
+- */
+-void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
+-                                  Error **errp)
+-{
+-    BdrvDirtyBitmap *bitmap;
+-    BlockDriverState *bs;
+-
+-    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
+-    if (!bitmap || !bs) {
+-        return;
+-    }
+-
+-    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) {
+-        return;
+-    }
+-
+-    bdrv_clear_dirty_bitmap(bitmap, NULL);
+-}
+-
+-void qmp_block_dirty_bitmap_enable(const char *node, const char *name,
+-                                   Error **errp)
+-{
+-    BlockDriverState *bs;
+-    BdrvDirtyBitmap *bitmap;
+-
+-    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
+-    if (!bitmap) {
+-        return;
+-    }
+-
+-    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
+-        return;
+-    }
+-
+-    bdrv_enable_dirty_bitmap(bitmap);
+-}
+-
+-void qmp_block_dirty_bitmap_disable(const char *node, const char *name,
+-                                    Error **errp)
+-{
+-    BlockDriverState *bs;
+-    BdrvDirtyBitmap *bitmap;
+-
+-    bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
+-    if (!bitmap) {
+-        return;
+-    }
+-
+-    if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
+-        return;
+-    }
+-
+-    bdrv_disable_dirty_bitmap(bitmap);
+-}
+-
+-BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
+-                                          BlockDirtyBitmapMergeSourceList *bms,
+-                                          HBitmap **backup, Error **errp)
+-{
+-    BlockDriverState *bs;
+-    BdrvDirtyBitmap *dst, *src, *anon;
+-    BlockDirtyBitmapMergeSourceList *lst;
+-    Error *local_err = NULL;
+-
+-    dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
+-    if (!dst) {
+-        return NULL;
+-    }
+-
+-    anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
+-                                    NULL, errp);
+-    if (!anon) {
+-        return NULL;
+-    }
+-
+-    for (lst = bms; lst; lst = lst->next) {
+-        switch (lst->value->type) {
+-            const char *name, *node;
+-        case QTYPE_QSTRING:
+-            name = lst->value->u.local;
+-            src = bdrv_find_dirty_bitmap(bs, name);
+-            if (!src) {
+-                error_setg(errp, "Dirty bitmap '%s' not found", name);
+-                dst = NULL;
+-                goto out;
+-            }
+-            break;
+-        case QTYPE_QDICT:
+-            node = lst->value->u.external.node;
+-            name = lst->value->u.external.name;
+-            src = block_dirty_bitmap_lookup(node, name, NULL, errp);
+-            if (!src) {
+-                dst = NULL;
+-                goto out;
+-            }
+-            break;
+-        default:
+-            abort();
+-        }
+-
+-        bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err);
+-        if (local_err) {
+-            error_propagate(errp, local_err);
+-            dst = NULL;
+-            goto out;
+-        }
+-    }
+-
+-    /* Merge into dst; dst is unchanged on failure. */
+-    bdrv_merge_dirty_bitmap(dst, anon, backup, errp);
+-
+- out:
+-    bdrv_release_dirty_bitmap(anon);
+-    return dst;
+-}
+-
+-void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
+-                                  BlockDirtyBitmapMergeSourceList *bitmaps,
+-                                  Error **errp)
+-{
+-    block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
+-}
+-
+ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
+                                                               const char *name,
+                                                               Error **errp)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-compat-disable-edid-for-virtio-gpu-ccw.patch b/SOURCES/kvm-compat-disable-edid-for-virtio-gpu-ccw.patch
new file mode 100644
index 0000000..e000534
--- /dev/null
+++ b/SOURCES/kvm-compat-disable-edid-for-virtio-gpu-ccw.patch
@@ -0,0 +1,50 @@
+From 8f9f4d8d52ebb7878543ac0b84cc372477041e33 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Wed, 1 Apr 2020 16:13:50 -0400
+Subject: [PATCH 2/2] compat: disable 'edid' for virtio-gpu-ccw
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200401161350.20462-1-cohuck@redhat.com>
+Patchwork-id: 94523
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2] compat: disable 'edid' for virtio-gpu-ccw
+Bugzilla: 1816793
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Markus Armbruster <armbru@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1816793
+Branch: rhel-av-8.2.1
+Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=27629804
+Upstream: downstream only
+Tested: verified that for a virtio-gpu-ccw device 'edid' is false with
+        a s390-ccw-virtio-rhel7.6.0 machine and true with a
+        s390-ccw-virtio-rhel8.2.0 (s390x does not have the 8.0 or 8.1
+        machine types)
+
+hw_compat_rhel_8_0 copied the original upstream version of
+disabling 'edid' for virtio-gpu-pci only (not following later
+changes). Switch it to virtio-gpu-device, following upstream
+02501fc39381 ("compat: disable edid on correct virtio-gpu device").
+
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Jon Maloy <jmaloy.redhat.com>
+---
+ hw/core/machine.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/core/machine.c b/hw/core/machine.c
+index e0e0eec8bf..5a025d1af2 100644
+--- a/hw/core/machine.c
++++ b/hw/core/machine.c
+@@ -72,7 +72,7 @@ GlobalProperty hw_compat_rhel_8_0[] = {
+     /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+     { "virtio-vga",     "edid", "false" },
+     /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+-    { "virtio-gpu-pci", "edid", "false" },
++    { "virtio-gpu-device", "edid", "false" },
+     /* hw_compat_rhel_8_0 from hw_compat_4_0 */
+     { "virtio-device", "use-started", "false" },
+     /* hw_compat_rhel_8_0 from hw_compat_3_1 - that was added in 4.1 */
+-- 
+2.18.2
+
diff --git a/SOURCES/kvm-config-enable-VFIO_CCW.patch b/SOURCES/kvm-config-enable-VFIO_CCW.patch
new file mode 100644
index 0000000..44af9cf
--- /dev/null
+++ b/SOURCES/kvm-config-enable-VFIO_CCW.patch
@@ -0,0 +1,39 @@
+From f3e80771c921560a58c30020781fa01a54be8eb0 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:43 -0400
+Subject: [PATCH 09/12] config: enable VFIO_CCW
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-10-cohuck@redhat.com>
+Patchwork-id: 97699
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 9/9] config: enable VFIO_CCW
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Enable vfio-ccw in RHEL builds.
+
+Upstream: n/a
+
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ default-configs/s390x-rh-devices.mak | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/default-configs/s390x-rh-devices.mak b/default-configs/s390x-rh-devices.mak
+index c3c73fe752..08a15f3e01 100644
+--- a/default-configs/s390x-rh-devices.mak
++++ b/default-configs/s390x-rh-devices.mak
+@@ -9,6 +9,7 @@ CONFIG_SCSI=y
+ CONFIG_TERMINAL3270=y
+ CONFIG_VFIO=y
+ CONFIG_VFIO_AP=y
++CONFIG_VFIO_CCW=y
+ CONFIG_VFIO_PCI=y
+ CONFIG_VHOST_USER=y
+ CONFIG_VIRTIO_CCW=y
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-crypto.c-cleanup-created-file-when-block_crypto_co_c.patch b/SOURCES/kvm-crypto.c-cleanup-created-file-when-block_crypto_co_c.patch
new file mode 100644
index 0000000..891b866
--- /dev/null
+++ b/SOURCES/kvm-crypto.c-cleanup-created-file-when-block_crypto_co_c.patch
@@ -0,0 +1,98 @@
+From 043decff5812c1f46ed44dd0f82099e3b8bb6a28 Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <mlevitsk@redhat.com>
+Date: Sun, 31 May 2020 16:40:35 +0100
+Subject: [PATCH 7/7] crypto.c: cleanup created file when
+ block_crypto_co_create_opts_luks fails
+
+RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: <20200531164035.34188-4-mlevitsk@redhat.com>
+Patchwork-id: 97060
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 3/3] crypto.c: cleanup created file when block_crypto_co_create_opts_luks fails
+Bugzilla: 1827630
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+
+From: Daniel Henrique Barboza <danielhb413@gmail.com>
+
+When using a non-UTF8 secret to create a volume using qemu-img, the
+following error happens:
+
+$ qemu-img create -f luks --object secret,id=vol_1_encrypt0,file=vol_resize_pool.vol_1.secret.qzVQrI -o key-secret=vol_1_encrypt0 /var/tmp/pool_target/vol_1 10240K
+
+Formatting '/var/tmp/pool_target/vol_1', fmt=luks size=10485760 key-secret=vol_1_encrypt0
+qemu-img: /var/tmp/pool_target/vol_1: Data from secret vol_1_encrypt0 is not valid UTF-8
+
+However, the created file '/var/tmp/pool_target/vol_1' is left behind in the
+file system after the failure. This behavior can be observed when creating
+the volume using Libvirt, via 'virsh vol-create', and then getting "volume
+target path already exist" errors when trying to re-create the volume.
+
+The volume file is created inside block_crypto_co_create_opts_luks(), in
+block/crypto.c. If the bdrv_create_file() call is successful but any
+succeeding step fails*, the existing 'fail' label does not take into
+account the created file, leaving it behind.
+
+This patch changes block_crypto_co_create_opts_luks() to delete
+'filename' in case of failure. A failure in this point means that
+the volume is now truncated/corrupted, so even if 'filename' was an
+existing volume before calling qemu-img, it is now unusable. Deleting
+the file it is not much worse than leaving it in the filesystem in
+this scenario, and we don't have to deal with checking the file
+pre-existence in the code.
+
+* in our case, block_crypto_co_create_generic calls qcrypto_block_create,
+which calls qcrypto_block_luks_create, and this function fails when
+calling qcrypto_secret_lookup_as_utf8.
+
+Reported-by: Srikanth Aithal <bssrikanth@in.ibm.com>
+Suggested-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Message-Id: <20200130213907.2830642-4-danielhb413@gmail.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 1bba30da24e1124ceeb0693c81382a0d77e20ca5)
+Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/crypto.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/block/crypto.c b/block/crypto.c
+index 970d463..5e3b15c 100644
+--- a/block/crypto.c
++++ b/block/crypto.c
+@@ -30,6 +30,7 @@
+ #include "qapi/error.h"
+ #include "qemu/module.h"
+ #include "qemu/option.h"
++#include "qemu/cutils.h"
+ #include "crypto.h"
+ 
+ typedef struct BlockCrypto BlockCrypto;
+@@ -597,6 +598,23 @@ static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
+ 
+     ret = 0;
+ fail:
++    /*
++     * If an error occurred, delete 'filename'. Even if the file existed
++     * beforehand, it has been truncated and corrupted in the process.
++     */
++    if (ret && bs) {
++        Error *local_delete_err = NULL;
++        int r_del = bdrv_co_delete_file(bs, &local_delete_err);
++        /*
++         * ENOTSUP will happen if the block driver doesn't support
++         * the 'bdrv_co_delete_file' interface. This is a predictable
++         * scenario and shouldn't be reported back to the user.
++         */
++        if ((r_del < 0) && (r_del != -ENOTSUP)) {
++            error_report_err(local_delete_err);
++        }
++    }
++
+     bdrv_unref(bs);
+     qapi_free_QCryptoBlockCreateOptions(create_opts);
+     qobject_unref(cryptoopts);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-enable-ramfb.patch b/SOURCES/kvm-enable-ramfb.patch
new file mode 100644
index 0000000..fa2fe11
--- /dev/null
+++ b/SOURCES/kvm-enable-ramfb.patch
@@ -0,0 +1,72 @@
+From 441128e2f13a56d4949b70971edd2f6902772959 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 3 Jun 2020 15:15:56 +0100
+Subject: [PATCH 01/17] enable ramfb
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20200603151556.1195-2-kraxel@redhat.com>
+Patchwork-id: 97097
+O-Subject: [RHEL-AV-8.2.0.z qemu-kvm PATCH 1/1] enable ramfb
+Bugzilla: 1841068
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+---
+ hw/vfio/pci.c            | 5 -----
+ hw/display/Makefile.objs | 5 ++---
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/display/Makefile.objs | 5 ++---
+ hw/vfio/pci.c            | 5 -----
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
+index 3d0cda1..f2182e3 100644
+--- a/hw/display/Makefile.objs
++++ b/hw/display/Makefile.objs
+@@ -1,9 +1,8 @@
+ common-obj-$(CONFIG_DDC) += i2c-ddc.o
+ common-obj-$(CONFIG_EDID) += edid-generate.o edid-region.o
+ 
+-# Disabled for Red Hat Enterprise Linux
+-#common-obj-$(CONFIG_FW_CFG_DMA) += ramfb.o
+-#common-obj-$(CONFIG_FW_CFG_DMA) += ramfb-standalone.o
++common-obj-$(CONFIG_FW_CFG_DMA) += ramfb.o
++common-obj-$(CONFIG_FW_CFG_DMA) += ramfb-standalone.o
+ 
+ common-obj-$(CONFIG_ADS7846) += ads7846.o
+ common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
+diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
+index d717520..f191904 100644
+--- a/hw/vfio/pci.c
++++ b/hw/vfio/pci.c
+@@ -3249,7 +3249,6 @@ static const TypeInfo vfio_pci_dev_info = {
+     },
+ };
+ 
+-#if 0 /* Disabled for Red Hat Enterprise Linux */
+ static Property vfio_pci_dev_nohotplug_properties[] = {
+     DEFINE_PROP_BOOL("ramfb", VFIOPCIDevice, enable_ramfb, false),
+     DEFINE_PROP_END_OF_LIST(),
+@@ -3269,15 +3268,11 @@ static const TypeInfo vfio_pci_nohotplug_dev_info = {
+     .instance_size = sizeof(VFIOPCIDevice),
+     .class_init = vfio_pci_nohotplug_dev_class_init,
+ };
+-#endif
+ 
+ static void register_vfio_pci_dev_type(void)
+ {
+     type_register_static(&vfio_pci_dev_info);
+-
+-#if 0 /* Disabled for Red Hat Enterprise Linux */
+     type_register_static(&vfio_pci_nohotplug_dev_info);
+-#endif
+ }
+ 
+ type_init(register_vfio_pci_dev_type)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-file-posix-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch b/SOURCES/kvm-file-posix-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
new file mode 100644
index 0000000..efdf16b
--- /dev/null
+++ b/SOURCES/kvm-file-posix-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
@@ -0,0 +1,48 @@
+From 55bfda3a0e077b822f57e8ed901f0cee848bc471 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:35 +0100
+Subject: [PATCH 07/17] file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-7-kwolf@redhat.com>
+Patchwork-id: 97452
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 06/11] file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
+OS, so we can advertise the flag and just ignore it.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 2f0c6e7a650de133eccd94e9bb6cf7b2070f07f1)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/file-posix.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/block/file-posix.c b/block/file-posix.c
+index 7551e8d..adafbfa 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -674,6 +674,10 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
+ #endif
+ 
+     bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
++    if (S_ISREG(st.st_mode)) {
++        /* When extending regular files, we get zeros from the OS */
++        bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
++    }
+     ret = 0;
+ fail:
+     if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hmat-acpi-Build-Memory-Proximity-Domain-Attributes-S.patch b/SOURCES/kvm-hmat-acpi-Build-Memory-Proximity-Domain-Attributes-S.patch
new file mode 100644
index 0000000..e34f576
--- /dev/null
+++ b/SOURCES/kvm-hmat-acpi-Build-Memory-Proximity-Domain-Attributes-S.patch
@@ -0,0 +1,275 @@
+From a0816e4374759048cb24b9b3549a093a2ccb6240 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:50 +0100
+Subject: [PATCH 07/12] hmat acpi: Build Memory Proximity Domain Attributes
+ Structure(s)
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-7-plai@redhat.com>
+Patchwork-id: 96734
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 06/11] hmat acpi: Build Memory Proximity Domain Attributes Structure(s)
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+HMAT is defined in ACPI 6.3: 5.2.27 Heterogeneous Memory Attribute Table
+(HMAT). The specification references below link:
+http://www.uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
+
+It describes the memory attributes, such as memory side cache
+attributes and bandwidth and latency details, related to the
+Memory Proximity Domain. The software is
+expected to use this information as hint for optimization.
+
+This structure describes Memory Proximity Domain Attributes by memory
+subsystem and its associativity with processor proximity domain as well as
+hint for memory usage.
+
+In the linux kernel, the codes in drivers/acpi/hmat/hmat.c parse and report
+the platform's HMAT tables.
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+Reviewed-by: Daniel Black <daniel@linux.ibm.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-5-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit e6f123c3b81241be33f1b763d0ff8b36d1ae9c1e)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/acpi/Kconfig       |  7 ++--
+ hw/acpi/Makefile.objs |  1 +
+ hw/acpi/hmat.c        | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ hw/acpi/hmat.h        | 42 ++++++++++++++++++++++
+ hw/i386/acpi-build.c  |  5 +++
+ 5 files changed, 152 insertions(+), 2 deletions(-)
+ create mode 100644 hw/acpi/hmat.c
+ create mode 100644 hw/acpi/hmat.h
+
+diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
+index 12e3f1e..54209c6 100644
+--- a/hw/acpi/Kconfig
++++ b/hw/acpi/Kconfig
+@@ -7,6 +7,7 @@ config ACPI_X86
+     select ACPI_NVDIMM
+     select ACPI_CPU_HOTPLUG
+     select ACPI_MEMORY_HOTPLUG
++    select ACPI_HMAT
+ 
+ config ACPI_X86_ICH
+     bool
+@@ -23,6 +24,10 @@ config ACPI_NVDIMM
+     bool
+     depends on ACPI
+ 
++config ACPI_HMAT
++    bool
++    depends on ACPI
++
+ config ACPI_PCI
+     bool
+     depends on ACPI && PCI
+@@ -33,5 +38,3 @@ config ACPI_VMGENID
+     depends on PC
+ 
+ config ACPI_HW_REDUCED
+-    bool
+-    depends on ACPI
+diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
+index 655a9c1..517bd88 100644
+--- a/hw/acpi/Makefile.objs
++++ b/hw/acpi/Makefile.objs
+@@ -7,6 +7,7 @@ common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
+ common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
+ common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
+ common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
++common-obj-$(CONFIG_ACPI_HMAT) += hmat.o
+ common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
+ 
+ common-obj-y += acpi_interface.o
+diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
+new file mode 100644
+index 0000000..9ff7930
+--- /dev/null
++++ b/hw/acpi/hmat.c
+@@ -0,0 +1,99 @@
++/*
++ * HMAT ACPI Implementation
++ *
++ * Copyright(C) 2019 Intel Corporation.
++ *
++ * Author:
++ *  Liu jingqi <jingqi.liu@linux.intel.com>
++ *  Tao Xu <tao3.xu@intel.com>
++ *
++ * HMAT is defined in ACPI 6.3: 5.2.27 Heterogeneous Memory Attribute Table
++ * (HMAT)
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>
++ */
++
++#include "qemu/osdep.h"
++#include "sysemu/numa.h"
++#include "hw/acpi/hmat.h"
++
++/*
++ * ACPI 6.3:
++ * 5.2.27.3 Memory Proximity Domain Attributes Structure: Table 5-145
++ */
++static void build_hmat_mpda(GArray *table_data, uint16_t flags,
++                            uint32_t initiator, uint32_t mem_node)
++{
++
++    /* Memory Proximity Domain Attributes Structure */
++    /* Type */
++    build_append_int_noprefix(table_data, 0, 2);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 2);
++    /* Length */
++    build_append_int_noprefix(table_data, 40, 4);
++    /* Flags */
++    build_append_int_noprefix(table_data, flags, 2);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 2);
++    /* Proximity Domain for the Attached Initiator */
++    build_append_int_noprefix(table_data, initiator, 4);
++    /* Proximity Domain for the Memory */
++    build_append_int_noprefix(table_data, mem_node, 4);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 4);
++    /*
++     * Reserved:
++     * Previously defined as the Start Address of the System Physical
++     * Address Range. Deprecated since ACPI Spec 6.3.
++     */
++    build_append_int_noprefix(table_data, 0, 8);
++    /*
++     * Reserved:
++     * Previously defined as the Range Length of the region in bytes.
++     * Deprecated since ACPI Spec 6.3.
++     */
++    build_append_int_noprefix(table_data, 0, 8);
++}
++
++/* Build HMAT sub table structures */
++static void hmat_build_table_structs(GArray *table_data, NumaState *numa_state)
++{
++    uint16_t flags;
++    int i;
++
++    for (i = 0; i < numa_state->num_nodes; i++) {
++        flags = 0;
++
++        if (numa_state->nodes[i].initiator < MAX_NODES) {
++            flags |= HMAT_PROXIMITY_INITIATOR_VALID;
++        }
++
++        build_hmat_mpda(table_data, flags, numa_state->nodes[i].initiator, i);
++    }
++}
++
++void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *numa_state)
++{
++    int hmat_start = table_data->len;
++
++    /* reserve space for HMAT header  */
++    acpi_data_push(table_data, 40);
++
++    hmat_build_table_structs(table_data, numa_state);
++
++    build_header(linker, table_data,
++                 (void *)(table_data->data + hmat_start),
++                 "HMAT", table_data->len - hmat_start, 2, NULL, NULL);
++}
+diff --git a/hw/acpi/hmat.h b/hw/acpi/hmat.h
+new file mode 100644
+index 0000000..437dbc6
+--- /dev/null
++++ b/hw/acpi/hmat.h
+@@ -0,0 +1,42 @@
++/*
++ * HMAT ACPI Implementation Header
++ *
++ * Copyright(C) 2019 Intel Corporation.
++ *
++ * Author:
++ *  Liu jingqi <jingqi.liu@linux.intel.com>
++ *  Tao Xu <tao3.xu@intel.com>
++ *
++ * HMAT is defined in ACPI 6.3: 5.2.27 Heterogeneous Memory Attribute Table
++ * (HMAT)
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>
++ */
++
++#ifndef HMAT_H
++#define HMAT_H
++
++#include "hw/acpi/aml-build.h"
++
++/*
++ * ACPI 6.3: 5.2.27.3 Memory Proximity Domain Attributes Structure,
++ * Table 5-145, Field "flag", Bit [0]: set to 1 to indicate that data in
++ * the Proximity Domain for the Attached Initiator field is valid.
++ * Other bits reserved.
++ */
++#define HMAT_PROXIMITY_INITIATOR_VALID  0x1
++
++void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *numa_state);
++
++#endif
+diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
+index 6400189..b1f8c55 100644
+--- a/hw/i386/acpi-build.c
++++ b/hw/i386/acpi-build.c
+@@ -67,6 +67,7 @@
+ #include "hw/i386/intel_iommu.h"
+ 
+ #include "hw/acpi/ipmi.h"
++#include "hw/acpi/hmat.h"
+ 
+ /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
+  * -M pc-i440fx-2.0.  Even if the actual amount of AML generated grows
+@@ -2837,6 +2838,10 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
+             acpi_add_table(table_offsets, tables_blob);
+             build_slit(tables_blob, tables->linker, machine);
+         }
++        if (machine->numa_state->hmat_enabled) {
++            acpi_add_table(table_offsets, tables_blob);
++            build_hmat(tables_blob, tables->linker, machine->numa_state);
++        }
+     }
+     if (acpi_get_mcfg(&mcfg)) {
+         acpi_add_table(table_offsets, tables_blob);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hmat-acpi-Build-Memory-Side-Cache-Information-Struct.patch b/SOURCES/kvm-hmat-acpi-Build-Memory-Side-Cache-Information-Struct.patch
new file mode 100644
index 0000000..01ef4ce
--- /dev/null
+++ b/SOURCES/kvm-hmat-acpi-Build-Memory-Side-Cache-Information-Struct.patch
@@ -0,0 +1,137 @@
+From d00453667cb972dc2fe1242081d3b39313a6a925 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:52 +0100
+Subject: [PATCH 09/12] hmat acpi: Build Memory Side Cache Information
+ Structure(s)
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-9-plai@redhat.com>
+Patchwork-id: 96741
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 08/11] hmat acpi: Build Memory Side Cache Information Structure(s)
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+This structure describes memory side cache information for memory
+proximity domains if the memory side cache is present and the
+physical device forms the memory side cache.
+The software could use this information to effectively place
+the data in memory to maximize the performance of the system
+memory that use the memory side cache.
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+Reviewed-by: Daniel Black <daniel@linux.ibm.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-7-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit a9c2b841af002db6e21e1297c9026b63fc22c875)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/acpi/hmat.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 68 insertions(+), 1 deletion(-)
+
+diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
+index 4635d45..7c24bb5 100644
+--- a/hw/acpi/hmat.c
++++ b/hw/acpi/hmat.c
+@@ -143,14 +143,62 @@ static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
+     g_free(entry_list);
+ }
+ 
++/* ACPI 6.3: 5.2.27.5 Memory Side Cache Information Structure: Table 5-147 */
++static void build_hmat_cache(GArray *table_data, uint8_t total_levels,
++                             NumaHmatCacheOptions *hmat_cache)
++{
++    /*
++     * Cache Attributes: Bits [3:0] – Total Cache Levels
++     * for this Memory Proximity Domain
++     */
++    uint32_t cache_attr = total_levels;
++
++    /* Bits [7:4] : Cache Level described in this structure */
++    cache_attr |= (uint32_t) hmat_cache->level << 4;
++
++    /* Bits [11:8] - Cache Associativity */
++    cache_attr |= (uint32_t) hmat_cache->associativity << 8;
++
++    /* Bits [15:12] - Write Policy */
++    cache_attr |= (uint32_t) hmat_cache->policy << 12;
++
++    /* Bits [31:16] - Cache Line size in bytes */
++    cache_attr |= (uint32_t) hmat_cache->line << 16;
++
++    /* Type */
++    build_append_int_noprefix(table_data, 2, 2);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 2);
++    /* Length */
++    build_append_int_noprefix(table_data, 32, 4);
++    /* Proximity Domain for the Memory */
++    build_append_int_noprefix(table_data, hmat_cache->node_id, 4);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 4);
++    /* Memory Side Cache Size */
++    build_append_int_noprefix(table_data, hmat_cache->size, 8);
++    /* Cache Attributes */
++    build_append_int_noprefix(table_data, cache_attr, 4);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 2);
++    /*
++     * Number of SMBIOS handles (n)
++     * Linux kernel uses Memory Side Cache Information Structure
++     * without SMBIOS entries for now, so set Number of SMBIOS handles
++     * as 0.
++     */
++    build_append_int_noprefix(table_data, 0, 2);
++}
++
+ /* Build HMAT sub table structures */
+ static void hmat_build_table_structs(GArray *table_data, NumaState *numa_state)
+ {
+     uint16_t flags;
+     uint32_t num_initiator = 0;
+     uint32_t initiator_list[MAX_NODES];
+-    int i, hierarchy, type;
++    int i, hierarchy, type, cache_level, total_levels;
+     HMAT_LB_Info *hmat_lb;
++    NumaHmatCacheOptions *hmat_cache;
+ 
+     for (i = 0; i < numa_state->num_nodes; i++) {
+         flags = 0;
+@@ -184,6 +232,25 @@ static void hmat_build_table_structs(GArray *table_data, NumaState *numa_state)
+             }
+         }
+     }
++
++    /*
++     * ACPI 6.3: 5.2.27.5 Memory Side Cache Information Structure:
++     * Table 5-147
++     */
++    for (i = 0; i < numa_state->num_nodes; i++) {
++        total_levels = 0;
++        for (cache_level = 1; cache_level < HMAT_LB_LEVELS; cache_level++) {
++            if (numa_state->hmat_cache[i][cache_level]) {
++                total_levels++;
++            }
++        }
++        for (cache_level = 0; cache_level <= total_levels; cache_level++) {
++            hmat_cache = numa_state->hmat_cache[i][cache_level];
++            if (hmat_cache) {
++                build_hmat_cache(table_data, total_levels, hmat_cache);
++            }
++        }
++    }
+ }
+ 
+ void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *numa_state)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hmat-acpi-Build-System-Locality-Latency-and-Bandwidt.patch b/SOURCES/kvm-hmat-acpi-Build-System-Locality-Latency-and-Bandwidt.patch
new file mode 100644
index 0000000..a7120d7
--- /dev/null
+++ b/SOURCES/kvm-hmat-acpi-Build-System-Locality-Latency-and-Bandwidt.patch
@@ -0,0 +1,173 @@
+From f55b8b251c323856087baf2380d93fbf2da15db7 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:51 +0100
+Subject: [PATCH 08/12] hmat acpi: Build System Locality Latency and Bandwidth
+ Information Structure(s)
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-8-plai@redhat.com>
+Patchwork-id: 96733
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 07/11] hmat acpi: Build System Locality Latency and Bandwidth Information Structure(s)
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+This structure describes the memory access latency and bandwidth
+information from various memory access initiator proximity domains.
+The latency and bandwidth numbers represented in this structure
+correspond to rated latency and bandwidth for the platform.
+The software could use this information as hint for optimization.
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-6-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 4586a2cb833f80b19c80ebe364a005ac2fa0974a)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/acpi/hmat.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 103 insertions(+), 1 deletion(-)
+
+diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
+index 9ff7930..4635d45 100644
+--- a/hw/acpi/hmat.c
++++ b/hw/acpi/hmat.c
+@@ -25,6 +25,7 @@
+  */
+ 
+ #include "qemu/osdep.h"
++#include "qemu/units.h"
+ #include "sysemu/numa.h"
+ #include "hw/acpi/hmat.h"
+ 
+@@ -67,11 +68,89 @@ static void build_hmat_mpda(GArray *table_data, uint16_t flags,
+     build_append_int_noprefix(table_data, 0, 8);
+ }
+ 
++/*
++ * ACPI 6.3: 5.2.27.4 System Locality Latency and Bandwidth Information
++ * Structure: Table 5-146
++ */
++static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
++                          uint32_t num_initiator, uint32_t num_target,
++                          uint32_t *initiator_list)
++{
++    int i, index;
++    HMAT_LB_Data *lb_data;
++    uint16_t *entry_list;
++    uint32_t base;
++    /* Length in bytes for entire structure */
++    uint32_t lb_length
++        = 32 /* Table length upto and including Entry Base Unit */
++        + 4 * num_initiator /* Initiator Proximity Domain List */
++        + 4 * num_target /* Target Proximity Domain List */
++        + 2 * num_initiator * num_target; /* Latency or Bandwidth Entries */
++
++    /* Type */
++    build_append_int_noprefix(table_data, 1, 2);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 2);
++    /* Length */
++    build_append_int_noprefix(table_data, lb_length, 4);
++    /* Flags: Bits [3:0] Memory Hierarchy, Bits[7:4] Reserved */
++    assert(!(hmat_lb->hierarchy >> 4));
++    build_append_int_noprefix(table_data, hmat_lb->hierarchy, 1);
++    /* Data Type */
++    build_append_int_noprefix(table_data, hmat_lb->data_type, 1);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 2);
++    /* Number of Initiator Proximity Domains (s) */
++    build_append_int_noprefix(table_data, num_initiator, 4);
++    /* Number of Target Proximity Domains (t) */
++    build_append_int_noprefix(table_data, num_target, 4);
++    /* Reserved */
++    build_append_int_noprefix(table_data, 0, 4);
++
++    /* Entry Base Unit */
++    if (hmat_lb->data_type <= HMAT_LB_DATA_WRITE_LATENCY) {
++        /* Convert latency base from nanoseconds to picosecond */
++        base = hmat_lb->base * 1000;
++    } else {
++        /* Convert bandwidth base from Byte to Megabyte */
++        base = hmat_lb->base / MiB;
++    }
++    build_append_int_noprefix(table_data, base, 8);
++
++    /* Initiator Proximity Domain List */
++    for (i = 0; i < num_initiator; i++) {
++        build_append_int_noprefix(table_data, initiator_list[i], 4);
++    }
++
++    /* Target Proximity Domain List */
++    for (i = 0; i < num_target; i++) {
++        build_append_int_noprefix(table_data, i, 4);
++    }
++
++    /* Latency or Bandwidth Entries */
++    entry_list = g_malloc0(num_initiator * num_target * sizeof(uint16_t));
++    for (i = 0; i < hmat_lb->list->len; i++) {
++        lb_data = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);
++        index = lb_data->initiator * num_target + lb_data->target;
++
++        entry_list[index] = (uint16_t)(lb_data->data / hmat_lb->base);
++    }
++
++    for (i = 0; i < num_initiator * num_target; i++) {
++        build_append_int_noprefix(table_data, entry_list[i], 2);
++    }
++
++    g_free(entry_list);
++}
++
+ /* Build HMAT sub table structures */
+ static void hmat_build_table_structs(GArray *table_data, NumaState *numa_state)
+ {
+     uint16_t flags;
+-    int i;
++    uint32_t num_initiator = 0;
++    uint32_t initiator_list[MAX_NODES];
++    int i, hierarchy, type;
++    HMAT_LB_Info *hmat_lb;
+ 
+     for (i = 0; i < numa_state->num_nodes; i++) {
+         flags = 0;
+@@ -82,6 +161,29 @@ static void hmat_build_table_structs(GArray *table_data, NumaState *numa_state)
+ 
+         build_hmat_mpda(table_data, flags, numa_state->nodes[i].initiator, i);
+     }
++
++    for (i = 0; i < numa_state->num_nodes; i++) {
++        if (numa_state->nodes[i].has_cpu) {
++            initiator_list[num_initiator++] = i;
++        }
++    }
++
++    /*
++     * ACPI 6.3: 5.2.27.4 System Locality Latency and Bandwidth Information
++     * Structure: Table 5-146
++     */
++    for (hierarchy = HMAT_LB_MEM_MEMORY;
++         hierarchy <= HMAT_LB_MEM_CACHE_3RD_LEVEL; hierarchy++) {
++        for (type = HMAT_LB_DATA_ACCESS_LATENCY;
++             type <= HMAT_LB_DATA_WRITE_BANDWIDTH; type++) {
++            hmat_lb = numa_state->hmat_lb[hierarchy][type];
++
++            if (hmat_lb && hmat_lb->list->len) {
++                build_hmat_lb(table_data, hmat_lb, num_initiator,
++                              numa_state->num_nodes, initiator_list);
++            }
++        }
++    }
+ }
+ 
+ void build_hmat(GArray *table_data, BIOSLinker *linker, NumaState *numa_state)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-pcie-Forbid-hot-plug-if-it-s-disabled-on-the-.patch b/SOURCES/kvm-hw-pci-pcie-Forbid-hot-plug-if-it-s-disabled-on-the-.patch
new file mode 100644
index 0000000..2f4f6dd
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-pcie-Forbid-hot-plug-if-it-s-disabled-on-the-.patch
@@ -0,0 +1,77 @@
+From fe8a9f211fba3588d60507b3d2f48c41d8ee3c79 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Mon, 4 May 2020 21:25:04 +0100
+Subject: [PATCH 1/9] hw/pci/pcie: Forbid hot-plug if it's disabled on the slot
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200504212505.15977-2-jusual@redhat.com>
+Patchwork-id: 96257
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/2] hw/pci/pcie: Forbid hot-plug if it's disabled on the slot
+Bugzilla: 1820531
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+Raise an error when trying to hot-plug/unplug a device through QMP to a device
+with disabled hot-plug capability. This makes the device behaviour more
+consistent and provides an explanation of the failure in the case of
+asynchronous unplug.
+
+Signed-off-by: Julia Suvorova <jusual@redhat.com>
+Message-Id: <20200427182440.92433-2-jusual@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
+(cherry picked from commit 0501e1aa1d32a6e02dd06a79bba97fbe9d557cb5)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/pci/pcie.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
+index 0eb3a2a..6b48d04 100644
+--- a/hw/pci/pcie.c
++++ b/hw/pci/pcie.c
+@@ -415,6 +415,7 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ {
+     PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
+     uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
++    uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
+     PCIDevice *pci_dev = PCI_DEVICE(dev);
+ 
+     /* Don't send event when device is enabled during qemu machine creation:
+@@ -430,6 +431,13 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+         return;
+     }
+ 
++    /* Check if hot-plug is disabled on the slot */
++    if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
++        error_setg(errp, "Hot-plug failed: unsupported by the port device '%s'",
++                         DEVICE(hotplug_pdev)->id);
++        return;
++    }
++
+     /* To enable multifunction hot-plug, we just ensure the function
+      * 0 added last. When function 0 is added, we set the sltsta and
+      * inform OS via event notification.
+@@ -470,6 +478,17 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
+     Error *local_err = NULL;
+     PCIDevice *pci_dev = PCI_DEVICE(dev);
+     PCIBus *bus = pci_get_bus(pci_dev);
++    PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
++    uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
++    uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
++
++    /* Check if hot-unplug is disabled on the slot */
++    if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
++        error_setg(errp, "Hot-unplug failed: "
++                         "unsupported by the port device '%s'",
++                         DEVICE(hotplug_pdev)->id);
++        return;
++    }
+ 
+     pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &local_err);
+     if (local_err) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-hw-pci-pcie-Move-hot-plug-capability-check-to-pre_pl.patch b/SOURCES/kvm-hw-pci-pcie-Move-hot-plug-capability-check-to-pre_pl.patch
new file mode 100644
index 0000000..0c44c77
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-pcie-Move-hot-plug-capability-check-to-pre_pl.patch
@@ -0,0 +1,90 @@
+From 035f8aaabf2c31cd6206bff6da23a12fee69d1b7 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Tue, 16 Jun 2020 12:25:36 -0400
+Subject: [PATCH 1/3] hw/pci/pcie: Move hot plug capability check to pre_plug
+ callback
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200616122536.1027685-1-jusual@redhat.com>
+Patchwork-id: 97548
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/1] hw/pci/pcie: Move hot plug capability check to pre_plug callback
+Bugzilla: 1820531
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1820531
+BRANCH: rhel-av-8.2.1
+UPSTREAM: merged
+BREW: 29422092
+
+Check for hot plug capability earlier to avoid removing devices attached
+during the initialization process.
+
+Run qemu with an unattached drive:
+  -drive file=$FILE,if=none,id=drive0 \
+  -device pcie-root-port,id=rp0,slot=3,bus=pcie.0,hotplug=off
+Hotplug a block device:
+  device_add virtio-blk-pci,id=blk0,drive=drive0,bus=rp0
+If hotplug fails on plug_cb, drive0 will be deleted.
+
+Fixes: 0501e1aa1d32a6 ("hw/pci/pcie: Forbid hot-plug if it's disabled on the slot")
+
+Acked-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Julia Suvorova <jusual@redhat.com>
+Message-Id: <20200604125947.881210-1-jusual@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 0dabc0f6544f2c0310546f6d6cf3b68979580a9c)
+Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+---
+ hw/pci/pcie.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
+index abc99b6eff..1386dd228c 100644
+--- a/hw/pci/pcie.c
++++ b/hw/pci/pcie.c
+@@ -407,6 +407,17 @@ static void pcie_cap_slot_plug_common(PCIDevice *hotplug_dev, DeviceState *dev,
+ void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+                                Error **errp)
+ {
++    PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
++    uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
++    uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
++
++    /* Check if hot-plug is disabled on the slot */
++    if (dev->hotplugged && (sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
++        error_setg(errp, "Hot-plug failed: unsupported by the port device '%s'",
++                         DEVICE(hotplug_pdev)->id);
++        return;
++    }
++
+     pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, errp);
+ }
+ 
+@@ -415,7 +426,6 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ {
+     PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
+     uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
+-    uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP);
+     PCIDevice *pci_dev = PCI_DEVICE(dev);
+ 
+     /* Don't send event when device is enabled during qemu machine creation:
+@@ -431,13 +441,6 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+         return;
+     }
+ 
+-    /* Check if hot-plug is disabled on the slot */
+-    if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) {
+-        error_setg(errp, "Hot-plug failed: unsupported by the port device '%s'",
+-                         DEVICE(hotplug_pdev)->id);
+-        return;
+-    }
+-
+     /* To enable multifunction hot-plug, we just ensure the function
+      * 0 added last. When function 0 is added, we set the sltsta and
+      * inform OS via event notification.
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-hw-pci-pcie-Replace-PCI_DEVICE-casts-with-existing-v.patch b/SOURCES/kvm-hw-pci-pcie-Replace-PCI_DEVICE-casts-with-existing-v.patch
new file mode 100644
index 0000000..51a587f
--- /dev/null
+++ b/SOURCES/kvm-hw-pci-pcie-Replace-PCI_DEVICE-casts-with-existing-v.patch
@@ -0,0 +1,62 @@
+From f98a1fdad0aa53337925ac46b73a3e6ad36f6295 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Mon, 4 May 2020 21:25:05 +0100
+Subject: [PATCH 2/9] hw/pci/pcie: Replace PCI_DEVICE() casts with existing
+ variable
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200504212505.15977-3-jusual@redhat.com>
+Patchwork-id: 96259
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] hw/pci/pcie: Replace PCI_DEVICE() casts with existing variable
+Bugzilla: 1820531
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+A little cleanup is possible because of hotplug_pdev introduction.
+
+Signed-off-by: Julia Suvorova <jusual@redhat.com>
+Message-Id: <20200427182440.92433-3-jusual@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
+(cherry picked from commit 6a1e073378353eb6ac0565e0dc649b3db76ed5dc)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/pci/pcie.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
+index 6b48d04..abc99b6 100644
+--- a/hw/pci/pcie.c
++++ b/hw/pci/pcie.c
+@@ -449,7 +449,7 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+             pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA,
+                                        PCI_EXP_LNKSTA_DLLLA);
+         }
+-        pcie_cap_slot_event(PCI_DEVICE(hotplug_dev),
++        pcie_cap_slot_event(hotplug_pdev,
+                             PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
+     }
+ }
+@@ -490,7 +490,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
+         return;
+     }
+ 
+-    pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &local_err);
++    pcie_cap_slot_plug_common(hotplug_pdev, dev, &local_err);
+     if (local_err) {
+         error_propagate(errp, local_err);
+         return;
+@@ -509,7 +509,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
+         return;
+     }
+ 
+-    pcie_cap_slot_push_attention_button(PCI_DEVICE(hotplug_dev));
++    pcie_cap_slot_push_attention_button(hotplug_pdev);
+ }
+ 
+ /* pci express slot for pci express root/downstream port
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-Add-MSR-feature-bit-for-MDS-NO.patch b/SOURCES/kvm-i386-Add-MSR-feature-bit-for-MDS-NO.patch
new file mode 100644
index 0000000..823ff0c
--- /dev/null
+++ b/SOURCES/kvm-i386-Add-MSR-feature-bit-for-MDS-NO.patch
@@ -0,0 +1,46 @@
+From cdafcc1d68110ed172c09c9e6bba42ee15b5a6df Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Fri, 15 May 2020 18:02:40 +0100
+Subject: [PATCH 13/17] i386: Add MSR feature bit for MDS-NO
+
+RH-Author: plai@redhat.com
+Message-id: <20200515180243.17488-2-plai@redhat.com>
+Patchwork-id: 96609
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 1/4] i386: Add MSR feature bit for MDS-NO
+Bugzilla: 1769912
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+From: Cathy Zhang <cathy.zhang@intel.com>
+
+Define MSR_ARCH_CAP_MDS_NO in the IA32_ARCH_CAPABILITIES MSR to allow
+CPU models to report the feature when host supports it.
+
+Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
+Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Reviewed-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <1571729728-23284-2-git-send-email-cathy.zhang@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 77b168d221191156c47fcd8d1c47329dfdb9439e)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 4441061..60304cc 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -839,6 +839,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define MSR_ARCH_CAP_RSBA       (1U << 2)
+ #define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
+ #define MSR_ARCH_CAP_SSB_NO     (1U << 4)
++#define MSR_ARCH_CAP_MDS_NO     (1U << 5)
+ 
+ #define MSR_CORE_CAP_SPLIT_LOCK_DETECT  (1U << 5)
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-Add-macro-for-stibp.patch b/SOURCES/kvm-i386-Add-macro-for-stibp.patch
new file mode 100644
index 0000000..17dd149
--- /dev/null
+++ b/SOURCES/kvm-i386-Add-macro-for-stibp.patch
@@ -0,0 +1,49 @@
+From 00f916987589f114f42ce20b138c00c47b9e4df7 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Fri, 15 May 2020 18:02:41 +0100
+Subject: [PATCH 14/17] i386: Add macro for stibp
+
+RH-Author: plai@redhat.com
+Message-id: <20200515180243.17488-3-plai@redhat.com>
+Patchwork-id: 96610
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 2/4] i386: Add macro for stibp
+Bugzilla: 1769912
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Cathy Zhang <cathy.zhang@intel.com>
+
+stibp feature is already added through the following commit.
+https://github.com/qemu/qemu/commit/0e8916582991b9fd0b94850a8444b8b80d0a0955
+
+Add a macro for it to allow CPU models to report it when host supports.
+
+Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
+Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Reviewed-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <1571729728-23284-3-git-send-email-cathy.zhang@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 5af514d0cb314f43bc53f2aefb437f6451d64d0c)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 60304cc..e77d101 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -772,6 +772,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_EDX_AVX512_4FMAPS     (1U << 3)
+ /* Speculation Control */
+ #define CPUID_7_0_EDX_SPEC_CTRL         (1U << 26)
++/* Single Thread Indirect Branch Predictors */
++#define CPUID_7_0_EDX_STIBP             (1U << 27)
+ /* Arch Capabilities */
+ #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)
+ /* Core Capability */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-i386-Add-new-CPU-model-Cooperlake.patch b/SOURCES/kvm-i386-Add-new-CPU-model-Cooperlake.patch
new file mode 100644
index 0000000..289d1e3
--- /dev/null
+++ b/SOURCES/kvm-i386-Add-new-CPU-model-Cooperlake.patch
@@ -0,0 +1,108 @@
+From cf62577aed781b2515ea97b9f42285c2f608a7bf Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Fri, 15 May 2020 18:02:42 +0100
+Subject: [PATCH 16/17] i386: Add new CPU model Cooperlake
+
+RH-Author: plai@redhat.com
+Message-id: <20200515180243.17488-4-plai@redhat.com>
+Patchwork-id: 96608
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 3/4] i386: Add new CPU model Cooperlake
+Bugzilla: 1769912
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Cathy Zhang <cathy.zhang@intel.com>
+
+Cooper Lake is intel's successor to Cascade Lake, the new
+CPU model inherits features from Cascadelake-Server, while
+add one platform associated new feature: AVX512_BF16. Meanwhile,
+add STIBP for speculative execution.
+
+Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
+Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Reviewed-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <1571729728-23284-4-git-send-email-cathy.zhang@intel.com>
+Reviewed-by: Bruce Rogers <brogers@suse.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 22a866b6166db5caa4abaa6e656c2a431fa60726)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 0f0a2db..996a74f 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3161,6 +3161,66 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         }
+     },
+     {
++        .name = "Cooperlake",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 85,
++        .stepping = 10,
++        .features[FEAT_1_EDX] =
++            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++            CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
++            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
++            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
++            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
++            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
++            CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
++        .features[FEAT_7_0_ECX] =
++            CPUID_7_0_ECX_PKU |
++            CPUID_7_0_ECX_AVX512VNNI,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_STIBP |
++            CPUID_7_0_EDX_SPEC_CTRL_SSBD | CPUID_7_0_EDX_ARCH_CAPABILITIES,
++        .features[FEAT_ARCH_CAPABILITIES] =
++            MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
++            MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO,
++        .features[FEAT_7_1_EAX] =
++            CPUID_7_1_EAX_AVX512_BF16,
++        /*
++         * Missing: XSAVES (not supported by some Linux versions,
++         * including v4.1 to v4.12).
++         * KVM doesn't yet expose any XSAVES state save component,
++         * and the only one defined in Skylake (processor tracing)
++         * probably will block migration anyway.
++         */
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
++            CPUID_XSAVE_XGETBV1,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .xlevel = 0x80000008,
++        .model_id = "Intel Xeon Processor (Cooperlake)",
++    },
++    {
+         .name = "Icelake-Client",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-introduce-kvm_kernel_irqchip_-functions.patch b/SOURCES/kvm-introduce-kvm_kernel_irqchip_-functions.patch
new file mode 100644
index 0000000..b171749
--- /dev/null
+++ b/SOURCES/kvm-introduce-kvm_kernel_irqchip_-functions.patch
@@ -0,0 +1,281 @@
+From 3899672db472c1ca530badd49d17726a1057f8af Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 5 Jun 2020 07:41:10 -0400
+Subject: [PATCH 40/42] kvm: introduce kvm_kernel_irqchip_* functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200605074111.2185-3-thuth@redhat.com>
+Patchwork-id: 97369
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 2/3] kvm: introduce kvm_kernel_irqchip_* functions
+Bugzilla: 1756946
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+The KVMState struct is opaque, so provide accessors for the fields
+that will be moved from current_machine to the accelerator.  For now
+they just forward to the machine object, but this will change.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 4376c40dedb22530738eeb104a603e94ed03f719)
+
+Conflicts:
+	accel/kvm/kvm-all.c
+	(contextual conflict due to missing other commits in downstream)
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ accel/kvm/kvm-all.c  | 23 +++++++++++++++++++----
+ hw/ppc/e500.c        |  5 ++---
+ hw/ppc/spapr_irq.c   | 16 ++++------------
+ include/sysemu/kvm.h |  7 +++++--
+ target/arm/kvm.c     |  8 ++++----
+ target/i386/kvm.c    |  4 ++--
+ target/mips/kvm.c    |  2 +-
+ target/ppc/kvm.c     |  2 +-
+ target/s390x/kvm.c   |  2 +-
+ 9 files changed, 39 insertions(+), 30 deletions(-)
+
+diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
+index 5007bdad96..b0250209f5 100644
+--- a/accel/kvm/kvm-all.c
++++ b/accel/kvm/kvm-all.c
+@@ -1772,7 +1772,7 @@ void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
+     g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
+ }
+ 
+-static void kvm_irqchip_create(MachineState *machine, KVMState *s)
++static void kvm_irqchip_create(KVMState *s)
+ {
+     int ret;
+ 
+@@ -1790,9 +1790,9 @@ static void kvm_irqchip_create(MachineState *machine, KVMState *s)
+ 
+     /* First probe and see if there's a arch-specific hook to create the
+      * in-kernel irqchip for us */
+-    ret = kvm_arch_irqchip_create(machine, s);
++    ret = kvm_arch_irqchip_create(s);
+     if (ret == 0) {
+-        if (machine_kernel_irqchip_split(machine)) {
++        if (kvm_kernel_irqchip_split()) {
+             perror("Split IRQ chip mode not supported.");
+             exit(1);
+         } else {
+@@ -2076,7 +2076,7 @@ static int kvm_init(MachineState *ms)
+     }
+ 
+     if (machine_kernel_irqchip_allowed(ms)) {
+-        kvm_irqchip_create(ms, s);
++        kvm_irqchip_create(s);
+     }
+ 
+     if (kvm_eventfds_allowed) {
+@@ -2966,6 +2966,21 @@ static bool kvm_accel_has_memory(MachineState *ms, AddressSpace *as,
+     return false;
+ }
+ 
++bool kvm_kernel_irqchip_allowed(void)
++{
++    return machine_kernel_irqchip_allowed(current_machine);
++}
++
++bool kvm_kernel_irqchip_required(void)
++{
++    return machine_kernel_irqchip_required(current_machine);
++}
++
++bool kvm_kernel_irqchip_split(void)
++{
++    return machine_kernel_irqchip_split(current_machine);
++}
++
+ static void kvm_accel_class_init(ObjectClass *oc, void *data)
+ {
+     AccelClass *ac = ACCEL_CLASS(oc);
+diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
+index 91cd4c26f9..12b6a5b2a8 100644
+--- a/hw/ppc/e500.c
++++ b/hw/ppc/e500.c
+@@ -793,7 +793,6 @@ static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,
+                                       MemoryRegion *ccsr,
+                                       IrqLines *irqs)
+ {
+-    MachineState *machine = MACHINE(pms);
+     const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
+     DeviceState *dev = NULL;
+     SysBusDevice *s;
+@@ -801,10 +800,10 @@ static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,
+     if (kvm_enabled()) {
+         Error *err = NULL;
+ 
+-        if (machine_kernel_irqchip_allowed(machine)) {
++        if (kvm_kernel_irqchip_allowed()) {
+             dev = ppce500_init_mpic_kvm(pmc, irqs, &err);
+         }
+-        if (machine_kernel_irqchip_required(machine) && !dev) {
++        if (kvm_kernel_irqchip_required() && !dev) {
+             error_reportf_err(err,
+                               "kernel_irqchip requested but unavailable: ");
+             exit(1);
+diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
+index 9da423658a..f388d07bf9 100644
+--- a/hw/ppc/spapr_irq.c
++++ b/hw/ppc/spapr_irq.c
+@@ -75,12 +75,11 @@ int spapr_irq_init_kvm(SpaprInterruptControllerInitKvm fn,
+                        uint32_t nr_servers,
+                        Error **errp)
+ {
+-    MachineState *machine = MACHINE(qdev_get_machine());
+     Error *local_err = NULL;
+ 
+-    if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
++    if (kvm_enabled() && kvm_kernel_irqchip_allowed()) {
+         if (fn(intc, nr_servers, &local_err) < 0) {
+-            if (machine_kernel_irqchip_required(machine)) {
++            if (kvm_kernel_irqchip_required()) {
+                 error_prepend(&local_err,
+                               "kernel_irqchip requested but unavailable: ");
+                 error_propagate(errp, local_err);
+@@ -185,7 +184,7 @@ static int spapr_irq_check(SpaprMachineState *spapr, Error **errp)
+      */
+     if (kvm_enabled() &&
+         spapr->irq == &spapr_irq_dual &&
+-        machine_kernel_irqchip_required(machine) &&
++        kvm_kernel_irqchip_required() &&
+         xics_kvm_has_broken_disconnect(spapr)) {
+         error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
+         return -1;
+@@ -288,20 +287,13 @@ uint32_t spapr_irq_nr_msis(SpaprMachineState *spapr)
+ 
+ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
+ {
+-    MachineState *machine = MACHINE(spapr);
+     SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ 
+-    if (machine_kernel_irqchip_split(machine)) {
++    if (kvm_enabled() && kvm_kernel_irqchip_split()) {
+         error_setg(errp, "kernel_irqchip split mode not supported on pseries");
+         return;
+     }
+ 
+-    if (!kvm_enabled() && machine_kernel_irqchip_required(machine)) {
+-        error_setg(errp,
+-                   "kernel_irqchip requested but only available with KVM");
+-        return;
+-    }
+-
+     if (spapr_irq_check(spapr, errp) < 0) {
+         return;
+     }
+diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
+index 9fe233b9bf..aaf2a502e8 100644
+--- a/include/sysemu/kvm.h
++++ b/include/sysemu/kvm.h
+@@ -519,10 +519,13 @@ void kvm_pc_gsi_handler(void *opaque, int n, int level);
+ void kvm_pc_setup_irq_routing(bool pci_enabled);
+ void kvm_init_irq_routing(KVMState *s);
+ 
++bool kvm_kernel_irqchip_allowed(void);
++bool kvm_kernel_irqchip_required(void);
++bool kvm_kernel_irqchip_split(void);
++
+ /**
+  * kvm_arch_irqchip_create:
+  * @KVMState: The KVMState pointer
+- * @MachineState: The MachineState pointer
+  *
+  * Allow architectures to create an in-kernel irq chip themselves.
+  *
+@@ -530,7 +533,7 @@ void kvm_init_irq_routing(KVMState *s);
+  *            0: irq chip was not created
+  *          > 0: irq chip was created
+  */
+-int kvm_arch_irqchip_create(MachineState *ms, KVMState *s);
++int kvm_arch_irqchip_create(KVMState *s);
+ 
+ /**
+  * kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl
+diff --git a/target/arm/kvm.c b/target/arm/kvm.c
+index 4be9497402..418bcedc3e 100644
+--- a/target/arm/kvm.c
++++ b/target/arm/kvm.c
+@@ -861,11 +861,11 @@ void kvm_arch_init_irq_routing(KVMState *s)
+ {
+ }
+ 
+-int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
++int kvm_arch_irqchip_create(KVMState *s)
+ {
+-     if (machine_kernel_irqchip_split(ms)) {
+-         perror("-machine kernel_irqchip=split is not supported on ARM.");
+-         exit(1);
++    if (kvm_kernel_irqchip_split()) {
++        perror("-machine kernel_irqchip=split is not supported on ARM.");
++        exit(1);
+     }
+ 
+     /* If we can create the VGIC using the newer device control API, we
+diff --git a/target/i386/kvm.c b/target/i386/kvm.c
+index fcc8f7d1f3..f5c17e0028 100644
+--- a/target/i386/kvm.c
++++ b/target/i386/kvm.c
+@@ -4532,10 +4532,10 @@ void kvm_arch_init_irq_routing(KVMState *s)
+     }
+ }
+ 
+-int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
++int kvm_arch_irqchip_create(KVMState *s)
+ {
+     int ret;
+-    if (machine_kernel_irqchip_split(ms)) {
++    if (kvm_kernel_irqchip_split()) {
+         ret = kvm_vm_enable_cap(s, KVM_CAP_SPLIT_IRQCHIP, 0, 24);
+         if (ret) {
+             error_report("Could not enable split irqchip mode: %s",
+diff --git a/target/mips/kvm.c b/target/mips/kvm.c
+index 578bc14625..de3e26ef1f 100644
+--- a/target/mips/kvm.c
++++ b/target/mips/kvm.c
+@@ -57,7 +57,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     return 0;
+ }
+ 
+-int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
++int kvm_arch_irqchip_create(KVMState *s)
+ {
+     return 0;
+ }
+diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
+index c77f9848ec..461dc6dae1 100644
+--- a/target/ppc/kvm.c
++++ b/target/ppc/kvm.c
+@@ -152,7 +152,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     return 0;
+ }
+ 
+-int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
++int kvm_arch_irqchip_create(KVMState *s)
+ {
+     return 0;
+ }
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 84d7cadd09..c589ef9034 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -386,7 +386,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     return 0;
+ }
+ 
+-int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
++int kvm_arch_irqchip_create(KVMState *s)
+ {
+     return 0;
+ }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-iotests-055-refactor-compressed-backup-to-vmdk.patch b/SOURCES/kvm-iotests-055-refactor-compressed-backup-to-vmdk.patch
new file mode 100644
index 0000000..401f39f
--- /dev/null
+++ b/SOURCES/kvm-iotests-055-refactor-compressed-backup-to-vmdk.patch
@@ -0,0 +1,176 @@
+From a5bf39550e82dbbe18f8debe07fa5d968a3fcf51 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:17 +0100
+Subject: [PATCH 18/26] iotests/055: refactor compressed backup to vmdk
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-4-kwolf@redhat.com>
+Patchwork-id: 97104
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 03/11] iotests/055: refactor compressed backup to vmdk
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+
+Instead of looping in each test, let's better refactor vmdk target case
+as a subclass.
+
+Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200430124713.3067-6-vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 8e8372944e5e097e98844b4db10f867689065e16)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/055     | 70 ++++++++++++++++++++++++----------------------
+ tests/qemu-iotests/055.out |  4 +--
+ 2 files changed, 39 insertions(+), 35 deletions(-)
+
+diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
+index eb50c9f..8666601 100755
+--- a/tests/qemu-iotests/055
++++ b/tests/qemu-iotests/055
+@@ -450,10 +450,9 @@ class TestSingleTransaction(iotests.QMPTestCase):
+         self.assert_no_active_block_jobs()
+ 
+ 
+-class TestDriveCompression(iotests.QMPTestCase):
++class TestCompressedToQcow2(iotests.QMPTestCase):
+     image_len = 64 * 1024 * 1024 # MB
+-    fmt_supports_compression = [{'type': 'qcow2', 'args': ()},
+-                                {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized')}]
++    target_fmt = {'type': 'qcow2', 'args': ()}
+ 
+     def tearDown(self):
+         self.vm.shutdown()
+@@ -463,19 +462,20 @@ class TestDriveCompression(iotests.QMPTestCase):
+         except OSError:
+             pass
+ 
+-    def do_prepare_drives(self, fmt, args, attach_target):
++    def do_prepare_drives(self, attach_target):
+         self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
+ 
+-        qemu_img('create', '-f', fmt, blockdev_target_img,
+-                 str(TestDriveCompression.image_len), *args)
++        qemu_img('create', '-f', self.target_fmt['type'], blockdev_target_img,
++                 str(self.image_len), *self.target_fmt['args'])
+         if attach_target:
+             self.vm.add_drive(blockdev_target_img,
+-                              img_format=fmt, interface="none")
++                              img_format=self.target_fmt['type'],
++                              interface="none")
+ 
+         self.vm.launch()
+ 
+-    def do_test_compress_complete(self, cmd, format, attach_target, **args):
+-        self.do_prepare_drives(format['type'], format['args'], attach_target)
++    def do_test_compress_complete(self, cmd, attach_target, **args):
++        self.do_prepare_drives(attach_target)
+ 
+         self.assert_no_active_block_jobs()
+ 
+@@ -486,21 +486,21 @@ class TestDriveCompression(iotests.QMPTestCase):
+ 
+         self.vm.shutdown()
+         self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
+-                                               iotests.imgfmt, format['type']),
++                                               iotests.imgfmt,
++                                               self.target_fmt['type']),
+                         'target image does not match source after backup')
+ 
+     def test_complete_compress_drive_backup(self):
+-        for format in TestDriveCompression.fmt_supports_compression:
+-            self.do_test_compress_complete('drive-backup', format, False,
+-                                           target=blockdev_target_img, mode='existing')
++        self.do_test_compress_complete('drive-backup', False,
++                                       target=blockdev_target_img,
++                                       mode='existing')
+ 
+     def test_complete_compress_blockdev_backup(self):
+-        for format in TestDriveCompression.fmt_supports_compression:
+-            self.do_test_compress_complete('blockdev-backup', format, True,
+-                                           target='drive1')
++        self.do_test_compress_complete('blockdev-backup',
++                                       True, target='drive1')
+ 
+-    def do_test_compress_cancel(self, cmd, format, attach_target, **args):
+-        self.do_prepare_drives(format['type'], format['args'], attach_target)
++    def do_test_compress_cancel(self, cmd, attach_target, **args):
++        self.do_prepare_drives(attach_target)
+ 
+         self.assert_no_active_block_jobs()
+ 
+@@ -514,17 +514,16 @@ class TestDriveCompression(iotests.QMPTestCase):
+         self.vm.shutdown()
+ 
+     def test_compress_cancel_drive_backup(self):
+-        for format in TestDriveCompression.fmt_supports_compression:
+-            self.do_test_compress_cancel('drive-backup', format, False,
+-                                         target=blockdev_target_img, mode='existing')
++        self.do_test_compress_cancel('drive-backup', False,
++                                     target=blockdev_target_img,
++                                     mode='existing')
+ 
+     def test_compress_cancel_blockdev_backup(self):
+-       for format in TestDriveCompression.fmt_supports_compression:
+-            self.do_test_compress_cancel('blockdev-backup', format, True,
+-                                         target='drive1')
++        self.do_test_compress_cancel('blockdev-backup', True,
++                                     target='drive1')
+ 
+-    def do_test_compress_pause(self, cmd, format, attach_target, **args):
+-        self.do_prepare_drives(format['type'], format['args'], attach_target)
++    def do_test_compress_pause(self, cmd, attach_target, **args):
++        self.do_prepare_drives(attach_target)
+ 
+         self.assert_no_active_block_jobs()
+ 
+@@ -550,18 +549,23 @@ class TestDriveCompression(iotests.QMPTestCase):
+ 
+         self.vm.shutdown()
+         self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
+-                                               iotests.imgfmt, format['type']),
++                                               iotests.imgfmt,
++                                               self.target_fmt['type']),
+                         'target image does not match source after backup')
+ 
+     def test_compress_pause_drive_backup(self):
+-        for format in TestDriveCompression.fmt_supports_compression:
+-            self.do_test_compress_pause('drive-backup', format, False,
+-                                        target=blockdev_target_img, mode='existing')
++        self.do_test_compress_pause('drive-backup', False,
++                                    target=blockdev_target_img,
++                                    mode='existing')
+ 
+     def test_compress_pause_blockdev_backup(self):
+-        for format in TestDriveCompression.fmt_supports_compression:
+-            self.do_test_compress_pause('blockdev-backup', format, True,
+-                                        target='drive1')
++        self.do_test_compress_pause('blockdev-backup', True,
++                                    target='drive1')
++
++
++class TestCompressedToVmdk(TestCompressedToQcow2):
++    target_fmt = {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized')}
++
+ 
+ if __name__ == '__main__':
+     iotests.main(supported_fmts=['raw', 'qcow2'],
+diff --git a/tests/qemu-iotests/055.out b/tests/qemu-iotests/055.out
+index 5ce2f9a..5c26d15 100644
+--- a/tests/qemu-iotests/055.out
++++ b/tests/qemu-iotests/055.out
+@@ -1,5 +1,5 @@
+-..............................
++....................................
+ ----------------------------------------------------------------------
+-Ran 30 tests
++Ran 36 tests
+ 
+ OK
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-055-skip-vmdk-target-tests-if-vmdk-is-not-wh.patch b/SOURCES/kvm-iotests-055-skip-vmdk-target-tests-if-vmdk-is-not-wh.patch
new file mode 100644
index 0000000..260d511
--- /dev/null
+++ b/SOURCES/kvm-iotests-055-skip-vmdk-target-tests-if-vmdk-is-not-wh.patch
@@ -0,0 +1,45 @@
+From 9a0ca4797cbd029dab9209d88f8c81b78ded8fd0 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:18 +0100
+Subject: [PATCH 19/26] iotests/055: skip vmdk target tests if vmdk is not
+ whitelisted
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-5-kwolf@redhat.com>
+Patchwork-id: 97101
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 04/11] iotests/055: skip vmdk target tests if vmdk is not whitelisted
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+
+Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200430124713.3067-7-vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 761cd2e791eae38c3d08ea5f83309ce58bb85ff7)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/055 | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
+index 8666601..c9cdc06 100755
+--- a/tests/qemu-iotests/055
++++ b/tests/qemu-iotests/055
+@@ -566,6 +566,10 @@ class TestCompressedToQcow2(iotests.QMPTestCase):
+ class TestCompressedToVmdk(TestCompressedToQcow2):
+     target_fmt = {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized')}
+ 
++    @iotests.skip_if_unsupported(['vmdk'])
++    def setUp(self):
++        pass
++
+ 
+ if __name__ == '__main__':
+     iotests.main(supported_fmts=['raw', 'qcow2'],
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-109-Don-t-mirror-with-mismatched-size.patch b/SOURCES/kvm-iotests-109-Don-t-mirror-with-mismatched-size.patch
new file mode 100644
index 0000000..c71bcba
--- /dev/null
+++ b/SOURCES/kvm-iotests-109-Don-t-mirror-with-mismatched-size.patch
@@ -0,0 +1,387 @@
+From 2202321b549dda551190d919a5a1cbee0fab8c90 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:22 +0100
+Subject: [PATCH 23/26] iotests/109: Don't mirror with mismatched size
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-9-kwolf@redhat.com>
+Patchwork-id: 97105
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 08/11] iotests/109: Don't mirror with mismatched size
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+This patch makes the raw image the same size as the file in a different
+format that is mirrored as raw to it to avoid errors when mirror starts
+to enforce that source and target are the same size.
+
+We check only that the first 512 bytes are zeroed (instead of 64k)
+because some image formats create image files that are smaller than 64k,
+so trying to read 64k would result in I/O errors. Apart from this, 512
+is more appropriate anyway because the raw format driver protects
+specifically the first 512 bytes.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200511135825.219437-2-kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit ffa41a62d0b0e6d91f2071328befa046d56993e1)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/109           | 10 +++---
+ tests/qemu-iotests/109.out       | 74 +++++++++++++++++-----------------------
+ tests/qemu-iotests/common.filter |  5 +++
+ 3 files changed, 41 insertions(+), 48 deletions(-)
+
+diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
+index 9897ceb..190c35e 100755
+--- a/tests/qemu-iotests/109
++++ b/tests/qemu-iotests/109
+@@ -76,14 +76,14 @@ for fmt in qcow qcow2 qed vdi vmdk vpc; do
+     echo "=== Writing a $fmt header into raw ==="
+     echo
+ 
+-    _make_test_img 64M
+     TEST_IMG="$TEST_IMG.src" IMGFMT=$fmt _make_test_img 64M
++    _make_test_img $(du -b "$TEST_IMG.src" | cut -f1) | _filter_img_create_size
+ 
+     # This first test should fail: The image format was probed, we may not
+     # write an image header at the start of the image
+     run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" |
+         _filter_block_job_len
+-    $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
++    $QEMU_IO -c 'read -P 0 0 512' "$TEST_IMG" | _filter_qemu_io
+ 
+ 
+     # When raw was explicitly specified, the same must succeed
+@@ -102,12 +102,12 @@ for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
+ 
+     # Can't use _use_sample_img because that isn't designed to be used multiple
+     # times and it overwrites $TEST_IMG (both breaks cleanup)
+-    _make_test_img 64M
+     bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
++    _make_test_img $(du -b "$TEST_IMG.src" | cut -f1) | _filter_img_create_size
+ 
+     run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" |
+         _filter_block_job_offset | _filter_block_job_len
+-    $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
++    $QEMU_IO -c 'read -P 0 0 512' "$TEST_IMG" | _filter_qemu_io
+ 
+     run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
+     $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
+@@ -118,8 +118,8 @@ echo "=== Write legitimate MBR into raw ==="
+ echo
+ 
+ for sample_img in grub_mbr.raw; do
+-    _make_test_img 64M
+     bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
++    _make_test_img $(du -b "$TEST_IMG.src" | cut -f1) | _filter_img_create_size
+ 
+     run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_READY"
+     $QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
+diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
+index 884f65f..ad739df 100644
+--- a/tests/qemu-iotests/109.out
++++ b/tests/qemu-iotests/109.out
+@@ -2,8 +2,8 @@ QA output created by 109
+ 
+ === Writing a qcow header into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -23,8 +23,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -43,13 +43,12 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Writing a qcow2 header into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -69,8 +68,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -89,13 +88,12 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Writing a qed header into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -115,8 +113,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -135,13 +133,12 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Writing a vdi header into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -161,8 +158,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -181,13 +178,12 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Writing a vmdk header into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -207,8 +203,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -227,13 +223,12 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Writing a vpc header into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+ Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -253,8 +248,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -273,12 +268,11 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Copying sample image empty.bochs into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -298,8 +292,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -318,12 +312,11 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Copying sample image iotest-dirtylog-10G-4M.vhdx into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -343,8 +336,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -363,12 +356,11 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Copying sample image parallels-v1 into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -388,8 +380,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -408,12 +400,11 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Copying sample image simple-pattern.cloop into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -433,8 +424,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"execute":"quit"}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-read 65536/65536 bytes at offset 0
+-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++read 512/512 bytes at offset 0
++512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -453,12 +444,11 @@ read 65536/65536 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ 
+ === Write legitimate MBR into raw ===
+ 
+-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
++Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+ {'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
+@@ -480,7 +470,6 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ { 'execute': 'qmp_capabilities' }
+ {"return": {}}
+@@ -500,6 +489,5 @@ Images are identical.
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
+-Warning: Image size mismatch!
+ Images are identical.
+ *** done
+diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
+index 5367dee..c8e8663 100644
+--- a/tests/qemu-iotests/common.filter
++++ b/tests/qemu-iotests/common.filter
+@@ -149,6 +149,11 @@ _filter_img_create()
+         -e "s# force_size=\\(on\\|off\\)##g"
+ }
+ 
++_filter_img_create_size()
++{
++    $SED -e "s# size=[0-9]\\+# size=SIZE#g"
++}
++
+ _filter_img_info()
+ {
+     if [[ "$1" == "--format-specific" ]]; then
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-229-Use-blkdebug-to-inject-an-error.patch b/SOURCES/kvm-iotests-229-Use-blkdebug-to-inject-an-error.patch
new file mode 100644
index 0000000..ef8807c
--- /dev/null
+++ b/SOURCES/kvm-iotests-229-Use-blkdebug-to-inject-an-error.patch
@@ -0,0 +1,120 @@
+From 104c8f6210bf573cf39c2a14cdb0b081baaaa3f0 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:23 +0100
+Subject: [PATCH 24/26] iotests/229: Use blkdebug to inject an error
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-10-kwolf@redhat.com>
+Patchwork-id: 97108
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 09/11] iotests/229: Use blkdebug to inject an error
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+229 relies on the mirror running into an I/O error when the target is
+smaller than the source. After changing mirror to catch this condition
+while starting the job, this test case won't get a job that is paused
+for an I/O error any more. Use blkdebug instead to inject an error.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200511135825.219437-3-kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit d89ac3cf305b28c024a76805a84d75c0ee1e786f)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/229     | 18 +++++++++++++-----
+ tests/qemu-iotests/229.out |  6 +++---
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
+index e18a464..511fbc0 100755
+--- a/tests/qemu-iotests/229
++++ b/tests/qemu-iotests/229
+@@ -32,6 +32,7 @@ _cleanup()
+     _cleanup_qemu
+     _cleanup_test_img
+     rm -f "$TEST_IMG" "$DEST_IMG"
++    rm -f "$TEST_DIR/blkdebug.conf"
+ }
+ trap "_cleanup; exit \$status" 0 1 2 3 15
+ 
+@@ -48,11 +49,10 @@ _supported_os Linux
+ 
+ DEST_IMG="$TEST_DIR/d.$IMGFMT"
+ TEST_IMG="$TEST_DIR/b.$IMGFMT"
++BLKDEBUG_CONF="$TEST_DIR/blkdebug.conf"
+ 
+ _make_test_img 2M
+-
+-# destination for mirror will be too small, causing error
+-TEST_IMG=$DEST_IMG _make_test_img 1M
++TEST_IMG=$DEST_IMG _make_test_img 2M
+ 
+ $QEMU_IO -c 'write 0 2M' "$TEST_IMG" | _filter_qemu_io
+ 
+@@ -66,11 +66,18 @@ echo
+ echo '=== Starting drive-mirror, causing error & stop  ==='
+ echo
+ 
++cat > "$BLKDEBUG_CONF" <<EOF
++[inject-error]
++event = "write_aio"
++errno = "5"
++once = "on"
++EOF
++
+ _send_qemu_cmd $QEMU_HANDLE \
+     "{'execute': 'drive-mirror',
+                  'arguments': {'device': 'testdisk',
+                                'format': '$IMGFMT',
+-                               'target': '$DEST_IMG',
++                               'target': 'blkdebug:$BLKDEBUG_CONF:$DEST_IMG',
+                                'sync':   'full',
+                                'mode':   'existing',
+                                'on-source-error': 'stop',
+@@ -89,7 +96,8 @@ success_or_failure="y" _send_qemu_cmd $QEMU_HANDLE \
+                  'arguments': { 'device': 'testdisk',
+                                 'force': true}}" \
+      "BLOCK_JOB_CANCELLED" "Assertion" \
+-    | grep -v '"BLOCK_JOB_ERROR"'
++    | grep -v '"BLOCK_JOB_ERROR"' \
++    | _filter_block_job_offset
+ 
+ # success, all done
+ echo "*** done"
+diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
+index 22350d7..4de6dfa 100644
+--- a/tests/qemu-iotests/229.out
++++ b/tests/qemu-iotests/229.out
+@@ -1,6 +1,6 @@
+ QA output created by 229
+ Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=2097152
+-Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=1048576
++Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=2097152
+ wrote 2097152/2097152 bytes at offset 0
+ 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ {'execute': 'qmp_capabilities'}
+@@ -8,7 +8,7 @@ wrote 2097152/2097152 bytes at offset 0
+ 
+ === Starting drive-mirror, causing error & stop  ===
+ 
+-{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'TEST_DIR/d.IMGFMT', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
++{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/d.IMGFMT', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
+ {"return": {}}
+@@ -21,5 +21,5 @@ wrote 2097152/2097152 bytes at offset 0
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
+-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": 1048576, "speed": 0, "type": "mirror"}}
++{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0, "type": "mirror"}}
+ *** done
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Add-more-skip_if_unsupported-statements-to-t.patch b/SOURCES/kvm-iotests-Add-more-skip_if_unsupported-statements-to-t.patch
new file mode 100644
index 0000000..6bdf130
--- /dev/null
+++ b/SOURCES/kvm-iotests-Add-more-skip_if_unsupported-statements-to-t.patch
@@ -0,0 +1,236 @@
+From adda561394bb07c13ef3f2712b36704790530891 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:15 +0100
+Subject: [PATCH 16/26] iotests: Add more "skip_if_unsupported" statements to
+ the python tests
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-2-kwolf@redhat.com>
+Patchwork-id: 97099
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 01/11] iotests: Add more "skip_if_unsupported" statements to the python tests
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+From: Thomas Huth <thuth@redhat.com>
+
+The python code already contains a possibility to skip tests if the
+corresponding driver is not available in the qemu binary - use it
+in more spots to avoid that the tests are failing if the driver has
+been disabled.
+
+While we're at it, we can now also remove some of the old checks that
+were using iotests.supports_quorum() - and which were apparently not
+working as expected since the tests aborted instead of being skipped
+when "quorum" was missing in the QEMU binary.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 9442bebe6e67a5d038bbf2572b79e7b59d202a23)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/030 |  4 +---
+ tests/qemu-iotests/040 |  2 ++
+ tests/qemu-iotests/041 | 39 +++------------------------------------
+ tests/qemu-iotests/245 |  2 ++
+ 4 files changed, 8 insertions(+), 39 deletions(-)
+
+diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
+index f3766f2..bddbb30 100755
+--- a/tests/qemu-iotests/030
++++ b/tests/qemu-iotests/030
+@@ -530,6 +530,7 @@ class TestQuorum(iotests.QMPTestCase):
+     children = []
+     backing = []
+ 
++    @iotests.skip_if_unsupported(['quorum'])
+     def setUp(self):
+         opts = ['driver=quorum', 'vote-threshold=2']
+ 
+@@ -560,9 +561,6 @@ class TestQuorum(iotests.QMPTestCase):
+             os.remove(img)
+ 
+     def test_stream_quorum(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', self.children[0]),
+                             qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', self.backing[0]),
+                             'image file map matches backing file before streaming')
+diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
+index 762ad1e..74f62c3 100755
+--- a/tests/qemu-iotests/040
++++ b/tests/qemu-iotests/040
+@@ -106,6 +106,7 @@ class TestSingleDrive(ImageCommitTestCase):
+         self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
+         self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+ 
++    @iotests.skip_if_unsupported(['throttle'])
+     def test_commit_with_filter_and_quit(self):
+         result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg')
+         self.assert_qmp(result, 'return', {})
+@@ -125,6 +126,7 @@ class TestSingleDrive(ImageCommitTestCase):
+         self.has_quit = True
+ 
+     # Same as above, but this time we add the filter after starting the job
++    @iotests.skip_if_unsupported(['throttle'])
+     def test_commit_plus_filter_and_quit(self):
+         result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg')
+         self.assert_qmp(result, 'return', {})
+diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
+index 8568426..a543b15 100755
+--- a/tests/qemu-iotests/041
++++ b/tests/qemu-iotests/041
+@@ -871,6 +871,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
+     image_len = 1 * 1024 * 1024 # MB
+     IMAGES = [ quorum_img1, quorum_img2, quorum_img3 ]
+ 
++    @iotests.skip_if_unsupported(['quorum'])
+     def setUp(self):
+         self.vm = iotests.VM()
+ 
+@@ -891,9 +892,8 @@ class TestRepairQuorum(iotests.QMPTestCase):
+         #assemble the quorum block device from the individual files
+         args = { "driver": "quorum", "node-name": "quorum0",
+                  "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] }
+-        if iotests.supports_quorum():
+-            result = self.vm.qmp("blockdev-add", **args)
+-            self.assert_qmp(result, 'return', {})
++        result = self.vm.qmp("blockdev-add", **args)
++        self.assert_qmp(result, 'return', {})
+ 
+ 
+     def tearDown(self):
+@@ -906,9 +906,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+                 pass
+ 
+     def test_complete(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         self.assert_no_active_block_jobs()
+ 
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+@@ -925,9 +922,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+                         'target image does not match source after mirroring')
+ 
+     def test_cancel(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         self.assert_no_active_block_jobs()
+ 
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+@@ -942,9 +936,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+         self.vm.shutdown()
+ 
+     def test_cancel_after_ready(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         self.assert_no_active_block_jobs()
+ 
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+@@ -961,9 +952,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+                         'target image does not match source after mirroring')
+ 
+     def test_pause(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         self.assert_no_active_block_jobs()
+ 
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+@@ -989,9 +977,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+                         'target image does not match source after mirroring')
+ 
+     def test_medium_not_found(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         if iotests.qemu_default_machine != 'pc':
+             return
+ 
+@@ -1003,9 +988,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
+     def test_image_not_found(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+                              sync='full', node_name='repair0', replaces='img1',
+                              mode='existing', target=quorum_repair_img,
+@@ -1013,9 +995,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
+     def test_device_not_found(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         result = self.vm.qmp('drive-mirror', job_id='job0',
+                              device='nonexistent', sync='full',
+                              node_name='repair0',
+@@ -1024,9 +1003,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
+     def test_wrong_sync_mode(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         result = self.vm.qmp('drive-mirror', device='quorum0', job_id='job0',
+                              node_name='repair0',
+                              replaces='img1',
+@@ -1034,27 +1010,18 @@ class TestRepairQuorum(iotests.QMPTestCase):
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
+     def test_no_node_name(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+                              sync='full', replaces='img1',
+                              target=quorum_repair_img, format=iotests.imgfmt)
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
+     def test_nonexistent_replaces(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
+                              sync='full', node_name='repair0', replaces='img77',
+                              target=quorum_repair_img, format=iotests.imgfmt)
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
+     def test_after_a_quorum_snapshot(self):
+-        if not iotests.supports_quorum():
+-            return
+-
+         result = self.vm.qmp('blockdev-snapshot-sync', node_name='img1',
+                              snapshot_file=quorum_snapshot_file,
+                              snapshot_node_name="snap1");
+diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
+index 919131d..ed972f9 100644
+--- a/tests/qemu-iotests/245
++++ b/tests/qemu-iotests/245
+@@ -478,6 +478,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
+     # This test verifies that we can't change the children of a block
+     # device during a reopen operation in a way that would create
+     # cycles in the node graph
++    @iotests.skip_if_unsupported(['blkverify'])
+     def test_graph_cycles(self):
+         opts = []
+ 
+@@ -534,6 +535,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
+         self.assert_qmp(result, 'return', {})
+ 
+     # Misc reopen tests with different block drivers
++    @iotests.skip_if_unsupported(['quorum', 'throttle'])
+     def test_misc_drivers(self):
+         ####################
+         ###### quorum ######
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Add-qemu_io_log.patch b/SOURCES/kvm-iotests-Add-qemu_io_log.patch
new file mode 100644
index 0000000..a65bc5a
--- /dev/null
+++ b/SOURCES/kvm-iotests-Add-qemu_io_log.patch
@@ -0,0 +1,48 @@
+From 2be333e847c01397bb6a92b2e4c60e904957675d Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:37 +0100
+Subject: [PATCH 09/17] iotests: Add qemu_io_log()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-9-kwolf@redhat.com>
+Patchwork-id: 97451
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 08/11] iotests: Add qemu_io_log()
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+Add a function that runs qemu-io and logs the output with the
+appropriate filters applied.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Reviewed-by: Alberto Garcia <berto@igalia.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit a96f0350e3d95c98f2bff1863d14493af5c1d360)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/iotests.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
+index be20d56..7a9c779 100644
+--- a/tests/qemu-iotests/iotests.py
++++ b/tests/qemu-iotests/iotests.py
+@@ -162,6 +162,11 @@ def qemu_io(*args):
+         sys.stderr.write('qemu-io received signal %i: %s\n' % (-exitcode, ' '.join(args)))
+     return subp.communicate()[0]
+ 
++def qemu_io_log(*args):
++    result = qemu_io(*args)
++    log(result, filters=[filter_testfiles, filter_qemu_io])
++    return result
++
+ def qemu_io_silent(*args):
+     '''Run qemu-io and return the exit code, suppressing stdout'''
+     args = qemu_io_args + list(args)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Add-test-291-to-for-qemu-img-bitmap-coverage.patch b/SOURCES/kvm-iotests-Add-test-291-to-for-qemu-img-bitmap-coverage.patch
new file mode 100644
index 0000000..6144043
--- /dev/null
+++ b/SOURCES/kvm-iotests-Add-test-291-to-for-qemu-img-bitmap-coverage.patch
@@ -0,0 +1,253 @@
+From eccae2f252513d2965ef919022c3ed068da275bd Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:20 +0100
+Subject: [PATCH 15/26] iotests: Add test 291 to for qemu-img bitmap coverage
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-13-eblake@redhat.com>
+Patchwork-id: 97079
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 12/12] iotests: Add test 291 to for qemu-img bitmap coverage
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Add a new test covering the 'qemu-img bitmap' subcommand, as well as
+'qemu-img convert --bitmaps', both added in recent patches.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200521192137.1120211-6-eblake@redhat.com>
+(cherry picked from commit cf2d1203dcfc2bf964453d83a2302231ce77f2dc)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	tests/qemu-iotests/group - context: other tests not backported
+	tests/qemu-iotests/291.out - zstd compression not backported
+Signed-off-by: Eric Blake <eblake@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/291     | 112 +++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/291.out |  78 +++++++++++++++++++++++++++++++
+ tests/qemu-iotests/group   |   1 +
+ 3 files changed, 191 insertions(+)
+ create mode 100755 tests/qemu-iotests/291
+ create mode 100644 tests/qemu-iotests/291.out
+
+diff --git a/tests/qemu-iotests/291 b/tests/qemu-iotests/291
+new file mode 100755
+index 0000000..3ca83b9
+--- /dev/null
++++ b/tests/qemu-iotests/291
+@@ -0,0 +1,112 @@
++#!/usr/bin/env bash
++#
++# Test qemu-img bitmap handling
++#
++# Copyright (C) 2018-2020 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++
++seq="$(basename $0)"
++echo "QA output created by $seq"
++
++status=1 # failure is the default!
++
++_cleanup()
++{
++    _cleanup_test_img
++    nbd_server_stop
++}
++trap "_cleanup; exit \$status" 0 1 2 3 15
++
++# get standard environment, filters and checks
++. ./common.rc
++. ./common.filter
++. ./common.nbd
++
++_supported_fmt qcow2
++_supported_proto file
++_supported_os Linux
++_require_command QEMU_NBD
++
++echo
++echo "=== Initial image setup ==="
++echo
++
++# Create backing image with one bitmap
++TEST_IMG="$TEST_IMG.base" _make_test_img 10M
++$QEMU_IMG bitmap --add -f $IMGFMT "$TEST_IMG.base" b0
++$QEMU_IO -c 'w 3M 1M' -f $IMGFMT "$TEST_IMG.base" | _filter_qemu_io
++
++# Create initial image and populate two bitmaps: one active, one inactive.
++ORIG_IMG=$TEST_IMG
++TEST_IMG=$TEST_IMG.orig
++_make_test_img -b "$ORIG_IMG.base" -F $IMGFMT 10M
++$QEMU_IO -c 'w 0 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
++$QEMU_IMG bitmap --add -g 512k -f $IMGFMT "$TEST_IMG" b1
++$QEMU_IMG bitmap --add --disable -f $IMGFMT "$TEST_IMG" b2
++$QEMU_IO -c 'w 3M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
++$QEMU_IMG bitmap --clear -f $IMGFMT "$TEST_IMG" b1
++$QEMU_IO -c 'w 1M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
++$QEMU_IMG bitmap --disable -f $IMGFMT "$TEST_IMG" b1
++$QEMU_IMG bitmap --enable -f $IMGFMT "$TEST_IMG" b2
++$QEMU_IO -c 'w 2M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
++
++echo
++echo "=== Bitmap preservation not possible to non-qcow2 ==="
++echo
++
++TEST_IMG=$ORIG_IMG
++$QEMU_IMG convert --bitmaps -O raw "$TEST_IMG.orig" "$TEST_IMG" &&
++    echo "unexpected success"
++
++echo
++echo "=== Convert with bitmap preservation ==="
++echo
++
++# Only bitmaps from the active layer are copied
++$QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG.orig" "$TEST_IMG"
++$QEMU_IMG info "$TEST_IMG" | _filter_img_info --format-specific
++# But we can also merge in bitmaps from other layers.  This test is a bit
++# contrived to cover more code paths, in reality, you could merge directly
++# into b0 without going through tmp
++$QEMU_IMG bitmap --add --disable -f $IMGFMT "$TEST_IMG" b0
++$QEMU_IMG bitmap --add --merge b0 -b "$TEST_IMG.base" -F $IMGFMT \
++     -f $IMGFMT "$TEST_IMG" tmp
++$QEMU_IMG bitmap --merge tmp -f $IMGFMT "$TEST_IMG" b0
++$QEMU_IMG bitmap --remove --image-opts \
++    driver=$IMGFMT,file.driver=file,file.filename="$TEST_IMG" tmp
++$QEMU_IMG info "$TEST_IMG" | _filter_img_info --format-specific
++
++echo
++echo "=== Check bitmap contents ==="
++echo
++
++# x-dirty-bitmap is a hack for reading bitmaps; it abuses block status to
++# report "data":false for portions of the bitmap which are set
++IMG="driver=nbd,server.type=unix,server.path=$nbd_unix_socket"
++nbd_server_start_unix_socket -r -f qcow2 -B b0 "$TEST_IMG"
++$QEMU_IMG map --output=json --image-opts \
++    "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b0" | _filter_qemu_img_map
++nbd_server_start_unix_socket -r -f qcow2 -B b1 "$TEST_IMG"
++$QEMU_IMG map --output=json --image-opts \
++    "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b1" | _filter_qemu_img_map
++nbd_server_start_unix_socket -r -f qcow2 -B b2 "$TEST_IMG"
++$QEMU_IMG map --output=json --image-opts \
++    "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b2" | _filter_qemu_img_map
++
++# success, all done
++echo '*** done'
++rm -f $seq.full
++status=0
+diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/291.out
+new file mode 100644
+index 0000000..14e5cfc
+--- /dev/null
++++ b/tests/qemu-iotests/291.out
+@@ -0,0 +1,78 @@
++QA output created by 291
++
++=== Initial image setup ===
++
++Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=10485760
++wrote 1048576/1048576 bytes at offset 3145728
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=10485760 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
++wrote 1048576/1048576 bytes at offset 0
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 1048576/1048576 bytes at offset 3145728
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 1048576/1048576 bytes at offset 1048576
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++wrote 1048576/1048576 bytes at offset 2097152
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Bitmap preservation not possible to non-qcow2 ===
++
++qemu-img: Format driver 'raw' does not support bitmaps
++
++=== Convert with bitmap preservation ===
++
++image: TEST_DIR/t.IMGFMT
++file format: IMGFMT
++virtual size: 10 MiB (10485760 bytes)
++disk size: 4.39 MiB
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    bitmaps:
++        [0]:
++            flags:
++            name: b1
++            granularity: 524288
++        [1]:
++            flags:
++                [0]: auto
++            name: b2
++            granularity: 65536
++    refcount bits: 16
++    corrupt: false
++image: TEST_DIR/t.IMGFMT
++file format: IMGFMT
++virtual size: 10 MiB (10485760 bytes)
++disk size: 4.48 MiB
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    bitmaps:
++        [0]:
++            flags:
++            name: b1
++            granularity: 524288
++        [1]:
++            flags:
++                [0]: auto
++            name: b2
++            granularity: 65536
++        [2]:
++            flags:
++            name: b0
++            granularity: 65536
++    refcount bits: 16
++    corrupt: false
++
++=== Check bitmap contents ===
++
++[{ "start": 0, "length": 3145728, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
++{ "start": 3145728, "length": 1048576, "depth": 0, "zero": false, "data": false},
++{ "start": 4194304, "length": 6291456, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
++[{ "start": 0, "length": 1048576, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
++{ "start": 1048576, "length": 1048576, "depth": 0, "zero": false, "data": false},
++{ "start": 2097152, "length": 8388608, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
++[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
++{ "start": 2097152, "length": 1048576, "depth": 0, "zero": false, "data": false},
++{ "start": 3145728, "length": 7340032, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
++*** done
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 9c565cf..033b54d 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -290,3 +290,4 @@
+ 280 rw migration quick
+ 281 rw quick
+ 284 rw
++291 rw quick
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Backup-with-different-source-target-size.patch b/SOURCES/kvm-iotests-Backup-with-different-source-target-size.patch
new file mode 100644
index 0000000..4008413
--- /dev/null
+++ b/SOURCES/kvm-iotests-Backup-with-different-source-target-size.patch
@@ -0,0 +1,105 @@
+From 456c5e79c32e3f2f9319a7d1452fe523aded7835 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:21 +0100
+Subject: [PATCH 22/26] iotests: Backup with different source/target size
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-8-kwolf@redhat.com>
+Patchwork-id: 97106
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 07/11] iotests: Backup with different source/target size
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+This tests that the backup job catches situations where the target node
+has a different size than the source node. It must also forbid resize
+operations when the job is already running.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200430142755.315494-5-kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 0a82a9273062d05764e3df3637b3aa95ad8291c6)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/055     | 42 ++++++++++++++++++++++++++++++++++++++++--
+ tests/qemu-iotests/055.out |  4 ++--
+ 2 files changed, 42 insertions(+), 4 deletions(-)
+
+diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
+index c9cdc06..1c70389 100755
+--- a/tests/qemu-iotests/055
++++ b/tests/qemu-iotests/055
+@@ -48,8 +48,10 @@ class TestSingleDrive(iotests.QMPTestCase):
+     def setUp(self):
+         qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))
+ 
+-        self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
+-        self.vm.add_drive(blockdev_target_img, interface="none")
++        self.vm = iotests.VM()
++        self.vm.add_drive('blkdebug::' + test_img, 'node-name=source')
++        self.vm.add_drive(blockdev_target_img, 'node-name=target',
++                          interface="none")
+         if iotests.qemu_default_machine == 'pc':
+             self.vm.add_drive(None, 'media=cdrom', 'ide')
+         self.vm.launch()
+@@ -112,6 +114,42 @@ class TestSingleDrive(iotests.QMPTestCase):
+     def test_pause_blockdev_backup(self):
+         self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
+ 
++    def do_test_resize_blockdev_backup(self, device, node):
++        def pre_finalize():
++            result = self.vm.qmp('block_resize', device=device, size=65536)
++            self.assert_qmp(result, 'error/class', 'GenericError')
++
++            result = self.vm.qmp('block_resize', node_name=node, size=65536)
++            self.assert_qmp(result, 'error/class', 'GenericError')
++
++        result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0',
++                             target='drive1', sync='full', auto_finalize=False,
++                             auto_dismiss=False)
++        self.assert_qmp(result, 'return', {})
++
++        self.vm.run_job('job0', auto_finalize=False, pre_finalize=pre_finalize,
++                        use_log=False)
++
++    def test_source_resize_blockdev_backup(self):
++        self.do_test_resize_blockdev_backup('drive0', 'source')
++
++    def test_target_resize_blockdev_backup(self):
++        self.do_test_resize_blockdev_backup('drive1', 'target')
++
++    def do_test_target_size(self, size):
++        result = self.vm.qmp('block_resize', device='drive1', size=size)
++        self.assert_qmp(result, 'return', {})
++
++        result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0',
++                             target='drive1', sync='full')
++        self.assert_qmp(result, 'error/class', 'GenericError')
++
++    def test_small_target(self):
++        self.do_test_target_size(image_len // 2)
++
++    def test_large_target(self):
++        self.do_test_target_size(image_len * 2)
++
+     def test_medium_not_found(self):
+         if iotests.qemu_default_machine != 'pc':
+             return
+diff --git a/tests/qemu-iotests/055.out b/tests/qemu-iotests/055.out
+index 5c26d15..0a5e958 100644
+--- a/tests/qemu-iotests/055.out
++++ b/tests/qemu-iotests/055.out
+@@ -1,5 +1,5 @@
+-....................................
++........................................
+ ----------------------------------------------------------------------
+-Ran 36 tests
++Ran 40 tests
+ 
+ OK
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Filter-testfiles-out-in-filter_img_info.patch b/SOURCES/kvm-iotests-Filter-testfiles-out-in-filter_img_info.patch
new file mode 100644
index 0000000..60c08ec
--- /dev/null
+++ b/SOURCES/kvm-iotests-Filter-testfiles-out-in-filter_img_info.patch
@@ -0,0 +1,52 @@
+From 8dc8a17d4e98aae41db01cbc073e69de44291b63 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:38 +0100
+Subject: [PATCH 10/17] iotests: Filter testfiles out in filter_img_info()
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-10-kwolf@redhat.com>
+Patchwork-id: 97455
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 09/11] iotests: Filter testfiles out in filter_img_info()
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+We want to keep TEST_IMG for the full path of the main test image, but
+filter_testfiles() must be called for other test images before replacing
+other things like the image format because the test directory path could
+contain the format as a substring.
+
+Insert a filter_testfiles() call between both.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit fd586ce8bee50d98773436214dc9e644ddda54aa)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/iotests.py | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
+index 7a9c779..cd5df36 100644
+--- a/tests/qemu-iotests/iotests.py
++++ b/tests/qemu-iotests/iotests.py
+@@ -335,8 +335,9 @@ def filter_img_info(output, filename):
+     for line in output.split('\n'):
+         if 'disk size' in line or 'actual-size' in line:
+             continue
+-        line = line.replace(filename, 'TEST_IMG') \
+-                   .replace(imgfmt, 'IMGFMT')
++        line = line.replace(filename, 'TEST_IMG')
++        line = filter_testfiles(line)
++        line = line.replace(imgfmt, 'IMGFMT')
+         line = re.sub('iters: [0-9]+', 'iters: XXX', line)
+         line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
+         line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Fix-test-178.patch b/SOURCES/kvm-iotests-Fix-test-178.patch
new file mode 100644
index 0000000..5e54daa
--- /dev/null
+++ b/SOURCES/kvm-iotests-Fix-test-178.patch
@@ -0,0 +1,59 @@
+From a04d324e41a40a6893bc94109994afc017f17192 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:16 +0100
+Subject: [PATCH 11/26] iotests: Fix test 178
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-9-eblake@redhat.com>
+Patchwork-id: 97075
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 08/12] iotests: Fix test 178
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+A recent change to qemu-img changed expected error message output, but
+178 takes long enough to execute that it does not get run by 'make
+check' or './check -g quick'.
+
+Fixes: 43d589b074
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200521192137.1120211-2-eblake@redhat.com>
+(cherry picked from commit ca01b7a641527052e3e8961845b40b81706ce5f9)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/178.out.qcow2 | 2 +-
+ tests/qemu-iotests/178.out.raw   | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
+index 9e7d8c4..345eab3 100644
+--- a/tests/qemu-iotests/178.out.qcow2
++++ b/tests/qemu-iotests/178.out.qcow2
+@@ -13,7 +13,7 @@ qemu-img: Invalid option list: ,
+ qemu-img: Invalid parameter 'snapshot.foo'
+ qemu-img: Failed in parsing snapshot param 'snapshot.foo'
+ qemu-img: --output must be used with human or json as argument.
+-qemu-img: Image size must be less than 8 EiB!
++qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
+ qemu-img: Unknown file format 'foo'
+ 
+ == Size calculation for a new file (human) ==
+diff --git a/tests/qemu-iotests/178.out.raw b/tests/qemu-iotests/178.out.raw
+index 6478365..15da915 100644
+--- a/tests/qemu-iotests/178.out.raw
++++ b/tests/qemu-iotests/178.out.raw
+@@ -13,7 +13,7 @@ qemu-img: Invalid option list: ,
+ qemu-img: Invalid parameter 'snapshot.foo'
+ qemu-img: Failed in parsing snapshot param 'snapshot.foo'
+ qemu-img: --output must be used with human or json as argument.
+-qemu-img: Image size must be less than 8 EiB!
++qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
+ qemu-img: Unknown file format 'foo'
+ 
+ == Size calculation for a new file (human) ==
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Let-_make_test_img-parse-its-parameters.patch b/SOURCES/kvm-iotests-Let-_make_test_img-parse-its-parameters.patch
new file mode 100644
index 0000000..d24f5e7
--- /dev/null
+++ b/SOURCES/kvm-iotests-Let-_make_test_img-parse-its-parameters.patch
@@ -0,0 +1,91 @@
+From 3c96dbd74fb67e2ae1a116b2771290b192041707 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:10 +0100
+Subject: [PATCH 05/26] iotests: Let _make_test_img parse its parameters
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-3-eblake@redhat.com>
+Patchwork-id: 97070
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 02/12] iotests: Let _make_test_img parse its parameters
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+From: Max Reitz <mreitz@redhat.com>
+
+This will allow us to add more options than just -b.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Message-id: 20191107163708.833192-9-mreitz@redhat.com
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit eea871d047701b563cfd66c1566b9ff6d163882b)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/common.rc | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
+index 0cc8acc..99fef4d 100644
+--- a/tests/qemu-iotests/common.rc
++++ b/tests/qemu-iotests/common.rc
+@@ -302,12 +302,12 @@ _make_test_img()
+     # extra qemu-img options can be added by tests
+     # at least one argument (the image size) needs to be added
+     local extra_img_options=""
+-    local image_size=$*
+     local optstr=""
+     local img_name=""
+     local use_backing=0
+     local backing_file=""
+     local object_options=""
++    local misc_params=()
+ 
+     if [ -n "$TEST_IMG_FILE" ]; then
+         img_name=$TEST_IMG_FILE
+@@ -323,11 +323,23 @@ _make_test_img()
+         optstr=$(_optstr_add "$optstr" "key-secret=keysec0")
+     fi
+ 
+-    if [ "$1" = "-b" ]; then
+-        use_backing=1
+-        backing_file=$2
+-        image_size=$3
+-    fi
++    for param; do
++        if [ "$use_backing" = "1" -a -z "$backing_file" ]; then
++            backing_file=$param
++            continue
++        fi
++
++        case "$param" in
++            -b)
++                use_backing=1
++                ;;
++
++            *)
++                misc_params=("${misc_params[@]}" "$param")
++                ;;
++        esac
++    done
++
+     if [ \( "$IMGFMT" = "qcow2" -o "$IMGFMT" = "qed" \) -a -n "$CLUSTER_SIZE" ]; then
+         optstr=$(_optstr_add "$optstr" "cluster_size=$CLUSTER_SIZE")
+     fi
+@@ -343,9 +355,9 @@ _make_test_img()
+     # XXX(hch): have global image options?
+     (
+      if [ $use_backing = 1 ]; then
+-        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1
++        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" "${misc_params[@]}" 2>&1
+      else
+-        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1
++        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" "${misc_params[@]}" 2>&1
+      fi
+     ) | _filter_img_create
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Mirror-with-different-source-target-size.patch b/SOURCES/kvm-iotests-Mirror-with-different-source-target-size.patch
new file mode 100644
index 0000000..7757632
--- /dev/null
+++ b/SOURCES/kvm-iotests-Mirror-with-different-source-target-size.patch
@@ -0,0 +1,110 @@
+From aff543186ff316d66b2c7acb434c6c17bdb8da78 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:25 +0100
+Subject: [PATCH 26/26] iotests: Mirror with different source/target size
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-12-kwolf@redhat.com>
+Patchwork-id: 97109
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 11/11] iotests: Mirror with different source/target size
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+This tests that the mirror job catches situations where the target node
+has a different size than the source node. It must also forbid resize
+operations when the job is already running.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200511135825.219437-5-kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 16cea4ee1c8e5a69a058e76f426b2e17974d8d7d)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/041     | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/041.out |  4 ++--
+ 2 files changed, 47 insertions(+), 2 deletions(-)
+
+diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
+index a543b15..20fb68a 100755
+--- a/tests/qemu-iotests/041
++++ b/tests/qemu-iotests/041
+@@ -240,6 +240,49 @@ class TestSingleBlockdev(TestSingleDrive):
+                              target=self.qmp_target)
+         self.assert_qmp(result, 'error/class', 'GenericError')
+ 
++    def do_test_resize(self, device, node):
++        def pre_finalize():
++            if device:
++                result = self.vm.qmp('block_resize', device=device, size=65536)
++                self.assert_qmp(result, 'error/class', 'GenericError')
++
++            result = self.vm.qmp('block_resize', node_name=node, size=65536)
++            self.assert_qmp(result, 'error/class', 'GenericError')
++
++        result = self.vm.qmp(self.qmp_cmd, job_id='job0', device='drive0',
++                             sync='full', target=self.qmp_target,
++                             auto_finalize=False, auto_dismiss=False)
++        self.assert_qmp(result, 'return', {})
++
++        result = self.vm.run_job('job0', auto_finalize=False,
++                                 pre_finalize=pre_finalize, use_log=False)
++        self.assertEqual(result, None)
++
++    def test_source_resize(self):
++        self.do_test_resize('drive0', 'top')
++
++    def test_target_resize(self):
++        self.do_test_resize(None, self.qmp_target)
++
++    def do_test_target_size(self, size):
++        result = self.vm.qmp('block_resize', node_name=self.qmp_target,
++                             size=size)
++        self.assert_qmp(result, 'return', {})
++
++        result = self.vm.qmp(self.qmp_cmd, job_id='job0',
++                             device='drive0', sync='full', auto_dismiss=False,
++                             target=self.qmp_target)
++        self.assert_qmp(result, 'return', {})
++
++        result = self.vm.run_job('job0', use_log=False)
++        self.assertEqual(result, 'Source and target image have different sizes')
++
++    def test_small_target(self):
++        self.do_test_target_size(self.image_len // 2)
++
++    def test_large_target(self):
++        self.do_test_target_size(self.image_len * 2)
++
+     test_large_cluster = None
+     test_image_not_found = None
+     test_small_buffer2 = None
+@@ -251,6 +294,8 @@ class TestSingleDriveZeroLength(TestSingleDrive):
+ 
+ class TestSingleBlockdevZeroLength(TestSingleBlockdev):
+     image_len = 0
++    test_small_target = None
++    test_large_target = None
+ 
+ class TestSingleDriveUnalignedLength(TestSingleDrive):
+     image_len = 1025 * 1024
+diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
+index 2c448b4..3ea6aa4 100644
+--- a/tests/qemu-iotests/041.out
++++ b/tests/qemu-iotests/041.out
+@@ -1,5 +1,5 @@
+-..........................................................................................
++....................................................................................................
+ ----------------------------------------------------------------------
+-Ran 90 tests
++Ran 100 tests
+ 
+ OK
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-Test-committing-to-short-backing-file.patch b/SOURCES/kvm-iotests-Test-committing-to-short-backing-file.patch
new file mode 100644
index 0000000..fbbaac6
--- /dev/null
+++ b/SOURCES/kvm-iotests-Test-committing-to-short-backing-file.patch
@@ -0,0 +1,480 @@
+From e2a1b3fd32be8bb730656a6f22eb4f543b120c9d Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:39 +0100
+Subject: [PATCH 11/17] iotests: Test committing to short backing file
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-11-kwolf@redhat.com>
+Patchwork-id: 97453
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 10/11] iotests: Test committing to short backing file
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit bf03dede475e29a16f9188ea85a4d77cd3dcf2b7)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/274     | 155 ++++++++++++++++++++++++++
+ tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++++++++++
+ tests/qemu-iotests/group   |   1 +
+ 3 files changed, 424 insertions(+)
+ create mode 100755 tests/qemu-iotests/274
+ create mode 100644 tests/qemu-iotests/274.out
+
+diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
+new file mode 100755
+index 0000000..e951f72
+--- /dev/null
++++ b/tests/qemu-iotests/274
+@@ -0,0 +1,155 @@
++#!/usr/bin/env python3
++#
++# Copyright (C) 2019 Red Hat, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
++#
++# Some tests for short backing files and short overlays
++
++import iotests
++
++iotests.verify_image_format(supported_fmts=['qcow2'])
++iotests.verify_platform(['linux'])
++
++size_short = 1 * 1024 * 1024
++size_long = 2 * 1024 * 1024
++size_diff = size_long - size_short
++
++def create_chain() -> None:
++    iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
++                         str(size_long))
++    iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
++                         str(size_short))
++    iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
++                         str(size_long))
++
++    iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
++
++def create_vm() -> iotests.VM:
++    vm = iotests.VM()
++    vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
++    vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
++    vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
++    vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
++                    % iotests.imgfmt)
++    vm.add_drive(top, 'backing=mid,node-name=top')
++    return vm
++
++with iotests.FilePath('base') as base, \
++     iotests.FilePath('mid') as mid, \
++     iotests.FilePath('top') as top:
++
++    iotests.log('== Commit tests ==')
++
++    create_chain()
++
++    iotests.log('=== Check visible data ===')
++
++    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
++    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
++
++    iotests.log('=== Checking allocation status ===')
++
++    iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
++                        '-c', 'alloc %d %d' % (size_short, size_diff),
++                        base)
++
++    iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
++                        '-c', 'alloc %d %d' % (size_short, size_diff),
++                        mid)
++
++    iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
++                        '-c', 'alloc %d %d' % (size_short, size_diff),
++                        top)
++
++    iotests.log('=== Checking map ===')
++
++    iotests.qemu_img_log('map', '--output=json', base)
++    iotests.qemu_img_log('map', '--output=human', base)
++    iotests.qemu_img_log('map', '--output=json', mid)
++    iotests.qemu_img_log('map', '--output=human', mid)
++    iotests.qemu_img_log('map', '--output=json', top)
++    iotests.qemu_img_log('map', '--output=human', top)
++
++    iotests.log('=== Testing qemu-img commit (top -> mid) ===')
++
++    iotests.qemu_img_log('commit', top)
++    iotests.img_info_log(mid)
++    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
++    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
++
++    iotests.log('=== Testing HMP commit (top -> mid) ===')
++
++    create_chain()
++    with create_vm() as vm:
++        vm.launch()
++        vm.qmp_log('human-monitor-command', command_line='commit drive0')
++
++    iotests.img_info_log(mid)
++    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
++    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
++
++    iotests.log('=== Testing QMP active commit (top -> mid) ===')
++
++    create_chain()
++    with create_vm() as vm:
++        vm.launch()
++        vm.qmp_log('block-commit', device='top', base_node='mid',
++                   job_id='job0', auto_dismiss=False)
++        vm.run_job('job0', wait=5)
++
++    iotests.img_info_log(mid)
++    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
++    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
++
++
++    iotests.log('== Resize tests ==')
++
++    # Use different sizes for different allocation modes:
++    #
++    # We want to have at least one test where 32 bit truncation in the size of
++    # the overlapping area becomes visible. This is covered by the
++    # prealloc='off' case (1G to 6G is an overlap of 5G).
++    #
++    # However, we can only do this for modes that don't preallocate data
++    # because otherwise we might run out of space on the test host.
++    #
++    # We also want to test some unaligned combinations.
++    for (prealloc, base_size, top_size_old, top_size_new, off) in [
++            ('off',       '6G',    '1G',   '8G',   '5G'),
++            ('metadata', '32G',   '30G',  '33G',  '31G'),
++            ('falloc',   '10M',    '5M',  '15M',   '9M'),
++            ('full',     '16M',    '8M',  '12M',  '11M'),
++            ('off',      '384k', '253k', '512k', '253k'),
++            ('off',      '400k', '256k', '512k', '336k'),
++            ('off',      '512k', '256k', '500k', '436k')]:
++
++        iotests.log('=== preallocation=%s ===' % prealloc)
++        iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
++        iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
++                             top_size_old)
++        iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
++
++        # After this, top_size_old to base_size should be allocated/zeroed.
++        #
++        # In theory, leaving base_size to top_size_new unallocated would be
++        # correct, but in practice, if we zero out anything, we zero out
++        # everything up to top_size_new.
++        iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
++                             '--preallocation', prealloc, top, top_size_new)
++        iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
++        iotests.qemu_io_log('-c', 'map', top)
++        iotests.qemu_img_log('map', '--output=json', top)
+diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
+new file mode 100644
+index 0000000..1a796fd
+--- /dev/null
++++ b/tests/qemu-iotests/274.out
+@@ -0,0 +1,268 @@
++== Commit tests ==
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 2097152/2097152 bytes at offset 0
++2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Check visible data ===
++read 1048576/1048576 bytes at offset 0
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++read 1048576/1048576 bytes at offset 1048576
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Checking allocation status ===
++1048576/1048576 bytes allocated at offset 0 bytes
++1048576/1048576 bytes allocated at offset 1 MiB
++
++0/1048576 bytes allocated at offset 0 bytes
++0/0 bytes allocated at offset 1 MiB
++
++0/1048576 bytes allocated at offset 0 bytes
++0/1048576 bytes allocated at offset 1 MiB
++
++=== Checking map ===
++[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
++
++Offset          Length          Mapped to       File
++0               0x200000        0x50000         TEST_DIR/PID-base
++
++[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
++
++Offset          Length          Mapped to       File
++0               0x100000        0x50000         TEST_DIR/PID-base
++
++[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
++{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
++
++Offset          Length          Mapped to       File
++0               0x100000        0x50000         TEST_DIR/PID-base
++
++=== Testing qemu-img commit (top -> mid) ===
++Image committed.
++
++image: TEST_IMG
++file format: IMGFMT
++virtual size: 2 MiB (2097152 bytes)
++cluster_size: 65536
++backing file: TEST_DIR/PID-base
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    refcount bits: 16
++    corrupt: false
++
++read 1048576/1048576 bytes at offset 0
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++read 1048576/1048576 bytes at offset 1048576
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Testing HMP commit (top -> mid) ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 2097152/2097152 bytes at offset 0
++2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
++{"return": ""}
++image: TEST_IMG
++file format: IMGFMT
++virtual size: 2 MiB (2097152 bytes)
++cluster_size: 65536
++backing file: TEST_DIR/PID-base
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    refcount bits: 16
++    corrupt: false
++
++read 1048576/1048576 bytes at offset 0
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++read 1048576/1048576 bytes at offset 1048576
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++=== Testing QMP active commit (top -> mid) ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 2097152/2097152 bytes at offset 0
++2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
++{"return": {}}
++{"execute": "job-complete", "arguments": {"id": "job0"}}
++{"return": {}}
++{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
++{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
++{"execute": "job-dismiss", "arguments": {"id": "job0"}}
++{"return": {}}
++image: TEST_IMG
++file format: IMGFMT
++virtual size: 2 MiB (2097152 bytes)
++cluster_size: 65536
++backing file: TEST_DIR/PID-base
++Format specific information:
++    compat: 1.1
++    lazy refcounts: false
++    refcount bits: 16
++    corrupt: false
++
++read 1048576/1048576 bytes at offset 0
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++read 1048576/1048576 bytes at offset 1048576
++1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++== Resize tests ==
++=== preallocation=off ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 5368709120
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 5368709120
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
++7 GiB (0x1c0000000) bytes     allocated at offset 1 GiB (0x40000000)
++
++[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
++{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
++
++=== preallocation=metadata ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 33285996544
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 33285996544
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
++3 GiB (0xc0000000) bytes     allocated at offset 30 GiB (0x780000000)
++
++[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
++{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
++{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
++{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
++{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
++{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
++{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
++
++=== preallocation=falloc ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 9437184
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 9437184
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
++10 MiB (0xa00000) bytes     allocated at offset 5 MiB (0x500000)
++
++[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
++{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
++
++=== preallocation=full ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 11534336
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 11534336
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
++4 MiB (0x400000) bytes     allocated at offset 8 MiB (0x800000)
++
++[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
++{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
++
++=== preallocation=off ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 259072
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 259072
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
++320 KiB (0x50000) bytes     allocated at offset 192 KiB (0x30000)
++
++[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
++{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
++{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
++
++=== preallocation=off ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 344064
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 344064
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
++256 KiB (0x40000) bytes     allocated at offset 256 KiB (0x40000)
++
++[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
++{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
++
++=== preallocation=off ===
++Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
++
++wrote 65536/65536 bytes at offset 446464
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++Image resized.
++
++read 65536/65536 bytes at offset 446464
++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
++
++256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
++244 KiB (0x3d000) bytes     allocated at offset 256 KiB (0x40000)
++
++[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
++{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
++
+diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
+index 033b54d..cddae00 100644
+--- a/tests/qemu-iotests/group
++++ b/tests/qemu-iotests/group
+@@ -286,6 +286,7 @@
+ 270 rw backing quick
+ 272 rw
+ 273 backing quick
++274 rw backing
+ 277 rw quick
+ 280 rw migration quick
+ 281 rw quick
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-iotests-don-t-use-format-for-drive_add.patch b/SOURCES/kvm-iotests-don-t-use-format-for-drive_add.patch
new file mode 100644
index 0000000..f95e17a
--- /dev/null
+++ b/SOURCES/kvm-iotests-don-t-use-format-for-drive_add.patch
@@ -0,0 +1,81 @@
+From 127360c2fa0fefa18ff828bfec3985e04791d665 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:16 +0100
+Subject: [PATCH 17/26] iotests: don't use 'format' for drive_add
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-3-kwolf@redhat.com>
+Patchwork-id: 97102
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 02/11] iotests: don't use 'format' for drive_add
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+From: John Snow <jsnow@redhat.com>
+
+It shadows (with a different type) the built-in format.
+Use something else.
+
+Signed-off-by: John Snow <jsnow@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200331000014.11581-3-jsnow@redhat.com>
+Reviewed-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+(cherry picked from commit 1d3d4b630c6ea8b19420c097f0c448b6ded95072)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/qemu-iotests/055        | 3 ++-
+ tests/qemu-iotests/iotests.py | 6 +++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
+index c732a11..eb50c9f 100755
+--- a/tests/qemu-iotests/055
++++ b/tests/qemu-iotests/055
+@@ -469,7 +469,8 @@ class TestDriveCompression(iotests.QMPTestCase):
+         qemu_img('create', '-f', fmt, blockdev_target_img,
+                  str(TestDriveCompression.image_len), *args)
+         if attach_target:
+-            self.vm.add_drive(blockdev_target_img, format=fmt, interface="none")
++            self.vm.add_drive(blockdev_target_img,
++                              img_format=fmt, interface="none")
+ 
+         self.vm.launch()
+ 
+diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
+index 46f880c..be20d56 100644
+--- a/tests/qemu-iotests/iotests.py
++++ b/tests/qemu-iotests/iotests.py
+@@ -481,20 +481,20 @@ class VM(qtest.QEMUQtestMachine):
+         self._args.append(opts)
+         return self
+ 
+-    def add_drive(self, path, opts='', interface='virtio', format=imgfmt):
++    def add_drive(self, path, opts='', interface='virtio', img_format=imgfmt):
+         '''Add a virtio-blk drive to the VM'''
+         options = ['if=%s' % interface,
+                    'id=drive%d' % self._num_drives]
+ 
+         if path is not None:
+             options.append('file=%s' % path)
+-            options.append('format=%s' % format)
++            options.append('format=%s' % img_format)
+             options.append('cache=%s' % cachemode)
+ 
+         if opts:
+             options.append(opts)
+ 
+-        if format == 'luks' and 'key-secret' not in opts:
++        if img_format == 'luks' and 'key-secret' not in opts:
+             # default luks support
+             if luks_default_secret_object not in self._args:
+                 self.add_object(luks_default_secret_object)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-linux-headers-support-vfio-ccw-features.patch b/SOURCES/kvm-linux-headers-support-vfio-ccw-features.patch
new file mode 100644
index 0000000..4eb95bf
--- /dev/null
+++ b/SOURCES/kvm-linux-headers-support-vfio-ccw-features.patch
@@ -0,0 +1,77 @@
+From 1da0eecb9f2086c880fdaf1260ae775bbfbf5f02 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:37 -0400
+Subject: [PATCH 03/12] linux-headers: support vfio-ccw features
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-4-cohuck@redhat.com>
+Patchwork-id: 97696
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 3/9] linux-headers: support vfio-ccw features
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+Partial update to support CRW and SCHIB regions.
+
+Upstream: n/a
+
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ linux-headers/linux/vfio.h     |  3 +++
+ linux-headers/linux/vfio_ccw.h | 19 +++++++++++++++++++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
+index fb10370d29..9e227348b3 100644
+--- a/linux-headers/linux/vfio.h
++++ b/linux-headers/linux/vfio.h
+@@ -378,6 +378,8 @@ struct vfio_region_gfx_edid {
+ 
+ /* sub-types for VFIO_REGION_TYPE_CCW */
+ #define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD	(1)
++#define VFIO_REGION_SUBTYPE_CCW_SCHIB		(2)
++#define VFIO_REGION_SUBTYPE_CCW_CRW		(3)
+ 
+ /*
+  * The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
+@@ -577,6 +579,7 @@ enum {
+ 
+ enum {
+ 	VFIO_CCW_IO_IRQ_INDEX,
++	VFIO_CCW_CRW_IRQ_INDEX,
+ 	VFIO_CCW_NUM_IRQS
+ };
+ 
+diff --git a/linux-headers/linux/vfio_ccw.h b/linux-headers/linux/vfio_ccw.h
+index fcc3e69ef5..6375d6ff25 100644
+--- a/linux-headers/linux/vfio_ccw.h
++++ b/linux-headers/linux/vfio_ccw.h
+@@ -34,4 +34,23 @@ struct ccw_cmd_region {
+ 	__u32 ret_code;
+ } __attribute__((packed));
+ 
++/*
++ * Used for processing commands that read the subchannel-information block
++ * Reading this region triggers a stsch() to hardware
++ * Note: this is controlled by a capability
++ */
++struct ccw_schib_region {
++#define SCHIB_AREA_SIZE 52
++       __u8 schib_area[SCHIB_AREA_SIZE];
++} __attribute__((packed));
++
++/*
++ * Used for returning a Channel Report Word to userspace.
++ * Note: this is controlled by a capability
++ */
++struct ccw_crw_region {
++       __u32 crw;
++       __u32 pad;
++} __attribute__((packed));
++
+ #endif
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-linux-headers-update-kvm.h.patch b/SOURCES/kvm-linux-headers-update-kvm.h.patch
new file mode 100644
index 0000000..1834e33
--- /dev/null
+++ b/SOURCES/kvm-linux-headers-update-kvm.h.patch
@@ -0,0 +1,119 @@
+From 9d1b94d3739567245578f30866facc13edb3be92 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:44 -0400
+Subject: [PATCH 02/42] linux-headers: update kvm.h
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-3-thuth@redhat.com>
+Patchwork-id: 97020
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 02/38] linux-headers: update kvm.h
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+Upstream-status: n/a
+
+Update kvm.h for the upcoming new s390x reset and protected virtualization
+ioctls. This patch is based on commit ddda37483dd17c9936fdde9ebf8f6ca2692b3842
+and commit dc6f8d458a4ccc360723993f31d310d06469f55f, but I dropped all
+(unrequired) changes to the other linux-header files.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ linux-headers/linux/kvm.h | 55 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 53 insertions(+), 2 deletions(-)
+
+diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
+index 3d9b18f7f8..578cd97c0d 100644
+--- a/linux-headers/linux/kvm.h
++++ b/linux-headers/linux/kvm.h
+@@ -468,12 +468,17 @@ struct kvm_s390_mem_op {
+ 	__u32 size;		/* amount of bytes */
+ 	__u32 op;		/* type of operation */
+ 	__u64 buf;		/* buffer in userspace */
+-	__u8 ar;		/* the access register number */
+-	__u8 reserved[31];	/* should be set to 0 */
++	union {
++		__u8 ar;	/* the access register number */
++		__u32 sida_offset; /* offset into the sida */
++		__u8 reserved[32]; /* should be set to 0 */
++	};
+ };
+ /* types for kvm_s390_mem_op->op */
+ #define KVM_S390_MEMOP_LOGICAL_READ	0
+ #define KVM_S390_MEMOP_LOGICAL_WRITE	1
++#define KVM_S390_MEMOP_SIDA_READ	2
++#define KVM_S390_MEMOP_SIDA_WRITE	3
+ /* flags for kvm_s390_mem_op->flags */
+ #define KVM_S390_MEMOP_F_CHECK_ONLY		(1ULL << 0)
+ #define KVM_S390_MEMOP_F_INJECT_EXCEPTION	(1ULL << 1)
+@@ -1000,6 +1005,12 @@ struct kvm_ppc_resize_hpt {
+ #define KVM_CAP_PMU_EVENT_FILTER 173
+ #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
+ #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
++#define KVM_CAP_PPC_GUEST_DEBUG_SSTEP 176
++#define KVM_CAP_ARM_NISV_TO_USER 177
++#define KVM_CAP_ARM_INJECT_EXT_DABT 178
++#define KVM_CAP_S390_VCPU_RESETS 179
++#define KVM_CAP_S390_PROTECTED 180
++#define KVM_CAP_PPC_SECURE_GUEST 181
+ 
+ #ifdef KVM_CAP_IRQ_ROUTING
+ 
+@@ -1461,6 +1472,43 @@ struct kvm_enc_region {
+ /* Available with KVM_CAP_ARM_SVE */
+ #define KVM_ARM_VCPU_FINALIZE	  _IOW(KVMIO,  0xc2, int)
+ 
++/* Available with  KVM_CAP_S390_VCPU_RESETS */
++#define KVM_S390_NORMAL_RESET	_IO(KVMIO,   0xc3)
++#define KVM_S390_CLEAR_RESET	_IO(KVMIO,   0xc4)
++
++struct kvm_s390_pv_sec_parm {
++	__u64 origin;
++	__u64 length;
++};
++
++struct kvm_s390_pv_unp {
++	__u64 addr;
++	__u64 size;
++	__u64 tweak;
++};
++
++enum pv_cmd_id {
++	KVM_PV_ENABLE,
++	KVM_PV_DISABLE,
++	KVM_PV_SET_SEC_PARMS,
++	KVM_PV_UNPACK,
++	KVM_PV_VERIFY,
++	KVM_PV_PREP_RESET,
++	KVM_PV_UNSHARE_ALL,
++};
++
++struct kvm_pv_cmd {
++	__u32 cmd;	/* Command to be executed */
++	__u16 rc;	/* Ultravisor return code */
++	__u16 rrc;	/* Ultravisor return reason code */
++	__u64 data;	/* Data or address */
++	__u32 flags;    /* flags for future extensions. Must be 0 for now */
++	__u32 reserved[3];
++};
++
++/* Available with KVM_CAP_S390_PROTECTED */
++#define KVM_S390_PV_COMMAND		_IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
++
+ /* Secure Encrypted Virtualization command */
+ enum sev_cmd_id {
+ 	/* Guest initialization commands */
+@@ -1611,4 +1659,7 @@ struct kvm_hyperv_eventfd {
+ #define KVM_HYPERV_CONN_ID_MASK		0x00ffffff
+ #define KVM_HYPERV_EVENTFD_DEASSIGN	(1 << 0)
+ 
++#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE    (1 << 0)
++#define KVM_DIRTY_LOG_INITIALLY_SET            (1 << 1)
++
+ #endif /* __LINUX_KVM_H */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-mirror-Make-sure-that-source-and-target-size-match.patch b/SOURCES/kvm-mirror-Make-sure-that-source-and-target-size-match.patch
new file mode 100644
index 0000000..09d1152
--- /dev/null
+++ b/SOURCES/kvm-mirror-Make-sure-that-source-and-target-size-match.patch
@@ -0,0 +1,89 @@
+From 98bf67db979927a5c7bbdc4a17c35d60b5f38e71 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 3 Jun 2020 16:03:24 +0100
+Subject: [PATCH 25/26] mirror: Make sure that source and target size match
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200603160325.67506-11-kwolf@redhat.com>
+Patchwork-id: 97110
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH v2 10/11] mirror: Make sure that source and target size match
+Bugzilla: 1778593
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+If the target is shorter than the source, mirror would copy data until
+it reaches the end of the target and then fail with an I/O error when
+trying to write past the end.
+
+If the target is longer than the source, the mirror job would complete
+successfully, but the target wouldn't actually be an accurate copy of
+the source image (it would contain some additional garbage at the end).
+
+Fix this by checking that both images have the same size when the job
+starts.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200511135825.219437-4-kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit e83dd6808c6e0975970f37b49b27cc37bb54eea8)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/mirror.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/block/mirror.c b/block/mirror.c
+index 5e5a521..0d32fca 100644
+--- a/block/mirror.c
++++ b/block/mirror.c
+@@ -859,6 +859,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
+     BlockDriverState *target_bs = blk_bs(s->target);
+     bool need_drain = true;
+     int64_t length;
++    int64_t target_length;
+     BlockDriverInfo bdi;
+     char backing_filename[2]; /* we only need 2 characters because we are only
+                                  checking for a NULL string */
+@@ -874,24 +875,26 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
+         goto immediate_exit;
+     }
+ 
++    target_length = blk_getlength(s->target);
++    if (target_length < 0) {
++        ret = target_length;
++        goto immediate_exit;
++    }
++
+     /* Active commit must resize the base image if its size differs from the
+      * active layer. */
+     if (s->base == blk_bs(s->target)) {
+-        int64_t base_length;
+-
+-        base_length = blk_getlength(s->target);
+-        if (base_length < 0) {
+-            ret = base_length;
+-            goto immediate_exit;
+-        }
+-
+-        if (s->bdev_length > base_length) {
++        if (s->bdev_length > target_length) {
+             ret = blk_truncate(s->target, s->bdev_length, false,
+                                PREALLOC_MODE_OFF, NULL);
+             if (ret < 0) {
+                 goto immediate_exit;
+             }
+         }
++    } else if (s->bdev_length != target_length) {
++        error_setg(errp, "Source and target image have different sizes");
++        ret = -EINVAL;
++        goto immediate_exit;
+     }
+ 
+     if (s->bdev_length == 0) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-nbd-server-Avoid-long-error-message-assertions-CVE-2.patch b/SOURCES/kvm-nbd-server-Avoid-long-error-message-assertions-CVE-2.patch
new file mode 100644
index 0000000..94d2c98
--- /dev/null
+++ b/SOURCES/kvm-nbd-server-Avoid-long-error-message-assertions-CVE-2.patch
@@ -0,0 +1,161 @@
+From f49ff2ed5675f1d0cddc404842e9d6e4e572d5a7 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Wed, 10 Jun 2020 18:32:01 -0400
+Subject: [PATCH 1/2] nbd/server: Avoid long error message assertions
+ CVE-2020-10761
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200610183202.3780750-2-eblake@redhat.com>
+Patchwork-id: 97494
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/2] nbd/server: Avoid long error message assertions CVE-2020-10761
+Bugzilla: 1845384
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+Ever since commit 36683283 (v2.8), the server code asserts that error
+strings sent to the client are well-formed per the protocol by not
+exceeding the maximum string length of 4096.  At the time the server
+first started sending error messages, the assertion could not be
+triggered, because messages were completely under our control.
+However, over the years, we have added latent scenarios where a client
+could trigger the server to attempt an error message that would
+include the client's information if it passed other checks first:
+
+- requesting NBD_OPT_INFO/GO on an export name that is not present
+  (commit 0cfae925 in v2.12 echoes the name)
+
+- requesting NBD_OPT_LIST/SET_META_CONTEXT on an export name that is
+  not present (commit e7b1948d in v2.12 echoes the name)
+
+At the time, those were still safe because we flagged names larger
+than 256 bytes with a different message; but that changed in commit
+93676c88 (v4.2) when we raised the name limit to 4096 to match the NBD
+string limit.  (That commit also failed to change the magic number
+4096 in nbd_negotiate_send_rep_err to the just-introduced named
+constant.)  So with that commit, long client names appended to server
+text can now trigger the assertion, and thus be used as a denial of
+service attack against a server.  As a mitigating factor, if the
+server requires TLS, the client cannot trigger the problematic paths
+unless it first supplies TLS credentials, and such trusted clients are
+less likely to try to intentionally crash the server.
+
+We may later want to further sanitize the user-supplied strings we
+place into our error messages, such as scrubbing out control
+characters, but that is less important to the CVE fix, so it can be a
+later patch to the new nbd_sanitize_name.
+
+Consideration was given to changing the assertion in
+nbd_negotiate_send_rep_verr to instead merely log a server error and
+truncate the message, to avoid leaving a latent path that could
+trigger a future CVE DoS on any new error message.  However, this
+merely complicates the code for something that is already (correctly)
+flagging coding errors, and now that we are aware of the long message
+pitfall, we are less likely to introduce such errors in the future,
+which would make such error handling dead code.
+
+Reported-by: Xueqiang Wei <xuwei@redhat.com>
+CC: qemu-stable@nongnu.org
+Fixes: https://bugzilla.redhat.com/1843684 CVE-2020-10761
+Fixes: 93676c88d7
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200610163741.3745251-2-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit 5c4fe018c025740fef4a0a4421e8162db0c3eefd)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+---
+ nbd/server.c               | 23 ++++++++++++++++++++---
+ tests/qemu-iotests/143     |  4 ++++
+ tests/qemu-iotests/143.out |  2 ++
+ 3 files changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/nbd/server.c b/nbd/server.c
+index 24ebc1a805..d5b9df092c 100644
+--- a/nbd/server.c
++++ b/nbd/server.c
+@@ -217,7 +217,7 @@ nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
+ 
+     msg = g_strdup_vprintf(fmt, va);
+     len = strlen(msg);
+-    assert(len < 4096);
++    assert(len < NBD_MAX_STRING_SIZE);
+     trace_nbd_negotiate_send_rep_err(msg);
+     ret = nbd_negotiate_send_rep_len(client, type, len, errp);
+     if (ret < 0) {
+@@ -231,6 +231,19 @@ nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
+     return 0;
+ }
+ 
++/*
++ * Return a malloc'd copy of @name suitable for use in an error reply.
++ */
++static char *
++nbd_sanitize_name(const char *name)
++{
++    if (strnlen(name, 80) < 80) {
++        return g_strdup(name);
++    }
++    /* XXX Should we also try to sanitize any control characters? */
++    return g_strdup_printf("%.80s...", name);
++}
++
+ /* Send an error reply.
+  * Return -errno on error, 0 on success. */
+ static int GCC_FMT_ATTR(4, 5)
+@@ -595,9 +608,11 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
+ 
+     exp = nbd_export_find(name);
+     if (!exp) {
++        g_autofree char *sane_name = nbd_sanitize_name(name);
++
+         return nbd_negotiate_send_rep_err(client, NBD_REP_ERR_UNKNOWN,
+                                           errp, "export '%s' not present",
+-                                          name);
++                                          sane_name);
+     }
+ 
+     /* Don't bother sending NBD_INFO_NAME unless client requested it */
+@@ -995,8 +1010,10 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
+ 
+     meta->exp = nbd_export_find(export_name);
+     if (meta->exp == NULL) {
++        g_autofree char *sane_name = nbd_sanitize_name(export_name);
++
+         return nbd_opt_drop(client, NBD_REP_ERR_UNKNOWN, errp,
+-                            "export '%s' not present", export_name);
++                            "export '%s' not present", sane_name);
+     }
+ 
+     ret = nbd_opt_read(client, &nb_queries, sizeof(nb_queries), errp);
+diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
+index f649b36195..d2349903b1 100755
+--- a/tests/qemu-iotests/143
++++ b/tests/qemu-iotests/143
+@@ -58,6 +58,10 @@ _send_qemu_cmd $QEMU_HANDLE \
+ $QEMU_IO_PROG -f raw -c quit \
+     "nbd+unix:///no_such_export?socket=$SOCK_DIR/nbd" 2>&1 \
+     | _filter_qemu_io | _filter_nbd
++# Likewise, with longest possible name permitted in NBD protocol
++$QEMU_IO_PROG -f raw -c quit \
++    "nbd+unix:///$(printf %4096d 1 | tr ' ' a)?socket=$SOCK_DIR/nbd" 2>&1 \
++    | _filter_qemu_io | _filter_nbd | sed 's/aaaa*aa/aa--aa/'
+ 
+ _send_qemu_cmd $QEMU_HANDLE \
+     "{ 'execute': 'quit' }" \
+diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
+index 1f4001c601..fc9c0a761f 100644
+--- a/tests/qemu-iotests/143.out
++++ b/tests/qemu-iotests/143.out
+@@ -5,6 +5,8 @@ QA output created by 143
+ {"return": {}}
+ qemu-io: can't open device nbd+unix:///no_such_export?socket=SOCK_DIR/nbd: Requested export not available
+ server reported: export 'no_such_export' not present
++qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested export not available
++server reported: export 'aa--aa...' not present
+ { 'execute': 'quit' }
+ {"return": {}}
+ {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-numa-Extend-CLI-to-provide-initiator-information-for.patch b/SOURCES/kvm-numa-Extend-CLI-to-provide-initiator-information-for.patch
new file mode 100644
index 0000000..6d9382c
--- /dev/null
+++ b/SOURCES/kvm-numa-Extend-CLI-to-provide-initiator-information-for.patch
@@ -0,0 +1,318 @@
+From 70f8bbb27f9f357ea83ff6639fc00aa60fc902b9 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:47 +0100
+Subject: [PATCH 04/12] numa: Extend CLI to provide initiator information for
+ numa nodes
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-4-plai@redhat.com>
+Patchwork-id: 96736
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 03/11] numa: Extend CLI to provide initiator information for numa nodes
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Tao Xu <tao3.xu@intel.com>
+
+In ACPI 6.3 chapter 5.2.27 Heterogeneous Memory Attribute Table (HMAT),
+The initiator represents processor which access to memory. And in 5.2.27.3
+Memory Proximity Domain Attributes Structure, the attached initiator is
+defined as where the memory controller responsible for a memory proximity
+domain. With attached initiator information, the topology of heterogeneous
+memory can be described. Add new machine property 'hmat' to enable all
+HMAT specific options.
+
+Extend CLI of "-numa node" option to indicate the initiator numa node-id.
+In the linux kernel, the codes in drivers/acpi/hmat/hmat.c parse and report
+the platform's HMAT tables. Before using initiator option, enable HMAT with
+-machine hmat=on.
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+Reviewed-by: Jingqi Liu <jingqi.liu@intel.com>
+Suggested-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-2-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 244b3f4485a07c7ce4b7123d6ce9d8c6012756e8)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/core/machine.c     | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ hw/core/numa.c        | 23 ++++++++++++++++++
+ include/sysemu/numa.h |  5 ++++
+ qapi/machine.json     | 10 +++++++-
+ qemu-options.hx       | 35 ++++++++++++++++++++++++----
+ 5 files changed, 131 insertions(+), 6 deletions(-)
+
+diff --git a/hw/core/machine.c b/hw/core/machine.c
+index 19c78c6..cb21ae1 100644
+--- a/hw/core/machine.c
++++ b/hw/core/machine.c
+@@ -688,6 +688,20 @@ static void machine_set_nvdimm(Object *obj, bool value, Error **errp)
+     ms->nvdimms_state->is_enabled = value;
+ }
+ 
++static bool machine_get_hmat(Object *obj, Error **errp)
++{
++    MachineState *ms = MACHINE(obj);
++
++    return ms->numa_state->hmat_enabled;
++}
++
++static void machine_set_hmat(Object *obj, bool value, Error **errp)
++{
++    MachineState *ms = MACHINE(obj);
++
++    ms->numa_state->hmat_enabled = value;
++}
++
+ static char *machine_get_nvdimm_persistence(Object *obj, Error **errp)
+ {
+     MachineState *ms = MACHINE(obj);
+@@ -815,6 +829,7 @@ void machine_set_cpu_numa_node(MachineState *machine,
+                                const CpuInstanceProperties *props, Error **errp)
+ {
+     MachineClass *mc = MACHINE_GET_CLASS(machine);
++    NodeInfo *numa_info = machine->numa_state->nodes;
+     bool match = false;
+     int i;
+ 
+@@ -884,6 +899,17 @@ void machine_set_cpu_numa_node(MachineState *machine,
+         match = true;
+         slot->props.node_id = props->node_id;
+         slot->props.has_node_id = props->has_node_id;
++
++        if (machine->numa_state->hmat_enabled) {
++            if ((numa_info[props->node_id].initiator < MAX_NODES) &&
++                (props->node_id != numa_info[props->node_id].initiator)) {
++                error_setg(errp, "The initiator of CPU NUMA node %" PRId64
++                        " should be itself", props->node_id);
++                return;
++            }
++            numa_info[props->node_id].has_cpu = true;
++            numa_info[props->node_id].initiator = props->node_id;
++        }
+     }
+ 
+     if (!match) {
+@@ -1130,6 +1156,13 @@ static void machine_initfn(Object *obj)
+ 
+     if (mc->cpu_index_to_instance_props && mc->get_default_cpu_node_id) {
+         ms->numa_state = g_new0(NumaState, 1);
++        object_property_add_bool(obj, "hmat",
++                                 machine_get_hmat, machine_set_hmat,
++                                 &error_abort);
++        object_property_set_description(obj, "hmat",
++                                        "Set on/off to enable/disable "
++                                        "ACPI Heterogeneous Memory Attribute "
++                                        "Table (HMAT)", NULL);
+     }
+ 
+     /* Register notifier when init is done for sysbus sanity checks */
+@@ -1218,6 +1251,32 @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
+     return g_string_free(s, false);
+ }
+ 
++static void numa_validate_initiator(NumaState *numa_state)
++{
++    int i;
++    NodeInfo *numa_info = numa_state->nodes;
++
++    for (i = 0; i < numa_state->num_nodes; i++) {
++        if (numa_info[i].initiator == MAX_NODES) {
++            error_report("The initiator of NUMA node %d is missing, use "
++                         "'-numa node,initiator' option to declare it", i);
++            exit(1);
++        }
++
++        if (!numa_info[numa_info[i].initiator].present) {
++            error_report("NUMA node %" PRIu16 " is missing, use "
++                         "'-numa node' option to declare it first",
++                         numa_info[i].initiator);
++            exit(1);
++        }
++
++        if (!numa_info[numa_info[i].initiator].has_cpu) {
++            error_report("The initiator of NUMA node %d is invalid", i);
++            exit(1);
++        }
++    }
++}
++
+ static void machine_numa_finish_cpu_init(MachineState *machine)
+ {
+     int i;
+@@ -1258,6 +1317,11 @@ static void machine_numa_finish_cpu_init(MachineState *machine)
+             machine_set_cpu_numa_node(machine, &props, &error_fatal);
+         }
+     }
++
++    if (machine->numa_state->hmat_enabled) {
++        numa_validate_initiator(machine->numa_state);
++    }
++
+     if (s->len && !qtest_enabled()) {
+         warn_report("CPU(s) not present in any NUMA nodes: %s",
+                     s->str);
+diff --git a/hw/core/numa.c b/hw/core/numa.c
+index 19f082d..a07eef9 100644
+--- a/hw/core/numa.c
++++ b/hw/core/numa.c
+@@ -129,6 +129,29 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
+         numa_info[nodenr].node_mem = object_property_get_uint(o, "size", NULL);
+         numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
+     }
++
++    /*
++     * If not set the initiator, set it to MAX_NODES. And if
++     * HMAT is enabled and this node has no cpus, QEMU will raise error.
++     */
++    numa_info[nodenr].initiator = MAX_NODES;
++    if (node->has_initiator) {
++        if (!ms->numa_state->hmat_enabled) {
++            error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
++                       "(HMAT) is disabled, enable it with -machine hmat=on "
++                       "before using any of hmat specific options");
++            return;
++        }
++
++        if (node->initiator >= MAX_NODES) {
++            error_report("The initiator id %" PRIu16 " expects an integer "
++                         "between 0 and %d", node->initiator,
++                         MAX_NODES - 1);
++            return;
++        }
++
++        numa_info[nodenr].initiator = node->initiator;
++    }
+     numa_info[nodenr].present = true;
+     max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
+     ms->numa_state->num_nodes++;
+diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
+index ae9c41d..788cbec 100644
+--- a/include/sysemu/numa.h
++++ b/include/sysemu/numa.h
+@@ -18,6 +18,8 @@ struct NodeInfo {
+     uint64_t node_mem;
+     struct HostMemoryBackend *node_memdev;
+     bool present;
++    bool has_cpu;
++    uint16_t initiator;
+     uint8_t distance[MAX_NODES];
+ };
+ 
+@@ -33,6 +35,9 @@ struct NumaState {
+     /* Allow setting NUMA distance for different NUMA nodes */
+     bool have_numa_distance;
+ 
++    /* Detect if HMAT support is enabled. */
++    bool hmat_enabled;
++
+     /* NUMA nodes information */
+     NodeInfo nodes[MAX_NODES];
+ };
+diff --git a/qapi/machine.json b/qapi/machine.json
+index ca26779..27d0e37 100644
+--- a/qapi/machine.json
++++ b/qapi/machine.json
+@@ -463,6 +463,13 @@
+ # @memdev: memory backend object.  If specified for one node,
+ #          it must be specified for all nodes.
+ #
++# @initiator: defined in ACPI 6.3 Chapter 5.2.27.3 Table 5-145,
++#             points to the nodeid which has the memory controller
++#             responsible for this NUMA node. This field provides
++#             additional information as to the initiator node that
++#             is closest (as in directly attached) to this node, and
++#             therefore has the best performance (since 5.0)
++#
+ # Since: 2.1
+ ##
+ { 'struct': 'NumaNodeOptions',
+@@ -470,7 +477,8 @@
+    '*nodeid': 'uint16',
+    '*cpus':   ['uint16'],
+    '*mem':    'size',
+-   '*memdev': 'str' }}
++   '*memdev': 'str',
++   '*initiator': 'uint16' }}
+ 
+ ##
+ # @NumaDistOptions:
+diff --git a/qemu-options.hx b/qemu-options.hx
+index df1d27b..e2ce754 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -43,7 +43,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
+     "                suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
+     "                nvdimm=on|off controls NVDIMM support (default=off)\n"
+     "                enforce-config-section=on|off enforce configuration section migration (default=off)\n"
+-    "                memory-encryption=@var{} memory encryption object to use (default=none)\n",
++    "                memory-encryption=@var{} memory encryption object to use (default=none)\n"
++    "                hmat=on|off controls ACPI HMAT support (default=off)\n",
+     QEMU_ARCH_ALL)
+ STEXI
+ @item -machine [type=]@var{name}[,prop=@var{value}[,...]]
+@@ -103,6 +104,9 @@ NOTE: this parameter is deprecated. Please use @option{-global}
+ @option{migration.send-configuration}=@var{on|off} instead.
+ @item memory-encryption=@var{}
+ Memory encryption object to use. The default is none.
++@item hmat=on|off
++Enables or disables ACPI Heterogeneous Memory Attribute Table (HMAT) support.
++The default is off.
+ @end table
+ ETEXI
+ 
+@@ -161,14 +165,14 @@ If any on the three values is given, the total number of CPUs @var{n} can be omi
+ ETEXI
+ 
+ DEF("numa", HAS_ARG, QEMU_OPTION_numa,
+-    "-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node]\n"
+-    "-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node]\n"
++    "-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
++    "-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
+     "-numa dist,src=source,dst=destination,val=distance\n"
+     "-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]\n",
+     QEMU_ARCH_ALL)
+ STEXI
+-@item -numa node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}]
+-@itemx -numa node[,memdev=@var{id}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}]
++@item -numa node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
++@itemx -numa node[,memdev=@var{id}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
+ @itemx -numa dist,src=@var{source},dst=@var{destination},val=@var{distance}
+ @itemx -numa cpu,node-id=@var{node}[,socket-id=@var{x}][,core-id=@var{y}][,thread-id=@var{z}]
+ @findex -numa
+@@ -215,6 +219,27 @@ split equally between them.
+ @samp{mem} and @samp{memdev} are mutually exclusive. Furthermore,
+ if one node uses @samp{memdev}, all of them have to use it.
+ 
++@samp{initiator} is an additional option that points to an @var{initiator}
++NUMA node that has best performance (the lowest latency or largest bandwidth)
++to this NUMA @var{node}. Note that this option can be set only when
++the machine property 'hmat' is set to 'on'.
++
++Following example creates a machine with 2 NUMA nodes, node 0 has CPU.
++node 1 has only memory, and its initiator is node 0. Note that because
++node 0 has CPU, by default the initiator of node 0 is itself and must be
++itself.
++@example
++-machine hmat=on \
++-m 2G,slots=2,maxmem=4G \
++-object memory-backend-ram,size=1G,id=m0 \
++-object memory-backend-ram,size=1G,id=m1 \
++-numa node,nodeid=0,memdev=m0 \
++-numa node,nodeid=1,memdev=m1,initiator=0 \
++-smp 2,sockets=2,maxcpus=2  \
++-numa cpu,node-id=0,socket-id=0 \
++-numa cpu,node-id=0,socket-id=1
++@end example
++
+ @var{source} and @var{destination} are NUMA node IDs.
+ @var{distance} is the NUMA distance from @var{source} to @var{destination}.
+ The distance from a node to itself is always 10. If any pair of nodes is
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-numa-Extend-CLI-to-provide-memory-latency-and-bandwi.patch b/SOURCES/kvm-numa-Extend-CLI-to-provide-memory-latency-and-bandwi.patch
new file mode 100644
index 0000000..306abeb
--- /dev/null
+++ b/SOURCES/kvm-numa-Extend-CLI-to-provide-memory-latency-and-bandwi.patch
@@ -0,0 +1,545 @@
+From 32341d8cf680625def040b44d70b197f2399bbdb Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:48 +0100
+Subject: [PATCH 05/12] numa: Extend CLI to provide memory latency and
+ bandwidth information
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-5-plai@redhat.com>
+Patchwork-id: 96731
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 04/11] numa: Extend CLI to provide memory latency and bandwidth information
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+Add -numa hmat-lb option to provide System Locality Latency and
+Bandwidth Information. These memory attributes help to build
+System Locality Latency and Bandwidth Information Structure(s)
+in ACPI Heterogeneous Memory Attribute Table (HMAT). Before using
+hmat-lb option, enable HMAT with -machine hmat=on.
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-3-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+(cherry picked from commit 9b12dfa03a94d7f7a4b54eb67229a31e58193384)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/core/numa.c        | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/sysemu/numa.h |  53 ++++++++++++++
+ qapi/machine.json     |  93 +++++++++++++++++++++++-
+ qemu-options.hx       |  47 +++++++++++-
+ 4 files changed, 384 insertions(+), 3 deletions(-)
+
+diff --git a/hw/core/numa.c b/hw/core/numa.c
+index a07eef9..58fe713 100644
+--- a/hw/core/numa.c
++++ b/hw/core/numa.c
+@@ -23,6 +23,7 @@
+  */
+ 
+ #include "qemu/osdep.h"
++#include "qemu/units.h"
+ #include "sysemu/hostmem.h"
+ #include "sysemu/numa.h"
+ #include "sysemu/sysemu.h"
+@@ -194,6 +195,186 @@ void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp)
+     ms->numa_state->have_numa_distance = true;
+ }
+ 
++void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
++                        Error **errp)
++{
++    int i, first_bit, last_bit;
++    uint64_t max_entry, temp_base, bitmap_copy;
++    NodeInfo *numa_info = numa_state->nodes;
++    HMAT_LB_Info *hmat_lb =
++        numa_state->hmat_lb[node->hierarchy][node->data_type];
++    HMAT_LB_Data lb_data = {};
++    HMAT_LB_Data *lb_temp;
++
++    /* Error checking */
++    if (node->initiator > numa_state->num_nodes) {
++        error_setg(errp, "Invalid initiator=%d, it should be less than %d",
++                   node->initiator, numa_state->num_nodes);
++        return;
++    }
++    if (node->target > numa_state->num_nodes) {
++        error_setg(errp, "Invalid target=%d, it should be less than %d",
++                   node->target, numa_state->num_nodes);
++        return;
++    }
++    if (!numa_info[node->initiator].has_cpu) {
++        error_setg(errp, "Invalid initiator=%d, it isn't an "
++                   "initiator proximity domain", node->initiator);
++        return;
++    }
++    if (!numa_info[node->target].present) {
++        error_setg(errp, "The target=%d should point to an existing node",
++                   node->target);
++        return;
++    }
++
++    if (!hmat_lb) {
++        hmat_lb = g_malloc0(sizeof(*hmat_lb));
++        numa_state->hmat_lb[node->hierarchy][node->data_type] = hmat_lb;
++        hmat_lb->list = g_array_new(false, true, sizeof(HMAT_LB_Data));
++    }
++    hmat_lb->hierarchy = node->hierarchy;
++    hmat_lb->data_type = node->data_type;
++    lb_data.initiator = node->initiator;
++    lb_data.target = node->target;
++
++    if (node->data_type <= HMATLB_DATA_TYPE_WRITE_LATENCY) {
++        /* Input latency data */
++
++        if (!node->has_latency) {
++            error_setg(errp, "Missing 'latency' option");
++            return;
++        }
++        if (node->has_bandwidth) {
++            error_setg(errp, "Invalid option 'bandwidth' since "
++                       "the data type is latency");
++            return;
++        }
++
++        /* Detect duplicate configuration */
++        for (i = 0; i < hmat_lb->list->len; i++) {
++            lb_temp = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);
++
++            if (node->initiator == lb_temp->initiator &&
++                node->target == lb_temp->target) {
++                error_setg(errp, "Duplicate configuration of the latency for "
++                    "initiator=%d and target=%d", node->initiator,
++                    node->target);
++                return;
++            }
++        }
++
++        hmat_lb->base = hmat_lb->base ? hmat_lb->base : UINT64_MAX;
++
++        if (node->latency) {
++            /* Calculate the temporary base and compressed latency */
++            max_entry = node->latency;
++            temp_base = 1;
++            while (QEMU_IS_ALIGNED(max_entry, 10)) {
++                max_entry /= 10;
++                temp_base *= 10;
++            }
++
++            /* Calculate the max compressed latency */
++            temp_base = MIN(hmat_lb->base, temp_base);
++            max_entry = node->latency / hmat_lb->base;
++            max_entry = MAX(hmat_lb->range_bitmap, max_entry);
++
++            /*
++             * For latency hmat_lb->range_bitmap record the max compressed
++             * latency which should be less than 0xFFFF (UINT16_MAX)
++             */
++            if (max_entry >= UINT16_MAX) {
++                error_setg(errp, "Latency %" PRIu64 " between initiator=%d and "
++                        "target=%d should not differ from previously entered "
++                        "min or max values on more than %d", node->latency,
++                        node->initiator, node->target, UINT16_MAX - 1);
++                return;
++            } else {
++                hmat_lb->base = temp_base;
++                hmat_lb->range_bitmap = max_entry;
++            }
++
++            /*
++             * Set lb_info_provided bit 0 as 1,
++             * latency information is provided
++             */
++            numa_info[node->target].lb_info_provided |= BIT(0);
++        }
++        lb_data.data = node->latency;
++    } else if (node->data_type >= HMATLB_DATA_TYPE_ACCESS_BANDWIDTH) {
++        /* Input bandwidth data */
++        if (!node->has_bandwidth) {
++            error_setg(errp, "Missing 'bandwidth' option");
++            return;
++        }
++        if (node->has_latency) {
++            error_setg(errp, "Invalid option 'latency' since "
++                       "the data type is bandwidth");
++            return;
++        }
++        if (!QEMU_IS_ALIGNED(node->bandwidth, MiB)) {
++            error_setg(errp, "Bandwidth %" PRIu64 " between initiator=%d and "
++                       "target=%d should be 1MB aligned", node->bandwidth,
++                       node->initiator, node->target);
++            return;
++        }
++
++        /* Detect duplicate configuration */
++        for (i = 0; i < hmat_lb->list->len; i++) {
++            lb_temp = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);
++
++            if (node->initiator == lb_temp->initiator &&
++                node->target == lb_temp->target) {
++                error_setg(errp, "Duplicate configuration of the bandwidth for "
++                    "initiator=%d and target=%d", node->initiator,
++                    node->target);
++                return;
++            }
++        }
++
++        hmat_lb->base = hmat_lb->base ? hmat_lb->base : 1;
++
++        if (node->bandwidth) {
++            /* Keep bitmap unchanged when bandwidth out of range */
++            bitmap_copy = hmat_lb->range_bitmap;
++            bitmap_copy |= node->bandwidth;
++            first_bit = ctz64(bitmap_copy);
++            temp_base = UINT64_C(1) << first_bit;
++            max_entry = node->bandwidth / temp_base;
++            last_bit = 64 - clz64(bitmap_copy);
++
++            /*
++             * For bandwidth, first_bit record the base unit of bandwidth bits,
++             * last_bit record the last bit of the max bandwidth. The max
++             * compressed bandwidth should be less than 0xFFFF (UINT16_MAX)
++             */
++            if ((last_bit - first_bit) > UINT16_BITS ||
++                max_entry >= UINT16_MAX) {
++                error_setg(errp, "Bandwidth %" PRIu64 " between initiator=%d "
++                        "and target=%d should not differ from previously "
++                        "entered values on more than %d", node->bandwidth,
++                        node->initiator, node->target, UINT16_MAX - 1);
++                return;
++            } else {
++                hmat_lb->base = temp_base;
++                hmat_lb->range_bitmap = bitmap_copy;
++            }
++
++            /*
++             * Set lb_info_provided bit 1 as 1,
++             * bandwidth information is provided
++             */
++            numa_info[node->target].lb_info_provided |= BIT(1);
++        }
++        lb_data.data = node->bandwidth;
++    } else {
++        assert(0);
++    }
++
++    g_array_append_val(hmat_lb->list, lb_data);
++}
++
+ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
+ {
+     Error *err = NULL;
+@@ -231,6 +412,19 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
+         machine_set_cpu_numa_node(ms, qapi_NumaCpuOptions_base(&object->u.cpu),
+                                   &err);
+         break;
++    case NUMA_OPTIONS_TYPE_HMAT_LB:
++        if (!ms->numa_state->hmat_enabled) {
++            error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
++                       "(HMAT) is disabled, enable it with -machine hmat=on "
++                       "before using any of hmat specific options");
++            return;
++        }
++
++        parse_numa_hmat_lb(ms->numa_state, &object->u.hmat_lb, &err);
++        if (err) {
++            goto end;
++        }
++        break;
+     default:
+         abort();
+     }
+diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
+index 788cbec..70f93c8 100644
+--- a/include/sysemu/numa.h
++++ b/include/sysemu/numa.h
+@@ -14,11 +14,34 @@ struct CPUArchId;
+ #define NUMA_DISTANCE_MAX         254
+ #define NUMA_DISTANCE_UNREACHABLE 255
+ 
++/* the value of AcpiHmatLBInfo flags */
++enum {
++    HMAT_LB_MEM_MEMORY           = 0,
++    HMAT_LB_MEM_CACHE_1ST_LEVEL  = 1,
++    HMAT_LB_MEM_CACHE_2ND_LEVEL  = 2,
++    HMAT_LB_MEM_CACHE_3RD_LEVEL  = 3,
++    HMAT_LB_LEVELS   /* must be the last entry */
++};
++
++/* the value of AcpiHmatLBInfo data type */
++enum {
++    HMAT_LB_DATA_ACCESS_LATENCY   = 0,
++    HMAT_LB_DATA_READ_LATENCY     = 1,
++    HMAT_LB_DATA_WRITE_LATENCY    = 2,
++    HMAT_LB_DATA_ACCESS_BANDWIDTH = 3,
++    HMAT_LB_DATA_READ_BANDWIDTH   = 4,
++    HMAT_LB_DATA_WRITE_BANDWIDTH  = 5,
++    HMAT_LB_TYPES   /* must be the last entry */
++};
++
++#define UINT16_BITS       16
++
+ struct NodeInfo {
+     uint64_t node_mem;
+     struct HostMemoryBackend *node_memdev;
+     bool present;
+     bool has_cpu;
++    uint8_t lb_info_provided;
+     uint16_t initiator;
+     uint8_t distance[MAX_NODES];
+ };
+@@ -28,6 +51,31 @@ struct NumaNodeMem {
+     uint64_t node_plugged_mem;
+ };
+ 
++struct HMAT_LB_Data {
++    uint8_t     initiator;
++    uint8_t     target;
++    uint64_t    data;
++};
++typedef struct HMAT_LB_Data HMAT_LB_Data;
++
++struct HMAT_LB_Info {
++    /* Indicates it's memory or the specified level memory side cache. */
++    uint8_t     hierarchy;
++
++    /* Present the type of data, access/read/write latency or bandwidth. */
++    uint8_t     data_type;
++
++    /* The range bitmap of bandwidth for calculating common base */
++    uint64_t    range_bitmap;
++
++    /* The common base unit for latencies or bandwidths */
++    uint64_t    base;
++
++    /* Array to store the latencies or bandwidths */
++    GArray      *list;
++};
++typedef struct HMAT_LB_Info HMAT_LB_Info;
++
+ struct NumaState {
+     /* Number of NUMA nodes */
+     int num_nodes;
+@@ -40,11 +88,16 @@ struct NumaState {
+ 
+     /* NUMA nodes information */
+     NodeInfo nodes[MAX_NODES];
++
++    /* NUMA nodes HMAT Locality Latency and Bandwidth Information */
++    HMAT_LB_Info *hmat_lb[HMAT_LB_LEVELS][HMAT_LB_TYPES];
+ };
+ typedef struct NumaState NumaState;
+ 
+ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
+ void parse_numa_opts(MachineState *ms);
++void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
++                        Error **errp);
+ void numa_complete_configuration(MachineState *ms);
+ void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms);
+ extern QemuOptsList qemu_numa_opts;
+diff --git a/qapi/machine.json b/qapi/machine.json
+index 27d0e37..cf8faf5 100644
+--- a/qapi/machine.json
++++ b/qapi/machine.json
+@@ -426,10 +426,12 @@
+ #
+ # @cpu: property based CPU(s) to node mapping (Since: 2.10)
+ #
++# @hmat-lb: memory latency and bandwidth information (Since: 5.0)
++#
+ # Since: 2.1
+ ##
+ { 'enum': 'NumaOptionsType',
+-  'data': [ 'node', 'dist', 'cpu' ] }
++  'data': [ 'node', 'dist', 'cpu', 'hmat-lb' ] }
+ 
+ ##
+ # @NumaOptions:
+@@ -444,7 +446,8 @@
+   'data': {
+     'node': 'NumaNodeOptions',
+     'dist': 'NumaDistOptions',
+-    'cpu': 'NumaCpuOptions' }}
++    'cpu': 'NumaCpuOptions',
++    'hmat-lb': 'NumaHmatLBOptions' }}
+ 
+ ##
+ # @NumaNodeOptions:
+@@ -558,6 +561,92 @@
+    'data' : {} }
+ 
+ ##
++# @HmatLBMemoryHierarchy:
++#
++# The memory hierarchy in the System Locality Latency and Bandwidth
++# Information Structure of HMAT (Heterogeneous Memory Attribute Table)
++#
++# For more information about @HmatLBMemoryHierarchy, see chapter
++# 5.2.27.4: Table 5-146: Field "Flags" of ACPI 6.3 spec.
++#
++# @memory: the structure represents the memory performance
++#
++# @first-level: first level of memory side cache
++#
++# @second-level: second level of memory side cache
++#
++# @third-level: third level of memory side cache
++#
++# Since: 5.0
++##
++{ 'enum': 'HmatLBMemoryHierarchy',
++  'data': [ 'memory', 'first-level', 'second-level', 'third-level' ] }
++
++##
++# @HmatLBDataType:
++#
++# Data type in the System Locality Latency and Bandwidth
++# Information Structure of HMAT (Heterogeneous Memory Attribute Table)
++#
++# For more information about @HmatLBDataType, see chapter
++# 5.2.27.4: Table 5-146:  Field "Data Type" of ACPI 6.3 spec.
++#
++# @access-latency: access latency (nanoseconds)
++#
++# @read-latency: read latency (nanoseconds)
++#
++# @write-latency: write latency (nanoseconds)
++#
++# @access-bandwidth: access bandwidth (Bytes per second)
++#
++# @read-bandwidth: read bandwidth (Bytes per second)
++#
++# @write-bandwidth: write bandwidth (Bytes per second)
++#
++# Since: 5.0
++##
++{ 'enum': 'HmatLBDataType',
++  'data': [ 'access-latency', 'read-latency', 'write-latency',
++            'access-bandwidth', 'read-bandwidth', 'write-bandwidth' ] }
++
++##
++# @NumaHmatLBOptions:
++#
++# Set the system locality latency and bandwidth information
++# between Initiator and Target proximity Domains.
++#
++# For more information about @NumaHmatLBOptions, see chapter
++# 5.2.27.4: Table 5-146 of ACPI 6.3 spec.
++#
++# @initiator: the Initiator Proximity Domain.
++#
++# @target: the Target Proximity Domain.
++#
++# @hierarchy: the Memory Hierarchy. Indicates the performance
++#             of memory or side cache.
++#
++# @data-type: presents the type of data, access/read/write
++#             latency or hit latency.
++#
++# @latency: the value of latency from @initiator to @target
++#           proximity domain, the latency unit is "ns(nanosecond)".
++#
++# @bandwidth: the value of bandwidth between @initiator and @target
++#             proximity domain, the bandwidth unit is
++#             "Bytes per second".
++#
++# Since: 5.0
++##
++{ 'struct': 'NumaHmatLBOptions',
++    'data': {
++    'initiator': 'uint16',
++    'target': 'uint16',
++    'hierarchy': 'HmatLBMemoryHierarchy',
++    'data-type': 'HmatLBDataType',
++    '*latency': 'uint64',
++    '*bandwidth': 'size' }}
++
++##
+ # @HostMemPolicy:
+ #
+ # Host memory policy types
+diff --git a/qemu-options.hx b/qemu-options.hx
+index e2ce754..86d9d8a 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -168,16 +168,19 @@ DEF("numa", HAS_ARG, QEMU_OPTION_numa,
+     "-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
+     "-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
+     "-numa dist,src=source,dst=destination,val=distance\n"
+-    "-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]\n",
++    "-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]\n"
++    "-numa hmat-lb,initiator=node,target=node,hierarchy=memory|first-level|second-level|third-level,data-type=access-latency|read-latency|write-latency[,latency=lat][,bandwidth=bw]\n",
+     QEMU_ARCH_ALL)
+ STEXI
+ @item -numa node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
+ @itemx -numa node[,memdev=@var{id}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
+ @itemx -numa dist,src=@var{source},dst=@var{destination},val=@var{distance}
+ @itemx -numa cpu,node-id=@var{node}[,socket-id=@var{x}][,core-id=@var{y}][,thread-id=@var{z}]
++@itemx -numa hmat-lb,initiator=@var{node},target=@var{node},hierarchy=@var{hierarchy},data-type=@var{tpye}[,latency=@var{lat}][,bandwidth=@var{bw}]
+ @findex -numa
+ Define a NUMA node and assign RAM and VCPUs to it.
+ Set the NUMA distance from a source node to a destination node.
++Set the ACPI Heterogeneous Memory Attributes for the given nodes.
+ 
+ Legacy VCPU assignment uses @samp{cpus} option where
+ @var{firstcpu} and @var{lastcpu} are CPU indexes. Each
+@@ -256,6 +259,48 @@ specified resources, it just assigns existing resources to NUMA
+ nodes. This means that one still has to use the @option{-m},
+ @option{-smp} options to allocate RAM and VCPUs respectively.
+ 
++Use @samp{hmat-lb} to set System Locality Latency and Bandwidth Information
++between initiator and target NUMA nodes in ACPI Heterogeneous Attribute Memory Table (HMAT).
++Initiator NUMA node can create memory requests, usually it has one or more processors.
++Target NUMA node contains addressable memory.
++
++In @samp{hmat-lb} option, @var{node} are NUMA node IDs. @var{hierarchy} is the memory
++hierarchy of the target NUMA node: if @var{hierarchy} is 'memory', the structure
++represents the memory performance; if @var{hierarchy} is 'first-level|second-level|third-level',
++this structure represents aggregated performance of memory side caches for each domain.
++@var{type} of 'data-type' is type of data represented by this structure instance:
++if 'hierarchy' is 'memory', 'data-type' is 'access|read|write' latency or 'access|read|write'
++bandwidth of the target memory; if 'hierarchy' is 'first-level|second-level|third-level',
++'data-type' is 'access|read|write' hit latency or 'access|read|write' hit bandwidth of the
++target memory side cache.
++
++@var{lat} is latency value in nanoseconds. @var{bw} is bandwidth value,
++the possible value and units are NUM[M|G|T], mean that the bandwidth value are
++NUM byte per second (or MB/s, GB/s or TB/s depending on used suffix).
++Note that if latency or bandwidth value is 0, means the corresponding latency or
++bandwidth information is not provided.
++
++For example, the following options describe 2 NUMA nodes. Node 0 has 2 cpus and
++a ram, node 1 has only a ram. The processors in node 0 access memory in node
++0 with access-latency 5 nanoseconds, access-bandwidth is 200 MB/s;
++The processors in NUMA node 0 access memory in NUMA node 1 with access-latency 10
++nanoseconds, access-bandwidth is 100 MB/s.
++@example
++-machine hmat=on \
++-m 2G \
++-object memory-backend-ram,size=1G,id=m0 \
++-object memory-backend-ram,size=1G,id=m1 \
++-smp 2 \
++-numa node,nodeid=0,memdev=m0 \
++-numa node,nodeid=1,memdev=m1,initiator=0 \
++-numa cpu,node-id=0,socket-id=0 \
++-numa cpu,node-id=0,socket-id=1 \
++-numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5 \
++-numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M \
++-numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10 \
++-numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M
++@end example
++
+ ETEXI
+ 
+ DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-numa-Extend-CLI-to-provide-memory-side-cache-informa.patch b/SOURCES/kvm-numa-Extend-CLI-to-provide-memory-side-cache-informa.patch
new file mode 100644
index 0000000..a17db22
--- /dev/null
+++ b/SOURCES/kvm-numa-Extend-CLI-to-provide-memory-side-cache-informa.patch
@@ -0,0 +1,326 @@
+From 8cd3544b1347b248b9d04eb3d6c9b9bde3a13655 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:49 +0100
+Subject: [PATCH 06/12] numa: Extend CLI to provide memory side cache
+ information
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-6-plai@redhat.com>
+Patchwork-id: 96740
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 05/11] numa: Extend CLI to provide memory side cache information
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Liu Jingqi <jingqi.liu@intel.com>
+
+Add -numa hmat-cache option to provide Memory Side Cache Information.
+These memory attributes help to build Memory Side Cache Information
+Structure(s) in ACPI Heterogeneous Memory Attribute Table (HMAT).
+Before using hmat-cache option, enable HMAT with -machine hmat=on.
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Signed-off-by: Liu Jingqi <jingqi.liu@intel.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-4-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+(cherry picked from commit c412a48d4d91e8f8b89aae02de0f44f1f0b729e5)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/core/numa.c        | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ include/sysemu/numa.h |  5 ++++
+ qapi/machine.json     | 81 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ qemu-options.hx       | 17 +++++++++--
+ 4 files changed, 179 insertions(+), 4 deletions(-)
+
+diff --git a/hw/core/numa.c b/hw/core/numa.c
+index 58fe713..0d1b4be 100644
+--- a/hw/core/numa.c
++++ b/hw/core/numa.c
+@@ -375,6 +375,73 @@ void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
+     g_array_append_val(hmat_lb->list, lb_data);
+ }
+ 
++void parse_numa_hmat_cache(MachineState *ms, NumaHmatCacheOptions *node,
++                           Error **errp)
++{
++    int nb_numa_nodes = ms->numa_state->num_nodes;
++    NodeInfo *numa_info = ms->numa_state->nodes;
++    NumaHmatCacheOptions *hmat_cache = NULL;
++
++    if (node->node_id >= nb_numa_nodes) {
++        error_setg(errp, "Invalid node-id=%" PRIu32 ", it should be less "
++                   "than %d", node->node_id, nb_numa_nodes);
++        return;
++    }
++
++    if (numa_info[node->node_id].lb_info_provided != (BIT(0) | BIT(1))) {
++        error_setg(errp, "The latency and bandwidth information of "
++                   "node-id=%" PRIu32 " should be provided before memory side "
++                   "cache attributes", node->node_id);
++        return;
++    }
++
++    if (node->level < 1 || node->level >= HMAT_LB_LEVELS) {
++        error_setg(errp, "Invalid level=%" PRIu8 ", it should be larger than 0 "
++                   "and less than or equal to %d", node->level,
++                   HMAT_LB_LEVELS - 1);
++        return;
++    }
++
++    assert(node->associativity < HMAT_CACHE_ASSOCIATIVITY__MAX);
++    assert(node->policy < HMAT_CACHE_WRITE_POLICY__MAX);
++    if (ms->numa_state->hmat_cache[node->node_id][node->level]) {
++        error_setg(errp, "Duplicate configuration of the side cache for "
++                   "node-id=%" PRIu32 " and level=%" PRIu8,
++                   node->node_id, node->level);
++        return;
++    }
++
++    if ((node->level > 1) &&
++        ms->numa_state->hmat_cache[node->node_id][node->level - 1] &&
++        (node->size >=
++            ms->numa_state->hmat_cache[node->node_id][node->level - 1]->size)) {
++        error_setg(errp, "Invalid size=%" PRIu64 ", the size of level=%" PRIu8
++                   " should be less than the size(%" PRIu64 ") of "
++                   "level=%u", node->size, node->level,
++                   ms->numa_state->hmat_cache[node->node_id]
++                                             [node->level - 1]->size,
++                   node->level - 1);
++        return;
++    }
++
++    if ((node->level < HMAT_LB_LEVELS - 1) &&
++        ms->numa_state->hmat_cache[node->node_id][node->level + 1] &&
++        (node->size <=
++            ms->numa_state->hmat_cache[node->node_id][node->level + 1]->size)) {
++        error_setg(errp, "Invalid size=%" PRIu64 ", the size of level=%" PRIu8
++                   " should be larger than the size(%" PRIu64 ") of "
++                   "level=%u", node->size, node->level,
++                   ms->numa_state->hmat_cache[node->node_id]
++                                             [node->level + 1]->size,
++                   node->level + 1);
++        return;
++    }
++
++    hmat_cache = g_malloc0(sizeof(*hmat_cache));
++    memcpy(hmat_cache, node, sizeof(*hmat_cache));
++    ms->numa_state->hmat_cache[node->node_id][node->level] = hmat_cache;
++}
++
+ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
+ {
+     Error *err = NULL;
+@@ -425,6 +492,19 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
+             goto end;
+         }
+         break;
++    case NUMA_OPTIONS_TYPE_HMAT_CACHE:
++        if (!ms->numa_state->hmat_enabled) {
++            error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
++                       "(HMAT) is disabled, enable it with -machine hmat=on "
++                       "before using any of hmat specific options");
++            return;
++        }
++
++        parse_numa_hmat_cache(ms, &object->u.hmat_cache, &err);
++        if (err) {
++            goto end;
++        }
++        break;
+     default:
+         abort();
+     }
+diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
+index 70f93c8..ba693cc 100644
+--- a/include/sysemu/numa.h
++++ b/include/sysemu/numa.h
+@@ -91,6 +91,9 @@ struct NumaState {
+ 
+     /* NUMA nodes HMAT Locality Latency and Bandwidth Information */
+     HMAT_LB_Info *hmat_lb[HMAT_LB_LEVELS][HMAT_LB_TYPES];
++
++    /* Memory Side Cache Information Structure */
++    NumaHmatCacheOptions *hmat_cache[MAX_NODES][HMAT_LB_LEVELS];
+ };
+ typedef struct NumaState NumaState;
+ 
+@@ -98,6 +101,8 @@ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
+ void parse_numa_opts(MachineState *ms);
+ void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
+                         Error **errp);
++void parse_numa_hmat_cache(MachineState *ms, NumaHmatCacheOptions *node,
++                           Error **errp);
+ void numa_complete_configuration(MachineState *ms);
+ void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms);
+ extern QemuOptsList qemu_numa_opts;
+diff --git a/qapi/machine.json b/qapi/machine.json
+index cf8faf5..b3d30bc 100644
+--- a/qapi/machine.json
++++ b/qapi/machine.json
+@@ -428,10 +428,12 @@
+ #
+ # @hmat-lb: memory latency and bandwidth information (Since: 5.0)
+ #
++# @hmat-cache: memory side cache information (Since: 5.0)
++#
+ # Since: 2.1
+ ##
+ { 'enum': 'NumaOptionsType',
+-  'data': [ 'node', 'dist', 'cpu', 'hmat-lb' ] }
++  'data': [ 'node', 'dist', 'cpu', 'hmat-lb', 'hmat-cache' ] }
+ 
+ ##
+ # @NumaOptions:
+@@ -447,7 +449,8 @@
+     'node': 'NumaNodeOptions',
+     'dist': 'NumaDistOptions',
+     'cpu': 'NumaCpuOptions',
+-    'hmat-lb': 'NumaHmatLBOptions' }}
++    'hmat-lb': 'NumaHmatLBOptions',
++    'hmat-cache': 'NumaHmatCacheOptions' }}
+ 
+ ##
+ # @NumaNodeOptions:
+@@ -647,6 +650,80 @@
+     '*bandwidth': 'size' }}
+ 
+ ##
++# @HmatCacheAssociativity:
++#
++# Cache associativity in the Memory Side Cache Information Structure
++# of HMAT
++#
++# For more information of @HmatCacheAssociativity, see chapter
++# 5.2.27.5: Table 5-147 of ACPI 6.3 spec.
++#
++# @none: None (no memory side cache in this proximity domain,
++#              or cache associativity unknown)
++#
++# @direct: Direct Mapped
++#
++# @complex: Complex Cache Indexing (implementation specific)
++#
++# Since: 5.0
++##
++{ 'enum': 'HmatCacheAssociativity',
++  'data': [ 'none', 'direct', 'complex' ] }
++
++##
++# @HmatCacheWritePolicy:
++#
++# Cache write policy in the Memory Side Cache Information Structure
++# of HMAT
++#
++# For more information of @HmatCacheWritePolicy, see chapter
++# 5.2.27.5: Table 5-147: Field "Cache Attributes" of ACPI 6.3 spec.
++#
++# @none: None (no memory side cache in this proximity domain,
++#              or cache write policy unknown)
++#
++# @write-back: Write Back (WB)
++#
++# @write-through: Write Through (WT)
++#
++# Since: 5.0
++##
++{ 'enum': 'HmatCacheWritePolicy',
++  'data': [ 'none', 'write-back', 'write-through' ] }
++
++##
++# @NumaHmatCacheOptions:
++#
++# Set the memory side cache information for a given memory domain.
++#
++# For more information of @NumaHmatCacheOptions, see chapter
++# 5.2.27.5: Table 5-147: Field "Cache Attributes" of ACPI 6.3 spec.
++#
++# @node-id: the memory proximity domain to which the memory belongs.
++#
++# @size: the size of memory side cache in bytes.
++#
++# @level: the cache level described in this structure.
++#
++# @associativity: the cache associativity,
++#         none/direct-mapped/complex(complex cache indexing).
++#
++# @policy: the write policy, none/write-back/write-through.
++#
++# @line: the cache Line size in bytes.
++#
++# Since: 5.0
++##
++{ 'struct': 'NumaHmatCacheOptions',
++  'data': {
++   'node-id': 'uint32',
++   'size': 'size',
++   'level': 'uint8',
++   'associativity': 'HmatCacheAssociativity',
++   'policy': 'HmatCacheWritePolicy',
++   'line': 'uint16' }}
++
++##
+ # @HostMemPolicy:
+ #
+ # Host memory policy types
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 86d9d8a..8fe05b6 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -169,7 +169,8 @@ DEF("numa", HAS_ARG, QEMU_OPTION_numa,
+     "-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
+     "-numa dist,src=source,dst=destination,val=distance\n"
+     "-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]\n"
+-    "-numa hmat-lb,initiator=node,target=node,hierarchy=memory|first-level|second-level|third-level,data-type=access-latency|read-latency|write-latency[,latency=lat][,bandwidth=bw]\n",
++    "-numa hmat-lb,initiator=node,target=node,hierarchy=memory|first-level|second-level|third-level,data-type=access-latency|read-latency|write-latency[,latency=lat][,bandwidth=bw]\n"
++    "-numa hmat-cache,node-id=node,size=size,level=level[,associativity=none|direct|complex][,policy=none|write-back|write-through][,line=size]\n",
+     QEMU_ARCH_ALL)
+ STEXI
+ @item -numa node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}][,initiator=@var{initiator}]
+@@ -177,6 +178,7 @@ STEXI
+ @itemx -numa dist,src=@var{source},dst=@var{destination},val=@var{distance}
+ @itemx -numa cpu,node-id=@var{node}[,socket-id=@var{x}][,core-id=@var{y}][,thread-id=@var{z}]
+ @itemx -numa hmat-lb,initiator=@var{node},target=@var{node},hierarchy=@var{hierarchy},data-type=@var{tpye}[,latency=@var{lat}][,bandwidth=@var{bw}]
++@itemx -numa hmat-cache,node-id=@var{node},size=@var{size},level=@var{level}[,associativity=@var{str}][,policy=@var{str}][,line=@var{size}]
+ @findex -numa
+ Define a NUMA node and assign RAM and VCPUs to it.
+ Set the NUMA distance from a source node to a destination node.
+@@ -280,11 +282,20 @@ NUM byte per second (or MB/s, GB/s or TB/s depending on used suffix).
+ Note that if latency or bandwidth value is 0, means the corresponding latency or
+ bandwidth information is not provided.
+ 
++In @samp{hmat-cache} option, @var{node-id} is the NUMA-id of the memory belongs.
++@var{size} is the size of memory side cache in bytes. @var{level} is the cache
++level described in this structure, note that the cache level 0 should not be used
++with @samp{hmat-cache} option. @var{associativity} is the cache associativity,
++the possible value is 'none/direct(direct-mapped)/complex(complex cache indexing)'.
++@var{policy} is the write policy. @var{line} is the cache Line size in bytes.
++
+ For example, the following options describe 2 NUMA nodes. Node 0 has 2 cpus and
+ a ram, node 1 has only a ram. The processors in node 0 access memory in node
+ 0 with access-latency 5 nanoseconds, access-bandwidth is 200 MB/s;
+ The processors in NUMA node 0 access memory in NUMA node 1 with access-latency 10
+ nanoseconds, access-bandwidth is 100 MB/s.
++And for memory side cache information, NUMA node 0 and 1 both have 1 level memory
++cache, size is 10KB, policy is write-back, the cache Line size is 8 bytes:
+ @example
+ -machine hmat=on \
+ -m 2G \
+@@ -298,7 +309,9 @@ nanoseconds, access-bandwidth is 100 MB/s.
+ -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5 \
+ -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M \
+ -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10 \
+--numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M
++-numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M \
++-numa hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8 \
++-numa hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
+ @end example
+ 
+ ETEXI
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-numa-properly-check-if-numa-is-supported.patch b/SOURCES/kvm-numa-properly-check-if-numa-is-supported.patch
new file mode 100644
index 0000000..c602256
--- /dev/null
+++ b/SOURCES/kvm-numa-properly-check-if-numa-is-supported.patch
@@ -0,0 +1,81 @@
+From e3a1c2ff0d7b930b1782d59d093fd15471d3aee1 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:46 +0100
+Subject: [PATCH 03/12] numa: properly check if numa is supported
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-3-plai@redhat.com>
+Patchwork-id: 96732
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 02/11] numa: properly check if numa is supported
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Igor Mammedov <imammedo@redhat.com>
+
+Commit aa57020774b, by mistake used MachineClass::numa_mem_supported
+to check if NUMA is supported by machine and also as unrelated change
+set it to true for sbsa-ref board.
+
+Luckily change didn't break machines that support NUMA, as the field
+is set to true for them.
+
+But the field is not intended for checking if NUMA is supported and
+will be flipped to false within this release for new machine types.
+
+Fix it:
+ - by using previously used condition
+      !mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id
+   the first time and then use MachineState::numa_state down the road
+   to check if NUMA is supported
+ - dropping stray sbsa-ref chunk
+
+Fixes: aa57020774b690a22be72453b8e91c9b5a68c516
+Signed-off-by: Igor Mammedov <imammedo@redhat.com>
+Message-Id: <1576154936-178362-3-git-send-email-imammedo@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit fcd3f2cc124600385dba46c69a80626985c15b50)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/arm/sbsa-ref.c | 1 -
+ hw/core/machine.c | 4 ++--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
+index 27046cc..c6261d4 100644
+--- a/hw/arm/sbsa-ref.c
++++ b/hw/arm/sbsa-ref.c
+@@ -791,7 +791,6 @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
+     mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids;
+     mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props;
+     mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id;
+-    mc->numa_mem_supported = true;
+ }
+ 
+ static const TypeInfo sbsa_ref_info = {
+diff --git a/hw/core/machine.c b/hw/core/machine.c
+index 5a025d1..19c78c6 100644
+--- a/hw/core/machine.c
++++ b/hw/core/machine.c
+@@ -1128,7 +1128,7 @@ static void machine_initfn(Object *obj)
+                                         NULL);
+     }
+ 
+-    if (mc->numa_mem_supported) {
++    if (mc->cpu_index_to_instance_props && mc->get_default_cpu_node_id) {
+         ms->numa_state = g_new0(NumaState, 1);
+     }
+ 
+@@ -1272,7 +1272,7 @@ void machine_run_board_init(MachineState *machine)
+ {
+     MachineClass *machine_class = MACHINE_GET_CLASS(machine);
+ 
+-    if (machine_class->numa_mem_supported) {
++    if (machine->numa_state) {
+         numa_complete_configuration(machine);
+         if (machine->numa_state->num_nodes) {
+             machine_numa_finish_cpu_init(machine);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-numa-remove-not-needed-check.patch b/SOURCES/kvm-numa-remove-not-needed-check.patch
new file mode 100644
index 0000000..cbe677f
--- /dev/null
+++ b/SOURCES/kvm-numa-remove-not-needed-check.patch
@@ -0,0 +1,59 @@
+From 348115bbd0d60fada6f7d9fa27848044690a4bc3 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:45 +0100
+Subject: [PATCH 02/12] numa: remove not needed check
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-2-plai@redhat.com>
+Patchwork-id: 96738
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 01/11] numa: remove not needed check
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Igor Mammedov <imammedo@redhat.com>
+
+Currently parse_numa_node() is always called from already numa
+enabled context.
+Drop unnecessary check if numa is supported.
+
+Signed-off-by: Igor Mammedov <imammedo@redhat.com>
+Message-Id: <1576154936-178362-2-git-send-email-imammedo@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 5275db59aa7ff8a26bd6aa5d07cb4d53de5cfab5)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/core/numa.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/hw/core/numa.c b/hw/core/numa.c
+index e3332a9..19f082d 100644
+--- a/hw/core/numa.c
++++ b/hw/core/numa.c
+@@ -83,10 +83,6 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
+         return;
+     }
+ 
+-    if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
+-        error_setg(errp, "NUMA is not supported by this machine-type");
+-        return;
+-    }
+     for (cpus = node->cpus; cpus; cpus = cpus->next) {
+         CpuInstanceProperties props;
+         if (cpus->value >= max_cpus) {
+@@ -178,9 +174,8 @@ void parse_numa_distance(MachineState *ms, NumaDistOptions *dist, Error **errp)
+ void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
+ {
+     Error *err = NULL;
+-    MachineClass *mc = MACHINE_GET_CLASS(ms);
+ 
+-    if (!mc->numa_mem_supported) {
++    if (!ms->numa_state) {
+         error_setg(errp, "NUMA is not supported by this machine-type");
+         goto end;
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-pc-bios-s390x-Fix-reset-psw-mask.patch b/SOURCES/kvm-pc-bios-s390x-Fix-reset-psw-mask.patch
new file mode 100644
index 0000000..9c45e92
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390x-Fix-reset-psw-mask.patch
@@ -0,0 +1,75 @@
+From 38ba55dd27a3b8308f0ce2e82a4c3eba3f197d20 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:53 -0400
+Subject: [PATCH 11/42] pc-bios/s390x: Fix reset psw mask
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-12-thuth@redhat.com>
+Patchwork-id: 97034
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 11/38] pc-bios/s390x: Fix reset psw mask
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+We need to set the short psw indication bit in the reset psw, as it is
+a short psw.
+
+Exposed by "s390x: Properly fetch and test the short psw on diag308
+subc 0/1".
+
+Fixes: 962982329029 ("pc-bios/s390-ccw: do a subsystem reset before running the guest")
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Message-Id: <20191203132813.2734-5-frankja@linux.ibm.com>
+Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 5c6f0d5f46a77d77460dfb518cf1e1e4145c276e)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/jump2ipl.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
+index 266f1502b9..da13c43cc0 100644
+--- a/pc-bios/s390-ccw/jump2ipl.c
++++ b/pc-bios/s390-ccw/jump2ipl.c
+@@ -12,11 +12,11 @@
+ #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 PSW_MASK_SHORTPSW 0x0008000000000000ULL
++#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_32 | PSW_MASK_64)
+ 
+ typedef struct ResetInfo {
+-    uint32_t ipl_mask;
+-    uint32_t ipl_addr;
++    uint64_t ipl_psw;
+     uint32_t ipl_continue;
+ } ResetInfo;
+ 
+@@ -50,7 +50,9 @@ void jump_to_IPL_code(uint64_t address)
+     ResetInfo *current = 0;
+ 
+     save = *current;
+-    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
++
++    current->ipl_psw = (uint64_t) &jump_to_IPL_2;
++    current->ipl_psw |= RESET_PSW_MASK;
+     current->ipl_continue = address & 0x7fffffff;
+ 
+     debug_print_int("set IPL addr to", current->ipl_continue);
+@@ -82,7 +84,7 @@ void jump_to_low_kernel(void)
+     }
+ 
+     /* Trying to get PSW at zero address */
+-    if (*((uint64_t *)0) & IPL_PSW_MASK) {
++    if (*((uint64_t *)0) & RESET_PSW_MASK) {
+         jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
+     }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-pc-bios-s390x-Save-iplb-location-in-lowcore.patch b/SOURCES/kvm-pc-bios-s390x-Save-iplb-location-in-lowcore.patch
new file mode 100644
index 0000000..2db2f93
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390x-Save-iplb-location-in-lowcore.patch
@@ -0,0 +1,145 @@
+From 8350ad9c0f54519a06ec396c2997330615f4b470 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:58 -0400
+Subject: [PATCH 16/42] pc-bios: s390x: Save iplb location in lowcore
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-17-thuth@redhat.com>
+Patchwork-id: 97027
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 16/38] pc-bios: s390x: Save iplb location in lowcore
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+The POP states that for a list directed IPL the IPLB is stored into
+memory by the machine loader and its address is stored at offset 0x14
+of the lowcore.
+
+ZIPL currently uses the address in offset 0x14 to access the IPLB and
+acquire flags about secure boot. If the IPLB address points into
+memory which has an unsupported mix of flags set, ZIPL will panic
+instead of booting the OS.
+
+As the lowcore can have quite a high entropy for a guest that did drop
+out of protected mode (i.e. rebooted) we encountered the ZIPL panic
+quite often.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Message-Id: <20200304114231.23493-19-frankja@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+(cherry picked from commit 9bfc04f9ef6802fff0fc77130ff345a541783363)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/jump2ipl.c  |  1 +
+ pc-bios/s390-ccw/main.c      |  8 +++++++-
+ pc-bios/s390-ccw/netmain.c   |  1 +
+ pc-bios/s390-ccw/s390-arch.h | 10 ++++++++--
+ pc-bios/s390-ccw/s390-ccw.h  |  1 +
+ 5 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
+index da13c43cc0..4eba2510b0 100644
+--- a/pc-bios/s390-ccw/jump2ipl.c
++++ b/pc-bios/s390-ccw/jump2ipl.c
+@@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
+ {
+     /* store the subsystem information _after_ the bootmap was loaded */
+     write_subsystem_identification();
++    write_iplb_location();
+ 
+     /* prevent unknown IPL types in the guest */
+     if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
+diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
+index a21b386280..4e65b411e1 100644
+--- a/pc-bios/s390-ccw/main.c
++++ b/pc-bios/s390-ccw/main.c
+@@ -9,6 +9,7 @@
+  */
+ 
+ #include "libc.h"
++#include "helper.h"
+ #include "s390-arch.h"
+ #include "s390-ccw.h"
+ #include "cio.h"
+@@ -22,7 +23,7 @@ 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 */
++LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
+ 
+ #define LOADPARM_PROMPT "PROMPT  "
+ #define LOADPARM_EMPTY  "        "
+@@ -42,6 +43,11 @@ void write_subsystem_identification(void)
+     *zeroes = 0;
+ }
+ 
++void write_iplb_location(void)
++{
++    lowcore->ptr_iplb = ptr2u32(&iplb);
++}
++
+ void panic(const char *string)
+ {
+     sclp_print(string);
+diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
+index f2dcc01e27..309ffa30d9 100644
+--- a/pc-bios/s390-ccw/netmain.c
++++ b/pc-bios/s390-ccw/netmain.c
+@@ -40,6 +40,7 @@
+ #define DEFAULT_TFTP_RETRIES 20
+ 
+ extern char _start[];
++void write_iplb_location(void) {}
+ 
+ #define KERNEL_ADDR             ((void *)0L)
+ #define KERNEL_MAX_SIZE         ((long)_start)
+diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
+index 504fc7c2f0..5f36361c02 100644
+--- a/pc-bios/s390-ccw/s390-arch.h
++++ b/pc-bios/s390-ccw/s390-arch.h
+@@ -36,7 +36,13 @@ typedef struct LowCore {
+     /* prefix area: defined by architecture */
+     PSWLegacy       ipl_psw;                  /* 0x000 */
+     uint32_t        ccw1[2];                  /* 0x008 */
+-    uint32_t        ccw2[2];                  /* 0x010 */
++    union {
++        uint32_t        ccw2[2];                  /* 0x010 */
++        struct {
++            uint32_t reserved10;
++            uint32_t ptr_iplb;
++        };
++    };
+     uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
+     uint32_t        ext_params;               /* 0x080 */
+     uint16_t        cpu_addr;                 /* 0x084 */
+@@ -85,7 +91,7 @@ typedef struct LowCore {
+     PSW             io_new_psw;               /* 0x1f0 */
+ } __attribute__((packed, aligned(8192))) LowCore;
+ 
+-extern LowCore const *lowcore;
++extern LowCore *lowcore;
+ 
+ static inline void set_prefix(uint32_t address)
+ {
+diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
+index 11bce7d73c..21f27e7990 100644
+--- a/pc-bios/s390-ccw/s390-ccw.h
++++ b/pc-bios/s390-ccw/s390-ccw.h
+@@ -57,6 +57,7 @@ void consume_io_int(void);
+ /* main.c */
+ void panic(const char *string);
+ void write_subsystem_identification(void);
++void write_iplb_location(void);
+ extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+ unsigned int get_loadparm_index(void);
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-pcie_root_port-Add-hotplug-disabling-option.patch b/SOURCES/kvm-pcie_root_port-Add-hotplug-disabling-option.patch
new file mode 100644
index 0000000..57f3c3b
--- /dev/null
+++ b/SOURCES/kvm-pcie_root_port-Add-hotplug-disabling-option.patch
@@ -0,0 +1,153 @@
+From 8587278a20283851081d4d282d11ef6bafd17dc2 Mon Sep 17 00:00:00 2001
+From: Julia Suvorova <jusual@redhat.com>
+Date: Tue, 17 Mar 2020 13:56:39 -0400
+Subject: [PATCH 1/2] pcie_root_port: Add hotplug disabling option
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Julia Suvorova <jusual@redhat.com>
+Message-id: <20200317135639.65085-1-jusual@redhat.com>
+Patchwork-id: 94367
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/1] pcie_root_port: Add hotplug disabling option
+Bugzilla: 1790899
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1790899
+BRANCH: rhel-av-8.2.1
+UPSTREAM: merged
+BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=27302449
+
+Make hot-plug/hot-unplug on PCIe Root Ports optional to allow libvirt
+manage it and restrict unplug for the whole machine. This is going to
+prevent user-initiated unplug in guests (Windows mostly).
+Hotplug is enabled by default.
+Usage:
+    -device pcie-root-port,hotplug=off,...
+
+If you want to disable hot-unplug on some downstream ports of one
+switch, disable hot-unplug on PCIe Root Port connected to the upstream
+port as well as on the selected downstream ports.
+
+Discussion related:
+    https://lists.gnu.org/archive/html/qemu-devel/2020-02/msg00530.html
+
+Signed-off-by: Julia Suvorova <jusual@redhat.com>
+Message-Id: <20200226174607.205941-1-jusual@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 530a0963184e57e71a5b538e9161f115df533e96)
+Signed-off-by: Jon Maloy <jmaloy.redhat.com>
+---
+ hw/pci-bridge/pcie_root_port.c     |  2 +-
+ hw/pci-bridge/xio3130_downstream.c |  2 +-
+ hw/pci/pcie.c                      | 11 +++++++----
+ hw/pci/pcie_port.c                 |  1 +
+ include/hw/pci/pcie.h              |  2 +-
+ include/hw/pci/pcie_port.h         |  3 +++
+ 6 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
+index 012c2cb12c..db80e2ec23 100644
+--- a/hw/pci-bridge/pcie_root_port.c
++++ b/hw/pci-bridge/pcie_root_port.c
+@@ -94,7 +94,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
+ 
+     pcie_cap_arifwd_init(d);
+     pcie_cap_deverr_init(d);
+-    pcie_cap_slot_init(d, s->slot);
++    pcie_cap_slot_init(d, s);
+     pcie_cap_root_init(d);
+ 
+     pcie_chassis_create(s->chassis);
+diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
+index a9f084b863..4489ce4a40 100644
+--- a/hw/pci-bridge/xio3130_downstream.c
++++ b/hw/pci-bridge/xio3130_downstream.c
+@@ -94,7 +94,7 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
+     }
+     pcie_cap_flr_init(d);
+     pcie_cap_deverr_init(d);
+-    pcie_cap_slot_init(d, s->slot);
++    pcie_cap_slot_init(d, s);
+     pcie_cap_arifwd_init(d);
+ 
+     pcie_chassis_create(s->chassis);
+diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
+index 08718188bb..0eb3a2a5d2 100644
+--- a/hw/pci/pcie.c
++++ b/hw/pci/pcie.c
+@@ -495,7 +495,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
+ 
+ /* pci express slot for pci express root/downstream port
+    PCI express capability slot registers */
+-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
++void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
+ {
+     uint32_t pos = dev->exp.exp_cap;
+ 
+@@ -505,13 +505,16 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
+     pci_long_test_and_clear_mask(dev->config + pos + PCI_EXP_SLTCAP,
+                                  ~PCI_EXP_SLTCAP_PSN);
+     pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
+-                               (slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
++                               (s->slot << PCI_EXP_SLTCAP_PSN_SHIFT) |
+                                PCI_EXP_SLTCAP_EIP |
+-                               PCI_EXP_SLTCAP_HPS |
+-                               PCI_EXP_SLTCAP_HPC |
+                                PCI_EXP_SLTCAP_PIP |
+                                PCI_EXP_SLTCAP_AIP |
+                                PCI_EXP_SLTCAP_ABP);
++    if (s->hotplug) {
++        pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
++                                   PCI_EXP_SLTCAP_HPS |
++                                   PCI_EXP_SLTCAP_HPC);
++    }
+ 
+     if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {
+         pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
+diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
+index c19a9be592..36dac33d98 100644
+--- a/hw/pci/pcie_port.c
++++ b/hw/pci/pcie_port.c
+@@ -147,6 +147,7 @@ static const TypeInfo pcie_port_type_info = {
+ static Property pcie_slot_props[] = {
+     DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
+     DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
++    DEFINE_PROP_BOOL("hotplug", PCIESlot, hotplug, true),
+     DEFINE_PROP_END_OF_LIST()
+ };
+ 
+diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
+index 7064875835..14c58ebdb6 100644
+--- a/include/hw/pci/pcie.h
++++ b/include/hw/pci/pcie.h
+@@ -104,7 +104,7 @@ void pcie_cap_deverr_reset(PCIDevice *dev);
+ void pcie_cap_lnkctl_init(PCIDevice *dev);
+ void pcie_cap_lnkctl_reset(PCIDevice *dev);
+ 
+-void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
++void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s);
+ void pcie_cap_slot_reset(PCIDevice *dev);
+ void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_ctl, uint16_t *slt_sta);
+ void pcie_cap_slot_write_config(PCIDevice *dev,
+diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
+index 7515430087..7072cc8731 100644
+--- a/include/hw/pci/pcie_port.h
++++ b/include/hw/pci/pcie_port.h
+@@ -55,6 +55,9 @@ struct PCIESlot {
+ 
+     /* Disable ACS (really for a pcie_root_port) */
+     bool        disable_acs;
++
++    /* Indicates whether hot-plug is enabled on the slot */
++    bool        hotplug;
+     QLIST_ENTRY(PCIESlot) next;
+ };
+ 
+-- 
+2.18.2
+
diff --git a/SOURCES/kvm-qcow2-Expose-bitmaps-size-during-measure.patch b/SOURCES/kvm-qcow2-Expose-bitmaps-size-during-measure.patch
new file mode 100644
index 0000000..48c15c5
--- /dev/null
+++ b/SOURCES/kvm-qcow2-Expose-bitmaps-size-during-measure.patch
@@ -0,0 +1,495 @@
+From af4d66e07c86d7593f7d18ae4b6a2151123b529b Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:17 +0100
+Subject: [PATCH 12/26] qcow2: Expose bitmaps' size during measure
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-10-eblake@redhat.com>
+Patchwork-id: 97072
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 09/12] qcow2: Expose bitmaps' size during measure
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+It's useful to know how much space can be occupied by qcow2 persistent
+bitmaps, even though such metadata is unrelated to the guest-visible
+data.  Report this value as an additional QMP field, present when
+measuring an existing image and output format that both support
+bitmaps.  Update iotest 178 and 190 to updated output, as well as new
+coverage in 190 demonstrating non-zero values made possible with the
+recently-added qemu-img bitmap command (see 3b51ab4b).
+
+The new 'bitmaps size:' field is displayed automatically as part of
+'qemu-img measure' any time it is present in QMP (that is, any time
+both the source image being measured and destination format support
+bitmaps, even if the measurement is 0 because there are no bitmaps
+present).  If the field is absent, it means that no bitmaps can be
+copied (source, destination, or both lack bitmaps, including when
+measuring based on size rather than on a source image).  This behavior
+is compatible with an upcoming patch adding 'qemu-img convert
+--bitmaps': that command will fail in the same situations where this
+patch omits the field.
+
+The addition of a new field demonstrates why we should always
+zero-initialize qapi C structs; while the qcow2 driver still fully
+populates all fields, the raw and crypto drivers had to be tweaked to
+avoid uninitialized data.
+
+Consideration was also given towards having a 'qemu-img measure
+--bitmaps' which errors out when bitmaps are not possible, and
+otherwise sums the bitmaps into the existing allocation totals rather
+than displaying as a separate field, as a potential convenience
+factor.  But this was ultimately decided to be more complexity than
+necessary when the QMP interface was sufficient enough with bitmaps
+remaining a separate field.
+
+See also: https://bugzilla.redhat.com/1779904
+
+Reported-by: Nir Soffer <nsoffer@redhat.com>
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200521192137.1120211-3-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit 5d72c68b49769c927e90b78af6d90f6a384b26ac)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	block/crypto.c - commit a9da6e49 not present (no measure support)
+	docs/tools/qemu-img.rst - changes in qemu-img.texi instead
+Signed-off-by: Eric Blake <eblake@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/qcow2-bitmap.c             | 36 ++++++++++++++++++++++++++++++
+ block/qcow2.c                    | 14 +++++++++---
+ block/qcow2.h                    |  2 ++
+ block/raw-format.c               |  2 +-
+ qapi/block-core.json             | 16 +++++++++-----
+ qemu-img.c                       |  3 +++
+ qemu-img.texi                    |  7 ++++++
+ tests/qemu-iotests/178.out.qcow2 | 16 ++++++++++++++
+ tests/qemu-iotests/190           | 47 ++++++++++++++++++++++++++++++++++++++--
+ tests/qemu-iotests/190.out       | 27 ++++++++++++++++++++++-
+ 10 files changed, 158 insertions(+), 12 deletions(-)
+
+diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
+index cbac905..10d1297 100644
+--- a/block/qcow2-bitmap.c
++++ b/block/qcow2-bitmap.c
+@@ -1766,3 +1766,39 @@ bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs)
+ 
+     return s->qcow_version >= 3;
+ }
++
++/*
++ * Compute the space required for bitmaps in @bs.
++ *
++ * The computation is based as if copying to a new image with the
++ * given @cluster_size, which may differ from the cluster size in @bs.
++ */
++uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
++                                                uint32_t cluster_size)
++{
++    uint64_t bitmaps_size = 0;
++    BdrvDirtyBitmap *bm;
++    size_t bitmap_dir_size = 0;
++
++    FOR_EACH_DIRTY_BITMAP(bs, bm) {
++        if (bdrv_dirty_bitmap_get_persistence(bm)) {
++            const char *name = bdrv_dirty_bitmap_name(bm);
++            uint32_t granularity = bdrv_dirty_bitmap_granularity(bm);
++            uint64_t bmbytes =
++                get_bitmap_bytes_needed(bdrv_dirty_bitmap_size(bm),
++                                        granularity);
++            uint64_t bmclusters = DIV_ROUND_UP(bmbytes, cluster_size);
++
++            /* Assume the entire bitmap is allocated */
++            bitmaps_size += bmclusters * cluster_size;
++            /* Also reserve space for the bitmap table entries */
++            bitmaps_size += ROUND_UP(bmclusters * sizeof(uint64_t),
++                                     cluster_size);
++            /* And space for contribution to bitmap directory size */
++            bitmap_dir_size += calc_dir_entry_size(strlen(name), 0);
++        }
++    }
++    bitmaps_size += ROUND_UP(bitmap_dir_size, cluster_size);
++
++    return bitmaps_size;
++}
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 36b0f7d..dbd870a 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -4751,16 +4751,24 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
+         required = virtual_size;
+     }
+ 
+-    info = g_new(BlockMeasureInfo, 1);
++    info = g_new0(BlockMeasureInfo, 1);
+     info->fully_allocated =
+         qcow2_calc_prealloc_size(virtual_size, cluster_size,
+                                  ctz32(refcount_bits)) + luks_payload_size;
+ 
+-    /* Remove data clusters that are not required.  This overestimates the
++    /*
++     * Remove data clusters that are not required.  This overestimates the
+      * required size because metadata needed for the fully allocated file is
+-     * still counted.
++     * still counted.  Show bitmaps only if both source and destination
++     * would support them.
+      */
+     info->required = info->fully_allocated - virtual_size + required;
++    info->has_bitmaps = version >= 3 && in_bs &&
++        bdrv_supports_persistent_dirty_bitmap(in_bs);
++    if (info->has_bitmaps) {
++        info->bitmaps = qcow2_get_persistent_dirty_bitmap_size(in_bs,
++                                                               cluster_size);
++    }
+     return info;
+ 
+ err:
+diff --git a/block/qcow2.h b/block/qcow2.h
+index ceb1ceb..3297e6b 100644
+--- a/block/qcow2.h
++++ b/block/qcow2.h
+@@ -768,6 +768,8 @@ int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
+                                             const char *name,
+                                             Error **errp);
+ bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
++uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
++                                                uint32_t cluster_size);
+ 
+ ssize_t coroutine_fn
+ qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
+diff --git a/block/raw-format.c b/block/raw-format.c
+index 93b25e1..4bb54f4 100644
+--- a/block/raw-format.c
++++ b/block/raw-format.c
+@@ -346,7 +346,7 @@ static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs,
+                             BDRV_SECTOR_SIZE);
+     }
+ 
+-    info = g_new(BlockMeasureInfo, 1);
++    info = g_new0(BlockMeasureInfo, 1);
+     info->required = required;
+ 
+     /* Unallocated sectors count towards the file size in raw images */
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index a64ad81..2893209 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -689,18 +689,24 @@
+ # efficiently so file size may be smaller than virtual disk size.
+ #
+ # The values are upper bounds that are guaranteed to fit the new image file.
+-# Subsequent modification, such as internal snapshot or bitmap creation, may
+-# require additional space and is not covered here.
++# Subsequent modification, such as internal snapshot or further bitmap
++# creation, may require additional space and is not covered here.
+ #
+-# @required: Size required for a new image file, in bytes.
++# @required: Size required for a new image file, in bytes, when copying just
++#            allocated guest-visible contents.
+ #
+ # @fully-allocated: Image file size, in bytes, once data has been written
+-#                   to all sectors.
++#                   to all sectors, when copying just guest-visible contents.
++#
++# @bitmaps: Additional size required if all the top-level bitmap metadata
++#           in the source image were to be copied to the destination,
++#           present only when source and destination both support
++#           persistent bitmaps. (since 5.1)
+ #
+ # Since: 2.10
+ ##
+ { 'struct': 'BlockMeasureInfo',
+-  'data': {'required': 'int', 'fully-allocated': 'int'} }
++  'data': {'required': 'int', 'fully-allocated': 'int', '*bitmaps': 'int'} }
+ 
+ ##
+ # @query-block:
+diff --git a/qemu-img.c b/qemu-img.c
+index 11a4537..b57856e 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -5212,6 +5212,9 @@ static int img_measure(int argc, char **argv)
+     if (output_format == OFORMAT_HUMAN) {
+         printf("required size: %" PRIu64 "\n", info->required);
+         printf("fully allocated size: %" PRIu64 "\n", info->fully_allocated);
++        if (info->has_bitmaps) {
++            printf("bitmaps size: %" PRIu64 "\n", info->bitmaps);
++        }
+     } else {
+         dump_json_block_measure_info(info);
+     }
+diff --git a/qemu-img.texi b/qemu-img.texi
+index abf2771..3670b96 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -576,6 +576,7 @@ The following fields are reported:
+ @example
+ required size: 524288
+ fully allocated size: 1074069504
++bitmaps size: 0
+ @end example
+ 
+ The @code{required size} is the file size of the new image.  It may be smaller
+@@ -586,6 +587,12 @@ been written to all sectors.  This is the maximum size that the image file can
+ occupy with the exception of internal snapshots, dirty bitmaps, vmstate data,
+ and other advanced image format features.
+ 
++The @code{bitmaps size} is the additional size required in order to
++copy bitmaps from a source image in addition to the guest-visible
++data; the line is omitted if either source or destination lacks
++bitmap support, or 0 if bitmaps are supported but there is nothing to
++copy.
++
+ @item snapshot [--object @var{objectdef}] [--image-opts] [-U] [-q] [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename}
+ 
+ List, apply, create or delete snapshots in image @var{filename}.
+diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
+index 345eab3..b9ed41b 100644
+--- a/tests/qemu-iotests/178.out.qcow2
++++ b/tests/qemu-iotests/178.out.qcow2
+@@ -37,6 +37,7 @@ qemu-img: The image size is too large (try using a larger cluster size)
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
+ required size: 196608
+ fully allocated size: 196608
++bitmaps size: 0
+ 
+ converted image file size in bytes: 196608
+ 
+@@ -45,6 +46,7 @@ converted image file size in bytes: 196608
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+ required size: 393216
+ fully allocated size: 1074135040
++bitmaps size: 0
+ wrote 512/512 bytes at offset 512
+ 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ wrote 65536/65536 bytes at offset 65536
+@@ -53,6 +55,7 @@ wrote 64512/64512 bytes at offset 134217728
+ 63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ required size: 589824
+ fully allocated size: 1074135040
++bitmaps size: 0
+ 
+ converted image file size in bytes: 524288
+ 
+@@ -60,6 +63,7 @@ converted image file size in bytes: 524288
+ 
+ required size: 524288
+ fully allocated size: 1074135040
++bitmaps size: 0
+ 
+ converted image file size in bytes: 458752
+ 
+@@ -67,16 +71,19 @@ converted image file size in bytes: 458752
+ 
+ required size: 1074135040
+ fully allocated size: 1074135040
++bitmaps size: 0
+ 
+ == qcow2 input image and LUKS encryption ==
+ 
+ required size: 2686976
+ fully allocated size: 1076232192
++bitmaps size: 0
+ 
+ == qcow2 input image and preallocation (human) ==
+ 
+ required size: 1074135040
+ fully allocated size: 1074135040
++bitmaps size: 0
+ 
+ converted image file size in bytes: 1074135040
+ 
+@@ -87,6 +94,7 @@ wrote 8388608/8388608 bytes at offset 0
+ 8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ required size: 8716288
+ fully allocated size: 8716288
++bitmaps size: 0
+ 
+ converted image file size in bytes: 8716288
+ 
+@@ -173,6 +181,7 @@ qemu-img: The image size is too large (try using a larger cluster size)
+ 
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
+ {
++    "bitmaps": 0,
+     "required": 196608,
+     "fully-allocated": 196608
+ }
+@@ -183,6 +192,7 @@ converted image file size in bytes: 196608
+ 
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+ {
++    "bitmaps": 0,
+     "required": 393216,
+     "fully-allocated": 1074135040
+ }
+@@ -193,6 +203,7 @@ wrote 65536/65536 bytes at offset 65536
+ wrote 64512/64512 bytes at offset 134217728
+ 63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ {
++    "bitmaps": 0,
+     "required": 589824,
+     "fully-allocated": 1074135040
+ }
+@@ -202,6 +213,7 @@ converted image file size in bytes: 524288
+ == qcow2 input image with internal snapshot (json) ==
+ 
+ {
++    "bitmaps": 0,
+     "required": 524288,
+     "fully-allocated": 1074135040
+ }
+@@ -211,6 +223,7 @@ converted image file size in bytes: 458752
+ == qcow2 input image and a backing file (json) ==
+ 
+ {
++    "bitmaps": 0,
+     "required": 1074135040,
+     "fully-allocated": 1074135040
+ }
+@@ -218,6 +231,7 @@ converted image file size in bytes: 458752
+ == qcow2 input image and LUKS encryption ==
+ 
+ {
++    "bitmaps": 0,
+     "required": 2686976,
+     "fully-allocated": 1076232192
+ }
+@@ -225,6 +239,7 @@ converted image file size in bytes: 458752
+ == qcow2 input image and preallocation (json) ==
+ 
+ {
++    "bitmaps": 0,
+     "required": 1074135040,
+     "fully-allocated": 1074135040
+ }
+@@ -237,6 +252,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608
+ wrote 8388608/8388608 bytes at offset 0
+ 8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+ {
++    "bitmaps": 0,
+     "required": 8716288,
+     "fully-allocated": 8716288
+ }
+diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
+index eb766ad..5084ccd 100755
+--- a/tests/qemu-iotests/190
++++ b/tests/qemu-iotests/190
+@@ -2,7 +2,7 @@
+ #
+ # qemu-img measure sub-command tests on huge qcow2 files
+ #
+-# Copyright (C) 2017 Red Hat, Inc.
++# Copyright (C) 2017-2020 Red Hat, Inc.
+ #
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+@@ -42,7 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
+ _supported_fmt qcow2
+ _supported_proto file
+ 
+-echo "== Huge file =="
++echo "== Huge file without bitmaps =="
+ echo
+ 
+ IMGOPTS='cluster_size=2M' _make_test_img 2T
+@@ -51,6 +51,49 @@ $QEMU_IMG measure -O raw -f qcow2 "$TEST_IMG"
+ $QEMU_IMG measure -O qcow2 -o cluster_size=64k -f qcow2 "$TEST_IMG"
+ $QEMU_IMG measure -O qcow2 -o cluster_size=2M -f qcow2 "$TEST_IMG"
+ 
++echo
++echo "== Huge file with bitmaps =="
++echo
++
++$QEMU_IMG bitmap --add --granularity 512 -f qcow2 "$TEST_IMG" b1
++$QEMU_IMG bitmap --add -g 2M -f qcow2 "$TEST_IMG" b2
++
++# No bitmap without a source
++$QEMU_IMG measure -O qcow2 --size 10M
++# No bitmap output, since raw does not support it
++$QEMU_IMG measure -O raw -f qcow2 "$TEST_IMG"
++# No bitmap output, since no bitmaps on raw source. Munge required size, as
++# some filesystems store the qcow2 file with less sparseness than others
++$QEMU_IMG measure -O qcow2 -f raw "$TEST_IMG" |
++    sed '/^required size:/ s/[0-9][0-9]*/SIZE/'
++# No bitmap output, since v2 does not support it
++$QEMU_IMG measure -O qcow2 -o compat=0.10 -f qcow2 "$TEST_IMG"
++
++# Compute expected output: bitmap clusters + bitmap tables + bitmaps directory
++echo
++val2T=$((2*1024*1024*1024*1024))
++cluster=$((64*1024))
++b1clusters=$(( (val2T/512/8 + cluster - 1) / cluster ))
++b2clusters=$(( (val2T/2/1024/1024/8 + cluster - 1) / cluster ))
++echo expected bitmap $((b1clusters * cluster +
++                        (b1clusters * 8 + cluster - 1) / cluster * cluster +
++                        b2clusters * cluster +
++                        (b2clusters * 8 + cluster - 1) / cluster * cluster +
++                        cluster))
++$QEMU_IMG measure -O qcow2 -o cluster_size=64k -f qcow2 "$TEST_IMG"
++
++# Compute expected output: bitmap clusters + bitmap tables + bitmaps directory
++echo
++cluster=$((2*1024*1024))
++b1clusters=$(( (val2T/512/8 + cluster - 1) / cluster ))
++b2clusters=$(( (val2T/2/1024/1024/8 + cluster - 1) / cluster ))
++echo expected bitmap $((b1clusters * cluster +
++                        (b1clusters * 8 + cluster - 1) / cluster * cluster +
++                        b2clusters * cluster +
++                        (b2clusters * 8 + cluster - 1) / cluster * cluster +
++                        cluster))
++$QEMU_IMG measure --output=json -O qcow2 -o cluster_size=2M -f qcow2 "$TEST_IMG"
++
+ # success, all done
+ echo "*** done"
+ rm -f $seq.full
+diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
+index d001942..ed9d821 100644
+--- a/tests/qemu-iotests/190.out
++++ b/tests/qemu-iotests/190.out
+@@ -1,11 +1,36 @@
+ QA output created by 190
+-== Huge file ==
++== Huge file without bitmaps ==
+ 
+ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2199023255552
+ required size: 2199023255552
+ fully allocated size: 2199023255552
+ required size: 335806464
+ fully allocated size: 2199359062016
++bitmaps size: 0
+ required size: 18874368
+ fully allocated size: 2199042129920
++bitmaps size: 0
++
++== Huge file with bitmaps ==
++
++required size: 327680
++fully allocated size: 10813440
++required size: 2199023255552
++fully allocated size: 2199023255552
++required size: SIZE
++fully allocated size: 17170432
++required size: 335806464
++fully allocated size: 2199359062016
++
++expected bitmap 537198592
++required size: 335806464
++fully allocated size: 2199359062016
++bitmaps size: 537198592
++
++expected bitmap 545259520
++{
++    "bitmaps": 545259520,
++    "required": 18874368,
++    "fully-allocated": 2199042129920
++}
+ *** done
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-Forward-ZERO_WRITE-flag-for-full-preallocation.patch b/SOURCES/kvm-qcow2-Forward-ZERO_WRITE-flag-for-full-preallocation.patch
new file mode 100644
index 0000000..522ba60
--- /dev/null
+++ b/SOURCES/kvm-qcow2-Forward-ZERO_WRITE-flag-for-full-preallocation.patch
@@ -0,0 +1,98 @@
+From 4290173219e15065e9a7c2e95774ac979b5fd869 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:40 +0100
+Subject: [PATCH 12/17] qcow2: Forward ZERO_WRITE flag for full preallocation
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-12-kwolf@redhat.com>
+Patchwork-id: 97456
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 11/11] qcow2: Forward ZERO_WRITE flag for full preallocation
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
+image is possibly preallocated and then the zero flag is added to all
+clusters. This means that a copy-on-write operation may be needed when
+writing to these clusters, despite having used preallocation, negating
+one of the major benefits of preallocation.
+
+Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
+and if the protocol driver can ensure that the new area reads as zeros,
+we can skip setting the zero flag in the qcow2 layer.
+
+Unfortunately, the same approach doesn't work for metadata
+preallocation, so we'll still set the zero flag there.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit eb8a0cf3ba26611f3981f8f45ac6a868975a68cc)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/qcow2.c              | 22 +++++++++++++++++++---
+ tests/qemu-iotests/274.out |  4 ++--
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/block/qcow2.c b/block/qcow2.c
+index f3d6cb0..b783662 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -4153,9 +4153,25 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
+         /* Allocate the data area */
+         new_file_size = allocation_start +
+                         nb_new_data_clusters * s->cluster_size;
+-        /* Image file grows, so @exact does not matter */
+-        ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
+-                               errp);
++        /*
++         * Image file grows, so @exact does not matter.
++         *
++         * If we need to zero out the new area, try first whether the protocol
++         * driver can already take care of this.
++         */
++        if (flags & BDRV_REQ_ZERO_WRITE) {
++            ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
++                                   BDRV_REQ_ZERO_WRITE, NULL);
++            if (ret >= 0) {
++                flags &= ~BDRV_REQ_ZERO_WRITE;
++            }
++        } else {
++            ret = -1;
++        }
++        if (ret < 0) {
++            ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
++                                   errp);
++        }
+         if (ret < 0) {
+             error_prepend(errp, "Failed to resize underlying file: ");
+             qcow2_free_clusters(bs, allocation_start,
+diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
+index 1a796fd..9d6fdeb 100644
+--- a/tests/qemu-iotests/274.out
++++ b/tests/qemu-iotests/274.out
+@@ -187,7 +187,7 @@ read 65536/65536 bytes at offset 9437184
+ 10 MiB (0xa00000) bytes     allocated at offset 5 MiB (0x500000)
+ 
+ [{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
+-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
++{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
+ 
+ === preallocation=full ===
+ Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+@@ -206,7 +206,7 @@ read 65536/65536 bytes at offset 11534336
+ 4 MiB (0x400000) bytes     allocated at offset 8 MiB (0x800000)
+ 
+ [{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
+-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
++{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
+ 
+ === preallocation=off ===
+ Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qcow2-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch b/SOURCES/kvm-qcow2-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
new file mode 100644
index 0000000..454759e
--- /dev/null
+++ b/SOURCES/kvm-qcow2-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
@@ -0,0 +1,101 @@
+From 3e603e344b81b3ecfea6fb9589ba91f70a22139d Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:33 +0100
+Subject: [PATCH 05/17] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-5-kwolf@redhat.com>
+Patchwork-id: 97449
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 04/11] qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
+qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
+undo any previous preallocation, but just adds the zero flag to all
+relevant L2 entries. If an external data file is in use, a write_zeroes
+request to the data file is made instead.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit f01643fb8b47e8a70c04bbf45e0f12a9e5bc54de)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/qcow2-cluster.c |  2 +-
+ block/qcow2.c         | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
+index dc3c270..9d04f8d 100644
+--- a/block/qcow2-cluster.c
++++ b/block/qcow2-cluster.c
+@@ -1784,7 +1784,7 @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
+     /* Caller must pass aligned values, except at image end */
+     assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
+     assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
+-           end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
++           end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
+ 
+     /* The zero flag is only supported by version 3 and newer */
+     if (s->qcow_version < 3) {
+diff --git a/block/qcow2.c b/block/qcow2.c
+index 86aa74a..f3d6cb0 100644
+--- a/block/qcow2.c
++++ b/block/qcow2.c
+@@ -1726,6 +1726,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
+     }
+ 
+     bs->supported_zero_flags = header.version >= 3 ? BDRV_REQ_MAY_UNMAP : 0;
++    bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
+ 
+     /* Repair image if dirty */
+     if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
+@@ -4197,6 +4198,39 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
+         g_assert_not_reached();
+     }
+ 
++    if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
++        uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
++
++        /*
++         * Use zero clusters as much as we can. qcow2_cluster_zeroize()
++         * requires a cluster-aligned start. The end may be unaligned if it is
++         * at the end of the image (which it is here).
++         */
++        ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
++        if (ret < 0) {
++            error_setg_errno(errp, -ret, "Failed to zero out new clusters");
++            goto fail;
++        }
++
++        /* Write explicit zeros for the unaligned head */
++        if (zero_start > old_length) {
++            uint64_t len = zero_start - old_length;
++            uint8_t *buf = qemu_blockalign0(bs, len);
++            QEMUIOVector qiov;
++            qemu_iovec_init_buf(&qiov, buf, len);
++
++            qemu_co_mutex_unlock(&s->lock);
++            ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
++            qemu_co_mutex_lock(&s->lock);
++
++            qemu_vfree(buf);
++            if (ret < 0) {
++                error_setg_errno(errp, -ret, "Failed to zero out the new area");
++                goto fail;
++            }
++        }
++    }
++
+     if (prealloc != PREALLOC_MODE_OFF) {
+         /* Flush metadata before actually changing the image size */
+         ret = qcow2_write_caches(bs);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-img-Add-bitmap-sub-command.patch b/SOURCES/kvm-qemu-img-Add-bitmap-sub-command.patch
new file mode 100644
index 0000000..eb80188
--- /dev/null
+++ b/SOURCES/kvm-qemu-img-Add-bitmap-sub-command.patch
@@ -0,0 +1,398 @@
+From 53baacb72e8561391841363b2acbd85a783cbc66 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:15 +0100
+Subject: [PATCH 10/26] qemu-img: Add bitmap sub-command
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-8-eblake@redhat.com>
+Patchwork-id: 97074
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 07/12] qemu-img: Add bitmap sub-command
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Include actions for --add, --remove, --clear, --enable, --disable, and
+--merge (note that --clear is a bit of fluff, because the same can be
+accomplished by removing a bitmap and then adding a new one in its
+place, but it matches what QMP commands exist).  Listing is omitted,
+because it does not require a bitmap name and because it was already
+possible with 'qemu-img info'.  A single command line can play one or
+more bitmap commands in sequence on the same bitmap name (although all
+added bitmaps share the same granularity, and and all merged bitmaps
+come from the same source file).  Merge defaults to other bitmaps in
+the primary image, but can also be told to merge bitmaps from a
+distinct image.
+
+While this supports --image-opts for the file being modified, I did
+not think it worth the extra complexity to support that for the source
+file in a cross-file merges.  Likewise, I chose to have --merge only
+take a single source rather than following the QMP support for
+multiple merges in one go (although you can still use more than one
+--merge in the command line); in part because qemu-img is offline and
+therefore atomicity is not an issue.
+
+Upcoming patches will add iotest coverage of these commands while
+also testing other features.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200513011648.166876-7-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit 3b51ab4bf0f49a01cc2db7b954e0669e081719b5)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	docs/tools/qemu-img.rst - lives in qemu-img.texi instead; plus
+	 fix a typo in the text for --merge rather than waiting for
+	 a one-line upstream followup patch
+	qemu-img-cmds.hx - context, use texi instead of rst
+	qemu-img.c - context
+Signed-off-by: Eric Blake <eblake@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ qemu-img-cmds.hx |   6 ++
+ qemu-img.c       | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ qemu-img.texi    |  27 ++++++
+ 3 files changed, 281 insertions(+)
+
+diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
+index 1c93e6d..1a6a8e9 100644
+--- a/qemu-img-cmds.hx
++++ b/qemu-img-cmds.hx
+@@ -25,6 +25,12 @@ STEXI
+ @item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] [--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] [--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] [-U] @var{filename}
+ ETEXI
+ 
++DEF("bitmap", img_bitmap,
++    "bitmap (--merge SOURCE | --add | --remove | --clear | --enable | --disable)... [-b source_file [-F source_fmt]] [-g granularity] [--object objectdef] [--image-opts | -f fmt] filename bitmap")
++STEXI
++.. option:: bitmap (--merge @var{source} | --add | --remove | --clear | --enable | --disable)... [-b @var{source_file} [-F @var{source_fmt}]] [-g @var{granularity}] [--object @var{objectdef}] [--image-opts | -f @var{fmt}] @var{filename} @var{bitmap}
++ETEXI
++
+ DEF("check", img_check,
+     "check [--object objectdef] [--image-opts] [-q] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] [-U] filename")
+ STEXI
+diff --git a/qemu-img.c b/qemu-img.c
+index e69529b..11a4537 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -28,6 +28,7 @@
+ #include "qemu-common.h"
+ #include "qemu-version.h"
+ #include "qapi/error.h"
++#include "qapi/qapi-commands-block-core.h"
+ #include "qapi/qapi-visit-block-core.h"
+ #include "qapi/qobject-output-visitor.h"
+ #include "qapi/qmp/qjson.h"
+@@ -70,6 +71,12 @@ enum {
+     OPTION_PREALLOCATION = 265,
+     OPTION_SHRINK = 266,
+     OPTION_SALVAGE = 267,
++    OPTION_ADD = 269,
++    OPTION_REMOVE = 270,
++    OPTION_CLEAR = 271,
++    OPTION_ENABLE = 272,
++    OPTION_DISABLE = 273,
++    OPTION_MERGE = 274,
+ };
+ 
+ typedef enum OutputFormat {
+@@ -168,6 +175,14 @@ static void QEMU_NORETURN help(void)
+            "  '-n' skips the target volume creation (useful if the volume is created\n"
+            "       prior to running qemu-img)\n"
+            "\n"
++           "Parameters to bitmap subcommand:\n"
++           "  'bitmap' is the name of the bitmap to manipulate, through one or more\n"
++           "       actions from '--add', '--remove', '--clear', '--enable', '--disable',\n"
++           "       or '--merge source'\n"
++           "  '-g granularity' sets the granularity for '--add' actions\n"
++           "  '-b source' and '-F src_fmt' tell '--merge' actions to find the source\n"
++           "       bitmaps from an alternative file\n"
++           "\n"
+            "Parameters to check subcommand:\n"
+            "  '-r' tries to repair any inconsistencies that are found during the check.\n"
+            "       '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
+@@ -4402,6 +4417,239 @@ out:
+     return 0;
+ }
+ 
++enum ImgBitmapAct {
++    BITMAP_ADD,
++    BITMAP_REMOVE,
++    BITMAP_CLEAR,
++    BITMAP_ENABLE,
++    BITMAP_DISABLE,
++    BITMAP_MERGE,
++};
++typedef struct ImgBitmapAction {
++    enum ImgBitmapAct act;
++    const char *src; /* only used for merge */
++    QSIMPLEQ_ENTRY(ImgBitmapAction) next;
++} ImgBitmapAction;
++
++static int img_bitmap(int argc, char **argv)
++{
++    Error *err = NULL;
++    int c, ret = 1;
++    QemuOpts *opts = NULL;
++    const char *fmt = NULL, *src_fmt = NULL, *src_filename = NULL;
++    const char *filename, *bitmap;
++    BlockBackend *blk = NULL, *src = NULL;
++    BlockDriverState *bs = NULL, *src_bs = NULL;
++    bool image_opts = false;
++    int64_t granularity = 0;
++    bool add = false, merge = false;
++    QSIMPLEQ_HEAD(, ImgBitmapAction) actions;
++    ImgBitmapAction *act, *act_next;
++    const char *op;
++
++    QSIMPLEQ_INIT(&actions);
++
++    for (;;) {
++        static const struct option long_options[] = {
++            {"help", no_argument, 0, 'h'},
++            {"object", required_argument, 0, OPTION_OBJECT},
++            {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
++            {"add", no_argument, 0, OPTION_ADD},
++            {"remove", no_argument, 0, OPTION_REMOVE},
++            {"clear", no_argument, 0, OPTION_CLEAR},
++            {"enable", no_argument, 0, OPTION_ENABLE},
++            {"disable", no_argument, 0, OPTION_DISABLE},
++            {"merge", required_argument, 0, OPTION_MERGE},
++            {"granularity", required_argument, 0, 'g'},
++            {"source-file", required_argument, 0, 'b'},
++            {"source-format", required_argument, 0, 'F'},
++            {0, 0, 0, 0}
++        };
++        c = getopt_long(argc, argv, ":b:f:F:g:h", long_options, NULL);
++        if (c == -1) {
++            break;
++        }
++
++        switch (c) {
++        case ':':
++            missing_argument(argv[optind - 1]);
++            break;
++        case '?':
++            unrecognized_option(argv[optind - 1]);
++            break;
++        case 'h':
++            help();
++            break;
++        case 'b':
++            src_filename = optarg;
++            break;
++        case 'f':
++            fmt = optarg;
++            break;
++        case 'F':
++            src_fmt = optarg;
++            break;
++        case 'g':
++            granularity = cvtnum("granularity", optarg);
++            if (granularity < 0) {
++                return 1;
++            }
++            break;
++        case OPTION_ADD:
++            act = g_new0(ImgBitmapAction, 1);
++            act->act = BITMAP_ADD;
++            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
++            add = true;
++            break;
++        case OPTION_REMOVE:
++            act = g_new0(ImgBitmapAction, 1);
++            act->act = BITMAP_REMOVE;
++            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
++            break;
++        case OPTION_CLEAR:
++            act = g_new0(ImgBitmapAction, 1);
++            act->act = BITMAP_CLEAR;
++            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
++            break;
++        case OPTION_ENABLE:
++            act = g_new0(ImgBitmapAction, 1);
++            act->act = BITMAP_ENABLE;
++            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
++            break;
++        case OPTION_DISABLE:
++            act = g_new0(ImgBitmapAction, 1);
++            act->act = BITMAP_DISABLE;
++            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
++            break;
++        case OPTION_MERGE:
++            act = g_new0(ImgBitmapAction, 1);
++            act->act = BITMAP_MERGE;
++            act->src = optarg;
++            QSIMPLEQ_INSERT_TAIL(&actions, act, next);
++            merge = true;
++            break;
++        case OPTION_OBJECT:
++            opts = qemu_opts_parse_noisily(&qemu_object_opts, optarg, true);
++            if (!opts) {
++                goto out;
++            }
++            break;
++        case OPTION_IMAGE_OPTS:
++            image_opts = true;
++            break;
++        }
++    }
++
++    if (qemu_opts_foreach(&qemu_object_opts,
++                          user_creatable_add_opts_foreach,
++                          qemu_img_object_print_help, &error_fatal)) {
++        goto out;
++    }
++
++    if (QSIMPLEQ_EMPTY(&actions)) {
++        error_report("Need at least one of --add, --remove, --clear, "
++                     "--enable, --disable, or --merge");
++        goto out;
++    }
++
++    if (granularity && !add) {
++        error_report("granularity only supported with --add");
++        goto out;
++    }
++    if (src_fmt && !src_filename) {
++        error_report("-F only supported with -b");
++        goto out;
++    }
++    if (src_filename && !merge) {
++        error_report("Merge bitmap source file only supported with "
++                     "--merge");
++        goto out;
++    }
++
++    if (optind != argc - 2) {
++        error_report("Expecting filename and bitmap name");
++        goto out;
++    }
++
++    filename = argv[optind];
++    bitmap = argv[optind + 1];
++
++    blk = img_open(image_opts, filename, fmt, BDRV_O_RDWR, false, false,
++                   false);
++    if (!blk) {
++        goto out;
++    }
++    bs = blk_bs(blk);
++    if (src_filename) {
++        src = img_open(false, src_filename, src_fmt, 0, false, false, false);
++        if (!src) {
++            goto out;
++        }
++        src_bs = blk_bs(src);
++    } else {
++        src_bs = bs;
++    }
++
++    QSIMPLEQ_FOREACH_SAFE(act, &actions, next, act_next) {
++        switch (act->act) {
++        case BITMAP_ADD:
++            qmp_block_dirty_bitmap_add(bs->node_name, bitmap,
++                                       !!granularity, granularity, true, true,
++                                       false, false, &err);
++            op = "add";
++            break;
++        case BITMAP_REMOVE:
++            qmp_block_dirty_bitmap_remove(bs->node_name, bitmap, &err);
++            op = "remove";
++            break;
++        case BITMAP_CLEAR:
++            qmp_block_dirty_bitmap_clear(bs->node_name, bitmap, &err);
++            op = "clear";
++            break;
++        case BITMAP_ENABLE:
++            qmp_block_dirty_bitmap_enable(bs->node_name, bitmap, &err);
++            op = "enable";
++            break;
++        case BITMAP_DISABLE:
++            qmp_block_dirty_bitmap_disable(bs->node_name, bitmap, &err);
++            op = "disable";
++            break;
++        case BITMAP_MERGE: {
++            BlockDirtyBitmapMergeSource *merge_src;
++            BlockDirtyBitmapMergeSourceList *list;
++
++            merge_src = g_new0(BlockDirtyBitmapMergeSource, 1);
++            merge_src->type = QTYPE_QDICT;
++            merge_src->u.external.node = g_strdup(src_bs->node_name);
++            merge_src->u.external.name = g_strdup(act->src);
++            list = g_new0(BlockDirtyBitmapMergeSourceList, 1);
++            list->value = merge_src;
++            qmp_block_dirty_bitmap_merge(bs->node_name, bitmap, list, &err);
++            qapi_free_BlockDirtyBitmapMergeSourceList(list);
++            op = "merge";
++            break;
++        }
++        default:
++            g_assert_not_reached();
++        }
++
++        if (err) {
++            error_reportf_err(err, "Operation %s on bitmap %s failed: ",
++                              op, bitmap);
++            goto out;
++        }
++        g_free(act);
++    }
++
++    ret = 0;
++
++ out:
++    blk_unref(src);
++    blk_unref(blk);
++    qemu_opts_del(opts);
++    return ret;
++}
++
+ #define C_BS      01
+ #define C_COUNT   02
+ #define C_IF      04
+diff --git a/qemu-img.texi b/qemu-img.texi
+index b5156d6..abf2771 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -230,6 +230,33 @@ specified as well.
+ For write tests, by default a buffer filled with zeros is written. This can be
+ overridden with a pattern byte specified by @var{pattern}.
+ 
++@item bitmap (--merge @var{source} | --add | --remove | --clear | --enable | --disable)... [-b @var{source_file} [-F @var{source_fmt}]] [-g @var{granularity}] [--object @var{objectdef}] [--image-opts | -f @var{fmt}] @var{filename} @var{bitmap}
++
++Perform one or more modifications of the persistent bitmap @var{bitmap}
++in the disk image @var{filename}.  The various modifications are:
++
++@table @option
++@item add
++create @var{bitmap}, enabled to record future edits.
++@item remove
++remove @var{bitmap}.
++@item clear
++clear @var{bitmap}.
++@item enable
++change @var{bitmap} to start recording future edits.
++@item disable
++change @var{bitmap} to stop recording future edits.
++@item merge @var{source}
++merge the contents of the @var{source} bitmap into @var{bitmap}.
++@end table
++
++Additional options include @option{-g} which sets a non-default
++@var{granularity} for @option{--add}, and @option{-b} and @option{-F}
++which select an alternative source file for all @var{source} bitmaps used by
++@option{--merge}.
++
++To see what bitmaps are present in an image, use @code{qemu-img info}.
++
+ @item check [--object @var{objectdef}] [--image-opts] [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] [-U] @var{filename}
+ 
+ Perform a consistency check on the disk image @var{filename}. The command can
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-img-Add-convert-bitmaps-option.patch b/SOURCES/kvm-qemu-img-Add-convert-bitmaps-option.patch
new file mode 100644
index 0000000..20eca9f
--- /dev/null
+++ b/SOURCES/kvm-qemu-img-Add-convert-bitmaps-option.patch
@@ -0,0 +1,244 @@
+From f2add7d5955770318824c3eee774bec2dd850936 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:19 +0100
+Subject: [PATCH 14/26] qemu-img: Add convert --bitmaps option
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-12-eblake@redhat.com>
+Patchwork-id: 97076
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 11/12] qemu-img: Add convert --bitmaps option
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Make it easier to copy all the persistent bitmaps of (the top layer
+of) a source image along with its guest-visible contents, by adding a
+boolean flag for use with qemu-img convert.  This is basically
+shorthand, as the same effect could be accomplished with a series of
+'qemu-img bitmap --add' and 'qemu-img bitmap --merge -b source'
+commands, or by their corresponding QMP commands.
+
+Note that this command will fail in the same scenarios where 'qemu-img
+measure' omits a 'bitmaps size:' line, namely, when either the source
+or the destination lacks persistent bitmap support altogether.
+
+See also https://bugzilla.redhat.com/show_bug.cgi?id=1779893
+
+While touching this, clean up a couple coding issues spotted in the
+same function: an extra blank line, and merging back-to-back 'if
+(!skip_create)' blocks.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200521192137.1120211-5-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit 15e39ad95078d528dfb9a75417453cab60332b77)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+
+Conflicts:
+	docs/tools/qemu-img.rst - qemu-img.texi instead
+	qemu-img.c - context: no --target-is-zero
+	qemu-img-cmds.hx - context: texi instead of rst
+Signed-off-by: Eric Blake <eblake@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ qemu-img-cmds.hx |  4 ++--
+ qemu-img.c       | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ qemu-img.texi    |  4 +++-
+ 3 files changed, 72 insertions(+), 6 deletions(-)
+
+diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
+index 1a6a8e9..48144aa 100644
+--- a/qemu-img-cmds.hx
++++ b/qemu-img-cmds.hx
+@@ -50,9 +50,9 @@ STEXI
+ ETEXI
+ 
+ DEF("convert", img_convert,
+-    "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
++    "convert [--object objectdef] [--image-opts] [--target-image-opts] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
+ STEXI
+-@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] [--salvage] @var{filename} [@var{filename2} [...]] @var{output_filename}
++@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] [--salvage] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ ETEXI
+ 
+ DEF("create", img_create,
+diff --git a/qemu-img.c b/qemu-img.c
+index 39e1586..6dc881b 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -77,6 +77,7 @@ enum {
+     OPTION_ENABLE = 272,
+     OPTION_DISABLE = 273,
+     OPTION_MERGE = 274,
++    OPTION_BITMAPS = 275,
+ };
+ 
+ typedef enum OutputFormat {
+@@ -190,6 +191,7 @@ static void QEMU_NORETURN help(void)
+            "       hiding corruption that has already occurred.\n"
+            "\n"
+            "Parameters to convert subcommand:\n"
++           "  '--bitmaps' copies all top-level persistent bitmaps to destination\n"
+            "  '-m' specifies how many coroutines work in parallel during the convert\n"
+            "       process (defaults to 8)\n"
+            "  '-W' allow to write to the target out of order rather than sequential\n"
+@@ -2084,6 +2086,39 @@ static int convert_do_copy(ImgConvertState *s)
+     return s->ret;
+ }
+ 
++static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst)
++{
++    BdrvDirtyBitmap *bm;
++    Error *err = NULL;
++
++    FOR_EACH_DIRTY_BITMAP(src, bm) {
++        const char *name;
++
++        if (!bdrv_dirty_bitmap_get_persistence(bm)) {
++            continue;
++        }
++        name = bdrv_dirty_bitmap_name(bm);
++        qmp_block_dirty_bitmap_add(dst->node_name, name,
++                                   true, bdrv_dirty_bitmap_granularity(bm),
++                                   true, true,
++                                   true, !bdrv_dirty_bitmap_enabled(bm),
++                                   &err);
++        if (err) {
++            error_reportf_err(err, "Failed to create bitmap %s: ", name);
++            return -1;
++        }
++
++        do_dirty_bitmap_merge(dst->node_name, name, src->node_name, name,
++                              &err);
++        if (err) {
++            error_reportf_err(err, "Failed to populate bitmap %s: ", name);
++            return -1;
++        }
++    }
++
++    return 0;
++}
++
+ #define MAX_BUF_SECTORS 32768
+ 
+ static int img_convert(int argc, char **argv)
+@@ -2105,6 +2140,7 @@ static int img_convert(int argc, char **argv)
+     int64_t ret = -EINVAL;
+     bool force_share = false;
+     bool explict_min_sparse = false;
++    bool bitmaps = false;
+ 
+     ImgConvertState s = (ImgConvertState) {
+         /* Need at least 4k of zeros for sparse detection */
+@@ -2123,6 +2159,7 @@ static int img_convert(int argc, char **argv)
+             {"force-share", no_argument, 0, 'U'},
+             {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
+             {"salvage", no_argument, 0, OPTION_SALVAGE},
++            {"bitmaps", no_argument, 0, OPTION_BITMAPS},
+             {0, 0, 0, 0}
+         };
+         c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
+@@ -2248,6 +2285,9 @@ static int img_convert(int argc, char **argv)
+         case OPTION_TARGET_IMAGE_OPTS:
+             tgt_image_opts = true;
+             break;
++        case OPTION_BITMAPS:
++            bitmaps = true;
++            break;
+         }
+     }
+ 
+@@ -2304,7 +2344,6 @@ static int img_convert(int argc, char **argv)
+         goto fail_getopt;
+     }
+ 
+-
+     /* ret is still -EINVAL until here */
+     ret = bdrv_parse_cache_mode(src_cache, &src_flags, &src_writethrough);
+     if (ret < 0) {
+@@ -2458,6 +2497,20 @@ static int img_convert(int argc, char **argv)
+         }
+     }
+ 
++    /* Determine if bitmaps need copying */
++    if (bitmaps) {
++        if (s.src_num > 1) {
++            error_report("Copying bitmaps only possible with single source");
++            ret = -1;
++            goto out;
++        }
++        if (!bdrv_supports_persistent_dirty_bitmap(blk_bs(s.src[0]))) {
++            error_report("Source lacks bitmap support");
++            ret = -1;
++            goto out;
++        }
++    }
++
+     /*
+      * The later open call will need any decryption secrets, and
+      * bdrv_create() will purge "opts", so extract them now before
+@@ -2466,9 +2519,7 @@ static int img_convert(int argc, char **argv)
+     if (!skip_create) {
+         open_opts = qdict_new();
+         qemu_opt_foreach(opts, img_add_key_secrets, open_opts, &error_abort);
+-    }
+ 
+-    if (!skip_create) {
+         /* Create the new image */
+         ret = bdrv_create(drv, out_filename, opts, &local_err);
+         if (ret < 0) {
+@@ -2506,6 +2557,13 @@ static int img_convert(int argc, char **argv)
+     }
+     out_bs = blk_bs(s.target);
+ 
++    if (bitmaps && !bdrv_supports_persistent_dirty_bitmap(out_bs)) {
++        error_report("Format driver '%s' does not support bitmaps",
++                     out_bs->drv->format_name);
++        ret = -1;
++        goto out;
++    }
++
+     if (s.compressed && !block_driver_can_compress(out_bs->drv)) {
+         error_report("Compression not supported for this file format");
+         ret = -1;
+@@ -2565,6 +2623,12 @@ static int img_convert(int argc, char **argv)
+     }
+ 
+     ret = convert_do_copy(&s);
++
++    /* Now copy the bitmaps */
++    if (bitmaps && ret == 0) {
++        ret = convert_copy_bitmaps(blk_bs(s.src[0]), out_bs);
++    }
++
+ out:
+     if (!ret) {
+         qemu_progress_print(100, 0);
+diff --git a/qemu-img.texi b/qemu-img.texi
+index 3670b96..b95d019 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -161,6 +161,8 @@ Parameters to convert subcommand:
+ 
+ @table @option
+ 
++@item --bitmaps
++Additionally copy all persistent bitmaps from the top layer of the source
+ @item -n
+ Skip the creation of the target volume
+ @item -m
+@@ -357,7 +359,7 @@ Error on reading data
+ 
+ @end table
+ 
+-@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
++@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [--bitmaps] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ 
+ Convert the disk image @var{filename} or a snapshot @var{snapshot_param}
+ to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu-img-Factor-out-code-for-merging-bitmaps.patch b/SOURCES/kvm-qemu-img-Factor-out-code-for-merging-bitmaps.patch
new file mode 100644
index 0000000..c4012b7
--- /dev/null
+++ b/SOURCES/kvm-qemu-img-Factor-out-code-for-merging-bitmaps.patch
@@ -0,0 +1,89 @@
+From 58816c3709e5058e8805333ca011cc4e793d67ff Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:18 +0100
+Subject: [PATCH 13/26] qemu-img: Factor out code for merging bitmaps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-11-eblake@redhat.com>
+Patchwork-id: 97078
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 10/12] qemu-img: Factor out code for merging bitmaps
+Bugzilla: 1779893 1779904
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+The next patch will add another client that wants to merge dirty
+bitmaps; it will be easier to refactor the code to construct the QAPI
+struct correctly into a helper function.
+
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Message-Id: <20200521192137.1120211-4-eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+(cherry picked from commit 6c729dd832207d7347ecb074912f538e2942f269)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ qemu-img.c | 34 +++++++++++++++++++++-------------
+ 1 file changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index b57856e..39e1586 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -1582,6 +1582,24 @@ out4:
+     return ret;
+ }
+ 
++/* Convenience wrapper around qmp_block_dirty_bitmap_merge */
++static void do_dirty_bitmap_merge(const char *dst_node, const char *dst_name,
++                                  const char *src_node, const char *src_name,
++                                  Error **errp)
++{
++    BlockDirtyBitmapMergeSource *merge_src;
++    BlockDirtyBitmapMergeSourceList *list;
++
++    merge_src = g_new0(BlockDirtyBitmapMergeSource, 1);
++    merge_src->type = QTYPE_QDICT;
++    merge_src->u.external.node = g_strdup(src_node);
++    merge_src->u.external.name = g_strdup(src_name);
++    list = g_new0(BlockDirtyBitmapMergeSourceList, 1);
++    list->value = merge_src;
++    qmp_block_dirty_bitmap_merge(dst_node, dst_name, list, errp);
++    qapi_free_BlockDirtyBitmapMergeSourceList(list);
++}
++
+ enum ImgConvertBlockStatus {
+     BLK_DATA,
+     BLK_ZERO,
+@@ -4614,21 +4632,11 @@ static int img_bitmap(int argc, char **argv)
+             qmp_block_dirty_bitmap_disable(bs->node_name, bitmap, &err);
+             op = "disable";
+             break;
+-        case BITMAP_MERGE: {
+-            BlockDirtyBitmapMergeSource *merge_src;
+-            BlockDirtyBitmapMergeSourceList *list;
+-
+-            merge_src = g_new0(BlockDirtyBitmapMergeSource, 1);
+-            merge_src->type = QTYPE_QDICT;
+-            merge_src->u.external.node = g_strdup(src_bs->node_name);
+-            merge_src->u.external.name = g_strdup(act->src);
+-            list = g_new0(BlockDirtyBitmapMergeSourceList, 1);
+-            list->value = merge_src;
+-            qmp_block_dirty_bitmap_merge(bs->node_name, bitmap, list, &err);
+-            qapi_free_BlockDirtyBitmapMergeSourceList(list);
++        case BITMAP_MERGE:
++            do_dirty_bitmap_merge(bs->node_name, bitmap, src_bs->node_name,
++                                  act->src, &err);
+             op = "merge";
+             break;
+-        }
+         default:
+             g_assert_not_reached();
+         }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-qemu_img-add-cvtnum_full-to-print-error-reports.patch b/SOURCES/kvm-qemu_img-add-cvtnum_full-to-print-error-reports.patch
new file mode 100644
index 0000000..b4180b9
--- /dev/null
+++ b/SOURCES/kvm-qemu_img-add-cvtnum_full-to-print-error-reports.patch
@@ -0,0 +1,241 @@
+From 1a8a4ece5def912e7cfa5ef8565fc8ecef6e72c3 Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Tue, 2 Jun 2020 02:34:11 +0100
+Subject: [PATCH 06/26] qemu_img: add cvtnum_full to print error reports
+
+RH-Author: Eric Blake <eblake@redhat.com>
+Message-id: <20200602023420.2133649-4-eblake@redhat.com>
+Patchwork-id: 97067
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 03/12] qemu_img: add cvtnum_full to print error reports
+Bugzilla: 1779893 1779904
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+From: Eyal Moscovici <eyal.moscovici@oracle.com>
+
+All calls to cvtnum check the return value and print the same error
+message more or less. And so error reporting moved to cvtnum_full to
+reduce code duplication and provide a single error
+message. Additionally, cvtnum now wraps cvtnum_full with the existing
+default range of 0 to MAX_INT64.
+
+Acked-by: Mark Kanda <mark.kanda@oracle.com>
+Signed-off-by: Eyal Moscovici <eyal.moscovici@oracle.com>
+Message-Id: <20200513133629.18508-2-eyal.moscovici@oracle.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+[eblake: fix printf formatting, avoid trailing space, change error wording,
+reformat commit message]
+Signed-off-by: Eric Blake <eblake@redhat.com>
+(cherry picked from commit 43d589b074370ebc9b340340b5f641b385da9df8)
+Signed-off-by: Eric Blake <eblake@redhat.com>
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ qemu-img.c                 | 76 +++++++++++++++++++++-------------------------
+ tests/qemu-iotests/049.out |  8 ++---
+ 2 files changed, 38 insertions(+), 46 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index 95a24b9..e69529b 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -422,19 +422,31 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts,
+     return 0;
+ }
+ 
+-static int64_t cvtnum(const char *s)
++static int64_t cvtnum_full(const char *name, const char *value, int64_t min,
++                           int64_t max)
+ {
+     int err;
+-    uint64_t value;
+-
+-    err = qemu_strtosz(s, NULL, &value);
+-    if (err < 0) {
++    uint64_t res;
++
++    err = qemu_strtosz(value, NULL, &res);
++    if (err < 0 && err != -ERANGE) {
++        error_report("Invalid %s specified. You may use "
++                     "k, M, G, T, P or E suffixes for", name);
++        error_report("kilobytes, megabytes, gigabytes, terabytes, "
++                     "petabytes and exabytes.");
+         return err;
+     }
+-    if (value > INT64_MAX) {
++    if (err == -ERANGE || res > max || res < min) {
++        error_report("Invalid %s specified. Must be between %" PRId64
++                     " and %" PRId64 ".", name, min, max);
+         return -ERANGE;
+     }
+-    return value;
++    return res;
++}
++
++static int64_t cvtnum(const char *name, const char *value)
++{
++    return cvtnum_full(name, value, 0, INT64_MAX);
+ }
+ 
+ static int img_create(int argc, char **argv)
+@@ -532,16 +544,8 @@ static int img_create(int argc, char **argv)
+     if (optind < argc) {
+         int64_t sval;
+ 
+-        sval = cvtnum(argv[optind++]);
++        sval = cvtnum("image size", argv[optind++]);
+         if (sval < 0) {
+-            if (sval == -ERANGE) {
+-                error_report("Image size must be less than 8 EiB!");
+-            } else {
+-                error_report("Invalid image size specified! You may use k, M, "
+-                      "G, T, P or E suffixes for ");
+-                error_report("kilobytes, megabytes, gigabytes, terabytes, "
+-                             "petabytes and exabytes.");
+-            }
+             goto fail;
+         }
+         img_size = (uint64_t)sval;
+@@ -2148,8 +2152,10 @@ static int img_convert(int argc, char **argv)
+         {
+             int64_t sval;
+ 
+-            sval = cvtnum(optarg);
+-            if (sval < 0 || !QEMU_IS_ALIGNED(sval, BDRV_SECTOR_SIZE) ||
++            sval = cvtnum("buffer size for sparse output", optarg);
++            if (sval < 0) {
++                goto fail_getopt;
++            } else if (!QEMU_IS_ALIGNED(sval, BDRV_SECTOR_SIZE) ||
+                 sval / BDRV_SECTOR_SIZE > MAX_BUF_SECTORS) {
+                 error_report("Invalid buffer size for sparse output specified. "
+                     "Valid sizes are multiples of %llu up to %llu. Select "
+@@ -4229,9 +4235,8 @@ static int img_bench(int argc, char **argv)
+             break;
+         case 'o':
+         {
+-            offset = cvtnum(optarg);
++            offset = cvtnum("offset", optarg);
+             if (offset < 0) {
+-                error_report("Invalid offset specified");
+                 return 1;
+             }
+             break;
+@@ -4244,9 +4249,8 @@ static int img_bench(int argc, char **argv)
+         {
+             int64_t sval;
+ 
+-            sval = cvtnum(optarg);
+-            if (sval < 0 || sval > INT_MAX) {
+-                error_report("Invalid buffer size specified");
++            sval = cvtnum_full("buffer size", optarg, 0, INT_MAX);
++            if (sval < 0) {
+                 return 1;
+             }
+ 
+@@ -4257,9 +4261,8 @@ static int img_bench(int argc, char **argv)
+         {
+             int64_t sval;
+ 
+-            sval = cvtnum(optarg);
+-            if (sval < 0 || sval > INT_MAX) {
+-                error_report("Invalid step size specified");
++            sval = cvtnum_full("step_size", optarg, 0, INT_MAX);
++            if (sval < 0) {
+                 return 1;
+             }
+ 
+@@ -4429,10 +4432,9 @@ static int img_dd_bs(const char *arg,
+ {
+     int64_t res;
+ 
+-    res = cvtnum(arg);
++    res = cvtnum_full("bs", arg, 1, INT_MAX);
+ 
+-    if (res <= 0 || res > INT_MAX) {
+-        error_report("invalid number: '%s'", arg);
++    if (res < 0) {
+         return 1;
+     }
+     in->bsz = out->bsz = res;
+@@ -4444,10 +4446,9 @@ static int img_dd_count(const char *arg,
+                         struct DdIo *in, struct DdIo *out,
+                         struct DdInfo *dd)
+ {
+-    dd->count = cvtnum(arg);
++    dd->count = cvtnum("count", arg);
+ 
+     if (dd->count < 0) {
+-        error_report("invalid number: '%s'", arg);
+         return 1;
+     }
+ 
+@@ -4476,10 +4477,9 @@ static int img_dd_skip(const char *arg,
+                        struct DdIo *in, struct DdIo *out,
+                        struct DdInfo *dd)
+ {
+-    in->offset = cvtnum(arg);
++    in->offset = cvtnum("skip", arg);
+ 
+     if (in->offset < 0) {
+-        error_report("invalid number: '%s'", arg);
+         return 1;
+     }
+ 
+@@ -4869,16 +4869,8 @@ static int img_measure(int argc, char **argv)
+         {
+             int64_t sval;
+ 
+-            sval = cvtnum(optarg);
++            sval = cvtnum("image size", optarg);
+             if (sval < 0) {
+-                if (sval == -ERANGE) {
+-                    error_report("Image size must be less than 8 EiB!");
+-                } else {
+-                    error_report("Invalid image size specified! You may use "
+-                                 "k, M, G, T, P or E suffixes for ");
+-                    error_report("kilobytes, megabytes, gigabytes, terabytes, "
+-                                 "petabytes and exabytes.");
+-                }
+                 goto out;
+             }
+             img_size = (uint64_t)sval;
+diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
+index 6b50540..8b35f3d 100644
+--- a/tests/qemu-iotests/049.out
++++ b/tests/qemu-iotests/049.out
+@@ -92,19 +92,19 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 l
+ == 3. Invalid sizes ==
+ 
+ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1024
+-qemu-img: Image size must be less than 8 EiB!
++qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
+ 
+ qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2
+ qemu-img: TEST_DIR/t.qcow2: Value '-1024' is out of range for parameter 'size'
+ 
+ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k
+-qemu-img: Image size must be less than 8 EiB!
++qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
+ 
+ qemu-img create -f qcow2 -o size=-1k TEST_DIR/t.qcow2
+ qemu-img: TEST_DIR/t.qcow2: Value '-1k' is out of range for parameter 'size'
+ 
+ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
+-qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
++qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
+ qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
+ 
+ qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
+@@ -113,7 +113,7 @@ Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
+ and exabytes, respectively.
+ 
+ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
+-qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
++qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
+ qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
+ 
+ qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-raw-format-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch b/SOURCES/kvm-raw-format-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
new file mode 100644
index 0000000..5384b51
--- /dev/null
+++ b/SOURCES/kvm-raw-format-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
@@ -0,0 +1,55 @@
+From 5d590d354e42515ea074bf2110a2ab236dbabba1 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 8 Jun 2020 15:01:34 +0100
+Subject: [PATCH 06/17] raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20200608150140.38218-6-kwolf@redhat.com>
+Patchwork-id: 97447
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 05/11] raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
+Bugzilla: 1780574
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+The raw format driver can simply forward the flag and let its bs->file
+child take care of actually providing the zeros.
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
+Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 1ddaabaecb7eaeb6d8948a32340af95db44c54a1)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/raw-format.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/block/raw-format.c b/block/raw-format.c
+index c3acf9a..bdec466 100644
+--- a/block/raw-format.c
++++ b/block/raw-format.c
+@@ -387,7 +387,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
+ 
+     s->size = offset;
+     offset += s->offset;
+-    return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
++    return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
+ }
+ 
+ static void raw_eject(BlockDriverState *bs, bool eject_flag)
+@@ -445,6 +445,8 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
+     bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
+         ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
+             bs->file->bs->supported_zero_flags);
++    bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
++                                   BDRV_REQ_ZERO_WRITE;
+ 
+     if (bs->probed && !bdrv_is_read_only(bs)) {
+         bdrv_refresh_filename(bs->file->bs);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-s390-ipl-fix-off-by-one-in-update_machine_ipl_proper.patch b/SOURCES/kvm-s390-ipl-fix-off-by-one-in-update_machine_ipl_proper.patch
new file mode 100644
index 0000000..c45158a
--- /dev/null
+++ b/SOURCES/kvm-s390-ipl-fix-off-by-one-in-update_machine_ipl_proper.patch
@@ -0,0 +1,54 @@
+From 1769600e1e3bd5ca48450de8ce8a118bf0af96f3 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:00 -0400
+Subject: [PATCH 18/42] s390/ipl: fix off-by-one in
+ update_machine_ipl_properties()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-19-thuth@redhat.com>
+Patchwork-id: 97028
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 18/38] s390/ipl: fix off-by-one in update_machine_ipl_properties()
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Halil Pasic <pasic@linux.ibm.com>
+
+In update_machine_ipl_properties() the array ascii_loadparm needs to
+hold the 8 char loadparm and a string terminating zero char.
+
+Let's increase the size of ascii_loadparm accordingly.
+
+Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
+Fixes: 0a01e082a428 ("s390/ipl: sync back loadparm")
+Fixes: Coverity CID 1421966
+Reported-by: Peter Maydell <peter.maydell@linaro.org>
+Message-Id: <20200320143101.41764-1-pasic@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 7722837369eb1c7e808021d79da68afa0c01c26f)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ipl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
+index f25339c503..fa0409dc23 100644
+--- a/hw/s390x/ipl.c
++++ b/hw/s390x/ipl.c
+@@ -537,7 +537,7 @@ static void update_machine_ipl_properties(IplParameterBlock *iplb)
+     /* Sync loadparm */
+     if (iplb->flags & DIAG308_FLAGS_LP_VALID) {
+         uint8_t *ebcdic_loadparm = iplb->loadparm;
+-        char ascii_loadparm[8];
++        char ascii_loadparm[9];
+         int i;
+ 
+         for (i = 0; i < 8 && ebcdic_loadparm[i]; i++) {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390-ipl-sync-back-loadparm.patch b/SOURCES/kvm-s390-ipl-sync-back-loadparm.patch
new file mode 100644
index 0000000..49f4d3f
--- /dev/null
+++ b/SOURCES/kvm-s390-ipl-sync-back-loadparm.patch
@@ -0,0 +1,91 @@
+From 53053ea2e6c757e5d044655c8b61c485e0aad4ed Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:59 -0400
+Subject: [PATCH 17/42] s390/ipl: sync back loadparm
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-18-thuth@redhat.com>
+Patchwork-id: 97039
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 17/38] s390/ipl: sync back loadparm
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Halil Pasic <pasic@linux.ibm.com>
+
+We expose loadparm as a r/w machine property, but if loadparm is set by
+the guest via DIAG 308, we don't update the property. Having a
+disconnect between the guest view and the QEMU property is not nice in
+itself, but things get even worse for SCSI, where under certain
+circumstances (see 789b5a401b "s390: Ensure IPL from SCSI works as
+expected" for details) we call s390_gen_initial_iplb() on resets
+effectively overwriting the guest/user supplied loadparm with the stale
+value.
+
+Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
+Fixes: 7104bae9de ("hw/s390x: provide loadparm property for the machine")
+Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
+Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20200309133223.100491-1-pasic@linux.ibm.com>
+[borntraeger@de.ibm.com: use reverse xmas tree]
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+(cherry picked from commit 0a01e082a428b921e48b5314881b1f23a7b0fe50)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ipl.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
+index 0b7548a549..f25339c503 100644
+--- a/hw/s390x/ipl.c
++++ b/hw/s390x/ipl.c
+@@ -529,6 +529,30 @@ static bool is_virtio_scsi_device(IplParameterBlock *iplb)
+     return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
+ }
+ 
++static void update_machine_ipl_properties(IplParameterBlock *iplb)
++{
++    Object *machine = qdev_get_machine();
++    Error *err = NULL;
++
++    /* Sync loadparm */
++    if (iplb->flags & DIAG308_FLAGS_LP_VALID) {
++        uint8_t *ebcdic_loadparm = iplb->loadparm;
++        char ascii_loadparm[8];
++        int i;
++
++        for (i = 0; i < 8 && ebcdic_loadparm[i]; i++) {
++            ascii_loadparm[i] = ebcdic2ascii[(uint8_t) ebcdic_loadparm[i]];
++        }
++        ascii_loadparm[i] = 0;
++        object_property_set_str(machine, ascii_loadparm, "loadparm", &err);
++    } else {
++        object_property_set_str(machine, "", "loadparm", &err);
++    }
++    if (err) {
++        warn_report_err(err);
++    }
++}
++
+ void s390_ipl_update_diag308(IplParameterBlock *iplb)
+ {
+     S390IPLState *ipl = get_ipl_device();
+@@ -536,6 +560,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
+     ipl->iplb = *iplb;
+     ipl->iplb_valid = true;
+     ipl->netboot = is_virtio_net_device(iplb);
++    update_machine_ipl_properties(iplb);
+ }
+ 
+ IplParameterBlock *s390_ipl_get_iplb(void)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390-sclp-improve-special-wait-psw-logic.patch b/SOURCES/kvm-s390-sclp-improve-special-wait-psw-logic.patch
new file mode 100644
index 0000000..2040d5c
--- /dev/null
+++ b/SOURCES/kvm-s390-sclp-improve-special-wait-psw-logic.patch
@@ -0,0 +1,52 @@
+From cd7da3cf1b19fef0a497fd556562040a85e579a7 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:57 -0400
+Subject: [PATCH 15/42] s390/sclp: improve special wait psw logic
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-16-thuth@redhat.com>
+Patchwork-id: 97037
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 15/38] s390/sclp: improve special wait psw logic
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+There is a special quiesce PSW that we check for "shutdown". Otherwise disabled
+wait is detected as "crashed". Architecturally we must only check PSW bits
+116-127. Fix this.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <1582204582-22995-1-git-send-email-borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Acked-by: Janosch Frank <frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 8b51c0961cc13e55b26bb6665ec3a341abdc7658)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/helper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/target/s390x/helper.c b/target/s390x/helper.c
+index a3a49164e4..6808dfda01 100644
+--- a/target/s390x/helper.c
++++ b/target/s390x/helper.c
+@@ -89,7 +89,7 @@ hwaddr s390_cpu_get_phys_addr_debug(CPUState *cs, vaddr vaddr)
+ static inline bool is_special_wait_psw(uint64_t psw_addr)
+ {
+     /* signal quiesce */
+-    return psw_addr == 0xfffUL;
++    return (psw_addr & 0xfffUL) == 0xfffUL;
+ }
+ 
+ void s390_handle_wait(S390CPU *cpu)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Add-SIDA-memory-ops.patch b/SOURCES/kvm-s390x-Add-SIDA-memory-ops.patch
new file mode 100644
index 0000000..1b566d7
--- /dev/null
+++ b/SOURCES/kvm-s390x-Add-SIDA-memory-ops.patch
@@ -0,0 +1,150 @@
+From ebcd74c2267d69fe09ca03cb8bfed7bef5ea3a85 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:08 -0400
+Subject: [PATCH 26/42] s390x: Add SIDA memory ops
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-27-thuth@redhat.com>
+Patchwork-id: 97033
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 26/38] s390x: Add SIDA memory ops
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Protected guests save the instruction control blocks in the SIDA
+instead of QEMU/KVM directly accessing the guest's memory.
+
+Let's introduce new functions to access the SIDA.
+
+The memops for doing so are available with KVM_CAP_S390_PROTECTED, so
+let's check for that.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-8-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 1cca8265499d394d9ed4bfb75bd6e7265b529f89)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu.h        |  7 ++++++-
+ target/s390x/kvm.c        | 26 ++++++++++++++++++++++++++
+ target/s390x/kvm_s390x.h  |  2 ++
+ target/s390x/mmu_helper.c | 14 ++++++++++++++
+ 4 files changed, 48 insertions(+), 1 deletion(-)
+
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 1ff84e6b3a..edf8391504 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -828,7 +828,12 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
+ #define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len)   \
+         s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
+ void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
+-
++int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
++                       int len, bool is_write);
++#define s390_cpu_pv_mem_read(cpu, offset, dest, len)    \
++        s390_cpu_pv_mem_rw(cpu, offset, dest, len, false)
++#define s390_cpu_pv_mem_write(cpu, offset, dest, len)       \
++        s390_cpu_pv_mem_rw(cpu, offset, dest, len, true)
+ 
+ /* sigp.c */
+ int s390_cpu_restart(S390CPU *cpu);
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index af50b2c253..f67bb5ce2c 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -154,6 +154,7 @@ static int cap_ri;
+ static int cap_gs;
+ static int cap_hpage_1m;
+ static int cap_vcpu_resets;
++static int cap_protected;
+ 
+ static int active_cmma;
+ 
+@@ -351,6 +352,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
+     cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
+     cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
++    cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED);
+ 
+     if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
+         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
+@@ -848,6 +850,30 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
+     return ret;
+ }
+ 
++int kvm_s390_mem_op_pv(S390CPU *cpu, uint64_t offset, void *hostbuf,
++                       int len, bool is_write)
++{
++    struct kvm_s390_mem_op mem_op = {
++        .sida_offset = offset,
++        .size = len,
++        .op = is_write ? KVM_S390_MEMOP_SIDA_WRITE
++                       : KVM_S390_MEMOP_SIDA_READ,
++        .buf = (uint64_t)hostbuf,
++    };
++    int ret;
++
++    if (!cap_mem_op || !cap_protected) {
++        return -ENOSYS;
++    }
++
++    ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
++    if (ret < 0) {
++        error_report("KVM_S390_MEM_OP failed: %s", strerror(-ret));
++        abort();
++    }
++    return ret;
++}
++
+ /*
+  * Legacy layout for s390:
+  * Older S390 KVM requires the topmost vma of the RAM to be
+diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
+index dea813f450..6ab17c81b7 100644
+--- a/target/s390x/kvm_s390x.h
++++ b/target/s390x/kvm_s390x.h
+@@ -19,6 +19,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
+ void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
+ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
+                     int len, bool is_write);
++int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
++                       bool is_write);
+ void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
+ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
+ void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
+diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
+index c9f3f34750..ec8befbdc8 100644
+--- a/target/s390x/mmu_helper.c
++++ b/target/s390x/mmu_helper.c
+@@ -474,6 +474,20 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
+     return 0;
+ }
+ 
++int s390_cpu_pv_mem_rw(S390CPU *cpu, unsigned int offset, void *hostbuf,
++                       int len, bool is_write)
++{
++    int ret;
++
++    if (kvm_enabled()) {
++        ret = kvm_s390_mem_op_pv(cpu, offset, hostbuf, len, is_write);
++    } else {
++        /* Protected Virtualization is a KVM/Hardware only feature */
++        g_assert_not_reached();
++    }
++    return ret;
++}
++
+ /**
+  * s390_cpu_virt_mem_rw:
+  * @laddr:     the logical start address
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Add-missing-vcpu-reset-functions.patch b/SOURCES/kvm-s390x-Add-missing-vcpu-reset-functions.patch
new file mode 100644
index 0000000..9ce071e
--- /dev/null
+++ b/SOURCES/kvm-s390x-Add-missing-vcpu-reset-functions.patch
@@ -0,0 +1,176 @@
+From e11643b5363262e9f809762a1f2bb5c4a8f26c2a Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:56 -0400
+Subject: [PATCH 14/42] s390x: Add missing vcpu reset functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-15-thuth@redhat.com>
+Patchwork-id: 97023
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 14/38] s390x: Add missing vcpu reset functions
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Up to now we only had an ioctl to reset vcpu data QEMU couldn't reach
+for the initial reset, which was also called for the clear reset. To
+be architecture compliant, we also need to clear local interrupts on a
+normal reset.
+
+Because of this and the upcoming protvirt support we need to add
+ioctls for the missing clear and normal resets.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20200214151636.8764-3-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit b91a03946e0f65ddd22927dd80ca1276bf89c5af)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu.c       | 14 ++++++++++++--
+ target/s390x/kvm-stub.c  | 10 +++++++++-
+ target/s390x/kvm.c       | 42 ++++++++++++++++++++++++++++++++--------
+ target/s390x/kvm_s390x.h |  4 +++-
+ 4 files changed, 58 insertions(+), 12 deletions(-)
+
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index e538a4a3e2..c0dd502b84 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -144,8 +144,18 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+     }
+ 
+     /* Reset state inside the kernel that we cannot access yet from QEMU. */
+-    if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
+-        kvm_s390_reset_vcpu(cpu);
++    if (kvm_enabled()) {
++        switch (type) {
++        case S390_CPU_RESET_CLEAR:
++            kvm_s390_reset_vcpu_clear(cpu);
++            break;
++        case S390_CPU_RESET_INITIAL:
++            kvm_s390_reset_vcpu_initial(cpu);
++            break;
++        case S390_CPU_RESET_NORMAL:
++            kvm_s390_reset_vcpu_normal(cpu);
++            break;
++        }
+     }
+ }
+ 
+diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
+index 5152e2bdf1..c4cd497f85 100644
+--- a/target/s390x/kvm-stub.c
++++ b/target/s390x/kvm-stub.c
+@@ -83,7 +83,15 @@ void kvm_s390_cmma_reset(void)
+ {
+ }
+ 
+-void kvm_s390_reset_vcpu(S390CPU *cpu)
++void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
++{
++}
++
++void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
++{
++}
++
++void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
+ {
+ }
+ 
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 1c5bc7a2f9..75d82af6fc 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -151,6 +151,7 @@ static int cap_s390_irq;
+ static int cap_ri;
+ static int cap_gs;
+ static int cap_hpage_1m;
++static int cap_vcpu_resets;
+ 
+ static int active_cmma;
+ 
+@@ -342,6 +343,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
+     cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
+     cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
++    cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
+ 
+     if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
+         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
+@@ -403,17 +405,41 @@ int kvm_arch_destroy_vcpu(CPUState *cs)
+     return 0;
+ }
+ 
+-void kvm_s390_reset_vcpu(S390CPU *cpu)
++static void kvm_s390_reset_vcpu(S390CPU *cpu, unsigned long type)
+ {
+     CPUState *cs = CPU(cpu);
+ 
+-    /* The initial reset call is needed here to reset in-kernel
+-     * vcpu data that we can't access directly from QEMU
+-     * (i.e. with older kernels which don't support sync_regs/ONE_REG).
+-     * Before this ioctl cpu_synchronize_state() is called in common kvm
+-     * code (kvm-all) */
+-    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
+-        error_report("Initial CPU reset failed on CPU %i", cs->cpu_index);
++    /*
++     * The reset call is needed here to reset in-kernel vcpu data that
++     * we can't access directly from QEMU (i.e. with older kernels
++     * which don't support sync_regs/ONE_REG).  Before this ioctl
++     * cpu_synchronize_state() is called in common kvm code
++     * (kvm-all).
++     */
++    if (kvm_vcpu_ioctl(cs, type)) {
++        error_report("CPU reset failed on CPU %i type %lx",
++                     cs->cpu_index, type);
++    }
++}
++
++void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
++{
++    kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
++}
++
++void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
++{
++    if (cap_vcpu_resets) {
++        kvm_s390_reset_vcpu(cpu, KVM_S390_CLEAR_RESET);
++    } else {
++        kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
++    }
++}
++
++void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
++{
++    if (cap_vcpu_resets) {
++        kvm_s390_reset_vcpu(cpu, KVM_S390_NORMAL_RESET);
+     }
+ }
+ 
+diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
+index caf985955b..0b21789796 100644
+--- a/target/s390x/kvm_s390x.h
++++ b/target/s390x/kvm_s390x.h
+@@ -34,7 +34,9 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
+                                     int vq, bool assign);
+ int kvm_s390_cmma_active(void);
+ void kvm_s390_cmma_reset(void);
+-void kvm_s390_reset_vcpu(S390CPU *cpu);
++void kvm_s390_reset_vcpu_clear(S390CPU *cpu);
++void kvm_s390_reset_vcpu_normal(S390CPU *cpu);
++void kvm_s390_reset_vcpu_initial(S390CPU *cpu);
+ int kvm_s390_set_mem_limit(uint64_t new_limit, uint64_t *hw_limit);
+ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
+ void kvm_s390_crypto_reset(void);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Add-unpack-facility-feature-to-GA1.patch b/SOURCES/kvm-s390x-Add-unpack-facility-feature-to-GA1.patch
new file mode 100644
index 0000000..8ffb7b0
--- /dev/null
+++ b/SOURCES/kvm-s390x-Add-unpack-facility-feature-to-GA1.patch
@@ -0,0 +1,76 @@
+From ab670456375f0d9b9b2d219fd497d04ec0009e1d Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:16 -0400
+Subject: [PATCH 34/42] s390x: Add unpack facility feature to GA1
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-35-thuth@redhat.com>
+Patchwork-id: 97052
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 34/38] s390x: Add unpack facility feature to GA1
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+The unpack facility is an indication that diagnose 308 subcodes 8-10
+are available to the guest. That means, that the guest can put itself
+into protected mode.
+
+Once it is in protected mode, the hardware stops any attempt of VM
+introspection by the hypervisor.
+
+Some features are currently not supported in protected mode:
+     * vfio devices
+     * Migration
+     * Huge page backings
+
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-17-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 572c0826615737f1c095b1b6d9e381ec40f72eb5)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/gen-features.c | 1 +
+ target/s390x/kvm.c          | 8 ++++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
+index 6278845b12..8ddeebc544 100644
+--- a/target/s390x/gen-features.c
++++ b/target/s390x/gen-features.c
+@@ -562,6 +562,7 @@ static uint16_t full_GEN15_GA1[] = {
+     S390_FEAT_GROUP_MSA_EXT_9,
+     S390_FEAT_GROUP_MSA_EXT_9_PCKMO,
+     S390_FEAT_ETOKEN,
++    S390_FEAT_UNPACK,
+ };
+ 
+ /* Default features (in order of release)
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 56fe60c49c..84d7cadd09 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -2407,6 +2407,14 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
+         clear_bit(S390_FEAT_BPB, model->features);
+     }
+ 
++    /*
++     * If we have support for protected virtualization, indicate
++     * the protected virtualization IPL unpack facility.
++     */
++    if (cap_protected) {
++        set_bit(S390_FEAT_UNPACK, model->features);
++    }
++
+     /* We emulate a zPCI bus and AEN, therefore we don't need HW support */
+     set_bit(S390_FEAT_ZPCI, model->features);
+     set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Beautify-diag308-handling.patch b/SOURCES/kvm-s390x-Beautify-diag308-handling.patch
new file mode 100644
index 0000000..2ffe6a3
--- /dev/null
+++ b/SOURCES/kvm-s390x-Beautify-diag308-handling.patch
@@ -0,0 +1,130 @@
+From da81f2b579987ea12929f0ec803716bc16a93df7 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:49 -0400
+Subject: [PATCH 07/42] s390x: Beautify diag308 handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-8-thuth@redhat.com>
+Patchwork-id: 97022
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 07/38] s390x: Beautify diag308 handling
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Let's improve readability by:
+* Using constants for the subcodes
+* Moving parameter checking into a function
+* Removing subcode > 6 check as the default case catches that
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20191127175046.4911-6-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 0b7fd817e0f383760e37ca9286150d5816cf0594)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/diag.c | 54 +++++++++++++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 22 deletions(-)
+
+diff --git a/target/s390x/diag.c b/target/s390x/diag.c
+index 53c2f81f2a..b5aec06d6b 100644
+--- a/target/s390x/diag.c
++++ b/target/s390x/diag.c
+@@ -53,6 +53,29 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
+ #define DIAG_308_RC_NO_CONF         0x0102
+ #define DIAG_308_RC_INVALID         0x0402
+ 
++#define DIAG308_RESET_MOD_CLR       0
++#define DIAG308_RESET_LOAD_NORM     1
++#define DIAG308_LOAD_CLEAR          3
++#define DIAG308_LOAD_NORMAL_DUMP    4
++#define DIAG308_SET                 5
++#define DIAG308_STORE               6
++
++static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
++                              uintptr_t ra, bool write)
++{
++    if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) {
++        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
++        return -1;
++    }
++    if (!address_space_access_valid(&address_space_memory, addr,
++                                    sizeof(IplParameterBlock), write,
++                                    MEMTXATTRS_UNSPECIFIED)) {
++        s390_program_interrupt(env, PGM_ADDRESSING, ra);
++        return -1;
++    }
++    return 0;
++}
++
+ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+ {
+     CPUState *cs = env_cpu(env);
+@@ -65,30 +88,24 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+         return;
+     }
+ 
+-    if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
++    if (subcode & ~0x0ffffULL) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+     }
+ 
+     switch (subcode) {
+-    case 0:
++    case DIAG308_RESET_MOD_CLR:
+         s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
+         break;
+-    case 1:
++    case DIAG308_RESET_LOAD_NORM:
+         s390_ipl_reset_request(cs, S390_RESET_LOAD_NORMAL);
+         break;
+-    case 3:
++    case DIAG308_LOAD_CLEAR:
++        /* Well we still lack the clearing bit... */
+         s390_ipl_reset_request(cs, S390_RESET_REIPL);
+         break;
+-    case 5:
+-        if ((r1 & 1) || (addr & 0x0fffULL)) {
+-            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+-            return;
+-        }
+-        if (!address_space_access_valid(&address_space_memory, addr,
+-                                        sizeof(IplParameterBlock), false,
+-                                        MEMTXATTRS_UNSPECIFIED)) {
+-            s390_program_interrupt(env, PGM_ADDRESSING, ra);
++    case DIAG308_SET:
++        if (diag308_parm_check(env, r1, addr, ra, false)) {
+             return;
+         }
+         iplb = g_new0(IplParameterBlock, 1);
+@@ -110,15 +127,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+ out:
+         g_free(iplb);
+         return;
+-    case 6:
+-        if ((r1 & 1) || (addr & 0x0fffULL)) {
+-            s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+-            return;
+-        }
+-        if (!address_space_access_valid(&address_space_memory, addr,
+-                                        sizeof(IplParameterBlock), true,
+-                                        MEMTXATTRS_UNSPECIFIED)) {
+-            s390_program_interrupt(env, PGM_ADDRESSING, ra);
++    case DIAG308_STORE:
++        if (diag308_parm_check(env, r1, addr, ra, true)) {
+             return;
+         }
+         iplb = s390_ipl_get_iplb();
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Don-t-do-a-normal-reset-on-the-initial-cpu.patch b/SOURCES/kvm-s390x-Don-t-do-a-normal-reset-on-the-initial-cpu.patch
new file mode 100644
index 0000000..dab8acc
--- /dev/null
+++ b/SOURCES/kvm-s390x-Don-t-do-a-normal-reset-on-the-initial-cpu.patch
@@ -0,0 +1,52 @@
+From 511638161566d4944a572a31d787eb27bbc0bc8e Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:45 -0400
+Subject: [PATCH 03/42] s390x: Don't do a normal reset on the initial cpu
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-4-thuth@redhat.com>
+Patchwork-id: 97017
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 03/38] s390x: Don't do a normal reset on the initial cpu
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+The initiating cpu needs to be reset with an initial reset. While
+doing a normal reset followed by a initial reset is not wrong per se,
+the Ultravisor will only allow the correct reset to be performed.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20191127175046.4911-2-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit ec9227339fce99412830d44a37eb0bd2fadd5f75)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/s390-virtio-ccw.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index c2c83d2fce..4ea01c53c0 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -348,6 +348,9 @@ static void s390_machine_reset(MachineState *machine)
+         break;
+     case S390_RESET_LOAD_NORMAL:
+         CPU_FOREACH(t) {
++            if (t == cs) {
++                continue;
++            }
+             run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
+         }
+         subsystem_reset();
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Fix-cpu-normal-reset-ri-clearing.patch b/SOURCES/kvm-s390x-Fix-cpu-normal-reset-ri-clearing.patch
new file mode 100644
index 0000000..9b81586
--- /dev/null
+++ b/SOURCES/kvm-s390x-Fix-cpu-normal-reset-ri-clearing.patch
@@ -0,0 +1,101 @@
+From bdad28b11e36f657cb8909e7223a7d8fc0948c2e Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:51 -0400
+Subject: [PATCH 09/42] s390x: Fix cpu normal reset ri clearing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-10-thuth@redhat.com>
+Patchwork-id: 97029
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 09/38] s390x: Fix cpu normal reset ri clearing
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+As it turns out we need to clear the ri controls and PSW enablement
+bit to be architecture compliant.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20191203132813.2734-4-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit e893baee70149896d1e43e341da4d6c614037d5d)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu.c | 7 ++++++-
+ target/s390x/cpu.h | 7 ++++++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index bd39cb54b7..99ea09085a 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -100,7 +100,7 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+     case S390_CPU_RESET_INITIAL:
+         /* initial reset does not clear everything! */
+         memset(&env->start_initial_reset_fields, 0,
+-               offsetof(CPUS390XState, end_reset_fields) -
++               offsetof(CPUS390XState, start_normal_reset_fields) -
+                offsetof(CPUS390XState, start_initial_reset_fields));
+ 
+         /* architectured initial value for Breaking-Event-Address register */
+@@ -123,6 +123,11 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+                                   &env->fpu_status);
+        /* fall through */
+     case S390_CPU_RESET_NORMAL:
++        env->psw.mask &= ~PSW_MASK_RI;
++        memset(&env->start_normal_reset_fields, 0,
++               offsetof(CPUS390XState, end_reset_fields) -
++               offsetof(CPUS390XState, start_normal_reset_fields));
++
+         env->pfault_token = -1UL;
+         env->bpbc = false;
+         break;
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index d2af13b345..7e1c18d596 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -58,7 +58,6 @@ struct CPUS390XState {
+      */
+     uint64_t vregs[32][2] QEMU_ALIGNED(16);  /* vector registers */
+     uint32_t aregs[16];    /* access registers */
+-    uint8_t riccb[64];     /* runtime instrumentation control */
+     uint64_t gscb[4];      /* guarded storage control */
+     uint64_t etoken;       /* etoken */
+     uint64_t etoken_extension; /* etoken extension */
+@@ -114,6 +113,10 @@ struct CPUS390XState {
+     uint64_t gbea;
+     uint64_t pp;
+ 
++    /* Fields up to this point are not cleared by normal CPU reset */
++    struct {} start_normal_reset_fields;
++    uint8_t riccb[64];     /* runtime instrumentation control */
++
+     /* Fields up to this point are cleared by a CPU reset */
+     struct {} end_reset_fields;
+ 
+@@ -252,6 +255,7 @@ extern const VMStateDescription vmstate_s390_cpu;
+ #undef PSW_SHIFT_ASC
+ #undef PSW_MASK_CC
+ #undef PSW_MASK_PM
++#undef PSW_MASK_RI
+ #undef PSW_SHIFT_MASK_PM
+ #undef PSW_MASK_64
+ #undef PSW_MASK_32
+@@ -273,6 +277,7 @@ extern const VMStateDescription vmstate_s390_cpu;
+ #define PSW_MASK_CC             0x0000300000000000ULL
+ #define PSW_MASK_PM             0x00000F0000000000ULL
+ #define PSW_SHIFT_MASK_PM       40
++#define PSW_MASK_RI             0x0000008000000000ULL
+ #define PSW_MASK_64             0x0000000100000000ULL
+ #define PSW_MASK_32             0x0000000080000000ULL
+ #define PSW_MASK_ESA_ADDR       0x000000007fffffffULL
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Move-clear-reset.patch b/SOURCES/kvm-s390x-Move-clear-reset.patch
new file mode 100644
index 0000000..7c1614c
--- /dev/null
+++ b/SOURCES/kvm-s390x-Move-clear-reset.patch
@@ -0,0 +1,146 @@
+From f268cc7071ecb4322c03f3183acbcf90421da3c7 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:48 -0400
+Subject: [PATCH 06/42] s390x: Move clear reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-7-thuth@redhat.com>
+Patchwork-id: 97019
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 06/38] s390x: Move clear reset
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Let's also move the clear reset function into the reset handler.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Message-Id: <20191127175046.4911-5-frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit eb8adcc3e9e3b8405c104ede72cf9f3bb2a5e226)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu-qom.h |  1 +
+ target/s390x/cpu.c     | 58 +++++++++++++-----------------------------
+ 2 files changed, 18 insertions(+), 41 deletions(-)
+
+diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
+index 6f0a12042e..dbe5346ec9 100644
+--- a/target/s390x/cpu-qom.h
++++ b/target/s390x/cpu-qom.h
+@@ -37,6 +37,7 @@ typedef struct S390CPUDef S390CPUDef;
+ typedef enum cpu_reset_type {
+     S390_CPU_RESET_NORMAL,
+     S390_CPU_RESET_INITIAL,
++    S390_CPU_RESET_CLEAR,
+ } cpu_reset_type;
+ 
+ /**
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index ca62fe7685..bd39cb54b7 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -94,6 +94,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+     s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
+ 
+     switch (type) {
++    case S390_CPU_RESET_CLEAR:
++        memset(env, 0, offsetof(CPUS390XState, start_initial_reset_fields));
++        /* fall through */
+     case S390_CPU_RESET_INITIAL:
+         /* initial reset does not clear everything! */
+         memset(&env->start_initial_reset_fields, 0,
+@@ -107,6 +110,14 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+         env->cregs[0] = CR0_RESET;
+         env->cregs[14] = CR14_RESET;
+ 
++#if defined(CONFIG_USER_ONLY)
++        /* user mode should always be allowed to use the full FPU */
++        env->cregs[0] |= CR0_AFP;
++        if (s390_has_feat(S390_FEAT_VECTOR)) {
++            env->cregs[0] |= CR0_VECTOR;
++        }
++#endif
++
+         /* tininess for underflow is detected before rounding */
+         set_float_detect_tininess(float_tininess_before_rounding,
+                                   &env->fpu_status);
+@@ -125,46 +136,6 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+     }
+ }
+ 
+-/* CPUClass:reset() */
+-static void s390_cpu_full_reset(CPUState *s)
+-{
+-    S390CPU *cpu = S390_CPU(s);
+-    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
+-    CPUS390XState *env = &cpu->env;
+-
+-    scc->parent_reset(s);
+-    cpu->env.sigp_order = 0;
+-    s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
+-
+-    memset(env, 0, offsetof(CPUS390XState, end_reset_fields));
+-
+-    /* architectured initial values for CR 0 and 14 */
+-    env->cregs[0] = CR0_RESET;
+-    env->cregs[14] = CR14_RESET;
+-
+-#if defined(CONFIG_USER_ONLY)
+-    /* user mode should always be allowed to use the full FPU */
+-    env->cregs[0] |= CR0_AFP;
+-    if (s390_has_feat(S390_FEAT_VECTOR)) {
+-        env->cregs[0] |= CR0_VECTOR;
+-    }
+-#endif
+-
+-    /* architectured initial value for Breaking-Event-Address register */
+-    env->gbea = 1;
+-
+-    env->pfault_token = -1UL;
+-
+-    /* tininess for underflow is detected before rounding */
+-    set_float_detect_tininess(float_tininess_before_rounding,
+-                              &env->fpu_status);
+-
+-    /* Reset state inside the kernel that we cannot access yet from QEMU. */
+-    if (kvm_enabled()) {
+-        kvm_s390_reset_vcpu(cpu);
+-    }
+-}
+-
+ #if !defined(CONFIG_USER_ONLY)
+ static void s390_cpu_machine_reset_cb(void *opaque)
+ {
+@@ -456,6 +427,11 @@ static Property s390x_cpu_properties[] = {
+     DEFINE_PROP_END_OF_LIST()
+ };
+ 
++static void s390_cpu_reset_full(CPUState *s)
++{
++    return s390_cpu_reset(s, S390_CPU_RESET_CLEAR);
++}
++
+ static void s390_cpu_class_init(ObjectClass *oc, void *data)
+ {
+     S390CPUClass *scc = S390_CPU_CLASS(oc);
+@@ -472,7 +448,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
+     scc->load_normal = s390_cpu_load_normal;
+ #endif
+     scc->reset = s390_cpu_reset;
+-    cc->reset = s390_cpu_full_reset;
++    cc->reset = s390_cpu_reset_full;
+     cc->class_by_name = s390_cpu_class_by_name,
+     cc->has_work = s390_cpu_has_work;
+ #ifdef CONFIG_TCG
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Move-diagnose-308-subcodes-and-rcs-into-ipl.h.patch b/SOURCES/kvm-s390x-Move-diagnose-308-subcodes-and-rcs-into-ipl.h.patch
new file mode 100644
index 0000000..ac183cf
--- /dev/null
+++ b/SOURCES/kvm-s390x-Move-diagnose-308-subcodes-and-rcs-into-ipl.h.patch
@@ -0,0 +1,83 @@
+From c9eee8aeed39976293e0d857039fcf729b821e83 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:03 -0400
+Subject: [PATCH 21/42] s390x: Move diagnose 308 subcodes and rcs into ipl.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-22-thuth@redhat.com>
+Patchwork-id: 97032
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 21/38] s390x: Move diagnose 308 subcodes and rcs into ipl.h
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+They are part of the IPL process, so let's put them into the ipl
+header.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20200319131921.2367-2-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 9b39d29470e9dbef24ee842a44ea56bd92b855ea)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ipl.h      | 11 +++++++++++
+ target/s390x/diag.c | 11 -----------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
+index 3e44abe1c6..a5665e6bfd 100644
+--- a/hw/s390x/ipl.h
++++ b/hw/s390x/ipl.h
+@@ -159,6 +159,17 @@ struct S390IPLState {
+ typedef struct S390IPLState S390IPLState;
+ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
+ 
++#define DIAG_308_RC_OK              0x0001
++#define DIAG_308_RC_NO_CONF         0x0102
++#define DIAG_308_RC_INVALID         0x0402
++
++#define DIAG308_RESET_MOD_CLR       0
++#define DIAG308_RESET_LOAD_NORM     1
++#define DIAG308_LOAD_CLEAR          3
++#define DIAG308_LOAD_NORMAL_DUMP    4
++#define DIAG308_SET                 5
++#define DIAG308_STORE               6
++
+ #define S390_IPL_TYPE_FCP 0x00
+ #define S390_IPL_TYPE_CCW 0x02
+ #define S390_IPL_TYPE_QEMU_SCSI 0xff
+diff --git a/target/s390x/diag.c b/target/s390x/diag.c
+index 54e5670b3f..8aba6341f9 100644
+--- a/target/s390x/diag.c
++++ b/target/s390x/diag.c
+@@ -49,17 +49,6 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
+     return diag288_class->handle_timer(diag288, func, timeout);
+ }
+ 
+-#define DIAG_308_RC_OK              0x0001
+-#define DIAG_308_RC_NO_CONF         0x0102
+-#define DIAG_308_RC_INVALID         0x0402
+-
+-#define DIAG308_RESET_MOD_CLR       0
+-#define DIAG308_RESET_LOAD_NORM     1
+-#define DIAG308_LOAD_CLEAR          3
+-#define DIAG308_LOAD_NORMAL_DUMP    4
+-#define DIAG308_SET                 5
+-#define DIAG308_STORE               6
+-
+ static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
+                               uintptr_t ra, bool write)
+ {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Move-initial-reset.patch b/SOURCES/kvm-s390x-Move-initial-reset.patch
new file mode 100644
index 0000000..0f2e9ab
--- /dev/null
+++ b/SOURCES/kvm-s390x-Move-initial-reset.patch
@@ -0,0 +1,159 @@
+From 0d1c0adf25a323be0663863ebe44a6aefb5f7baf Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:47 -0400
+Subject: [PATCH 05/42] s390x: Move initial reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-6-thuth@redhat.com>
+Patchwork-id: 97024
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 05/38] s390x: Move initial reset
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Let's move the intial reset into the reset handler and cleanup
+afterwards.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20191128083723.11937-1-frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 81b9222358e5c8f666f0d86057c75e40531d804c)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu-qom.h |  2 +-
+ target/s390x/cpu.c     | 46 +++++++++++++++++-------------------------
+ target/s390x/cpu.h     |  2 +-
+ target/s390x/sigp.c    |  2 +-
+ 4 files changed, 21 insertions(+), 31 deletions(-)
+
+diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
+index f3b71bac67..6f0a12042e 100644
+--- a/target/s390x/cpu-qom.h
++++ b/target/s390x/cpu-qom.h
+@@ -36,6 +36,7 @@ typedef struct S390CPUDef S390CPUDef;
+ 
+ typedef enum cpu_reset_type {
+     S390_CPU_RESET_NORMAL,
++    S390_CPU_RESET_INITIAL,
+ } cpu_reset_type;
+ 
+ /**
+@@ -62,7 +63,6 @@ typedef struct S390CPUClass {
+     void (*parent_reset)(CPUState *cpu);
+     void (*load_normal)(CPUState *cpu);
+     void (*reset)(CPUState *cpu, cpu_reset_type type);
+-    void (*initial_cpu_reset)(CPUState *cpu);
+ } S390CPUClass;
+ 
+ typedef struct S390CPU S390CPU;
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index 67d6fbfa44..ca62fe7685 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -94,6 +94,23 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+     s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
+ 
+     switch (type) {
++    case S390_CPU_RESET_INITIAL:
++        /* initial reset does not clear everything! */
++        memset(&env->start_initial_reset_fields, 0,
++               offsetof(CPUS390XState, end_reset_fields) -
++               offsetof(CPUS390XState, start_initial_reset_fields));
++
++        /* architectured initial value for Breaking-Event-Address register */
++        env->gbea = 1;
++
++        /* architectured initial values for CR 0 and 14 */
++        env->cregs[0] = CR0_RESET;
++        env->cregs[14] = CR14_RESET;
++
++        /* tininess for underflow is detected before rounding */
++        set_float_detect_tininess(float_tininess_before_rounding,
++                                  &env->fpu_status);
++       /* fall through */
+     case S390_CPU_RESET_NORMAL:
+         env->pfault_token = -1UL;
+         env->bpbc = false;
+@@ -101,35 +118,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+     default:
+         g_assert_not_reached();
+     }
+-}
+-
+-/* S390CPUClass::initial_reset() */
+-static void s390_cpu_initial_reset(CPUState *s)
+-{
+-    S390CPU *cpu = S390_CPU(s);
+-    CPUS390XState *env = &cpu->env;
+-
+-    s390_cpu_reset(s, S390_CPU_RESET_NORMAL);
+-    /* initial reset does not clear everything! */
+-    memset(&env->start_initial_reset_fields, 0,
+-        offsetof(CPUS390XState, end_reset_fields) -
+-        offsetof(CPUS390XState, start_initial_reset_fields));
+-
+-    /* architectured initial values for CR 0 and 14 */
+-    env->cregs[0] = CR0_RESET;
+-    env->cregs[14] = CR14_RESET;
+-
+-    /* architectured initial value for Breaking-Event-Address register */
+-    env->gbea = 1;
+-
+-    env->pfault_token = -1UL;
+-
+-    /* tininess for underflow is detected before rounding */
+-    set_float_detect_tininess(float_tininess_before_rounding,
+-                              &env->fpu_status);
+ 
+     /* Reset state inside the kernel that we cannot access yet from QEMU. */
+-    if (kvm_enabled()) {
++    if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
+         kvm_s390_reset_vcpu(cpu);
+     }
+ }
+@@ -481,7 +472,6 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
+     scc->load_normal = s390_cpu_load_normal;
+ #endif
+     scc->reset = s390_cpu_reset;
+-    scc->initial_cpu_reset = s390_cpu_initial_reset;
+     cc->reset = s390_cpu_full_reset;
+     cc->class_by_name = s390_cpu_class_by_name,
+     cc->has_work = s390_cpu_has_work;
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 18123dfd5b..d2af13b345 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -748,7 +748,7 @@ static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
+ {
+     S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
+ 
+-    scc->initial_cpu_reset(cs);
++    scc->reset(cs, S390_CPU_RESET_INITIAL);
+ }
+ 
+ static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
+diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
+index 850139b9cd..727875bb4a 100644
+--- a/target/s390x/sigp.c
++++ b/target/s390x/sigp.c
+@@ -254,7 +254,7 @@ static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
+     SigpInfo *si = arg.host_ptr;
+ 
+     cpu_synchronize_state(cs);
+-    scc->initial_cpu_reset(cs);
++    scc->reset(cs, S390_CPU_RESET_INITIAL);
+     cpu_synchronize_post_reset(cs);
+     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
+ }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Move-reset-normal-to-shared-reset-handler.patch b/SOURCES/kvm-s390x-Move-reset-normal-to-shared-reset-handler.patch
new file mode 100644
index 0000000..81a4368
--- /dev/null
+++ b/SOURCES/kvm-s390x-Move-reset-normal-to-shared-reset-handler.patch
@@ -0,0 +1,145 @@
+From 53b5a7f83f3e6b94c66cbbb97ea42bbf02cb96b4 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:46 -0400
+Subject: [PATCH 04/42] s390x: Move reset normal to shared reset handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-5-thuth@redhat.com>
+Patchwork-id: 97018
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 04/38] s390x: Move reset normal to shared reset handler
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Let's start moving the cpu reset functions into a single function with
+a switch/case, so we can later use fallthroughs and share more code
+between resets.
+
+This patch introduces the reset function by renaming cpu_reset().
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20191127175046.4911-3-frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit eac4f82791f1807c423e85670837db103b9d59b3)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu-qom.h |  6 +++++-
+ target/s390x/cpu.c     | 19 +++++++++++++------
+ target/s390x/cpu.h     |  2 +-
+ target/s390x/sigp.c    |  2 +-
+ 4 files changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
+index b809ec8418..f3b71bac67 100644
+--- a/target/s390x/cpu-qom.h
++++ b/target/s390x/cpu-qom.h
+@@ -34,6 +34,10 @@
+ typedef struct S390CPUModel S390CPUModel;
+ typedef struct S390CPUDef S390CPUDef;
+ 
++typedef enum cpu_reset_type {
++    S390_CPU_RESET_NORMAL,
++} cpu_reset_type;
++
+ /**
+  * S390CPUClass:
+  * @parent_realize: The parent class' realize handler.
+@@ -57,7 +61,7 @@ typedef struct S390CPUClass {
+     DeviceRealize parent_realize;
+     void (*parent_reset)(CPUState *cpu);
+     void (*load_normal)(CPUState *cpu);
+-    void (*cpu_reset)(CPUState *cpu);
++    void (*reset)(CPUState *cpu, cpu_reset_type type);
+     void (*initial_cpu_reset)(CPUState *cpu);
+ } S390CPUClass;
+ 
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index 3abe7e80fd..67d6fbfa44 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -82,18 +82,25 @@ static void s390_cpu_load_normal(CPUState *s)
+ }
+ #endif
+ 
+-/* S390CPUClass::cpu_reset() */
+-static void s390_cpu_reset(CPUState *s)
++/* S390CPUClass::reset() */
++static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
+ {
+     S390CPU *cpu = S390_CPU(s);
+     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
+     CPUS390XState *env = &cpu->env;
+ 
+-    env->pfault_token = -1UL;
+-    env->bpbc = false;
+     scc->parent_reset(s);
+     cpu->env.sigp_order = 0;
+     s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
++
++    switch (type) {
++    case S390_CPU_RESET_NORMAL:
++        env->pfault_token = -1UL;
++        env->bpbc = false;
++        break;
++    default:
++        g_assert_not_reached();
++    }
+ }
+ 
+ /* S390CPUClass::initial_reset() */
+@@ -102,7 +109,7 @@ static void s390_cpu_initial_reset(CPUState *s)
+     S390CPU *cpu = S390_CPU(s);
+     CPUS390XState *env = &cpu->env;
+ 
+-    s390_cpu_reset(s);
++    s390_cpu_reset(s, S390_CPU_RESET_NORMAL);
+     /* initial reset does not clear everything! */
+     memset(&env->start_initial_reset_fields, 0,
+         offsetof(CPUS390XState, end_reset_fields) -
+@@ -473,7 +480,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
+ #if !defined(CONFIG_USER_ONLY)
+     scc->load_normal = s390_cpu_load_normal;
+ #endif
+-    scc->cpu_reset = s390_cpu_reset;
++    scc->reset = s390_cpu_reset;
+     scc->initial_cpu_reset = s390_cpu_initial_reset;
+     cc->reset = s390_cpu_full_reset;
+     cc->class_by_name = s390_cpu_class_by_name,
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 17460ed7b3..18123dfd5b 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -741,7 +741,7 @@ static inline void s390_do_cpu_reset(CPUState *cs, run_on_cpu_data arg)
+ {
+     S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
+ 
+-    scc->cpu_reset(cs);
++    scc->reset(cs, S390_CPU_RESET_NORMAL);
+ }
+ 
+ static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
+diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
+index 2ce22d4dc1..850139b9cd 100644
+--- a/target/s390x/sigp.c
++++ b/target/s390x/sigp.c
+@@ -266,7 +266,7 @@ static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
+     SigpInfo *si = arg.host_ptr;
+ 
+     cpu_synchronize_state(cs);
+-    scc->cpu_reset(cs);
++    scc->reset(cs, S390_CPU_RESET_NORMAL);
+     cpu_synchronize_post_reset(cs);
+     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
+ }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Properly-fetch-and-test-the-short-psw-on-diag3.patch b/SOURCES/kvm-s390x-Properly-fetch-and-test-the-short-psw-on-diag3.patch
new file mode 100644
index 0000000..9447240
--- /dev/null
+++ b/SOURCES/kvm-s390x-Properly-fetch-and-test-the-short-psw-on-diag3.patch
@@ -0,0 +1,70 @@
+From 7171a794e8a7d91805516174187addc3b8e6b423 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:54 -0400
+Subject: [PATCH 12/42] s390x: Properly fetch and test the short psw on diag308
+ subc 0/1
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-13-thuth@redhat.com>
+Patchwork-id: 97025
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 12/38] s390x: Properly fetch and test the short psw on diag308 subc 0/1
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+We need to actually fetch the cpu mask and set it. As we invert the
+short psw indication in the mask, SIE will report a specification
+exception, if it wasn't present in the reset psw.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20191129142025.21453-2-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 104130cb7c106378dab944397c6a455c4a6d552f)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu.c | 12 ++++++++++--
+ target/s390x/cpu.h |  1 +
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index 99ea09085a..625daeedd1 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -76,8 +76,16 @@ static bool s390_cpu_has_work(CPUState *cs)
+ static void s390_cpu_load_normal(CPUState *s)
+ {
+     S390CPU *cpu = S390_CPU(s);
+-    cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR;
+-    cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
++    uint64_t spsw = ldq_phys(s->as, 0);
++
++    cpu->env.psw.mask = spsw & 0xffffffff80000000ULL;
++    /*
++     * Invert short psw indication, so SIE will report a specification
++     * exception if it was not set.
++     */
++    cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
++    cpu->env.psw.addr = spsw & 0x7fffffffULL;
++
+     s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
+ }
+ #endif
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 7e1c18d596..7f5fa1d35b 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -269,6 +269,7 @@ extern const VMStateDescription vmstate_s390_cpu;
+ #define PSW_MASK_EXT            0x0100000000000000ULL
+ #define PSW_MASK_KEY            0x00F0000000000000ULL
+ #define PSW_SHIFT_KEY           52
++#define PSW_MASK_SHORTPSW       0x0008000000000000ULL
+ #define PSW_MASK_MCHECK         0x0004000000000000ULL
+ #define PSW_MASK_WAIT           0x0002000000000000ULL
+ #define PSW_MASK_PSTATE         0x0001000000000000ULL
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-Rename-and-use-constants-for-short-PSW-address.patch b/SOURCES/kvm-s390x-Rename-and-use-constants-for-short-PSW-address.patch
new file mode 100644
index 0000000..b1c7e01
--- /dev/null
+++ b/SOURCES/kvm-s390x-Rename-and-use-constants-for-short-PSW-address.patch
@@ -0,0 +1,87 @@
+From 4bd5ae889376816238ecad1bce054b0e198cde2b Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:55 -0400
+Subject: [PATCH 13/42] s390x: Rename and use constants for short PSW address
+ and mask
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-14-thuth@redhat.com>
+Patchwork-id: 97050
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 13/38] s390x: Rename and use constants for short PSW address and mask
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Let's rename PSW_MASK_ESA_ADDR to PSW_MASK_SHORT_ADDR because we're
+not working with a ESA PSW which would not support the extended
+addressing bit. Also let's actually use it.
+
+Additionally we introduce PSW_MASK_SHORT_CTRL and use it throughout
+the codebase.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20200227092341.38558-1-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit b6c2dbd7214b0b2396e1dcf9668c8b48ab571115)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ipl.c     | 2 +-
+ target/s390x/cpu.c | 4 ++--
+ target/s390x/cpu.h | 3 ++-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
+index ca544d64c5..0b7548a549 100644
+--- a/hw/s390x/ipl.c
++++ b/hw/s390x/ipl.c
+@@ -179,7 +179,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
+                 /* if not Linux load the address of the (short) IPL PSW */
+                 ipl_psw = rom_ptr(4, 4);
+                 if (ipl_psw) {
+-                    pentry = be32_to_cpu(*ipl_psw) & 0x7fffffffUL;
++                    pentry = be32_to_cpu(*ipl_psw) & PSW_MASK_SHORT_ADDR;
+                 } else {
+                     error_setg(&err, "Could not get IPL PSW");
+                     goto error;
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index 625daeedd1..e538a4a3e2 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -78,13 +78,13 @@ static void s390_cpu_load_normal(CPUState *s)
+     S390CPU *cpu = S390_CPU(s);
+     uint64_t spsw = ldq_phys(s->as, 0);
+ 
+-    cpu->env.psw.mask = spsw & 0xffffffff80000000ULL;
++    cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
+     /*
+      * Invert short psw indication, so SIE will report a specification
+      * exception if it was not set.
+      */
+     cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
+-    cpu->env.psw.addr = spsw & 0x7fffffffULL;
++    cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
+ 
+     s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
+ }
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 7f5fa1d35b..1ff84e6b3a 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -281,7 +281,8 @@ extern const VMStateDescription vmstate_s390_cpu;
+ #define PSW_MASK_RI             0x0000008000000000ULL
+ #define PSW_MASK_64             0x0000000100000000ULL
+ #define PSW_MASK_32             0x0000000080000000ULL
+-#define PSW_MASK_ESA_ADDR       0x000000007fffffffULL
++#define PSW_MASK_SHORT_ADDR     0x000000007fffffffULL
++#define PSW_MASK_SHORT_CTRL     0xffffffff80000000ULL
+ 
+ #undef PSW_ASC_PRIMARY
+ #undef PSW_ASC_ACCREG
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-css-Refactor-the-css_queue_crw-routine.patch b/SOURCES/kvm-s390x-css-Refactor-the-css_queue_crw-routine.patch
new file mode 100644
index 0000000..8ce7625
--- /dev/null
+++ b/SOURCES/kvm-s390x-css-Refactor-the-css_queue_crw-routine.patch
@@ -0,0 +1,119 @@
+From 04d4e7eda95316b64ea9dc0f4ca8801d531652e7 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:41 -0400
+Subject: [PATCH 07/12] s390x/css: Refactor the css_queue_crw() routine
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-8-cohuck@redhat.com>
+Patchwork-id: 97700
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 7/9] s390x/css: Refactor the css_queue_crw() routine
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Eric Farman <farman@linux.ibm.com>
+
+We have a use case (vfio-ccw) where a CRW is already built and
+ready to use.  Rather than teasing out the components just to
+reassemble it later, let's rework this code so we can queue a
+fully-qualified CRW directly.
+
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200505125757.98209-6-farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit f6dde1b012e678aa64339520ef7519ec04026cf1)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/css.c         | 44 ++++++++++++++++++++++++++++--------------
+ include/hw/s390x/css.h |  1 +
+ 2 files changed, 30 insertions(+), 15 deletions(-)
+
+diff --git a/hw/s390x/css.c b/hw/s390x/css.c
+index 71fd3f9a00..a8de8a0c84 100644
+--- a/hw/s390x/css.c
++++ b/hw/s390x/css.c
+@@ -2170,30 +2170,23 @@ void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
+     }
+ }
+ 
+-void css_queue_crw(uint8_t rsc, uint8_t erc, int solicited,
+-                   int chain, uint16_t rsid)
++void css_crw_add_to_queue(CRW crw)
+ {
+     CrwContainer *crw_cont;
+ 
+-    trace_css_crw(rsc, erc, rsid, chain ? "(chained)" : "");
++    trace_css_crw((crw.flags & CRW_FLAGS_MASK_RSC) >> 8,
++                  crw.flags & CRW_FLAGS_MASK_ERC,
++                  crw.rsid,
++                  (crw.flags & CRW_FLAGS_MASK_C) ? "(chained)" : "");
++
+     /* TODO: Maybe use a static crw pool? */
+     crw_cont = g_try_new0(CrwContainer, 1);
+     if (!crw_cont) {
+         channel_subsys.crws_lost = true;
+         return;
+     }
+-    crw_cont->crw.flags = (rsc << 8) | erc;
+-    if (solicited) {
+-        crw_cont->crw.flags |= CRW_FLAGS_MASK_S;
+-    }
+-    if (chain) {
+-        crw_cont->crw.flags |= CRW_FLAGS_MASK_C;
+-    }
+-    crw_cont->crw.rsid = rsid;
+-    if (channel_subsys.crws_lost) {
+-        crw_cont->crw.flags |= CRW_FLAGS_MASK_R;
+-        channel_subsys.crws_lost = false;
+-    }
++
++    crw_cont->crw = crw;
+ 
+     QTAILQ_INSERT_TAIL(&channel_subsys.pending_crws, crw_cont, sibling);
+ 
+@@ -2204,6 +2197,27 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int solicited,
+     }
+ }
+ 
++void css_queue_crw(uint8_t rsc, uint8_t erc, int solicited,
++                   int chain, uint16_t rsid)
++{
++    CRW crw;
++
++    crw.flags = (rsc << 8) | erc;
++    if (solicited) {
++        crw.flags |= CRW_FLAGS_MASK_S;
++    }
++    if (chain) {
++        crw.flags |= CRW_FLAGS_MASK_C;
++    }
++    crw.rsid = rsid;
++    if (channel_subsys.crws_lost) {
++        crw.flags |= CRW_FLAGS_MASK_R;
++        channel_subsys.crws_lost = false;
++    }
++
++    css_crw_add_to_queue(crw);
++}
++
+ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
+                            int hotplugged, int add)
+ {
+diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
+index 7e3a5e7433..08c869ab0a 100644
+--- a/include/hw/s390x/css.h
++++ b/include/hw/s390x/css.h
+@@ -205,6 +205,7 @@ void copy_scsw_to_guest(SCSW *dest, const SCSW *src);
+ void css_inject_io_interrupt(SubchDev *sch);
+ void css_reset(void);
+ void css_reset_sch(SubchDev *sch);
++void css_crw_add_to_queue(CRW crw);
+ void css_queue_crw(uint8_t rsc, uint8_t erc, int solicited,
+                    int chain, uint16_t rsid);
+ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-ipl-Consolidate-iplb-validity-check-into-one-f.patch b/SOURCES/kvm-s390x-ipl-Consolidate-iplb-validity-check-into-one-f.patch
new file mode 100644
index 0000000..8b9294e
--- /dev/null
+++ b/SOURCES/kvm-s390x-ipl-Consolidate-iplb-validity-check-into-one-f.patch
@@ -0,0 +1,82 @@
+From 536b6081c0739bebbb33583370f62116d0cb42da Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:01 -0400
+Subject: [PATCH 19/42] s390x: ipl: Consolidate iplb validity check into one
+ function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-20-thuth@redhat.com>
+Patchwork-id: 97038
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 19/38] s390x: ipl: Consolidate iplb validity check into one function
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+It's nicer to just call one function than calling a function for each
+possible iplb type.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20200310090950.61172-1-frankja@linux.ibm.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+(cherry picked from commit 94c21436e5a89143f8b9cb4d089d1a2f3f4fd377)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ipl.h      | 18 +++++++++---------
+ target/s390x/diag.c |  2 +-
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
+index d4813105db..3e44abe1c6 100644
+--- a/hw/s390x/ipl.h
++++ b/hw/s390x/ipl.h
+@@ -173,16 +173,16 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb)
+     return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
+ }
+ 
+-static inline bool iplb_valid_ccw(IplParameterBlock *iplb)
++static inline bool iplb_valid(IplParameterBlock *iplb)
+ {
+-    return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN &&
+-           iplb->pbt == S390_IPL_TYPE_CCW;
+-}
+-
+-static inline bool iplb_valid_fcp(IplParameterBlock *iplb)
+-{
+-    return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN &&
+-           iplb->pbt == S390_IPL_TYPE_FCP;
++    switch (iplb->pbt) {
++    case S390_IPL_TYPE_FCP:
++        return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN;
++    case S390_IPL_TYPE_CCW:
++        return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN;
++    default:
++        return false;
++    }
+ }
+ 
+ #endif
+diff --git a/target/s390x/diag.c b/target/s390x/diag.c
+index b5aec06d6b..54e5670b3f 100644
+--- a/target/s390x/diag.c
++++ b/target/s390x/diag.c
+@@ -117,7 +117,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+ 
+         cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
+ 
+-        if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
++        if (!iplb_valid(iplb)) {
+             env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+             goto out;
+         }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-kvm-Make-kvm_sclp_service_call-void.patch b/SOURCES/kvm-s390x-kvm-Make-kvm_sclp_service_call-void.patch
new file mode 100644
index 0000000..9882324
--- /dev/null
+++ b/SOURCES/kvm-s390x-kvm-Make-kvm_sclp_service_call-void.patch
@@ -0,0 +1,83 @@
+From 999cf62d870ff9aa8e9609fcbbcefef9ae1aceb6 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:50 -0400
+Subject: [PATCH 08/42] s390x: kvm: Make kvm_sclp_service_call void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-9-thuth@redhat.com>
+Patchwork-id: 97030
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 08/38] s390x: kvm: Make kvm_sclp_service_call void
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+It defaults to returning 0 anyway and that return value is not
+necessary, as 0 is also the default rc that the caller would return.
+
+While doing that we can simplify the logic a bit and return early if
+we inject a PGM exception.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <20191129091713.4582-1-frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 15b6c0370c3e2774fd9ffda5c10c6e36952e8eb6)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/kvm.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index a02d569537..1c5bc7a2f9 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -1159,13 +1159,13 @@ void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code)
+     kvm_s390_vcpu_interrupt(cpu, &irq);
+ }
+ 
+-static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
++static void kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
+                                  uint16_t ipbh0)
+ {
+     CPUS390XState *env = &cpu->env;
+     uint64_t sccb;
+     uint32_t code;
+-    int r = 0;
++    int r;
+ 
+     sccb = env->regs[ipbh0 & 0xf];
+     code = env->regs[(ipbh0 & 0xf0) >> 4];
+@@ -1173,11 +1173,9 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
+     r = sclp_service_call(env, sccb, code);
+     if (r < 0) {
+         kvm_s390_program_interrupt(cpu, -r);
+-    } else {
+-        setcc(cpu, r);
++        return;
+     }
+-
+-    return 0;
++    setcc(cpu, r);
+ }
+ 
+ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
+@@ -1240,7 +1238,7 @@ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
+         setcc(cpu, 3);
+         break;
+     case PRIV_B2_SCLP_CALL:
+-        rc = kvm_sclp_service_call(cpu, run, ipbh0);
++        kvm_sclp_service_call(cpu, run, ipbh0);
+         break;
+     default:
+         rc = -1;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Add-migration-blocker.patch b/SOURCES/kvm-s390x-protvirt-Add-migration-blocker.patch
new file mode 100644
index 0000000..056f8d5
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Add-migration-blocker.patch
@@ -0,0 +1,79 @@
+From 0ba8d4ea1cc34230356cc446dfa8d1cb52cbd2f3 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:05 -0400
+Subject: [PATCH 23/42] s390x: protvirt: Add migration blocker
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-24-thuth@redhat.com>
+Patchwork-id: 97043
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 23/38] s390x: protvirt: Add migration blocker
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Migration is not yet supported.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-5-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 0141e1b47707d90f5bd9d252da064ebdaca698a6)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/s390-virtio-ccw.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index 82da1d9ab5..dbd5125232 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -44,6 +44,9 @@
+ #include "sysemu/sysemu.h"
+ #include "hw/s390x/pv.h"
+ #include <linux/kvm.h>
++#include "migration/blocker.h"
++
++static Error *pv_mig_blocker;
+ 
+ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
+ {
+@@ -325,15 +328,30 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
+ {
+     s390_pv_vm_disable();
+     ms->pv = false;
++    migrate_del_blocker(pv_mig_blocker);
++    error_free_or_abort(&pv_mig_blocker);
+ }
+ 
+ static int s390_machine_protect(S390CcwMachineState *ms)
+ {
++    Error *local_err = NULL;
+     int rc;
+ 
++    error_setg(&pv_mig_blocker,
++               "protected VMs are currently not migrateable.");
++    rc = migrate_add_blocker(pv_mig_blocker, &local_err);
++    if (rc) {
++        error_report_err(local_err);
++        error_free_or_abort(&pv_mig_blocker);
++        return rc;
++    }
++
+     /* Create SE VM */
+     rc = s390_pv_vm_enable();
+     if (rc) {
++        error_report_err(local_err);
++        migrate_del_blocker(pv_mig_blocker);
++        error_free_or_abort(&pv_mig_blocker);
+         return rc;
+     }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Disable-address-checks-for-PV-guest-I.patch b/SOURCES/kvm-s390x-protvirt-Disable-address-checks-for-PV-guest-I.patch
new file mode 100644
index 0000000..0cf75b0
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Disable-address-checks-for-PV-guest-I.patch
@@ -0,0 +1,135 @@
+From 1cfcff169f392179258e4535e60d4ef9cabae3c6 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:13 -0400
+Subject: [PATCH 31/42] s390x: protvirt: Disable address checks for PV guest IO
+ emulation
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-32-thuth@redhat.com>
+Patchwork-id: 97044
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 31/38] s390x: protvirt: Disable address checks for PV guest IO emulation
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+IO instruction data is routed through SIDAD for protected guests, so
+adresses do not need to be checked, as this is kernel memory which is
+always available.
+
+Also the instruction data always starts at offset 0 of the SIDAD.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-13-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit c10b708752e5264a85b5c3afa0a0ccfcf6503ddf)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/ioinst.c | 35 ++++++++++++++++++++++++++++-------
+ 1 file changed, 28 insertions(+), 7 deletions(-)
+
+diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
+index c437a1d8c6..bbcccf6be2 100644
+--- a/target/s390x/ioinst.c
++++ b/target/s390x/ioinst.c
+@@ -16,6 +16,25 @@
+ #include "hw/s390x/ioinst.h"
+ #include "trace.h"
+ #include "hw/s390x/s390-pci-bus.h"
++#include "hw/s390x/pv.h"
++
++/* All I/O instructions but chsc use the s format */
++static uint64_t get_address_from_regs(CPUS390XState *env, uint32_t ipb,
++                                      uint8_t *ar)
++{
++    /*
++     * Addresses for protected guests are all offsets into the
++     * satellite block which holds the IO control structures. Those
++     * control structures are always starting at offset 0 and are
++     * always aligned and accessible. So we can return 0 here which
++     * will pass the following address checks.
++     */
++    if (s390_is_pv()) {
++        *ar = 0;
++        return 0;
++    }
++    return decode_basedisp_s(env, ipb, ar);
++}
+ 
+ int ioinst_disassemble_sch_ident(uint32_t value, int *m, int *cssid, int *ssid,
+                                  int *schid)
+@@ -114,7 +133,7 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+     CPUS390XState *env = &cpu->env;
+     uint8_t ar;
+ 
+-    addr = decode_basedisp_s(env, ipb, &ar);
++    addr = get_address_from_regs(env, ipb, &ar);
+     if (addr & 3) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+@@ -171,7 +190,7 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+     CPUS390XState *env = &cpu->env;
+     uint8_t ar;
+ 
+-    addr = decode_basedisp_s(env, ipb, &ar);
++    addr = get_address_from_regs(env, ipb, &ar);
+     if (addr & 3) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+@@ -203,7 +222,7 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
+     CPUS390XState *env = &cpu->env;
+     uint8_t ar;
+ 
+-    addr = decode_basedisp_s(env, ipb, &ar);
++    addr = get_address_from_regs(env, ipb, &ar);
+     if (addr & 3) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+@@ -234,7 +253,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
+     CPUS390XState *env = &cpu->env;
+     uint8_t ar;
+ 
+-    addr = decode_basedisp_s(env, ipb, &ar);
++    addr = get_address_from_regs(env, ipb, &ar);
+     if (addr & 3) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+@@ -303,7 +322,7 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+         return -EIO;
+     }
+     trace_ioinst_sch_id("tsch", cssid, ssid, schid);
+-    addr = decode_basedisp_s(env, ipb, &ar);
++    addr = get_address_from_regs(env, ipb, &ar);
+     if (addr & 3) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return -EIO;
+@@ -601,7 +620,7 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
+ {
+     ChscReq *req;
+     ChscResp *res;
+-    uint64_t addr;
++    uint64_t addr = 0;
+     int reg;
+     uint16_t len;
+     uint16_t command;
+@@ -610,7 +629,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
+ 
+     trace_ioinst("chsc");
+     reg = (ipb >> 20) & 0x00f;
+-    addr = env->regs[reg];
++    if (!s390_is_pv()) {
++        addr = env->regs[reg];
++    }
+     /* Page boundary? */
+     if (addr & 0xfff) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Fix-stray-error_report_err-in-s390_ma.patch b/SOURCES/kvm-s390x-protvirt-Fix-stray-error_report_err-in-s390_ma.patch
new file mode 100644
index 0000000..9857f28
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Fix-stray-error_report_err-in-s390_ma.patch
@@ -0,0 +1,55 @@
+From b54e5e6df5d5bbe4dc0a206be9f6b6d971ce6f43 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:17 -0400
+Subject: [PATCH 35/42] s390x: protvirt: Fix stray error_report_err in
+ s390_machine_protect
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-36-thuth@redhat.com>
+Patchwork-id: 97042
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 35/38] s390x: protvirt: Fix stray error_report_err in s390_machine_protect
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+In case the protection of the machine fails at s390_pv_vm_enable(),
+we'll currently report the local_error variable. Problem is that
+there's no migration blocker error that we can report at this point so
+the pointer is always NULL which leads to a SEGFAULT.
+
+Let's remove the error report.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Fixes: 0141e1b47707 ("s390x: protvirt: Add migration blocker")
+Message-Id: <20200326140505.2432-1-frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 7152c9ecc6530ea145c122b0a58cc28802f630c6)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/s390-virtio-ccw.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index b4ebe83766..c08e42bda1 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -360,7 +360,6 @@ static int s390_machine_protect(S390CcwMachineState *ms)
+     rc = s390_pv_vm_enable();
+     if (rc) {
+         qemu_balloon_inhibit(false);
+-        error_report_err(local_err);
+         migrate_del_blocker(pv_mig_blocker);
+         error_free_or_abort(&pv_mig_blocker);
+         return rc;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Handle-SIGP-store-status-correctly.patch b/SOURCES/kvm-s390x-protvirt-Handle-SIGP-store-status-correctly.patch
new file mode 100644
index 0000000..4d6a44b
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Handle-SIGP-store-status-correctly.patch
@@ -0,0 +1,61 @@
+From 680154545d1f9d75fb33615b1900661e7d09be4e Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:15 -0400
+Subject: [PATCH 33/42] s390x: protvirt: Handle SIGP store status correctly
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-34-thuth@redhat.com>
+Patchwork-id: 97054
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 33/38] s390x: protvirt: Handle SIGP store status correctly
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+For protected VMs status storing is not done by QEMU anymore.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-15-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit f2a2d9a2bae8f6fdc5e9a40c1241e9428f15b4df)
+[thuth: fixed contextual conflict due to missing commit 44eaccd091a7365fd37)
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/helper.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/target/s390x/helper.c b/target/s390x/helper.c
+index 6808dfda01..36b6d3d9d1 100644
+--- a/target/s390x/helper.c
++++ b/target/s390x/helper.c
+@@ -25,6 +25,7 @@
+ #include "qemu/timer.h"
+ #include "qemu/qemu-print.h"
+ #include "hw/s390x/ioinst.h"
++#include "hw/s390x/pv.h"
+ #include "sysemu/hw_accel.h"
+ #include "sysemu/runstate.h"
+ #ifndef CONFIG_USER_ONLY
+@@ -246,6 +247,11 @@ int s390_store_status(S390CPU *cpu, hwaddr addr, bool store_arch)
+     hwaddr len = sizeof(*sa);
+     int i;
+ 
++    /* For PVMs storing will occur when this cpu enters SIE again */
++    if (s390_is_pv()) {
++        return 0;
++    }
++
+     sa = cpu_physical_memory_map(addr, &len, 1);
+     if (!sa) {
+         return -EFAULT;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Inhibit-balloon-when-switching-to-pro.patch b/SOURCES/kvm-s390x-protvirt-Inhibit-balloon-when-switching-to-pro.patch
new file mode 100644
index 0000000..a843d03
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Inhibit-balloon-when-switching-to-pro.patch
@@ -0,0 +1,104 @@
+From 095553f9dd1fec02869bf974e8cc07614d6587e5 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:06 -0400
+Subject: [PATCH 24/42] s390x: protvirt: Inhibit balloon when switching to
+ protected mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-25-thuth@redhat.com>
+Patchwork-id: 97036
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 24/38] s390x: protvirt: Inhibit balloon when switching to protected mode
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Ballooning in protected VMs can only be done when the guest shares the
+pages it gives to the host. If pages are not shared, the integrity
+checks will fail once those pages have been altered and are given back
+to the guest.
+
+As we currently do not yet have a solution for this we will continue
+like this:
+
+1. We block ballooning now in QEMU (with this patch).
+
+2. Later we will provide a change to virtio that removes the blocker
+and adds VIRTIO_F_IOMMU_PLATFORM automatically by QEMU when doing the
+protvirt switch. This is OK, as the balloon driver in Linux (the only
+supported guest) will refuse to work with the IOMMU_PLATFORM feature
+bit set.
+
+3. Later, we can fix the guest balloon driver to accept the IOMMU
+feature bit and correctly exercise sharing and unsharing of balloon
+pages.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-6-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit b1697f63fd8f8201b1447bb55f595830b9cbde31)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/s390-virtio-ccw.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index dbd5125232..b4ebe83766 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -42,6 +42,7 @@
+ #include "hw/qdev-properties.h"
+ #include "hw/s390x/tod.h"
+ #include "sysemu/sysemu.h"
++#include "sysemu/balloon.h"
+ #include "hw/s390x/pv.h"
+ #include <linux/kvm.h>
+ #include "migration/blocker.h"
+@@ -330,6 +331,7 @@ static void s390_machine_unprotect(S390CcwMachineState *ms)
+     ms->pv = false;
+     migrate_del_blocker(pv_mig_blocker);
+     error_free_or_abort(&pv_mig_blocker);
++    qemu_balloon_inhibit(false);
+ }
+ 
+ static int s390_machine_protect(S390CcwMachineState *ms)
+@@ -337,10 +339,18 @@ static int s390_machine_protect(S390CcwMachineState *ms)
+     Error *local_err = NULL;
+     int rc;
+ 
++   /*
++    * Ballooning on protected VMs needs support in the guest for
++    * sharing and unsharing balloon pages. Block ballooning for
++    * now, until we have a solution to make at least Linux guests
++    * either support it or fail gracefully.
++    */
++    qemu_balloon_inhibit(true);
+     error_setg(&pv_mig_blocker,
+                "protected VMs are currently not migrateable.");
+     rc = migrate_add_blocker(pv_mig_blocker, &local_err);
+     if (rc) {
++        qemu_balloon_inhibit(false);
+         error_report_err(local_err);
+         error_free_or_abort(&pv_mig_blocker);
+         return rc;
+@@ -349,6 +359,7 @@ static int s390_machine_protect(S390CcwMachineState *ms)
+     /* Create SE VM */
+     rc = s390_pv_vm_enable();
+     if (rc) {
++        qemu_balloon_inhibit(false);
+         error_report_err(local_err);
+         migrate_del_blocker(pv_mig_blocker);
+         error_free_or_abort(&pv_mig_blocker);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-KVM-intercept-changes.patch b/SOURCES/kvm-s390x-protvirt-KVM-intercept-changes.patch
new file mode 100644
index 0000000..2ac3d03
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-KVM-intercept-changes.patch
@@ -0,0 +1,75 @@
+From 10ed4f6ad687d98f0bfe06d75775e8c541da80a0 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:07 -0400
+Subject: [PATCH 25/42] s390x: protvirt: KVM intercept changes
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-26-thuth@redhat.com>
+Patchwork-id: 97035
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 25/38] s390x: protvirt: KVM intercept changes
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Protected VMs no longer intercept with code 4 for an instruction
+interception. Instead they have codes 104 and 108 for protected
+instruction interception and protected instruction notification
+respectively.
+
+The 104 mirrors the 4 interception.
+
+The 108 is a notification interception to let KVM and QEMU know that
+something changed and we need to update tracking information or
+perform specific tasks. It's currently taken for the following
+instructions:
+
+* spx (To inform about the changed prefix location)
+* sclp (On incorrect SCCB values, so we can inject a IRQ)
+* sigp (All but "stop and store status")
+* diag308 (Subcodes 0/1)
+
+Of these exits only sclp errors, state changing sigps and diag308 will
+reach QEMU. QEMU will do its parts of the job, while the ultravisor
+has done the instruction part of the job.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-7-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 2585e507ffa1da01b57dbea26b1e1fe507d27198)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/kvm.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 9a0be13959..af50b2c253 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -115,6 +115,8 @@
+ #define ICPT_CPU_STOP                   0x28
+ #define ICPT_OPEREXC                    0x2c
+ #define ICPT_IO                         0x40
++#define ICPT_PV_INSTR                   0x68
++#define ICPT_PV_INSTR_NOTIFICATION      0x6c
+ 
+ #define NR_LOCAL_IRQS 32
+ /*
+@@ -1695,6 +1697,8 @@ static int handle_intercept(S390CPU *cpu)
+             (long)cs->kvm_run->psw_addr);
+     switch (icpt_code) {
+         case ICPT_INSTRUCTION:
++        case ICPT_PV_INSTR:
++        case ICPT_PV_INSTR_NOTIFICATION:
+             r = handle_instruction(cpu, run);
+             break;
+         case ICPT_PROGRAM:
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Move-IO-control-structures-over-SIDA.patch b/SOURCES/kvm-s390x-protvirt-Move-IO-control-structures-over-SIDA.patch
new file mode 100644
index 0000000..0609546
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Move-IO-control-structures-over-SIDA.patch
@@ -0,0 +1,171 @@
+From 8345b90f43b14435938fbbe0f3a510a60f5d0ded Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:14 -0400
+Subject: [PATCH 32/42] s390x: protvirt: Move IO control structures over SIDA
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-33-thuth@redhat.com>
+Patchwork-id: 97040
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 32/38] s390x: protvirt: Move IO control structures over SIDA
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+For protected guests, we need to put the IO emulation results into the
+SIDA, so SIE will write them into the guest at the next entry.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-14-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit fcc10c1470d6e9460ebcf4c30f5bbd37b921a041)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/ioinst.c | 61 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 45 insertions(+), 16 deletions(-)
+
+diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
+index bbcccf6be2..f40c35c6ff 100644
+--- a/target/s390x/ioinst.c
++++ b/target/s390x/ioinst.c
+@@ -138,7 +138,9 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+     }
+-    if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib));
++    } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
+         s390_cpu_virt_mem_handle_exc(cpu, ra);
+         return;
+     }
+@@ -195,7 +197,9 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return;
+     }
+-    if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb));
++    } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
+         s390_cpu_virt_mem_handle_exc(cpu, ra);
+         return;
+     }
+@@ -231,14 +235,19 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
+     cc = css_do_stcrw(&crw);
+     /* 0 - crw stored, 1 - zeroes stored */
+ 
+-    if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw));
+         setcc(cpu, cc);
+     } else {
+-        if (cc == 0) {
+-            /* Write failed: requeue CRW since STCRW is suppressing */
+-            css_undo_stcrw(&crw);
++        if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
++            setcc(cpu, cc);
++        } else {
++            if (cc == 0) {
++                /* Write failed: requeue CRW since STCRW is suppressing */
++                css_undo_stcrw(&crw);
++            }
++            s390_cpu_virt_mem_handle_exc(cpu, ra);
+         }
+-        s390_cpu_virt_mem_handle_exc(cpu, ra);
+     }
+ }
+ 
+@@ -260,6 +269,13 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
+     }
+ 
+     if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
++        /*
++         * The Ultravisor checks schid bit 16 to be one and bits 0-12
++         * to be 0 and injects a operand exception itself.
++         *
++         * Hence we should never end up here.
++         */
++        g_assert(!s390_is_pv());
+         /*
+          * As operand exceptions have a lower priority than access exceptions,
+          * we check whether the memory area is writeable (injecting the
+@@ -292,14 +308,17 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
+         }
+     }
+     if (cc != 3) {
+-        if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
+-                                    sizeof(schib)) != 0) {
++        if (s390_is_pv()) {
++            s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib));
++        } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
++                                           sizeof(schib)) != 0) {
+             s390_cpu_virt_mem_handle_exc(cpu, ra);
+             return;
+         }
+     } else {
+         /* Access exceptions have a higher priority than cc3 */
+-        if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
++        if (!s390_is_pv() &&
++            s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
+             s390_cpu_virt_mem_handle_exc(cpu, ra);
+             return;
+         }
+@@ -336,7 +355,9 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+     }
+     /* 0 - status pending, 1 - not status pending, 3 - not operational */
+     if (cc != 3) {
+-        if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
++        if (s390_is_pv()) {
++            s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len);
++        } else if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
+             s390_cpu_virt_mem_handle_exc(cpu, ra);
+             return -EFAULT;
+         }
+@@ -344,7 +365,8 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
+     } else {
+         irb_len = sizeof(irb) - sizeof(irb.emw);
+         /* Access exceptions have a higher priority than cc3 */
+-        if (s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
++        if (!s390_is_pv() &&
++            s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
+             s390_cpu_virt_mem_handle_exc(cpu, ra);
+             return -EFAULT;
+         }
+@@ -642,7 +664,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
+      * present CHSC sub-handlers ... if we ever need more, we should take
+      * care of req->len here first.
+      */
+-    if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_read(cpu, addr, buf, sizeof(ChscReq));
++    } else if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
+         s390_cpu_virt_mem_handle_exc(cpu, ra);
+         return;
+     }
+@@ -675,11 +699,16 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
+         break;
+     }
+ 
+-    if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
+-                                 be16_to_cpu(res->len))) {
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_write(cpu, addr + len, res, be16_to_cpu(res->len));
+         setcc(cpu, 0);    /* Command execution complete */
+     } else {
+-        s390_cpu_virt_mem_handle_exc(cpu, ra);
++        if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
++                                     be16_to_cpu(res->len))) {
++            setcc(cpu, 0);    /* Command execution complete */
++        } else {
++            s390_cpu_virt_mem_handle_exc(cpu, ra);
++        }
+     }
+ }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Move-STSI-data-over-SIDAD.patch b/SOURCES/kvm-s390x-protvirt-Move-STSI-data-over-SIDAD.patch
new file mode 100644
index 0000000..1d60070
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Move-STSI-data-over-SIDAD.patch
@@ -0,0 +1,70 @@
+From 27f5d8a3af2863e39b7c46a3128009988d772f15 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:09 -0400
+Subject: [PATCH 27/42] s390x: protvirt: Move STSI data over SIDAD
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-28-thuth@redhat.com>
+Patchwork-id: 97046
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 27/38] s390x: protvirt: Move STSI data over SIDAD
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+For protected guests, we need to put the STSI emulation results into
+the SIDA, so SIE will write them into the guest at the next entry.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-9-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 7c713b8acb70fb61f9650f8a7702dec546752bb6)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/kvm.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index f67bb5ce2c..6809a5ac40 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -50,6 +50,7 @@
+ #include "exec/memattrs.h"
+ #include "hw/s390x/s390-virtio-ccw.h"
+ #include "hw/s390x/s390-virtio-hcall.h"
++#include "hw/s390x/pv.h"
+ 
+ #ifndef DEBUG_KVM
+ #define DEBUG_KVM  0
+@@ -1803,7 +1804,9 @@ static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, uint8_t ar)
+     SysIB_322 sysib;
+     int del;
+ 
+-    if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_read(cpu, 0, &sysib, sizeof(sysib));
++    } else if (s390_cpu_virt_mem_read(cpu, addr, ar, &sysib, sizeof(sysib))) {
+         return;
+     }
+     /* Shift the stack of Extended Names to prepare for our own data */
+@@ -1843,7 +1846,11 @@ static void insert_stsi_3_2_2(S390CPU *cpu, __u64 addr, uint8_t ar)
+     /* Insert UUID */
+     memcpy(sysib.vm[0].uuid, &qemu_uuid, sizeof(sysib.vm[0].uuid));
+ 
+-    s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
++    if (s390_is_pv()) {
++        s390_cpu_pv_mem_write(cpu, 0, &sysib, sizeof(sysib));
++    } else {
++        s390_cpu_virt_mem_write(cpu, addr, ar, &sysib, sizeof(sysib));
++    }
+ }
+ 
+ static int handle_stsi(S390CPU *cpu)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Move-diag-308-data-over-SIDA.patch b/SOURCES/kvm-s390x-protvirt-Move-diag-308-data-over-SIDA.patch
new file mode 100644
index 0000000..1b22719
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Move-diag-308-data-over-SIDA.patch
@@ -0,0 +1,93 @@
+From 33d4e21cfd236aecd9e4dbe8228d058fd1f22400 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:12 -0400
+Subject: [PATCH 30/42] s390x: protvirt: Move diag 308 data over SIDA
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-31-thuth@redhat.com>
+Patchwork-id: 97048
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 30/38] s390x: protvirt: Move diag 308 data over SIDA
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+For protected guests the IPIB is written/read to/from the SIDA, so we
+need those accesses to go through s390_cpu_pv_mem_read/write().
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-12-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 9c61e11238cfa8f70e3eb90aac5d3e5646e5432f)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/diag.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/target/s390x/diag.c b/target/s390x/diag.c
+index b2cbefb8cf..1a48429564 100644
+--- a/target/s390x/diag.c
++++ b/target/s390x/diag.c
+@@ -75,6 +75,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+ {
+     bool valid;
+     CPUState *cs = env_cpu(env);
++    S390CPU *cpu = S390_CPU(cs);
+     uint64_t addr =  env->regs[r1];
+     uint64_t subcode = env->regs[r3];
+     IplParameterBlock *iplb;
+@@ -111,13 +112,22 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+             return;
+         }
+         iplb = g_new0(IplParameterBlock, 1);
+-        cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
++        if (!s390_is_pv()) {
++            cpu_physical_memory_read(addr, iplb, sizeof(iplb->len));
++        } else {
++            s390_cpu_pv_mem_read(cpu, 0, iplb, sizeof(iplb->len));
++        }
++
+         if (!iplb_valid_len(iplb)) {
+             env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+             goto out;
+         }
+ 
+-        cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
++        if (!s390_is_pv()) {
++            cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
++        } else {
++            s390_cpu_pv_mem_read(cpu, 0, iplb, be32_to_cpu(iplb->len));
++        }
+ 
+         valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb);
+         if (!valid) {
+@@ -140,12 +150,17 @@ out:
+         } else {
+             iplb = s390_ipl_get_iplb();
+         }
+-        if (iplb) {
++        if (!iplb) {
++            env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
++            return;
++        }
++
++        if (!s390_is_pv()) {
+             cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
+-            env->regs[r1 + 1] = DIAG_308_RC_OK;
+         } else {
+-            env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
++            s390_cpu_pv_mem_write(cpu, 0, iplb, be32_to_cpu(iplb->len));
+         }
++        env->regs[r1 + 1] = DIAG_308_RC_OK;
+         return;
+     case DIAG308_PV_START:
+         iplb = s390_ipl_get_iplb_pv();
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-SCLP-interpretation.patch b/SOURCES/kvm-s390x-protvirt-SCLP-interpretation.patch
new file mode 100644
index 0000000..10f1930
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-SCLP-interpretation.patch
@@ -0,0 +1,172 @@
+From 5a8b40c3fdafeb49072f8643210bea00ce1478c4 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:10 -0400
+Subject: [PATCH 28/42] s390x: protvirt: SCLP interpretation
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-29-thuth@redhat.com>
+Patchwork-id: 97053
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 28/38] s390x: protvirt: SCLP interpretation
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+SCLP for a protected guest is done over the SIDAD, so we need to use
+the s390_cpu_pv_mem_* functions to access the SIDAD instead of guest
+memory when reading/writing SCBs.
+
+To not confuse the sclp emulation, we set 0x4000 as the SCCB address,
+since the function that injects the sclp external interrupt would
+reject a zero sccb address.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20200319131921.2367-10-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 0f73c5b30b8ba6c0828608be496d2f59a5427539)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/sclp.c         | 56 +++++++++++++++++++++++++++++++++--------
+ include/hw/s390x/sclp.h |  2 ++
+ target/s390x/kvm.c      | 25 ++++++++++++++----
+ 3 files changed, 67 insertions(+), 16 deletions(-)
+
+diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
+index f57ce7b739..1c380a49cc 100644
+--- a/hw/s390x/sclp.c
++++ b/hw/s390x/sclp.c
+@@ -33,6 +33,22 @@ static inline SCLPDevice *get_sclp_device(void)
+     return sclp;
+ }
+ 
++static inline bool sclp_command_code_valid(uint32_t code)
++{
++    switch (code & SCLP_CMD_CODE_MASK) {
++    case SCLP_CMDW_READ_SCP_INFO:
++    case SCLP_CMDW_READ_SCP_INFO_FORCED:
++    case SCLP_CMDW_READ_CPU_INFO:
++    case SCLP_CMDW_CONFIGURE_IOA:
++    case SCLP_CMDW_DECONFIGURE_IOA:
++    case SCLP_CMD_READ_EVENT_DATA:
++    case SCLP_CMD_WRITE_EVENT_DATA:
++    case SCLP_CMD_WRITE_EVENT_MASK:
++        return true;
++    }
++    return false;
++}
++
+ static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
+ {
+     MachineState *ms = MACHINE(qdev_get_machine());
+@@ -193,6 +209,34 @@ static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
+     }
+ }
+ 
++/*
++ * We only need the address to have something valid for the
++ * service_interrupt call.
++ */
++#define SCLP_PV_DUMMY_ADDR 0x4000
++int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
++                                uint32_t code)
++{
++    SCLPDevice *sclp = get_sclp_device();
++    SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
++    SCCB work_sccb;
++    hwaddr sccb_len = sizeof(SCCB);
++
++    s390_cpu_pv_mem_read(env_archcpu(env), 0, &work_sccb, sccb_len);
++
++    if (!sclp_command_code_valid(code)) {
++        work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
++        goto out_write;
++    }
++
++    sclp_c->execute(sclp, &work_sccb, code);
++out_write:
++    s390_cpu_pv_mem_write(env_archcpu(env), 0, &work_sccb,
++                          be16_to_cpu(work_sccb.h.length));
++    sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR);
++    return 0;
++}
++
+ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
+ {
+     SCLPDevice *sclp = get_sclp_device();
+@@ -230,17 +274,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
+         goto out;
+     }
+ 
+-    switch (code & SCLP_CMD_CODE_MASK) {
+-    case SCLP_CMDW_READ_SCP_INFO:
+-    case SCLP_CMDW_READ_SCP_INFO_FORCED:
+-    case SCLP_CMDW_READ_CPU_INFO:
+-    case SCLP_CMDW_CONFIGURE_IOA:
+-    case SCLP_CMDW_DECONFIGURE_IOA:
+-    case SCLP_CMD_READ_EVENT_DATA:
+-    case SCLP_CMD_WRITE_EVENT_DATA:
+-    case SCLP_CMD_WRITE_EVENT_MASK:
+-        break;
+-    default:
++    if (!sclp_command_code_valid(code)) {
+         work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+         goto out_write;
+     }
+diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
+index c54413b78c..c0a3faa37d 100644
+--- a/include/hw/s390x/sclp.h
++++ b/include/hw/s390x/sclp.h
+@@ -217,5 +217,7 @@ void s390_sclp_init(void);
+ void sclp_service_interrupt(uint32_t sccb);
+ void raise_irq_cpu_hotplug(void);
+ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
++int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
++                                uint32_t code);
+ 
+ #endif
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 6809a5ac40..56fe60c49c 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -1230,12 +1230,27 @@ static void kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
+     sccb = env->regs[ipbh0 & 0xf];
+     code = env->regs[(ipbh0 & 0xf0) >> 4];
+ 
+-    r = sclp_service_call(env, sccb, code);
+-    if (r < 0) {
+-        kvm_s390_program_interrupt(cpu, -r);
+-        return;
++    switch (run->s390_sieic.icptcode) {
++    case ICPT_PV_INSTR_NOTIFICATION:
++        g_assert(s390_is_pv());
++        /* The notification intercepts are currently handled by KVM */
++        error_report("unexpected SCLP PV notification");
++        exit(1);
++        break;
++    case ICPT_PV_INSTR:
++        g_assert(s390_is_pv());
++        sclp_service_call_protected(env, sccb, code);
++        /* Setting the CC is done by the Ultravisor. */
++        break;
++    case ICPT_INSTRUCTION:
++        g_assert(!s390_is_pv());
++        r = sclp_service_call(env, sccb, code);
++        if (r < 0) {
++            kvm_s390_program_interrupt(cpu, -r);
++            return;
++        }
++        setcc(cpu, r);
+     }
+-    setcc(cpu, r);
+ }
+ 
+ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Set-guest-IPL-PSW.patch b/SOURCES/kvm-s390x-protvirt-Set-guest-IPL-PSW.patch
new file mode 100644
index 0000000..ef246c7
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Set-guest-IPL-PSW.patch
@@ -0,0 +1,75 @@
+From d738b4336c79be68b6040f73427e089f46957728 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:11 -0400
+Subject: [PATCH 29/42] s390x: protvirt: Set guest IPL PSW
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-30-thuth@redhat.com>
+Patchwork-id: 97049
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 29/38] s390x: protvirt: Set guest IPL PSW
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Handling of CPU reset and setting of the IPL psw from guest storage at
+offset 0 is done by a Ultravisor call. Let's only fetch it if
+necessary.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200319131921.2367-11-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 59181010a2ff82c3a97e9b5768ee87c38e4815f1)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/cpu.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index 8f38cd8e6f..371b91b2d7 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -77,16 +77,24 @@ static bool s390_cpu_has_work(CPUState *cs)
+ static void s390_cpu_load_normal(CPUState *s)
+ {
+     S390CPU *cpu = S390_CPU(s);
+-    uint64_t spsw = ldq_phys(s->as, 0);
+-
+-    cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
+-    /*
+-     * Invert short psw indication, so SIE will report a specification
+-     * exception if it was not set.
+-     */
+-    cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
+-    cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
++    uint64_t spsw;
+ 
++    if (!s390_is_pv()) {
++        spsw = ldq_phys(s->as, 0);
++        cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
++        /*
++         * Invert short psw indication, so SIE will report a specification
++         * exception if it was not set.
++         */
++        cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
++        cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
++    } else {
++        /*
++         * Firmware requires us to set the load state before we set
++         * the cpu to operating on protected guests.
++         */
++        s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
++    }
+     s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
+ }
+ #endif
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-protvirt-Support-unpack-facility.patch b/SOURCES/kvm-s390x-protvirt-Support-unpack-facility.patch
new file mode 100644
index 0000000..204de2a
--- /dev/null
+++ b/SOURCES/kvm-s390x-protvirt-Support-unpack-facility.patch
@@ -0,0 +1,886 @@
+From e6474080e3816e82e87c545a3d22db77c55ab053 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:04 -0400
+Subject: [PATCH 22/42] s390x: protvirt: Support unpack facility
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-23-thuth@redhat.com>
+Patchwork-id: 97045
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 22/38] s390x: protvirt: Support unpack facility
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+The unpack facility provides the means to setup a protected guest. A
+protected guest cannot be introspected by the hypervisor or any
+user/administrator of the machine it is running on.
+
+Protected guests are encrypted at rest and need a special boot
+mechanism via diag308 subcode 8 and 10.
+
+Code 8 sets the PV specific IPLB which is retained separately from
+those set via code 5.
+
+Code 10 is used to unpack the VM into protected memory, verify its
+integrity and start it.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Co-developed-by: Christian Borntraeger <borntraeger@de.ibm.com> [Changes
+to machine]
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200323083606.24520-1-frankja@linux.ibm.com>
+[CH: fixed up KVM_PV_VM_ -> KVM_PV_]
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit c3347ed0d2ee42a7dcf7bfe7f9c3884a9596727a)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ MAINTAINERS                         |   2 +
+ hw/s390x/Makefile.objs              |   1 +
+ hw/s390x/ipl.c                      |  59 +++++++++++++-
+ hw/s390x/ipl.h                      |  91 ++++++++++++++++++++-
+ hw/s390x/pv.c                       |  98 +++++++++++++++++++++++
+ hw/s390x/s390-virtio-ccw.c          | 119 +++++++++++++++++++++++++++-
+ include/hw/s390x/pv.h               |  55 +++++++++++++
+ include/hw/s390x/s390-virtio-ccw.h  |   1 +
+ target/s390x/cpu.c                  |   1 +
+ target/s390x/cpu_features_def.inc.h |   1 +
+ target/s390x/diag.c                 |  39 ++++++++-
+ target/s390x/kvm-stub.c             |   5 ++
+ target/s390x/kvm.c                  |   5 ++
+ target/s390x/kvm_s390x.h            |   1 +
+ 14 files changed, 468 insertions(+), 10 deletions(-)
+ create mode 100644 hw/s390x/pv.c
+ create mode 100644 include/hw/s390x/pv.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 49d5d44edc..2742c95575 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -385,6 +385,8 @@ F: target/s390x/machine.c
+ F: target/s390x/sigp.c
+ F: target/s390x/cpu_features*.[ch]
+ F: target/s390x/cpu_models.[ch]
++F: hw/s390x/pv.c
++F: include/hw/s390x/pv.h
+ F: hw/intc/s390_flic.c
+ F: hw/intc/s390_flic_kvm.c
+ F: include/hw/s390x/s390_flic.h
+diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
+index e02ed80b68..a46a1c7894 100644
+--- a/hw/s390x/Makefile.objs
++++ b/hw/s390x/Makefile.objs
+@@ -31,6 +31,7 @@ obj-y += tod-qemu.o
+ obj-$(CONFIG_KVM) += tod-kvm.o
+ obj-$(CONFIG_KVM) += s390-skeys-kvm.o
+ obj-$(CONFIG_KVM) += s390-stattrib-kvm.o
++obj-$(CONFIG_KVM) += pv.o
+ obj-y += s390-ccw.o
+ obj-y += ap-device.o
+ obj-y += ap-bridge.o
+diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
+index fa0409dc23..586d95b5b6 100644
+--- a/hw/s390x/ipl.c
++++ b/hw/s390x/ipl.c
+@@ -1,10 +1,11 @@
+ /*
+  * bootloader support
+  *
+- * Copyright IBM, Corp. 2012
++ * Copyright IBM, Corp. 2012, 2020
+  *
+  * Authors:
+  *  Christian Borntraeger <borntraeger@de.ibm.com>
++ *  Janosch Frank <frankja@linux.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.
+@@ -27,6 +28,7 @@
+ #include "hw/s390x/vfio-ccw.h"
+ #include "hw/s390x/css.h"
+ #include "hw/s390x/ebcdic.h"
++#include "hw/s390x/pv.h"
+ #include "ipl.h"
+ #include "qemu/error-report.h"
+ #include "qemu/config-file.h"
+@@ -557,12 +559,31 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
+ {
+     S390IPLState *ipl = get_ipl_device();
+ 
+-    ipl->iplb = *iplb;
+-    ipl->iplb_valid = true;
++    /*
++     * The IPLB set and retrieved by subcodes 8/9 is completely
++     * separate from the one managed via subcodes 5/6.
++     */
++    if (iplb->pbt == S390_IPL_TYPE_PV) {
++        ipl->iplb_pv = *iplb;
++        ipl->iplb_valid_pv = true;
++    } else {
++        ipl->iplb = *iplb;
++        ipl->iplb_valid = true;
++    }
+     ipl->netboot = is_virtio_net_device(iplb);
+     update_machine_ipl_properties(iplb);
+ }
+ 
++IplParameterBlock *s390_ipl_get_iplb_pv(void)
++{
++    S390IPLState *ipl = get_ipl_device();
++
++    if (!ipl->iplb_valid_pv) {
++        return NULL;
++    }
++    return &ipl->iplb_pv;
++}
++
+ IplParameterBlock *s390_ipl_get_iplb(void)
+ {
+     S390IPLState *ipl = get_ipl_device();
+@@ -651,6 +672,38 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu)
+     cpu_physical_memory_unmap(addr, len, 1, len);
+ }
+ 
++int s390_ipl_prepare_pv_header(void)
++{
++    IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
++    IPLBlockPV *ipib_pv = &ipib->pv;
++    void *hdr = g_malloc(ipib_pv->pv_header_len);
++    int rc;
++
++    cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr,
++                             ipib_pv->pv_header_len);
++    rc = s390_pv_set_sec_parms((uintptr_t)hdr,
++                               ipib_pv->pv_header_len);
++    g_free(hdr);
++    return rc;
++}
++
++int s390_ipl_pv_unpack(void)
++{
++    IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
++    IPLBlockPV *ipib_pv = &ipib->pv;
++    int i, rc = 0;
++
++    for (i = 0; i < ipib_pv->num_comp; i++) {
++        rc = s390_pv_unpack(ipib_pv->components[i].addr,
++                            TARGET_PAGE_ALIGN(ipib_pv->components[i].size),
++                            ipib_pv->components[i].tweak_pref);
++        if (rc) {
++            break;
++        }
++    }
++    return rc;
++}
++
+ void s390_ipl_prepare_cpu(S390CPU *cpu)
+ {
+     S390IPLState *ipl = get_ipl_device();
+diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
+index a5665e6bfd..89b3044d7a 100644
+--- a/hw/s390x/ipl.h
++++ b/hw/s390x/ipl.h
+@@ -1,8 +1,9 @@
+ /*
+  * s390 IPL device
+  *
+- * Copyright 2015 IBM Corp.
++ * Copyright 2015, 2020 IBM Corp.
+  * Author(s): Zhang Fan <bjfanzh@cn.ibm.com>
++ * Janosch Frank <frankja@linux.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
+@@ -15,6 +16,24 @@
+ #include "cpu.h"
+ #include "hw/qdev-core.h"
+ 
++struct IPLBlockPVComp {
++    uint64_t tweak_pref;
++    uint64_t addr;
++    uint64_t size;
++} QEMU_PACKED;
++typedef struct IPLBlockPVComp IPLBlockPVComp;
++
++struct IPLBlockPV {
++    uint8_t  reserved18[87];    /* 0x18 */
++    uint8_t  version;           /* 0x6f */
++    uint32_t reserved70;        /* 0x70 */
++    uint32_t num_comp;          /* 0x74 */
++    uint64_t pv_header_addr;    /* 0x78 */
++    uint64_t pv_header_len;     /* 0x80 */
++    struct IPLBlockPVComp components[];
++} QEMU_PACKED;
++typedef struct IPLBlockPV IPLBlockPV;
++
+ struct IplBlockCcw {
+     uint8_t  reserved0[85];
+     uint8_t  ssid;
+@@ -71,6 +90,7 @@ union IplParameterBlock {
+         union {
+             IplBlockCcw ccw;
+             IplBlockFcp fcp;
++            IPLBlockPV pv;
+             IplBlockQemuScsi scsi;
+         };
+     } QEMU_PACKED;
+@@ -85,8 +105,11 @@ typedef union IplParameterBlock IplParameterBlock;
+ 
+ int s390_ipl_set_loadparm(uint8_t *loadparm);
+ void s390_ipl_update_diag308(IplParameterBlock *iplb);
++int s390_ipl_prepare_pv_header(void);
++int s390_ipl_pv_unpack(void);
+ void s390_ipl_prepare_cpu(S390CPU *cpu);
+ IplParameterBlock *s390_ipl_get_iplb(void);
++IplParameterBlock *s390_ipl_get_iplb_pv(void);
+ 
+ enum s390_reset {
+     /* default is a reset not triggered by a CPU e.g. issued by QMP */
+@@ -94,6 +117,7 @@ enum s390_reset {
+     S390_RESET_REIPL,
+     S390_RESET_MODIFIED_CLEAR,
+     S390_RESET_LOAD_NORMAL,
++    S390_RESET_PV,
+ };
+ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type);
+ void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type);
+@@ -133,6 +157,7 @@ struct S390IPLState {
+     /*< private >*/
+     DeviceState parent_obj;
+     IplParameterBlock iplb;
++    IplParameterBlock iplb_pv;
+     QemuIplParameters qipl;
+     uint64_t start_addr;
+     uint64_t compat_start_addr;
+@@ -140,6 +165,7 @@ struct S390IPLState {
+     uint64_t compat_bios_start_addr;
+     bool enforce_bios;
+     bool iplb_valid;
++    bool iplb_valid_pv;
+     bool netboot;
+     /* reset related properties don't have to be migrated or reset */
+     enum s390_reset reset_type;
+@@ -162,6 +188,8 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
+ #define DIAG_308_RC_OK              0x0001
+ #define DIAG_308_RC_NO_CONF         0x0102
+ #define DIAG_308_RC_INVALID         0x0402
++#define DIAG_308_RC_NO_PV_CONF      0x0902
++#define DIAG_308_RC_INVAL_FOR_PV    0x0a02
+ 
+ #define DIAG308_RESET_MOD_CLR       0
+ #define DIAG308_RESET_LOAD_NORM     1
+@@ -169,12 +197,17 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
+ #define DIAG308_LOAD_NORMAL_DUMP    4
+ #define DIAG308_SET                 5
+ #define DIAG308_STORE               6
++#define DIAG308_PV_SET              8
++#define DIAG308_PV_STORE            9
++#define DIAG308_PV_START            10
+ 
+ #define S390_IPL_TYPE_FCP 0x00
+ #define S390_IPL_TYPE_CCW 0x02
++#define S390_IPL_TYPE_PV 0x05
+ #define S390_IPL_TYPE_QEMU_SCSI 0xff
+ 
+ #define S390_IPLB_HEADER_LEN 8
++#define S390_IPLB_MIN_PV_LEN 148
+ #define S390_IPLB_MIN_CCW_LEN 200
+ #define S390_IPLB_MIN_FCP_LEN 384
+ #define S390_IPLB_MIN_QEMU_SCSI_LEN 200
+@@ -184,6 +217,62 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb)
+     return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
+ }
+ 
++static inline bool ipl_valid_pv_components(IplParameterBlock *iplb)
++{
++    IPLBlockPV *ipib_pv = &iplb->pv;
++    int i;
++
++    if (ipib_pv->num_comp == 0) {
++        return false;
++    }
++
++    for (i = 0; i < ipib_pv->num_comp; i++) {
++        /* Addr must be 4k aligned */
++        if (ipib_pv->components[i].addr & ~TARGET_PAGE_MASK) {
++            return false;
++        }
++
++        /* Tweak prefix is monotonically increasing with each component */
++        if (i < ipib_pv->num_comp - 1 &&
++            ipib_pv->components[i].tweak_pref >=
++            ipib_pv->components[i + 1].tweak_pref) {
++            return false;
++        }
++    }
++    return true;
++}
++
++static inline bool ipl_valid_pv_header(IplParameterBlock *iplb)
++{
++        IPLBlockPV *ipib_pv = &iplb->pv;
++
++        if (ipib_pv->pv_header_len > 2 * TARGET_PAGE_SIZE) {
++            return false;
++        }
++
++        if (!address_space_access_valid(&address_space_memory,
++                                        ipib_pv->pv_header_addr,
++                                        ipib_pv->pv_header_len,
++                                        false,
++                                        MEMTXATTRS_UNSPECIFIED)) {
++            return false;
++        }
++
++        return true;
++}
++
++static inline bool iplb_valid_pv(IplParameterBlock *iplb)
++{
++    if (iplb->pbt != S390_IPL_TYPE_PV ||
++        be32_to_cpu(iplb->len) < S390_IPLB_MIN_PV_LEN) {
++        return false;
++    }
++    if (!ipl_valid_pv_header(iplb)) {
++        return false;
++    }
++    return ipl_valid_pv_components(iplb);
++}
++
+ static inline bool iplb_valid(IplParameterBlock *iplb)
+ {
+     switch (iplb->pbt) {
+diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
+new file mode 100644
+index 0000000000..a40a844806
+--- /dev/null
++++ b/hw/s390x/pv.c
+@@ -0,0 +1,98 @@
++/*
++ * Protected Virtualization functions
++ *
++ * Copyright IBM Corp. 2020
++ * Author(s):
++ *  Janosch Frank <frankja@linux.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 "qemu/osdep.h"
++
++#include <linux/kvm.h>
++
++#include "qemu/error-report.h"
++#include "sysemu/kvm.h"
++#include "hw/s390x/pv.h"
++
++static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
++{
++    struct kvm_pv_cmd pv_cmd = {
++        .cmd = cmd,
++        .data = (uint64_t)data,
++    };
++    int rc = kvm_vm_ioctl(kvm_state, KVM_S390_PV_COMMAND, &pv_cmd);
++
++    if (rc) {
++        error_report("KVM PV command %d (%s) failed: header rc %x rrc %x "
++                     "IOCTL rc: %d", cmd, cmdname, pv_cmd.rc, pv_cmd.rrc,
++                     rc);
++    }
++    return rc;
++}
++
++/*
++ * This macro lets us pass the command as a string to the function so
++ * we can print it on an error.
++ */
++#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data);
++#define s390_pv_cmd_exit(cmd, data)    \
++{                                      \
++    int rc;                            \
++                                       \
++    rc = __s390_pv_cmd(cmd, #cmd, data);\
++    if (rc) {                          \
++        exit(1);                       \
++    }                                  \
++}
++
++int s390_pv_vm_enable(void)
++{
++    return s390_pv_cmd(KVM_PV_ENABLE, NULL);
++}
++
++void s390_pv_vm_disable(void)
++{
++     s390_pv_cmd_exit(KVM_PV_DISABLE, NULL);
++}
++
++int s390_pv_set_sec_parms(uint64_t origin, uint64_t length)
++{
++    struct kvm_s390_pv_sec_parm args = {
++        .origin = origin,
++        .length = length,
++    };
++
++    return s390_pv_cmd(KVM_PV_SET_SEC_PARMS, &args);
++}
++
++/*
++ * Called for each component in the SE type IPL parameter block 0.
++ */
++int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak)
++{
++    struct kvm_s390_pv_unp args = {
++        .addr = addr,
++        .size = size,
++        .tweak = tweak,
++    };
++
++    return s390_pv_cmd(KVM_PV_UNPACK, &args);
++}
++
++void s390_pv_perf_clear_reset(void)
++{
++    s390_pv_cmd_exit(KVM_PV_PREP_RESET, NULL);
++}
++
++int s390_pv_verify(void)
++{
++    return s390_pv_cmd(KVM_PV_VERIFY, NULL);
++}
++
++void s390_pv_unshare(void)
++{
++    s390_pv_cmd_exit(KVM_PV_UNSHARE_ALL, NULL);
++}
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index 4ea01c53c0..82da1d9ab5 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -1,9 +1,10 @@
+ /*
+  * virtio ccw machine
+  *
+- * Copyright 2012 IBM Corp.
++ * Copyright 2012, 2020 IBM Corp.
+  * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
+  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
++ *            Janosch Frank <frankja@linux.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
+@@ -41,6 +42,8 @@
+ #include "hw/qdev-properties.h"
+ #include "hw/s390x/tod.h"
+ #include "sysemu/sysemu.h"
++#include "hw/s390x/pv.h"
++#include <linux/kvm.h>
+ 
+ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
+ {
+@@ -318,10 +321,78 @@ static inline void s390_do_cpu_ipl(CPUState *cs, run_on_cpu_data arg)
+     s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
+ }
+ 
++static void s390_machine_unprotect(S390CcwMachineState *ms)
++{
++    s390_pv_vm_disable();
++    ms->pv = false;
++}
++
++static int s390_machine_protect(S390CcwMachineState *ms)
++{
++    int rc;
++
++    /* Create SE VM */
++    rc = s390_pv_vm_enable();
++    if (rc) {
++        return rc;
++    }
++
++    ms->pv = true;
++
++    /* Set SE header and unpack */
++    rc = s390_ipl_prepare_pv_header();
++    if (rc) {
++        goto out_err;
++    }
++
++    /* Decrypt image */
++    rc = s390_ipl_pv_unpack();
++    if (rc) {
++        goto out_err;
++    }
++
++    /* Verify integrity */
++    rc = s390_pv_verify();
++    if (rc) {
++        goto out_err;
++    }
++    return rc;
++
++out_err:
++    s390_machine_unprotect(ms);
++    return rc;
++}
++
++static void s390_machine_inject_pv_error(CPUState *cs)
++{
++    int r1 = (cs->kvm_run->s390_sieic.ipa & 0x00f0) >> 4;
++    CPUS390XState *env = &S390_CPU(cs)->env;
++
++    /* Report that we are unable to enter protected mode */
++    env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
++}
++
++static void s390_pv_prepare_reset(S390CcwMachineState *ms)
++{
++    CPUState *cs;
++
++    if (!s390_is_pv()) {
++        return;
++    }
++    /* Unsharing requires all cpus to be stopped */
++    CPU_FOREACH(cs) {
++        s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs));
++    }
++    s390_pv_unshare();
++    s390_pv_perf_clear_reset();
++}
++
+ static void s390_machine_reset(MachineState *machine)
+ {
++    S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
+     enum s390_reset reset_type;
+     CPUState *cs, *t;
++    S390CPU *cpu;
+ 
+     /* get the reset parameters, reset them once done */
+     s390_ipl_get_reset_request(&cs, &reset_type);
+@@ -329,9 +400,15 @@ static void s390_machine_reset(MachineState *machine)
+     /* all CPUs are paused and synchronized at this point */
+     s390_cmma_reset();
+ 
++    cpu = S390_CPU(cs);
++
+     switch (reset_type) {
+     case S390_RESET_EXTERNAL:
+     case S390_RESET_REIPL:
++        if (s390_is_pv()) {
++            s390_machine_unprotect(ms);
++        }
++
+         qemu_devices_reset();
+         s390_crypto_reset();
+ 
+@@ -339,22 +416,56 @@ static void s390_machine_reset(MachineState *machine)
+         run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
+         break;
+     case S390_RESET_MODIFIED_CLEAR:
++        /*
++         * Susbsystem reset needs to be done before we unshare memory
++         * and lose access to VIRTIO structures in guest memory.
++         */
++        subsystem_reset();
++        s390_crypto_reset();
++        s390_pv_prepare_reset(ms);
+         CPU_FOREACH(t) {
+             run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
+         }
+-        subsystem_reset();
+-        s390_crypto_reset();
+         run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
+         break;
+     case S390_RESET_LOAD_NORMAL:
++        /*
++         * Susbsystem reset needs to be done before we unshare memory
++         * and lose access to VIRTIO structures in guest memory.
++         */
++        subsystem_reset();
++        s390_pv_prepare_reset(ms);
+         CPU_FOREACH(t) {
+             if (t == cs) {
+                 continue;
+             }
+             run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
+         }
+-        subsystem_reset();
+         run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL);
++        run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
++        break;
++    case S390_RESET_PV: /* Subcode 10 */
++        subsystem_reset();
++        s390_crypto_reset();
++
++        CPU_FOREACH(t) {
++            if (t == cs) {
++                continue;
++            }
++            run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
++        }
++        run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL);
++
++        if (s390_machine_protect(ms)) {
++            s390_machine_inject_pv_error(cs);
++            /*
++             * Continue after the diag308 so the guest knows something
++             * went wrong.
++             */
++            s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
++            return;
++        }
++
+         run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
+         break;
+     default:
+diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
+new file mode 100644
+index 0000000000..c6cb360f2f
+--- /dev/null
++++ b/include/hw/s390x/pv.h
+@@ -0,0 +1,55 @@
++/*
++ * Protected Virtualization header
++ *
++ * Copyright IBM Corp. 2020
++ * Author(s):
++ *  Janosch Frank <frankja@linux.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 HW_S390_PV_H
++#define HW_S390_PV_H
++
++#ifdef CONFIG_KVM
++#include "hw/s390x/s390-virtio-ccw.h"
++
++static inline bool s390_is_pv(void)
++{
++    static S390CcwMachineState *ccw;
++    Object *obj;
++
++    if (ccw) {
++        return ccw->pv;
++    }
++
++    /* we have to bail out for the "none" machine */
++    obj = object_dynamic_cast(qdev_get_machine(),
++                              TYPE_S390_CCW_MACHINE);
++    if (!obj) {
++        return false;
++    }
++    ccw = S390_CCW_MACHINE(obj);
++    return ccw->pv;
++}
++
++int s390_pv_vm_enable(void);
++void s390_pv_vm_disable(void);
++int s390_pv_set_sec_parms(uint64_t origin, uint64_t length);
++int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak);
++void s390_pv_perf_clear_reset(void);
++int s390_pv_verify(void);
++void s390_pv_unshare(void);
++#else /* CONFIG_KVM */
++static inline bool s390_is_pv(void) { return false; }
++static inline int s390_pv_vm_enable(void) { return 0; }
++static inline void s390_pv_vm_disable(void) {}
++static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; }
++static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) { return 0; }
++static inline void s390_pv_perf_clear_reset(void) {}
++static inline int s390_pv_verify(void) { return 0; }
++static inline void s390_pv_unshare(void) {}
++#endif /* CONFIG_KVM */
++
++#endif /* HW_S390_PV_H */
+diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
+index 8aa27199c9..cd1dccc6e3 100644
+--- a/include/hw/s390x/s390-virtio-ccw.h
++++ b/include/hw/s390x/s390-virtio-ccw.h
+@@ -28,6 +28,7 @@ typedef struct S390CcwMachineState {
+     /*< public >*/
+     bool aes_key_wrap;
+     bool dea_key_wrap;
++    bool pv;
+     uint8_t loadparm[8];
+ } S390CcwMachineState;
+ 
+diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
+index c0dd502b84..8f38cd8e6f 100644
+--- a/target/s390x/cpu.c
++++ b/target/s390x/cpu.c
+@@ -37,6 +37,7 @@
+ #include "sysemu/hw_accel.h"
+ #include "hw/qdev-properties.h"
+ #ifndef CONFIG_USER_ONLY
++#include "hw/s390x/pv.h"
+ #include "hw/boards.h"
+ #include "sysemu/arch_init.h"
+ #include "sysemu/sysemu.h"
+diff --git a/target/s390x/cpu_features_def.inc.h b/target/s390x/cpu_features_def.inc.h
+index 31dff0d84e..60db28351d 100644
+--- a/target/s390x/cpu_features_def.inc.h
++++ b/target/s390x/cpu_features_def.inc.h
+@@ -107,6 +107,7 @@ DEF_FEAT(DEFLATE_BASE, "deflate-base", STFL, 151, "Deflate-conversion facility (
+ 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")
++DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack 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")
+diff --git a/target/s390x/diag.c b/target/s390x/diag.c
+index 8aba6341f9..b2cbefb8cf 100644
+--- a/target/s390x/diag.c
++++ b/target/s390x/diag.c
+@@ -20,6 +20,8 @@
+ #include "sysemu/cpus.h"
+ #include "hw/s390x/ipl.h"
+ #include "hw/s390x/s390-virtio-ccw.h"
++#include "hw/s390x/pv.h"
++#include "kvm_s390x.h"
+ 
+ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
+ {
+@@ -52,6 +54,10 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
+ static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
+                               uintptr_t ra, bool write)
+ {
++    /* Handled by the Ultravisor */
++    if (s390_is_pv()) {
++        return 0;
++    }
+     if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) {
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         return -1;
+@@ -67,6 +73,7 @@ static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
+ 
+ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+ {
++    bool valid;
+     CPUState *cs = env_cpu(env);
+     uint64_t addr =  env->regs[r1];
+     uint64_t subcode = env->regs[r3];
+@@ -82,6 +89,11 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+         return;
+     }
+ 
++    if (subcode >= DIAG308_PV_SET && !s390_has_feat(S390_FEAT_UNPACK)) {
++        s390_program_interrupt(env, PGM_SPECIFICATION, ra);
++        return;
++    }
++
+     switch (subcode) {
+     case DIAG308_RESET_MOD_CLR:
+         s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
+@@ -94,6 +106,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+         s390_ipl_reset_request(cs, S390_RESET_REIPL);
+         break;
+     case DIAG308_SET:
++    case DIAG308_PV_SET:
+         if (diag308_parm_check(env, r1, addr, ra, false)) {
+             return;
+         }
+@@ -106,7 +119,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
+ 
+         cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
+ 
+-        if (!iplb_valid(iplb)) {
++        valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb);
++        if (!valid) {
+             env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+             goto out;
+         }
+@@ -117,10 +131,15 @@ out:
+         g_free(iplb);
+         return;
+     case DIAG308_STORE:
++    case DIAG308_PV_STORE:
+         if (diag308_parm_check(env, r1, addr, ra, true)) {
+             return;
+         }
+-        iplb = s390_ipl_get_iplb();
++        if (subcode == DIAG308_PV_STORE) {
++            iplb = s390_ipl_get_iplb_pv();
++        } else {
++            iplb = s390_ipl_get_iplb();
++        }
+         if (iplb) {
+             cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len));
+             env->regs[r1 + 1] = DIAG_308_RC_OK;
+@@ -128,6 +147,22 @@ out:
+             env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
+         }
+         return;
++    case DIAG308_PV_START:
++        iplb = s390_ipl_get_iplb_pv();
++        if (!iplb) {
++            env->regs[r1 + 1] = DIAG_308_RC_NO_PV_CONF;
++            return;
++        }
++
++        if (kvm_s390_get_hpage_1m()) {
++            error_report("Protected VMs can currently not be backed with "
++                         "huge pages");
++            env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
++            return;
++        }
++
++        s390_ipl_reset_request(cs, S390_RESET_PV);
++        break;
+     default:
+         s390_program_interrupt(env, PGM_SPECIFICATION, ra);
+         break;
+diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
+index c4cd497f85..aa185017a2 100644
+--- a/target/s390x/kvm-stub.c
++++ b/target/s390x/kvm-stub.c
+@@ -39,6 +39,11 @@ int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
+     return 0;
+ }
+ 
++int kvm_s390_get_hpage_1m(void)
++{
++    return 0;
++}
++
+ int kvm_s390_get_ri(void)
+ {
+     return 0;
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index 75d82af6fc..9a0be13959 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -321,6 +321,11 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp)
+     cap_hpage_1m = 1;
+ }
+ 
++int kvm_s390_get_hpage_1m(void)
++{
++    return cap_hpage_1m;
++}
++
+ static void ccw_machine_class_foreach(ObjectClass *oc, void *opaque)
+ {
+     MachineClass *mc = MACHINE_CLASS(oc);
+diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
+index 0b21789796..dea813f450 100644
+--- a/target/s390x/kvm_s390x.h
++++ b/target/s390x/kvm_s390x.h
+@@ -23,6 +23,7 @@ void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
+ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
+ void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
+ int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
++int kvm_s390_get_hpage_1m(void);
+ int kvm_s390_get_ri(void);
+ int kvm_s390_get_gs(void);
+ int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-pv-Fix-KVM_PV_PREP_RESET-command-wrapper-name.patch b/SOURCES/kvm-s390x-pv-Fix-KVM_PV_PREP_RESET-command-wrapper-name.patch
new file mode 100644
index 0000000..764ceb1
--- /dev/null
+++ b/SOURCES/kvm-s390x-pv-Fix-KVM_PV_PREP_RESET-command-wrapper-name.patch
@@ -0,0 +1,92 @@
+From f3594f3d84a7442c194b1b9fd288e7414540ec0f Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:20 -0400
+Subject: [PATCH 38/42] s390x: pv: Fix KVM_PV_PREP_RESET command wrapper name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-39-thuth@redhat.com>
+Patchwork-id: 97051
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 38/38] s390x: pv: Fix KVM_PV_PREP_RESET command wrapper name
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Janosch Frank <frankja@linux.ibm.com>
+
+Upstream: Merged in https://github.com/cohuck/qemu/tree/s390-next
+
+s390_pv_perf_clear_reset() is not a very helpful name since that
+function needs to be called for a normal and a clear reset via
+diag308.
+
+Let's instead name it s390_pv_prep_reset() which reflects the purpose
+of the function a bit better.
+
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Message-Id: <20200505124159.24099-1-frankja@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit f9628f3f6db341751002dac3be18610fa77c01ad)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/pv.c              | 2 +-
+ hw/s390x/s390-virtio-ccw.c | 2 +-
+ include/hw/s390x/pv.h      | 4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
+index f11868e865..ab3a2482aa 100644
+--- a/hw/s390x/pv.c
++++ b/hw/s390x/pv.c
+@@ -88,7 +88,7 @@ int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak)
+     return s390_pv_cmd(KVM_PV_UNPACK, &args);
+ }
+ 
+-void s390_pv_perf_clear_reset(void)
++void s390_pv_prep_reset(void)
+ {
+     s390_pv_cmd_exit(KVM_PV_PREP_RESET, NULL);
+ }
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index 07773a12b2..e6ed13b649 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -402,7 +402,7 @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms)
+         s390_cpu_set_state(S390_CPU_STATE_STOPPED, S390_CPU(cs));
+     }
+     s390_pv_unshare();
+-    s390_pv_perf_clear_reset();
++    s390_pv_prep_reset();
+ }
+ 
+ static void s390_machine_reset(MachineState *machine)
+diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
+index 522ca6a04e..aee758bc2d 100644
+--- a/include/hw/s390x/pv.h
++++ b/include/hw/s390x/pv.h
+@@ -39,7 +39,7 @@ int s390_pv_vm_enable(void);
+ void s390_pv_vm_disable(void);
+ int s390_pv_set_sec_parms(uint64_t origin, uint64_t length);
+ int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak);
+-void s390_pv_perf_clear_reset(void);
++void s390_pv_prep_reset(void);
+ int s390_pv_verify(void);
+ void s390_pv_unshare(void);
+ void s390_pv_inject_reset_error(CPUState *cs);
+@@ -49,7 +49,7 @@ static inline int s390_pv_vm_enable(void) { return 0; }
+ static inline void s390_pv_vm_disable(void) {}
+ static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; }
+ static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) { return 0; }
+-static inline void s390_pv_perf_clear_reset(void) {}
++static inline void s390_pv_prep_reset(void) {}
+ static inline int s390_pv_verify(void) { return 0; }
+ static inline void s390_pv_unshare(void) {}
+ static inline void s390_pv_inject_reset_error(CPUState *cs) {};
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-pv-Retry-ioctls-on-EINTR.patch b/SOURCES/kvm-s390x-pv-Retry-ioctls-on-EINTR.patch
new file mode 100644
index 0000000..65208c7
--- /dev/null
+++ b/SOURCES/kvm-s390x-pv-Retry-ioctls-on-EINTR.patch
@@ -0,0 +1,57 @@
+From 1678288d945906d83d7adae109b842080aebaf19 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:18 -0400
+Subject: [PATCH 36/42] s390x/pv: Retry ioctls on -EINTR
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-37-thuth@redhat.com>
+Patchwork-id: 97055
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 36/38] s390x/pv: Retry ioctls on -EINTR
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+PV_ENABLE (and maybe others) might return -EINTR when a signal is
+pending. See the Linux kernel patch "s390/gmap: return proper error code
+on ksm unsharing" for details. Let us retry the ioctl in that case.
+
+Fixes: c3347ed0d2ee ("s390x: protvirt: Support unpack facility")
+Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Acked-by: Janosch Frank <frankja@linux.vnet.ibm.com>
+Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20200327124616.34866-1-borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit e8d12a55f6d3e577455b02f15907c460578c689b)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/pv.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
+index a40a844806..cb0dce4a4f 100644
+--- a/hw/s390x/pv.c
++++ b/hw/s390x/pv.c
+@@ -23,7 +23,11 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
+         .cmd = cmd,
+         .data = (uint64_t)data,
+     };
+-    int rc = kvm_vm_ioctl(kvm_state, KVM_S390_PV_COMMAND, &pv_cmd);
++    int rc;
++
++    do {
++        rc = kvm_vm_ioctl(kvm_state, KVM_S390_PV_COMMAND, &pv_cmd);
++    } while (rc == -EINTR);
+ 
+     if (rc) {
+         error_report("KVM PV command %d (%s) failed: header rc %x rrc %x "
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-s390x-s390-virtio-ccw-Fix-build-on-systems-without-K.patch b/SOURCES/kvm-s390x-s390-virtio-ccw-Fix-build-on-systems-without-K.patch
new file mode 100644
index 0000000..e78f4da
--- /dev/null
+++ b/SOURCES/kvm-s390x-s390-virtio-ccw-Fix-build-on-systems-without-K.patch
@@ -0,0 +1,150 @@
+From 0db8d909a2f3c53d12b0ae12307965f9a8193dbc Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:19 -0400
+Subject: [PATCH 37/42] s390x/s390-virtio-ccw: Fix build on systems without KVM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-38-thuth@redhat.com>
+Patchwork-id: 97047
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 37/38] s390x/s390-virtio-ccw: Fix build on systems without KVM
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+linux/kvm.h is not available on all platforms. Let us move
+s390_machine_inject_pv_error into pv.c as it uses KVM structures.
+Also rename the function to s390_pv_inject_reset_error.
+
+While at it, ipl.h needs an include for "exec/address-spaces.h"
+as it uses address_space_memory.
+
+Fixes: c3347ed0d2ee ("s390x: protvirt: Support unpack facility")
+Reported-by: Bruce Rogers <brogers@suse.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Message-Id: <20200406100158.5940-2-borntraeger@de.ibm.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit fbc1384ccd48fa7c0c38f950adf7992a4fb6042e)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/ipl.h             |  1 +
+ hw/s390x/pv.c              | 11 +++++++++++
+ hw/s390x/s390-virtio-ccw.c | 12 +-----------
+ include/hw/s390x/pv.h      |  3 +++
+ 4 files changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
+index 89b3044d7a..53cc9eb5ac 100644
+--- a/hw/s390x/ipl.h
++++ b/hw/s390x/ipl.h
+@@ -14,6 +14,7 @@
+ #define HW_S390_IPL_H
+ 
+ #include "cpu.h"
++#include "exec/address-spaces.h"
+ #include "hw/qdev-core.h"
+ 
+ struct IPLBlockPVComp {
+diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
+index cb0dce4a4f..f11868e865 100644
+--- a/hw/s390x/pv.c
++++ b/hw/s390x/pv.c
+@@ -13,8 +13,10 @@
+ 
+ #include <linux/kvm.h>
+ 
++#include "cpu.h"
+ #include "qemu/error-report.h"
+ #include "sysemu/kvm.h"
++#include "hw/s390x/ipl.h"
+ #include "hw/s390x/pv.h"
+ 
+ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
+@@ -100,3 +102,12 @@ void s390_pv_unshare(void)
+ {
+     s390_pv_cmd_exit(KVM_PV_UNSHARE_ALL, NULL);
+ }
++
++void s390_pv_inject_reset_error(CPUState *cs)
++{
++    int r1 = (cs->kvm_run->s390_sieic.ipa & 0x00f0) >> 4;
++    CPUS390XState *env = &S390_CPU(cs)->env;
++
++    /* Report that we are unable to enter protected mode */
++    env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
++}
+diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
+index c08e42bda1..07773a12b2 100644
+--- a/hw/s390x/s390-virtio-ccw.c
++++ b/hw/s390x/s390-virtio-ccw.c
+@@ -44,7 +44,6 @@
+ #include "sysemu/sysemu.h"
+ #include "sysemu/balloon.h"
+ #include "hw/s390x/pv.h"
+-#include <linux/kvm.h>
+ #include "migration/blocker.h"
+ 
+ static Error *pv_mig_blocker;
+@@ -391,15 +390,6 @@ out_err:
+     return rc;
+ }
+ 
+-static void s390_machine_inject_pv_error(CPUState *cs)
+-{
+-    int r1 = (cs->kvm_run->s390_sieic.ipa & 0x00f0) >> 4;
+-    CPUS390XState *env = &S390_CPU(cs)->env;
+-
+-    /* Report that we are unable to enter protected mode */
+-    env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
+-}
+-
+ static void s390_pv_prepare_reset(S390CcwMachineState *ms)
+ {
+     CPUState *cs;
+@@ -485,7 +475,7 @@ static void s390_machine_reset(MachineState *machine)
+         run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL);
+ 
+         if (s390_machine_protect(ms)) {
+-            s390_machine_inject_pv_error(cs);
++            s390_pv_inject_reset_error(cs);
+             /*
+              * Continue after the diag308 so the guest knows something
+              * went wrong.
+diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h
+index c6cb360f2f..522ca6a04e 100644
+--- a/include/hw/s390x/pv.h
++++ b/include/hw/s390x/pv.h
+@@ -13,6 +13,7 @@
+ #define HW_S390_PV_H
+ 
+ #ifdef CONFIG_KVM
++#include "cpu.h"
+ #include "hw/s390x/s390-virtio-ccw.h"
+ 
+ static inline bool s390_is_pv(void)
+@@ -41,6 +42,7 @@ int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak);
+ void s390_pv_perf_clear_reset(void);
+ int s390_pv_verify(void);
+ void s390_pv_unshare(void);
++void s390_pv_inject_reset_error(CPUState *cs);
+ #else /* CONFIG_KVM */
+ static inline bool s390_is_pv(void) { return false; }
+ static inline int s390_pv_vm_enable(void) { return 0; }
+@@ -50,6 +52,7 @@ static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) {
+ static inline void s390_pv_perf_clear_reset(void) {}
+ static inline int s390_pv_verify(void) { return 0; }
+ static inline void s390_pv_unshare(void) {}
++static inline void s390_pv_inject_reset_error(CPUState *cs) {};
+ #endif /* CONFIG_KVM */
+ 
+ #endif /* HW_S390_PV_H */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-spapr-Pass-the-maximum-number-of-vCPUs-to-the-KVM-in.patch b/SOURCES/kvm-spapr-Pass-the-maximum-number-of-vCPUs-to-the-KVM-in.patch
new file mode 100644
index 0000000..7c48718
--- /dev/null
+++ b/SOURCES/kvm-spapr-Pass-the-maximum-number-of-vCPUs-to-the-KVM-in.patch
@@ -0,0 +1,213 @@
+From 5aea41b56f07f586e0f56a5c8b3e8443e485cd77 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 5 Jun 2020 07:41:09 -0400
+Subject: [PATCH 39/42] spapr: Pass the maximum number of vCPUs to the KVM
+ interrupt controller
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200605074111.2185-2-thuth@redhat.com>
+Patchwork-id: 97368
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 1/3] spapr: Pass the maximum number of vCPUs to the KVM interrupt controller
+Bugzilla: 1756946
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+The XIVE and XICS-on-XIVE KVM devices on POWER9 hosts can greatly reduce
+their consumption of some scarce HW resources, namely Virtual Presenter
+identifiers, if they know the maximum number of vCPUs that may run in the
+VM.
+
+Prepare ground for this by passing the value down to xics_kvm_connect()
+and kvmppc_xive_connect(). This is purely mechanical, no functional
+change.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Message-Id: <157478678301.67101.2717368060417156338.stgit@bahia.tlslab.ibm.com>
+Reviewed-by: Cédric Le Goater <clg@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 4ffb7496881ec361deaf1f51c41a933bde3cbf7b)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/intc/spapr_xive.c        |  6 ++++--
+ hw/intc/spapr_xive_kvm.c    |  3 ++-
+ hw/intc/xics_kvm.c          |  3 ++-
+ hw/intc/xics_spapr.c        |  5 +++--
+ hw/ppc/spapr_irq.c          |  8 +++++---
+ include/hw/ppc/spapr_irq.h  | 10 ++++++++--
+ include/hw/ppc/spapr_xive.h |  3 ++-
+ include/hw/ppc/xics_spapr.h |  3 ++-
+ 8 files changed, 28 insertions(+), 13 deletions(-)
+
+diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
+index 9cb8d38a3b..a570e6e90a 100644
+--- a/hw/intc/spapr_xive.c
++++ b/hw/intc/spapr_xive.c
+@@ -651,12 +651,14 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
+                      plat_res_int_priorities, sizeof(plat_res_int_priorities)));
+ }
+ 
+-static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
++static int spapr_xive_activate(SpaprInterruptController *intc,
++                               uint32_t nr_servers, Error **errp)
+ {
+     SpaprXive *xive = SPAPR_XIVE(intc);
+ 
+     if (kvm_enabled()) {
+-        int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp);
++        int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, nr_servers,
++                                    errp);
+         if (rc < 0) {
+             return rc;
+         }
+diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
+index 08012ac7cd..c1c837a764 100644
+--- a/hw/intc/spapr_xive_kvm.c
++++ b/hw/intc/spapr_xive_kvm.c
+@@ -740,7 +740,8 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len,
+  * All the XIVE memory regions are now backed by mappings from the KVM
+  * XIVE device.
+  */
+-int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
++int kvmppc_xive_connect(SpaprInterruptController *intc, uint32_t nr_servers,
++                        Error **errp)
+ {
+     SpaprXive *xive = SPAPR_XIVE(intc);
+     XiveSource *xsrc = &xive->source;
+diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
+index 954c424b36..a1f1b7b0d3 100644
+--- a/hw/intc/xics_kvm.c
++++ b/hw/intc/xics_kvm.c
+@@ -342,7 +342,8 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
+     }
+ }
+ 
+-int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
++int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
++                     Error **errp)
+ {
+     ICSState *ics = ICS_SPAPR(intc);
+     int rc;
+diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
+index b3705dab0e..8ae4f41459 100644
+--- a/hw/intc/xics_spapr.c
++++ b/hw/intc/xics_spapr.c
+@@ -422,10 +422,11 @@ static int xics_spapr_post_load(SpaprInterruptController *intc, int version_id)
+     return 0;
+ }
+ 
+-static int xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
++static int xics_spapr_activate(SpaprInterruptController *intc,
++                               uint32_t nr_servers, Error **errp)
+ {
+     if (kvm_enabled()) {
+-        return spapr_irq_init_kvm(xics_kvm_connect, intc, errp);
++        return spapr_irq_init_kvm(xics_kvm_connect, intc, nr_servers, errp);
+     }
+     return 0;
+ }
+diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
+index d6bb7fd2d6..9da423658a 100644
+--- a/hw/ppc/spapr_irq.c
++++ b/hw/ppc/spapr_irq.c
+@@ -70,15 +70,16 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
+     bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
+ }
+ 
+-int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
++int spapr_irq_init_kvm(SpaprInterruptControllerInitKvm fn,
+                        SpaprInterruptController *intc,
++                       uint32_t nr_servers,
+                        Error **errp)
+ {
+     MachineState *machine = MACHINE(qdev_get_machine());
+     Error *local_err = NULL;
+ 
+     if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
+-        if (fn(intc, &local_err) < 0) {
++        if (fn(intc, nr_servers, &local_err) < 0) {
+             if (machine_kernel_irqchip_required(machine)) {
+                 error_prepend(&local_err,
+                               "kernel_irqchip requested but unavailable: ");
+@@ -495,6 +496,7 @@ static void set_active_intc(SpaprMachineState *spapr,
+                             SpaprInterruptController *new_intc)
+ {
+     SpaprInterruptControllerClass *sicc;
++    uint32_t nr_servers = spapr_max_server_number(spapr);
+ 
+     assert(new_intc);
+ 
+@@ -512,7 +514,7 @@ static void set_active_intc(SpaprMachineState *spapr,
+ 
+     sicc = SPAPR_INTC_GET_CLASS(new_intc);
+     if (sicc->activate) {
+-        sicc->activate(new_intc, &error_fatal);
++        sicc->activate(new_intc, nr_servers, &error_fatal);
+     }
+ 
+     spapr->active_intc = new_intc;
+diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
+index ff814d13de..ca8cb44213 100644
+--- a/include/hw/ppc/spapr_irq.h
++++ b/include/hw/ppc/spapr_irq.h
+@@ -43,7 +43,8 @@ typedef struct SpaprInterruptController SpaprInterruptController;
+ typedef struct SpaprInterruptControllerClass {
+     InterfaceClass parent;
+ 
+-    int (*activate)(SpaprInterruptController *intc, Error **errp);
++    int (*activate)(SpaprInterruptController *intc, uint32_t nr_servers,
++                    Error **errp);
+     void (*deactivate)(SpaprInterruptController *intc);
+ 
+     /*
+@@ -98,8 +99,13 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
+ int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
+ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp);
+ int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp);
+-int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
++
++typedef int (*SpaprInterruptControllerInitKvm)(SpaprInterruptController *,
++                                               uint32_t, Error **);
++
++int spapr_irq_init_kvm(SpaprInterruptControllerInitKvm fn,
+                        SpaprInterruptController *intc,
++                       uint32_t nr_servers,
+                        Error **errp);
+ 
+ /*
+diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
+index 742b7e834f..3a103c224d 100644
+--- a/include/hw/ppc/spapr_xive.h
++++ b/include/hw/ppc/spapr_xive.h
+@@ -66,7 +66,8 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
+ /*
+  * KVM XIVE device helpers
+  */
+-int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp);
++int kvmppc_xive_connect(SpaprInterruptController *intc, uint32_t nr_servers,
++                        Error **errp);
+ void kvmppc_xive_disconnect(SpaprInterruptController *intc);
+ void kvmppc_xive_reset(SpaprXive *xive, Error **errp);
+ void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS *eas,
+diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
+index 28b87038c8..1c65c96e3c 100644
+--- a/include/hw/ppc/xics_spapr.h
++++ b/include/hw/ppc/xics_spapr.h
+@@ -32,7 +32,8 @@
+ #define TYPE_ICS_SPAPR "ics-spapr"
+ #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
+ 
+-int xics_kvm_connect(SpaprInterruptController *intc, Error **errp);
++int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
++                     Error **errp);
+ void xics_kvm_disconnect(SpaprInterruptController *intc);
+ bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-target-arm-Fix-PAuth-sbox-functions.patch b/SOURCES/kvm-target-arm-Fix-PAuth-sbox-functions.patch
new file mode 100644
index 0000000..0e08184
--- /dev/null
+++ b/SOURCES/kvm-target-arm-Fix-PAuth-sbox-functions.patch
@@ -0,0 +1,65 @@
+From b8c8288a65146952cdfe7d5f0cd96734c9de8ee1 Mon Sep 17 00:00:00 2001
+From: jmaloy <jmaloy@redhat.com>
+Date: Thu, 7 May 2020 17:57:08 +0100
+Subject: [PATCH 1/7] target/arm: Fix PAuth sbox functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: jmaloy <jmaloy@redhat.com>
+Message-id: <20200507175708.1165177-2-jmaloy@redhat.com>
+Patchwork-id: 96341
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/1] target/arm: Fix PAuth sbox functions
+Bugzilla: 1813940
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+
+From: Vincent Dehors <vincent.dehors@smile.fr>
+
+In the PAC computation, sbox was applied over wrong bits.
+As this is a 4-bit sbox, bit index should be incremented by 4 instead of 16.
+
+Test vector from QARMA paper (https://eprint.iacr.org/2016/444.pdf) was
+used to verify one computation of the pauth_computepac() function which
+uses sbox2.
+
+Launchpad: https://bugs.launchpad.net/bugs/1859713
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Signed-off-by: Vincent DEHORS <vincent.dehors@smile.fr>
+Signed-off-by: Adrien GRASSEIN <adrien.grassein@smile.fr>
+Message-id: 20200116230809.19078-2-richard.henderson@linaro.org
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+(cherry picked from commit de0b1bae6461f67243282555475f88b2384a1eb9)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/arm/pauth_helper.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
+index d3194f2..0a5f41e 100644
+--- a/target/arm/pauth_helper.c
++++ b/target/arm/pauth_helper.c
+@@ -89,7 +89,7 @@ static uint64_t pac_sub(uint64_t i)
+     uint64_t o = 0;
+     int b;
+ 
+-    for (b = 0; b < 64; b += 16) {
++    for (b = 0; b < 64; b += 4) {
+         o |= (uint64_t)sub[(i >> b) & 0xf] << b;
+     }
+     return o;
+@@ -104,7 +104,7 @@ static uint64_t pac_inv_sub(uint64_t i)
+     uint64_t o = 0;
+     int b;
+ 
+-    for (b = 0; b < 64; b += 16) {
++    for (b = 0; b < 64; b += 4) {
+         o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
+     }
+     return o;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-Add-ARCH_CAPABILITIES-related-bits-into-.patch b/SOURCES/kvm-target-i386-Add-ARCH_CAPABILITIES-related-bits-into-.patch
new file mode 100644
index 0000000..ffb6ab7
--- /dev/null
+++ b/SOURCES/kvm-target-i386-Add-ARCH_CAPABILITIES-related-bits-into-.patch
@@ -0,0 +1,83 @@
+From 4c9201a83e3ff48d2a55e45a34eb27966a1e4ab0 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Fri, 5 Jun 2020 18:37:33 -0400
+Subject: [PATCH 3/3] target/i386: Add ARCH_CAPABILITIES related bits into
+ Icelake-Server CPU model
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: plai@redhat.com
+Message-id: <20200605183733.8269-1-plai@redhat.com>
+Patchwork-id: 97380
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH] target/i386: Add ARCH_CAPABILITIES related bits into Icelake-Server CPU model
+Bugzilla: 1840342
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+RH-Acked-by: Bandan Das <bsd@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Xiaoyao Li <xiaoyao.li@intel.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1840342
+Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=28983822
+Branch: rhel-av-8.2.1
+
+Tested on HOST: intel-whitley-09.khw1.lab.eng.bos.redhat.com
+
+1. qemu-kvm -cpu host …
+        VM guest does have arch_capabilities in cpuinfo/flags.
+	[Expected success]
+
+2. qemu-kvm -cpu Icelake-Server …
+        VM guest does NOT have arch_capabilities in cpuinfo/flags.
+	[Expected failure]
+
+3. qemu-kvm -cpu Icelake-Server-v3 …
+        VM guest does have arch_capabilities in cpuinfo/flags.
+	[Expected success]
+
+---
+
+Current Icelake-Server CPU model lacks all the features enumerated by
+MSR_IA32_ARCH_CAPABILITIES.
+
+Add them, so that guest of "Icelake-Server" can see all of them.
+
+Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Message-Id: <20200316095605.12318-1-xiaoyao.li@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit d965dc35592d24c0c1519f1c566223c6277cb80e)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+---
+ target/i386/cpu.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index b763adcdc5..7d7b016bb7 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3496,6 +3496,19 @@ static X86CPUDefinition builtin_x86_defs[] = {
+                     { /* end of list */ }
+                 },
+             },
++            {
++                .version = 3,
++                .props = (PropValue[]) {
++                    { "arch-capabilities", "on" },
++                    { "rdctl-no", "on" },
++                    { "ibrs-all", "on" },
++                    { "skip-l1dfl-vmentry", "on" },
++                    { "mds-no", "on" },
++                    { "pschange-mc-no", "on" },
++                    { "taa-no", "on" },
++                    { /* end of list */ }
++                },
++            },
+             { /* end of list */ }
+         }
+     },
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-target-i386-Add-missed-features-to-Cooperlake-CPU-mo.patch b/SOURCES/kvm-target-i386-Add-missed-features-to-Cooperlake-CPU-mo.patch
new file mode 100644
index 0000000..ef95ccf
--- /dev/null
+++ b/SOURCES/kvm-target-i386-Add-missed-features-to-Cooperlake-CPU-mo.patch
@@ -0,0 +1,103 @@
+From 1ffeb321151b3878bcbb2229639456c0677305f5 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Fri, 15 May 2020 18:02:43 +0100
+Subject: [PATCH 17/17] target/i386: Add missed features to Cooperlake CPU
+ model
+
+RH-Author: plai@redhat.com
+Message-id: <20200515180243.17488-5-plai@redhat.com>
+Patchwork-id: 96611
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 4/4] target/i386: Add missed features to Cooperlake CPU model
+Bugzilla: 1769912
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Xiaoyao Li <xiaoyao.li@intel.com>
+
+It lacks VMX features and two security feature bits (disclosed recently) in
+MSR_IA32_ARCH_CAPABILITIES in current Cooperlake CPU model, so add them.
+
+Fixes: 22a866b6166d ("i386: Add new CPU model Cooperlake")
+Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Message-Id: <20191225063018.20038-3-xiaoyao.li@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 2dea9d9ca4ea7e9afe83d0b4153b21a16987e866)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 996a74f..b763adc 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -3202,7 +3202,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
+             CPUID_7_0_EDX_SPEC_CTRL_SSBD | CPUID_7_0_EDX_ARCH_CAPABILITIES,
+         .features[FEAT_ARCH_CAPABILITIES] =
+             MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
+-            MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO,
++            MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO |
++            MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO,
+         .features[FEAT_7_1_EAX] =
+             CPUID_7_1_EAX_AVX512_BF16,
+         /*
+@@ -3217,6 +3218,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 (Cooperlake)",
+     },
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch b/SOURCES/kvm-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch
new file mode 100644
index 0000000..ad2dd77
--- /dev/null
+++ b/SOURCES/kvm-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch
@@ -0,0 +1,62 @@
+From 6f0630299a3edbb8f5e5ac41eb9e1f1c363f1e3e Mon Sep 17 00:00:00 2001
+From: Danilo de Paula <ddepaula@redhat.com>
+Date: Tue, 9 Jun 2020 18:46:51 +0100
+Subject: [PATCH 15/17] target/i386: Add new bit definitions of
+ MSR_IA32_ARCH_CAPABILITIES
+
+RH-Author: Danilo de Paula <ddepaula@redhat.com>
+Message-id: <20200609184651.1328372-1-ddepaula@redhat.com>
+Patchwork-id: 97489
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 5/4] target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES
+Bugzilla: 1769912
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Danilo de Paula <ddepaula@redhat.com>
+
+redhat: builds with that series were failing. It complains about a undefined
+MSR_ARCH_CAP_TAA_NO.
+
+The bit 6, 7 and 8 of MSR_IA32_ARCH_CAPABILITIES are recently disclosed
+for some security issues. Add the definitions for them to be used by named
+CPU models.
+
+Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
+Message-Id: <20191225063018.20038-2-xiaoyao.li@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 6c997b4adb300788d61d72e2b8bc67c03a584956)
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.h | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index e77d101..7bfbf2a 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -836,12 +836,15 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_TOPOLOGY_LEVEL_DIE      (5U << 8)
+ 
+ /* MSR Feature Bits */
+-#define MSR_ARCH_CAP_RDCL_NO    (1U << 0)
+-#define MSR_ARCH_CAP_IBRS_ALL   (1U << 1)
+-#define MSR_ARCH_CAP_RSBA       (1U << 2)
++#define MSR_ARCH_CAP_RDCL_NO            (1U << 0)
++#define MSR_ARCH_CAP_IBRS_ALL           (1U << 1)
++#define MSR_ARCH_CAP_RSBA               (1U << 2)
+ #define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
+-#define MSR_ARCH_CAP_SSB_NO     (1U << 4)
+-#define MSR_ARCH_CAP_MDS_NO     (1U << 5)
++#define MSR_ARCH_CAP_SSB_NO             (1U << 4)
++#define MSR_ARCH_CAP_MDS_NO             (1U << 5)
++#define MSR_ARCH_CAP_PSCHANGE_MC_NO     (1U << 6)
++#define MSR_ARCH_CAP_TSX_CTRL_MSR       (1U << 7)
++#define MSR_ARCH_CAP_TAA_NO             (1U << 8)
+ 
+ #define MSR_CORE_CAP_SPLIT_LOCK_DETECT  (1U << 5)
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-i386-set-the-CPUID-level-to-0x14-on-old-machi.patch b/SOURCES/kvm-target-i386-set-the-CPUID-level-to-0x14-on-old-machi.patch
new file mode 100644
index 0000000..49e54ba
--- /dev/null
+++ b/SOURCES/kvm-target-i386-set-the-CPUID-level-to-0x14-on-old-machi.patch
@@ -0,0 +1,69 @@
+From 72a1827006be22791017ff2b671eac1c96be5d12 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 7 May 2020 22:09:23 +0100
+Subject: [PATCH 01/26] target/i386: set the CPUID level to 0x14 on old
+ machine-type
+
+RH-Author: plai@redhat.com
+Message-id: <20200507220923.13723-1-plai@redhat.com>
+Patchwork-id: 96347
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH RESEND] target/i386: set the CPUID level to 0x14 on old machine-type
+Bugzilla: 1513681
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+
+From: Luwei Kang <luwei.kang@intel.com>
+
+BZ https://bugzilla.redhat.com/show_bug.cgi?id=1513681
+Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=28146304
+Branch: rhel-av-8.2.1
+
+Tested on intel-icelake-y-01.ml3.eng.bos.redhat.com.
+
+The CPUID level need to be set to 0x14 manually on old
+machine-type if Intel PT is enabled in guest. E.g. the
+CPUID[0].EAX(level)=7 and CPUID[7].EBX[25](intel-pt)=1 when the
+Qemu with "-machine pc-i440fx-3.1 -cpu qemu64,+intel-pt" parameter.
+
+Some Intel PT capabilities are exposed by leaf 0x14 and the
+missing capabilities will cause some MSRs access failed.
+This patch add a warning message to inform the user to extend
+the CPUID level.
+
+Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Luwei Kang <luwei.kang@intel.com>
+Message-Id: <1584031686-16444-1-git-send-email-luwei.kang@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit ddc2fc9e4e42ebce48b088963dc7fbd1c08d5f33)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 1685a8c..0f0a2db 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -6206,9 +6206,14 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
+         x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
+ 
+         /* Intel Processor Trace requires CPUID[0x14] */
+-        if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
+-             kvm_enabled() && cpu->intel_pt_auto_level) {
+-            x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
++        if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT)) {
++            if (cpu->intel_pt_auto_level) {
++                x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
++            } else if (cpu->env.cpuid_min_level < 0x14) {
++                mark_unavailable_features(cpu, FEAT_7_0_EBX,
++                    CPUID_7_0_EBX_INTEL_PT,
++                    "Intel PT need CPUID leaf 0x14, please set by \"-cpu ...,+intel-pt,level=0x14\"");
++            }
+         }
+ 
+         /* CPU topology with multi-dies support requires CPUID[0x1F] */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-target-s390x-kvm-Enable-adapter-interruption-suppres.patch b/SOURCES/kvm-target-s390x-kvm-Enable-adapter-interruption-suppres.patch
new file mode 100644
index 0000000..38e5637
--- /dev/null
+++ b/SOURCES/kvm-target-s390x-kvm-Enable-adapter-interruption-suppres.patch
@@ -0,0 +1,60 @@
+From c4fe37ae6d75ed72e6a3bde01fea053eb508274c Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 5 Jun 2020 07:41:11 -0400
+Subject: [PATCH 41/42] target/s390x/kvm: Enable adapter interruption
+ suppression again
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200605074111.2185-4-thuth@redhat.com>
+Patchwork-id: 97370
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 3/3] target/s390x/kvm: Enable adapter interruption suppression again
+Bugzilla: 1756946
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+The AIS feature has been disabled late in the v2.10 development cycle since
+there were some issues with migration (see commit 3f2d07b3b01ea61126b -
+"s390x/ais: for 2.10 stable: disable ais facility"). We originally wanted
+to enable it again for newer machine types, but apparently we forgot to do
+this so far. Let's do it now for the machines that support proper CPU models.
+
+Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1756946
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <20200122101437.5069-1-thuth@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit a5c8617af6919515b84256978452edf07401c45e)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/s390x/kvm.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
+index c589ef9034..0bbf8f81b0 100644
+--- a/target/s390x/kvm.c
++++ b/target/s390x/kvm.c
+@@ -377,10 +377,13 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
+     /*
+      * The migration interface for ais was introduced with kernel 4.13
+      * but the capability itself had been active since 4.12. As migration
+-     * support is considered necessary let's disable ais in the 2.10
+-     * machine.
++     * support is considered necessary, we only try to enable this for
++     * newer machine types if KVM_CAP_S390_AIS_MIGRATION is available.
+      */
+-    /* kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0); */
++    if (cpu_model_allowed() && kvm_kernel_irqchip_allowed() &&
++        kvm_check_extension(s, KVM_CAP_S390_AIS_MIGRATION)) {
++        kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0);
++    }
+ 
+     kvm_set_max_memslot_size(KVM_SLOT_MAX_BYTES);
+     return 0;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-tests-bios-tables-test-add-test-cases-for-ACPI-HMAT.patch b/SOURCES/kvm-tests-bios-tables-test-add-test-cases-for-ACPI-HMAT.patch
new file mode 100644
index 0000000..12df637
--- /dev/null
+++ b/SOURCES/kvm-tests-bios-tables-test-add-test-cases-for-ACPI-HMAT.patch
@@ -0,0 +1,127 @@
+From 6d549629becb69f315dd4213f730122d19c9c566 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:54 +0100
+Subject: [PATCH 11/12] tests/bios-tables-test: add test cases for ACPI HMAT
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-11-plai@redhat.com>
+Patchwork-id: 96739
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 10/11] tests/bios-tables-test: add test cases for ACPI HMAT
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Tao Xu <tao3.xu@intel.com>
+
+ACPI table HMAT has been introduced, QEMU now builds HMAT tables for
+Heterogeneous Memory with boot option '-numa node'.
+
+Add test cases on PC and Q35 machines with 2 numa nodes.
+Because HMAT is generated when system enable numa, the
+following tables need to be added for this test:
+    tests/data/acpi/pc/APIC.acpihmat
+    tests/data/acpi/pc/SRAT.acpihmat
+    tests/data/acpi/pc/HMAT.acpihmat
+    tests/data/acpi/pc/DSDT.acpihmat
+    tests/data/acpi/q35/APIC.acpihmat
+    tests/data/acpi/q35/SRAT.acpihmat
+    tests/data/acpi/q35/HMAT.acpihmat
+    tests/data/acpi/q35/DSDT.acpihmat
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+Reviewed-by: Daniel Black <daniel@linux.ibm.com>
+Reviewed-by: Jingqi Liu <Jingqi.liu@intel.com>
+Suggested-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-9-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit 1c8f85d93d261dc555a0aad6f54f2b5e8009d859)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/bios-tables-test-allowed-diff.h |  8 +++++++
+ tests/bios-tables-test.c              | 44 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 52 insertions(+)
+
+diff --git a/tests/bios-tables-test-allowed-diff.h b/tests/bios-tables-test-allowed-diff.h
+index dfb8523..3c9e0c9 100644
+--- a/tests/bios-tables-test-allowed-diff.h
++++ b/tests/bios-tables-test-allowed-diff.h
+@@ -1 +1,9 @@
+ /* List of comma-separated changed AML files to ignore */
++"tests/data/acpi/pc/APIC.acpihmat",
++"tests/data/acpi/pc/SRAT.acpihmat",
++"tests/data/acpi/pc/HMAT.acpihmat",
++"tests/data/acpi/pc/DSDT.acpihmat",
++"tests/data/acpi/q35/APIC.acpihmat",
++"tests/data/acpi/q35/SRAT.acpihmat",
++"tests/data/acpi/q35/HMAT.acpihmat",
++"tests/data/acpi/q35/DSDT.acpihmat",
+diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
+index 79f5da0..9823820 100644
+--- a/tests/bios-tables-test.c
++++ b/tests/bios-tables-test.c
+@@ -947,6 +947,48 @@ static void test_acpi_virt_tcg_numamem(void)
+ 
+ }
+ 
++static void test_acpi_tcg_acpi_hmat(const char *machine)
++{
++    test_data data;
++
++    memset(&data, 0, sizeof(data));
++    data.machine = machine;
++    data.variant = ".acpihmat";
++    test_acpi_one(" -machine hmat=on"
++                  " -smp 2,sockets=2"
++                  " -m 128M,slots=2,maxmem=1G"
++                  " -object memory-backend-ram,size=64M,id=m0"
++                  " -object memory-backend-ram,size=64M,id=m1"
++                  " -numa node,nodeid=0,memdev=m0"
++                  " -numa node,nodeid=1,memdev=m1,initiator=0"
++                  " -numa cpu,node-id=0,socket-id=0"
++                  " -numa cpu,node-id=0,socket-id=1"
++                  " -numa hmat-lb,initiator=0,target=0,hierarchy=memory,"
++                  "data-type=access-latency,latency=1"
++                  " -numa hmat-lb,initiator=0,target=0,hierarchy=memory,"
++                  "data-type=access-bandwidth,bandwidth=65534M"
++                  " -numa hmat-lb,initiator=0,target=1,hierarchy=memory,"
++                  "data-type=access-latency,latency=65534"
++                  " -numa hmat-lb,initiator=0,target=1,hierarchy=memory,"
++                  "data-type=access-bandwidth,bandwidth=32767M"
++                  " -numa hmat-cache,node-id=0,size=10K,level=1,"
++                  "associativity=direct,policy=write-back,line=8"
++                  " -numa hmat-cache,node-id=1,size=10K,level=1,"
++                  "associativity=direct,policy=write-back,line=8",
++                  &data);
++    free_test_data(&data);
++}
++
++static void test_acpi_q35_tcg_acpi_hmat(void)
++{
++    test_acpi_tcg_acpi_hmat(MACHINE_Q35);
++}
++
++static void test_acpi_piix4_tcg_acpi_hmat(void)
++{
++    test_acpi_tcg_acpi_hmat(MACHINE_PC);
++}
++
+ static void test_acpi_virt_tcg(void)
+ {
+     test_data data = {
+@@ -991,6 +1033,8 @@ int main(int argc, char *argv[])
+         qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem);
+         qtest_add_func("acpi/piix4/dimmpxm", test_acpi_piix4_tcg_dimm_pxm);
+         qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
++        qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat);
++        qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat);
+     } else if (strcmp(arch, "aarch64") == 0) {
+         qtest_add_func("acpi/virt", test_acpi_virt_tcg);
+         qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tests-boot-sector-Fix-the-bad-s390x-assembler-code.patch b/SOURCES/kvm-tests-boot-sector-Fix-the-bad-s390x-assembler-code.patch
new file mode 100644
index 0000000..240c408
--- /dev/null
+++ b/SOURCES/kvm-tests-boot-sector-Fix-the-bad-s390x-assembler-code.patch
@@ -0,0 +1,60 @@
+From f73b18e03c6758500bf367b1575205772d1f878f Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:53:52 -0400
+Subject: [PATCH 10/42] tests/boot-sector: Fix the bad s390x assembler code
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-11-thuth@redhat.com>
+Patchwork-id: 97031
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 10/38] tests/boot-sector: Fix the bad s390x assembler code
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+There are currently two bugs in s390x_code[]: First, the initial jump
+uses the wrong offset, so it was jumping to 0x10014 instead of 0x10010.
+Second, LHI only loads the lower 32-bit of the register.
+
+Everything worked fine as long as the s390-ccw bios code was jumping
+here with r3 containing zeroes in the uppermost 48 bit - which just
+happened to be the case so far by accident. But we can not rely on this
+fact, and indeed one of the recent suggested patches to jump2ipl.c cause
+the newer GCCs to put different values into r3. In that case the code
+from s390x_code[] crashes very ungracefully.
+
+Thus let's make sure to jump to the right instruction, and use LGHI
+instead of LHI to make sure that we always zero out the upper bits
+of the register.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <20191217150642.27946-1-thuth@redhat.com>
+Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 5afec76fbe2c07d03fd8c9ac525140059499637a)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/boot-sector.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tests/boot-sector.c b/tests/boot-sector.c
+index 7824286b9a..9e66c6d013 100644
+--- a/tests/boot-sector.c
++++ b/tests/boot-sector.c
+@@ -75,11 +75,11 @@ static const uint8_t s390x_psw_and_magic[] = {
+     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* in the s390-ccw bios */
+ };
+ static const uint8_t s390x_code[] = {
+-    0xa7, 0xf4, 0x00, 0x0a,                                /* j 0x10010 */
++    0xa7, 0xf4, 0x00, 0x08,                                /* j 0x10010 */
+     0x00, 0x00, 0x00, 0x00,
+     'S', '3', '9', '0',
+     'E', 'P', 0x00, 0x01,
+-    0xa7, 0x38, HIGH(SIGNATURE_ADDR), LOW(SIGNATURE_ADDR), /* lhi r3,0x7c10 */
++    0xa7, 0x39, HIGH(SIGNATURE_ADDR), LOW(SIGNATURE_ADDR), /* lghi r3,0x7c10 */
+     0xa7, 0x48, LOW(SIGNATURE), HIGH(SIGNATURE),           /* lhi r4,0xadde */
+     0x40, 0x40, 0x30, 0x00,                                /* sth r4,0(r3) */
+     0xa7, 0xf4, 0xff, 0xfa                                 /* j 0x10010 */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-tests-numa-Add-case-for-QMP-build-HMAT.patch b/SOURCES/kvm-tests-numa-Add-case-for-QMP-build-HMAT.patch
new file mode 100644
index 0000000..41ee71c
--- /dev/null
+++ b/SOURCES/kvm-tests-numa-Add-case-for-QMP-build-HMAT.patch
@@ -0,0 +1,266 @@
+From 0f11aae02dcabd3a5ee0b5946aec39da6dddea52 Mon Sep 17 00:00:00 2001
+From: "plai@redhat.com" <plai@redhat.com>
+Date: Thu, 21 May 2020 23:56:53 +0100
+Subject: [PATCH 10/12] tests/numa: Add case for QMP build HMAT
+
+RH-Author: plai@redhat.com
+Message-id: <20200521235655.27141-10-plai@redhat.com>
+Patchwork-id: 96735
+O-Subject: [RHEL8.2.1 AV qemu-kvm PATCH 09/11] tests/numa: Add case for QMP build HMAT
+Bugzilla: 1600217
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
+RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
+
+From: Tao Xu <tao3.xu@intel.com>
+
+Check configuring HMAT usecase
+
+Acked-by: Markus Armbruster <armbru@redhat.com>
+Suggested-by: Igor Mammedov <imammedo@redhat.com>
+Signed-off-by: Tao Xu <tao3.xu@intel.com>
+Message-Id: <20191213011929.2520-8-tao3.xu@intel.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Igor Mammedov <imammedo@redhat.com>
+(cherry picked from commit d00817c944ed15fbe4a61d44fe7f9fe166c7df88)
+Signed-off-by: Paul Lai <plai@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/numa-test.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 213 insertions(+)
+
+diff --git a/tests/numa-test.c b/tests/numa-test.c
+index 8de8581..17dd807 100644
+--- a/tests/numa-test.c
++++ b/tests/numa-test.c
+@@ -327,6 +327,216 @@ static void pc_dynamic_cpu_cfg(const void *data)
+     qtest_quit(qs);
+ }
+ 
++static void pc_hmat_build_cfg(const void *data)
++{
++    QTestState *qs = qtest_initf("%s -nodefaults --preconfig -machine hmat=on "
++                     "-smp 2,sockets=2 "
++                     "-m 128M,slots=2,maxmem=1G "
++                     "-object memory-backend-ram,size=64M,id=m0 "
++                     "-object memory-backend-ram,size=64M,id=m1 "
++                     "-numa node,nodeid=0,memdev=m0 "
++                     "-numa node,nodeid=1,memdev=m1,initiator=0 "
++                     "-numa cpu,node-id=0,socket-id=0 "
++                     "-numa cpu,node-id=0,socket-id=1",
++                     data ? (char *)data : "");
++
++    /* Fail: Initiator should be less than the number of nodes */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 2, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }")));
++
++    /* Fail: Target should be less than the number of nodes */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 2,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }")));
++
++    /* Fail: Initiator should contain cpu */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 1, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\" } }")));
++
++    /* Fail: Data-type mismatch */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"write-latency\","
++        " 'bandwidth': 524288000 } }")));
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"read-bandwidth\","
++        " 'latency': 5 } }")));
++
++    /* Fail: Bandwidth should be 1MB (1048576) aligned */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
++        " 'bandwidth': 1048575 } }")));
++
++    /* Configuring HMAT bandwidth and latency details */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
++        " 'latency': 1 } }")));    /* 1 ns */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
++        " 'latency': 5 } }")));    /* Fail: Duplicate configuration */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
++        " 'bandwidth': 68717379584 } }")));    /* 65534 MB/s */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
++        " 'latency': 65534 } }")));    /* 65534 ns */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
++        " 'bandwidth': 34358689792 } }")));    /* 32767 MB/s */
++
++    /* Fail: node_id should be less than the number of nodes */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 2, 'size': 10240,"
++        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++
++    /* Fail: level should be less than HMAT_LB_LEVELS (4) */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 4, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++
++    /* Fail: associativity option should be 'none', if level is 0 */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 0, 'associativity': \"direct\", 'policy': \"none\","
++        " 'line': 0 } }")));
++    /* Fail: policy option should be 'none', if level is 0 */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 0, 'associativity': \"none\", 'policy': \"write-back\","
++        " 'line': 0 } }")));
++    /* Fail: line option should be 0, if level is 0 */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 0, 'associativity': \"none\", 'policy': \"none\","
++        " 'line': 8 } }")));
++
++    /* Configuring HMAT memory side cache attributes */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));    /* Fail: Duplicate configuration */
++    /* Fail: The size of level 2 size should be small than level 1 */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 2, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++    /* Fail: The size of level 0 size should be larger than level 1 */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 0, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 1, 'size': 10240,"
++        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++
++    /* let machine initialization to complete and run */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs,
++        "{ 'execute': 'x-exit-preconfig' }")));
++    qtest_qmp_eventwait(qs, "RESUME");
++
++    qtest_quit(qs);
++}
++
++static void pc_hmat_off_cfg(const void *data)
++{
++    QTestState *qs = qtest_initf("%s -nodefaults --preconfig "
++                     "-smp 2,sockets=2 "
++                     "-m 128M,slots=2,maxmem=1G "
++                     "-object memory-backend-ram,size=64M,id=m0 "
++                     "-object memory-backend-ram,size=64M,id=m1 "
++                     "-numa node,nodeid=0,memdev=m0",
++                     data ? (char *)data : "");
++
++    /*
++     * Fail: Enable HMAT with -machine hmat=on
++     * before using any of hmat specific options
++     */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\","
++        " 'initiator': 0 } }")));
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'node', 'nodeid': 1, 'memdev': \"m1\" } }")));
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
++        " 'latency': 1 } }")));
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++
++    /* let machine initialization to complete and run */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs,
++        "{ 'execute': 'x-exit-preconfig' }")));
++    qtest_qmp_eventwait(qs, "RESUME");
++
++    qtest_quit(qs);
++}
++
++static void pc_hmat_erange_cfg(const void *data)
++{
++    QTestState *qs = qtest_initf("%s -nodefaults --preconfig -machine hmat=on "
++                     "-smp 2,sockets=2 "
++                     "-m 128M,slots=2,maxmem=1G "
++                     "-object memory-backend-ram,size=64M,id=m0 "
++                     "-object memory-backend-ram,size=64M,id=m1 "
++                     "-numa node,nodeid=0,memdev=m0 "
++                     "-numa node,nodeid=1,memdev=m1,initiator=0 "
++                     "-numa cpu,node-id=0,socket-id=0 "
++                     "-numa cpu,node-id=0,socket-id=1",
++                     data ? (char *)data : "");
++
++    /* Can't store the compressed latency */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
++        " 'latency': 1 } }")));    /* 1 ns */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-latency\","
++        " 'latency': 65535 } }")));    /* 65535 ns */
++
++    /* Test the 0 input (bandwidth not provided) */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 0,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
++        " 'bandwidth': 0 } }")));    /* 0 MB/s */
++    /* Fail: bandwidth should be provided before memory side cache attributes */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-cache', 'node-id': 0, 'size': 10240,"
++        " 'level': 1, 'associativity': \"direct\", 'policy': \"write-back\","
++        " 'line': 8 } }")));
++
++    /* Can't store the compressed bandwidth */
++    g_assert_true(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
++        " 'arguments': { 'type': 'hmat-lb', 'initiator': 0, 'target': 1,"
++        " 'hierarchy': \"memory\", 'data-type': \"access-bandwidth\","
++        " 'bandwidth': 68718428160 } }")));    /* 65535 MB/s */
++
++    /* let machine initialization to complete and run */
++    g_assert_false(qmp_rsp_is_err(qtest_qmp(qs,
++        "{ 'execute': 'x-exit-preconfig' }")));
++    qtest_qmp_eventwait(qs, "RESUME");
++
++    qtest_quit(qs);
++}
++
+ int main(int argc, char **argv)
+ {
+     const char *args = NULL;
+@@ -346,6 +556,9 @@ int main(int argc, char **argv)
+     if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) {
+         qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu);
+         qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg);
++        qtest_add_data_func("/numa/pc/hmat/build", args, pc_hmat_build_cfg);
++        qtest_add_data_func("/numa/pc/hmat/off", args, pc_hmat_off_cfg);
++        qtest_add_data_func("/numa/pc/hmat/erange", args, pc_hmat_erange_cfg);
+     }
+ 
+     if (!strcmp(arch, "ppc64")) {
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-tools-virtiofsd-passthrough_ll-Fix-double-close.patch b/SOURCES/kvm-tools-virtiofsd-passthrough_ll-Fix-double-close.patch
new file mode 100644
index 0000000..6af549a
--- /dev/null
+++ b/SOURCES/kvm-tools-virtiofsd-passthrough_ll-Fix-double-close.patch
@@ -0,0 +1,56 @@
+From 8ce8ccc2a22798a89bac06a37427c3a3cea91a62 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:35:54 +0100
+Subject: [PATCH 3/9] tools/virtiofsd/passthrough_ll: Fix double close()
+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: <20200505163600.22956-2-dgilbert@redhat.com>
+Patchwork-id: 96269
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/7] tools/virtiofsd/passthrough_ll: Fix double close()
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+On success, the fdopendir() call closes fd. Later on the error
+path we try to close an already-closed fd. This can lead to
+use-after-free. Fix by only closing the fd if the fdopendir()
+call failed.
+
+Cc: qemu-stable@nongnu.org
+Fixes: b39bce121b (add dirp_map to hide lo_dirp pointers)
+Reported-by: Coverity (CID 1421933 USE_AFTER_FREE)
+Suggested-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Message-Id: <20200321120654.7985-1-philmd@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit e1cd92d95cd4f97b3464c4e08cd5b22bf5ca05cb)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 9cba3f1..50ff672 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -1524,8 +1524,7 @@ out_err:
+     if (d) {
+         if (d->dp) {
+             closedir(d->dp);
+-        }
+-        if (fd != -1) {
++        } else if (fd != -1) {
+             close(fd);
+         }
+         free(d);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-vfio-ccw-Add-support-for-the-CRW-region-and-IRQ.patch b/SOURCES/kvm-vfio-ccw-Add-support-for-the-CRW-region-and-IRQ.patch
new file mode 100644
index 0000000..c515676
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-Add-support-for-the-CRW-region-and-IRQ.patch
@@ -0,0 +1,175 @@
+From 58edd0fba4d9e98edfeb16139467d6035a1f4e61 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:42 -0400
+Subject: [PATCH 08/12] vfio-ccw: Add support for the CRW region and IRQ
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-9-cohuck@redhat.com>
+Patchwork-id: 97698
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 8/9] vfio-ccw: Add support for the CRW region and IRQ
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Farhan Ali <alifm@linux.ibm.com>
+
+The crw region can be used to obtain information about
+Channel Report Words (CRW) from vfio-ccw driver.
+
+Currently only channel-path related CRWs are passed to
+QEMU from vfio-ccw driver.
+
+Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200505125757.98209-7-farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit f030532f2ad6eeb200034915e9c6357cce81b538)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/ccw.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index 94a0d9840d..b72a505893 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -44,7 +44,11 @@ struct VFIOCCWDevice {
+     uint64_t schib_region_size;
+     uint64_t schib_region_offset;
+     struct ccw_schib_region *schib_region;
++    uint64_t crw_region_size;
++    uint64_t crw_region_offset;
++    struct ccw_crw_region *crw_region;
+     EventNotifier io_notifier;
++    EventNotifier crw_notifier;
+     bool force_orb_pfch;
+     bool warned_orb_pfch;
+ };
+@@ -254,6 +258,44 @@ static void vfio_ccw_reset(DeviceState *dev)
+     ioctl(vcdev->vdev.fd, VFIO_DEVICE_RESET);
+ }
+ 
++static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
++{
++    struct ccw_crw_region *region = vcdev->crw_region;
++    CRW crw;
++    int size;
++
++    /* Keep reading CRWs as long as data is returned */
++    do {
++        memset(region, 0, sizeof(*region));
++        size = pread(vcdev->vdev.fd, region, vcdev->crw_region_size,
++                     vcdev->crw_region_offset);
++
++        if (size == -1) {
++            error_report("vfio-ccw: Read crw region failed with errno=%d",
++                         errno);
++            break;
++        }
++
++        if (region->crw == 0) {
++            /* No more CRWs to queue */
++            break;
++        }
++
++        memcpy(&crw, &region->crw, sizeof(CRW));
++
++        css_crw_add_to_queue(crw);
++    } while (1);
++}
++
++static void vfio_ccw_crw_notifier_handler(void *opaque)
++{
++    VFIOCCWDevice *vcdev = opaque;
++
++    while (event_notifier_test_and_clear(&vcdev->crw_notifier)) {
++        vfio_ccw_crw_read(vcdev);
++    }
++}
++
+ static void vfio_ccw_io_notifier_handler(void *opaque)
+ {
+     VFIOCCWDevice *vcdev = opaque;
+@@ -340,6 +382,10 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
+         notifier = &vcdev->io_notifier;
+         fd_read = vfio_ccw_io_notifier_handler;
+         break;
++    case VFIO_CCW_CRW_IRQ_INDEX:
++        notifier = &vcdev->crw_notifier;
++        fd_read = vfio_ccw_crw_notifier_handler;
++        break;
+     default:
+         error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
+         return;
+@@ -391,6 +437,9 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
+     case VFIO_CCW_IO_IRQ_INDEX:
+         notifier = &vcdev->io_notifier;
+         break;
++    case VFIO_CCW_CRW_IRQ_INDEX:
++        notifier = &vcdev->crw_notifier;
++        break;
+     default:
+         error_report("vfio: Unsupported device irq(%d)", irq);
+         return;
+@@ -468,10 +517,24 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+         vcdev->schib_region = g_malloc(info->size);
+     }
+ 
++    ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
++                                   VFIO_REGION_SUBTYPE_CCW_CRW, &info);
++
++    if (!ret) {
++        vcdev->crw_region_size = info->size;
++        if (sizeof(*vcdev->crw_region) != vcdev->crw_region_size) {
++            error_setg(errp, "vfio: Unexpected size of the CRW region");
++            goto out_err;
++        }
++        vcdev->crw_region_offset = info->offset;
++        vcdev->crw_region = g_malloc(info->size);
++    }
++
+     g_free(info);
+     return;
+ 
+ out_err:
++    g_free(vcdev->crw_region);
+     g_free(vcdev->schib_region);
+     g_free(vcdev->async_cmd_region);
+     g_free(vcdev->io_region);
+@@ -481,6 +544,7 @@ out_err:
+ 
+ static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
+ {
++    g_free(vcdev->crw_region);
+     g_free(vcdev->schib_region);
+     g_free(vcdev->async_cmd_region);
+     g_free(vcdev->io_region);
+@@ -596,6 +660,14 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
+         goto out_notifier_err;
+     }
+ 
++    if (vcdev->crw_region) {
++        vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err);
++        if (err) {
++            vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
++            goto out_notifier_err;
++        }
++    }
++
+     return;
+ 
+ out_notifier_err:
+@@ -620,6 +692,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
+     S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+     VFIOGroup *group = vcdev->vdev.group;
+ 
++    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
+     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
+     vfio_ccw_put_region(vcdev);
+     vfio_ccw_put_device(vcdev);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-ccw-Add-support-for-the-schib-region.patch b/SOURCES/kvm-vfio-ccw-Add-support-for-the-schib-region.patch
new file mode 100644
index 0000000..667e5cf
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-Add-support-for-the-schib-region.patch
@@ -0,0 +1,254 @@
+From b73e3e52f76db823d7bffe3f705f575ca413863b Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:39 -0400
+Subject: [PATCH 05/12] vfio-ccw: Add support for the schib region
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-6-cohuck@redhat.com>
+Patchwork-id: 97697
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 5/9] vfio-ccw: Add support for the schib region
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Farhan Ali <alifm@linux.ibm.com>
+
+The schib region can be used to obtain the latest SCHIB from the host
+passthrough subchannel. Since the guest SCHIB is virtualized,
+we currently only update the path related information so that the
+guest is aware of any path related changes when it issues the
+'stsch' instruction.
+
+Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200505125757.98209-4-farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 46ea3841edaff2a7657b8f6c7f474e5e3850cd62)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/s390x/css.c              | 13 ++++++--
+ hw/s390x/s390-ccw.c         | 21 +++++++++++++
+ hw/vfio/ccw.c               | 63 +++++++++++++++++++++++++++++++++++++
+ include/hw/s390x/css.h      |  3 +-
+ include/hw/s390x/s390-ccw.h |  1 +
+ target/s390x/ioinst.c       |  3 +-
+ 6 files changed, 99 insertions(+), 5 deletions(-)
+
+diff --git a/hw/s390x/css.c b/hw/s390x/css.c
+index 844caab408..71fd3f9a00 100644
+--- a/hw/s390x/css.c
++++ b/hw/s390x/css.c
+@@ -1335,11 +1335,20 @@ static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
+     }
+ }
+ 
+-int css_do_stsch(SubchDev *sch, SCHIB *schib)
++IOInstEnding css_do_stsch(SubchDev *sch, SCHIB *schib)
+ {
++    int ret;
++
++    /*
++     * For some subchannels, we may want to update parts of
++     * the schib (e.g., update path masks from the host device
++     * for passthrough subchannels).
++     */
++    ret = s390_ccw_store(sch);
++
+     /* Use current status. */
+     copy_schib_to_guest(schib, &sch->curr_status);
+-    return 0;
++    return ret;
+ }
+ 
+ static void copy_pmcw_from_guest(PMCW *dest, const PMCW *src)
+diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
+index 0c5a5b60bd..75b788c95e 100644
+--- a/hw/s390x/s390-ccw.c
++++ b/hw/s390x/s390-ccw.c
+@@ -51,6 +51,27 @@ int s390_ccw_clear(SubchDev *sch)
+     return cdc->handle_clear(sch);
+ }
+ 
++IOInstEnding s390_ccw_store(SubchDev *sch)
++{
++    S390CCWDeviceClass *cdc = NULL;
++    int ret = IOINST_CC_EXPECTED;
++
++    /*
++     * This code is called for both virtual and passthrough devices,
++     * but only applies to to the latter.  This ugly check makes that
++     * distinction for us.
++     */
++    if (object_dynamic_cast(OBJECT(sch->driver_data), TYPE_S390_CCW)) {
++        cdc = S390_CCW_DEVICE_GET_CLASS(sch->driver_data);
++    }
++
++    if (cdc && cdc->handle_store) {
++        ret = cdc->handle_store(sch);
++    }
++
++    return ret;
++}
++
+ static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
+                                   char *sysfsdev,
+                                   Error **errp)
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index 17eb4c4048..859ad646f1 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -41,6 +41,9 @@ struct VFIOCCWDevice {
+     uint64_t async_cmd_region_size;
+     uint64_t async_cmd_region_offset;
+     struct ccw_cmd_region *async_cmd_region;
++    uint64_t schib_region_size;
++    uint64_t schib_region_offset;
++    struct ccw_schib_region *schib_region;
+     EventNotifier io_notifier;
+     bool force_orb_pfch;
+     bool warned_orb_pfch;
+@@ -116,6 +119,51 @@ again:
+     }
+ }
+ 
++static IOInstEnding vfio_ccw_handle_store(SubchDev *sch)
++{
++    S390CCWDevice *cdev = sch->driver_data;
++    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
++    SCHIB *schib = &sch->curr_status;
++    struct ccw_schib_region *region = vcdev->schib_region;
++    SCHIB *s;
++    int ret;
++
++    /* schib region not available so nothing else to do */
++    if (!region) {
++        return IOINST_CC_EXPECTED;
++    }
++
++    memset(region, 0, sizeof(*region));
++    ret = pread(vcdev->vdev.fd, region, vcdev->schib_region_size,
++                vcdev->schib_region_offset);
++
++    if (ret == -1) {
++        /*
++         * Device is probably damaged, but store subchannel does not
++         * have a nonzero cc defined for this scenario.  Log an error,
++         * and presume things are otherwise fine.
++         */
++        error_report("vfio-ccw: store region read failed with errno=%d", errno);
++        return IOINST_CC_EXPECTED;
++    }
++
++    /*
++     * Selectively copy path-related bits of the SCHIB,
++     * rather than copying the entire struct.
++     */
++    s = (SCHIB *)region->schib_area;
++    schib->pmcw.pnom = s->pmcw.pnom;
++    schib->pmcw.lpum = s->pmcw.lpum;
++    schib->pmcw.pam = s->pmcw.pam;
++    schib->pmcw.pom = s->pmcw.pom;
++
++    if (s->scsw.flags & SCSW_FLAGS_MASK_PNO) {
++        schib->scsw.flags |= SCSW_FLAGS_MASK_PNO;
++    }
++
++    return IOINST_CC_EXPECTED;
++}
++
+ static int vfio_ccw_handle_clear(SubchDev *sch)
+ {
+     S390CCWDevice *cdev = sch->driver_data;
+@@ -382,10 +430,23 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+         vcdev->async_cmd_region = g_malloc0(info->size);
+     }
+ 
++    ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
++                                   VFIO_REGION_SUBTYPE_CCW_SCHIB, &info);
++    if (!ret) {
++        vcdev->schib_region_size = info->size;
++        if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) {
++            error_setg(errp, "vfio: Unexpected size of the schib region");
++            goto out_err;
++        }
++        vcdev->schib_region_offset = info->offset;
++        vcdev->schib_region = g_malloc(info->size);
++    }
++
+     g_free(info);
+     return;
+ 
+ out_err:
++    g_free(vcdev->schib_region);
+     g_free(vcdev->async_cmd_region);
+     g_free(vcdev->io_region);
+     g_free(info);
+@@ -394,6 +455,7 @@ out_err:
+ 
+ static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
+ {
++    g_free(vcdev->schib_region);
+     g_free(vcdev->async_cmd_region);
+     g_free(vcdev->io_region);
+ }
+@@ -569,6 +631,7 @@ static void vfio_ccw_class_init(ObjectClass *klass, void *data)
+     cdc->handle_request = vfio_ccw_handle_request;
+     cdc->handle_halt = vfio_ccw_handle_halt;
+     cdc->handle_clear = vfio_ccw_handle_clear;
++    cdc->handle_store = vfio_ccw_handle_store;
+ }
+ 
+ static const TypeInfo vfio_ccw_info = {
+diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
+index f46bcafb16..7e3a5e7433 100644
+--- a/include/hw/s390x/css.h
++++ b/include/hw/s390x/css.h
+@@ -218,6 +218,7 @@ IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
+ 
+ int s390_ccw_halt(SubchDev *sch);
+ int s390_ccw_clear(SubchDev *sch);
++IOInstEnding s390_ccw_store(SubchDev *sch);
+ 
+ typedef enum {
+     CSS_IO_ADAPTER_VIRTIO = 0,
+@@ -242,7 +243,7 @@ SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
+                          uint16_t schid);
+ bool css_subch_visible(SubchDev *sch);
+ void css_conditional_io_interrupt(SubchDev *sch);
+-int css_do_stsch(SubchDev *sch, SCHIB *schib);
++IOInstEnding css_do_stsch(SubchDev *sch, SCHIB *schib);
+ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid);
+ IOInstEnding css_do_msch(SubchDev *sch, const SCHIB *schib);
+ IOInstEnding css_do_xsch(SubchDev *sch);
+diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
+index fffb54562f..4a43803ef2 100644
+--- a/include/hw/s390x/s390-ccw.h
++++ b/include/hw/s390x/s390-ccw.h
+@@ -37,6 +37,7 @@ typedef struct S390CCWDeviceClass {
+     IOInstEnding (*handle_request) (SubchDev *sch);
+     int (*handle_halt) (SubchDev *sch);
+     int (*handle_clear) (SubchDev *sch);
++    IOInstEnding (*handle_store) (SubchDev *sch);
+ } S390CCWDeviceClass;
+ 
+ #endif
+diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
+index f40c35c6ff..b6be300cc4 100644
+--- a/target/s390x/ioinst.c
++++ b/target/s390x/ioinst.c
+@@ -292,8 +292,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
+     sch = css_find_subch(m, cssid, ssid, schid);
+     if (sch) {
+         if (css_subch_visible(sch)) {
+-            css_do_stsch(sch, &schib);
+-            cc = 0;
++            cc = css_do_stsch(sch, &schib);
+         } else {
+             /* Indicate no more subchannels in this css/ss */
+             cc = 3;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-ccw-Fix-error-message.patch b/SOURCES/kvm-vfio-ccw-Fix-error-message.patch
new file mode 100644
index 0000000..86d2fdf
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-Fix-error-message.patch
@@ -0,0 +1,48 @@
+From 7258b1fabcd152c2ad9b61485b869a41d1bc64e2 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:35 -0400
+Subject: [PATCH 01/12] vfio-ccw: Fix error message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-2-cohuck@redhat.com>
+Patchwork-id: 97693
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 1/9] vfio-ccw: Fix error message
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: Boris Fiuczynski <fiuczy@linux.ibm.com>
+
+Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Reviewed-by: Eric Farman <farman@linux.ibm.com>
+Message-Id: <20191128143015.5231-1-fiuczy@linux.ibm.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 91f751dc111b270b1e81d80ac92cf479e7620fa4)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/ccw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index 6863f6c69f..3b5520ae75 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -102,7 +102,7 @@ again:
+         if (errno == EAGAIN) {
+             goto again;
+         }
+-        error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno);
++        error_report("vfio-ccw: write I/O region failed with errno=%d", errno);
+         ret = -errno;
+     } else {
+         ret = region->ret_code;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-ccw-Refactor-ccw-irq-handler.patch b/SOURCES/kvm-vfio-ccw-Refactor-ccw-irq-handler.patch
new file mode 100644
index 0000000..8a3514d
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-Refactor-ccw-irq-handler.patch
@@ -0,0 +1,155 @@
+From ee9b03e774641fba8baaf85256706fcc5e8d8efa Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:40 -0400
+Subject: [PATCH 06/12] vfio-ccw: Refactor ccw irq handler
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-7-cohuck@redhat.com>
+Patchwork-id: 97695
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 6/9] vfio-ccw: Refactor ccw irq handler
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Eric Farman <farman@linux.ibm.com>
+
+Make it easier to add new ones in the future.
+
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200505125757.98209-5-farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 690e29b91102ac69810b35fe72cd90bc9fa1fff7)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/ccw.c | 58 +++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 42 insertions(+), 16 deletions(-)
+
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index 859ad646f1..94a0d9840d 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -324,22 +324,36 @@ read_err:
+     css_inject_io_interrupt(sch);
+ }
+ 
+-static void vfio_ccw_register_io_notifier(VFIOCCWDevice *vcdev, Error **errp)
++static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
++                                           unsigned int irq,
++                                           Error **errp)
+ {
+     VFIODevice *vdev = &vcdev->vdev;
+     struct vfio_irq_info *irq_info;
+     size_t argsz;
+     int fd;
++    EventNotifier *notifier;
++    IOHandler *fd_read;
++
++    switch (irq) {
++    case VFIO_CCW_IO_IRQ_INDEX:
++        notifier = &vcdev->io_notifier;
++        fd_read = vfio_ccw_io_notifier_handler;
++        break;
++    default:
++        error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
++        return;
++    }
+ 
+-    if (vdev->num_irqs < VFIO_CCW_IO_IRQ_INDEX + 1) {
+-        error_setg(errp, "vfio: unexpected number of io irqs %u",
++    if (vdev->num_irqs < irq + 1) {
++        error_setg(errp, "vfio: unexpected number of irqs %u",
+                    vdev->num_irqs);
+         return;
+     }
+ 
+     argsz = sizeof(*irq_info);
+     irq_info = g_malloc0(argsz);
+-    irq_info->index = VFIO_CCW_IO_IRQ_INDEX;
++    irq_info->index = irq;
+     irq_info->argsz = argsz;
+     if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
+               irq_info) < 0 || irq_info->count < 1) {
+@@ -347,37 +361,49 @@ static void vfio_ccw_register_io_notifier(VFIOCCWDevice *vcdev, Error **errp)
+         goto out_free_info;
+     }
+ 
+-    if (event_notifier_init(&vcdev->io_notifier, 0)) {
++    if (event_notifier_init(notifier, 0)) {
+         error_setg_errno(errp, errno,
+-                         "vfio: Unable to init event notifier for IO");
++                         "vfio: Unable to init event notifier for irq (%d)",
++                         irq);
+         goto out_free_info;
+     }
+ 
+-    fd = event_notifier_get_fd(&vcdev->io_notifier);
+-    qemu_set_fd_handler(fd, vfio_ccw_io_notifier_handler, NULL, vcdev);
++    fd = event_notifier_get_fd(notifier);
++    qemu_set_fd_handler(fd, fd_read, NULL, vcdev);
+ 
+-    if (vfio_set_irq_signaling(vdev, VFIO_CCW_IO_IRQ_INDEX, 0,
++    if (vfio_set_irq_signaling(vdev, irq, 0,
+                                VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
+         qemu_set_fd_handler(fd, NULL, NULL, vcdev);
+-        event_notifier_cleanup(&vcdev->io_notifier);
++        event_notifier_cleanup(notifier);
+     }
+ 
+ out_free_info:
+     g_free(irq_info);
+ }
+ 
+-static void vfio_ccw_unregister_io_notifier(VFIOCCWDevice *vcdev)
++static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
++                                             unsigned int irq)
+ {
+     Error *err = NULL;
++    EventNotifier *notifier;
++
++    switch (irq) {
++    case VFIO_CCW_IO_IRQ_INDEX:
++        notifier = &vcdev->io_notifier;
++        break;
++    default:
++        error_report("vfio: Unsupported device irq(%d)", irq);
++        return;
++    }
+ 
+-    if (vfio_set_irq_signaling(&vcdev->vdev, VFIO_CCW_IO_IRQ_INDEX, 0,
++    if (vfio_set_irq_signaling(&vcdev->vdev, irq, 0,
+                                VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) {
+         error_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
+     }
+ 
+-    qemu_set_fd_handler(event_notifier_get_fd(&vcdev->io_notifier),
++    qemu_set_fd_handler(event_notifier_get_fd(notifier),
+                         NULL, NULL, vcdev);
+-    event_notifier_cleanup(&vcdev->io_notifier);
++    event_notifier_cleanup(notifier);
+ }
+ 
+ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+@@ -565,7 +591,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
+         goto out_region_err;
+     }
+ 
+-    vfio_ccw_register_io_notifier(vcdev, &err);
++    vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err);
+     if (err) {
+         goto out_notifier_err;
+     }
+@@ -594,7 +620,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
+     S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
+     VFIOGroup *group = vcdev->vdev.group;
+ 
+-    vfio_ccw_unregister_io_notifier(vcdev);
++    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
+     vfio_ccw_put_region(vcdev);
+     vfio_ccw_put_device(vcdev);
+     vfio_put_group(group);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-ccw-Refactor-cleanup-of-regions.patch b/SOURCES/kvm-vfio-ccw-Refactor-cleanup-of-regions.patch
new file mode 100644
index 0000000..1741f4b
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-Refactor-cleanup-of-regions.patch
@@ -0,0 +1,73 @@
+From 30906c9c78af2710a2b86c096cc7b18bbc4b4e69 Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:38 -0400
+Subject: [PATCH 04/12] vfio-ccw: Refactor cleanup of regions
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-5-cohuck@redhat.com>
+Patchwork-id: 97694
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 4/9] vfio-ccw: Refactor cleanup of regions
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Eric Farman <farman@linux.ibm.com>
+
+While we're at it, add a g_free() for the async_cmd_region that
+is the last thing currently created.  g_free() knows how to handle
+NULL pointers, so this makes it easier to remember what cleanups
+need to be performed when new regions are added.
+
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20200505125757.98209-3-farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 2a3b9cbaa7b25a4db4cdcfe1c65279c5464f2923)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/ccw.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index 6bc612b5b7..17eb4c4048 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -363,8 +363,7 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+     vcdev->io_region_size = info->size;
+     if (sizeof(*vcdev->io_region) != vcdev->io_region_size) {
+         error_setg(errp, "vfio: Unexpected size of the I/O region");
+-        g_free(info);
+-        return;
++        goto out_err;
+     }
+ 
+     vcdev->io_region_offset = info->offset;
+@@ -377,15 +376,20 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+         vcdev->async_cmd_region_size = info->size;
+         if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) {
+             error_setg(errp, "vfio: Unexpected size of the async cmd region");
+-            g_free(vcdev->io_region);
+-            g_free(info);
+-            return;
++            goto out_err;
+         }
+         vcdev->async_cmd_region_offset = info->offset;
+         vcdev->async_cmd_region = g_malloc0(info->size);
+     }
+ 
+     g_free(info);
++    return;
++
++out_err:
++    g_free(vcdev->async_cmd_region);
++    g_free(vcdev->io_region);
++    g_free(info);
++    return;
+ }
+ 
+ static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-ccw-allow-non-prefetch-ORBs.patch b/SOURCES/kvm-vfio-ccw-allow-non-prefetch-ORBs.patch
new file mode 100644
index 0000000..da2fc5c
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-allow-non-prefetch-ORBs.patch
@@ -0,0 +1,61 @@
+From d5f5a307f3396064d29ef0d300c7377756dd165b Mon Sep 17 00:00:00 2001
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Tue, 23 Jun 2020 09:25:36 -0400
+Subject: [PATCH 02/12] vfio-ccw: allow non-prefetch ORBs
+
+RH-Author: Cornelia Huck <cohuck@redhat.com>
+Message-id: <20200623092543.358315-3-cohuck@redhat.com>
+Patchwork-id: 97692
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 2/9] vfio-ccw: allow non-prefetch ORBs
+Bugzilla: 1660916
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Jared Rossi <jrossi@linux.ibm.com>
+
+Remove the explicit prefetch check when using vfio-ccw devices.
+This check does not trigger in practice as all Linux channel programs
+are intended to use prefetch.
+
+Newer Linux kernel versions do not require to force the PFCH flag with
+vfio-ccw devices anymore.
+
+Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
+Reviewed-by: Eric Farman <farman@linux.ibm.com>
+Message-Id: <20200512181535.18630-2-jrossi@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit 24e58a7b1d411627e326144030a20dcf0093fed0)
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/ccw.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index 3b5520ae75..6bc612b5b7 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -74,16 +74,9 @@ static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
+     struct ccw_io_region *region = vcdev->io_region;
+     int ret;
+ 
+-    if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH)) {
+-        if (!(vcdev->force_orb_pfch)) {
+-            warn_once_pfch(vcdev, sch, "requires PFCH flag set");
+-            sch_gen_unit_exception(sch);
+-            css_inject_io_interrupt(sch);
+-            return IOINST_CC_EXPECTED;
+-        } else {
+-            sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH;
+-            warn_once_pfch(vcdev, sch, "PFCH flag forced");
+-        }
++    if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH) && vcdev->force_orb_pfch) {
++        sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH;
++        warn_once_pfch(vcdev, sch, "PFCH flag forced");
+     }
+ 
+     QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-nvlink-Remove-exec-permission-to-avoid-SELinux-.patch b/SOURCES/kvm-vfio-nvlink-Remove-exec-permission-to-avoid-SELinux-.patch
new file mode 100644
index 0000000..81cf80e
--- /dev/null
+++ b/SOURCES/kvm-vfio-nvlink-Remove-exec-permission-to-avoid-SELinux-.patch
@@ -0,0 +1,75 @@
+From f01098bb86c12f485895f38f7a24170ec84b60b6 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <gkurz@redhat.com>
+Date: Mon, 8 Jun 2020 16:25:21 -0400
+Subject: [PATCH 42/42] vfio/nvlink: Remove exec permission to avoid SELinux
+ AVCs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Greg Kurz <gkurz@redhat.com>
+Message-id: <20200608162521.382858-2-gkurz@redhat.com>
+Patchwork-id: 97459
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH 1/1] vfio/nvlink: Remove exec permission to avoid SELinux AVCs
+Bugzilla: 1823275
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: Leonardo Bras <leobras.c@gmail.com>
+
+If SELinux is setup without 'execmem' permission for qemu, all mmap
+with (PROT_WRITE | PROT_EXEC) will fail and print a warning in
+SELinux log.
+
+If "nvlink2-mr" memory allocation fails (fist diff), it will cause
+guest NUMA nodes to not be correctly configured (V100 memory will
+not be visible for guest, nor its NUMA nodes).
+
+Not having 'execmem' permission is intesting for virtual machines to
+avoid buffer-overflow based attacks, and it's adopted in distros
+like RHEL.
+
+So, removing the PROT_EXEC flag seems the right thing to do.
+
+Browsing some other code that mmaps memory for usage with
+memory_region_init_ram_device_ptr, I could notice it's usual to
+not have PROT_EXEC (only PROT_READ | PROT_WRITE), so it should be
+no problem around this.
+
+Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
+Message-Id: <20200501055448.286518-1-leobras.c@gmail.com>
+Acked-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 9c7c0407028355ca83349b8a60fddfad46f2ebd8)
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/pci-quirks.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
+index 4505ffe48a..1c5fe014cf 100644
+--- a/hw/vfio/pci-quirks.c
++++ b/hw/vfio/pci-quirks.c
+@@ -2237,7 +2237,7 @@ int vfio_pci_nvidia_v100_ram_init(VFIOPCIDevice *vdev, Error **errp)
+     }
+     cap = (void *) hdr;
+ 
+-    p = mmap(NULL, nv2reg->size, PROT_READ | PROT_WRITE | PROT_EXEC,
++    p = mmap(NULL, nv2reg->size, PROT_READ | PROT_WRITE,
+              MAP_SHARED, vdev->vbasedev.fd, nv2reg->offset);
+     if (p == MAP_FAILED) {
+         ret = -errno;
+@@ -2297,7 +2297,7 @@ int vfio_pci_nvlink2_init(VFIOPCIDevice *vdev, Error **errp)
+ 
+     /* Some NVLink bridges may not have assigned ATSD */
+     if (atsdreg->size) {
+-        p = mmap(NULL, atsdreg->size, PROT_READ | PROT_WRITE | PROT_EXEC,
++        p = mmap(NULL, atsdreg->size, PROT_READ | PROT_WRITE,
+                  MAP_SHARED, vdev->vbasedev.fd, atsdreg->offset);
+         if (p == MAP_FAILED) {
+             ret = -errno;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vhost-correctly-turn-on-VIRTIO_F_IOMMU_PLATFORM.patch b/SOURCES/kvm-vhost-correctly-turn-on-VIRTIO_F_IOMMU_PLATFORM.patch
new file mode 100644
index 0000000..7e1353c
--- /dev/null
+++ b/SOURCES/kvm-vhost-correctly-turn-on-VIRTIO_F_IOMMU_PLATFORM.patch
@@ -0,0 +1,69 @@
+From e06655cfe0fa9473b1e8b311571f36d787472834 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 29 May 2020 05:54:02 -0400
+Subject: [PATCH 20/42] vhost: correctly turn on VIRTIO_F_IOMMU_PLATFORM
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20200529055420.16855-21-thuth@redhat.com>
+Patchwork-id: 97041
+O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 20/38] vhost: correctly turn on VIRTIO_F_IOMMU_PLATFORM
+Bugzilla: 1828317
+RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+We turn on device IOTLB via VIRTIO_F_IOMMU_PLATFORM unconditionally on
+platform without IOMMU support. This can lead unnecessary IOTLB
+transactions which will damage the performance.
+
+Fixing this by check whether the device is backed by IOMMU and disable
+device IOTLB.
+
+Reported-by: Halil Pasic <pasic@linux.ibm.com>
+Tested-by: Halil Pasic <pasic@linux.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Message-Id: <20200302042454.24814-1-jasowang@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+(cherry picked from commit f7ef7e6e3ba6e994e070cc609eb154339d1c4a11)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/virtio/vhost.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
+index 9edfadc81d..9182a00495 100644
+--- a/hw/virtio/vhost.c
++++ b/hw/virtio/vhost.c
+@@ -290,7 +290,14 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
+ {
+     VirtIODevice *vdev = dev->vdev;
+ 
+-    return virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
++    /*
++     * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
++     * incremental memory mapping API via IOTLB API. For platform that
++     * does not have IOMMU, there's no need to enable this feature
++     * which may cause unnecessary IOTLB miss/update trnasactions.
++     */
++    return vdev->dma_as != &address_space_memory &&
++           virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+ }
+ 
+ static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
+@@ -765,6 +772,9 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
+     if (enable_log) {
+         features |= 0x1ULL << VHOST_F_LOG_ALL;
+     }
++    if (!vhost_dev_has_iommu(dev)) {
++        features &= ~(0x1ULL << VIRTIO_F_IOMMU_PLATFORM);
++    }
+     r = dev->vhost_ops->vhost_set_features(dev, features);
+     if (r < 0) {
+         VHOST_OPS_DEBUG("vhost_set_features failed");
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtio-blk-On-restart-process-queued-requests-in-the.patch b/SOURCES/kvm-virtio-blk-On-restart-process-queued-requests-in-the.patch
new file mode 100644
index 0000000..9e46be1
--- /dev/null
+++ b/SOURCES/kvm-virtio-blk-On-restart-process-queued-requests-in-the.patch
@@ -0,0 +1,203 @@
+From fdd1f3bf672ad8bb0a6db896ec8cbc797c31da1f Mon Sep 17 00:00:00 2001
+From: Sergio Lopez Pascual <slp@redhat.com>
+Date: Wed, 24 Jun 2020 13:24:53 -0400
+Subject: [PATCH 11/12] virtio-blk: On restart, process queued requests in the
+ proper context
+
+RH-Author: Sergio Lopez Pascual <slp@redhat.com>
+Message-id: <20200624132453.111276-3-slp@redhat.com>
+Patchwork-id: 97798
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/2] virtio-blk: On restart, process queued requests in the proper context
+Bugzilla:
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+On restart, we were scheduling a BH to process queued requests, which
+would run before starting up the data plane, leading to those requests
+being assigned and started on coroutines on the main context.
+
+This could cause requests to be wrongly processed in parallel from
+different threads (the main thread and the iothread managing the data
+plane), potentially leading to multiple issues.
+
+For example, stopping and resuming a VM multiple times while the guest
+is generating I/O on a virtio_blk device can trigger a crash with a
+stack tracing looking like this one:
+
+<------>
+ Thread 2 (Thread 0x7ff736765700 (LWP 1062503)):
+ #0  0x00005567a13b99d6 in iov_memset
+     (iov=0x6563617073206f4e, iov_cnt=1717922848, offset=516096, fillc=0, bytes=7018105756081554803)
+     at util/iov.c:69
+ #1  0x00005567a13bab73 in qemu_iovec_memset
+     (qiov=0x7ff73ec99748, offset=516096, fillc=0, bytes=7018105756081554803) at util/iov.c:530
+ #2  0x00005567a12f411c in qemu_laio_process_completion (laiocb=0x7ff6512ee6c0) at block/linux-aio.c:86
+ #3  0x00005567a12f42ff in qemu_laio_process_completions (s=0x7ff7182e8420) at block/linux-aio.c:217
+ #4  0x00005567a12f480d in ioq_submit (s=0x7ff7182e8420) at block/linux-aio.c:323
+ #5  0x00005567a12f43d9 in qemu_laio_process_completions_and_submit (s=0x7ff7182e8420)
+     at block/linux-aio.c:236
+ #6  0x00005567a12f44c2 in qemu_laio_poll_cb (opaque=0x7ff7182e8430) at block/linux-aio.c:267
+ #7  0x00005567a13aed83 in run_poll_handlers_once (ctx=0x5567a2b58c70, timeout=0x7ff7367645f8)
+     at util/aio-posix.c:520
+ #8  0x00005567a13aee9f in run_poll_handlers (ctx=0x5567a2b58c70, max_ns=16000, timeout=0x7ff7367645f8)
+     at util/aio-posix.c:562
+ #9  0x00005567a13aefde in try_poll_mode (ctx=0x5567a2b58c70, timeout=0x7ff7367645f8)
+     at util/aio-posix.c:597
+ #10 0x00005567a13af115 in aio_poll (ctx=0x5567a2b58c70, blocking=true) at util/aio-posix.c:639
+ #11 0x00005567a109acca in iothread_run (opaque=0x5567a2b29760) at iothread.c:75
+ #12 0x00005567a13b2790 in qemu_thread_start (args=0x5567a2b694c0) at util/qemu-thread-posix.c:519
+ #13 0x00007ff73eedf2de in start_thread () at /lib64/libpthread.so.0
+ #14 0x00007ff73ec10e83 in clone () at /lib64/libc.so.6
+
+ Thread 1 (Thread 0x7ff743986f00 (LWP 1062500)):
+ #0  0x00005567a13b99d6 in iov_memset
+     (iov=0x6563617073206f4e, iov_cnt=1717922848, offset=516096, fillc=0, bytes=7018105756081554803)
+     at util/iov.c:69
+ #1  0x00005567a13bab73 in qemu_iovec_memset
+     (qiov=0x7ff73ec99748, offset=516096, fillc=0, bytes=7018105756081554803) at util/iov.c:530
+ #2  0x00005567a12f411c in qemu_laio_process_completion (laiocb=0x7ff6512ee6c0) at block/linux-aio.c:86
+ #3  0x00005567a12f42ff in qemu_laio_process_completions (s=0x7ff7182e8420) at block/linux-aio.c:217
+ #4  0x00005567a12f480d in ioq_submit (s=0x7ff7182e8420) at block/linux-aio.c:323
+ #5  0x00005567a12f4a2f in laio_do_submit (fd=19, laiocb=0x7ff5f4ff9ae0, offset=472363008, type=2)
+     at block/linux-aio.c:375
+ #6  0x00005567a12f4af2 in laio_co_submit
+     (bs=0x5567a2b8c460, s=0x7ff7182e8420, fd=19, offset=472363008, qiov=0x7ff5f4ff9ca0, type=2)
+     at block/linux-aio.c:394
+ #7  0x00005567a12f1803 in raw_co_prw
+     (bs=0x5567a2b8c460, offset=472363008, bytes=20480, qiov=0x7ff5f4ff9ca0, type=2)
+     at block/file-posix.c:1892
+ #8  0x00005567a12f1941 in raw_co_pwritev
+     (bs=0x5567a2b8c460, offset=472363008, bytes=20480, qiov=0x7ff5f4ff9ca0, flags=0)
+     at block/file-posix.c:1925
+ #9  0x00005567a12fe3e1 in bdrv_driver_pwritev
+     (bs=0x5567a2b8c460, offset=472363008, bytes=20480, qiov=0x7ff5f4ff9ca0, qiov_offset=0, flags=0)
+     at block/io.c:1183
+ #10 0x00005567a1300340 in bdrv_aligned_pwritev
+     (child=0x5567a2b5b070, req=0x7ff5f4ff9db0, offset=472363008, bytes=20480, align=512, qiov=0x7ff72c0425b8, qiov_offset=0, flags=0) at block/io.c:1980
+ #11 0x00005567a1300b29 in bdrv_co_pwritev_part
+     (child=0x5567a2b5b070, offset=472363008, bytes=20480, qiov=0x7ff72c0425b8, qiov_offset=0, flags=0)
+     at block/io.c:2137
+ #12 0x00005567a12baba1 in qcow2_co_pwritev_task
+     (bs=0x5567a2b92740, file_cluster_offset=472317952, offset=487305216, bytes=20480, qiov=0x7ff72c0425b8, qiov_offset=0, l2meta=0x0) at block/qcow2.c:2444
+ #13 0x00005567a12bacdb in qcow2_co_pwritev_task_entry (task=0x5567a2b48540) at block/qcow2.c:2475
+ #14 0x00005567a13167d8 in aio_task_co (opaque=0x5567a2b48540) at block/aio_task.c:45
+ #15 0x00005567a13cf00c in coroutine_trampoline (i0=738245600, i1=32759) at util/coroutine-ucontext.c:115
+ #16 0x00007ff73eb622e0 in __start_context () at /lib64/libc.so.6
+ #17 0x00007ff6626f1350 in  ()
+ #18 0x0000000000000000 in  ()
+<------>
+
+This is also known to cause crashes with this message (assertion
+failed):
+
+ aio_co_schedule: Co-routine was already scheduled in 'aio_co_schedule'
+
+RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1812765
+Signed-off-by: Sergio Lopez <slp@redhat.com>
+Message-Id: <20200603093240.40489-3-slp@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 49b44549ace7890fffdf027fd3695218ee7f1121)
+Signed-off-by: Sergio Lopez <slp@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/block/dataplane/virtio-blk.c |  8 ++++++++
+ hw/block/virtio-blk.c           | 18 ++++++++++++------
+ include/hw/virtio/virtio-blk.h  |  2 +-
+ 3 files changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
+index 119906a5fe..ac495fd72a 100644
+--- a/hw/block/dataplane/virtio-blk.c
++++ b/hw/block/dataplane/virtio-blk.c
+@@ -220,6 +220,9 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
+         goto fail_guest_notifiers;
+     }
+ 
++    /* Process queued requests before the ones in vring */
++    virtio_blk_process_queued_requests(vblk, false);
++
+     /* Kick right away to begin processing requests already in vring */
+     for (i = 0; i < nvqs; i++) {
+         VirtQueue *vq = virtio_get_queue(s->vdev, i);
+@@ -239,6 +242,11 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
+     return 0;
+ 
+   fail_guest_notifiers:
++    /*
++     * If we failed to set up the guest notifiers queued requests will be
++     * processed on the main context.
++     */
++    virtio_blk_process_queued_requests(vblk, false);
+     vblk->dataplane_disabled = true;
+     s->starting = false;
+     vblk->dataplane_started = true;
+diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
+index 6ff29a05d6..493a263fa6 100644
+--- a/hw/block/virtio-blk.c
++++ b/hw/block/virtio-blk.c
+@@ -819,7 +819,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+     virtio_blk_handle_output_do(s, vq);
+ }
+ 
+-void virtio_blk_process_queued_requests(VirtIOBlock *s)
++void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh)
+ {
+     VirtIOBlockReq *req = s->rq;
+     MultiReqBuffer mrb = {};
+@@ -847,7 +847,9 @@ void virtio_blk_process_queued_requests(VirtIOBlock *s)
+     if (mrb.num_reqs) {
+         virtio_blk_submit_multireq(s->blk, &mrb);
+     }
+-    blk_dec_in_flight(s->conf.conf.blk);
++    if (is_bh) {
++        blk_dec_in_flight(s->conf.conf.blk);
++    }
+     aio_context_release(blk_get_aio_context(s->conf.conf.blk));
+ }
+ 
+@@ -858,21 +860,25 @@ static void virtio_blk_dma_restart_bh(void *opaque)
+     qemu_bh_delete(s->bh);
+     s->bh = NULL;
+ 
+-    virtio_blk_process_queued_requests(s);
++    virtio_blk_process_queued_requests(s, true);
+ }
+ 
+ static void virtio_blk_dma_restart_cb(void *opaque, int running,
+                                       RunState state)
+ {
+     VirtIOBlock *s = opaque;
++    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
++    VirtioBusState *bus = VIRTIO_BUS(qbus);
+ 
+     if (!running) {
+         return;
+     }
+ 
+-    if (!s->bh) {
+-        /* FIXME The data plane is not started yet, so these requests are
+-         * processed in the main thread. */
++    /*
++     * If ioeventfd is enabled, don't schedule the BH here as queued
++     * requests will be processed while starting the data plane.
++     */
++    if (!s->bh && !virtio_bus_ioeventfd_enabled(bus)) {
+         s->bh = aio_bh_new(blk_get_aio_context(s->conf.conf.blk),
+                            virtio_blk_dma_restart_bh, s);
+         blk_inc_in_flight(s->conf.conf.blk);
+diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
+index cf8eea2f58..e77f0db3b0 100644
+--- a/include/hw/virtio/virtio-blk.h
++++ b/include/hw/virtio/virtio-blk.h
+@@ -84,6 +84,6 @@ typedef struct MultiReqBuffer {
+ } MultiReqBuffer;
+ 
+ bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
+-void virtio_blk_process_queued_requests(VirtIOBlock *s);
++void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh);
+ 
+ #endif
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtio-blk-Refactor-the-code-that-processes-queued-r.patch b/SOURCES/kvm-virtio-blk-Refactor-the-code-that-processes-queued-r.patch
new file mode 100644
index 0000000..148045d
--- /dev/null
+++ b/SOURCES/kvm-virtio-blk-Refactor-the-code-that-processes-queued-r.patch
@@ -0,0 +1,83 @@
+From 73d83d8880e85eedc22c9651b67d1eacd5de5ff4 Mon Sep 17 00:00:00 2001
+From: Sergio Lopez Pascual <slp@redhat.com>
+Date: Wed, 24 Jun 2020 13:24:52 -0400
+Subject: [PATCH 10/12] virtio-blk: Refactor the code that processes queued
+ requests
+
+RH-Author: Sergio Lopez Pascual <slp@redhat.com>
+Message-id: <20200624132453.111276-2-slp@redhat.com>
+Patchwork-id: 97797
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 1/2] virtio-blk: Refactor the code that processes queued requests
+Bugzilla:
+RH-Acked-by: John Snow <jsnow@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+
+Move the code that processes queued requests from
+virtio_blk_dma_restart_bh() to its own, non-static, function. This
+will allow us to call it from the virtio_blk_data_plane_start() in a
+future patch.
+
+Signed-off-by: Sergio Lopez <slp@redhat.com>
+Message-Id: <20200603093240.40489-2-slp@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 7aa1c247b466870b0704d3ccdc3755e5e7394dca)
+Signed-off-by: Sergio Lopez <slp@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/block/virtio-blk.c          | 16 +++++++++++-----
+ include/hw/virtio/virtio-blk.h |  1 +
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
+index c4e55fb3de..6ff29a05d6 100644
+--- a/hw/block/virtio-blk.c
++++ b/hw/block/virtio-blk.c
+@@ -819,15 +819,11 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+     virtio_blk_handle_output_do(s, vq);
+ }
+ 
+-static void virtio_blk_dma_restart_bh(void *opaque)
++void virtio_blk_process_queued_requests(VirtIOBlock *s)
+ {
+-    VirtIOBlock *s = opaque;
+     VirtIOBlockReq *req = s->rq;
+     MultiReqBuffer mrb = {};
+ 
+-    qemu_bh_delete(s->bh);
+-    s->bh = NULL;
+-
+     s->rq = NULL;
+ 
+     aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
+@@ -855,6 +851,16 @@ static void virtio_blk_dma_restart_bh(void *opaque)
+     aio_context_release(blk_get_aio_context(s->conf.conf.blk));
+ }
+ 
++static void virtio_blk_dma_restart_bh(void *opaque)
++{
++    VirtIOBlock *s = opaque;
++
++    qemu_bh_delete(s->bh);
++    s->bh = NULL;
++
++    virtio_blk_process_queued_requests(s);
++}
++
+ static void virtio_blk_dma_restart_cb(void *opaque, int running,
+                                       RunState state)
+ {
+diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
+index cddcfbebe9..cf8eea2f58 100644
+--- a/include/hw/virtio/virtio-blk.h
++++ b/include/hw/virtio/virtio-blk.h
+@@ -84,5 +84,6 @@ typedef struct MultiReqBuffer {
+ } MultiReqBuffer;
+ 
+ bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
++void virtio_blk_process_queued_requests(VirtIOBlock *s);
+ 
+ #endif
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtiofsd-Show-submounts.patch b/SOURCES/kvm-virtiofsd-Show-submounts.patch
new file mode 100644
index 0000000..d45a030
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-Show-submounts.patch
@@ -0,0 +1,51 @@
+From 717373379510cd6ecf8c6d0e1aae65edfac4551d Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:35:58 +0100
+Subject: [PATCH 7/9] virtiofsd: Show submounts
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20200505163600.22956-6-dgilbert@redhat.com>
+Patchwork-id: 96273
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 5/7] virtiofsd: Show submounts
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Max Reitz <mreitz@redhat.com>
+
+Currently, setup_mounts() bind-mounts the shared directory without
+MS_REC.  This makes all submounts disappear.
+
+Pass MS_REC so that the guest can see submounts again.
+
+Fixes: 5baa3b8e95064c2434bd9e2f312edd5e9ae275dc
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200424133516.73077-1-mreitz@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+  Changed Fixes to point to the commit with the problem rather than
+          the commit that turned it on
+(cherry picked from commit ace0829c0d08f0e5f1451e402e94495bc2166772)
+
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 73d8405..614ba55 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -2670,7 +2670,7 @@ static void setup_mounts(const char *source)
+     int oldroot;
+     int newroot;
+ 
+-    if (mount(source, source, NULL, MS_BIND, NULL) < 0) {
++    if (mount(source, source, NULL, MS_BIND | MS_REC, NULL) < 0) {
+         fuse_log(FUSE_LOG_ERR, "mount(%s, %s, MS_BIND): %m\n", source, source);
+         exit(1);
+     }
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtiofsd-add-rlimit-nofile-NUM-option.patch b/SOURCES/kvm-virtiofsd-add-rlimit-nofile-NUM-option.patch
new file mode 100644
index 0000000..a6a9cc9
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-add-rlimit-nofile-NUM-option.patch
@@ -0,0 +1,164 @@
+From 555ec3463b3dbfd6e08eac7840419d176f113e46 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:35:55 +0100
+Subject: [PATCH 4/9] virtiofsd: add --rlimit-nofile=NUM option
+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: <20200505163600.22956-3-dgilbert@redhat.com>
+Patchwork-id: 96270
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 2/7] virtiofsd: add --rlimit-nofile=NUM option
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+Make it possible to specify the RLIMIT_NOFILE on the command-line.
+Users running multiple virtiofsd processes should allocate a certain
+number to each process so that the system-wide limit can never be
+exhausted.
+
+When this option is set to 0 the rlimit is left at its current value.
+This is useful when a management tool wants to configure the rlimit
+itself.
+
+The default behavior remains unchanged: try to set the limit to
+1,000,000 file descriptors if the current rlimit is lower.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-Id: <20200501140644.220940-2-stefanha@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 6dbb716877728ce4eb51619885ef6ef4ada9565f)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/fuse_lowlevel.h  |  1 +
+ tools/virtiofsd/helper.c         | 23 +++++++++++++++++++++++
+ tools/virtiofsd/passthrough_ll.c | 22 ++++++++--------------
+ 3 files changed, 32 insertions(+), 14 deletions(-)
+
+diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h
+index 8f6d705..562fd52 100644
+--- a/tools/virtiofsd/fuse_lowlevel.h
++++ b/tools/virtiofsd/fuse_lowlevel.h
+@@ -1777,6 +1777,7 @@ struct fuse_cmdline_opts {
+     int syslog;
+     int log_level;
+     unsigned int max_idle_threads;
++    unsigned long rlimit_nofile;
+ };
+ 
+ /**
+diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
+index 0801cf7..9b3eddc 100644
+--- a/tools/virtiofsd/helper.c
++++ b/tools/virtiofsd/helper.c
+@@ -23,6 +23,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/param.h>
++#include <sys/time.h>
++#include <sys/resource.h>
+ #include <unistd.h>
+ 
+ #define FUSE_HELPER_OPT(t, p)                       \
+@@ -53,6 +55,7 @@ static const struct fuse_opt fuse_helper_opts[] = {
+     FUSE_HELPER_OPT("subtype=", nodefault_subtype),
+     FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
+     FUSE_HELPER_OPT("max_idle_threads=%u", max_idle_threads),
++    FUSE_HELPER_OPT("--rlimit-nofile=%lu", rlimit_nofile),
+     FUSE_HELPER_OPT("--syslog", syslog),
+     FUSE_HELPER_OPT_VALUE("log_level=debug", log_level, FUSE_LOG_DEBUG),
+     FUSE_HELPER_OPT_VALUE("log_level=info", log_level, FUSE_LOG_INFO),
+@@ -171,6 +174,9 @@ void fuse_cmdline_help(void)
+            "                               default: no_writeback\n"
+            "    -o xattr|no_xattr          enable/disable xattr\n"
+            "                               default: no_xattr\n"
++           "    --rlimit-nofile=<num>      set maximum number of file descriptors\n"
++           "                               (0 leaves rlimit unchanged)\n"
++           "                               default: 1,000,000 if the current rlimit is lower\n"
+            );
+ }
+ 
+@@ -191,11 +197,28 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key,
+     }
+ }
+ 
++static unsigned long get_default_rlimit_nofile(void)
++{
++    rlim_t max_fds = 1000000; /* our default RLIMIT_NOFILE target */
++    struct rlimit rlim;
++
++    if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
++        fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
++        exit(1);
++    }
++
++    if (rlim.rlim_cur >= max_fds) {
++        return 0; /* we have more fds available than required! */
++    }
++    return max_fds;
++}
++
+ int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
+ {
+     memset(opts, 0, sizeof(struct fuse_cmdline_opts));
+ 
+     opts->max_idle_threads = 10;
++    opts->rlimit_nofile = get_default_rlimit_nofile();
+     opts->foreground = 1;
+ 
+     if (fuse_opt_parse(args, opts, fuse_helper_opts, fuse_helper_opt_proc) ==
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 50ff672..184ad0f 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -2711,24 +2711,18 @@ static void setup_sandbox(struct lo_data *lo, struct fuse_session *se,
+     setup_seccomp(enable_syslog);
+ }
+ 
+-/* Raise the maximum number of open file descriptors */
+-static void setup_nofile_rlimit(void)
++/* Set the maximum number of open file descriptors */
++static void setup_nofile_rlimit(unsigned long rlimit_nofile)
+ {
+-    const rlim_t max_fds = 1000000;
+-    struct rlimit rlim;
+-
+-    if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+-        fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
+-        exit(1);
+-    }
++    struct rlimit rlim = {
++        .rlim_cur = rlimit_nofile,
++        .rlim_max = rlimit_nofile,
++    };
+ 
+-    if (rlim.rlim_cur >= max_fds) {
++    if (rlimit_nofile == 0) {
+         return; /* nothing to do */
+     }
+ 
+-    rlim.rlim_cur = max_fds;
+-    rlim.rlim_max = max_fds;
+-
+     if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+         /* Ignore SELinux denials */
+         if (errno == EPERM) {
+@@ -2981,7 +2975,7 @@ int main(int argc, char *argv[])
+ 
+     fuse_daemonize(opts.foreground);
+ 
+-    setup_nofile_rlimit();
++    setup_nofile_rlimit(opts.rlimit_nofile);
+ 
+     /* Must be before sandbox since it wants /proc */
+     setup_capng();
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtiofsd-drop-all-capabilities-in-the-wait-parent-p.patch b/SOURCES/kvm-virtiofsd-drop-all-capabilities-in-the-wait-parent-p.patch
new file mode 100644
index 0000000..569096d
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-drop-all-capabilities-in-the-wait-parent-p.patch
@@ -0,0 +1,67 @@
+From 78152453940967f9ece9fe3ffc5017c669d6ec28 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:36:00 +0100
+Subject: [PATCH 9/9] virtiofsd: drop all capabilities in the wait parent
+ process
+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: <20200505163600.22956-8-dgilbert@redhat.com>
+Patchwork-id: 96274
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 7/7] virtiofsd: drop all capabilities in the wait parent process
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+All this process does is wait for its child.  No capabilities are
+needed.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 66502bbca37ca7a3bfa57e82cfc03b89a7a11eae)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 6358874..f41a6b0 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -2535,6 +2535,17 @@ static void print_capabilities(void)
+ }
+ 
+ /*
++ * Drop all Linux capabilities because the wait parent process only needs to
++ * sit in waitpid(2) and terminate.
++ */
++static void setup_wait_parent_capabilities(void)
++{
++    capng_setpid(syscall(SYS_gettid));
++    capng_clear(CAPNG_SELECT_BOTH);
++    capng_apply(CAPNG_SELECT_BOTH);
++}
++
++/*
+  * Move to a new mount, net, and pid namespaces to isolate this process.
+  */
+ static void setup_namespaces(struct lo_data *lo, struct fuse_session *se)
+@@ -2567,6 +2578,8 @@ static void setup_namespaces(struct lo_data *lo, struct fuse_session *se)
+         pid_t waited;
+         int wstatus;
+ 
++        setup_wait_parent_capabilities();
++
+         /* The parent waits for the child */
+         do {
+             waited = waitpid(child, &wstatus, 0);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtiofsd-jail-lo-proc_self_fd.patch b/SOURCES/kvm-virtiofsd-jail-lo-proc_self_fd.patch
new file mode 100644
index 0000000..df69242
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-jail-lo-proc_self_fd.patch
@@ -0,0 +1,85 @@
+From 852a0a22d674b0594aecf0912a0885d197f34978 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:35:57 +0100
+Subject: [PATCH 6/9] virtiofsd: jail lo->proc_self_fd
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20200505163600.22956-5-dgilbert@redhat.com>
+Patchwork-id: 96275
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 4/7] virtiofsd: jail lo->proc_self_fd
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+While it's not possible to escape the proc filesystem through
+lo->proc_self_fd, it is possible to escape to the root of the proc
+filesystem itself through "../..".
+
+Use a temporary mount for opening lo->proc_self_fd, that has it's root at
+/proc/self/fd/, preventing access to the ancestor directories.
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Message-Id: <20200429124733.22488-1-mszeredi@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 397ae982f4df46e7d4b2625c431062c9146f3b83)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 184ad0f..73d8405 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -2540,6 +2540,8 @@ static void print_capabilities(void)
+ static void setup_namespaces(struct lo_data *lo, struct fuse_session *se)
+ {
+     pid_t child;
++    char template[] = "virtiofsd-XXXXXX";
++    char *tmpdir;
+ 
+     /*
+      * Create a new pid namespace for *child* processes.  We'll have to
+@@ -2601,12 +2603,33 @@ static void setup_namespaces(struct lo_data *lo, struct fuse_session *se)
+         exit(1);
+     }
+ 
++    tmpdir = mkdtemp(template);
++    if (!tmpdir) {
++        fuse_log(FUSE_LOG_ERR, "tmpdir(%s): %m\n", template);
++        exit(1);
++    }
++
++    if (mount("/proc/self/fd", tmpdir, NULL, MS_BIND, NULL) < 0) {
++        fuse_log(FUSE_LOG_ERR, "mount(/proc/self/fd, %s, MS_BIND): %m\n",
++                 tmpdir);
++        exit(1);
++    }
++
+     /* Now we can get our /proc/self/fd directory file descriptor */
+-    lo->proc_self_fd = open("/proc/self/fd", O_PATH);
++    lo->proc_self_fd = open(tmpdir, O_PATH);
+     if (lo->proc_self_fd == -1) {
+-        fuse_log(FUSE_LOG_ERR, "open(/proc/self/fd, O_PATH): %m\n");
++        fuse_log(FUSE_LOG_ERR, "open(%s, O_PATH): %m\n", tmpdir);
+         exit(1);
+     }
++
++    if (umount2(tmpdir, MNT_DETACH) < 0) {
++        fuse_log(FUSE_LOG_ERR, "umount2(%s, MNT_DETACH): %m\n", tmpdir);
++        exit(1);
++    }
++
++    if (rmdir(tmpdir) < 0) {
++        fuse_log(FUSE_LOG_ERR, "rmdir(%s): %m\n", tmpdir);
++    }
+ }
+ 
+ /*
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtiofsd-only-retain-file-system-capabilities.patch b/SOURCES/kvm-virtiofsd-only-retain-file-system-capabilities.patch
new file mode 100644
index 0000000..15c8cd8
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-only-retain-file-system-capabilities.patch
@@ -0,0 +1,112 @@
+From 8727e4904e7a6588e39f231d837f4527f265e47e Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:35:59 +0100
+Subject: [PATCH 8/9] virtiofsd: only retain file system capabilities
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20200505163600.22956-7-dgilbert@redhat.com>
+Patchwork-id: 96272
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 6/7] virtiofsd: only retain file system capabilities
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+virtiofsd runs as root but only needs a subset of root's Linux
+capabilities(7).  As a file server its purpose is to create and access
+files on behalf of a client.  It needs to be able to access files with
+arbitrary uid/gid owners.  It also needs to be create device nodes.
+
+Introduce a Linux capabilities(7) whitelist and drop all capabilities
+that we don't need, making the virtiofsd process less powerful than a
+regular uid root process.
+
+  # cat /proc/PID/status
+  ...
+          Before           After
+  CapInh: 0000000000000000 0000000000000000
+  CapPrm: 0000003fffffffff 00000000880000df
+  CapEff: 0000003fffffffff 00000000880000df
+  CapBnd: 0000003fffffffff 0000000000000000
+  CapAmb: 0000000000000000 0000000000000000
+
+Note that file capabilities cannot be used to achieve the same effect on
+the virtiofsd executable because mount is used during sandbox setup.
+Therefore we drop capabilities programmatically at the right point
+during startup.
+
+This patch only affects the sandboxed child process.  The parent process
+that sits in waitpid(2) still has full root capabilities and will be
+addressed in the next patch.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20200416164907.244868-2-stefanha@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit a59feb483b8fae24d043569ccfcc97ea23d54a02)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 614ba55..6358874 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -2723,6 +2723,43 @@ static void setup_mounts(const char *source)
+ }
+ 
+ /*
++ * Only keep whitelisted capabilities that are needed for file system operation
++ */
++static void setup_capabilities(void)
++{
++    pthread_mutex_lock(&cap.mutex);
++    capng_restore_state(&cap.saved);
++
++    /*
++     * Whitelist file system-related capabilities that are needed for a file
++     * server to act like root.  Drop everything else like networking and
++     * sysadmin capabilities.
++     *
++     * Exclusions:
++     * 1. CAP_LINUX_IMMUTABLE is not included because it's only used via ioctl
++     *    and we don't support that.
++     * 2. CAP_MAC_OVERRIDE is not included because it only seems to be
++     *    used by the Smack LSM.  Omit it until there is demand for it.
++     */
++    capng_setpid(syscall(SYS_gettid));
++    capng_clear(CAPNG_SELECT_BOTH);
++    capng_updatev(CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE,
++            CAP_CHOWN,
++            CAP_DAC_OVERRIDE,
++            CAP_DAC_READ_SEARCH,
++            CAP_FOWNER,
++            CAP_FSETID,
++            CAP_SETGID,
++            CAP_SETUID,
++            CAP_MKNOD,
++            CAP_SETFCAP);
++    capng_apply(CAPNG_SELECT_BOTH);
++
++    cap.saved = capng_save_state();
++    pthread_mutex_unlock(&cap.mutex);
++}
++
++/*
+  * Lock down this process to prevent access to other processes or files outside
+  * source directory.  This reduces the impact of arbitrary code execution bugs.
+  */
+@@ -2732,6 +2769,7 @@ static void setup_sandbox(struct lo_data *lo, struct fuse_session *se,
+     setup_namespaces(lo, se);
+     setup_mounts(lo->source);
+     setup_seccomp(enable_syslog);
++    setup_capabilities();
+ }
+ 
+ /* Set the maximum number of open file descriptors */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/kvm-virtiofsd-stay-below-fs.file-max-sysctl-value-CVE-20.patch b/SOURCES/kvm-virtiofsd-stay-below-fs.file-max-sysctl-value-CVE-20.patch
new file mode 100644
index 0000000..ce74f4d
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-stay-below-fs.file-max-sysctl-value-CVE-20.patch
@@ -0,0 +1,88 @@
+From 301f19f2ebd617e43e3a8e7bdcf694de580fe689 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Tue, 5 May 2020 16:35:56 +0100
+Subject: [PATCH 5/9] virtiofsd: stay below fs.file-max sysctl value
+ (CVE-2020-10717)
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20200505163600.22956-4-dgilbert@redhat.com>
+Patchwork-id: 96271
+O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 3/7] virtiofsd: stay below fs.file-max sysctl value (CVE-2020-10717)
+Bugzilla: 1817445
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+The system-wide fs.file-max sysctl value determines how many files can
+be open.  It defaults to a value calculated based on the machine's RAM
+size.  Previously virtiofsd would try to set RLIMIT_NOFILE to 1,000,000
+and this allowed the FUSE client to exhaust the number of open files
+system-wide on Linux hosts with less than 10 GB of RAM!
+
+Take fs.file-max into account when choosing the default RLIMIT_NOFILE
+value.
+
+Fixes: CVE-2020-10717
+Reported-by: Yuval Avrahami <yavrahami@paloaltonetworks.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-Id: <20200501140644.220940-3-stefanha@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 8c1d353d107b4fc344e27f2f08ea7fa25de2eea2)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/helper.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
+index 9b3eddc..5b222ea 100644
+--- a/tools/virtiofsd/helper.c
++++ b/tools/virtiofsd/helper.c
+@@ -176,7 +176,8 @@ void fuse_cmdline_help(void)
+            "                               default: no_xattr\n"
+            "    --rlimit-nofile=<num>      set maximum number of file descriptors\n"
+            "                               (0 leaves rlimit unchanged)\n"
+-           "                               default: 1,000,000 if the current rlimit is lower\n"
++           "                               default: min(1000000, fs.file-max - 16384)\n"
++           "                                        if the current rlimit is lower\n"
+            );
+ }
+ 
+@@ -199,9 +200,32 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key,
+ 
+ static unsigned long get_default_rlimit_nofile(void)
+ {
++    g_autofree gchar *file_max_str = NULL;
++    const rlim_t reserved_fds = 16384; /* leave at least this many fds free */
+     rlim_t max_fds = 1000000; /* our default RLIMIT_NOFILE target */
++    rlim_t file_max;
+     struct rlimit rlim;
+ 
++    /*
++     * Reduce max_fds below the system-wide maximum, if necessary.  This
++     * ensures there are fds available for other processes so we don't
++     * cause resource exhaustion.
++     */
++    if (!g_file_get_contents("/proc/sys/fs/file-max", &file_max_str,
++                             NULL, NULL)) {
++        fuse_log(FUSE_LOG_ERR, "can't read /proc/sys/fs/file-max\n");
++        exit(1);
++    }
++    file_max = g_ascii_strtoull(file_max_str, NULL, 10);
++    if (file_max < 2 * reserved_fds) {
++        fuse_log(FUSE_LOG_ERR,
++                 "The fs.file-max sysctl is too low (%lu) to allow a "
++                 "reasonable number of open files.\n",
++                 (unsigned long)file_max);
++        exit(1);
++    }
++    max_fds = MIN(file_max - reserved_fds, max_fds);
++
+     if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+         fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
+         exit(1);
+-- 
+1.8.3.1
+
diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec
index ba806ba..9f52a1c 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: 4.2.0
-Release: 19%{?dist}
+Release: 29%{?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
@@ -643,6 +643,276 @@ Patch246: kvm-block-Increase-BB.in_flight-for-coroutine-and-sync-i.patch
 Patch247: kvm-block-Fix-blk-in_flight-during-blk_wait_while_draine.patch
 # For bz#1822682 - QEMU-4.2 fails to start a VM on Azure
 Patch248: kvm-target-i386-do-not-set-unsupported-VMX-secondary-exe.patch
+# For bz#1790899 - [RFE] QEMU devices should have the option to enable/disable hotplug/unplug
+Patch249: kvm-pcie_root_port-Add-hotplug-disabling-option.patch
+# For bz#1816793 - 'edid' compat handling missing for virtio-gpu-ccw
+Patch250: kvm-compat-disable-edid-for-virtio-gpu-ccw.patch
+# For bz#1820531 - qmp command query-pci get wrong result after hotplug device under hotplug=off controller
+Patch251: kvm-hw-pci-pcie-Forbid-hot-plug-if-it-s-disabled-on-the-.patch
+# For bz#1820531 - qmp command query-pci get wrong result after hotplug device under hotplug=off controller
+Patch252: kvm-hw-pci-pcie-Replace-PCI_DEVICE-casts-with-existing-v.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch253: kvm-tools-virtiofsd-passthrough_ll-Fix-double-close.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch254: kvm-virtiofsd-add-rlimit-nofile-NUM-option.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch255: kvm-virtiofsd-stay-below-fs.file-max-sysctl-value-CVE-20.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch256: kvm-virtiofsd-jail-lo-proc_self_fd.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch257: kvm-virtiofsd-Show-submounts.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch258: kvm-virtiofsd-only-retain-file-system-capabilities.patch
+# For bz#1817445 - CVE-2020-10717 virt:8.2/qemu-kvm: QEMU: virtiofsd: guest may open maximum file descriptor to cause DoS [rhel-av-8]
+Patch259: kvm-virtiofsd-drop-all-capabilities-in-the-wait-parent-p.patch
+# For bz#1775462 - Creating luks-inside-qcow2 images with cluster_size=2k/4k will get a corrupted image
+Patch260: kvm-block-always-fill-entire-LUKS-header-space-with-zero.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch261: kvm-numa-remove-not-needed-check.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch262: kvm-numa-properly-check-if-numa-is-supported.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch263: kvm-numa-Extend-CLI-to-provide-initiator-information-for.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch264: kvm-numa-Extend-CLI-to-provide-memory-latency-and-bandwi.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch265: kvm-numa-Extend-CLI-to-provide-memory-side-cache-informa.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch266: kvm-hmat-acpi-Build-Memory-Proximity-Domain-Attributes-S.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch267: kvm-hmat-acpi-Build-System-Locality-Latency-and-Bandwidt.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch268: kvm-hmat-acpi-Build-Memory-Side-Cache-Information-Struct.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch269: kvm-tests-numa-Add-case-for-QMP-build-HMAT.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch270: kvm-tests-bios-tables-test-add-test-cases-for-ACPI-HMAT.patch
+# For bz#1600217 - [Intel 8.2.1 FEAT] KVM ACPI HMAT support - qemu-kvm  Fast Train
+Patch271: kvm-ACPI-add-expected-files-for-HMAT-tests-acpihmat.patch
+# For bz#1813940 - CVE-2020-10702 virt:8.1/qemu-kvm: qemu: weak signature generation in Pointer Authentication support for ARM [rhel-av-8]
+Patch272: kvm-target-arm-Fix-PAuth-sbox-functions.patch
+# For bz#1749737 - CVE-2019-15890 qemu-kvm: QEMU: Slirp: use-after-free during packet reassembly [rhel-av-8]
+Patch273: kvm-Don-t-leak-memory-when-reallocation-fails.patch
+# For bz#1749737 - CVE-2019-15890 qemu-kvm: QEMU: Slirp: use-after-free during packet reassembly [rhel-av-8]
+Patch274: kvm-Replace-remaining-malloc-free-user-with-glib.patch
+# For bz#1839030 - RFE: enable the "memfd" memory backend
+Patch275: kvm-Revert-RHEL-disable-hostmem-memfd.patch
+# For bz#1827630 - volume creation leaving uncleaned stuff behind on error (vol-clone/libvirt/qemu-kvm)
+Patch276: kvm-block-introducing-bdrv_co_delete_file-interface.patch
+# For bz#1827630 - volume creation leaving uncleaned stuff behind on error (vol-clone/libvirt/qemu-kvm)
+Patch277: kvm-block.c-adding-bdrv_co_delete_file.patch
+# For bz#1827630 - volume creation leaving uncleaned stuff behind on error (vol-clone/libvirt/qemu-kvm)
+Patch278: kvm-crypto.c-cleanup-created-file-when-block_crypto_co_c.patch
+# For bz#1513681 - [Intel 8.2.1 Feat] qemu-kvm PT VMX -- Fast Train
+Patch279: kvm-target-i386-set-the-CPUID-level-to-0x14-on-old-machi.patch
+# For bz#1841038 - qemu-img: /var/tmp/v2vovl56bced.qcow2: CURL: Error opening file: Server does not support 'range' (byte ranges) with HTTP/2 server in VMware ESXi 7
+Patch280: kvm-block-curl-HTTP-header-fields-allow-whitespace-aroun.patch
+# For bz#1841038 - qemu-img: /var/tmp/v2vovl56bced.qcow2: CURL: Error opening file: Server does not support 'range' (byte ranges) with HTTP/2 server in VMware ESXi 7
+Patch281: kvm-block-curl-HTTP-header-field-names-are-case-insensit.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch282: kvm-MAINTAINERS-fix-qcow2-bitmap.c-under-Dirty-Bitmaps-h.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch283: kvm-iotests-Let-_make_test_img-parse-its-parameters.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch284: kvm-qemu_img-add-cvtnum_full-to-print-error-reports.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch285: kvm-block-Make-it-easier-to-learn-which-BDS-support-bitm.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch286: kvm-blockdev-Promote-several-bitmap-functions-to-non-sta.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch287: kvm-blockdev-Split-off-basic-bitmap-operations-for-qemu-.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch288: kvm-qemu-img-Add-bitmap-sub-command.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch289: kvm-iotests-Fix-test-178.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch290: kvm-qcow2-Expose-bitmaps-size-during-measure.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch291: kvm-qemu-img-Factor-out-code-for-merging-bitmaps.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch292: kvm-qemu-img-Add-convert-bitmaps-option.patch
+# For bz#1779893 - RFE: Copy bitmaps with qemu-img convert
+# For bz#1779904 - RFE: ability to estimate bitmap space utilization for qcow2
+Patch293: kvm-iotests-Add-test-291-to-for-qemu-img-bitmap-coverage.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch294: kvm-iotests-Add-more-skip_if_unsupported-statements-to-t.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch295: kvm-iotests-don-t-use-format-for-drive_add.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch296: kvm-iotests-055-refactor-compressed-backup-to-vmdk.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch297: kvm-iotests-055-skip-vmdk-target-tests-if-vmdk-is-not-wh.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch298: kvm-backup-Improve-error-for-bdrv_getlength-failure.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch299: kvm-backup-Make-sure-that-source-and-target-size-match.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch300: kvm-iotests-Backup-with-different-source-target-size.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch301: kvm-iotests-109-Don-t-mirror-with-mismatched-size.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch302: kvm-iotests-229-Use-blkdebug-to-inject-an-error.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch303: kvm-mirror-Make-sure-that-source-and-target-size-match.patch
+# For bz#1778593 - Qemu coredump when backup to a existing small size image
+Patch304: kvm-iotests-Mirror-with-different-source-target-size.patch
+# For bz#1841068 - RFE: please support the "ramfb" display device model
+Patch305: kvm-enable-ramfb.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch306: kvm-block-Add-flags-to-BlockDriver.bdrv_co_truncate.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch307: kvm-block-Add-flags-to-bdrv-_co-_truncate.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch308: kvm-block-backend-Add-flags-to-blk_truncate.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch309: kvm-qcow2-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch310: kvm-raw-format-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch311: kvm-file-posix-Support-BDRV_REQ_ZERO_WRITE-for-truncate.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch312: kvm-block-truncate-Don-t-make-backing-file-data-visible.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch313: kvm-iotests-Add-qemu_io_log.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch314: kvm-iotests-Filter-testfiles-out-in-filter_img_info.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch315: kvm-iotests-Test-committing-to-short-backing-file.patch
+# For bz#1780574 - Data corruption with resizing short overlay over longer backing files
+Patch316: kvm-qcow2-Forward-ZERO_WRITE-flag-for-full-preallocation.patch
+# For bz#1769912 - [Intel 8.2.1 Feature] introduce Cooper Lake cpu model - qemu-kvm Fast Train
+Patch317: kvm-i386-Add-MSR-feature-bit-for-MDS-NO.patch
+# For bz#1769912 - [Intel 8.2.1 Feature] introduce Cooper Lake cpu model - qemu-kvm Fast Train
+Patch318: kvm-i386-Add-macro-for-stibp.patch
+# For bz#1769912 - [Intel 8.2.1 Feature] introduce Cooper Lake cpu model - qemu-kvm Fast Train
+Patch319: kvm-target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch
+# For bz#1769912 - [Intel 8.2.1 Feature] introduce Cooper Lake cpu model - qemu-kvm Fast Train
+Patch320: kvm-i386-Add-new-CPU-model-Cooperlake.patch
+# For bz#1769912 - [Intel 8.2.1 Feature] introduce Cooper Lake cpu model - qemu-kvm Fast Train
+Patch321: kvm-target-i386-Add-missed-features-to-Cooperlake-CPU-mo.patch
+# For bz#1845384 - CVE-2020-10761 virt:8.2/qemu-kvm: QEMU: nbd: reachable assertion failure in nbd_negotiate_send_rep_verr via remote client [rhel-av-8]
+Patch322: kvm-nbd-server-Avoid-long-error-message-assertions-CVE-2.patch
+# For bz#1845384 - CVE-2020-10761 virt:8.2/qemu-kvm: QEMU: nbd: reachable assertion failure in nbd_negotiate_send_rep_verr via remote client [rhel-av-8]
+Patch323: kvm-block-Call-attention-to-truncation-of-long-NBD-expor.patch
+# For bz#1820531 - qmp command query-pci get wrong result after hotplug device under hotplug=off controller
+Patch324: kvm-hw-pci-pcie-Move-hot-plug-capability-check-to-pre_pl.patch
+# For bz#1840342 - [Intel 8.2.1 Bug] qemu-kvm Add ARCH_CAPABILITIES to Icelake-Server cpu model - Fast Train
+Patch325: kvm-target-i386-Add-ARCH_CAPABILITIES-related-bits-into-.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch327: kvm-linux-headers-update-kvm.h.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch328: kvm-s390x-Don-t-do-a-normal-reset-on-the-initial-cpu.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch329: kvm-s390x-Move-reset-normal-to-shared-reset-handler.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch330: kvm-s390x-Move-initial-reset.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch331: kvm-s390x-Move-clear-reset.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch332: kvm-s390x-Beautify-diag308-handling.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch333: kvm-s390x-kvm-Make-kvm_sclp_service_call-void.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch334: kvm-s390x-Fix-cpu-normal-reset-ri-clearing.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch335: kvm-tests-boot-sector-Fix-the-bad-s390x-assembler-code.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch336: kvm-pc-bios-s390x-Fix-reset-psw-mask.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch337: kvm-s390x-Properly-fetch-and-test-the-short-psw-on-diag3.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch338: kvm-s390x-Rename-and-use-constants-for-short-PSW-address.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch339: kvm-s390x-Add-missing-vcpu-reset-functions.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch340: kvm-s390-sclp-improve-special-wait-psw-logic.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch341: kvm-pc-bios-s390x-Save-iplb-location-in-lowcore.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch342: kvm-s390-ipl-sync-back-loadparm.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch343: kvm-s390-ipl-fix-off-by-one-in-update_machine_ipl_proper.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch344: kvm-s390x-ipl-Consolidate-iplb-validity-check-into-one-f.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch345: kvm-vhost-correctly-turn-on-VIRTIO_F_IOMMU_PLATFORM.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch346: kvm-s390x-Move-diagnose-308-subcodes-and-rcs-into-ipl.h.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch347: kvm-s390x-protvirt-Support-unpack-facility.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch348: kvm-s390x-protvirt-Add-migration-blocker.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch349: kvm-s390x-protvirt-Inhibit-balloon-when-switching-to-pro.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch350: kvm-s390x-protvirt-KVM-intercept-changes.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch351: kvm-s390x-Add-SIDA-memory-ops.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch352: kvm-s390x-protvirt-Move-STSI-data-over-SIDAD.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch353: kvm-s390x-protvirt-SCLP-interpretation.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch354: kvm-s390x-protvirt-Set-guest-IPL-PSW.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch355: kvm-s390x-protvirt-Move-diag-308-data-over-SIDA.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch356: kvm-s390x-protvirt-Disable-address-checks-for-PV-guest-I.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch357: kvm-s390x-protvirt-Move-IO-control-structures-over-SIDA.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch358: kvm-s390x-protvirt-Handle-SIGP-store-status-correctly.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch359: kvm-s390x-Add-unpack-facility-feature-to-GA1.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch360: kvm-s390x-protvirt-Fix-stray-error_report_err-in-s390_ma.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch361: kvm-s390x-pv-Retry-ioctls-on-EINTR.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch362: kvm-s390x-s390-virtio-ccw-Fix-build-on-systems-without-K.patch
+# For bz#1828317 - [IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part
+Patch363: kvm-s390x-pv-Fix-KVM_PV_PREP_RESET-command-wrapper-name.patch
+# For bz#1756946 - [zKVM] Re-enable KVM_CAP_S390_AIS for new machine types
+Patch364: kvm-spapr-Pass-the-maximum-number-of-vCPUs-to-the-KVM-in.patch
+# For bz#1756946 - [zKVM] Re-enable KVM_CAP_S390_AIS for new machine types
+Patch365: kvm-introduce-kvm_kernel_irqchip_-functions.patch
+# For bz#1756946 - [zKVM] Re-enable KVM_CAP_S390_AIS for new machine types
+Patch366: kvm-target-s390x-kvm-Enable-adapter-interruption-suppres.patch
+# For bz#1823275 - RHEL8.1 - GPU Numa nodes not visible in guest post the pass-through.
+Patch367: kvm-vfio-nvlink-Remove-exec-permission-to-avoid-SELinux-.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch368: kvm-vfio-ccw-Fix-error-message.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch369: kvm-vfio-ccw-allow-non-prefetch-ORBs.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch370: kvm-linux-headers-support-vfio-ccw-features.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch371: kvm-vfio-ccw-Refactor-cleanup-of-regions.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch372: kvm-vfio-ccw-Add-support-for-the-schib-region.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch373: kvm-vfio-ccw-Refactor-ccw-irq-handler.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch374: kvm-s390x-css-Refactor-the-css_queue_crw-routine.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch375: kvm-vfio-ccw-Add-support-for-the-CRW-region-and-IRQ.patch
+# For bz#1660916 - [IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part
+Patch376: kvm-config-enable-VFIO_CCW.patch
+Patch377: kvm-virtio-blk-Refactor-the-code-that-processes-queued-r.patch
+Patch378: kvm-virtio-blk-On-restart-process-queued-requests-in-the.patch
+# For bz#1838070 - CVE-2020-1983 virt:rhel/qemu-kvm: QEMU: slirp: use-after-free in ip_reass() function in ip_input.c [rhel-8]
+Patch379: kvm-Fix-use-afte-free-in-ip_reass-CVE-2020-1983.patch
 
 BuildRequires: wget
 BuildRequires: rpm-build
@@ -1128,6 +1398,11 @@ cp -a %{kvm_target}-softmmu/qemu-system-%{kvm_target} qemu-kvm
 gcc %{SOURCE6} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o ksmctl
 gcc %{SOURCE35} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o udev-kvm-check
 
+%ifarch s390x
+    # Copy the built new images into place for "make check":
+    cp pc-bios/s390-ccw/s390-ccw.img pc-bios/s390-ccw/s390-netboot.img pc-bios/
+%endif
+
 %install
 %define _udevdir %(pkg-config --variable=udevdir udev)
 %define _udevrulesdir %{_udevdir}/rules.d
@@ -1178,9 +1453,9 @@ install -p -m 0755 tests/Makefile.include $RPM_BUILD_ROOT%{testsdir}/tests/
 # Install qemu-iotests
 cp -R tests/qemu-iotests/* $RPM_BUILD_ROOT%{testsdir}/tests/qemu-iotests/
 # Avoid ambiguous 'python' interpreter name
-find $RPM_BUILD_ROOT%{testsdir}/tests/qemu-iotests/* -maxdepth 1 -type f -exec sed -i -e '1 s+/usr/bin/env python+%{__python3}+' {} \;
-find $RPM_BUILD_ROOT%{testsdir}/scripts/qmp/* -maxdepth 1 -type f -exec sed -i -e '1 s+/usr/bin/env python+%{__python3}+' {} \;
-find $RPM_BUILD_ROOT%{testsdir}/scripts/qmp/* -maxdepth 1 -type f -exec sed -i -e '1 s+/usr/bin/python+%{__python3}+' {} \;
+find $RPM_BUILD_ROOT%{testsdir}/tests/qemu-iotests/* -maxdepth 1 -type f -exec sed -i -e '1 s+/usr/bin/env \(python\|python3\)+%{__python3}+' {} \;
+find $RPM_BUILD_ROOT%{testsdir}/scripts/qmp/* -maxdepth 1 -type f -exec sed -i -e '1 s+/usr/bin/env \(python\|python3\)+%{__python3}+' {} \;
+find $RPM_BUILD_ROOT%{testsdir}/scripts/qmp/* -maxdepth 1 -type f -exec sed -i -e '1 s+/usr/bin/\(python\|python3\)+%{__python3}+' {} \;
 
 install -p -m 0644 %{SOURCE36} $RPM_BUILD_ROOT%{testsdir}/README
 
@@ -1266,6 +1541,7 @@ rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/qemu_vga.ndrv
 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/skiboot.lid
 
 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/s390-ccw.img
+rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/s390-netboot.img
 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/hppa-firmware.img
 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/canyonlands.dtb
 rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/u-boot-sam460-20100605.bin
@@ -1282,10 +1558,9 @@ rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/qemu-nsis.bmp
 rm -rf ${RPM_BUILD_ROOT}%{_libdir}/qemu-kvm/ui-spice-app.so
 
 %ifarch s390x
-    # Use the s390-ccw.img that we've just built, not the pre-built one
+    # Use the s390-*.imgs that we've just built, not the pre-built ones
     install -m 0644 pc-bios/s390-ccw/s390-ccw.img $RPM_BUILD_ROOT%{_datadir}/%{name}/
-%else
-    rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}/s390-netboot.img
+    install -m 0644 pc-bios/s390-ccw/s390-netboot.img $RPM_BUILD_ROOT%{_datadir}/%{name}/
 %endif
 
 %ifnarch x86_64
@@ -1570,6 +1845,88 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
 
 
 %changelog
+* Sun Jun 28 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-29.el8
+- kvm-vfio-ccw-Fix-error-message.patch [bz#1660916]
+- kvm-vfio-ccw-allow-non-prefetch-ORBs.patch [bz#1660916]
+- kvm-linux-headers-support-vfio-ccw-features.patch [bz#1660916]
+- kvm-vfio-ccw-Refactor-cleanup-of-regions.patch [bz#1660916]
+- kvm-vfio-ccw-Add-support-for-the-schib-region.patch [bz#1660916]
+- kvm-vfio-ccw-Refactor-ccw-irq-handler.patch [bz#1660916]
+- kvm-s390x-css-Refactor-the-css_queue_crw-routine.patch [bz#1660916]
+- kvm-vfio-ccw-Add-support-for-the-CRW-region-and-IRQ.patch [bz#1660916]
+- kvm-config-enable-VFIO_CCW.patch [bz#1660916]
+- kvm-virtio-blk-Refactor-the-code-that-processes-queued-r.patch []
+- kvm-virtio-blk-On-restart-process-queued-requests-in-the.patch []
+- kvm-Fix-use-afte-free-in-ip_reass-CVE-2020-1983.patch [bz#1838070]
+- Resolves: bz#1660916
+  ([IBM 8.3 FEAT] KVM s390x: DASD passthrough support - qemu part)
+- Resolves: bz#1838070
+  (CVE-2020-1983 virt:rhel/qemu-kvm: QEMU: slirp: use-after-free in ip_reass() function in ip_input.c [rhel-8])
+
+* Fri Jun 19 2020 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-28.el8
+- kvm-redhat-Install-the-s390-netboot.img-that-we-ve-built.patch [bz#1828317]
+- kvm-linux-headers-update-kvm.h.patch [bz#1828317]
+- kvm-s390x-Don-t-do-a-normal-reset-on-the-initial-cpu.patch [bz#1828317]
+- kvm-s390x-Move-reset-normal-to-shared-reset-handler.patch [bz#1828317]
+- kvm-s390x-Move-initial-reset.patch [bz#1828317]
+- kvm-s390x-Move-clear-reset.patch [bz#1828317]
+- kvm-s390x-Beautify-diag308-handling.patch [bz#1828317]
+- kvm-s390x-kvm-Make-kvm_sclp_service_call-void.patch [bz#1828317]
+- kvm-s390x-Fix-cpu-normal-reset-ri-clearing.patch [bz#1828317]
+- kvm-tests-boot-sector-Fix-the-bad-s390x-assembler-code.patch [bz#1828317]
+- kvm-pc-bios-s390x-Fix-reset-psw-mask.patch [bz#1828317]
+- kvm-s390x-Properly-fetch-and-test-the-short-psw-on-diag3.patch [bz#1828317]
+- kvm-s390x-Rename-and-use-constants-for-short-PSW-address.patch [bz#1828317]
+- kvm-s390x-Add-missing-vcpu-reset-functions.patch [bz#1828317]
+- kvm-s390-sclp-improve-special-wait-psw-logic.patch [bz#1828317]
+- kvm-pc-bios-s390x-Save-iplb-location-in-lowcore.patch [bz#1828317]
+- kvm-s390-ipl-sync-back-loadparm.patch [bz#1828317]
+- kvm-s390-ipl-fix-off-by-one-in-update_machine_ipl_proper.patch [bz#1828317]
+- kvm-s390x-ipl-Consolidate-iplb-validity-check-into-one-f.patch [bz#1828317]
+- kvm-vhost-correctly-turn-on-VIRTIO_F_IOMMU_PLATFORM.patch [bz#1828317]
+- kvm-s390x-Move-diagnose-308-subcodes-and-rcs-into-ipl.h.patch [bz#1828317]
+- kvm-s390x-protvirt-Support-unpack-facility.patch [bz#1828317]
+- kvm-s390x-protvirt-Add-migration-blocker.patch [bz#1828317]
+- kvm-s390x-protvirt-Inhibit-balloon-when-switching-to-pro.patch [bz#1828317]
+- kvm-s390x-protvirt-KVM-intercept-changes.patch [bz#1828317]
+- kvm-s390x-Add-SIDA-memory-ops.patch [bz#1828317]
+- kvm-s390x-protvirt-Move-STSI-data-over-SIDAD.patch [bz#1828317]
+- kvm-s390x-protvirt-SCLP-interpretation.patch [bz#1828317]
+- kvm-s390x-protvirt-Set-guest-IPL-PSW.patch [bz#1828317]
+- kvm-s390x-protvirt-Move-diag-308-data-over-SIDA.patch [bz#1828317]
+- kvm-s390x-protvirt-Disable-address-checks-for-PV-guest-I.patch [bz#1828317]
+- kvm-s390x-protvirt-Move-IO-control-structures-over-SIDA.patch [bz#1828317]
+- kvm-s390x-protvirt-Handle-SIGP-store-status-correctly.patch [bz#1828317]
+- kvm-s390x-Add-unpack-facility-feature-to-GA1.patch [bz#1828317]
+- kvm-s390x-protvirt-Fix-stray-error_report_err-in-s390_ma.patch [bz#1828317]
+- kvm-s390x-pv-Retry-ioctls-on-EINTR.patch [bz#1828317]
+- kvm-s390x-s390-virtio-ccw-Fix-build-on-systems-without-K.patch [bz#1828317]
+- kvm-s390x-pv-Fix-KVM_PV_PREP_RESET-command-wrapper-name.patch [bz#1828317]
+- kvm-spapr-Pass-the-maximum-number-of-vCPUs-to-the-KVM-in.patch [bz#1756946]
+- kvm-introduce-kvm_kernel_irqchip_-functions.patch [bz#1756946]
+- kvm-target-s390x-kvm-Enable-adapter-interruption-suppres.patch [bz#1756946]
+- kvm-vfio-nvlink-Remove-exec-permission-to-avoid-SELinux-.patch [bz#1823275]
+- Resolves: bz#1756946
+  ([zKVM] Re-enable KVM_CAP_S390_AIS for new machine types)
+- Resolves: bz#1823275
+  (RHEL8.1 - GPU Numa nodes not visible in guest post the pass-through.)
+- Resolves: bz#1828317
+  ([IBM 8.3 FEAT] s390x: Base KVM setup for secure guests - qemu part)
+
+* Fri Jun 19 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 4.2.0
+- Resolves: bz#1810193
+(Upgrade components in virt:rhel module:stream for RHEL-8.3 release)
+
+* Tue Jun 09 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 4.2.0-25
+- Resolves: bz#1810193
+  (Upgrade components in virt:rhel module:stream for RHEL-8.3 release)
+  Another sync
+
+* Thu Jun 04 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 4.2.0-23.el8
+- Resolves: bz#1810193
+  (Upgrade components in virt:rhel module:stream for RHEL-8.3 release)
+  Another syncronization
+
 * Mon Apr 27 2020 Danilo C. L. de Paula <ddepaula@redhat.com> - 4.2.0
 - Resolves: bz#1810193
   (Upgrade components in virt:rhel module:stream for RHEL-8.3 release)