diff --git a/SOURCES/kvm-Add-mtod_check.patch b/SOURCES/kvm-Add-mtod_check.patch
new file mode 100644
index 0000000..0b2e710
--- /dev/null
+++ b/SOURCES/kvm-Add-mtod_check.patch
@@ -0,0 +1,68 @@
+From 52bf635da30c75d0fdb0a3e7e7b9a2483ca033fc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:55:59 -0400
+Subject: [PATCH 05/14] Add mtod_check()
+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: <20210708082537.1550263-2-marcandre.lureau@redhat.com>
+Patchwork-id: 101819
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/8] Add mtod_check()
+Bugzilla: 1970819 1970835 1970843 1970853
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Recent security issues demonstrate the lack of safety care when casting
+a mbuf to a particular structure type. At least, it should check that
+the buffer is large enough. The following patches will make use of this
+function.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+(cherry picked from commit 93e645e72a056ec0b2c16e0299fc5c6b94e4ca17)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/mbuf.c | 11 +++++++++++
+ slirp/src/mbuf.h |  1 +
+ 2 files changed, 12 insertions(+)
+
+diff --git a/slirp/src/mbuf.c b/slirp/src/mbuf.c
+index 4fd62282a9..6d0653ed3d 100644
+--- a/slirp/src/mbuf.c
++++ b/slirp/src/mbuf.c
+@@ -222,3 +222,14 @@ struct mbuf *dtom(Slirp *slirp, void *dat)
+ 
+     return (struct mbuf *)0;
+ }
++
++void *mtod_check(struct mbuf *m, size_t len)
++{
++    if (m->m_len >= len) {
++        return m->m_data;
++    }
++
++    DEBUG_ERROR("mtod failed");
++
++    return NULL;
++}
+diff --git a/slirp/src/mbuf.h b/slirp/src/mbuf.h
+index 546e7852c5..2015e3232f 100644
+--- a/slirp/src/mbuf.h
++++ b/slirp/src/mbuf.h
+@@ -118,6 +118,7 @@ void m_inc(struct mbuf *, int);
+ void m_adj(struct mbuf *, int);
+ int m_copy(struct mbuf *, struct mbuf *, int, int);
+ struct mbuf *dtom(Slirp *, void *);
++void *mtod_check(struct mbuf *, size_t len);
+ 
+ static inline void ifs_init(struct mbuf *ifm)
+ {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-Compress-lines-for-immediate-return.patch b/SOURCES/kvm-Compress-lines-for-immediate-return.patch
new file mode 100644
index 0000000..aed5149
--- /dev/null
+++ b/SOURCES/kvm-Compress-lines-for-immediate-return.patch
@@ -0,0 +1,242 @@
+From 5cf6dd33456c4e7e2a8849f458ce234fb5bb290c Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Fri, 25 Jun 2021 17:41:03 -0400
+Subject: [PATCH 3/4] Compress lines for immediate return
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20210625174104.44313-2-kwolf@redhat.com>
+Patchwork-id: 101777
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] Compress lines for immediate return
+Bugzilla: 1970912
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Simran Singhal <singhalsimran0@gmail.com>
+
+Compress two lines into a single line if immediate return statement is found.
+
+It also remove variables progress, val, data, ret and sock
+as they are no longer needed.
+
+Remove space between function "mixer_load" and '(' to fix the
+checkpatch.pl error:-
+ERROR: space prohibited between function name and open parenthesis '('
+
+Done using following coccinelle script:
+@@
+local idexpression ret;
+expression e;
+@@
+
+-ret =
++return
+     e;
+-return ret;
+
+Signed-off-by: Simran Singhal <singhalsimran0@gmail.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20200401165314.GA3213@simran-Inspiron-5558>
+[lv: in handle_aiocb_write_zeroes_unmap() move "int ret" inside the #ifdef]
+Signed-off-by: Laurent Vivier <laurent@vivier.eu>
+(cherry picked from commit b3ac2b94cdc939a90d5a22338ae507689e2cfab0)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/file-posix.c      | 8 +++-----
+ block/nfs.c             | 3 +--
+ block/nvme.c            | 4 +---
+ block/vhdx.c            | 3 +--
+ hw/audio/ac97.c         | 4 +---
+ hw/audio/adlib.c        | 5 +----
+ hw/display/cirrus_vga.c | 4 +---
+ migration/ram.c         | 4 +---
+ ui/gtk.c                | 3 +--
+ util/qemu-sockets.c     | 5 +----
+ 10 files changed, 12 insertions(+), 31 deletions(-)
+
+diff --git a/block/file-posix.c b/block/file-posix.c
+index 371572f1b0..837edcf027 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -1626,13 +1626,12 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
+ {
+     RawPosixAIOData *aiocb = opaque;
+     BDRVRawState *s G_GNUC_UNUSED = aiocb->bs->opaque;
+-    int ret;
+ 
+     /* First try to write zeros and unmap at the same time */
+ 
+ #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+-    ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+-                       aiocb->aio_offset, aiocb->aio_nbytes);
++    int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
++                           aiocb->aio_offset, aiocb->aio_nbytes);
+     if (ret != -ENOTSUP) {
+         return ret;
+     }
+@@ -1640,8 +1639,7 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
+ 
+     /* If we couldn't manage to unmap while guaranteed that the area reads as
+      * all-zero afterwards, just write zeroes without unmapping */
+-    ret = handle_aiocb_write_zeroes(aiocb);
+-    return ret;
++    return handle_aiocb_write_zeroes(aiocb);
+ }
+ 
+ #ifndef HAVE_COPY_FILE_RANGE
+diff --git a/block/nfs.c b/block/nfs.c
+index 2393fbfe6b..18c0a73694 100644
+--- a/block/nfs.c
++++ b/block/nfs.c
+@@ -623,8 +623,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
+     }
+ 
+     bs->total_sectors = ret;
+-    ret = 0;
+-    return ret;
++    return 0;
+ }
+ 
+ static QemuOptsList nfs_create_opts = {
+diff --git a/block/nvme.c b/block/nvme.c
+index 7b7c0cc5d6..eb2f54dd9d 100644
+--- a/block/nvme.c
++++ b/block/nvme.c
+@@ -575,11 +575,9 @@ static bool nvme_poll_cb(void *opaque)
+ {
+     EventNotifier *e = opaque;
+     BDRVNVMeState *s = container_of(e, BDRVNVMeState, irq_notifier);
+-    bool progress = false;
+ 
+     trace_nvme_poll_cb(s);
+-    progress = nvme_poll_queues(s);
+-    return progress;
++    return nvme_poll_queues(s);
+ }
+ 
+ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
+diff --git a/block/vhdx.c b/block/vhdx.c
+index 21497f7318..a427e47f10 100644
+--- a/block/vhdx.c
++++ b/block/vhdx.c
+@@ -411,8 +411,7 @@ int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
+     if (ret < 0) {
+         return ret;
+     }
+-    ret = vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
+-    return ret;
++    return vhdx_update_header(bs, s, generate_data_write_guid, log_guid);
+ }
+ 
+ /* opens the specified header block from the VHDX file header section */
+diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
+index a136b97f68..a2cfae52b3 100644
+--- a/hw/audio/ac97.c
++++ b/hw/audio/ac97.c
+@@ -574,11 +574,9 @@ static uint32_t nam_readb (void *opaque, uint32_t addr)
+ static uint32_t nam_readw (void *opaque, uint32_t addr)
+ {
+     AC97LinkState *s = opaque;
+-    uint32_t val = ~0U;
+     uint32_t index = addr;
+     s->cas = 0;
+-    val = mixer_load (s, index);
+-    return val;
++    return mixer_load(s, index);
+ }
+ 
+ static uint32_t nam_readl (void *opaque, uint32_t addr)
+diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
+index cb4178d861..5779d09815 100644
+--- a/hw/audio/adlib.c
++++ b/hw/audio/adlib.c
+@@ -120,13 +120,10 @@ static void adlib_write(void *opaque, uint32_t nport, uint32_t val)
+ static uint32_t adlib_read(void *opaque, uint32_t nport)
+ {
+     AdlibState *s = opaque;
+-    uint8_t data;
+     int a = nport & 3;
+ 
+     adlib_kill_timers (s);
+-    data = OPLRead (s->opl, a);
+-
+-    return data;
++    return OPLRead (s->opl, a);
+ }
+ 
+ static void timer_handler (void *opaque, int c, double interval_Sec)
+diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
+index 93afa26fda..a52d3094b9 100644
+--- a/hw/display/cirrus_vga.c
++++ b/hw/display/cirrus_vga.c
+@@ -2411,12 +2411,10 @@ static uint64_t cirrus_linear_bitblt_read(void *opaque,
+                                           unsigned size)
+ {
+     CirrusVGAState *s = opaque;
+-    uint32_t ret;
+ 
+     /* XXX handle bitblt */
+     (void)s;
+-    ret = 0xff;
+-    return ret;
++    return 0xff;
+ }
+ 
+ static void cirrus_linear_bitblt_write(void *opaque,
+diff --git a/migration/ram.c b/migration/ram.c
+index 5344c7d59e..92c506d13c 100644
+--- a/migration/ram.c
++++ b/migration/ram.c
+@@ -3101,9 +3101,7 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
+     }
+     trace_ram_postcopy_send_discard_bitmap();
+ 
+-    ret = postcopy_each_ram_send_discard(ms);
+-
+-    return ret;
++    return postcopy_each_ram_send_discard(ms);
+ }
+ 
+ /**
+diff --git a/ui/gtk.c b/ui/gtk.c
+index 692ccc7bbb..e032e3c36f 100644
+--- a/ui/gtk.c
++++ b/ui/gtk.c
+@@ -1649,8 +1649,7 @@ static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
+                      G_CALLBACK(gd_menu_switch_vc), s);
+     gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), vc->menu_item);
+ 
+-    group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
+-    return group;
++    return gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
+ }
+ 
+ #if defined(CONFIG_VTE)
+diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
+index bcc06d0e01..86c48b9fa5 100644
+--- a/util/qemu-sockets.c
++++ b/util/qemu-sockets.c
+@@ -765,15 +765,12 @@ static int vsock_connect_addr(const struct sockaddr_vm *svm, Error **errp)
+ static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp)
+ {
+     struct sockaddr_vm svm;
+-    int sock = -1;
+ 
+     if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
+         return -1;
+     }
+ 
+-    sock = vsock_connect_addr(&svm, errp);
+-
+-    return sock;
++    return vsock_connect_addr(&svm, errp);
+ }
+ 
+ static int vsock_listen_saddr(VsockSocketAddress *vaddr,
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch b/SOURCES/kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch
new file mode 100644
index 0000000..2dd4457
--- /dev/null
+++ b/SOURCES/kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch
@@ -0,0 +1,59 @@
+From d0c668aa0ad255c3598267816154874541ac2943 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:42 -0400
+Subject: [PATCH 12/14] Fix "DHCP broken in libslirp v4.6.0"
+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: <20210708082537.1550263-9-marcandre.lureau@redhat.com>
+Patchwork-id: 101824
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 8/8] Fix "DHCP broken in libslirp v4.6.0"
+Bugzilla: 1970819 1970835 1970843 1970853
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
+
+Fix issue 48
+
+Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
+
+(cherry picked from commit c9f314f6e315a5518432761fea864196a290f799)
+[ minor conflict fix due to indentation change ]
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/bootp.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/slirp/src/bootp.c b/slirp/src/bootp.c
+index 5789187166..3e4af075f1 100644
+--- a/slirp/src/bootp.c
++++ b/slirp/src/bootp.c
+@@ -354,14 +354,14 @@ static void bootp_reply(Slirp *slirp,
+         q += sizeof(nak_msg) - 1;
+     }
+     assert(q < end);
+-    *q =
+-RFC1533_END
+-;
++    *q = RFC1533_END;
+ 
+-daddr.sin_addr.s_addr = 0xffffffffu;
++    daddr.sin_addr.s_addr = 0xffffffffu;
+ 
+-m->m_len = sizeof(struct bootp_t) - sizeof(struct ip) - sizeof(struct udphdr);
+-udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
++    assert ((q - rbp->bp_vend + 1) <= DHCP_OPT_LEN);
++
++    m->m_len = sizeof(struct bootp_t) + (q - rbp->bp_vend + 1) - sizeof(struct ip) - sizeof(struct udphdr);
++    udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ }
+ 
+ void bootp_input(struct mbuf *m)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch b/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch
new file mode 100644
index 0000000..1538d11
--- /dev/null
+++ b/SOURCES/kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch
@@ -0,0 +1,82 @@
+From dcac680adb6b8624f14eda3e812521bddbe8ecea Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Wed, 21 Apr 2021 22:30:04 -0400
+Subject: [PATCH 5/7] acpi: accept byte and word access to core ACPI registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210421223006.19650-5-jmaloy@redhat.com>
+Patchwork-id: 101482
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 4/6] acpi: accept byte and word access to core ACPI registers
+Bugzilla: 1842478
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Michael Tokarev <mjt@tls.msk.ru>
+
+All ISA registers should be accessible as bytes, words or dwords
+(if wide enough).  Fix the access constraints for acpi-pm-evt,
+acpi-pm-tmr & acpi-cnt registers.
+
+Fixes: 5d971f9e67 (memory: Revert "memory: accept mismatching sizes in memory_region_access_valid")
+Fixes: afafe4bbe0 (apci: switch cnt to memory api)
+Fixes: 77d58b1e47 (apci: switch timer to memory api)
+Fixes: b5a7c024d2 (apci: switch evt to memory api)
+Buglink: https://lore.kernel.org/xen-devel/20200630170913.123646-1-anthony.perard@citrix.com/T/
+Buglink: https://bugs.debian.org/964793
+BugLink: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=964247
+BugLink: https://bugs.launchpad.net/bugs/1886318
+Reported-By: Simon John <git@the-jedi.co.uk>
+Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
+Message-Id: <20200720160627.15491-1-mjt@msgid.tls.msk.ru>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+
+(cherry picked from commit dba04c3488c4699f5afe96f66e448b1d447cf3fb)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/acpi/core.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/hw/acpi/core.c b/hw/acpi/core.c
+index 45cbed49ab..d85052c34a 100644
+--- a/hw/acpi/core.c
++++ b/hw/acpi/core.c
+@@ -461,7 +461,8 @@ static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val,
+ static const MemoryRegionOps acpi_pm_evt_ops = {
+     .read = acpi_pm_evt_read,
+     .write = acpi_pm_evt_write,
+-    .valid.min_access_size = 2,
++    .impl.min_access_size = 2,
++    .valid.min_access_size = 1,
+     .valid.max_access_size = 2,
+     .endianness = DEVICE_LITTLE_ENDIAN,
+ };
+@@ -530,7 +531,8 @@ static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val,
+ static const MemoryRegionOps acpi_pm_tmr_ops = {
+     .read = acpi_pm_tmr_read,
+     .write = acpi_pm_tmr_write,
+-    .valid.min_access_size = 4,
++    .impl.min_access_size = 4,
++    .valid.min_access_size = 1,
+     .valid.max_access_size = 4,
+     .endianness = DEVICE_LITTLE_ENDIAN,
+ };
+@@ -602,7 +604,8 @@ static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val,
+ static const MemoryRegionOps acpi_pm_cnt_ops = {
+     .read = acpi_pm_cnt_read,
+     .write = acpi_pm_cnt_write,
+-    .valid.min_access_size = 2,
++    .impl.min_access_size = 2,
++    .valid.min_access_size = 1,
+     .valid.max_access_size = 2,
+     .endianness = DEVICE_LITTLE_ENDIAN,
+ };
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch b/SOURCES/kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch
new file mode 100644
index 0000000..a234140
--- /dev/null
+++ b/SOURCES/kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch
@@ -0,0 +1,132 @@
+From b474155fdc38f86f516c14ba9a6f934616d589ef Mon Sep 17 00:00:00 2001
+From: Andrew Jones <drjones@redhat.com>
+Date: Wed, 4 Aug 2021 03:27:22 -0400
+Subject: [PATCH 1/2] aio-wait: delegate polling of main AioContext if BQL not
+ held
+
+RH-Author: Andrew Jones <drjones@redhat.com>
+Message-id: <20210729134448.4995-2-drjones@redhat.com>
+Patchwork-id: 101935
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 1/2] aio-wait: delegate polling of main AioContext if BQL not held
+Bugzilla: 1969848
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+Any thread that is not a iothread returns NULL for qemu_get_current_aio_context().
+As a result, it would also return true for
+in_aio_context_home_thread(qemu_get_aio_context()), causing
+AIO_WAIT_WHILE to invoke aio_poll() directly.  This is incorrect
+if the BQL is not held, because aio_poll() does not expect to
+run concurrently from multiple threads, and it can actually
+happen when savevm writes to the vmstate file from the
+migration thread.
+
+Therefore, restrict in_aio_context_home_thread to return true
+for the main AioContext only if the BQL is held.
+
+The function is moved to aio-wait.h because it is mostly used
+there and to avoid a circular reference between main-loop.h
+and block/aio.h.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-Id: <20200407140746.8041-5-pbonzini@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 3c18a92dc4b55ca8cc37a755ed119f11c0f34099)
+Signed-off-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/block/aio-wait.h | 22 ++++++++++++++++++++++
+ include/block/aio.h      | 29 ++++++++++-------------------
+ 2 files changed, 32 insertions(+), 19 deletions(-)
+
+diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
+index afeeb18f95..716d2639df 100644
+--- a/include/block/aio-wait.h
++++ b/include/block/aio-wait.h
+@@ -26,6 +26,7 @@
+ #define QEMU_AIO_WAIT_H
+ 
+ #include "block/aio.h"
++#include "qemu/main-loop.h"
+ 
+ /**
+  * AioWait:
+@@ -124,4 +125,25 @@ void aio_wait_kick(void);
+  */
+ void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
+ 
++/**
++ * in_aio_context_home_thread:
++ * @ctx: the aio context
++ *
++ * Return whether we are running in the thread that normally runs @ctx.  Note
++ * that acquiring/releasing ctx does not affect the outcome, each AioContext
++ * still only has one home thread that is responsible for running it.
++ */
++static inline bool in_aio_context_home_thread(AioContext *ctx)
++{
++    if (ctx == qemu_get_current_aio_context()) {
++        return true;
++    }
++
++    if (ctx == qemu_get_aio_context()) {
++        return qemu_mutex_iothread_locked();
++    } else {
++        return false;
++    }
++}
++
+ #endif /* QEMU_AIO_WAIT_H */
+diff --git a/include/block/aio.h b/include/block/aio.h
+index 6b0d52f732..9d28e247df 100644
+--- a/include/block/aio.h
++++ b/include/block/aio.h
+@@ -60,12 +60,16 @@ struct AioContext {
+     QLIST_HEAD(, AioHandler) aio_handlers;
+ 
+     /* Used to avoid unnecessary event_notifier_set calls in aio_notify;
+-     * accessed with atomic primitives.  If this field is 0, everything
+-     * (file descriptors, bottom halves, timers) will be re-evaluated
+-     * before the next blocking poll(), thus the event_notifier_set call
+-     * can be skipped.  If it is non-zero, you may need to wake up a
+-     * concurrent aio_poll or the glib main event loop, making
+-     * event_notifier_set necessary.
++     * only written from the AioContext home thread, or under the BQL in
++     * the case of the main AioContext.  However, it is read from any
++     * thread so it is still accessed with atomic primitives.
++     *
++     * If this field is 0, everything (file descriptors, bottom halves,
++     * timers) will be re-evaluated before the next blocking poll() or
++     * io_uring wait; therefore, the event_notifier_set call can be
++     * skipped.  If it is non-zero, you may need to wake up a concurrent
++     * aio_poll or the glib main event loop, making event_notifier_set
++     * necessary.
+      *
+      * Bit 0 is reserved for GSource usage of the AioContext, and is 1
+      * between a call to aio_ctx_prepare and the next call to aio_ctx_check.
+@@ -580,19 +584,6 @@ void aio_co_enter(AioContext *ctx, struct Coroutine *co);
+  */
+ AioContext *qemu_get_current_aio_context(void);
+ 
+-/**
+- * in_aio_context_home_thread:
+- * @ctx: the aio context
+- *
+- * Return whether we are running in the thread that normally runs @ctx.  Note
+- * that acquiring/releasing ctx does not affect the outcome, each AioContext
+- * still only has one home thread that is responsible for running it.
+- */
+-static inline bool in_aio_context_home_thread(AioContext *ctx)
+-{
+-    return ctx == qemu_get_current_aio_context();
+-}
+-
+ /**
+  * aio_context_setup:
+  * @ctx: the aio context
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-async-use-explicit-memory-barriers.patch b/SOURCES/kvm-async-use-explicit-memory-barriers.patch
new file mode 100644
index 0000000..2bf7245
--- /dev/null
+++ b/SOURCES/kvm-async-use-explicit-memory-barriers.patch
@@ -0,0 +1,183 @@
+From 82a02aec3a8b3c2ac925d0b71ea4c35aa5d6463b Mon Sep 17 00:00:00 2001
+From: Andrew Jones <drjones@redhat.com>
+Date: Wed, 4 Aug 2021 03:27:24 -0400
+Subject: [PATCH 2/2] async: use explicit memory barriers
+
+RH-Author: Andrew Jones <drjones@redhat.com>
+Message-id: <20210729134448.4995-3-drjones@redhat.com>
+Patchwork-id: 101937
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 2/2] async: use explicit memory barriers
+Bugzilla: 1969848
+RH-Acked-by: Gavin Shan <gshan@redhat.com>
+RH-Acked-by: Auger Eric <eric.auger@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+When using C11 atomics, non-seqcst reads and writes do not participate
+in the total order of seqcst operations.  In util/async.c and util/aio-posix.c,
+in particular, the pattern that we use
+
+          write ctx->notify_me                 write bh->scheduled
+          read bh->scheduled                   read ctx->notify_me
+          if !bh->scheduled, sleep             if ctx->notify_me, notify
+
+needs to use seqcst operations for both the write and the read.  In
+general this is something that we do not want, because there can be
+many sources that are polled in addition to bottom halves.  The
+alternative is to place a seqcst memory barrier between the write
+and the read.  This also comes with a disadvantage, in that the
+memory barrier is implicit on strongly-ordered architectures and
+it wastes a few dozen clock cycles.
+
+Fortunately, ctx->notify_me is never written concurrently by two
+threads, so we can assert that and relax the writes to ctx->notify_me.
+The resulting solution works and performs well on both aarch64 and x86.
+
+Note that the atomic_set/atomic_read combination is not an atomic
+read-modify-write, and therefore it is even weaker than C11 ATOMIC_RELAXED;
+on x86, ATOMIC_RELAXED compiles to a locked operation.
+
+Analyzed-by: Ying Fang <fangying1@huawei.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Tested-by: Ying Fang <fangying1@huawei.com>
+Message-Id: <20200407140746.8041-6-pbonzini@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+(cherry picked from commit 5710a3e09f9b85801e5ce70797a4a511e5fc9e2c)
+Signed-off-by: Andrew Jones <drjones@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ util/aio-posix.c | 16 ++++++++++++++--
+ util/aio-win32.c | 17 ++++++++++++++---
+ util/async.c     | 16 ++++++++++++----
+ 3 files changed, 40 insertions(+), 9 deletions(-)
+
+diff --git a/util/aio-posix.c b/util/aio-posix.c
+index abc396d030..8cfb25650d 100644
+--- a/util/aio-posix.c
++++ b/util/aio-posix.c
+@@ -624,6 +624,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
+     int64_t timeout;
+     int64_t start = 0;
+ 
++    /*
++     * There cannot be two concurrent aio_poll calls for the same AioContext (or
++     * an aio_poll concurrent with a GSource prepare/check/dispatch callback).
++     * We rely on this below to avoid slow locked accesses to ctx->notify_me.
++     */
+     assert(in_aio_context_home_thread(ctx));
+ 
+     /* aio_notify can avoid the expensive event_notifier_set if
+@@ -634,7 +639,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
+      * so disable the optimization now.
+      */
+     if (blocking) {
+-        atomic_add(&ctx->notify_me, 2);
++        atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2);
++        /*
++         * Write ctx->notify_me before computing the timeout
++         * (reading bottom half flags, etc.).  Pairs with
++         * smp_mb in aio_notify().
++         */
++        smp_mb();
+     }
+ 
+     qemu_lockcnt_inc(&ctx->list_lock);
+@@ -679,7 +690,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
+     }
+ 
+     if (blocking) {
+-        atomic_sub(&ctx->notify_me, 2);
++        /* Finish the poll before clearing the flag.  */
++        atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2);
+         aio_notify_accept(ctx);
+     }
+ 
+diff --git a/util/aio-win32.c b/util/aio-win32.c
+index a23b9c364d..729d533faf 100644
+--- a/util/aio-win32.c
++++ b/util/aio-win32.c
+@@ -321,6 +321,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
+     int count;
+     int timeout;
+ 
++    /*
++     * There cannot be two concurrent aio_poll calls for the same AioContext (or
++     * an aio_poll concurrent with a GSource prepare/check/dispatch callback).
++     * We rely on this below to avoid slow locked accesses to ctx->notify_me.
++     */
++    assert(in_aio_context_home_thread(ctx));
+     progress = false;
+ 
+     /* aio_notify can avoid the expensive event_notifier_set if
+@@ -331,7 +337,13 @@ bool aio_poll(AioContext *ctx, bool blocking)
+      * so disable the optimization now.
+      */
+     if (blocking) {
+-        atomic_add(&ctx->notify_me, 2);
++        atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2);
++        /*
++         * Write ctx->notify_me before computing the timeout
++         * (reading bottom half flags, etc.).  Pairs with
++         * smp_mb in aio_notify().
++         */
++        smp_mb();
+     }
+ 
+     qemu_lockcnt_inc(&ctx->list_lock);
+@@ -364,8 +376,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
+         ret = WaitForMultipleObjects(count, events, FALSE, timeout);
+         if (blocking) {
+             assert(first);
+-            assert(in_aio_context_home_thread(ctx));
+-            atomic_sub(&ctx->notify_me, 2);
++            atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2);
+             aio_notify_accept(ctx);
+         }
+ 
+diff --git a/util/async.c b/util/async.c
+index b1fa5319e5..c65c58bbc9 100644
+--- a/util/async.c
++++ b/util/async.c
+@@ -220,7 +220,14 @@ aio_ctx_prepare(GSource *source, gint    *timeout)
+ {
+     AioContext *ctx = (AioContext *) source;
+ 
+-    atomic_or(&ctx->notify_me, 1);
++    atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) | 1);
++
++    /*
++     * Write ctx->notify_me before computing the timeout
++     * (reading bottom half flags, etc.).  Pairs with
++     * smp_mb in aio_notify().
++     */
++    smp_mb();
+ 
+     /* We assume there is no timeout already supplied */
+     *timeout = qemu_timeout_ns_to_ms(aio_compute_timeout(ctx));
+@@ -238,7 +245,8 @@ aio_ctx_check(GSource *source)
+     AioContext *ctx = (AioContext *) source;
+     QEMUBH *bh;
+ 
+-    atomic_and(&ctx->notify_me, ~1);
++    /* Finish computing the timeout before clearing the flag.  */
++    atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) & ~1);
+     aio_notify_accept(ctx);
+ 
+     for (bh = ctx->first_bh; bh; bh = bh->next) {
+@@ -343,10 +351,10 @@ LinuxAioState *aio_get_linux_aio(AioContext *ctx)
+ void aio_notify(AioContext *ctx)
+ {
+     /* Write e.g. bh->scheduled before reading ctx->notify_me.  Pairs
+-     * with atomic_or in aio_ctx_prepare or atomic_add in aio_poll.
++     * with smp_mb in aio_ctx_prepare or aio_poll.
+      */
+     smp_mb();
+-    if (ctx->notify_me) {
++    if (atomic_read(&ctx->notify_me)) {
+         event_notifier_set(&ctx->notifier);
+         atomic_mb_set(&ctx->notified, true);
+     }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch b/SOURCES/kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch
new file mode 100644
index 0000000..1a20688
--- /dev/null
+++ b/SOURCES/kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch
@@ -0,0 +1,53 @@
+From 96c8fcafa7325cd0e8a23a743a55f0ad0aa9f79b Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 18 Mar 2021 09:13:42 -0400
+Subject: [PATCH 5/5] audio: audio_generic_get_buffer_in should honor *size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: <20210318091342.3232471-2-kraxel@redhat.com>
+Patchwork-id: 101352
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] audio: audio_generic_get_buffer_in should honor *size
+Bugzilla: 1932823
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: Volker Rümelin <vr_qemu@t-online.de>
+
+The function generic_get_buffer_in currently ignores the *size
+parameter and may return a buffer larger than *size.
+
+As a result the variable samples in function
+audio_pcm_hw_run_in may underflow. The while loop then most
+likely will never termiate.
+
+Buglink: http://bugs.debian.org/948658
+Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
+Message-Id: <20200123074943.6699-9-vr_qemu@t-online.de>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 599eac4e5a41e828645594097daee39373acc3c0)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ audio/audio.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/audio/audio.c b/audio/audio.c
+index 56fae55047..39a62fc62a 100644
+--- a/audio/audio.c
++++ b/audio/audio.c
+@@ -1402,7 +1402,8 @@ void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size)
+     }
+     assert(start >= 0 && start < hw->size_emul);
+ 
+-    *size = MIN(hw->pending_emul, hw->size_emul - start);
++    *size = MIN(*size, hw->pending_emul);
++    *size = MIN(*size, hw->size_emul - start);
+     return hw->buf_emul + start;
+ }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch b/SOURCES/kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch
new file mode 100644
index 0000000..60b1b0a
--- /dev/null
+++ b/SOURCES/kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch
@@ -0,0 +1,76 @@
+From 8c339c3535728179acc94deb5b922aebcfac9ab6 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Thu, 3 Jun 2021 16:13:34 -0400
+Subject: [PATCH 2/4] block/file-posix: Fix problem with fallocate(PUNCH_HOLE)
+ on GPFS
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20210603161334.607005-2-thuth@redhat.com>
+Patchwork-id: 101673
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] block/file-posix: Fix problem with fallocate(PUNCH_HOLE) on GPFS
+Bugzilla: 1944861
+RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+A customer reported that running
+
+ qemu-img convert -t none -O qcow2 -f qcow2 input.qcow2 output.qcow2
+
+fails for them with the following error message when the images are
+stored on a GPFS file system :
+
+ qemu-img: error while writing sector 0: Invalid argument
+
+After analyzing the strace output, it seems like the problem is in
+handle_aiocb_write_zeroes(): The call to fallocate(FALLOC_FL_PUNCH_HOLE)
+returns EINVAL, which can apparently happen if the file system has
+a different idea of the granularity of the operation. It's arguably
+a bug in GPFS, since the PUNCH_HOLE mode should not result in EINVAL
+according to the man-page of fallocate(), but the file system is out
+there in production and so we have to deal with it. In commit 294682cc3a
+("block: workaround for unaligned byte range in fallocate()") we also
+already applied the a work-around for the same problem to the earlier
+fallocate(FALLOC_FL_ZERO_RANGE) call, so do it now similar with the
+PUNCH_HOLE call. But instead of silently catching and returning
+-ENOTSUP (which causes the caller to fall back to writing zeroes),
+let's rather inform the user once about the buggy file system and
+try the other fallback instead.
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Message-Id: <20210527172020.847617-2-thuth@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit 73ebf29729d1a40feaa9f8ab8951b6ee6dbfbede)
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1944861
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/file-posix.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/block/file-posix.c b/block/file-posix.c
+index 62a463229f..371572f1b0 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -1587,6 +1587,17 @@ static int handle_aiocb_write_zeroes(void *opaque)
+                 return ret;
+             }
+             s->has_fallocate = false;
++        } else if (ret == -EINVAL) {
++            /*
++             * Some file systems like older versions of GPFS do not like un-
++             * aligned byte ranges, and return EINVAL in such a case, though
++             * they should not do it according to the man-page of fallocate().
++             * Warn about the bad filesystem and try the final fallback instead.
++             */
++            warn_report_once("Your file system is misbehaving: "
++                             "fallocate(FALLOC_FL_PUNCH_HOLE) returned EINVAL. "
++                             "Please report this bug to your file sytem "
++                             "vendor.");
+         } else if (ret != -ENOTSUP) {
+             return ret;
+         } else {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-bootp-check-bootp_input-buffer-size.patch b/SOURCES/kvm-bootp-check-bootp_input-buffer-size.patch
new file mode 100644
index 0000000..3362cb0
--- /dev/null
+++ b/SOURCES/kvm-bootp-check-bootp_input-buffer-size.patch
@@ -0,0 +1,52 @@
+From a66ab346bf74ebf3ed8fca0dc2e2febfe70069e8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:28 -0400
+Subject: [PATCH 07/14] bootp: check bootp_input buffer size
+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: <20210708082537.1550263-4-marcandre.lureau@redhat.com>
+Patchwork-id: 101820
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 3/8] bootp: check bootp_input buffer size
+Bugzilla: 1970819
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Fixes: CVE-2021-3592
+Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/44
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970819
+
+(cherry picked from commit 2eca0838eee1da96204545e22cdaed860d9d7c6c)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/bootp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/slirp/src/bootp.c b/slirp/src/bootp.c
+index 5754327138..5789187166 100644
+--- a/slirp/src/bootp.c
++++ b/slirp/src/bootp.c
+@@ -366,9 +366,9 @@ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ 
+ void bootp_input(struct mbuf *m)
+ {
+-    struct bootp_t *bp = mtod(m, struct bootp_t *);
++    struct bootp_t *bp = mtod_check(m, sizeof(struct bootp_t));
+ 
+-    if (bp->bp_op == BOOTP_REQUEST) {
++    if (bp && bp->bp_op == BOOTP_REQUEST) {
+         bootp_reply(m->slirp, bp, m_end(m));
+     }
+ }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch b/SOURCES/kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch
new file mode 100644
index 0000000..bbf9b03
--- /dev/null
+++ b/SOURCES/kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch
@@ -0,0 +1,175 @@
+From 8198ae7c21a4d37f7e365058f973867c41d44d21 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:25 -0400
+Subject: [PATCH 06/14] bootp: limit vendor-specific area to input packet
+ memory buffer
+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: <20210708082537.1550263-3-marcandre.lureau@redhat.com>
+Patchwork-id: 101821
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/8] bootp: limit vendor-specific area to input packet memory buffer
+Bugzilla: 1970819 1970835 1970843 1970853
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+sizeof(bootp_t) currently holds DHCP_OPT_LEN. Remove this optional field
+from the structure, to help with the following patch checking for
+minimal header size. Modify the bootp_reply() function to take the
+buffer boundaries and avoiding potential buffer overflow.
+
+Related to CVE-2021-3592.
+
+https://gitlab.freedesktop.org/slirp/libslirp/-/issues/44
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+(cherry picked from commit f13cad45b25d92760bb0ad67bec0300a4d7d5275)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/bootp.c | 26 +++++++++++++++-----------
+ slirp/src/bootp.h |  2 +-
+ slirp/src/mbuf.c  |  5 +++++
+ slirp/src/mbuf.h  |  1 +
+ 4 files changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/slirp/src/bootp.c b/slirp/src/bootp.c
+index 3f9ce2553e..5754327138 100644
+--- a/slirp/src/bootp.c
++++ b/slirp/src/bootp.c
+@@ -92,21 +92,22 @@ found:
+     return bc;
+ }
+ 
+-static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
++static void dhcp_decode(const struct bootp_t *bp,
++                        const uint8_t *bp_end,
++                        int *pmsg_type,
+                         struct in_addr *preq_addr)
+ {
+-    const uint8_t *p, *p_end;
++    const uint8_t *p;
+     int len, tag;
+ 
+     *pmsg_type = 0;
+     preq_addr->s_addr = htonl(0L);
+ 
+     p = bp->bp_vend;
+-    p_end = p + DHCP_OPT_LEN;
+     if (memcmp(p, rfc1533_cookie, 4) != 0)
+         return;
+     p += 4;
+-    while (p < p_end) {
++    while (p < bp_end) {
+         tag = p[0];
+         if (tag == RFC1533_PAD) {
+             p++;
+@@ -114,10 +115,10 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
+             break;
+         } else {
+             p++;
+-            if (p >= p_end)
++            if (p >= bp_end)
+                 break;
+             len = *p++;
+-            if (p + len > p_end) {
++            if (p + len > bp_end) {
+                 break;
+             }
+             DPRINTF("dhcp: tag=%d len=%d\n", tag, len);
+@@ -144,7 +145,9 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
+     }
+ }
+ 
+-static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
++static void bootp_reply(Slirp *slirp,
++                        const struct bootp_t *bp,
++                        const uint8_t *bp_end)
+ {
+     BOOTPClient *bc = NULL;
+     struct mbuf *m;
+@@ -157,7 +160,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
+     uint8_t client_ethaddr[ETH_ALEN];
+ 
+     /* extract exact DHCP msg type */
+-    dhcp_decode(bp, &dhcp_msg_type, &preq_addr);
++    dhcp_decode(bp, bp_end, &dhcp_msg_type, &preq_addr);
+     DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
+     if (preq_addr.s_addr != htonl(0L))
+         DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));
+@@ -179,9 +182,10 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
+         return;
+     }
+     m->m_data += IF_MAXLINKHDR;
++    m_inc(m, sizeof(struct bootp_t) + DHCP_OPT_LEN);
+     rbp = (struct bootp_t *)m->m_data;
+     m->m_data += sizeof(struct udpiphdr);
+-    memset(rbp, 0, sizeof(struct bootp_t));
++    memset(rbp, 0, sizeof(struct bootp_t) + DHCP_OPT_LEN);
+ 
+     if (dhcp_msg_type == DHCPDISCOVER) {
+         if (preq_addr.s_addr != htonl(0L)) {
+@@ -235,7 +239,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
+     rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
+ 
+     q = rbp->bp_vend;
+-    end = (uint8_t *)&rbp[1];
++    end = rbp->bp_vend + DHCP_OPT_LEN;
+     memcpy(q, rfc1533_cookie, 4);
+     q += 4;
+ 
+@@ -365,6 +369,6 @@ void bootp_input(struct mbuf *m)
+     struct bootp_t *bp = mtod(m, struct bootp_t *);
+ 
+     if (bp->bp_op == BOOTP_REQUEST) {
+-        bootp_reply(m->slirp, bp);
++        bootp_reply(m->slirp, bp, m_end(m));
+     }
+ }
+diff --git a/slirp/src/bootp.h b/slirp/src/bootp.h
+index 03ece9bf28..0d20a944a8 100644
+--- a/slirp/src/bootp.h
++++ b/slirp/src/bootp.h
+@@ -114,7 +114,7 @@ struct bootp_t {
+     uint8_t bp_hwaddr[16];
+     uint8_t bp_sname[64];
+     uint8_t bp_file[128];
+-    uint8_t bp_vend[DHCP_OPT_LEN];
++    uint8_t bp_vend[];
+ };
+ 
+ typedef struct {
+diff --git a/slirp/src/mbuf.c b/slirp/src/mbuf.c
+index 6d0653ed3d..7db07c088e 100644
+--- a/slirp/src/mbuf.c
++++ b/slirp/src/mbuf.c
+@@ -233,3 +233,8 @@ void *mtod_check(struct mbuf *m, size_t len)
+ 
+     return NULL;
+ }
++
++void *m_end(struct mbuf *m)
++{
++    return m->m_data + m->m_len;
++}
+diff --git a/slirp/src/mbuf.h b/slirp/src/mbuf.h
+index 2015e3232f..a9752a36e0 100644
+--- a/slirp/src/mbuf.h
++++ b/slirp/src/mbuf.h
+@@ -119,6 +119,7 @@ void m_adj(struct mbuf *, int);
+ int m_copy(struct mbuf *, struct mbuf *, int, int);
+ struct mbuf *dtom(Slirp *, void *);
+ void *mtod_check(struct mbuf *, size_t len);
++void *m_end(struct mbuf *);
+ 
+ static inline void ifs_init(struct mbuf *ifm)
+ {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch b/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch
new file mode 100644
index 0000000..32d5377
--- /dev/null
+++ b/SOURCES/kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch
@@ -0,0 +1,60 @@
+From 6f1ebcfdb92d12ef2caae0b63a3a380265cba1fa Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:46 -0400
+Subject: [PATCH 8/9] cadence_gem: switch to use qemu_receive_packet() for
+ loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-9-jmaloy@redhat.com>
+Patchwork-id: 101793
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 8/9] cadence_gem: switch to use qemu_receive_packet() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alexander Bulekov <alxndr@bu.edu>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit e73adfbeec9d4e008630c814759052ed945c3fed)
+Conflict: upstream commit 24d62fd5028e ("net: cadence_gem: Move tx/rx
+packet buffert to CadenceGEMState") is missing in this version, so
+we stick to using the original stack variable tx_packet in the calls.
+
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/cadence_gem.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
+index b8be73dc55..be7c91123b 100644
+--- a/hw/net/cadence_gem.c
++++ b/hw/net/cadence_gem.c
+@@ -1225,8 +1225,8 @@ static void gem_transmit(CadenceGEMState *s)
+                 /* Send the packet somewhere */
+                 if (s->phy_loop || (s->regs[GEM_NWCTRL] &
+                                     GEM_NWCTRL_LOCALLOOP)) {
+-                    gem_receive(qemu_get_queue(s->nic), tx_packet,
+-                                total_bytes);
++                    qemu_receive_packet(qemu_get_queue(s->nic), tx_packet,
++                                        total_bytes);
+                 } else {
+                     qemu_send_packet(qemu_get_queue(s->nic), tx_packet,
+                                      total_bytes);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch b/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch
new file mode 100644
index 0000000..77e99eb
--- /dev/null
+++ b/SOURCES/kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch
@@ -0,0 +1,53 @@
+From a6f0bef82cdd84844a06dac1e6d279d95824d827 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:41 -0400
+Subject: [PATCH 3/9] dp8393x: switch to use qemu_receive_packet() for loopback
+ packet
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-4-jmaloy@redhat.com>
+Patchwork-id: 101789
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 3/9] dp8393x: switch to use qemu_receive_packet() for loopback packet
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 331d2ac9ea307c990dc86e6493e8f0c48d14bb33)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/dp8393x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
+index 3d991af163..6d55b5de64 100644
+--- a/hw/net/dp8393x.c
++++ b/hw/net/dp8393x.c
+@@ -482,7 +482,7 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
+             s->regs[SONIC_TCR] |= SONIC_TCR_CRSL;
+             if (nc->info->can_receive(nc)) {
+                 s->loopback_packet = 1;
+-                nc->info->receive(nc, s->tx_buffer, tx_len);
++                qemu_receive_packet(nc, s->tx_buffer, tx_len);
+             }
+         } else {
+             /* Transmit packet */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-e1000-fail-early-for-evil-descriptor.patch b/SOURCES/kvm-e1000-fail-early-for-evil-descriptor.patch
new file mode 100644
index 0000000..e599b7c
--- /dev/null
+++ b/SOURCES/kvm-e1000-fail-early-for-evil-descriptor.patch
@@ -0,0 +1,65 @@
+From 7bd3000cf22a91e6bc6afc1e7adbf0ae1b731104 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 13 Apr 2021 22:45:17 -0400
+Subject: [PATCH 2/5] e1000: fail early for evil descriptor
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210413224517.3841507-2-jmaloy@redhat.com>
+Patchwork-id: 101473
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] e1000: fail early for evil descriptor
+Bugzilla: 1930092
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+During procss_tx_desc(), driver can try to chain data descriptor with
+legacy descriptor, when will lead underflow for the following
+calculation in process_tx_desc() for bytes:
+
+            if (tp->size + bytes > msh)
+                bytes = msh - tp->size;
+
+This will lead a infinite loop. So check and fail early if tp->size if
+greater or equal to msh.
+
+Reported-by: Alexander Bulekov <alxndr@bu.edu>
+Reported-by: Cheolwoo Myung <cwmyung@snu.ac.kr>
+Reported-by: Ruhr-University Bochum <bugs-syssec@rub.de>
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 3de46e6fc489c52c9431a8a832ad8170a7569bd8)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/e1000.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/net/e1000.c b/hw/net/e1000.c
+index fc73fdd6fa..fe56bccd52 100644
+--- a/hw/net/e1000.c
++++ b/hw/net/e1000.c
+@@ -671,6 +671,9 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
+         msh = tp->tso_props.hdr_len + tp->tso_props.mss;
+         do {
+             bytes = split_size;
++            if (tp->size >= msh) {
++                goto eop;
++            }
+             if (tp->size + bytes > msh)
+                 bytes = msh - tp->size;
+ 
+@@ -696,6 +699,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
+         tp->size += split_size;
+     }
+ 
++eop:
+     if (!(txd_lower & E1000_TXD_CMD_EOP))
+         return;
+     if (!(tp->cptse && tp->size < tp->tso_props.hdr_len)) {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch b/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch
new file mode 100644
index 0000000..05ff372
--- /dev/null
+++ b/SOURCES/kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch
@@ -0,0 +1,52 @@
+From 128b97f6049144af3c1a41ceb8e8583419edcd69 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:40 -0400
+Subject: [PATCH 2/9] e1000: switch to use qemu_receive_packet() for loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-3-jmaloy@redhat.com>
+Patchwork-id: 101784
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 2/9] e1000: switch to use qemu_receive_packet() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 1caff0340f49c93d535c6558a5138d20d475315c)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/e1000.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/e1000.c b/hw/net/e1000.c
+index fe56bccd52..8680b7d46b 100644
+--- a/hw/net/e1000.c
++++ b/hw/net/e1000.c
+@@ -547,7 +547,7 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
+ 
+     NetClientState *nc = qemu_get_queue(s->nic);
+     if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) {
+-        nc->info->receive(nc, buf, size);
++        qemu_receive_packet(nc, buf, size);
+     } else {
+         qemu_send_packet(nc, buf, size);
+     }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch b/SOURCES/kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch
new file mode 100644
index 0000000..ac7b859
--- /dev/null
+++ b/SOURCES/kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch
@@ -0,0 +1,59 @@
+From 94d99b13b48e922861570f043490efc966b3b445 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Fri, 25 Jun 2021 17:41:04 -0400
+Subject: [PATCH 4/4] file-posix: Handle `EINVAL` fallocate return value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20210625174104.44313-3-kwolf@redhat.com>
+Patchwork-id: 101778
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] file-posix: Handle `EINVAL` fallocate return value
+Bugzilla: 1970912
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Antoine Damhet <antoine.damhet@blade-group.com>
+
+The `detect-zeroes=unmap` option may issue unaligned
+`FALLOC_FL_PUNCH_HOLE` requests, raw block devices can (and will) return
+`EINVAL`, qemu should then write the zeroes to the blockdev instead of
+issuing an `IO_ERROR`.
+
+The problem can be reprodced like this:
+
+$ qemu-io -c 'write -P 0 42 1234' --image-opts driver=host_device,filename=/dev/loop0,detect-zeroes=unmap
+write failed: Invalid argument
+
+Signed-off-by: Antoine Damhet <antoine.damhet@blade-group.com>
+Message-Id: <20200717135603.51180-1-antoine.damhet@blade-group.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit bae127d4dcf6158c5042e2eee9582430839a9967)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/file-posix.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/block/file-posix.c b/block/file-posix.c
+index 837edcf027..6cd19e6c9a 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -1632,7 +1632,11 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
+ #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+     int ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+                            aiocb->aio_offset, aiocb->aio_nbytes);
+-    if (ret != -ENOTSUP) {
++    switch (ret) {
++    case -ENOTSUP:
++    case -EINVAL:
++        break;
++    default:
+         return ret;
+     }
+ #endif
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch b/SOURCES/kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch
new file mode 100644
index 0000000..e8639f3
--- /dev/null
+++ b/SOURCES/kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch
@@ -0,0 +1,466 @@
+From 7ee01b5ccb7fc660dafaf3fdb1578649d17fbddf Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 26 May 2021 09:05:52 -0400
+Subject: [PATCH 1/4] file-posix: Mitigate file fragmentation with extent size
+ hints
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20210526090552.155820-2-kwolf@redhat.com>
+Patchwork-id: 101638
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] file-posix: Mitigate file fragmentation with extent size hints
+Bugzilla: 1877163
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+Especially when O_DIRECT is used with image files so that the page cache
+indirection can't cause a merge of allocating requests, the file will
+fragment on the file system layer, with a potentially very small
+fragment size (this depends on the requests the guest sent).
+
+On Linux, fragmentation can be reduced by setting an extent size hint
+when creating the file (at least on XFS, it can't be set any more after
+the first extent has been allocated), basically giving raw files a
+"cluster size" for allocation.
+
+This adds a create option to set the extent size hint, and changes the
+default from not setting a hint to setting it to 1 MB. The main reason
+why qcow2 defaults to smaller cluster sizes is that COW becomes more
+expensive, which is not an issue with raw files, so we can choose a
+larger size. The tradeoff here is only potentially wasted disk space.
+
+For qcow2 (or other image formats) over file-posix, the advantage should
+even be greater because they grow sequentially without leaving holes, so
+there won't be wasted space. Setting even larger extent size hints for
+such images may make sense. This can be done with the new option, but
+let's keep the default conservative for now.
+
+The effect is very visible with a test that intentionally creates a
+badly fragmented file with qemu-img bench (the time difference while
+creating the file is already remarkable) and then looks at the number of
+extents and the time a simple "qemu-img map" takes.
+
+Without an extent size hint:
+
+    $ ./qemu-img create -f raw -o extent_size_hint=0 ~/tmp/test.raw 10G
+    Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 extent_size_hint=0
+    $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 0
+    Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 0, step size 8192)
+    Run completed in 25.848 seconds.
+    $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 4096
+    Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 4096, step size 8192)
+    Run completed in 19.616 seconds.
+    $ filefrag ~/tmp/test.raw
+    /home/kwolf/tmp/test.raw: 2000000 extents found
+    $ time ./qemu-img map ~/tmp/test.raw
+    Offset          Length          Mapped to       File
+    0               0x1e8480000     0               /home/kwolf/tmp/test.raw
+
+    real    0m1,279s
+    user    0m0,043s
+    sys     0m1,226s
+
+With the new default extent size hint of 1 MB:
+
+    $ ./qemu-img create -f raw -o extent_size_hint=1M ~/tmp/test.raw 10G
+    Formatting '/home/kwolf/tmp/test.raw', fmt=raw size=10737418240 extent_size_hint=1048576
+    $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 0
+    Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 0, step size 8192)
+    Run completed in 11.833 seconds.
+    $ ./qemu-img bench -f raw -t none -n -w ~/tmp/test.raw -c 1000000 -S 8192 -o 4096
+    Sending 1000000 write requests, 4096 bytes each, 64 in parallel (starting at offset 4096, step size 8192)
+    Run completed in 10.155 seconds.
+    $ filefrag ~/tmp/test.raw
+    /home/kwolf/tmp/test.raw: 178 extents found
+    $ time ./qemu-img map ~/tmp/test.raw
+    Offset          Length          Mapped to       File
+    0               0x1e8480000     0               /home/kwolf/tmp/test.raw
+
+    real    0m0,061s
+    user    0m0,040s
+    sys     0m0,014s
+
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200707142329.48303-1-kwolf@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit ffa244c84a1a30dff69ecc80b0137a2b6d428ecb)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ block/file-posix.c               | 44 ++++++++++++++++++++++++++++++++
+ include/block/block_int.h        |  1 +
+ qapi/block-core.json             | 11 +++++---
+ tests/qemu-iotests/082.out       | 16 ++++++++++++
+ tests/qemu-iotests/106           |  7 +++--
+ tests/qemu-iotests/175           |  6 ++---
+ tests/qemu-iotests/243           |  6 ++---
+ tests/qemu-iotests/common.filter |  1 +
+ 8 files changed, 80 insertions(+), 12 deletions(-)
+
+diff --git a/block/file-posix.c b/block/file-posix.c
+index 2d834fbdf6..62a463229f 100644
+--- a/block/file-posix.c
++++ b/block/file-posix.c
+@@ -30,6 +30,7 @@
+ #include "block/block_int.h"
+ #include "qemu/module.h"
+ #include "qemu/option.h"
++#include "qemu/units.h"
+ #include "trace.h"
+ #include "block/thread-pool.h"
+ #include "qemu/iov.h"
+@@ -2289,6 +2290,14 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+     if (!file_opts->has_preallocation) {
+         file_opts->preallocation = PREALLOC_MODE_OFF;
+     }
++    if (!file_opts->has_extent_size_hint) {
++        file_opts->extent_size_hint = 1 * MiB;
++    }
++    if (file_opts->extent_size_hint > UINT32_MAX) {
++        result = -EINVAL;
++        error_setg(errp, "Extent size hint is too large");
++        goto out;
++    }
+ 
+     /* Create file */
+     fd = qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_BINARY, 0644);
+@@ -2346,6 +2355,27 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+         }
+ #endif
+     }
++#ifdef FS_IOC_FSSETXATTR
++    /*
++     * Try to set the extent size hint. Failure is not fatal, and a warning is
++     * only printed if the option was explicitly specified.
++     */
++    {
++        struct fsxattr attr;
++        result = ioctl(fd, FS_IOC_FSGETXATTR, &attr);
++        if (result == 0) {
++            attr.fsx_xflags |= FS_XFLAG_EXTSIZE;
++            attr.fsx_extsize = file_opts->extent_size_hint;
++            result = ioctl(fd, FS_IOC_FSSETXATTR, &attr);
++        }
++        if (result < 0 && file_opts->has_extent_size_hint &&
++            file_opts->extent_size_hint)
++        {
++            warn_report("Failed to set extent size hint: %s",
++                        strerror(errno));
++        }
++    }
++#endif
+ 
+     /* Resize and potentially preallocate the file to the desired
+      * final size */
+@@ -2381,6 +2411,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+ {
+     BlockdevCreateOptions options;
+     int64_t total_size = 0;
++    int64_t extent_size_hint = 0;
++    bool has_extent_size_hint = false;
+     bool nocow = false;
+     PreallocMode prealloc;
+     char *buf = NULL;
+@@ -2392,6 +2424,11 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+     /* Read out options */
+     total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+                           BDRV_SECTOR_SIZE);
++    if (qemu_opt_get(opts, BLOCK_OPT_EXTENT_SIZE_HINT)) {
++        has_extent_size_hint = true;
++        extent_size_hint =
++            qemu_opt_get_size_del(opts, BLOCK_OPT_EXTENT_SIZE_HINT, -1);
++    }
+     nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
+     buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+     prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
+@@ -2411,6 +2448,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
+             .preallocation      = prealloc,
+             .has_nocow          = true,
+             .nocow              = nocow,
++            .has_extent_size_hint = has_extent_size_hint,
++            .extent_size_hint   = extent_size_hint,
+         },
+     };
+     return raw_co_create(&options, errp);
+@@ -2902,6 +2941,11 @@ static QemuOptsList raw_create_opts = {
+ #endif
+                     ", full)"
+         },
++        {
++            .name = BLOCK_OPT_EXTENT_SIZE_HINT,
++            .type = QEMU_OPT_SIZE,
++            .help = "Extent size hint for the image file, 0 to disable"
++        },
+         { /* end of list */ }
+     }
+ };
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index 41f13ecbed..4b23da2eb0 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -53,6 +53,7 @@
+ #define BLOCK_OPT_ADAPTER_TYPE      "adapter_type"
+ #define BLOCK_OPT_REDUNDANCY        "redundancy"
+ #define BLOCK_OPT_NOCOW             "nocow"
++#define BLOCK_OPT_EXTENT_SIZE_HINT  "extent_size_hint"
+ #define BLOCK_OPT_OBJECT_SIZE       "object_size"
+ #define BLOCK_OPT_REFCOUNT_BITS     "refcount_bits"
+ #define BLOCK_OPT_DATA_FILE         "data_file"
+diff --git a/qapi/block-core.json b/qapi/block-core.json
+index 289320902d..c7aa919fa3 100644
+--- a/qapi/block-core.json
++++ b/qapi/block-core.json
+@@ -4272,14 +4272,17 @@
+ #                   falloc (if defined CONFIG_POSIX_FALLOCATE),
+ #                   full (if defined CONFIG_POSIX))
+ # @nocow            Turn off copy-on-write (valid only on btrfs; default: off)
++# @extent-size-hint: Extent size hint to add to the image file; 0 for not
++#                    adding an extent size hint (default: 1 MB, since 5.1)
+ #
+ # Since: 2.12
+ ##
+ { 'struct': 'BlockdevCreateOptionsFile',
+-  'data': { 'filename':         'str',
+-            'size':             'size',
+-            '*preallocation':   'PreallocMode',
+-            '*nocow':           'bool' } }
++  'data': { 'filename':             'str',
++            'size':                 'size',
++            '*preallocation':       'PreallocMode',
++            '*nocow':               'bool',
++            '*extent-size-hint':    'size'} }
+ 
+ ##
+ # @BlockdevCreateOptionsGluster:
+diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
+index 9d4ed4dc9d..7a87946fa2 100644
+--- a/tests/qemu-iotests/082.out
++++ b/tests/qemu-iotests/082.out
+@@ -59,6 +59,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -82,6 +83,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -105,6 +107,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -128,6 +131,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -151,6 +155,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -174,6 +179,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -197,6 +203,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -220,6 +227,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -339,6 +347,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -362,6 +371,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -385,6 +395,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -408,6 +419,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -431,6 +443,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -454,6 +467,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -477,6 +491,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+@@ -500,6 +515,7 @@ Supported options:
+   encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
+   encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
+   encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
++  extent_size_hint=<size> - Extent size hint for the image file, 0 to disable
+   lazy_refcounts=<bool (on/off)> - Postpone refcount updates
+   nocow=<bool (on/off)>  - Turn off copy-on-write (valid only on btrfs)
+   preallocation=<str>    - Preallocation mode (allowed values: off, metadata, falloc, full)
+diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
+index ac47eaa0f5..ee6f51d08b 100755
+--- a/tests/qemu-iotests/106
++++ b/tests/qemu-iotests/106
+@@ -51,7 +51,10 @@ for create_mode in off falloc full; do
+         echo
+         echo "--- create_mode=$create_mode growth_mode=$growth_mode ---"
+ 
+-        IMGOPTS="preallocation=$create_mode" _make_test_img ${CREATION_SIZE}K
++        # Our calculation below assumes kilobytes as unit for the actual size.
++        # Disable the extent size hint because it would give us a result in
++        # megabytes.
++        IMGOPTS="preallocation=$create_mode,extent_size_hint=0" _make_test_img ${CREATION_SIZE}K
+         $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
+ 
+         expected_size=0
+@@ -98,7 +101,7 @@ for growth_mode in falloc full; do
+     # plain int.  We should use the correct type for the result, and
+     # this tests we do.
+ 
+-    _make_test_img 2G
++    _make_test_img -o "extent_size_hint=0" 2G
+     $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
+ 
+     actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
+diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
+index 55db2803ed..8a8494aeb6 100755
+--- a/tests/qemu-iotests/175
++++ b/tests/qemu-iotests/175
+@@ -89,20 +89,20 @@ min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
+ 
+ echo
+ echo "== creating image with default preallocation =="
+-_make_test_img $size | _filter_imgfmt
++_make_test_img -o extent_size_hint=0 $size | _filter_imgfmt
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
+ 
+ for mode in off full falloc; do
+     echo
+     echo "== creating image with preallocation $mode =="
+-    IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
++    IMGOPTS="preallocation=$mode,extent_size_hint=0" _make_test_img $size | _filter_imgfmt
+     stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
+ done
+ 
+ for new_size in 4096 1048576; do
+     echo
+     echo "== resize empty image with block_resize =="
+-    _make_test_img 0 | _filter_imgfmt
++    _make_test_img -o extent_size_hint=0 0 | _filter_imgfmt
+     _block_resize $TEST_IMG $new_size >/dev/null
+     stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size
+ done
+diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243
+index e563761307..104c7256c4 100755
+--- a/tests/qemu-iotests/243
++++ b/tests/qemu-iotests/243
+@@ -47,7 +47,7 @@ for mode in off metadata falloc full; do
+     echo "=== preallocation=$mode ==="
+     echo
+ 
+-    IMGOPTS="preallocation=$mode" _make_test_img 64M
++    IMGOPTS="preallocation=$mode,extent_size_hint=0" _make_test_img 64M
+ 
+     printf "File size: "
+     du -b $TEST_IMG | cut -f1
+@@ -64,7 +64,7 @@ for mode in off metadata falloc full; do
+     echo "=== External data file: preallocation=$mode ==="
+     echo
+ 
+-    IMGOPTS="data_file=$TEST_IMG.data,preallocation=$mode" _make_test_img 64M
++    IMGOPTS="data_file=$TEST_IMG.data,preallocation=$mode,extent_size_hint=0" _make_test_img 64M
+ 
+     echo -n "qcow2 file size: "
+     du -b $TEST_IMG | cut -f1
+@@ -75,7 +75,7 @@ for mode in off metadata falloc full; do
+     echo -n "qcow2 disk usage: "
+     [ $(du -B1 $TEST_IMG | cut -f1) -lt 1048576 ] && echo "low" || echo "high"
+     echo -n "data disk usage:  "
+-    [ $(du -B1 $TEST_IMG.data | cut -f1) -lt 1048576 ] && echo "low" || echo "high"
++    [ $(du -B1 $TEST_IMG.data | cut -f1) -lt 2097152 ] && echo "low" || echo "high"
+ 
+ done
+ 
+diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
+index c8e8663665..f29c1d3238 100644
+--- a/tests/qemu-iotests/common.filter
++++ b/tests/qemu-iotests/common.filter
+@@ -146,6 +146,7 @@ _filter_img_create()
+         -e "s# refcount_bits=[0-9]\\+##g" \
+         -e "s# key-secret=[a-zA-Z0-9]\\+##g" \
+         -e "s# iter-time=[0-9]\\+##g" \
++        -e "s# extent_size_hint=[0-9]\\+##g" \
+         -e "s# force_size=\\(on\\|off\\)##g"
+ }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch b/SOURCES/kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch
new file mode 100644
index 0000000..551b2eb
--- /dev/null
+++ b/SOURCES/kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch
@@ -0,0 +1,89 @@
+From 15331267d11713906361ddd767c3e04ae46d9a83 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:55:50 -0400
+Subject: [PATCH 01/14] glib-compat: add g_unix_get_passwd_entry_qemu()
+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: <20210609100615.2501448-2-marcandre.lureau@redhat.com>
+Patchwork-id: 101687
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/4] glib-compat: add g_unix_get_passwd_entry_qemu()
+Bugzilla: 1967716
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Michal Privoznik <mprivozn@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+The glib function was introduced in 2.64. It's a safer version of
+getpwnam, and also simpler to use than getpwnam_r.
+
+Currently, it's only use by the next patch in qemu-ga, which doesn't
+(well well...) need the thread safety guarantees. Since the fallback
+version is still unsafe, I would rather keep the _qemu postfix, to make
+sure it's not being misused by mistake. When/if necessary, we can
+implement a safer fallback and drop the _qemu suffix.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+*fix checkpatch warnings about newlines before/after block comments
+Signed-off-by: Michael Roth <michael.roth@amd.com>
+
+(cherry picked from commit 6d593ab451c490b0ca941c6a519894231634751e)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/glib-compat.h | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/include/glib-compat.h b/include/glib-compat.h
+index 0b0ec76299..695a96f7ea 100644
+--- a/include/glib-compat.h
++++ b/include/glib-compat.h
+@@ -30,6 +30,11 @@
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ 
+ #include <glib.h>
++#if defined(G_OS_UNIX)
++#include <glib-unix.h>
++#include <sys/types.h>
++#include <pwd.h>
++#endif
+ 
+ /*
+  * Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
+@@ -72,6 +77,29 @@
+ gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
+ #endif
+ 
++#if defined(G_OS_UNIX)
++/*
++ * Note: The fallback implementation is not MT-safe, and it returns a copy of
++ * the libc passwd (must be g_free() after use) but not the content. Because of
++ * these important differences the caller must be aware of, it's not #define for
++ * GLib API substitution.
++ */
++static inline struct passwd *
++g_unix_get_passwd_entry_qemu(const gchar *user_name, GError **error)
++{
++#if GLIB_CHECK_VERSION(2, 64, 0)
++    return g_unix_get_passwd_entry(user_name, error);
++#else
++    struct passwd *p = getpwnam(user_name);
++    if (!p) {
++        g_set_error_literal(error, G_UNIX_ERROR, 0, g_strerror(errno));
++        return NULL;
++    }
++    return (struct passwd *)g_memdup(p, sizeof(*p));
++#endif
++}
++#endif /* G_OS_UNIX */
++
+ #pragma GCC diagnostic pop
+ 
+ #endif
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch b/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch
new file mode 100644
index 0000000..650555c
--- /dev/null
+++ b/SOURCES/kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch
@@ -0,0 +1,80 @@
+From dad4f9beaa3fd1eec1e0dd46c3d5cd2f444c0f48 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 13 Apr 2021 20:05:51 -0400
+Subject: [PATCH 1/7] hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210413200551.3825495-2-jmaloy@redhat.com>
+Patchwork-id: 101471
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
+Bugzilla: 1925430
+RH-Acked-by: Andrew Jones <drjones@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: Philippe Mathieu-Daudé <f4bug@amsat.org>
+
+Per the ARM Generic Interrupt Controller Architecture specification
+(document "ARM IHI 0048B.b (ID072613)"), the SGIINTID field is 4 bit,
+not 10:
+
+  - 4.3 Distributor register descriptions
+  - 4.3.15 Software Generated Interrupt Register, GICD_SG
+
+    - Table 4-21 GICD_SGIR bit assignments
+
+    The Interrupt ID of the SGI to forward to the specified CPU
+    interfaces. The value of this field is the Interrupt ID, in
+    the range 0-15, for example a value of 0b0011 specifies
+    Interrupt ID 3.
+
+Correct the irq mask to fix an undefined behavior (which eventually
+lead to a heap-buffer-overflow, see [Buglink]):
+
+   $ echo 'writel 0x8000f00 0xff4affb0' | qemu-system-aarch64 -M virt,accel=qtest -qtest stdio
+   [I 1612088147.116987] OPENED
+  [R +0.278293] writel 0x8000f00 0xff4affb0
+  ../hw/intc/arm_gic.c:1498:13: runtime error: index 944 out of bounds for type 'uint8_t [16][8]'
+  SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../hw/intc/arm_gic.c:1498:13
+
+This fixes a security issue when running with KVM on Arm with
+kernel-irqchip=off. (The default is kernel-irqchip=on, which is
+unaffected, and which is also the correct choice for performance.)
+
+Cc: qemu-stable@nongnu.org
+Fixes: CVE-2021-20221
+Fixes: 9ee6e8bb853 ("ARMv7 support.")
+Buglink: https://bugs.launchpad.net/qemu/+bug/1913916
+Buglink: https://bugs.launchpad.net/qemu/+bug/1913917
+Reported-by: Alexander Bulekov <alxndr@bu.edu>
+Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
+Message-id: 20210131103401.217160-1-f4bug@amsat.org
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+
+(cherry picked from commit edfe2eb4360cde4ed5d95bda7777edcb3510f76a)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/intc/arm_gic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
+index 1d7da7baa2..df355f4d11 100644
+--- a/hw/intc/arm_gic.c
++++ b/hw/intc/arm_gic.c
+@@ -1455,7 +1455,7 @@ static void gic_dist_writel(void *opaque, hwaddr offset,
+         int target_cpu;
+ 
+         cpu = gic_get_current_cpu(s);
+-        irq = value & 0x3ff;
++        irq = value & 0xf;
+         switch ((value >> 24) & 3) {
+         case 0:
+             mask = (value >> 16) & ALL_CPU_MASK;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-i386-Add-the-support-for-AMD-EPYC-3rd-generation-pro.patch b/SOURCES/kvm-i386-Add-the-support-for-AMD-EPYC-3rd-generation-pro.patch
new file mode 100644
index 0000000..5c335f8
--- /dev/null
+++ b/SOURCES/kvm-i386-Add-the-support-for-AMD-EPYC-3rd-generation-pro.patch
@@ -0,0 +1,213 @@
+From 4daa8dca77edec191dfe0ae4a0a9fc70f8f63607 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 24 Feb 2021 11:30:37 -0500
+Subject: [PATCH 4/4] i386: Add the support for AMD EPYC 3rd generation
+ processors
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20210224113037.15599-5-dgilbert@redhat.com>
+Patchwork-id: 101202
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 4/4] i386: Add the support for AMD EPYC 3rd generation processors
+Bugzilla: 1790620
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Babu Moger <babu.moger@amd.com>
+
+Adds the support for AMD 3rd generation processors. The model
+display for the new processor will be EPYC-Milan.
+
+Adds the following new feature bits on top of the feature bits from
+the first and second generation EPYC models.
+
+pcid          : Process context identifiers support
+ibrs          : Indirect Branch Restricted Speculation
+ssbd          : Speculative Store Bypass Disable
+erms          : Enhanced REP MOVSB/STOSB support
+fsrm          : Fast Short REP MOVSB support
+invpcid       : Invalidate processor context ID
+pku           : Protection keys support
+svme-addr-chk : SVM instructions address check for #GP handling
+
+Depends on the following kernel commits:
+14c2bf81fcd2 ("KVM: SVM: Fix #GP handling for doubly-nested virtualization")
+3b9c723ed7cf ("KVM: SVM: Add support for SVM instruction address check change")
+4aa2691dcbd3 ("8ce1c461188799d863398dd2865d KVM: x86: Factor out x86 instruction emulation with decoding")
+4407a797e941 ("KVM: SVM: Enable INVPCID feature on AMD")
+9715092f8d7e ("KVM: X86: Move handling of INVPCID types to x86")
+3f3393b3ce38 ("KVM: X86: Rename and move the function vmx_handle_memory_failure to x86.c")
+830bd71f2c06 ("KVM: SVM: Remove set_cr_intercept, clr_cr_intercept and is_cr_intercept")
+4c44e8d6c193 ("KVM: SVM: Add new intercept word in vmcb_control_area")
+c62e2e94b9d4 ("KVM: SVM: Modify 64 bit intercept field to two 32 bit vectors")
+9780d51dc2af ("KVM: SVM: Modify intercept_exceptions to generic intercepts")
+30abaa88382c ("KVM: SVM: Change intercept_dr to generic intercepts")
+03bfeeb988a9 ("KVM: SVM: Change intercept_cr to generic intercepts")
+c45ad7229d13 ("KVM: SVM: Introduce vmcb_(set_intercept/clr_intercept/_is_intercept)")
+a90c1ed9f11d ("(pcid) KVM: nSVM: Remove unused field")
+fa44b82eb831 ("KVM: x86: Move MPK feature detection to common code")
+38f3e775e9c2 ("x86/Kconfig: Update config and kernel doc for MPK feature on AMD")
+37486135d3a7 ("KVM: x86: Fix pkru save/restore when guest CR4.PKE=0, move it to x86.c")
+
+Signed-off-by: Babu Moger <babu.moger@amd.com>
+Message-Id: <161290460478.11352.8933244555799318236.stgit@bmoger-ubuntu>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 623972ceae091b31331ae4a1dc94fe5cbb891937)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 107 +++++++++++++++++++++++++++++++++++++++++++++-
+ target/i386/cpu.h |   4 ++
+ 2 files changed, 110 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 7227c803c3..d5b0d4b7f0 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1133,7 +1133,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             "clzero", NULL, "xsaveerptr", NULL,
+             NULL, NULL, NULL, NULL,
+             NULL, "wbnoinvd", NULL, NULL,
+-            "ibpb", NULL, NULL, "amd-stibp",
++            "ibpb", NULL, "ibrs", "amd-stibp",
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL, NULL,
+             "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
+@@ -1853,6 +1853,56 @@ static CPUCaches epyc_rome_cache_info = {
+     },
+ };
+ 
++static CPUCaches epyc_milan_cache_info = {
++    .l1d_cache = &(CPUCacheInfo) {
++        .type = DATA_CACHE,
++        .level = 1,
++        .size = 32 * KiB,
++        .line_size = 64,
++        .associativity = 8,
++        .partitions = 1,
++        .sets = 64,
++        .lines_per_tag = 1,
++        .self_init = 1,
++        .no_invd_sharing = true,
++    },
++    .l1i_cache = &(CPUCacheInfo) {
++        .type = INSTRUCTION_CACHE,
++        .level = 1,
++        .size = 32 * KiB,
++        .line_size = 64,
++        .associativity = 8,
++        .partitions = 1,
++        .sets = 64,
++        .lines_per_tag = 1,
++        .self_init = 1,
++        .no_invd_sharing = true,
++    },
++    .l2_cache = &(CPUCacheInfo) {
++        .type = UNIFIED_CACHE,
++        .level = 2,
++        .size = 512 * KiB,
++        .line_size = 64,
++        .associativity = 8,
++        .partitions = 1,
++        .sets = 1024,
++        .lines_per_tag = 1,
++    },
++    .l3_cache = &(CPUCacheInfo) {
++        .type = UNIFIED_CACHE,
++        .level = 3,
++        .size = 32 * MiB,
++        .line_size = 64,
++        .associativity = 16,
++        .partitions = 1,
++        .sets = 32768,
++        .lines_per_tag = 1,
++        .self_init = true,
++        .inclusive = true,
++        .complex_indexing = true,
++    },
++};
++
+ /* The following VMX features are not supported by KVM and are left out in the
+  * CPU definitions:
+  *
+@@ -4124,6 +4174,61 @@ static X86CPUDefinition builtin_x86_defs[] = {
+         .model_id = "AMD EPYC-Rome Processor",
+         .cache_info = &epyc_rome_cache_info,
+     },
++    {
++        .name = "EPYC-Milan",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_AMD,
++        .family = 25,
++        .model = 1,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
++            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
++            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
++            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
++            CPUID_VME | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
++            CPUID_EXT_XSAVE | CPUID_EXT_AES |  CPUID_EXT_POPCNT |
++            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
++            CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++            CPUID_EXT_PCID,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
++            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
++            CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
++            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
++            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
++            CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE,
++        .features[FEAT_8000_0008_EBX] =
++            CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR |
++            CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB |
++            CPUID_8000_0008_EBX_IBRS | CPUID_8000_0008_EBX_STIBP |
++            CPUID_8000_0008_EBX_AMD_SSBD,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
++            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
++            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
++            CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_ERMS |
++            CPUID_7_0_EBX_INVPCID,
++        .features[FEAT_7_0_ECX] =
++            CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_PKU,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_FSRM,
++        .features[FEAT_XSAVE] =
++            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
++            CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES,
++        .features[FEAT_6_EAX] =
++            CPUID_6_EAX_ARAT,
++        .features[FEAT_SVM] =
++            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE | CPUID_SVM_SVME_ADDR_CHK,
++        .xlevel = 0x8000001E,
++        .model_id = "AMD EPYC-Milan Processor",
++        .cache_info = &epyc_milan_cache_info,
++    },
+ };
+ 
+ /* KVM-specific features that are automatically added/removed
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index e1b67910c2..7a3aa40201 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -800,8 +800,12 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_8000_0008_EBX_WBNOINVD    (1U << 9)
+ /* Indirect Branch Prediction Barrier */
+ #define CPUID_8000_0008_EBX_IBPB        (1U << 12)
++/* Indirect Branch Restricted Speculation */
++#define CPUID_8000_0008_EBX_IBRS        (1U << 14)
+ /* Single Thread Indirect Branch Predictors */
+ #define CPUID_8000_0008_EBX_STIBP       (1U << 15)
++/* Speculative Store Bypass Disable */
++#define CPUID_8000_0008_EBX_AMD_SSBD    (1U << 24)
+ 
+ #define CPUID_XSAVE_XSAVEOPT   (1U << 0)
+ #define CPUID_XSAVE_XSAVEC     (1U << 1)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-ide-atapi-check-logical-block-address-and-read-size-.patch b/SOURCES/kvm-ide-atapi-check-logical-block-address-and-read-size-.patch
new file mode 100644
index 0000000..706bd8b
--- /dev/null
+++ b/SOURCES/kvm-ide-atapi-check-logical-block-address-and-read-size-.patch
@@ -0,0 +1,120 @@
+From 0453588f95294ed5ce912cb8b810a322bf9d91e0 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Thu, 25 Feb 2021 19:43:02 -0500
+Subject: [PATCH] ide: atapi: check logical block address and read size
+ (CVE-2020-29443)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210225194302.3137699-2-jmaloy@redhat.com>
+Patchwork-id: 101208
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH v2 1/1] ide: atapi: check logical block address and read size (CVE-2020-29443)
+Bugzilla: 1917451
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
+RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+
+From: Prasad J Pandit <pjp@fedoraproject.org>
+
+While processing ATAPI cmd_read/cmd_read_cd commands,
+Logical Block Address (LBA) maybe invalid OR closer to the last block,
+leading to an OOB access issues. Add range check to avoid it.
+
+Fixes: CVE-2020-29443
+Reported-by: Wenxiang Qian <leonwxqian@gmail.com>
+Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-Id: <20210118115130.457044-1-ppandit@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+(cherry picked from commit b8d7f1bc59276fec85e4d09f1567613a3e14d31e)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/ide/atapi.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
+index 17a9d635d8..d064935c8d 100644
+--- a/hw/ide/atapi.c
++++ b/hw/ide/atapi.c
+@@ -320,6 +320,8 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
+ static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
+                                    int sector_size)
+ {
++    assert(0 <= lba && lba < (s->nb_sectors >> 2));
++
+     s->lba = lba;
+     s->packet_transfer_size = nb_sectors * sector_size;
+     s->elementary_transfer_size = 0;
+@@ -418,6 +420,8 @@ eot:
+ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
+                                    int sector_size)
+ {
++    assert(0 <= lba && lba < (s->nb_sectors >> 2));
++
+     s->lba = lba;
+     s->packet_transfer_size = nb_sectors * sector_size;
+     s->io_buffer_size = 0;
+@@ -971,35 +975,49 @@ static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf)
+ 
+ static void cmd_read(IDEState *s, uint8_t* buf)
+ {
+-    int nb_sectors, lba;
++    unsigned int nb_sectors, lba;
++
++    /* Total logical sectors of ATAPI_SECTOR_SIZE(=2048) bytes */
++    uint64_t total_sectors = s->nb_sectors >> 2;
+ 
+     if (buf[0] == GPCMD_READ_10) {
+         nb_sectors = lduw_be_p(buf + 7);
+     } else {
+         nb_sectors = ldl_be_p(buf + 6);
+     }
+-
+-    lba = ldl_be_p(buf + 2);
+     if (nb_sectors == 0) {
+         ide_atapi_cmd_ok(s);
+         return;
+     }
+ 
++    lba = ldl_be_p(buf + 2);
++    if (lba >= total_sectors || lba + nb_sectors - 1 >= total_sectors) {
++        ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
++        return;
++    }
++
+     ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+ }
+ 
+ static void cmd_read_cd(IDEState *s, uint8_t* buf)
+ {
+-    int nb_sectors, lba, transfer_request;
++    unsigned int nb_sectors, lba, transfer_request;
+ 
+-    nb_sectors = (buf[6] << 16) | (buf[7] << 8) | buf[8];
+-    lba = ldl_be_p(buf + 2);
++    /* Total logical sectors of ATAPI_SECTOR_SIZE(=2048) bytes */
++    uint64_t total_sectors = s->nb_sectors >> 2;
+ 
++    nb_sectors = (buf[6] << 16) | (buf[7] << 8) | buf[8];
+     if (nb_sectors == 0) {
+         ide_atapi_cmd_ok(s);
+         return;
+     }
+ 
++    lba = ldl_be_p(buf + 2);
++    if (lba >= total_sectors || lba + nb_sectors - 1 >= total_sectors) {
++        ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
++        return;
++    }
++
+     transfer_request = buf[9] & 0xf8;
+     if (transfer_request == 0x00) {
+         /* nothing */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch b/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch
new file mode 100644
index 0000000..902af6c
--- /dev/null
+++ b/SOURCES/kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch
@@ -0,0 +1,53 @@
+From e2cafb929acb74377754cb688419575b139b922a Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:47 -0400
+Subject: [PATCH 9/9] lan9118: switch to use qemu_receive_packet() for loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-10-jmaloy@redhat.com>
+Patchwork-id: 101790
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 9/9] lan9118: switch to use qemu_receive_packet() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alexander Bulekov <alxndr@bu.edu>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
+Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 37cee01784ff0df13e5209517e1b3594a5e792d1)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/lan9118.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
+index ed551f2178..7bb4633f0f 100644
+--- a/hw/net/lan9118.c
++++ b/hw/net/lan9118.c
+@@ -667,7 +667,7 @@ static void do_tx_packet(lan9118_state *s)
+     /* FIXME: Honor TX disable, and allow queueing of packets.  */
+     if (s->phy_control & 0x4000)  {
+         /* This assumes the receive routine doesn't touch the VLANClient.  */
+-        lan9118_receive(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
++        qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
+     } else {
+         qemu_send_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
+     }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch b/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch
new file mode 100644
index 0000000..71a2eac
--- /dev/null
+++ b/SOURCES/kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch
@@ -0,0 +1,47 @@
+From 2687e0348e3e4d377b4f5356e46948dc2b371b6d Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Wed, 21 Apr 2021 22:30:02 -0400
+Subject: [PATCH 3/7] libqos: pci-pc: use 32-bit write for EJ register
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210421223006.19650-3-jmaloy@redhat.com>
+Patchwork-id: 101484
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 2/6] libqos: pci-pc: use 32-bit write for EJ register
+Bugzilla: 1842478
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+The memory region ops have min_access_size == 4 so obey it.
+
+Tested-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+(cherry picked from commit 4b7c06837ae0b1ff56473202a42e7e386f53d6db)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/libqos/pci-pc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
+index 0bc591d1da..3bb2eb3ba8 100644
+--- a/tests/libqos/pci-pc.c
++++ b/tests/libqos/pci-pc.c
+@@ -186,7 +186,7 @@ void qpci_unplug_acpi_device_test(QTestState *qts, const char *id, uint8_t slot)
+     g_assert(!qdict_haskey(response, "error"));
+     qobject_unref(response);
+ 
+-    qtest_outb(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);
++    qtest_outl(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);
+ 
+     qtest_qmp_eventwait(qts, "DEVICE_DELETED");
+ }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch b/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch
new file mode 100644
index 0000000..424a60c
--- /dev/null
+++ b/SOURCES/kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch
@@ -0,0 +1,48 @@
+From 6320b4e76965b1cf64da4307f4d313fe6b2aa971 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Wed, 21 Apr 2021 22:30:01 -0400
+Subject: [PATCH 2/7] libqos: usb-hcd-ehci: use 32-bit write for config
+ register
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210421223006.19650-2-jmaloy@redhat.com>
+Patchwork-id: 101478
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 1/6] libqos: usb-hcd-ehci: use 32-bit write for config register
+Bugzilla: 1842478
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+The memory region ops have min_access_size == 4 so obey it.
+
+Tested-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+(cherry picked from commit 89ed83d8b23c11d250c290593cad3ca839d5b053)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tests/usb-hcd-ehci-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/usb-hcd-ehci-test.c b/tests/usb-hcd-ehci-test.c
+index 5251d539e9..c51e8bb223 100644
+--- a/tests/usb-hcd-ehci-test.c
++++ b/tests/usb-hcd-ehci-test.c
+@@ -96,7 +96,7 @@ static void pci_ehci_port_1(void)
+ static void pci_ehci_config(void)
+ {
+     /* hands over all ports from companion uhci to ehci */
+-    qpci_io_writew(ehci1.dev, ehci1.bar, 0x60, 1);
++    qpci_io_writel(ehci1.dev, ehci1.bar, 0x60, 1);
+ }
+ 
+ static void pci_uhci_port_2(void)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch b/SOURCES/kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch
new file mode 100644
index 0000000..d9c81cf
--- /dev/null
+++ b/SOURCES/kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch
@@ -0,0 +1,43 @@
+From f844ca939adb619cce8426e104b0039a7eba70a6 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 11 May 2021 11:24:04 -0400
+Subject: [PATCH 1/5] linux-headers: Add VFIO_CCW_REQ_IRQ_INDEX
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20210511112405.297037-2-thuth@redhat.com>
+Patchwork-id: 101537
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] linux-headers: Add VFIO_CCW_REQ_IRQ_INDEX
+Bugzilla: 1940450
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940450
+Upstream-status: N/A
+
+This is based on upstream commit b3c818a47f ("Update linux headers to
+5.11-rc2"), but has been reduced to the single hunk that is required
+for the next patch (there were too many unrelated conflicts in the other
+files for doing full backport of the original upstream commit).
+
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ linux-headers/linux/vfio.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
+index f660bd7bac..9c8810bef4 100644
+--- a/linux-headers/linux/vfio.h
++++ b/linux-headers/linux/vfio.h
+@@ -580,6 +580,7 @@ enum {
+ enum {
+ 	VFIO_CCW_IO_IRQ_INDEX,
+ 	VFIO_CCW_CRW_IRQ_INDEX,
++	VFIO_CCW_REQ_IRQ_INDEX,
+ 	VFIO_CCW_NUM_IRQS
+ };
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch b/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch
new file mode 100644
index 0000000..f81c86f
--- /dev/null
+++ b/SOURCES/kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch
@@ -0,0 +1,104 @@
+From 13f4ebe4708f4f4dc20d710e475a42d520459860 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Wed, 21 Apr 2021 22:30:03 -0400
+Subject: [PATCH 4/7] memory: Revert "memory: accept mismatching sizes in
+ memory_region_access_valid"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210421223006.19650-4-jmaloy@redhat.com>
+Patchwork-id: 101480
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 3/6] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"
+Bugzilla: 1842478
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: "Michael S. Tsirkin" <mst@redhat.com>
+
+Memory API documentation documents valid .min_access_size and .max_access_size
+fields and explains that any access outside these boundaries is blocked.
+
+This is what devices seem to assume.
+
+However this is not what the implementation does: it simply
+ignores the boundaries unless there's an "accepts" callback.
+
+Naturally, this breaks a bunch of devices.
+
+Revert to the documented behaviour.
+
+Devices that want to allow any access can just drop the valid field,
+or add the impl field to have accesses converted to appropriate
+length.
+
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Richard Henderson <rth@twiddle.net>
+Fixes: CVE-2020-13754
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1842363
+Fixes: a014ed07bd5a ("memory: accept mismatching sizes in memory_region_access_valid")
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20200610134731.1514409-1-mst@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+(cherry picked from commit 5d971f9e672507210e77d020d89e0e89165c8fc9)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ memory.c | 29 +++++++++--------------------
+ 1 file changed, 9 insertions(+), 20 deletions(-)
+
+diff --git a/memory.c b/memory.c
+index 5a4a80842d..0cfcb72a5a 100644
+--- a/memory.c
++++ b/memory.c
+@@ -1351,35 +1351,24 @@ bool memory_region_access_valid(MemoryRegion *mr,
+                                 bool is_write,
+                                 MemTxAttrs attrs)
+ {
+-    int access_size_min, access_size_max;
+-    int access_size, i;
+-
+-    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
++    if (mr->ops->valid.accepts
++        && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
+         return false;
+     }
+ 
+-    if (!mr->ops->valid.accepts) {
+-        return true;
+-    }
+-
+-    access_size_min = mr->ops->valid.min_access_size;
+-    if (!mr->ops->valid.min_access_size) {
+-        access_size_min = 1;
++    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
++        return false;
+     }
+ 
+-    access_size_max = mr->ops->valid.max_access_size;
++    /* Treat zero as compatibility all valid */
+     if (!mr->ops->valid.max_access_size) {
+-        access_size_max = 4;
++        return true;
+     }
+ 
+-    access_size = MAX(MIN(size, access_size_max), access_size_min);
+-    for (i = 0; i < size; i += access_size) {
+-        if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
+-                                    is_write, attrs)) {
+-            return false;
+-        }
++    if (size > mr->ops->valid.max_access_size
++        || size < mr->ops->valid.min_access_size) {
++        return false;
+     }
+-
+     return true;
+ }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch b/SOURCES/kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch
new file mode 100644
index 0000000..654a64f
--- /dev/null
+++ b/SOURCES/kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch
@@ -0,0 +1,301 @@
+From 512c7e92808dff66779f7421f1c17a081f18d7e6 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:46 -0400
+Subject: [PATCH 13/14] net: check if the file descriptor is valid before using
+ it
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20210726102337.6359-2-lvivier@redhat.com>
+Patchwork-id: 101924
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] net: check if the file descriptor is valid before using it
+Bugzilla: 1982134
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1982134
+BRANCH: rhel-8.5.0
+UPSTREAM: Merged
+BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=38380653
+
+qemu_set_nonblock() checks that the file descriptor can be used and, if
+not, crashes QEMU. An assert() is used for that. The use of assert() is
+used to detect programming error and the coredump will allow to debug
+the problem.
+
+But in the case of the tap device, this assert() can be triggered by
+a misconfiguration by the user. At startup, it's not a real problem, but it
+can also happen during the hot-plug of a new device, and here it's a
+problem because we can crash a perfectly healthy system.
+
+For instance:
+ # ip link add link virbr0 name macvtap0 type macvtap mode bridge
+ # ip link set macvtap0 up
+ # TAP=/dev/tap$(ip -o link show macvtap0 | cut -d: -f1)
+ # qemu-system-x86_64 -machine q35 -device pcie-root-port,id=pcie-root-port-0 -monitor stdio 9<> $TAP
+ (qemu) netdev_add type=tap,id=hostnet0,vhost=on,fd=9
+ (qemu) device_add driver=virtio-net-pci,netdev=hostnet0,id=net0,bus=pcie-root-port-0
+ (qemu) device_del net0
+ (qemu) netdev_del hostnet0
+ (qemu) netdev_add type=tap,id=hostnet1,vhost=on,fd=9
+ qemu-system-x86_64: .../util/oslib-posix.c:247: qemu_set_nonblock: Assertion `f != -1' failed.
+ Aborted (core dumped)
+
+To avoid that, add a function, qemu_try_set_nonblock(), that allows to report the
+problem without crashing.
+
+In the same way, we also update the function for vhostfd in net_init_tap_one() and
+for fd in net_init_socket() (both descriptors are provided by the user and can
+be wrong).
+
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+(cherry picked from commit 894022e616016fe81745753f14adfbd680a1c7ee)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ include/qemu/sockets.h |  1 +
+ net/socket.c           |  9 +++++--
+ net/tap.c              | 25 +++++++++++++++---
+ util/oslib-posix.c     | 26 +++++++++++++------
+ util/oslib-win32.c     | 57 ++++++++++++++++++++++++------------------
+ 5 files changed, 79 insertions(+), 39 deletions(-)
+
+diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
+index 57cd049d6e..7d1f813576 100644
+--- a/include/qemu/sockets.h
++++ b/include/qemu/sockets.h
+@@ -18,6 +18,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+ int socket_set_cork(int fd, int v);
+ int socket_set_nodelay(int fd);
+ void qemu_set_block(int fd);
++int qemu_try_set_nonblock(int fd);
+ void qemu_set_nonblock(int fd);
+ int socket_set_fast_reuse(int fd);
+ 
+diff --git a/net/socket.c b/net/socket.c
+index c92354049b..2d21fddd9c 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -725,13 +725,18 @@ int net_init_socket(const Netdev *netdev, const char *name,
+     }
+ 
+     if (sock->has_fd) {
+-        int fd;
++        int fd, ret;
+ 
+         fd = monitor_fd_param(cur_mon, sock->fd, errp);
+         if (fd == -1) {
+             return -1;
+         }
+-        qemu_set_nonblock(fd);
++        ret = qemu_try_set_nonblock(fd);
++        if (ret < 0) {
++            error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
++                             name, fd);
++            return -1;
++        }
+         if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
+                                 errp)) {
+             return -1;
+diff --git a/net/tap.c b/net/tap.c
+index 6207f61f84..41a20102fd 100644
+--- a/net/tap.c
++++ b/net/tap.c
+@@ -689,6 +689,8 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
+         }
+ 
+         if (vhostfdname) {
++            int ret;
++
+             vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);
+             if (vhostfd == -1) {
+                 if (tap->has_vhostforce && tap->vhostforce) {
+@@ -698,7 +700,12 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
+                 }
+                 return;
+             }
+-            qemu_set_nonblock(vhostfd);
++            ret = qemu_try_set_nonblock(vhostfd);
++            if (ret < 0) {
++                error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
++                                 name, fd);
++                return;
++            }
+         } else {
+             vhostfd = open("/dev/vhost-net", O_RDWR);
+             if (vhostfd < 0) {
+@@ -766,6 +773,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
+     Error *err = NULL;
+     const char *vhostfdname;
+     char ifname[128];
++    int ret = 0;
+ 
+     assert(netdev->type == NET_CLIENT_DRIVER_TAP);
+     tap = &netdev->u.tap;
+@@ -795,7 +803,12 @@ int net_init_tap(const Netdev *netdev, const char *name,
+             return -1;
+         }
+ 
+-        qemu_set_nonblock(fd);
++        ret = qemu_try_set_nonblock(fd);
++        if (ret < 0) {
++            error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
++                             name, fd);
++            return -1;
++        }
+ 
+         vnet_hdr = tap_probe_vnet_hdr(fd);
+ 
+@@ -810,7 +823,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
+         char **fds;
+         char **vhost_fds;
+         int nfds = 0, nvhosts = 0;
+-        int ret = 0;
+ 
+         if (tap->has_ifname || tap->has_script || tap->has_downscript ||
+             tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
+@@ -843,7 +855,12 @@ int net_init_tap(const Netdev *netdev, const char *name,
+                 goto free_fail;
+             }
+ 
+-            qemu_set_nonblock(fd);
++            ret = qemu_try_set_nonblock(fd);
++            if (ret < 0) {
++                error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
++                                 name, fd);
++                goto free_fail;
++            }
+ 
+             if (i == 0) {
+                 vnet_hdr = tap_probe_vnet_hdr(fd);
+diff --git a/util/oslib-posix.c b/util/oslib-posix.c
+index 8f88e4dbe1..db70416dbb 100644
+--- a/util/oslib-posix.c
++++ b/util/oslib-posix.c
+@@ -240,25 +240,35 @@ void qemu_set_block(int fd)
+     assert(f != -1);
+ }
+ 
+-void qemu_set_nonblock(int fd)
++int qemu_try_set_nonblock(int fd)
+ {
+     int f;
+     f = fcntl(fd, F_GETFL);
+-    assert(f != -1);
+-    f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
+-#ifdef __OpenBSD__
+     if (f == -1) {
++        return -errno;
++    }
++    if (fcntl(fd, F_SETFL, f | O_NONBLOCK) == -1) {
++#ifdef __OpenBSD__
+         /*
+          * Previous to OpenBSD 6.3, fcntl(F_SETFL) is not permitted on
+          * memory devices and sets errno to ENODEV.
+          * It's OK if we fail to set O_NONBLOCK on devices like /dev/null,
+          * because they will never block anyway.
+          */
+-        assert(errno == ENODEV);
+-    }
+-#else
+-    assert(f != -1);
++        if (errno == ENODEV) {
++            return 0;
++        }
+ #endif
++        return -errno;
++    }
++    return 0;
++}
++
++void qemu_set_nonblock(int fd)
++{
++    int f;
++    f = qemu_try_set_nonblock(fd);
++    assert(f == 0);
+ }
+ 
+ int socket_set_fast_reuse(int fd)
+diff --git a/util/oslib-win32.c b/util/oslib-win32.c
+index 3b49d27297..7eedbe5859 100644
+--- a/util/oslib-win32.c
++++ b/util/oslib-win32.c
+@@ -132,31 +132,6 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
+ }
+ #endif /* CONFIG_LOCALTIME_R */
+ 
+-void qemu_set_block(int fd)
+-{
+-    unsigned long opt = 0;
+-    WSAEventSelect(fd, NULL, 0);
+-    ioctlsocket(fd, FIONBIO, &opt);
+-}
+-
+-void qemu_set_nonblock(int fd)
+-{
+-    unsigned long opt = 1;
+-    ioctlsocket(fd, FIONBIO, &opt);
+-    qemu_fd_register(fd);
+-}
+-
+-int socket_set_fast_reuse(int fd)
+-{
+-    /* Enabling the reuse of an endpoint that was used by a socket still in
+-     * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
+-     * fast reuse is the default and SO_REUSEADDR does strange things. So we
+-     * don't have to do anything here. More info can be found at:
+-     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
+-    return 0;
+-}
+-
+-
+ static int socket_error(void)
+ {
+     switch (WSAGetLastError()) {
+@@ -233,6 +208,38 @@ static int socket_error(void)
+     }
+ }
+ 
++void qemu_set_block(int fd)
++{
++    unsigned long opt = 0;
++    WSAEventSelect(fd, NULL, 0);
++    ioctlsocket(fd, FIONBIO, &opt);
++}
++
++int qemu_try_set_nonblock(int fd)
++{
++    unsigned long opt = 1;
++    if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) {
++        return -socket_error();
++    }
++    qemu_fd_register(fd);
++    return 0;
++}
++
++void qemu_set_nonblock(int fd)
++{
++    (void)qemu_try_set_nonblock(fd);
++}
++
++int socket_set_fast_reuse(int fd)
++{
++    /* Enabling the reuse of an endpoint that was used by a socket still in
++     * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
++     * fast reuse is the default and SO_REUSEADDR does strange things. So we
++     * don't have to do anything here. More info can be found at:
++     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
++    return 0;
++}
++
+ int inet_aton(const char *cp, struct in_addr *ia)
+ {
+     uint32_t addr = inet_addr(cp);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch b/SOURCES/kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch
new file mode 100644
index 0000000..8718c71
--- /dev/null
+++ b/SOURCES/kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch
@@ -0,0 +1,221 @@
+From 3475ea6598896edb689ca8ba6fb81781e2517b6f Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:49 -0400
+Subject: [PATCH 14/14] net: detect errors from probing vnet hdr flag for TAP
+ devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20210726102337.6359-3-lvivier@redhat.com>
+Patchwork-id: 101923
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] net: detect errors from probing vnet hdr flag for TAP devices
+Bugzilla: 1982134
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+From: "Daniel P. Berrange" <berrange@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1982134
+BRANCH: rhel-8.5.0
+UPSTREAM: Merged
+BREW: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=38380653
+
+When QEMU sets up a tap based network device backend, it mostly ignores errors
+reported from various ioctl() calls it makes, assuming the TAP file descriptor
+is valid. This assumption can easily be violated when the user is passing in a
+pre-opened file descriptor. At best, the ioctls may fail with a -EBADF, but if
+the user passes in a bogus FD number that happens to clash with a FD number that
+QEMU has opened internally for another reason, a wide variety of errnos may
+result, as the TUNGETIFF ioctl number may map to a completely different command
+on a different type of file.
+
+By ignoring all these errors, QEMU sets up a zombie network backend that will
+never pass any data. Even worse, when QEMU shuts down, or that network backend
+is hot-removed, it will close this bogus file descriptor, which could belong to
+another QEMU device backend.
+
+There's no obvious guaranteed reliable way to detect that a FD genuinely is a
+TAP device, as opposed to a UNIX socket, or pipe, or something else. Checking
+the errno from probing vnet hdr flag though, does catch the big common cases.
+ie calling TUNGETIFF will return EBADF for an invalid FD, and ENOTTY when FD is
+a UNIX socket, or pipe which catches accidental collisions with FDs used for
+stdio, or monitor socket.
+
+Previously the example below where bogus fd 9 collides with the FD used for the
+chardev saw:
+
+$ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \
+  -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \
+  -monitor stdio -vnc :0
+qemu-system-x86_64: -netdev tap,id=hostnet0,fd=9: TUNGETIFF ioctl() failed: Inappropriate ioctl for device
+TUNSETOFFLOAD ioctl() failed: Bad address
+QEMU 2.9.1 monitor - type 'help' for more information
+(qemu) Warning: netdev hostnet0 has no peer
+
+which gives a running QEMU with a zombie network backend.
+
+With this change applied we get an error message and QEMU immediately exits
+before carrying on and making a bigger disaster:
+
+$ ./x86_64-softmmu/qemu-system-x86_64 -netdev tap,id=hostnet0,fd=9 \
+  -chardev socket,id=charchannel0,path=/tmp/qga,server,nowait \
+  -monitor stdio -vnc :0
+qemu-system-x86_64: -netdev tap,id=hostnet0,vhost=on,fd=9: Unable to query TUNGETIFF on FD 9: Inappropriate ioctl for device
+
+Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
+Tested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: 20171027085548.3472-1-berrange@redhat.com
+[lv: to simplify, don't check on EINVAL with TUNGETIFF as it exists since v2.6.27]
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+(cherry picked from commit e7b347d0bf640adb1c998d317eaf44d2d7cbd973)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ net/tap-bsd.c     |  2 +-
+ net/tap-linux.c   |  8 +++++---
+ net/tap-solaris.c |  2 +-
+ net/tap-stub.c    |  2 +-
+ net/tap.c         | 25 ++++++++++++++++++++-----
+ net/tap_int.h     |  2 +-
+ 6 files changed, 29 insertions(+), 12 deletions(-)
+
+diff --git a/net/tap-bsd.c b/net/tap-bsd.c
+index a5c3707f80..77aaf674b1 100644
+--- a/net/tap-bsd.c
++++ b/net/tap-bsd.c
+@@ -211,7 +211,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
+ {
+ }
+ 
+-int tap_probe_vnet_hdr(int fd)
++int tap_probe_vnet_hdr(int fd, Error **errp)
+ {
+     return 0;
+ }
+diff --git a/net/tap-linux.c b/net/tap-linux.c
+index e0dd442ee3..b0635e9e32 100644
+--- a/net/tap-linux.c
++++ b/net/tap-linux.c
+@@ -147,13 +147,15 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
+     }
+ }
+ 
+-int tap_probe_vnet_hdr(int fd)
++int tap_probe_vnet_hdr(int fd, Error **errp)
+ {
+     struct ifreq ifr;
+ 
+     if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
+-        error_report("TUNGETIFF ioctl() failed: %s", strerror(errno));
+-        return 0;
++        /* TUNGETIFF is available since kernel v2.6.27 */
++        error_setg_errno(errp, errno,
++                         "Unable to query TUNGETIFF on FD %d", fd);
++        return -1;
+     }
+ 
+     return ifr.ifr_flags & IFF_VNET_HDR;
+diff --git a/net/tap-solaris.c b/net/tap-solaris.c
+index 4725d2314e..ae2ba68284 100644
+--- a/net/tap-solaris.c
++++ b/net/tap-solaris.c
+@@ -206,7 +206,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
+ {
+ }
+ 
+-int tap_probe_vnet_hdr(int fd)
++int tap_probe_vnet_hdr(int fd, Error **errp)
+ {
+     return 0;
+ }
+diff --git a/net/tap-stub.c b/net/tap-stub.c
+index a9ab8f8293..de525a2e69 100644
+--- a/net/tap-stub.c
++++ b/net/tap-stub.c
+@@ -37,7 +37,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
+ {
+ }
+ 
+-int tap_probe_vnet_hdr(int fd)
++int tap_probe_vnet_hdr(int fd, Error **errp)
+ {
+     return 0;
+ }
+diff --git a/net/tap.c b/net/tap.c
+index 41a20102fd..b37ccae00c 100644
+--- a/net/tap.c
++++ b/net/tap.c
+@@ -597,7 +597,11 @@ int net_init_bridge(const Netdev *netdev, const char *name,
+     }
+ 
+     qemu_set_nonblock(fd);
+-    vnet_hdr = tap_probe_vnet_hdr(fd);
++    vnet_hdr = tap_probe_vnet_hdr(fd, errp);
++    if (vnet_hdr < 0) {
++        close(fd);
++        return -1;
++    }
+     s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
+ 
+     snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper,
+@@ -810,7 +814,11 @@ int net_init_tap(const Netdev *netdev, const char *name,
+             return -1;
+         }
+ 
+-        vnet_hdr = tap_probe_vnet_hdr(fd);
++        vnet_hdr = tap_probe_vnet_hdr(fd, errp);
++        if (vnet_hdr < 0) {
++            close(fd);
++            return -1;
++        }
+ 
+         net_init_tap_one(tap, peer, "tap", name, NULL,
+                          script, downscript,
+@@ -863,8 +871,11 @@ int net_init_tap(const Netdev *netdev, const char *name,
+             }
+ 
+             if (i == 0) {
+-                vnet_hdr = tap_probe_vnet_hdr(fd);
+-            } else if (vnet_hdr != tap_probe_vnet_hdr(fd)) {
++                vnet_hdr = tap_probe_vnet_hdr(fd, errp);
++                if (vnet_hdr < 0) {
++                    goto free_fail;
++                }
++            } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
+                 error_setg(errp,
+                            "vnet_hdr not consistent across given tap fds");
+                 ret = -1;
+@@ -909,7 +920,11 @@ free_fail:
+         }
+ 
+         qemu_set_nonblock(fd);
+-        vnet_hdr = tap_probe_vnet_hdr(fd);
++        vnet_hdr = tap_probe_vnet_hdr(fd, errp);
++        if (vnet_hdr < 0) {
++            close(fd);
++            return -1;
++        }
+ 
+         net_init_tap_one(tap, peer, "bridge", name, ifname,
+                          script, downscript, vhostfdname,
+diff --git a/net/tap_int.h b/net/tap_int.h
+index e3194b23f4..225a49ea48 100644
+--- a/net/tap_int.h
++++ b/net/tap_int.h
+@@ -34,7 +34,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
+ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
+ 
+ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
+-int tap_probe_vnet_hdr(int fd);
++int tap_probe_vnet_hdr(int fd, Error **errp);
+ int tap_probe_vnet_hdr_len(int fd, int len);
+ int tap_probe_has_ufo(int fd);
+ void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-net-forbid-the-reentrant-RX.patch b/SOURCES/kvm-net-forbid-the-reentrant-RX.patch
new file mode 100644
index 0000000..aaf57ed
--- /dev/null
+++ b/SOURCES/kvm-net-forbid-the-reentrant-RX.patch
@@ -0,0 +1,50 @@
+From 1e01e2f96fd5e903394eab59365d5363394c8b18 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 13 Apr 2021 18:59:12 -0400
+Subject: [PATCH 3/5] net: forbid the reentrant RX
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210413185912.3811035-2-jmaloy@redhat.com>
+Patchwork-id: 101467
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] net: forbid the reentrant RX
+Bugzilla: 1859175
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+RH-Acked-by: Xiao Wang <jasowang@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+The memory API allows DMA into NIC's MMIO area. This means the NIC's
+RX routine must be reentrant. Instead of auditing all the NIC, we can
+simply detect the reentrancy and return early. The queue->delivering
+is set and cleared by qemu_net_queue_deliver() for other queue helpers
+to know whether the delivering in on going (NIC's receive is being
+called). We can check it and return early in qemu_net_queue_flush() to
+forbid reentrant RX.
+
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 22dc8663d9fc7baa22100544c600b6285a63c7a3)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ net/queue.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/queue.c b/net/queue.c
+index 61276ca4be..c679d79f4b 100644
+--- a/net/queue.c
++++ b/net/queue.c
+@@ -250,6 +250,9 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
+ 
+ bool qemu_net_queue_flush(NetQueue *queue)
+ {
++    if (queue->delivering)
++        return false;
++
+     while (!QTAILQ_EMPTY(&queue->packets)) {
+         NetPacket *packet;
+         int ret;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-net-introduce-qemu_receive_packet.patch b/SOURCES/kvm-net-introduce-qemu_receive_packet.patch
new file mode 100644
index 0000000..8de8cae
--- /dev/null
+++ b/SOURCES/kvm-net-introduce-qemu_receive_packet.patch
@@ -0,0 +1,187 @@
+From 89732bf03b26daaebbd3e6e031e79459ae3f77e1 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:39 -0400
+Subject: [PATCH 1/9] net: introduce qemu_receive_packet()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-2-jmaloy@redhat.com>
+Patchwork-id: 101785
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 1/9] net: introduce qemu_receive_packet()
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+Some NIC supports loopback mode and this is done by calling
+nc->info->receive() directly which in fact suppresses the effort of
+reentrancy check that is done in qemu_net_queue_send().
+
+Unfortunately we can't use qemu_net_queue_send() here since for
+loopback there's no sender as peer, so this patch introduce a
+qemu_receive_packet() which is used for implementing loopback mode
+for a NIC with this check.
+
+NIC that supports loopback mode will be converted to this helper.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 705df5466c98f3efdd2b68d3b31dad86858acad7)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ include/net/net.h   |  5 +++++
+ include/net/queue.h |  8 ++++++++
+ net/net.c           | 38 +++++++++++++++++++++++++++++++-------
+ net/queue.c         | 22 ++++++++++++++++++++++
+ 4 files changed, 66 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/net.h b/include/net/net.h
+index e175ba9677..1b32a8aaec 100644
+--- a/include/net/net.h
++++ b/include/net/net.h
+@@ -142,12 +142,17 @@ void *qemu_get_nic_opaque(NetClientState *nc);
+ void qemu_del_net_client(NetClientState *nc);
+ typedef void (*qemu_nic_foreach)(NICState *nic, void *opaque);
+ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque);
++int qemu_can_receive_packet(NetClientState *nc);
+ int qemu_can_send_packet(NetClientState *nc);
+ ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov,
+                           int iovcnt);
+ ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
+                                 int iovcnt, NetPacketSent *sent_cb);
+ ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
++ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size);
++ssize_t qemu_receive_packet_iov(NetClientState *nc,
++                                const struct iovec *iov,
++                                int iovcnt);
+ ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
+ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
+                                int size, NetPacketSent *sent_cb);
+diff --git a/include/net/queue.h b/include/net/queue.h
+index c0269bb1dc..9f2f289d77 100644
+--- a/include/net/queue.h
++++ b/include/net/queue.h
+@@ -55,6 +55,14 @@ void qemu_net_queue_append_iov(NetQueue *queue,
+ 
+ void qemu_del_net_queue(NetQueue *queue);
+ 
++ssize_t qemu_net_queue_receive(NetQueue *queue,
++                               const uint8_t *data,
++                               size_t size);
++
++ssize_t qemu_net_queue_receive_iov(NetQueue *queue,
++                                   const struct iovec *iov,
++                                   int iovcnt);
++
+ ssize_t qemu_net_queue_send(NetQueue *queue,
+                             NetClientState *sender,
+                             unsigned flags,
+diff --git a/net/net.c b/net/net.c
+index 84aa6d8d00..d0b651ca95 100644
+--- a/net/net.c
++++ b/net/net.c
+@@ -516,6 +516,17 @@ int qemu_set_vnet_be(NetClientState *nc, bool is_be)
+ #endif
+ }
+ 
++int qemu_can_receive_packet(NetClientState *nc)
++{
++    if (nc->receive_disabled) {
++        return 0;
++    } else if (nc->info->can_receive &&
++               !nc->info->can_receive(nc)) {
++        return 0;
++    }
++    return 1;
++}
++
+ int qemu_can_send_packet(NetClientState *sender)
+ {
+     int vm_running = runstate_is_running();
+@@ -528,13 +539,7 @@ int qemu_can_send_packet(NetClientState *sender)
+         return 1;
+     }
+ 
+-    if (sender->peer->receive_disabled) {
+-        return 0;
+-    } else if (sender->peer->info->can_receive &&
+-               !sender->peer->info->can_receive(sender->peer)) {
+-        return 0;
+-    }
+-    return 1;
++    return qemu_can_receive_packet(sender->peer);
+ }
+ 
+ static ssize_t filter_receive_iov(NetClientState *nc,
+@@ -667,6 +672,25 @@ ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
+     return qemu_send_packet_async(nc, buf, size, NULL);
+ }
+ 
++ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size)
++{
++    if (!qemu_can_receive_packet(nc)) {
++        return 0;
++    }
++
++    return qemu_net_queue_receive(nc->incoming_queue, buf, size);
++}
++
++ssize_t qemu_receive_packet_iov(NetClientState *nc, const struct iovec *iov,
++                                int iovcnt)
++{
++    if (!qemu_can_receive_packet(nc)) {
++        return 0;
++    }
++
++    return qemu_net_queue_receive_iov(nc->incoming_queue, iov, iovcnt);
++}
++
+ ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
+ {
+     return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW,
+diff --git a/net/queue.c b/net/queue.c
+index c679d79f4b..5f0f9ffcaf 100644
+--- a/net/queue.c
++++ b/net/queue.c
+@@ -182,6 +182,28 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
+     return ret;
+ }
+ 
++ssize_t qemu_net_queue_receive(NetQueue *queue,
++                               const uint8_t *data,
++                               size_t size)
++{
++    if (queue->delivering) {
++        return 0;
++    }
++
++    return qemu_net_queue_deliver(queue, NULL, 0, data, size);
++}
++
++ssize_t qemu_net_queue_receive_iov(NetQueue *queue,
++                                   const struct iovec *iov,
++                                   int iovcnt)
++{
++    if (queue->delivering) {
++        return 0;
++    }
++
++    return qemu_net_queue_deliver_iov(queue, NULL, 0, iov, iovcnt);
++}
++
+ ssize_t qemu_net_queue_send(NetQueue *queue,
+                             NetClientState *sender,
+                             unsigned flags,
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch b/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch
new file mode 100644
index 0000000..b619e78
--- /dev/null
+++ b/SOURCES/kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch
@@ -0,0 +1,59 @@
+From b7de63e72c479df42c324c058a487517210fa069 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 13 Apr 2021 19:21:50 -0400
+Subject: [PATCH 1/5] net: remove an assert call in eth_get_gso_type
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210413192150.3817133-2-jmaloy@redhat.com>
+Patchwork-id: 101469
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] net: remove an assert call in eth_get_gso_type
+Bugzilla: 1892350
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Xiao Wang <jasowang@redhat.com>
+
+From: Prasad J Pandit <pjp@fedoraproject.org>
+
+eth_get_gso_type() routine returns segmentation offload type based on
+L3 protocol type. It calls g_assert_not_reached if L3 protocol is
+unknown, making the following return statement unreachable. Remove the
+g_assert call, it maybe triggered by a guest user.
+
+Reported-by: Gaoning Pan <pgn@zju.edu.cn>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 7564bf7701f00214cdc8a678a9f7df765244def1)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ net/eth.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/eth.c b/net/eth.c
+index 0c1d413ee2..1e0821c5f8 100644
+--- a/net/eth.c
++++ b/net/eth.c
+@@ -16,6 +16,7 @@
+  */
+ 
+ #include "qemu/osdep.h"
++#include "qemu/log.h"
+ #include "net/eth.h"
+ #include "net/checksum.h"
+ #include "net/tap.h"
+@@ -71,9 +72,8 @@ eth_get_gso_type(uint16_t l3_proto, uint8_t *l3_hdr, uint8_t l4proto)
+             return VIRTIO_NET_HDR_GSO_TCPV6 | ecn_state;
+         }
+     }
+-
+-    /* Unsupported offload */
+-    g_assert_not_reached();
++    qemu_log_mask(LOG_UNIMP, "%s: probably not GSO frame, "
++        "unknown L3 protocol: 0x%04"PRIx16"\n", __func__, l3_proto);
+ 
+     return VIRTIO_NET_HDR_GSO_NONE | ecn_state;
+ }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch b/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch
new file mode 100644
index 0000000..414cc13
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch
@@ -0,0 +1,50 @@
+From 56ae2d8a1ee3a35e2eed4f4baa61f97184189b47 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 18 May 2021 13:51:24 -0400
+Subject: [PATCH 4/5] pc-bios/s390-ccw: break loop if a null block number is
+ reached
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20210518135125.191329-3-thuth@redhat.com>
+Patchwork-id: 101549
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/3] pc-bios/s390-ccw: break loop if a null block number is reached
+Bugzilla: 1942880
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+
+Break the loop if `cur_block_nr` is a null block number because this
+means that the end of chunk is reached. In this case we will try to
+boot the default entry.
+
+Fixes: ba831b25262a ("s390-ccw: read stage2 boot loader data to find menu")
+Reviewed-by: Collin Walling <walling@linux.ibm.com>
+Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Message-Id: <20200924085926.21709-3-mhartmay@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 468184ec9024f4f7b55247f70ec57554e8a500d7)
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/bootmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
+index bb6e003270..624f524331 100644
+--- a/pc-bios/s390-ccw/bootmap.c
++++ b/pc-bios/s390-ccw/bootmap.c
+@@ -192,7 +192,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
+     for (i = 0; i < STAGE2_BLK_CNT_MAX; i++) {
+         cur_block_nr = eckd_block_num(&s1b->seek[i].chs);
+ 
+-        if (!cur_block_nr) {
++        if (!cur_block_nr || is_null_block_number(cur_block_nr)) {
+             break;
+         }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch b/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch
new file mode 100644
index 0000000..2597118
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch
@@ -0,0 +1,48 @@
+From 52ba1903b2c8ce69e8cd1de2a78c2c63cc60383b Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 18 May 2021 13:51:25 -0400
+Subject: [PATCH 5/5] pc-bios/s390-ccw: don't try to read the next block if end
+ of chunk is reached
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20210518135125.191329-4-thuth@redhat.com>
+Patchwork-id: 101550
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 3/3] pc-bios/s390-ccw: don't try to read the next block if end of chunk is reached
+Bugzilla: 1942880
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+
+Don't read the block if a null block number is reached, because this means that
+the end of chunk is reached.
+
+Reviewed-by: Collin Walling <walling@linux.ibm.com>
+Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Message-Id: <20210416074736.17409-1-mhartmay@linux.ibm.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit a6625d38cce3901a7c1cba069f0abcf743a293f1)
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/bootmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
+index 624f524331..8458b15cb6 100644
+--- a/pc-bios/s390-ccw/bootmap.c
++++ b/pc-bios/s390-ccw/bootmap.c
+@@ -212,7 +212,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
+                 next_block_nr = eckd_block_num(&s1b->seek[i + 1].chs);
+             }
+ 
+-            if (next_block_nr) {
++            if (next_block_nr && !is_null_block_number(next_block_nr)) {
+                 read_block(next_block_nr, s2_next_blk,
+                            "Cannot read stage2 boot loader");
+             }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch b/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch
new file mode 100644
index 0000000..691bed4
--- /dev/null
+++ b/SOURCES/kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch
@@ -0,0 +1,51 @@
+From 0e9bdb960045f98d70f765bbb585f1647e5fea08 Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 18 May 2021 13:51:23 -0400
+Subject: [PATCH 3/5] pc-bios/s390-ccw: fix off-by-one error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20210518135125.191329-2-thuth@redhat.com>
+Patchwork-id: 101548
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/3] pc-bios/s390-ccw: fix off-by-one error
+Bugzilla: 1942880
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+
+This error takes effect when the magic value "zIPL" is located at the
+end of a block. For example if s2_cur_blk = 0x7fe18000 and the magic
+value "zIPL" is located at 0x7fe18ffc - 0x7fe18fff.
+
+Fixes: ba831b25262a ("s390-ccw: read stage2 boot loader data to find menu")
+Reviewed-by: Collin Walling <walling@linux.ibm.com>
+Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+Message-Id: <20200924085926.21709-2-mhartmay@linux.ibm.com>
+Reviewed-by: Thomas Huth <thuth@redhat.com>
+[thuth: Use "<= ... - 4" instead of "< ... - 3"]
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit 5f97ba0c74ccace0a4014460de9751ff3c6f454a)
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ pc-bios/s390-ccw/bootmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
+index e91ea719ff..bb6e003270 100644
+--- a/pc-bios/s390-ccw/bootmap.c
++++ b/pc-bios/s390-ccw/bootmap.c
+@@ -163,7 +163,7 @@ static bool find_zipl_boot_menu_banner(int *offset)
+     int i;
+ 
+     /* Menu banner starts with "zIPL" */
+-    for (i = 0; i < virtio_get_block_size() - 4; i++) {
++    for (i = 0; i <= virtio_get_block_size() - 4; i++) {
+         if (magic_match(s2_cur_blk + i, ZIPL_MAGIC_EBCDIC)) {
+             *offset = i;
+             return true;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch b/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch
new file mode 100644
index 0000000..8c33334
--- /dev/null
+++ b/SOURCES/kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch
@@ -0,0 +1,54 @@
+From b36a9259e085b4d32532d896e485889181b130ae Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:45 -0400
+Subject: [PATCH 7/9] pcnet: switch to use qemu_receive_packet() for loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-8-jmaloy@redhat.com>
+Patchwork-id: 101791
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 7/9] pcnet: switch to use qemu_receive_packet() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alexander Bulekov <alxndr@bu.edu>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Buglink: https://bugs.launchpad.net/qemu/+bug/1917085
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
+Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 99ccfaa1edafd79f7a3a0ff7b58ae4da7c514928)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/pcnet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
+index f3f18d8598..dcd3fc4948 100644
+--- a/hw/net/pcnet.c
++++ b/hw/net/pcnet.c
+@@ -1250,7 +1250,7 @@ txagain:
+             if (BCR_SWSTYLE(s) == 1)
+                 add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
+             s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
+-            pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
++            qemu_receive_packet(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
+             s->looptest = 0;
+         } else {
+             if (s->nic) {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-qemu-img-convert-Don-t-pre-zero-images.patch b/SOURCES/kvm-qemu-img-convert-Don-t-pre-zero-images.patch
new file mode 100644
index 0000000..28311f4
--- /dev/null
+++ b/SOURCES/kvm-qemu-img-convert-Don-t-pre-zero-images.patch
@@ -0,0 +1,73 @@
+From eea45924903f03dc6d8f20576be0a4a84d5acce4 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Wed, 10 Feb 2021 10:16:11 -0500
+Subject: [PATCH 4/5] qemu-img convert: Don't pre-zero images
+
+RH-Author: Kevin Wolf <kwolf@redhat.com>
+Message-id: <20210210101611.137928-2-kwolf@redhat.com>
+Patchwork-id: 101030
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] qemu-img convert: Don't pre-zero images
+Bugzilla: 1855250
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Max Reitz <mreitz@redhat.com>
+
+Since commit 5a37b60a61c, qemu-img create will pre-zero the target image
+if it isn't already zero-initialised (most importantly, for host block
+devices, but also iscsi etc.), so that writing explicit zeros wouldn't
+be necessary later.
+
+This could speed up the operation significantly, in particular when the
+source image file was only sparsely populated. However, it also means
+that some block are written twice: Once when pre-zeroing them, and then
+when they are overwritten with actual data. On a full image, the
+pre-zeroing is wasted work because everything will be overwritten.
+
+In practice, write_zeroes typically turns out faster than writing
+explicit zero buffers, but slow enough that first zeroing everything and
+then overwriting parts can be a significant net loss.
+
+Meanwhile, qemu-img convert was rewritten in 690c7301600 and zero blocks
+are now written to the target using bdrv_co_pwrite_zeroes() if the
+target could be pre-zeroed. This way we already make use of the faster
+write_zeroes operation, but avoid writing any blocks twice.
+
+Remove the pre-zeroing because these days this former optimisation has
+actually turned into a pessimisation in the common case.
+
+Reported-by: Nir Soffer <nsoffer@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Message-Id: <20200622151203.35624-1-kwolf@redhat.com>
+Tested-by:  Nir Soffer <nsoffer@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+(cherry picked from commit edafc70c0c8510862f2f213a3acf7067113bcd08)
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ qemu-img.c | 9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index a27ad70851..b10dc5129b 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -2029,15 +2029,6 @@ static int convert_do_copy(ImgConvertState *s)
+         s->has_zero_init = false;
+     }
+ 
+-    if (!s->has_zero_init && !s->target_has_backing &&
+-        bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
+-    {
+-        ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
+-        if (ret == 0) {
+-            s->has_zero_init = true;
+-        }
+-    }
+-
+     /* Allocate buffer for copied data. For compressed images, only one cluster
+      * can be copied at a time. */
+     if (s->compressed) {
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch b/SOURCES/kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch
new file mode 100644
index 0000000..dec7f7b
--- /dev/null
+++ b/SOURCES/kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch
@@ -0,0 +1,176 @@
+From 7f8888f2c53060c4536856859d5ea94d23ea9e45 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:55:54 -0400
+Subject: [PATCH 03/14] qga: add *reset argument to ssh-add-authorized-keys
+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: <20210609100615.2501448-4-marcandre.lureau@redhat.com>
+Patchwork-id: 101689
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 3/4] qga: add *reset argument to ssh-add-authorized-keys
+Bugzilla: 1967716
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Michal Privoznik <mprivozn@redhat.com>
+
+From: Michael Roth <michael.roth@amd.com>
+
+I prefer 'reset' over 'clear', since 'clear' and keys may have some
+other relations or meaning.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+*fix disallowed g_assert* usage reported by checkpatch
+Signed-off-by: Michael Roth <michael.roth@amd.com>
+
+(cherry picked from commit 0e3c94758e3851f0ab30d2a1e63a73284499775d)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qga/commands-posix-ssh.c | 53 ++++++++++++++++++++++++++++++++++++----
+ qga/qapi-schema.json     |  3 ++-
+ 2 files changed, 50 insertions(+), 6 deletions(-)
+
+diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
+index f74d89679c..362c9e8816 100644
+--- a/qga/commands-posix-ssh.c
++++ b/qga/commands-posix-ssh.c
+@@ -168,6 +168,7 @@ read_authkeys(const char *path, Error **errp)
+ 
+ void
+ qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys,
++                                  bool has_reset, bool reset,
+                                   Error **errp)
+ {
+     g_autofree struct passwd *p = NULL;
+@@ -178,6 +179,7 @@ qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys,
+     size_t nkeys, nauthkeys;
+ 
+     ERRP_GUARD();
++    reset = has_reset && reset;
+ 
+     if (!check_openssh_pub_keys(keys, &nkeys, errp)) {
+         return;
+@@ -191,7 +193,9 @@ qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys,
+     ssh_path = g_build_filename(p->pw_dir, ".ssh", NULL);
+     authkeys_path = g_build_filename(ssh_path, "authorized_keys", NULL);
+ 
+-    authkeys = read_authkeys(authkeys_path, NULL);
++    if (!reset) {
++        authkeys = read_authkeys(authkeys_path, NULL);
++    }
+     if (authkeys == NULL) {
+         if (!g_file_test(ssh_path, G_FILE_TEST_IS_DIR) &&
+             !mkdir_for_user(ssh_path, p, 0700, errp)) {
+@@ -318,7 +322,7 @@ test_invalid_user(void)
+ {
+     Error *err = NULL;
+ 
+-    qmp_guest_ssh_add_authorized_keys("", NULL, &err);
++    qmp_guest_ssh_add_authorized_keys("", NULL, FALSE, FALSE, &err);
+     error_free_or_abort(&err);
+ 
+     qmp_guest_ssh_remove_authorized_keys("", NULL, &err);
+@@ -333,7 +337,8 @@ test_invalid_key(void)
+     };
+     Error *err = NULL;
+ 
+-    qmp_guest_ssh_add_authorized_keys(g_get_user_name(), &key, &err);
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(), &key,
++                                      FALSE, FALSE, &err);
+     error_free_or_abort(&err);
+ 
+     qmp_guest_ssh_remove_authorized_keys(g_get_user_name(), &key, &err);
+@@ -346,13 +351,17 @@ test_add_keys(void)
+     Error *err = NULL;
+ 
+     qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
+-                                      (strList *)&test_key2, &err);
++                                      (strList *)&test_key2,
++                                      FALSE, FALSE,
++                                      &err);
+     g_assert(err == NULL);
+ 
+     test_authorized_keys_equal("algo key2 comments");
+ 
+     qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
+-                                      (strList *)&test_key1_2, &err);
++                                      (strList *)&test_key1_2,
++                                      FALSE, FALSE,
++                                      &err);
+     g_assert(err == NULL);
+ 
+     /*  key2 came first, and should'nt be duplicated */
+@@ -360,6 +369,39 @@ test_add_keys(void)
+                                "algo key1 comments");
+ }
+ 
++static void
++test_add_reset_keys(void)
++{
++    Error *err = NULL;
++
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
++                                      (strList *)&test_key1_2,
++                                      FALSE, FALSE,
++                                      &err);
++    g_assert(err == NULL);
++
++    /* reset with key2 only */
++    test_authorized_keys_equal("algo key1 comments\n"
++                               "algo key2 comments");
++
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
++                                      (strList *)&test_key2,
++                                      TRUE, TRUE,
++                                      &err);
++    g_assert(err == NULL);
++
++    test_authorized_keys_equal("algo key2 comments");
++
++    /* empty should clear file */
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
++                                      (strList *)NULL,
++                                      TRUE, TRUE,
++                                      &err);
++    g_assert(err == NULL);
++
++    test_authorized_keys_equal("");
++}
++
+ static void
+ test_remove_keys(void)
+ {
+@@ -393,6 +435,7 @@ int main(int argc, char *argv[])
+     g_test_add_func("/qga/ssh/invalid_user", test_invalid_user);
+     g_test_add_func("/qga/ssh/invalid_key", test_invalid_key);
+     g_test_add_func("/qga/ssh/add_keys", test_add_keys);
++    g_test_add_func("/qga/ssh/add_reset_keys", test_add_reset_keys);
+     g_test_add_func("/qga/ssh/remove_keys", test_remove_keys);
+ 
+     return g_test_run();
+diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
+index 3b85f5a03f..a70ea5da77 100644
+--- a/qga/qapi-schema.json
++++ b/qga/qapi-schema.json
+@@ -1279,6 +1279,7 @@
+ #
+ # @username: the user account to add the authorized keys
+ # @keys: the public keys to add (in OpenSSH/sshd(8) authorized_keys format)
++# @reset: ignore the existing content, set it with the given keys only
+ #
+ # Append public keys to user .ssh/authorized_keys on Unix systems (not
+ # implemented for other systems).
+@@ -1288,7 +1289,7 @@
+ # Since: 5.2
+ ##
+ { 'command': 'guest-ssh-add-authorized-keys',
+-  'data': { 'username': 'str', 'keys': ['str'] },
++  'data': { 'username': 'str', 'keys': ['str'], '*reset': 'bool' },
+   'if': 'defined(CONFIG_POSIX)' }
+ 
+ ##
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-qga-add-ssh-add-remove-authorized-keys.patch b/SOURCES/kvm-qga-add-ssh-add-remove-authorized-keys.patch
new file mode 100644
index 0000000..b767d42
--- /dev/null
+++ b/SOURCES/kvm-qga-add-ssh-add-remove-authorized-keys.patch
@@ -0,0 +1,525 @@
+From 4be6cb23235b29d6ce450c2dacaef09c52d1aeea Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:55:52 -0400
+Subject: [PATCH 02/14] qga: add ssh-{add, remove}-authorized-keys
+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: <20210609100615.2501448-3-marcandre.lureau@redhat.com>
+Patchwork-id: 101688
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/4] qga: add ssh-{add, remove}-authorized-keys
+Bugzilla: 1967716
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Michal Privoznik <mprivozn@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Add new commands to add and remove SSH public keys from
+~/.ssh/authorized_keys.
+
+I took a different approach for testing, including the unit tests right
+with the code. I wanted to overwrite the function to get the user
+details, I couldn't easily do that over QMP. Furthermore, I prefer
+having unit tests very close to the code, and unit files that are domain
+specific (commands-posix is too crowded already). FWIW, that
+coding/testing style is Rust-style (where tests can or should even be
+part of the documentation!).
+
+Fixes:
+https://bugzilla.redhat.com/show_bug.cgi?id=1885332
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+*squashed in fix-ups for setting file ownership and use of QAPI
+ conditionals for CONFIG_POSIX instead of stub definitions
+*disable qga-ssh-test for now due to G_TEST_OPTION_ISOLATE_DIRS
+ triggering leak detector in build-oss-fuzz
+*fix disallowed g_assert* usage reported by checkpatch
+Signed-off-by: Michael Roth <michael.roth@amd.com>
+
+(cherry picked from commit 8d769ec777dccbff199711aba43aa6297fe4a0e0)
+[ Fixes trivial backport conflicts and use Makefile.objs build-sys ]
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qga/Makefile.objs        |   2 +-
+ qga/commands-posix-ssh.c | 407 +++++++++++++++++++++++++++++++++++++++
+ qga/qapi-schema.json     |  35 ++++
+ 3 files changed, 443 insertions(+), 1 deletion(-)
+ create mode 100644 qga/commands-posix-ssh.c
+
+diff --git a/qga/Makefile.objs b/qga/Makefile.objs
+index 80e6bb3c2e..c8da634db0 100644
+--- a/qga/Makefile.objs
++++ b/qga/Makefile.objs
+@@ -1,6 +1,6 @@
+ commands-posix.o-libs := $(LIBUDEV_LIBS)
+ qga-obj-y = commands.o guest-agent-command-state.o main.o
+-qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o
++qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o commands-posix-ssh.o
+ qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
+ qga-obj-$(CONFIG_WIN32) += vss-win32.o
+ qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
+diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
+new file mode 100644
+index 0000000000..f74d89679c
+--- /dev/null
++++ b/qga/commands-posix-ssh.c
+@@ -0,0 +1,407 @@
++ /*
++  * This work is licensed under the terms of the GNU GPL, version 2 or later.
++  * See the COPYING file in the top-level directory.
++  */
++#include "qemu/osdep.h"
++
++#include <glib-unix.h>
++#include <glib/gstdio.h>
++#include <locale.h>
++#include <pwd.h>
++
++#include "qapi/error.h"
++#include "qga-qapi-commands.h"
++
++#ifdef QGA_BUILD_UNIT_TEST
++static struct passwd *
++test_get_passwd_entry(const gchar *user_name, GError **error)
++{
++    struct passwd *p;
++    int ret;
++
++    if (!user_name || g_strcmp0(user_name, g_get_user_name())) {
++        g_set_error(error, G_UNIX_ERROR, 0, "Invalid user name");
++        return NULL;
++    }
++
++    p = g_new0(struct passwd, 1);
++    p->pw_dir = (char *)g_get_home_dir();
++    p->pw_uid = geteuid();
++    p->pw_gid = getegid();
++
++    ret = g_mkdir_with_parents(p->pw_dir, 0700);
++    g_assert(ret == 0);
++
++    return p;
++}
++
++#define g_unix_get_passwd_entry_qemu(username, err) \
++   test_get_passwd_entry(username, err)
++#endif
++
++static struct passwd *
++get_passwd_entry(const char *username, Error **errp)
++{
++    g_autoptr(GError) err = NULL;
++    struct passwd *p;
++
++    ERRP_GUARD();
++
++    p = g_unix_get_passwd_entry_qemu(username, &err);
++    if (p == NULL) {
++        error_setg(errp, "failed to lookup user '%s': %s",
++                   username, err->message);
++        return NULL;
++    }
++
++    return p;
++}
++
++static bool
++mkdir_for_user(const char *path, const struct passwd *p,
++               mode_t mode, Error **errp)
++{
++    ERRP_GUARD();
++
++    if (g_mkdir(path, mode) == -1) {
++        error_setg(errp, "failed to create directory '%s': %s",
++                   path, g_strerror(errno));
++        return false;
++    }
++
++    if (chown(path, p->pw_uid, p->pw_gid) == -1) {
++        error_setg(errp, "failed to set ownership of directory '%s': %s",
++                   path, g_strerror(errno));
++        return false;
++    }
++
++    if (chmod(path, mode) == -1) {
++        error_setg(errp, "failed to set permissions of directory '%s': %s",
++                   path, g_strerror(errno));
++        return false;
++    }
++
++    return true;
++}
++
++static bool
++check_openssh_pub_key(const char *key, Error **errp)
++{
++    ERRP_GUARD();
++
++    /* simple sanity-check, we may want more? */
++    if (!key || key[0] == '#' || strchr(key, '\n')) {
++        error_setg(errp, "invalid OpenSSH public key: '%s'", key);
++        return false;
++    }
++
++    return true;
++}
++
++static bool
++check_openssh_pub_keys(strList *keys, size_t *nkeys, Error **errp)
++{
++    size_t n = 0;
++    strList *k;
++
++    ERRP_GUARD();
++
++    for (k = keys; k != NULL; k = k->next) {
++        if (!check_openssh_pub_key(k->value, errp)) {
++            return false;
++        }
++        n++;
++    }
++
++    if (nkeys) {
++        *nkeys = n;
++    }
++    return true;
++}
++
++static bool
++write_authkeys(const char *path, const GStrv keys,
++               const struct passwd *p, Error **errp)
++{
++    g_autofree char *contents = NULL;
++    g_autoptr(GError) err = NULL;
++
++    ERRP_GUARD();
++
++    contents = g_strjoinv("\n", keys);
++    if (!g_file_set_contents(path, contents, -1, &err)) {
++        error_setg(errp, "failed to write to '%s': %s", path, err->message);
++        return false;
++    }
++
++    if (chown(path, p->pw_uid, p->pw_gid) == -1) {
++        error_setg(errp, "failed to set ownership of directory '%s': %s",
++                   path, g_strerror(errno));
++        return false;
++    }
++
++    if (chmod(path, 0600) == -1) {
++        error_setg(errp, "failed to set permissions of '%s': %s",
++                   path, g_strerror(errno));
++        return false;
++    }
++
++    return true;
++}
++
++static GStrv
++read_authkeys(const char *path, Error **errp)
++{
++    g_autoptr(GError) err = NULL;
++    g_autofree char *contents = NULL;
++
++    ERRP_GUARD();
++
++    if (!g_file_get_contents(path, &contents, NULL, &err)) {
++        error_setg(errp, "failed to read '%s': %s", path, err->message);
++        return NULL;
++    }
++
++    return g_strsplit(contents, "\n", -1);
++
++}
++
++void
++qmp_guest_ssh_add_authorized_keys(const char *username, strList *keys,
++                                  Error **errp)
++{
++    g_autofree struct passwd *p = NULL;
++    g_autofree char *ssh_path = NULL;
++    g_autofree char *authkeys_path = NULL;
++    g_auto(GStrv) authkeys = NULL;
++    strList *k;
++    size_t nkeys, nauthkeys;
++
++    ERRP_GUARD();
++
++    if (!check_openssh_pub_keys(keys, &nkeys, errp)) {
++        return;
++    }
++
++    p = get_passwd_entry(username, errp);
++    if (p == NULL) {
++        return;
++    }
++
++    ssh_path = g_build_filename(p->pw_dir, ".ssh", NULL);
++    authkeys_path = g_build_filename(ssh_path, "authorized_keys", NULL);
++
++    authkeys = read_authkeys(authkeys_path, NULL);
++    if (authkeys == NULL) {
++        if (!g_file_test(ssh_path, G_FILE_TEST_IS_DIR) &&
++            !mkdir_for_user(ssh_path, p, 0700, errp)) {
++            return;
++        }
++    }
++
++    nauthkeys = authkeys ? g_strv_length(authkeys) : 0;
++    authkeys = g_realloc_n(authkeys, nauthkeys + nkeys + 1, sizeof(char *));
++    memset(authkeys + nauthkeys, 0, (nkeys + 1) * sizeof(char *));
++
++    for (k = keys; k != NULL; k = k->next) {
++        if (g_strv_contains((const gchar * const *)authkeys, k->value)) {
++            continue;
++        }
++        authkeys[nauthkeys++] = g_strdup(k->value);
++    }
++
++    write_authkeys(authkeys_path, authkeys, p, errp);
++}
++
++void
++qmp_guest_ssh_remove_authorized_keys(const char *username, strList *keys,
++                                     Error **errp)
++{
++    g_autofree struct passwd *p = NULL;
++    g_autofree char *authkeys_path = NULL;
++    g_autofree GStrv new_keys = NULL; /* do not own the strings */
++    g_auto(GStrv) authkeys = NULL;
++    GStrv a;
++    size_t nkeys = 0;
++
++    ERRP_GUARD();
++
++    if (!check_openssh_pub_keys(keys, NULL, errp)) {
++        return;
++    }
++
++    p = get_passwd_entry(username, errp);
++    if (p == NULL) {
++        return;
++    }
++
++    authkeys_path = g_build_filename(p->pw_dir, ".ssh",
++                                     "authorized_keys", NULL);
++    if (!g_file_test(authkeys_path, G_FILE_TEST_EXISTS)) {
++        return;
++    }
++    authkeys = read_authkeys(authkeys_path, errp);
++    if (authkeys == NULL) {
++        return;
++    }
++
++    new_keys = g_new0(char *, g_strv_length(authkeys) + 1);
++    for (a = authkeys; *a != NULL; a++) {
++        strList *k;
++
++        for (k = keys; k != NULL; k = k->next) {
++            if (g_str_equal(k->value, *a)) {
++                break;
++            }
++        }
++        if (k != NULL) {
++            continue;
++        }
++
++        new_keys[nkeys++] = *a;
++    }
++
++    write_authkeys(authkeys_path, new_keys, p, errp);
++}
++
++
++#ifdef QGA_BUILD_UNIT_TEST
++#if GLIB_CHECK_VERSION(2, 60, 0)
++static const strList test_key2 = {
++    .value = (char *)"algo key2 comments"
++};
++
++static const strList test_key1_2 = {
++    .value = (char *)"algo key1 comments",
++    .next = (strList *)&test_key2,
++};
++
++static char *
++test_get_authorized_keys_path(void)
++{
++    return g_build_filename(g_get_home_dir(), ".ssh", "authorized_keys", NULL);
++}
++
++static void
++test_authorized_keys_set(const char *contents)
++{
++    g_autoptr(GError) err = NULL;
++    g_autofree char *path = NULL;
++    int ret;
++
++    path = g_build_filename(g_get_home_dir(), ".ssh", NULL);
++    ret = g_mkdir_with_parents(path, 0700);
++    g_assert(ret == 0);
++    g_free(path);
++
++    path = test_get_authorized_keys_path();
++    g_file_set_contents(path, contents, -1, &err);
++    g_assert(err == NULL);
++}
++
++static void
++test_authorized_keys_equal(const char *expected)
++{
++    g_autoptr(GError) err = NULL;
++    g_autofree char *path = NULL;
++    g_autofree char *contents = NULL;
++
++    path = test_get_authorized_keys_path();
++    g_file_get_contents(path, &contents, NULL, &err);
++    g_assert(err == NULL);
++
++    g_assert(g_strcmp0(contents, expected) == 0);
++}
++
++static void
++test_invalid_user(void)
++{
++    Error *err = NULL;
++
++    qmp_guest_ssh_add_authorized_keys("", NULL, &err);
++    error_free_or_abort(&err);
++
++    qmp_guest_ssh_remove_authorized_keys("", NULL, &err);
++    error_free_or_abort(&err);
++}
++
++static void
++test_invalid_key(void)
++{
++    strList key = {
++        .value = (char *)"not a valid\nkey"
++    };
++    Error *err = NULL;
++
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(), &key, &err);
++    error_free_or_abort(&err);
++
++    qmp_guest_ssh_remove_authorized_keys(g_get_user_name(), &key, &err);
++    error_free_or_abort(&err);
++}
++
++static void
++test_add_keys(void)
++{
++    Error *err = NULL;
++
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
++                                      (strList *)&test_key2, &err);
++    g_assert(err == NULL);
++
++    test_authorized_keys_equal("algo key2 comments");
++
++    qmp_guest_ssh_add_authorized_keys(g_get_user_name(),
++                                      (strList *)&test_key1_2, &err);
++    g_assert(err == NULL);
++
++    /*  key2 came first, and should'nt be duplicated */
++    test_authorized_keys_equal("algo key2 comments\n"
++                               "algo key1 comments");
++}
++
++static void
++test_remove_keys(void)
++{
++    Error *err = NULL;
++    static const char *authkeys =
++        "algo key1 comments\n"
++        /* originally duplicated */
++        "algo key1 comments\n"
++        "# a commented line\n"
++        "algo some-key another\n";
++
++    test_authorized_keys_set(authkeys);
++    qmp_guest_ssh_remove_authorized_keys(g_get_user_name(),
++                                         (strList *)&test_key2, &err);
++    g_assert(err == NULL);
++    test_authorized_keys_equal(authkeys);
++
++    qmp_guest_ssh_remove_authorized_keys(g_get_user_name(),
++                                         (strList *)&test_key1_2, &err);
++    g_assert(err == NULL);
++    test_authorized_keys_equal("# a commented line\n"
++                               "algo some-key another\n");
++}
++
++int main(int argc, char *argv[])
++{
++    setlocale(LC_ALL, "");
++
++    g_test_init(&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
++
++    g_test_add_func("/qga/ssh/invalid_user", test_invalid_user);
++    g_test_add_func("/qga/ssh/invalid_key", test_invalid_key);
++    g_test_add_func("/qga/ssh/add_keys", test_add_keys);
++    g_test_add_func("/qga/ssh/remove_keys", test_remove_keys);
++
++    return g_test_run();
++}
++#else
++int main(int argc, char *argv[])
++{
++    g_test_message("test skipped, needs glib >= 2.60");
++    return 0;
++}
++#endif /* GLIB_2_60 */
++#endif /* BUILD_UNIT_TEST */
+diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
+index 4222cb92d3..3b85f5a03f 100644
+--- a/qga/qapi-schema.json
++++ b/qga/qapi-schema.json
+@@ -1273,3 +1273,38 @@
+ ##
+ { 'command': 'guest-get-osinfo',
+   'returns': 'GuestOSInfo' }
++
++##
++# @guest-ssh-add-authorized-keys:
++#
++# @username: the user account to add the authorized keys
++# @keys: the public keys to add (in OpenSSH/sshd(8) authorized_keys format)
++#
++# Append public keys to user .ssh/authorized_keys on Unix systems (not
++# implemented for other systems).
++#
++# Returns: Nothing on success.
++#
++# Since: 5.2
++##
++{ 'command': 'guest-ssh-add-authorized-keys',
++  'data': { 'username': 'str', 'keys': ['str'] },
++  'if': 'defined(CONFIG_POSIX)' }
++
++##
++# @guest-ssh-remove-authorized-keys:
++#
++# @username: the user account to remove the authorized keys
++# @keys: the public keys to remove (in OpenSSH/sshd(8) authorized_keys format)
++#
++# Remove public keys from the user .ssh/authorized_keys on Unix systems (not
++# implemented for other systems). It's not an error if the key is already
++# missing.
++#
++# Returns: Nothing on success.
++#
++# Since: 5.2
++##
++{ 'command': 'guest-ssh-remove-authorized-keys',
++  'data': { 'username': 'str', 'keys': ['str'] },
++  'if': 'defined(CONFIG_POSIX)' }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-qga-add-ssh-get-authorized-keys.patch b/SOURCES/kvm-qga-add-ssh-get-authorized-keys.patch
new file mode 100644
index 0000000..2b4c377
--- /dev/null
+++ b/SOURCES/kvm-qga-add-ssh-get-authorized-keys.patch
@@ -0,0 +1,170 @@
+From 1ed102f5489e6cf3168d9014e9a082909193b6fc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:55:57 -0400
+Subject: [PATCH 04/14] qga: add ssh-get-authorized-keys
+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: <20210609100615.2501448-5-marcandre.lureau@redhat.com>
+Patchwork-id: 101690
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 4/4] qga: add ssh-get-authorized-keys
+Bugzilla: 1967716
+RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Michal Privoznik <mprivozn@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+*fix-up merge conflicts due to qga-ssh-test being disabled in earlier
+ patch due to G_TEST_OPTION_ISOLATE_DIRS triggering build-oss-fuzz
+ leak detector.
+*fix up style and disallowed g_assert* usage reported by checkpatch
+Signed-off-by: Michael Roth <michael.roth@amd.com>
+
+(cherry picked from commit cad97c08a1c17830d77a46780088bc0199df89d1)
+[ Fix trivial schema conflict ]
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ qga/commands-posix-ssh.c | 66 ++++++++++++++++++++++++++++++++++++++++
+ qga/qapi-schema.json     | 30 ++++++++++++++++++
+ 2 files changed, 96 insertions(+)
+
+diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
+index 362c9e8816..749167e82d 100644
+--- a/qga/commands-posix-ssh.c
++++ b/qga/commands-posix-ssh.c
+@@ -268,6 +268,46 @@ qmp_guest_ssh_remove_authorized_keys(const char *username, strList *keys,
+     write_authkeys(authkeys_path, new_keys, p, errp);
+ }
+ 
++GuestAuthorizedKeys *
++qmp_guest_ssh_get_authorized_keys(const char *username, Error **errp)
++{
++    g_autofree struct passwd *p = NULL;
++    g_autofree char *authkeys_path = NULL;
++    g_auto(GStrv) authkeys = NULL;
++    g_autoptr(GuestAuthorizedKeys) ret = NULL;
++    int i;
++
++    ERRP_GUARD();
++
++    p = get_passwd_entry(username, errp);
++    if (p == NULL) {
++        return NULL;
++    }
++
++    authkeys_path = g_build_filename(p->pw_dir, ".ssh",
++                                     "authorized_keys", NULL);
++    authkeys = read_authkeys(authkeys_path, errp);
++    if (authkeys == NULL) {
++        return NULL;
++    }
++
++    ret = g_new0(GuestAuthorizedKeys, 1);
++    for (i = 0; authkeys[i] != NULL; i++) {
++        strList *new;
++
++        g_strstrip(authkeys[i]);
++        if (!authkeys[i][0] || authkeys[i][0] == '#') {
++            continue;
++        }
++
++        new = g_new0(strList, 1);
++        new->value = g_strdup(authkeys[i]);
++        new->next = ret->keys;
++        ret->keys = new;
++    }
++
++    return g_steal_pointer(&ret);
++}
+ 
+ #ifdef QGA_BUILD_UNIT_TEST
+ #if GLIB_CHECK_VERSION(2, 60, 0)
+@@ -426,6 +466,31 @@ test_remove_keys(void)
+                                "algo some-key another\n");
+ }
+ 
++static void
++test_get_keys(void)
++{
++    Error *err = NULL;
++    static const char *authkeys =
++        "algo key1 comments\n"
++        "# a commented line\n"
++        "algo some-key another\n";
++    g_autoptr(GuestAuthorizedKeys) ret = NULL;
++    strList *k;
++    size_t len = 0;
++
++    test_authorized_keys_set(authkeys);
++
++    ret = qmp_guest_ssh_get_authorized_keys(g_get_user_name(), &err);
++    g_assert(err == NULL);
++
++    for (len = 0, k = ret->keys; k != NULL; k = k->next) {
++        g_assert(g_str_has_prefix(k->value, "algo "));
++        len++;
++    }
++
++    g_assert(len == 2);
++}
++
+ int main(int argc, char *argv[])
+ {
+     setlocale(LC_ALL, "");
+@@ -437,6 +502,7 @@ int main(int argc, char *argv[])
+     g_test_add_func("/qga/ssh/add_keys", test_add_keys);
+     g_test_add_func("/qga/ssh/add_reset_keys", test_add_reset_keys);
+     g_test_add_func("/qga/ssh/remove_keys", test_remove_keys);
++    g_test_add_func("/qga/ssh/get_keys", test_get_keys);
+ 
+     return g_test_run();
+ }
+diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
+index a70ea5da77..97bf96712e 100644
+--- a/qga/qapi-schema.json
++++ b/qga/qapi-schema.json
+@@ -1274,6 +1274,36 @@
+ { 'command': 'guest-get-osinfo',
+   'returns': 'GuestOSInfo' }
+ 
++##
++# @GuestAuthorizedKeys:
++#
++# @keys: public keys (in OpenSSH/sshd(8) authorized_keys format)
++#
++# Since: 5.2
++##
++{ 'struct': 'GuestAuthorizedKeys',
++  'data': {
++      'keys': ['str']
++  },
++  'if': 'defined(CONFIG_POSIX)' }
++
++##
++# @guest-ssh-get-authorized-keys:
++#
++# @username: the user account to add the authorized keys
++#
++# Return the public keys from user .ssh/authorized_keys on Unix systems (not
++# implemented for other systems).
++#
++# Returns: @GuestAuthorizedKeys
++#
++# Since: 5.2
++##
++{ 'command': 'guest-ssh-get-authorized-keys',
++  'data': { 'username': 'str' },
++  'returns': 'GuestAuthorizedKeys',
++  'if': 'defined(CONFIG_POSIX)' }
++
+ ##
+ # @guest-ssh-add-authorized-keys:
+ #
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch b/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch
new file mode 100644
index 0000000..917e3ff
--- /dev/null
+++ b/SOURCES/kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch
@@ -0,0 +1,54 @@
+From 4079c4e96f910fe7e57af13feb433f06246f1d79 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:44 -0400
+Subject: [PATCH 6/9] rtl8139: switch to use qemu_receive_packet() for loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-7-jmaloy@redhat.com>
+Patchwork-id: 101792
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 6/9] rtl8139: switch to use qemu_receive_packet() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Alexander Bulekov <alxndr@bu.edu>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Buglink: https://bugs.launchpad.net/qemu/+bug/1910826
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com
+Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 5311fb805a4403bba024e83886fa0e7572265de4)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/rtl8139.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
+index 21d80e96cf..ccb04faa4c 100644
+--- a/hw/net/rtl8139.c
++++ b/hw/net/rtl8139.c
+@@ -1793,7 +1793,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
+         }
+ 
+         DPRINTF("+++ transmit loopback mode\n");
+-        rtl8139_do_receive(qemu_get_queue(s->nic), buf, size, do_interrupt);
++        qemu_receive_packet(qemu_get_queue(s->nic), buf, size);
+ 
+         if (iov) {
+             g_free(buf2);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch b/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch
new file mode 100644
index 0000000..e4e1bc4
--- /dev/null
+++ b/SOURCES/kvm-softmmu-memory-Log-invalid-memory-accesses.patch
@@ -0,0 +1,84 @@
+From be0a190e3c5c4ff84f7c53630ed5a55644d18acc Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Wed, 21 Apr 2021 22:30:06 -0400
+Subject: [PATCH 7/7] softmmu/memory: Log invalid memory accesses
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210421223006.19650-7-jmaloy@redhat.com>
+Patchwork-id: 101481
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 6/6] softmmu/memory: Log invalid memory accesses
+Bugzilla: 1842478
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Philippe Mathieu-Daudé <philmd@redhat.com>
+
+Log invalid memory accesses with as GUEST_ERROR.
+
+This is particularly useful since commit 5d971f9e67 which reverted
+("memory: accept mismatching sizes in memory_region_access_valid").
+
+Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Message-Id: <20201005152725.2143444-1-philmd@redhat.com>
+Signed-off-by: Laurent Vivier <laurent@vivier.eu>
+
+(cherry picked from commit 21786c7e59847b1612406ff394958f22e5b323f8)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ memory.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/memory.c b/memory.c
+index 0cfcb72a5a..660df8159a 100644
+--- a/memory.c
++++ b/memory.c
+@@ -14,6 +14,7 @@
+  */
+ 
+ #include "qemu/osdep.h"
++#include "qemu/log.h"
+ #include "qapi/error.h"
+ #include "cpu.h"
+ #include "exec/memory.h"
+@@ -1353,10 +1354,18 @@ bool memory_region_access_valid(MemoryRegion *mr,
+ {
+     if (mr->ops->valid.accepts
+         && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
++        qemu_log_mask(LOG_GUEST_ERROR, "Invalid access at addr "
++                                       "0x%" HWADDR_PRIX ", size %u, "
++                                       "region '%s', reason: rejected\n",
++                      addr, size, memory_region_name(mr));
+         return false;
+     }
+ 
+     if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
++        qemu_log_mask(LOG_GUEST_ERROR, "Invalid access at addr "
++                                       "0x%" HWADDR_PRIX ", size %u, "
++                                       "region '%s', reason: unaligned\n",
++                      addr, size, memory_region_name(mr));
+         return false;
+     }
+ 
+@@ -1367,6 +1376,13 @@ bool memory_region_access_valid(MemoryRegion *mr,
+ 
+     if (size > mr->ops->valid.max_access_size
+         || size < mr->ops->valid.min_access_size) {
++        qemu_log_mask(LOG_GUEST_ERROR, "Invalid access at addr "
++                                       "0x%" HWADDR_PRIX ", size %u, "
++                                       "region '%s', reason: invalid size "
++                                       "(min:%u max:%u)\n",
++                      addr, size, memory_region_name(mr),
++                      mr->ops->valid.min_access_size,
++                      mr->ops->valid.max_access_size);
+         return false;
+     }
+     return true;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-spapr-Adjust-firmware-path-of-PCI-devices.patch b/SOURCES/kvm-spapr-Adjust-firmware-path-of-PCI-devices.patch
new file mode 100644
index 0000000..7aaa982
--- /dev/null
+++ b/SOURCES/kvm-spapr-Adjust-firmware-path-of-PCI-devices.patch
@@ -0,0 +1,205 @@
+From dfdf950e893c23e77c9dc0be18fca66ad195d260 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <gkurz@redhat.com>
+Date: Wed, 10 Feb 2021 15:56:45 +0000
+Subject: [PATCH 2/2] spapr: Adjust firmware path of PCI devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Greg Kurz <gkurz@redhat.com>
+Message-id: <20210210165645.470195-2-gkurz@redhat.com>
+Patchwork-id: 101038
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] spapr: Adjust firmware path of PCI devices
+Bugzilla: 1912891
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Greg Kurz <groug@kaod.org>
+
+It is currently not possible to perform a strict boot from USB storage:
+
+$ qemu-system-ppc64 -accel kvm -nodefaults -nographic -serial stdio \
+	-boot strict=on \
+	-device qemu-xhci \
+	-device usb-storage,drive=disk,bootindex=0 \
+	-blockdev driver=file,node-name=disk,filename=fedora-ppc64le.qcow2
+
+SLOF **********************************************************************
+QEMU Starting
+ Build Date = Jul 17 2020 11:15:24
+ FW Version = git-e18ddad8516ff2cf
+ Press "s" to enter Open Firmware.
+
+Populating /vdevice methods
+Populating /vdevice/vty@71000000
+Populating /vdevice/nvram@71000001
+Populating /pci@800000020000000
+                     00 0000 (D) : 1b36 000d    serial bus [ usb-xhci ]
+No NVRAM common partition, re-initializing...
+Scanning USB
+  XHCI: Initializing
+    USB Storage
+       SCSI: Looking for devices
+          101000000000000 DISK     : "QEMU     QEMU HARDDISK    2.5+"
+Using default console: /vdevice/vty@71000000
+
+  Welcome to Open Firmware
+
+  Copyright (c) 2004, 2017 IBM Corporation All rights reserved.
+  This program and the accompanying materials are made available
+  under the terms of the BSD License available at
+  http://www.opensource.org/licenses/bsd-license.php
+
+Trying to load:  from: /pci@800000020000000/usb@0/storage@1/disk@101000000000000 ...
+E3405: No such device
+
+E3407: Load failed
+
+  Type 'boot' and press return to continue booting the system.
+  Type 'reset-all' and press return to reboot the system.
+
+Ready!
+0 >
+
+The device tree handed over by QEMU to SLOF indeed contains:
+
+qemu,boot-list =
+	"/pci@800000020000000/usb@0/storage@1/disk@101000000000000 HALT";
+
+but the device node is named usb-xhci@0, not usb@0.
+
+This happens because the firmware names of PCI devices returned
+by get_boot_devices_list() come from pcibus_get_fw_dev_path(),
+while the sPAPR PHB code uses a different naming scheme for
+device nodes. This inconsistency has always been there but it was
+hidden for a long time because SLOF used to rename USB device
+nodes, until this commit, merged in QEMU 4.2.0 :
+
+commit 85164ad4ed9960cac842fa4cc067c6b6699b0994
+Author: Alexey Kardashevskiy <aik@ozlabs.ru>
+Date:   Wed Sep 11 16:24:32 2019 +1000
+
+    pseries: Update SLOF firmware image
+
+    This fixes USB host bus adapter name in the device tree to match QEMU's
+    one.
+
+    Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+    Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+
+Fortunately, sPAPR implements the firmware path provider interface.
+This provides a way to override the default firmware paths.
+
+Just factor out the sPAPR PHB naming logic from spapr_dt_pci_device()
+to a helper, and use it in the sPAPR firmware path provider hook.
+
+Fixes: 85164ad4ed99 ("pseries: Update SLOF firmware image")
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Message-Id: <20210122170157.246374-1-groug@kaod.org>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 040bdafce12f750816d879442014df2999a995c4)
+Signed-off-by: Greg Kurz <gkurz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/ppc/spapr.c              |  5 +++++
+ hw/ppc/spapr_pci.c          | 33 ++++++++++++++++++---------------
+ include/hw/pci-host/spapr.h |  2 ++
+ 3 files changed, 25 insertions(+), 15 deletions(-)
+
+diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
+index 00b1ef075e..bee2299199 100644
+--- a/hw/ppc/spapr.c
++++ b/hw/ppc/spapr.c
+@@ -3013,6 +3013,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
+     SCSIDevice *d = CAST(SCSIDevice,  dev, TYPE_SCSI_DEVICE);
+     SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
+     VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
++    PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
+ 
+     if (d) {
+         void *spapr = CAST(void, bus->parent, "spapr-vscsi");
+@@ -3086,6 +3087,10 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
+         return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn));
+     }
+ 
++    if (pcidev) {
++        return spapr_pci_fw_dev_name(pcidev);
++    }
++
+     return NULL;
+ }
+ 
+diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
+index f6fbcf99ed..befa570aa8 100644
+--- a/hw/ppc/spapr_pci.c
++++ b/hw/ppc/spapr_pci.c
+@@ -1348,15 +1348,29 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
+     return offset;
+ }
+ 
++char *spapr_pci_fw_dev_name(PCIDevice *dev)
++{
++    const gchar *basename;
++    int slot = PCI_SLOT(dev->devfn);
++    int func = PCI_FUNC(dev->devfn);
++    uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
++
++    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
++                                  ccode & 0xff);
++
++    if (func != 0) {
++        return g_strdup_printf("%s@%x,%x", basename, slot, func);
++    } else {
++        return g_strdup_printf("%s@%x", basename, slot);
++    }
++}
++
+ /* create OF node for pci device and required OF DT properties */
+ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
+                                void *fdt, int parent_offset)
+ {
+     int offset;
+-    const gchar *basename;
+-    gchar *nodename;
+-    int slot = PCI_SLOT(dev->devfn);
+-    int func = PCI_FUNC(dev->devfn);
++    g_autofree gchar *nodename = spapr_pci_fw_dev_name(dev);
+     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+     ResourceProps rp;
+     SpaprDrc *drc = drc_from_dev(sphb, dev);
+@@ -1373,19 +1387,8 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
+     uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
+     gchar *loc_code;
+ 
+-    basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
+-                                  ccode & 0xff);
+-
+-    if (func != 0) {
+-        nodename = g_strdup_printf("%s@%x,%x", basename, slot, func);
+-    } else {
+-        nodename = g_strdup_printf("%s@%x", basename, slot);
+-    }
+-
+     _FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename));
+ 
+-    g_free(nodename);
+-
+     /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
+     _FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id));
+     _FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id));
+diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
+index 8877ff51fb..9522db9047 100644
+--- a/include/hw/pci-host/spapr.h
++++ b/include/hw/pci-host/spapr.h
+@@ -212,4 +212,6 @@ static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb)
+     return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
+ }
+ 
++char *spapr_pci_fw_dev_name(PCIDevice *dev);
++
+ #endif /* PCI_HOST_SPAPR_H */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch b/SOURCES/kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch
new file mode 100644
index 0000000..8d30406
--- /dev/null
+++ b/SOURCES/kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch
@@ -0,0 +1,165 @@
+From f9d332b1280cd3f6009b59323719548a36a7c52b Mon Sep 17 00:00:00 2001
+From: Daniel Henrique Barboza <dbarboza@redhat.com>
+Date: Mon, 21 Jun 2021 14:40:24 -0400
+Subject: [PATCH 2/4] spapr: Fix EEH capability issue on KVM guest for PCI
+ passthru
+
+RH-Author: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-id: <20210621144024.199732-2-dbarboza@redhat.com>
+Patchwork-id: 101740
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] spapr: Fix EEH capability issue on KVM guest for PCI passthru
+Bugzilla: 1957866
+RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+
+From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+
+With upstream kernel, especially after commit 98ba956f6a389
+("powerpc/pseries/eeh: Rework device EEH PE determination") we see that KVM
+guest isn't able to enable EEH option for PCI pass-through devices anymore.
+
+[root@atest-guest ~]# dmesg | grep EEH
+[    0.032337] EEH: pSeries platform initialized
+[    0.298207] EEH: No capable adapters found: recovery disabled.
+[root@atest-guest ~]#
+
+So far the linux kernel was assuming pe_config_addr equal to device's
+config_addr and using it to enable EEH on the PE through ibm,set-eeh-option
+RTAS call. Which wasn't the correct way as per PAPR. The linux kernel
+commit 98ba956f6a389 fixed this flow. With that fixed, linux now uses PE
+config address returned by ibm,get-config-addr-info2 RTAS call to enable
+EEH option per-PE basis instead of per-device basis. However this has
+uncovered a bug in qemu where ibm,set-eeh-option is treating PE config
+address as per-device config address.
+
+Hence in qemu guest with recent kernel the ibm,set-eeh-option RTAS call
+fails with -3 return value indicating that there is no PCI device exist for
+the specified PE config address. The rtas_ibm_set_eeh_option call uses
+pci_find_device() to get the PC device that matches specific bus and devfn
+extracted from PE config address passed as argument. Thus it tries to map
+the PE config address to a single specific PCI device 'bus->devices[devfn]'
+which always results into checking device on slot 0 'bus->devices[0]'.
+This succeeds when there is a pass-through device (vfio-pci) present on
+slot 0. But in cases where there is no pass-through device present in slot
+0, but present in non-zero slots, ibm,set-eeh-option call fails to enable
+the EEH capability.
+
+hw/ppc/spapr_pci_vfio.c: spapr_phb_vfio_eeh_set_option()
+   case RTAS_EEH_ENABLE: {
+        PCIHostState *phb;
+        PCIDevice *pdev;
+
+        /*
+         * The EEH functionality is enabled on basis of PCI device,
+         * instead of PE. We need check the validity of the PCI
+         * device address.
+         */
+        phb = PCI_HOST_BRIDGE(sphb);
+        pdev = pci_find_device(phb->bus,
+                               (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);
+        if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
+            return RTAS_OUT_PARAM_ERROR;
+        }
+
+hw/pci/pci.c:pci_find_device()
+
+PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
+{
+    bus = pci_find_bus_nr(bus, bus_num);
+
+    if (!bus)
+        return NULL;
+
+    return bus->devices[devfn];
+}
+
+This patch fixes ibm,set-eeh-option to check for presence of any PCI device
+(vfio-pci) under specified bus and enable the EEH if found. The current
+code already makes sure that all the devices on that bus are from same
+iommu group (within same PE) and fail very early if it does not.
+
+After this fix guest is able to find EEH capable devices and enable EEH
+recovery on it.
+
+[root@atest-guest ~]# dmesg | grep EEH
+[    0.048139] EEH: pSeries platform initialized
+[    0.405115] EEH: Capable adapter found: recovery enabled.
+[root@atest-guest ~]#
+
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+Message-Id: <162158429107.145117.5843504911924013125.stgit@jupiter>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit ac9ef668321ebb6eb871a0c4dd380fa7d7891b4e)
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/ppc/spapr_pci_vfio.c | 40 +++++++++++++++++++++++++++++++++-------
+ 1 file changed, 33 insertions(+), 7 deletions(-)
+
+diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
+index ecb34aaade..a411b08d60 100644
+--- a/hw/ppc/spapr_pci_vfio.c
++++ b/hw/ppc/spapr_pci_vfio.c
+@@ -48,6 +48,16 @@ void spapr_phb_vfio_reset(DeviceState *qdev)
+     spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
+ }
+ 
++static void spapr_eeh_pci_find_device(PCIBus *bus, PCIDevice *pdev,
++                                      void *opaque)
++{
++    bool *found = opaque;
++
++    if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
++        *found = true;
++    }
++}
++
+ int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
+                                   unsigned int addr, int option)
+ {
+@@ -60,17 +70,33 @@ int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
+         break;
+     case RTAS_EEH_ENABLE: {
+         PCIHostState *phb;
+-        PCIDevice *pdev;
++        bool found = false;
+ 
+         /*
+-         * The EEH functionality is enabled on basis of PCI device,
+-         * instead of PE. We need check the validity of the PCI
+-         * device address.
++         * The EEH functionality is enabled per sphb level instead of
++         * per PCI device. We have already identified this specific sphb
++         * based on buid passed as argument to ibm,set-eeh-option rtas
++         * call. Now we just need to check the validity of the PCI
++         * pass-through devices (vfio-pci) under this sphb bus.
++         * We have already validated that all the devices under this sphb
++         * are from same iommu group (within same PE) before comming here.
++         *
++         * Prior to linux commit 98ba956f6a389 ("powerpc/pseries/eeh:
++         * Rework device EEH PE determination") kernel would call
++         * eeh-set-option for each device in the PE using the device's
++         * config_address as the argument rather than the PE address.
++         * Hence if we check validity of supplied config_addr whether
++         * it matches to this PHB will cause issues with older kernel
++         * versions v5.9 and older. If we return an error from
++         * eeh-set-option when the argument isn't a valid PE address
++         * then older kernels (v5.9 and older) will interpret that as
++         * EEH not being supported.
+          */
+         phb = PCI_HOST_BRIDGE(sphb);
+-        pdev = pci_find_device(phb->bus,
+-                               (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);
+-        if (!pdev || !object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
++        pci_for_each_device(phb->bus, (addr >> 16) & 0xFF,
++                            spapr_eeh_pci_find_device, &found);
++
++        if (!found) {
+             return RTAS_OUT_PARAM_ERROR;
+         }
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch b/SOURCES/kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch
new file mode 100644
index 0000000..4f15509
--- /dev/null
+++ b/SOURCES/kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch
@@ -0,0 +1,50 @@
+From b46fdf56b1a7938468565838bdadf260870e4f9b Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 9 Jun 2021 10:05:00 -0400
+Subject: [PATCH 3/4] spapr: Remove stale comment about power-saving LPCR bits
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20210609100501.427096-2-lvivier@redhat.com>
+Patchwork-id: 101682
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] spapr: Remove stale comment about power-saving LPCR bits
+Bugzilla: 1969768
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+Commit 47a9b551547 ("spapr: Clean up handling of LPCR power-saving exit
+bits") moved this logic but did not remove the comment from the
+previous location.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Message-Id: <20210526091626.3388262-2-npiggin@gmail.com>
+Reviewed-by: Cédric Le Goater <clg@kaod.org>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit 7be3bf6c8429969f97728bb712d9a99997835607)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/ppc/spapr_rtas.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
+index 8d8d8cdfcb..295eac986e 100644
+--- a/hw/ppc/spapr_rtas.c
++++ b/hw/ppc/spapr_rtas.c
+@@ -163,7 +163,6 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
+ 
+     env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
+ 
+-    /* Enable Power-saving mode Exit Cause exceptions for the new CPU */
+     lpcr = env->spr[SPR_LPCR];
+     if (!pcc->interrupts_big_endian(callcpu)) {
+         lpcr |= LPCR_ILE;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch b/SOURCES/kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch
new file mode 100644
index 0000000..84abc74
--- /dev/null
+++ b/SOURCES/kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch
@@ -0,0 +1,89 @@
+From 28794dca79a94d01c8732b84fe6ac6ba2986ce45 Mon Sep 17 00:00:00 2001
+From: Laurent Vivier <lvivier@redhat.com>
+Date: Wed, 9 Jun 2021 10:05:01 -0400
+Subject: [PATCH 4/4] spapr: Set LPCR to current AIL mode when starting a new
+ CPU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Laurent Vivier <lvivier@redhat.com>
+Message-id: <20210609100501.427096-3-lvivier@redhat.com>
+Patchwork-id: 101683
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] spapr: Set LPCR to current AIL mode when starting a new CPU
+Bugzilla: 1969768
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: David Gibson <dgibson@redhat.com>
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+TCG does not keep track of AIL mode in a central place, it's based on
+the current LPCR[AIL] bits. Synchronize the new CPU's LPCR to the
+current LPCR in rtas_start_cpu(), similarly to the way the ILE bit is
+synchronized.
+
+Open-code the ILE setting as well now that the caller's LPCR is
+available directly, there is no need for the indirection.
+
+Without this, under both TCG and KVM, adding a POWER8/9/10 class CPU
+with a new core ID after a modern Linux has booted results in the new
+CPU's LPCR missing the LPCR[AIL]=0b11 setting that the other CPUs have.
+This can cause crashes and unexpected behaviour.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Message-Id: <20210526091626.3388262-3-npiggin@gmail.com>
+Reviewed-by: Cédric Le Goater <clg@kaod.org>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
+(cherry picked from commit ac559ecbea2649819e7b3fdd09f4e0243e0128db)
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/ppc/spapr_rtas.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
+index 295eac986e..5acb7c1f10 100644
+--- a/hw/ppc/spapr_rtas.c
++++ b/hw/ppc/spapr_rtas.c
+@@ -132,8 +132,8 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
+     target_ulong id, start, r3;
+     PowerPCCPU *newcpu;
+     CPUPPCState *env;
+-    PowerPCCPUClass *pcc;
+     target_ulong lpcr;
++    target_ulong caller_lpcr;
+ 
+     if (nargs != 3 || nret != 1) {
+         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+@@ -152,7 +152,6 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
+     }
+ 
+     env = &newcpu->env;
+-    pcc = POWERPC_CPU_GET_CLASS(newcpu);
+ 
+     if (!CPU(newcpu)->halted) {
+         rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+@@ -163,10 +162,15 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
+ 
+     env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
+ 
++    caller_lpcr = callcpu->env.spr[SPR_LPCR];
+     lpcr = env->spr[SPR_LPCR];
+-    if (!pcc->interrupts_big_endian(callcpu)) {
+-        lpcr |= LPCR_ILE;
+-    }
++
++    /* Set ILE the same way */
++    lpcr = (lpcr & ~LPCR_ILE) | (caller_lpcr & LPCR_ILE);
++
++    /* Set AIL the same way */
++    lpcr = (lpcr & ~LPCR_AIL) | (caller_lpcr & LPCR_AIL);
++
+     if (env->mmu_model == POWERPC_MMU_3_00) {
+         /*
+          * New cpus are expected to start in the same radix/hash mode
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch b/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch
new file mode 100644
index 0000000..e8c9f8b
--- /dev/null
+++ b/SOURCES/kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch
@@ -0,0 +1,54 @@
+From 07df0f52c26a3819bc02b4f2970b6735bcf15c5b Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:42 -0400
+Subject: [PATCH 4/9] sungem: switch to use qemu_receive_packet() for loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-5-jmaloy@redhat.com>
+Patchwork-id: 101786
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 4/9] sungem: switch to use qemu_receive_packet() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+This patch switches to use qemu_receive_packet() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 8c92060d3c0248bd4d515719a35922cd2391b9b4)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/sungem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/sungem.c b/hw/net/sungem.c
+index f31d41ac5b..8b202b5c15 100644
+--- a/hw/net/sungem.c
++++ b/hw/net/sungem.c
+@@ -305,7 +305,7 @@ static void sungem_send_packet(SunGEMState *s, const uint8_t *buf,
+     NetClientState *nc = qemu_get_queue(s->nic);
+ 
+     if (s->macregs[MAC_XIFCFG >> 2] & MAC_XIFCFG_LBCK) {
+-        nc->info->receive(nc, buf, size);
++        qemu_receive_packet(nc, buf, size);
+     } else {
+         qemu_send_packet(nc, buf, size);
+     }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-target-i386-add-fast-short-REP-MOV-support.patch b/SOURCES/kvm-target-i386-add-fast-short-REP-MOV-support.patch
new file mode 100644
index 0000000..51af7e7
--- /dev/null
+++ b/SOURCES/kvm-target-i386-add-fast-short-REP-MOV-support.patch
@@ -0,0 +1,59 @@
+From f33880c5f7a4e2cad25c22112da073273c6e2cfb Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 24 Feb 2021 11:30:35 -0500
+Subject: [PATCH 2/4] target/i386: add fast short REP MOV support
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20210224113037.15599-3-dgilbert@redhat.com>
+Patchwork-id: 101201
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 2/4] target/i386: add fast short REP MOV support
+Bugzilla: 1790620
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Chenyi Qiang <chenyi.qiang@intel.com>
+
+For CPUs support fast short REP MOV[CPUID.(EAX=7,ECX=0):EDX(bit4)], e.g
+Icelake and Tigerlake, expose it to the guest VM.
+
+Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
+Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
+Message-Id: <20200714084148.26690-2-chenyi.qiang@intel.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+(cherry picked from commit 5cb287d2bd578dfe4897458793b4fce35bc4f744)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 2 +-
+ target/i386/cpu.h | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 67dab94aa5..f6a9ed84b3 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1077,7 +1077,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         .type = CPUID_FEATURE_WORD,
+         .feat_names = {
+             NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
+-            NULL, NULL, NULL, NULL,
++            "fsrm", NULL, NULL, NULL,
+             "avx512-vp2intersect", NULL, "md-clear", NULL,
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL /* pconfig */, NULL,
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 8e2e52ed31..f5a4efcec6 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -770,6 +770,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_EDX_AVX512_4VNNIW     (1U << 2)
+ /* AVX512 Multiply Accumulation Single Precision */
+ #define CPUID_7_0_EDX_AVX512_4FMAPS     (1U << 3)
++/* Fast Short Rep Mov */
++#define CPUID_7_0_EDX_FSRM              (1U << 4)
+ /* AVX512 Vector Pair Intersection to a Pair of Mask Registers */
+ #define CPUID_7_0_EDX_AVX512_VP2INTERSECT (1U << 8)
+ /* Speculation Control */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-tftp-check-tftp_input-buffer-size.patch b/SOURCES/kvm-tftp-check-tftp_input-buffer-size.patch
new file mode 100644
index 0000000..85ed811
--- /dev/null
+++ b/SOURCES/kvm-tftp-check-tftp_input-buffer-size.patch
@@ -0,0 +1,53 @@
+From 6bd4d80f9274f76eb402ce85aa60729150b39980 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:34 -0400
+Subject: [PATCH 09/14] tftp: check tftp_input buffer size
+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: <20210708082537.1550263-6-marcandre.lureau@redhat.com>
+Patchwork-id: 101823
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 5/8] tftp: check tftp_input buffer size
+Bugzilla: 1970843
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Fixes: CVE-2021-3595
+Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/46
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970843
+
+(cherry picked from commit 3f17948137155f025f7809fdc38576d5d2451c3d)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/tftp.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/slirp/src/tftp.c b/slirp/src/tftp.c
+index 093c2e06a3..07e8f3cb2f 100644
+--- a/slirp/src/tftp.c
++++ b/slirp/src/tftp.c
+@@ -444,7 +444,11 @@ static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas,
+ 
+ void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m)
+ {
+-    struct tftp_t *tp = (struct tftp_t *)m->m_data;
++    struct tftp_t *tp = mtod_check(m, offsetof(struct tftp_t, x.tp_buf));
++
++    if (tp == NULL) {
++        return;
++    }
+ 
+     switch (ntohs(tp->tp_op)) {
+     case TFTP_RRQ:
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-tftp-introduce-a-header-structure.patch b/SOURCES/kvm-tftp-introduce-a-header-structure.patch
new file mode 100644
index 0000000..d8c8ddb
--- /dev/null
+++ b/SOURCES/kvm-tftp-introduce-a-header-structure.patch
@@ -0,0 +1,263 @@
+From af72e344459614fcf2746739f05494ef7e691a78 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:36 -0400
+Subject: [PATCH 10/14] tftp: introduce a header structure
+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: <20210708082537.1550263-7-marcandre.lureau@redhat.com>
+Patchwork-id: 101825
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 6/8] tftp: introduce a header structure
+Bugzilla: 1970819 1970835 1970843 1970853
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Instead of using a composed structure and potentially reading past the
+incoming buffer, use a different structure for the header.
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+(cherry picked from commit 990163cf3ac86b7875559f49602c4d76f46f6f30)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/tftp.c | 58 +++++++++++++++++++++++++-----------------------
+ slirp/src/tftp.h |  6 ++++-
+ 2 files changed, 35 insertions(+), 29 deletions(-)
+
+diff --git a/slirp/src/tftp.c b/slirp/src/tftp.c
+index 07e8f3cb2f..53e04d0aeb 100644
+--- a/slirp/src/tftp.c
++++ b/slirp/src/tftp.c
+@@ -50,7 +50,7 @@ static void tftp_session_terminate(struct tftp_session *spt)
+ }
+ 
+ static int tftp_session_allocate(Slirp *slirp, struct sockaddr_storage *srcsas,
+-                                 struct tftp_t *tp)
++                                 struct tftphdr *hdr)
+ {
+     struct tftp_session *spt;
+     int k;
+@@ -75,7 +75,7 @@ found:
+     memcpy(&spt->client_addr, srcsas, sockaddr_size(srcsas));
+     spt->fd = -1;
+     spt->block_size = 512;
+-    spt->client_port = tp->udp.uh_sport;
++    spt->client_port = hdr->udp.uh_sport;
+     spt->slirp = slirp;
+ 
+     tftp_session_update(spt);
+@@ -84,7 +84,7 @@ found:
+ }
+ 
+ static int tftp_session_find(Slirp *slirp, struct sockaddr_storage *srcsas,
+-                             struct tftp_t *tp)
++                             struct tftphdr *hdr)
+ {
+     struct tftp_session *spt;
+     int k;
+@@ -94,7 +94,7 @@ static int tftp_session_find(Slirp *slirp, struct sockaddr_storage *srcsas,
+ 
+         if (tftp_session_in_use(spt)) {
+             if (sockaddr_equal(&spt->client_addr, srcsas)) {
+-                if (spt->client_port == tp->udp.uh_sport) {
++                if (spt->client_port == hdr->udp.uh_sport) {
+                     return k;
+                 }
+             }
+@@ -146,13 +146,13 @@ static struct tftp_t *tftp_prep_mbuf_data(struct tftp_session *spt,
+ }
+ 
+ static void tftp_udp_output(struct tftp_session *spt, struct mbuf *m,
+-                            struct tftp_t *recv_tp)
++                            struct tftphdr *hdr)
+ {
+     if (spt->client_addr.ss_family == AF_INET6) {
+         struct sockaddr_in6 sa6, da6;
+ 
+         sa6.sin6_addr = spt->slirp->vhost_addr6;
+-        sa6.sin6_port = recv_tp->udp.uh_dport;
++        sa6.sin6_port = hdr->udp.uh_dport;
+         da6.sin6_addr = ((struct sockaddr_in6 *)&spt->client_addr)->sin6_addr;
+         da6.sin6_port = spt->client_port;
+ 
+@@ -161,7 +161,7 @@ static void tftp_udp_output(struct tftp_session *spt, struct mbuf *m,
+         struct sockaddr_in sa4, da4;
+ 
+         sa4.sin_addr = spt->slirp->vhost_addr;
+-        sa4.sin_port = recv_tp->udp.uh_dport;
++        sa4.sin_port = hdr->udp.uh_dport;
+         da4.sin_addr = ((struct sockaddr_in *)&spt->client_addr)->sin_addr;
+         da4.sin_port = spt->client_port;
+ 
+@@ -183,7 +183,7 @@ static int tftp_send_oack(struct tftp_session *spt, const char *keys[],
+ 
+     tp = tftp_prep_mbuf_data(spt, m);
+ 
+-    tp->tp_op = htons(TFTP_OACK);
++    tp->hdr.tp_op = htons(TFTP_OACK);
+     for (i = 0; i < nb; i++) {
+         n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s",
+                       keys[i]) +
+@@ -195,7 +195,7 @@ static int tftp_send_oack(struct tftp_session *spt, const char *keys[],
+ 
+     m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + n -
+                sizeof(struct udphdr);
+-    tftp_udp_output(spt, m, recv_tp);
++    tftp_udp_output(spt, m, &recv_tp->hdr);
+ 
+     return 0;
+ }
+@@ -216,21 +216,21 @@ static void tftp_send_error(struct tftp_session *spt, uint16_t errorcode,
+ 
+     tp = tftp_prep_mbuf_data(spt, m);
+ 
+-    tp->tp_op = htons(TFTP_ERROR);
++    tp->hdr.tp_op = htons(TFTP_ERROR);
+     tp->x.tp_error.tp_error_code = htons(errorcode);
+     slirp_pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg),
+                   msg);
+ 
+     m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 +
+                strlen(msg) - sizeof(struct udphdr);
+-    tftp_udp_output(spt, m, recv_tp);
++    tftp_udp_output(spt, m, &recv_tp->hdr);
+ 
+ out:
+     tftp_session_terminate(spt);
+ }
+ 
+ static void tftp_send_next_block(struct tftp_session *spt,
+-                                 struct tftp_t *recv_tp)
++                                 struct tftphdr *hdr)
+ {
+     struct mbuf *m;
+     struct tftp_t *tp;
+@@ -244,7 +244,7 @@ static void tftp_send_next_block(struct tftp_session *spt,
+ 
+     tp = tftp_prep_mbuf_data(spt, m);
+ 
+-    tp->tp_op = htons(TFTP_DATA);
++    tp->hdr.tp_op = htons(TFTP_DATA);
+     tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff);
+ 
+     nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf,
+@@ -262,7 +262,7 @@ static void tftp_send_next_block(struct tftp_session *spt,
+ 
+     m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX - nobytes) -
+                sizeof(struct udphdr);
+-    tftp_udp_output(spt, m, recv_tp);
++    tftp_udp_output(spt, m, hdr);
+ 
+     if (nobytes == spt->block_size) {
+         tftp_session_update(spt);
+@@ -285,12 +285,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
+     int nb_options = 0;
+ 
+     /* check if a session already exists and if so terminate it */
+-    s = tftp_session_find(slirp, srcsas, tp);
++    s = tftp_session_find(slirp, srcsas, &tp->hdr);
+     if (s >= 0) {
+         tftp_session_terminate(&slirp->tftp_sessions[s]);
+     }
+ 
+-    s = tftp_session_allocate(slirp, srcsas, tp);
++    s = tftp_session_allocate(slirp, srcsas, &tp->hdr);
+ 
+     if (s < 0) {
+         return;
+@@ -411,29 +411,29 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
+     }
+ 
+     spt->block_nr = 0;
+-    tftp_send_next_block(spt, tp);
++    tftp_send_next_block(spt, &tp->hdr);
+ }
+ 
+ static void tftp_handle_ack(Slirp *slirp, struct sockaddr_storage *srcsas,
+-                            struct tftp_t *tp, int pktlen)
++                            struct tftphdr *hdr)
+ {
+     int s;
+ 
+-    s = tftp_session_find(slirp, srcsas, tp);
++    s = tftp_session_find(slirp, srcsas, hdr);
+ 
+     if (s < 0) {
+         return;
+     }
+ 
+-    tftp_send_next_block(&slirp->tftp_sessions[s], tp);
++    tftp_send_next_block(&slirp->tftp_sessions[s], hdr);
+ }
+ 
+ static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas,
+-                              struct tftp_t *tp, int pktlen)
++                              struct tftphdr *hdr)
+ {
+     int s;
+ 
+-    s = tftp_session_find(slirp, srcsas, tp);
++    s = tftp_session_find(slirp, srcsas, hdr);
+ 
+     if (s < 0) {
+         return;
+@@ -444,23 +444,25 @@ static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas,
+ 
+ void tftp_input(struct sockaddr_storage *srcsas, struct mbuf *m)
+ {
+-    struct tftp_t *tp = mtod_check(m, offsetof(struct tftp_t, x.tp_buf));
++    struct tftphdr *hdr = mtod_check(m, sizeof(struct tftphdr));
+ 
+-    if (tp == NULL) {
++    if (hdr == NULL) {
+         return;
+     }
+ 
+-    switch (ntohs(tp->tp_op)) {
++    switch (ntohs(hdr->tp_op)) {
+     case TFTP_RRQ:
+-        tftp_handle_rrq(m->slirp, srcsas, tp, m->m_len);
++        tftp_handle_rrq(m->slirp, srcsas,
++                        mtod(m, struct tftp_t *),
++                        m->m_len);
+         break;
+ 
+     case TFTP_ACK:
+-        tftp_handle_ack(m->slirp, srcsas, tp, m->m_len);
++        tftp_handle_ack(m->slirp, srcsas, hdr);
+         break;
+ 
+     case TFTP_ERROR:
+-        tftp_handle_error(m->slirp, srcsas, tp, m->m_len);
++        tftp_handle_error(m->slirp, srcsas, hdr);
+         break;
+     }
+ }
+diff --git a/slirp/src/tftp.h b/slirp/src/tftp.h
+index c47bb43c7d..021f6cf109 100644
+--- a/slirp/src/tftp.h
++++ b/slirp/src/tftp.h
+@@ -18,9 +18,13 @@
+ #define TFTP_FILENAME_MAX 512
+ #define TFTP_BLOCKSIZE_MAX 1428
+ 
+-struct tftp_t {
++struct tftphdr {
+     struct udphdr udp;
+     uint16_t tp_op;
++} SLIRP_PACKED;
++
++struct tftp_t {
++    struct tftphdr hdr;
+     union {
+         struct {
+             uint16_t tp_block_nr;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch b/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch
new file mode 100644
index 0000000..4da71cc
--- /dev/null
+++ b/SOURCES/kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch
@@ -0,0 +1,53 @@
+From 87cacc268f37758553ad93fefa8b312ed0bd2520 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 29 Jun 2021 03:42:43 -0400
+Subject: [PATCH 5/9] tx_pkt: switch to use qemu_receive_packet_iov() for
+ loopback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210629034247.3286477-6-jmaloy@redhat.com>
+Patchwork-id: 101788
+O-Subject: [RHEL-8.4.0.z qemu-kvm PATCH v2 5/9] tx_pkt: switch to use qemu_receive_packet_iov() for loopback
+Bugzilla: 1932917
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Thomas Huth <thuth@redhat.com>
+
+From: Jason Wang <jasowang@redhat.com>
+
+This patch switches to use qemu_receive_receive_iov() which can detect
+reentrancy and return early.
+
+This is intended to address CVE-2021-3416.
+
+Cc: Prasad J Pandit <ppandit@redhat.com>
+Cc: qemu-stable@nongnu.org
+Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+(cherry picked from commit 8c552542b81e56ff532dd27ec6e5328954bdda73)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/net/net_tx_pkt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
+index 54d4c3bbd0..646cdfaf4d 100644
+--- a/hw/net/net_tx_pkt.c
++++ b/hw/net/net_tx_pkt.c
+@@ -544,7 +544,7 @@ static inline void net_tx_pkt_sendv(struct NetTxPkt *pkt,
+     NetClientState *nc, const struct iovec *iov, int iov_cnt)
+ {
+     if (pkt->is_loopback) {
+-        nc->info->receive_iov(nc, iov, iov_cnt);
++        qemu_receive_packet_iov(nc, iov, iov_cnt);
+     } else {
+         qemu_sendv_packet(nc, iov, iov_cnt);
+     }
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-udp-check-upd_input-buffer-size.patch b/SOURCES/kvm-udp-check-upd_input-buffer-size.patch
new file mode 100644
index 0000000..0f3c6f3
--- /dev/null
+++ b/SOURCES/kvm-udp-check-upd_input-buffer-size.patch
@@ -0,0 +1,52 @@
+From 1b8aa33b218a8ff3e8aa2f1b6875df40fd70f0ed Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:40 -0400
+Subject: [PATCH 11/14] udp: check upd_input buffer size
+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: <20210708082537.1550263-8-marcandre.lureau@redhat.com>
+Patchwork-id: 101826
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 7/8] udp: check upd_input buffer size
+Bugzilla: 1970853
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Fixes: CVE-2021-3594
+Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/47
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970853
+
+(cherry picked from commit 74572be49247c8c5feae7c6e0b50c4f569ca9824)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/udp.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/slirp/src/udp.c b/slirp/src/udp.c
+index ae23ba4b2a..86142bba14 100644
+--- a/slirp/src/udp.c
++++ b/slirp/src/udp.c
+@@ -90,7 +90,10 @@ void udp_input(register struct mbuf *m, int iphlen)
+     /*
+      * Get IP and UDP header together in first mbuf.
+      */
+-    ip = mtod(m, struct ip *);
++    ip = mtod_check(m, iphlen + sizeof(struct udphdr));
++    if (ip == NULL) {
++        goto bad;
++    }
+     uh = (struct udphdr *)((char *)ip + iphlen);
+ 
+     /*
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-upd6-check-udp6_input-buffer-size.patch b/SOURCES/kvm-upd6-check-udp6_input-buffer-size.patch
new file mode 100644
index 0000000..2aa3a24
--- /dev/null
+++ b/SOURCES/kvm-upd6-check-udp6_input-buffer-size.patch
@@ -0,0 +1,52 @@
+From 6808086932ddc83fd748c46fea495e7004299b55 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Thu, 29 Jul 2021 04:56:31 -0400
+Subject: [PATCH 08/14] upd6: check udp6_input buffer size
+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: <20210708082537.1550263-5-marcandre.lureau@redhat.com>
+Patchwork-id: 101822
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 4/8] upd6: check udp6_input buffer size
+Bugzilla: 1970835
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Eric Blake <eblake@redhat.com>
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+From: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+Fixes: CVE-2021-3593
+Fixes: https://gitlab.freedesktop.org/slirp/libslirp/-/issues/45
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+
+BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1970835
+
+(cherry picked from commit de71c15de66ba9350bf62c45b05f8fbff166517b)
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
+---
+ slirp/src/udp6.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/slirp/src/udp6.c b/slirp/src/udp6.c
+index 6f9486bbca..8c490e4d10 100644
+--- a/slirp/src/udp6.c
++++ b/slirp/src/udp6.c
+@@ -28,7 +28,10 @@ void udp6_input(struct mbuf *m)
+     ip = mtod(m, struct ip6 *);
+     m->m_len -= iphlen;
+     m->m_data += iphlen;
+-    uh = mtod(m, struct udphdr *);
++    uh = mtod_check(m, sizeof(struct udphdr));
++    if (uh == NULL) {
++        goto bad;
++    }
+     m->m_len += iphlen;
+     m->m_data -= iphlen;
+ 
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-vfio-ccw-Connect-the-device-request-notifier.patch b/SOURCES/kvm-vfio-ccw-Connect-the-device-request-notifier.patch
new file mode 100644
index 0000000..298fb29
--- /dev/null
+++ b/SOURCES/kvm-vfio-ccw-Connect-the-device-request-notifier.patch
@@ -0,0 +1,128 @@
+From db6a782f8b9ba062f195ff504b4d2f93e471fecc Mon Sep 17 00:00:00 2001
+From: Thomas Huth <thuth@redhat.com>
+Date: Tue, 11 May 2021 11:24:05 -0400
+Subject: [PATCH 2/5] vfio-ccw: Connect the device request notifier
+
+RH-Author: Thomas Huth <thuth@redhat.com>
+Message-id: <20210511112405.297037-3-thuth@redhat.com>
+Patchwork-id: 101536
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] vfio-ccw: Connect the device request notifier
+Bugzilla: 1940450
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: David Hildenbrand <david@redhat.com>
+
+Now that the vfio-ccw code has a notifier interface to request that
+a device be unplugged, let's wire that together.
+
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Cornelia Huck <cohuck@redhat.com>
+Message-Id: <20210104202057.48048-4-farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+(cherry picked from commit b2f96f9e4f5fbc8f2770a436191cb328da4d5350)
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940450
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/vfio/ccw.c | 40 ++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 4 deletions(-)
+
+diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
+index b72a505893..3d450fe1c9 100644
+--- a/hw/vfio/ccw.c
++++ b/hw/vfio/ccw.c
+@@ -49,6 +49,7 @@ struct VFIOCCWDevice {
+     struct ccw_crw_region *crw_region;
+     EventNotifier io_notifier;
+     EventNotifier crw_notifier;
++    EventNotifier req_notifier;
+     bool force_orb_pfch;
+     bool warned_orb_pfch;
+ };
+@@ -287,6 +288,21 @@ static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
+     } while (1);
+ }
+ 
++static void vfio_ccw_req_notifier_handler(void *opaque)
++{
++    VFIOCCWDevice *vcdev = opaque;
++    Error *err = NULL;
++
++    if (!event_notifier_test_and_clear(&vcdev->req_notifier)) {
++        return;
++    }
++
++    qdev_unplug(DEVICE(vcdev), &err);
++    if (err) {
++        warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
++    }
++}
++
+ static void vfio_ccw_crw_notifier_handler(void *opaque)
+ {
+     VFIOCCWDevice *vcdev = opaque;
+@@ -386,6 +402,10 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
+         notifier = &vcdev->crw_notifier;
+         fd_read = vfio_ccw_crw_notifier_handler;
+         break;
++    case VFIO_CCW_REQ_IRQ_INDEX:
++        notifier = &vcdev->req_notifier;
++        fd_read = vfio_ccw_req_notifier_handler;
++        break;
+     default:
+         error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
+         return;
+@@ -440,6 +460,9 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
+     case VFIO_CCW_CRW_IRQ_INDEX:
+         notifier = &vcdev->crw_notifier;
+         break;
++    case VFIO_CCW_REQ_IRQ_INDEX:
++        notifier = &vcdev->req_notifier;
++        break;
+     default:
+         error_report("vfio: Unsupported device irq(%d)", irq);
+         return;
+@@ -657,20 +680,28 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
+ 
+     vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err);
+     if (err) {
+-        goto out_notifier_err;
++        goto out_io_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;
++            goto out_crw_notifier_err;
+         }
+     }
+ 
++    vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err);
++    if (err) {
++        goto out_req_notifier_err;
++    }
++
+     return;
+ 
+-out_notifier_err:
++out_req_notifier_err:
++    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
++out_crw_notifier_err:
++    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
++out_io_notifier_err:
+     vfio_ccw_put_region(vcdev);
+ out_region_err:
+     vfio_ccw_put_device(vcdev);
+@@ -692,6 +723,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_REQ_IRQ_INDEX);
+     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);
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch b/SOURCES/kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch
new file mode 100644
index 0000000..90b6b35
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch
@@ -0,0 +1,72 @@
+From 3ec945ba7c2649cca13cf6070c6365b1262ad1ec Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Fri, 6 Aug 2021 11:58:26 -0400
+Subject: [PATCH 1/2] virtiofsd: Disable remote posix locks by default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20210806115827.740945-2-mreitz@redhat.com>
+Patchwork-id: 101970
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/2] virtiofsd: Disable remote posix locks by default
+Bugzilla: 1967496
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Vivek Goyal <vgoyal@redhat.com>
+
+From: Vivek Goyal <vgoyal@redhat.com>
+
+Right now we enable remote posix locks by default. That means when guest
+does a posix lock it sends request to server (virtiofsd). But currently
+we only support non-blocking posix lock and return -EOPNOTSUPP for
+blocking version.
+
+This means that existing applications which are doing blocking posix
+locks get -EOPNOTSUPP and fail. To avoid this, people have been
+running virtiosd with option "-o no_posix_lock". For new users it
+is still a surprise and trial and error takes them to this option.
+
+Given posix lock implementation is not complete in virtiofsd, disable
+it by default. This means that posix locks will work with-in applications
+in a guest but not across guests. Anyway we don't support sharing
+filesystem among different guests yet in virtiofs so this should
+not lead to any kind of surprise or regression and will make life
+little easier for virtiofs users.
+
+Reported-by: Aa Aa <jimbothom@yandex.com>
+Suggested-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 88fc107956a5812649e5918e0c092d3f78bb28ad)
+
+Conflicts:
+	docs/tools/virtiofsd.rst
+	We do not have virtiofsd.rst downstream (added upstream in
+	commit 6a7e2bbee5fa), so I dropped that hunk (which effectively
+	updated the default value in the man page).
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+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 cb0992f2db..b47029da89 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -3001,7 +3001,7 @@ int main(int argc, char *argv[])
+     struct lo_data lo = {
+         .debug = 0,
+         .writeback = 0,
+-        .posix_lock = 1,
++        .posix_lock = 0,
+         .proc_self_fd = -1,
+     };
+     struct lo_map_elem *root_elem;
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch b/SOURCES/kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch
new file mode 100644
index 0000000..98907a5
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch
@@ -0,0 +1,51 @@
+From 6abfb7b3c37015ff901d11f178bc6900deec2acf Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Fri, 6 Aug 2021 11:58:27 -0400
+Subject: [PATCH 2/2] virtiofsd: Fix the help message of posix lock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20210806115827.740945-3-mreitz@redhat.com>
+Patchwork-id: 101969
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] virtiofsd: Fix the help message of posix lock
+Bugzilla: 1967496
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Vivek Goyal <vgoyal@redhat.com>
+
+From: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
+
+The commit 88fc107956a5812649e5918e0c092d3f78bb28ad disabled remote
+posix locks by default. But the --help message still says it is enabled
+by default. So fix it to output no_posix_lock.
+
+Signed-off-by: Jiachen Zhang <zhangjiachen.jaycee@bytedance.com>
+Message-Id: <20201027081558.29904-1-zhangjiachen.jaycee@bytedance.com>
+Reviewed-by: Philippe Mathieu-Daudé <philmd@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 0429eaf518be1d4742356056e6c886b7f9bc9712)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/helper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
+index 5b222ea49b..813d9490e5 100644
+--- a/tools/virtiofsd/helper.c
++++ b/tools/virtiofsd/helper.c
+@@ -163,7 +163,7 @@ void fuse_cmdline_help(void)
+            "                               default: false\n"
+            "    -o posix_lock|no_posix_lock\n"
+            "                               enable/disable remote posix lock\n"
+-           "                               default: posix_lock\n"
++           "                               default: no_posix_lock\n"
+            "    -o readdirplus|no_readdirplus\n"
+            "                               enable/disable readirplus\n"
+            "                               default: readdirplus except with "
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtiofsd-Whitelist-fchmod.patch b/SOURCES/kvm-virtiofsd-Whitelist-fchmod.patch
new file mode 100644
index 0000000..a4f95d9
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-Whitelist-fchmod.patch
@@ -0,0 +1,79 @@
+From 181ed1777c3dd50b1ff9907b0a4199e845af1270 Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Fri, 18 Jun 2021 16:21:17 -0400
+Subject: [PATCH 1/4] virtiofsd: Whitelist fchmod
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Max Reitz <mreitz@redhat.com>
+Message-id: <20210618162117.97775-2-mreitz@redhat.com>
+Patchwork-id: 101719
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 1/1] virtiofsd: Whitelist fchmod
+Bugzilla: 1967914
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Vivek Goyal <vgoyal@redhat.com>
+RH-Acked-by: Connor Kuehl <ckuehl@redhat.com>
+
+lo_setattr() invokes fchmod() in a rarely used code path, so it should
+be whitelisted or virtiofsd will crash with EBADSYS.
+
+Said code path can be triggered for example as follows:
+
+On the host, in the shared directory, create a file with the sticky bit
+set and a security.capability xattr:
+(1) # touch foo
+(2) # chmod u+s foo
+(3) # setcap '' foo
+
+Then in the guest let some process truncate that file after it has
+dropped all of its capabilities (at least CAP_FSETID):
+
+int main(int argc, char *argv[])
+{
+    capng_setpid(getpid());
+    capng_clear(CAPNG_SELECT_BOTH);
+    capng_updatev(CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, 0);
+    capng_apply(CAPNG_SELECT_BOTH);
+
+    ftruncate(open(argv[1], O_RDWR), 0);
+}
+
+This will cause the guest kernel to drop the sticky bit (i.e. perform a
+mode change) as part of the truncate (where FATTR_FH is set), and that
+will cause virtiofsd to invoke fchmod() instead of fchmodat().
+
+(A similar configuration exists further below with futimens() vs.
+utimensat(), but the former is not a syscall but just a wrapper for the
+latter, so no further whitelisting is required.)
+
+Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1842667
+Reported-by: Qian Cai <caiqian@redhat.com>
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Message-Id: <20200608093111.14942-1-mreitz@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Vivek Goyal <vgoyal@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+(cherry picked from commit 63659fe74e76f5c5285466f0c5cfbdca65b3688e)
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ tools/virtiofsd/seccomp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/virtiofsd/seccomp.c b/tools/virtiofsd/seccomp.c
+index bd9e7b083c..3b1522acdd 100644
+--- a/tools/virtiofsd/seccomp.c
++++ b/tools/virtiofsd/seccomp.c
+@@ -42,6 +42,7 @@ static const int syscall_whitelist[] = {
+     SCMP_SYS(exit_group),
+     SCMP_SYS(fallocate),
+     SCMP_SYS(fchdir),
++    SCMP_SYS(fchmod),
+     SCMP_SYS(fchmodat),
+     SCMP_SYS(fchownat),
+     SCMP_SYS(fcntl),
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-virtiofsd-extract-lo_do_open-from-lo_open.patch b/SOURCES/kvm-virtiofsd-extract-lo_do_open-from-lo_open.patch
new file mode 100644
index 0000000..b0f678f
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-extract-lo_do_open-from-lo_open.patch
@@ -0,0 +1,167 @@
+From c02ebc7e43f55b9423a065a7c53ba72bdb821c98 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 9 Feb 2021 23:14:54 -0500
+Subject: [PATCH 1/3] virtiofsd: extract lo_do_open() from lo_open()
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210209231456.1555472-2-jmaloy@redhat.com>
+Patchwork-id: 101024
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/3] virtiofsd: extract lo_do_open() from lo_open()
+Bugzilla: 1919111
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+Both lo_open() and lo_create() have similar code to open a file. Extract
+a common lo_do_open() function from lo_open() that will be used by
+lo_create() in a later commit.
+
+Since lo_do_open() does not otherwise need fuse_req_t req, convert
+lo_add_fd_mapping() to use struct lo_data *lo instead.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20210204150208.367837-2-stefanha@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+(cherry-picked from commit 8afaaee976965b7fb90ec225a51d60f35c5f173c)
+
+Conflict: update_open_flags() takes fewer arguments in this version
+          than in upstream. Instead of applying commit e12a0edafeb
+          ("virtiofsd: Add -o allow_direct_io|no_allow_direct_io
+          options") we keep the old signature, since this seems to
+          be an unrelated change.
+
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Jon Maloy <jmaloy.redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 73 ++++++++++++++++++++------------
+ 1 file changed, 46 insertions(+), 27 deletions(-)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index f41a6b07c8..518ba11c47 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -439,17 +439,17 @@ static void lo_map_remove(struct lo_map *map, size_t key)
+ }
+ 
+ /* Assumes lo->mutex is held */
+-static ssize_t lo_add_fd_mapping(fuse_req_t req, int fd)
++static ssize_t lo_add_fd_mapping(struct lo_data *lo, int fd)
+ {
+     struct lo_map_elem *elem;
+ 
+-    elem = lo_map_alloc_elem(&lo_data(req)->fd_map);
++    elem = lo_map_alloc_elem(&lo->fd_map);
+     if (!elem) {
+         return -1;
+     }
+ 
+     elem->fd = fd;
+-    return elem - lo_data(req)->fd_map.elems;
++    return elem - lo->fd_map.elems;
+ }
+ 
+ /* Assumes lo->mutex is held */
+@@ -1712,6 +1712,38 @@ static void update_open_flags(int writeback, struct fuse_file_info *fi)
+     fi->flags &= ~O_DIRECT;
+ }
+ 
++static int lo_do_open(struct lo_data *lo, struct lo_inode *inode,
++                      struct fuse_file_info *fi)
++{
++    char buf[64];
++    ssize_t fh;
++    int fd;
++
++    update_open_flags(lo->writeback, fi);
++
++    sprintf(buf, "%i", inode->fd);
++    fd = openat(lo->proc_self_fd, buf, fi->flags & ~O_NOFOLLOW);
++    if (fd == -1) {
++        return errno;
++    }
++
++    pthread_mutex_lock(&lo->mutex);
++    fh = lo_add_fd_mapping(lo, fd);
++    pthread_mutex_unlock(&lo->mutex);
++    if (fh == -1) {
++        close(fd);
++        return ENOMEM;
++    }
++
++    fi->fh = fh;
++    if (lo->cache == CACHE_NONE) {
++        fi->direct_io = 1;
++    } else if (lo->cache == CACHE_ALWAYS) {
++        fi->keep_cache = 1;
++    }
++    return 0;
++}
++
+ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
+                       mode_t mode, struct fuse_file_info *fi)
+ {
+@@ -1752,7 +1784,7 @@ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
+         ssize_t fh;
+ 
+         pthread_mutex_lock(&lo->mutex);
+-        fh = lo_add_fd_mapping(req, fd);
++        fh = lo_add_fd_mapping(lo, fd);
+         pthread_mutex_unlock(&lo->mutex);
+         if (fh == -1) {
+             close(fd);
+@@ -1943,38 +1975,25 @@ static void lo_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
+ 
+ static void lo_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+ {
+-    int fd;
+-    ssize_t fh;
+-    char buf[64];
+     struct lo_data *lo = lo_data(req);
++    struct lo_inode *inode = lo_inode(req, ino);
++    int err;
+ 
+     fuse_log(FUSE_LOG_DEBUG, "lo_open(ino=%" PRIu64 ", flags=%d)\n", ino,
+              fi->flags);
+ 
+-    update_open_flags(lo->writeback, fi);
+-
+-    sprintf(buf, "%i", lo_fd(req, ino));
+-    fd = openat(lo->proc_self_fd, buf, fi->flags & ~O_NOFOLLOW);
+-    if (fd == -1) {
+-        return (void)fuse_reply_err(req, errno);
+-    }
+-
+-    pthread_mutex_lock(&lo->mutex);
+-    fh = lo_add_fd_mapping(req, fd);
+-    pthread_mutex_unlock(&lo->mutex);
+-    if (fh == -1) {
+-        close(fd);
+-        fuse_reply_err(req, ENOMEM);
++    if (!inode) {
++        fuse_reply_err(req, EBADF);
+         return;
+     }
+ 
+-    fi->fh = fh;
+-    if (lo->cache == CACHE_NONE) {
+-        fi->direct_io = 1;
+-    } else if (lo->cache == CACHE_ALWAYS) {
+-        fi->keep_cache = 1;
++    err = lo_do_open(lo, inode, fi);
++    lo_inode_put(lo, &inode);
++    if (err) {
++        fuse_reply_err(req, err);
++    } else {
++        fuse_reply_open(req, fi);
+     }
+-    fuse_reply_open(req, fi);
+ }
+ 
+ static void lo_release(fuse_req_t req, fuse_ino_t ino,
+-- 
+2.18.2
+
diff --git a/SOURCES/kvm-virtiofsd-optionally-return-inode-pointer-from-lo_do.patch b/SOURCES/kvm-virtiofsd-optionally-return-inode-pointer-from-lo_do.patch
new file mode 100644
index 0000000..f21d793
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-optionally-return-inode-pointer-from-lo_do.patch
@@ -0,0 +1,124 @@
+From f2c0b07088966c396ddcee54f4bed97cdb01192f Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 9 Feb 2021 23:14:55 -0500
+Subject: [PATCH 2/3] virtiofsd: optionally return inode pointer from
+ lo_do_lookup()
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210209231456.1555472-3-jmaloy@redhat.com>
+Patchwork-id: 101022
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 2/3] virtiofsd: optionally return inode pointer from lo_do_lookup()
+Bugzilla: 1919111
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+lo_do_lookup() finds an existing inode or allocates a new one. It
+increments nlookup so that the inode stays alive until the client
+releases it.
+
+Existing callers don't need the struct lo_inode so the function doesn't
+return it. Extend the function to optionally return the inode. The next
+commit will need it.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Message-Id: <20210204150208.367837-3-stefanha@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+(cherry-picked from commit 22d2ece71e533310da31f2857ebc4a00d91968b3)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Jon Maloy <jmaloy.redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index 518ba11c47..e5bd3d73e4 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -878,11 +878,13 @@ static void posix_locks_value_destroy(gpointer data)
+ }
+ 
+ /*
+- * Increments nlookup and caller must release refcount using
+- * lo_inode_put(&parent).
++ * Increments nlookup on the inode on success. unref_inode_lolocked() must be
++ * called eventually to decrement nlookup again. If inodep is non-NULL, the
++ * inode pointer is stored and the caller must call lo_inode_put().
+  */
+ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
+-                        struct fuse_entry_param *e)
++                        struct fuse_entry_param *e,
++                        struct lo_inode **inodep)
+ {
+     int newfd;
+     int res;
+@@ -891,6 +893,10 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
+     struct lo_inode *inode = NULL;
+     struct lo_inode *dir = lo_inode(req, parent);
+ 
++    if (inodep) {
++        *inodep = NULL;
++    }
++
+     /*
+      * name_to_handle_at() and open_by_handle_at() can reach here with fuse
+      * mount point in guest, but we don't have its inode info in the
+@@ -953,7 +959,14 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
+         pthread_mutex_unlock(&lo->mutex);
+     }
+     e->ino = inode->fuse_ino;
+-    lo_inode_put(lo, &inode);
++
++    /* Transfer ownership of inode pointer to caller or drop it */
++    if (inodep) {
++        *inodep = inode;
++    } else {
++        lo_inode_put(lo, &inode);
++    }
++
+     lo_inode_put(lo, &dir);
+ 
+     fuse_log(FUSE_LOG_DEBUG, "  %lli/%s -> %lli\n", (unsigned long long)parent,
+@@ -988,7 +1001,7 @@ static void lo_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
+         return;
+     }
+ 
+-    err = lo_do_lookup(req, parent, name, &e);
++    err = lo_do_lookup(req, parent, name, &e, NULL);
+     if (err) {
+         fuse_reply_err(req, err);
+     } else {
+@@ -1098,7 +1111,7 @@ static void lo_mknod_symlink(fuse_req_t req, fuse_ino_t parent,
+         goto out;
+     }
+ 
+-    saverr = lo_do_lookup(req, parent, name, &e);
++    saverr = lo_do_lookup(req, parent, name, &e, NULL);
+     if (saverr) {
+         goto out;
+     }
+@@ -1599,7 +1612,7 @@ static void lo_do_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
+ 
+         if (plus) {
+             if (!is_dot_or_dotdot(name)) {
+-                err = lo_do_lookup(req, ino, name, &e);
++                err = lo_do_lookup(req, ino, name, &e, NULL);
+                 if (err) {
+                     goto error;
+                 }
+@@ -1793,7 +1806,7 @@ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
+         }
+ 
+         fi->fh = fh;
+-        err = lo_do_lookup(req, parent, name, &e);
++        err = lo_do_lookup(req, parent, name, &e, NULL);
+     }
+     if (lo->cache == CACHE_NONE) {
+         fi->direct_io = 1;
+-- 
+2.18.2
+
diff --git a/SOURCES/kvm-virtiofsd-prevent-opening-of-special-files-CVE-2020-.patch b/SOURCES/kvm-virtiofsd-prevent-opening-of-special-files-CVE-2020-.patch
new file mode 100644
index 0000000..5956dce
--- /dev/null
+++ b/SOURCES/kvm-virtiofsd-prevent-opening-of-special-files-CVE-2020-.patch
@@ -0,0 +1,314 @@
+From cc9a776fba8ec62c862db55753107f19459dafa8 Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Tue, 9 Feb 2021 23:14:56 -0500
+Subject: [PATCH 3/3] virtiofsd: prevent opening of special files
+ (CVE-2020-35517)
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210209231456.1555472-4-jmaloy@redhat.com>
+Patchwork-id: 101023
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 3/3] virtiofsd: prevent opening of special files (CVE-2020-35517)
+Bugzilla: 1919111
+RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
+RH-Acked-by: Greg Kurz <gkurz@redhat.com>
+RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+A well-behaved FUSE client does not attempt to open special files with
+FUSE_OPEN because they are handled on the client side (e.g. device nodes
+are handled by client-side device drivers).
+
+The check to prevent virtiofsd from opening special files is missing in
+a few cases, most notably FUSE_OPEN. A malicious client can cause
+virtiofsd to open a device node, potentially allowing the guest to
+escape. This can be exploited by a modified guest device driver. It is
+not exploitable from guest userspace since the guest kernel will handle
+special files inside the guest instead of sending FUSE requests.
+
+This patch fixes this issue by introducing the lo_inode_open() function
+to check the file type before opening it. This is a short-term solution
+because it does not prevent a compromised virtiofsd process from opening
+device nodes on the host.
+
+Restructure lo_create() to try O_CREAT | O_EXCL first. Note that O_CREAT
+| O_EXCL does not follow symlinks, so O_NOFOLLOW masking is not
+necessary here. If the file exists and the user did not specify O_EXCL,
+open it via lo_do_open().
+
+Reported-by: Alex Xu <alex@alxu.ca>
+Fixes: CVE-2020-35517
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Vivek Goyal <vgoyal@redhat.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-Id: <20210204150208.367837-4-stefanha@redhat.com>
+Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+
+(cherry picked from commit a3fdbbc7f271bff7d53d0501b29d910ece0b3789)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Jon Maloy <jmaloy.redhat.com>
+---
+ tools/virtiofsd/passthrough_ll.c | 144 ++++++++++++++++++++-----------
+ 1 file changed, 92 insertions(+), 52 deletions(-)
+
+diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
+index e5bd3d73e4..cb0992f2db 100644
+--- a/tools/virtiofsd/passthrough_ll.c
++++ b/tools/virtiofsd/passthrough_ll.c
+@@ -535,6 +535,38 @@ static int lo_fd(fuse_req_t req, fuse_ino_t ino)
+     return fd;
+ }
+ 
++/*
++ * Open a file descriptor for an inode. Returns -EBADF if the inode is not a
++ * regular file or a directory.
++ *
++ * Use this helper function instead of raw openat(2) to prevent security issues
++ * when a malicious client opens special files such as block device nodes.
++ * Symlink inodes are also rejected since symlinks must already have been
++ * traversed on the client side.
++ */
++static int lo_inode_open(struct lo_data *lo, struct lo_inode *inode,
++                         int open_flags)
++{
++    g_autofree char *fd_str = g_strdup_printf("%d", inode->fd);
++    int fd;
++
++    if (!S_ISREG(inode->filetype) && !S_ISDIR(inode->filetype)) {
++        return -EBADF;
++    }
++
++    /*
++     * The file is a symlink so O_NOFOLLOW must be ignored. We checked earlier
++     * that the inode is not a special file but if an external process races
++     * with us then symlinks are traversed here. It is not possible to escape
++     * the shared directory since it is mounted as "/" though.
++     */
++    fd = openat(lo->proc_self_fd, fd_str, open_flags & ~O_NOFOLLOW);
++    if (fd < 0) {
++        return -errno;
++    }
++    return fd;
++}
++
+ static void lo_init(void *userdata, struct fuse_conn_info *conn)
+ {
+     struct lo_data *lo = (struct lo_data *)userdata;
+@@ -788,9 +820,9 @@ static void lo_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
+         if (fi) {
+             truncfd = fd;
+         } else {
+-            sprintf(procname, "%i", ifd);
+-            truncfd = openat(lo->proc_self_fd, procname, O_RDWR);
++            truncfd = lo_inode_open(lo, inode, O_RDWR);
+             if (truncfd < 0) {
++                errno = -truncfd;
+                 goto out_err;
+             }
+         }
+@@ -894,7 +926,7 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name,
+     struct lo_inode *dir = lo_inode(req, parent);
+ 
+     if (inodep) {
+-        *inodep = NULL;
++        *inodep = NULL; /* in case there is an error */
+     }
+ 
+     /*
+@@ -1725,19 +1757,26 @@ static void update_open_flags(int writeback, struct fuse_file_info *fi)
+     fi->flags &= ~O_DIRECT;
+ }
+ 
++/*
++ * Open a regular file, set up an fd mapping, and fill out the struct
++ * fuse_file_info for it. If existing_fd is not negative, use that fd instead
++ * opening a new one. Takes ownership of existing_fd.
++ *
++ * Returns 0 on success or a positive errno.
++ */
+ static int lo_do_open(struct lo_data *lo, struct lo_inode *inode,
+-                      struct fuse_file_info *fi)
++                      int existing_fd, struct fuse_file_info *fi)
+ {
+-    char buf[64];
+     ssize_t fh;
+-    int fd;
++    int fd = existing_fd;
+ 
+     update_open_flags(lo->writeback, fi);
+ 
+-    sprintf(buf, "%i", inode->fd);
+-    fd = openat(lo->proc_self_fd, buf, fi->flags & ~O_NOFOLLOW);
+-    if (fd == -1) {
+-        return errno;
++    if (fd < 0) {
++        fd = lo_inode_open(lo, inode, fi->flags);
++        if (fd < 0) {
++            return -fd;
++        }
+     }
+ 
+     pthread_mutex_lock(&lo->mutex);
+@@ -1760,9 +1799,10 @@ static int lo_do_open(struct lo_data *lo, struct lo_inode *inode,
+ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
+                       mode_t mode, struct fuse_file_info *fi)
+ {
+-    int fd;
++    int fd = -1;
+     struct lo_data *lo = lo_data(req);
+     struct lo_inode *parent_inode;
++    struct lo_inode *inode = NULL;
+     struct fuse_entry_param e;
+     int err;
+     struct lo_cred old = {};
+@@ -1788,36 +1828,38 @@ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
+ 
+     update_open_flags(lo->writeback, fi);
+ 
+-    fd = openat(parent_inode->fd, name, (fi->flags | O_CREAT) & ~O_NOFOLLOW,
+-                mode);
++    /* Try to create a new file but don't open existing files */
++    fd = openat(parent_inode->fd, name, fi->flags | O_CREAT | O_EXCL, mode);
+     err = fd == -1 ? errno : 0;
+-    lo_restore_cred(&old);
+ 
+-    if (!err) {
+-        ssize_t fh;
++    lo_restore_cred(&old);
+ 
+-        pthread_mutex_lock(&lo->mutex);
+-        fh = lo_add_fd_mapping(lo, fd);
+-        pthread_mutex_unlock(&lo->mutex);
+-        if (fh == -1) {
+-            close(fd);
+-            err = ENOMEM;
+-            goto out;
+-        }
++    /* Ignore the error if file exists and O_EXCL was not given */
++    if (err && (err != EEXIST || (fi->flags & O_EXCL))) {
++        goto out;
++    }
+ 
+-        fi->fh = fh;
+-        err = lo_do_lookup(req, parent, name, &e, NULL);
++    err = lo_do_lookup(req, parent, name, &e, &inode);
++    if (err) {
++        goto out;
+     }
+-    if (lo->cache == CACHE_NONE) {
+-        fi->direct_io = 1;
+-    } else if (lo->cache == CACHE_ALWAYS) {
+-        fi->keep_cache = 1;
++
++    err = lo_do_open(lo, inode, fd, fi);
++    fd = -1; /* lo_do_open() takes ownership of fd */
++    if (err) {
++        /* Undo lo_do_lookup() nlookup ref */
++        unref_inode_lolocked(lo, inode, 1);
+     }
+ 
+ out:
++    lo_inode_put(lo, &inode);
+     lo_inode_put(lo, &parent_inode);
+ 
+     if (err) {
++        if (fd >= 0) {
++            close(fd);
++        }
++
+         fuse_reply_err(req, err);
+     } else {
+         fuse_reply_create(req, &e, fi);
+@@ -1831,7 +1873,6 @@ static struct lo_inode_plock *lookup_create_plock_ctx(struct lo_data *lo,
+                                                       pid_t pid, int *err)
+ {
+     struct lo_inode_plock *plock;
+-    char procname[64];
+     int fd;
+ 
+     plock =
+@@ -1848,12 +1889,10 @@ static struct lo_inode_plock *lookup_create_plock_ctx(struct lo_data *lo,
+     }
+ 
+     /* Open another instance of file which can be used for ofd locks. */
+-    sprintf(procname, "%i", inode->fd);
+-
+     /* TODO: What if file is not writable? */
+-    fd = openat(lo->proc_self_fd, procname, O_RDWR);
+-    if (fd == -1) {
+-        *err = errno;
++    fd = lo_inode_open(lo, inode, O_RDWR);
++    if (fd < 0) {
++        *err = -fd;
+         free(plock);
+         return NULL;
+     }
+@@ -2000,7 +2039,7 @@ static void lo_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+         return;
+     }
+ 
+-    err = lo_do_open(lo, inode, fi);
++    err = lo_do_open(lo, inode, -1, fi);
+     lo_inode_put(lo, &inode);
+     if (err) {
+         fuse_reply_err(req, err);
+@@ -2056,39 +2095,40 @@ static void lo_flush(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
+ static void lo_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
+                      struct fuse_file_info *fi)
+ {
++    struct lo_inode *inode = lo_inode(req, ino);
++    struct lo_data *lo = lo_data(req);
+     int res;
+     int fd;
+-    char *buf;
+ 
+     fuse_log(FUSE_LOG_DEBUG, "lo_fsync(ino=%" PRIu64 ", fi=0x%p)\n", ino,
+              (void *)fi);
+ 
+-    if (!fi) {
+-        struct lo_data *lo = lo_data(req);
+-
+-        res = asprintf(&buf, "%i", lo_fd(req, ino));
+-        if (res == -1) {
+-            return (void)fuse_reply_err(req, errno);
+-        }
++    if (!inode) {
++        fuse_reply_err(req, EBADF);
++        return;
++    }
+ 
+-        fd = openat(lo->proc_self_fd, buf, O_RDWR);
+-        free(buf);
+-        if (fd == -1) {
+-            return (void)fuse_reply_err(req, errno);
++    if (!fi) {
++        fd = lo_inode_open(lo, inode, O_RDWR);
++        if (fd < 0) {
++            res = -fd;
++            goto out;
+         }
+     } else {
+         fd = lo_fi_fd(req, fi);
+     }
+ 
+     if (datasync) {
+-        res = fdatasync(fd);
++        res = fdatasync(fd) == -1 ? errno : 0;
+     } else {
+-        res = fsync(fd);
++        res = fsync(fd) == -1 ? errno : 0;
+     }
+     if (!fi) {
+         close(fd);
+     }
+-    fuse_reply_err(req, res == -1 ? errno : 0);
++out:
++    lo_inode_put(lo, &inode);
++    fuse_reply_err(req, res);
+ }
+ 
+ static void lo_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t offset,
+-- 
+2.18.2
+
diff --git a/SOURCES/kvm-x86-cpu-Enable-AVX512_VP2INTERSECT-cpu-feature.patch b/SOURCES/kvm-x86-cpu-Enable-AVX512_VP2INTERSECT-cpu-feature.patch
new file mode 100644
index 0000000..dbcf2a7
--- /dev/null
+++ b/SOURCES/kvm-x86-cpu-Enable-AVX512_VP2INTERSECT-cpu-feature.patch
@@ -0,0 +1,63 @@
+From ad50e0e2d310277f06a9c512fe6e31da183ead6e Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 24 Feb 2021 11:30:34 -0500
+Subject: [PATCH 1/4] x86/cpu: Enable AVX512_VP2INTERSECT cpu feature
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20210224113037.15599-2-dgilbert@redhat.com>
+Patchwork-id: 101203
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/4] x86/cpu: Enable AVX512_VP2INTERSECT cpu feature
+Bugzilla: 1790620
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Cathy Zhang <cathy.zhang@intel.com>
+
+AVX512_VP2INTERSECT compute vector pair intersection to a pair
+of mask registers, which is introduced with intel Tiger Lake,
+defining as CPUID.(EAX=7,ECX=0):EDX[bit 08].
+
+Refer to the following release spec:
+https://software.intel.com/sites/default/files/managed/c5/15/\
+architecture-instruction-set-extensions-programming-reference.pdf
+
+Signed-off-by: Cathy Zhang <cathy.zhang@intel.com>
+Message-Id: <1586760758-13638-1-git-send-email-cathy.zhang@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 353f98c9ad52ff4b8cfe553c90be04f747a14c98)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c | 2 +-
+ target/i386/cpu.h | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index ff39fc9905..67dab94aa5 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1078,7 +1078,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+         .feat_names = {
+             NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
+             NULL, NULL, NULL, NULL,
+-            NULL, NULL, "md-clear", NULL,
++            "avx512-vp2intersect", NULL, "md-clear", NULL,
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL /* pconfig */, NULL,
+             NULL, NULL, NULL, NULL,
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index f3da25cb8a..8e2e52ed31 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -770,6 +770,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_7_0_EDX_AVX512_4VNNIW     (1U << 2)
+ /* AVX512 Multiply Accumulation Single Precision */
+ #define CPUID_7_0_EDX_AVX512_4FMAPS     (1U << 3)
++/* AVX512 Vector Pair Intersection to a Pair of Mask Registers */
++#define CPUID_7_0_EDX_AVX512_VP2INTERSECT (1U << 8)
+ /* Speculation Control */
+ #define CPUID_7_0_EDX_SPEC_CTRL         (1U << 26)
+ /* Single Thread Indirect Branch Predictors */
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-x86-cpu-Populate-SVM-CPUID-feature-bits.patch b/SOURCES/kvm-x86-cpu-Populate-SVM-CPUID-feature-bits.patch
new file mode 100644
index 0000000..9ef6d04
--- /dev/null
+++ b/SOURCES/kvm-x86-cpu-Populate-SVM-CPUID-feature-bits.patch
@@ -0,0 +1,91 @@
+From 655e723a5190206302f6cc4f2e794563b8e1c226 Mon Sep 17 00:00:00 2001
+From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Date: Wed, 24 Feb 2021 11:30:36 -0500
+Subject: [PATCH 3/4] x86/cpu: Populate SVM CPUID feature bits
+
+RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Message-id: <20210224113037.15599-4-dgilbert@redhat.com>
+Patchwork-id: 101200
+O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 3/4] x86/cpu: Populate SVM CPUID feature bits
+Bugzilla: 1790620
+RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
+RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
+RH-Acked-by: Peter Xu <peterx@redhat.com>
+
+From: Wei Huang <wei.huang2@amd.com>
+
+Newer AMD CPUs will add CPUID_0x8000000A_EDX[28] bit, which indicates
+that SVM instructions (VMRUN/VMSAVE/VMLOAD) will trigger #VMEXIT before
+CPU checking their EAX against reserved memory regions. This change will
+allow the hypervisor to avoid intercepting #GP and emulating SVM
+instructions. KVM turns on this CPUID bit for nested VMs. In order to
+support it, let us populate this bit, along with other SVM feature bits,
+in FEAT_SVM.
+
+Signed-off-by: Wei Huang <wei.huang2@amd.com>
+Message-Id: <20210126202456.589932-1-wei.huang2@amd.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+(cherry picked from commit 5447089c2b3b084b51670af36fc86ee3979e04be)
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ target/i386/cpu.c |  6 +++---
+ target/i386/cpu.h | 24 ++++++++++++++----------
+ 2 files changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index f6a9ed84b3..7227c803c3 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -1026,11 +1026,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
+             "npt", "lbrv", "svm-lock", "nrip-save",
+             "tsc-scale", "vmcb-clean",  "flushbyasid", "decodeassists",
+             NULL, NULL, "pause-filter", NULL,
+-            "pfthreshold", NULL, NULL, NULL,
+-            NULL, NULL, NULL, NULL,
+-            NULL, NULL, NULL, NULL,
++            "pfthreshold", "avic", NULL, "v-vmsave-vmload",
++            "vgif", NULL, NULL, NULL,
+             NULL, NULL, NULL, NULL,
+             NULL, NULL, NULL, NULL,
++            "svme-addr-chk", NULL, NULL, NULL,
+         },
+         .cpuid = { .eax = 0x8000000A, .reg = R_EDX, },
+         .tcg_features = TCG_SVM_FEATURES,
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index f5a4efcec6..e1b67910c2 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -667,16 +667,20 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
+ #define CPUID_EXT3_PERFCORE (1U << 23)
+ #define CPUID_EXT3_PERFNB  (1U << 24)
+ 
+-#define CPUID_SVM_NPT          (1U << 0)
+-#define CPUID_SVM_LBRV         (1U << 1)
+-#define CPUID_SVM_SVMLOCK      (1U << 2)
+-#define CPUID_SVM_NRIPSAVE     (1U << 3)
+-#define CPUID_SVM_TSCSCALE     (1U << 4)
+-#define CPUID_SVM_VMCBCLEAN    (1U << 5)
+-#define CPUID_SVM_FLUSHASID    (1U << 6)
+-#define CPUID_SVM_DECODEASSIST (1U << 7)
+-#define CPUID_SVM_PAUSEFILTER  (1U << 10)
+-#define CPUID_SVM_PFTHRESHOLD  (1U << 12)
++#define CPUID_SVM_NPT             (1U << 0)
++#define CPUID_SVM_LBRV            (1U << 1)
++#define CPUID_SVM_SVMLOCK         (1U << 2)
++#define CPUID_SVM_NRIPSAVE        (1U << 3)
++#define CPUID_SVM_TSCSCALE        (1U << 4)
++#define CPUID_SVM_VMCBCLEAN       (1U << 5)
++#define CPUID_SVM_FLUSHASID       (1U << 6)
++#define CPUID_SVM_DECODEASSIST    (1U << 7)
++#define CPUID_SVM_PAUSEFILTER     (1U << 10)
++#define CPUID_SVM_PFTHRESHOLD     (1U << 12)
++#define CPUID_SVM_AVIC            (1U << 13)
++#define CPUID_SVM_V_VMSAVE_VMLOAD (1U << 15)
++#define CPUID_SVM_VGIF            (1U << 16)
++#define CPUID_SVM_SVME_ADDR_CHK   (1U << 28)
+ 
+ /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */
+ #define CPUID_7_0_EBX_FSGSBASE          (1U << 0)
+-- 
+2.27.0
+
diff --git a/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch b/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch
new file mode 100644
index 0000000..aabe041
--- /dev/null
+++ b/SOURCES/kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch
@@ -0,0 +1,76 @@
+From f38f51d422e82d1241b678960dd6a033ffa398da Mon Sep 17 00:00:00 2001
+From: Jon Maloy <jmaloy@redhat.com>
+Date: Wed, 21 Apr 2021 22:30:05 -0400
+Subject: [PATCH 6/7] xhci: fix valid.max_access_size to access address
+ registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RH-Author: Jon Maloy <jmaloy@redhat.com>
+Message-id: <20210421223006.19650-6-jmaloy@redhat.com>
+Patchwork-id: 101483
+O-Subject: [RHEL-8.5.0 qemu-kvm PATCH v2 5/6] xhci: fix valid.max_access_size to access address registers
+Bugzilla: 1842478
+RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
+RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
+RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
+
+From: Laurent Vivier <lvivier@redhat.com>
+
+QEMU XHCI advertises AC64 (64-bit addressing) but doesn't allow
+64-bit mode access in "runtime" and "operational" MemoryRegionOps.
+
+Set the max_access_size based on sizeof(dma_addr_t) as AC64 is set.
+
+XHCI specs:
+"If the xHC supports 64-bit addressing (AC64 = ‘1’), then software
+should write 64-bit registers using only Qword accesses.  If a
+system is incapable of issuing Qword accesses, then writes to the
+64-bit address fields shall be performed using 2 Dword accesses;
+low Dword-first, high-Dword second.  If the xHC supports 32-bit
+addressing (AC64 = ‘0’), then the high Dword of registers containing
+64-bit address fields are unused and software should write addresses
+using only Dword accesses"
+
+The problem has been detected with SLOF, as linux kernel always accesses
+registers using 32-bit access even if AC64 is set and revealed by
+5d971f9e6725 ("memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"")
+
+Suggested-by: Alexey Kardashevskiy <aik@au1.ibm.com>
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Message-id: 20200721083322.90651-1-lvivier@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+
+(cherry picked from commit 8e67fda2dd6202ccec093fda561107ba14830a17)
+Signed-off-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
+---
+ hw/usb/hcd-xhci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
+index 646c78cde9..ab449bb003 100644
+--- a/hw/usb/hcd-xhci.c
++++ b/hw/usb/hcd-xhci.c
+@@ -3183,7 +3183,7 @@ static const MemoryRegionOps xhci_oper_ops = {
+     .read = xhci_oper_read,
+     .write = xhci_oper_write,
+     .valid.min_access_size = 4,
+-    .valid.max_access_size = 4,
++    .valid.max_access_size = sizeof(dma_addr_t),
+     .endianness = DEVICE_LITTLE_ENDIAN,
+ };
+ 
+@@ -3199,7 +3199,7 @@ static const MemoryRegionOps xhci_runtime_ops = {
+     .read = xhci_runtime_read,
+     .write = xhci_runtime_write,
+     .valid.min_access_size = 4,
+-    .valid.max_access_size = 4,
++    .valid.max_access_size = sizeof(dma_addr_t),
+     .endianness = DEVICE_LITTLE_ENDIAN,
+ };
+ 
+-- 
+2.27.0
+
diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec
index e8a06e1..22e8f20 100644
--- a/SPECS/qemu-kvm.spec
+++ b/SPECS/qemu-kvm.spec
@@ -61,13 +61,13 @@ Requires: %{name}-block-ssh = %{epoch}:%{version}-%{release}
 
 # Macro to properly setup RHEL/RHEV conflict handling
 %define rhev_ma_conflicts()                                      \
-Obsoletes: %1-ma                                                 \
-Obsoletes: %1-rhev
+Obsoletes: %1-ma <= %{epoch}:%{version}-%{release}               \
+Obsoletes: %1-rhev <= %{epoch}:%{version}-%{release}
 
 Summary: QEMU is a machine emulator and virtualizer
 Name: qemu-kvm
 Version: 4.2.0
-Release: 44%{?dist}
+Release: 58%{?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
@@ -1112,6 +1112,140 @@ Patch479: kvm-block-Require-aligned-image-size-to-avoid-assertion-.patch
 Patch480: kvm-file-posix-Allow-byte-aligned-O_DIRECT-with-NFS.patch
 # For bz#1912974 - CVE-2020-11947 virt:rhel/qemu-kvm: QEMU: heap buffer overflow in iscsi_aio_ioctl_cb() in block/iscsi.c may lead to information disclosure [rhel-8]
 Patch481: kvm-block-iscsi-fix-heap-buffer-overflow-in-iscsi_aio_io.patch
+# For bz#1919111 - CVE-2020-35517 virt:rhel/qemu-kvm: QEMU: virtiofsd: potential privileged host device access from guest [rhel-8.4.0]
+Patch482: kvm-virtiofsd-extract-lo_do_open-from-lo_open.patch
+# For bz#1919111 - CVE-2020-35517 virt:rhel/qemu-kvm: QEMU: virtiofsd: potential privileged host device access from guest [rhel-8.4.0]
+Patch483: kvm-virtiofsd-optionally-return-inode-pointer-from-lo_do.patch
+# For bz#1919111 - CVE-2020-35517 virt:rhel/qemu-kvm: QEMU: virtiofsd: potential privileged host device access from guest [rhel-8.4.0]
+Patch484: kvm-virtiofsd-prevent-opening-of-special-files-CVE-2020-.patch
+# For bz#1912891 - [ppc64le] --disk cdimage.iso,bus=usb fails to boot
+Patch486: kvm-spapr-Adjust-firmware-path-of-PCI-devices.patch
+# For bz#1790620 - [RFE] AMD Milan - Add KVM/support for EPYC-Milan CPU Model - Slow Train
+Patch487: kvm-x86-cpu-Enable-AVX512_VP2INTERSECT-cpu-feature.patch
+# For bz#1790620 - [RFE] AMD Milan - Add KVM/support for EPYC-Milan CPU Model - Slow Train
+Patch488: kvm-target-i386-add-fast-short-REP-MOV-support.patch
+# For bz#1790620 - [RFE] AMD Milan - Add KVM/support for EPYC-Milan CPU Model - Slow Train
+Patch489: kvm-x86-cpu-Populate-SVM-CPUID-feature-bits.patch
+# For bz#1790620 - [RFE] AMD Milan - Add KVM/support for EPYC-Milan CPU Model - Slow Train
+Patch490: kvm-i386-Add-the-support-for-AMD-EPYC-3rd-generation-pro.patch
+# For bz#1917451 - CVE-2020-29443 virt:rhel/qemu-kvm: QEMU: ide: atapi: OOB access while processing read commands [rhel-8.4.0]
+Patch491: kvm-ide-atapi-check-logical-block-address-and-read-size-.patch
+# For bz#1892350 - CVE-2020-27617 virt:rhel/qemu-kvm: QEMU: net: an assert failure via eth_get_gso_type [rhel-8.5.0]
+Patch492: kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch
+# For bz#1930092 - CVE-2021-20257 virt:rhel/qemu-kvm: QEMU: net: e1000: infinite loop while processing transmit descriptors [rhel-8.5.0]
+Patch493: kvm-e1000-fail-early-for-evil-descriptor.patch
+# For bz#1859175 - CVE-2020-15859 virt:rhel/qemu-kvm: QEMU: net: e1000e: use-after-free while sending packets [rhel-8]
+Patch494: kvm-net-forbid-the-reentrant-RX.patch
+# For bz#1855250 - qemu-img convert uses possibly slow pre-zeroing on block storage
+Patch495: kvm-qemu-img-convert-Don-t-pre-zero-images.patch
+# For bz#1932823 - after upgrade from 4.3 to 4.4 audio stops working in guests after couple of seconds
+Patch496: kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch
+# For bz#1925430 - CVE-2021-20221 virt:rhel/qemu-kvm: qemu: out-of-bound heap buffer access via an interrupt ID field [rhel-8.5.0]
+Patch497: kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch
+# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]
+Patch498: kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch
+# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]
+Patch499: kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch
+# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]
+Patch500: kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch
+# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]
+Patch501: kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch
+# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]
+Patch502: kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch
+# For bz#1842478 - CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0]
+Patch503: kvm-softmmu-memory-Log-invalid-memory-accesses.patch
+# For bz#1940450 - RHEL8.5 - Mediated Device already in use by same domain we are booting (vfio-ccw/Multipath Testing) (kvm) - qemu-kvm part (also has kernel and libvirt parts)
+Patch504: kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch
+# For bz#1940450 - RHEL8.5 - Mediated Device already in use by same domain we are booting (vfio-ccw/Multipath Testing) (kvm) - qemu-kvm part (also has kernel and libvirt parts)
+Patch505: kvm-vfio-ccw-Connect-the-device-request-notifier.patch
+# For bz#1942880 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm)
+Patch506: kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch
+# For bz#1942880 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm)
+Patch507: kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch
+# For bz#1942880 - RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm)
+Patch508: kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch
+# For bz#1877163 - [FJ 8.3 Bug] The progress bar of the "virt-clone --nonsparse" command shows the progress rate exceeding 100%.
+Patch509: kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch
+# For bz#1944861 - Qemu-img convert fails when source image is on gpfs
+Patch510: kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch
+# For bz#1969768 - [ppc64le] Hotplug vcpu device hit call trace:[qemu output] KVM: unknown exit, hardware reason 7fff9ce87ed8
+Patch511: kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch
+# For bz#1969768 - [ppc64le] Hotplug vcpu device hit call trace:[qemu output] KVM: unknown exit, hardware reason 7fff9ce87ed8
+Patch512: kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch
+# For bz#1967914 - [virtio-fs] virtiofsd quit when coping file to a folder in virtio-fs mounted volume(windows guest)
+Patch513: kvm-virtiofsd-Whitelist-fchmod.patch
+# For bz#1957866 - RHEL8.4 - EEH capability disabled on KVM guest and recovery of PCI passthru device fails(CX5 / mlx5_core) (qemu-kvm)
+Patch514: kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch
+# For bz#1970912 - Deployment fails with "Invalid or missing agent token received"
+Patch515: kvm-Compress-lines-for-immediate-return.patch
+# For bz#1970912 - Deployment fails with "Invalid or missing agent token received"
+Patch516: kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch517: kvm-net-introduce-qemu_receive_packet.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch518: kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch519: kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch520: kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch521: kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch522: kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch523: kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch524: kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch
+# For bz#1932917 - CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow
+Patch525: kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch
+# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support
+Patch526: kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch
+# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support
+Patch527: kvm-qga-add-ssh-add-remove-authorized-keys.patch
+# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support
+Patch528: kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch
+# For bz#1967716 - RFE: rebuild guest agent to include public ssh injection api support
+Patch529: kvm-qga-add-ssh-get-authorized-keys.patch
+# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8]
+# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8]
+# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8]
+# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8]
+Patch530: kvm-Add-mtod_check.patch
+# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8]
+# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8]
+# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8]
+# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8]
+Patch531: kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch
+# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8]
+Patch532: kvm-bootp-check-bootp_input-buffer-size.patch
+# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8]
+Patch533: kvm-upd6-check-udp6_input-buffer-size.patch
+# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8]
+Patch534: kvm-tftp-check-tftp_input-buffer-size.patch
+# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8]
+# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8]
+# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8]
+# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8]
+Patch535: kvm-tftp-introduce-a-header-structure.patch
+# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8]
+Patch536: kvm-udp-check-upd_input-buffer-size.patch
+# For bz#1970819 - CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8]
+# For bz#1970835 - CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8]
+# For bz#1970843 - CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8]
+# For bz#1970853 - CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8]
+Patch537: kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch
+# For bz#1982134 - QEMU core dump while booting guest with a non-exist fd on tap
+Patch538: kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch
+# For bz#1982134 - QEMU core dump while booting guest with a non-exist fd on tap
+Patch539: kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch
+# For bz#1969848 - qemu-img convert hangs on aarch64
+Patch540: kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch
+# For bz#1969848 - qemu-img convert hangs on aarch64
+Patch541: kvm-async-use-explicit-memory-barriers.patch
+# For bz#1967496 - [virtio-fs] nfs/xfstest generic/089 generic/478 generic/632 failed
+Patch542: kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch
+# For bz#1967496 - [virtio-fs] nfs/xfstest generic/089 generic/478 generic/632 failed
+Patch543: kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch
 
 BuildRequires: wget
 BuildRequires: rpm-build
@@ -1486,7 +1620,7 @@ buildldflags="VL_LDFLAGS=-Wl,--build-id"
   --audio-drv-list= \
   --block-drv-ro-whitelist=vmdk,vhdx,vpc,https,ssh \
   --with-coroutine=ucontext \
-  --tls-priority=NORMAL \
+  --tls-priority=@QEMU,SYSTEM \
   --disable-bluez \
   --disable-brlapi \
   --enable-cap-ng \
@@ -2060,6 +2194,157 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
 
 
 %changelog
+* Wed Aug 18 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-58.el8
+- kvm-virtiofsd-Disable-remote-posix-locks-by-default.patch [bz#1967496]
+- kvm-virtiofsd-Fix-the-help-message-of-posix-lock.patch [bz#1967496]
+- Resolves: bz#1967496
+  ([virtio-fs] nfs/xfstest generic/089 generic/478 generic/632 failed)
+
+* Wed Aug 04 2021 Miroslav Rezanina <mrezanin@redhat.com> - 4.2.0-57
+- kvm-aio-wait-delegate-polling-of-main-AioContext-if-BQL-.patch [bz#1969848]
+- kvm-async-use-explicit-memory-barriers.patch [bz#1969848]
+- Resolves: bz#1969848
+  (qemu-img convert hangs on aarch64)
+
+* Thu Jul 29 2021 Miroslav Rezanina <mrezanin@redhat.com> - 4.2.0-56
+- kvm-glib-compat-add-g_unix_get_passwd_entry_qemu.patch [bz#1967716]
+- kvm-qga-add-ssh-add-remove-authorized-keys.patch [bz#1967716]
+- kvm-qga-add-reset-argument-to-ssh-add-authorized-keys.patch [bz#1967716]
+- kvm-qga-add-ssh-get-authorized-keys.patch [bz#1967716]
+- kvm-Add-mtod_check.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853]
+- kvm-bootp-limit-vendor-specific-area-to-input-packet-mem.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853]
+- kvm-bootp-check-bootp_input-buffer-size.patch [bz#1970819]
+- kvm-upd6-check-udp6_input-buffer-size.patch [bz#1970835]
+- kvm-tftp-check-tftp_input-buffer-size.patch [bz#1970843]
+- kvm-tftp-introduce-a-header-structure.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853]
+- kvm-udp-check-upd_input-buffer-size.patch [bz#1970853]
+- kvm-Fix-DHCP-broken-in-libslirp-v4.6.0.patch [bz#1970819 bz#1970835 bz#1970843 bz#1970853]
+- kvm-net-check-if-the-file-descriptor-is-valid-before-usi.patch [bz#1982134]
+- kvm-net-detect-errors-from-probing-vnet-hdr-flag-for-TAP.patch [bz#1982134]
+- Resolves: bz#1967716
+  (RFE: rebuild guest agent to include public ssh injection api support)
+- Resolves: bz#1970819
+  (CVE-2021-3592 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (bootp) [rhel-8])
+- Resolves: bz#1970835
+  (CVE-2021-3593 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp6) [rhel-8])
+- Resolves: bz#1970843
+  (CVE-2021-3595 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (tftp) [rhel-8])
+- Resolves: bz#1970853
+  (CVE-2021-3594 virt:rhel/qemu-kvm: QEMU: slirp: invalid pointer initialization may lead to information disclosure (udp) [rhel-8])
+- Resolves: bz#1982134
+  (QEMU core dump while booting guest with a non-exist fd on tap)
+
+* Fri Jul 23 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-55.el8
+- kvm-net-introduce-qemu_receive_packet.patch [bz#1932917]
+- kvm-e1000-switch-to-use-qemu_receive_packet-for-loopback.patch [bz#1932917]
+- kvm-dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch [bz#1932917]
+- kvm-sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch [bz#1932917]
+- kvm-tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch [bz#1932917]
+- kvm-rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch [bz#1932917]
+- kvm-pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch [bz#1932917]
+- kvm-cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch [bz#1932917]
+- kvm-lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch [bz#1932917]
+- Resolves: bz#1932917
+  (CVE-2021-3416 virt:rhel/qemu-kvm: QEMU: net: infinite loop in loopback mode may lead to stack overflow)
+
+* Thu Jul 22 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-54.el8
+- kvm-redhat-Fix-unversioned-Obsoletes-warning.patch [bz#1967329]
+- Resolves: bz#1967329
+  (Make qemu-kvm use versioned obsoletes for qemu-kvm-ma and qemu-kvm-rhev)
+
+* Fri Jul 02 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-53.el8
+- kvm-virtiofsd-Whitelist-fchmod.patch [bz#1967914]
+- kvm-spapr-Fix-EEH-capability-issue-on-KVM-guest-for-PCI-.patch [bz#1957866]
+- kvm-Compress-lines-for-immediate-return.patch [bz#1970912]
+- kvm-file-posix-Handle-EINVAL-fallocate-return-value.patch [bz#1970912]
+- Resolves: bz#1967914
+  ([virtio-fs] virtiofsd quit when coping file to a folder in virtio-fs mounted volume(windows guest))
+- Resolves: bz#1957866
+  (RHEL8.4 - EEH capability disabled on KVM guest and recovery of PCI passthru device fails(CX5 / mlx5_core) (qemu-kvm))
+- Resolves: bz#1970912
+  (Deployment fails with "Invalid or missing agent token received")
+
+* Fri Jun 11 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-52.el8
+- kvm-file-posix-Mitigate-file-fragmentation-with-extent-s.patch [bz#1877163]
+- kvm-block-file-posix-Fix-problem-with-fallocate-PUNCH_HO.patch [bz#1944861]
+- kvm-spapr-Remove-stale-comment-about-power-saving-LPCR-b.patch [bz#1969768]
+- kvm-spapr-Set-LPCR-to-current-AIL-mode-when-starting-a-n.patch [bz#1969768]
+- Resolves: bz#1877163
+  ([FJ 8.3 Bug] The progress bar of the "virt-clone --nonsparse" command shows the progress rate exceeding 100%.)
+- Resolves: bz#1944861
+  (Qemu-img convert fails when source image is on gpfs)
+- Resolves: bz#1969768
+  ([ppc64le] Hotplug vcpu device hit call trace:[qemu output] KVM: unknown exit, hardware reason 7fff9ce87ed8)
+
+* Tue May 25 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-51.el8
+- kvm-linux-headers-Add-VFIO_CCW_REQ_IRQ_INDEX.patch [bz#1940450]
+- kvm-vfio-ccw-Connect-the-device-request-notifier.patch [bz#1940450]
+- kvm-pc-bios-s390-ccw-fix-off-by-one-error.patch [bz#1942880]
+- kvm-pc-bios-s390-ccw-break-loop-if-a-null-block-number-i.patch [bz#1942880]
+- kvm-pc-bios-s390-ccw-don-t-try-to-read-the-next-block-if.patch [bz#1942880]
+- Resolves: bz#1940450
+  (RHEL8.5 - Mediated Device already in use by same domain we are booting (vfio-ccw/Multipath Testing) (kvm) - qemu-kvm part (also has kernel and libvirt parts))
+- Resolves: bz#1942880
+  (RHEL8.4 Nightly[0322] - KVM guest fails to find zipl boot menu index (qemu-kvm))
+
+* Wed May 05 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-50.el8
+- kvm-hw-intc-arm_gic-Fix-interrupt-ID-in-GICD_SGIR-regist.patch [bz#1925430]
+- kvm-libqos-usb-hcd-ehci-use-32-bit-write-for-config-regi.patch [bz#1842478]
+- kvm-libqos-pci-pc-use-32-bit-write-for-EJ-register.patch [bz#1842478]
+- kvm-memory-Revert-memory-accept-mismatching-sizes-in-mem.patch [bz#1842478]
+- kvm-acpi-accept-byte-and-word-access-to-core-ACPI-regist.patch [bz#1842478]
+- kvm-xhci-fix-valid.max_access_size-to-access-address-reg.patch [bz#1842478]
+- kvm-softmmu-memory-Log-invalid-memory-accesses.patch [bz#1842478]
+- Resolves: bz#1925430
+  (CVE-2021-20221 virt:rhel/qemu-kvm: qemu: out-of-bound heap buffer access via an interrupt ID field [rhel-8.5.0])
+- Resolves: bz#1842478
+  (CVE-2020-13754 virt:rhel/qemu-kvm: QEMU: msix: OOB access during mmio operations may lead to DoS [rhel-8.5.0])
+
+* Wed Apr 28 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-49.el8
+- kvm-net-remove-an-assert-call-in-eth_get_gso_type.patch [bz#1892350]
+- kvm-e1000-fail-early-for-evil-descriptor.patch [bz#1930092]
+- kvm-net-forbid-the-reentrant-RX.patch [bz#1859175]
+- kvm-qemu-img-convert-Don-t-pre-zero-images.patch [bz#1855250]
+- kvm-audio-audio_generic_get_buffer_in-should-honor-size.patch [bz#1932823]
+- Resolves: bz#1892350
+  (CVE-2020-27617 virt:rhel/qemu-kvm: QEMU: net: an assert failure via eth_get_gso_type [rhel-8.5.0])
+- Resolves: bz#1930092
+  (CVE-2021-20257 virt:rhel/qemu-kvm: QEMU: net: e1000: infinite loop while processing transmit descriptors [rhel-8.5.0])
+- Resolves: bz#1859175
+  (CVE-2020-15859 virt:rhel/qemu-kvm: QEMU: net: e1000e: use-after-free while sending packets [rhel-8])
+- Resolves: bz#1855250
+  (qemu-img convert uses possibly slow pre-zeroing on block storage)
+- Resolves: bz#1932823
+  (after upgrade from 4.3 to 4.4 audio stops working in guests after couple of seconds)
+
+* Tue Mar 16 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-48.el8
+- kvm-ide-atapi-check-logical-block-address-and-read-size-.patch [bz#1917451]
+- Resolves: bz#1917451
+  (CVE-2020-29443 virt:rhel/qemu-kvm: QEMU: ide: atapi: OOB access while processing read commands [rhel-8.4.0])
+
+* Mon Mar 08 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-47.el8
+- kvm-x86-cpu-Enable-AVX512_VP2INTERSECT-cpu-feature.patch [bz#1790620]
+- kvm-target-i386-add-fast-short-REP-MOV-support.patch [bz#1790620]
+- kvm-x86-cpu-Populate-SVM-CPUID-feature-bits.patch [bz#1790620]
+- kvm-i386-Add-the-support-for-AMD-EPYC-3rd-generation-pro.patch [bz#1790620]
+- Resolves: bz#1790620
+  ([RFE] AMD Milan - Add KVM/support for EPYC-Milan CPU Model - Slow Train)
+
+* Wed Mar 03 2021 Danilo Cesar Lemes de Paula <ddepaula@redhat.com> - 4.2.0-46.el8
+- kvm-redhat-makes-qemu-respect-system-s-crypto-profile.patch [bz#1902960]
+- kvm-spapr-Adjust-firmware-path-of-PCI-devices.patch [bz#1912891]
+- Resolves: bz#1902960
+  (QEMU doesn't honour system crypto policies)
+- Resolves: bz#1912891
+  ([ppc64le] --disk cdimage.iso,bus=usb fails to boot)
+
+* Wed Feb 10 2021 Jon Maloy <jmaloy@redhat.com> - 4.2.0-45.el8
+- kvm-virtiofsd-extract-lo_do_open-from-lo_open.patch [bz#1919111]
+- kvm-virtiofsd-optionally-return-inode-pointer-from-lo_do.patch [bz#1919111]
+- kvm-virtiofsd-prevent-opening-of-special-files-CVE-2020-.patch [bz#1919111]
+- Resolves: bz#1919111
+  (CVE-2020-35517 virt:rhel/qemu-kvm: QEMU: virtiofsd: potential privileged host device access from guest [rhel-8.4.0])
+
 * Tue Feb 02 2021 Jon Maloy <jmaloy@redhat.com> - 4.2.0-44.el8
 - kvm-spapr-Improve-handling-of-fdt-buffer-size.patch [bz#1901837]
 - kvm-spapr-Fold-h_cas_compose_response-into-h_client_arch.patch [bz#1901837]