diff --git a/kvm-Acceptance-tests-add-Linux-initrd-checking-test.patch b/kvm-Acceptance-tests-add-Linux-initrd-checking-test.patch new file mode 100644 index 0000000..99f762c --- /dev/null +++ b/kvm-Acceptance-tests-add-Linux-initrd-checking-test.patch @@ -0,0 +1,105 @@ +From ba8f254594f7033183cda79b47e2c7a5c1f5bcfe Mon Sep 17 00:00:00 2001 +From: Yash Mankad +Date: Mon, 4 Feb 2019 19:14:22 +0000 +Subject: [PATCH 1/8] Acceptance tests: add Linux initrd checking test +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Yash Mankad +Message-id: +Patchwork-id: 84209 +O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 1/1] Acceptance tests: add Linux initrd checking test +Bugzilla: 1669922 +RH-Acked-by: Wainer dos Santos Moschetta +RH-Acked-by: Thomas Huth +RH-Acked-by: Laszlo Ersek + +From: Wainer dos Santos Moschetta + +QEMU used to exits with a not accurate error message when +an initrd > 2GiB was passed. That was fixed on patch: + + commit f3839fda5771596152b75dd1e1a6d050e6e6e380 + Author: Li Zhijian + Date: Thu Sep 13 18:07:13 2018 +0800 + + change get_image_size return type to int64_t + +This change adds a regression test for that fix. It starts +QEMU with a 2GiB dummy initrd, and checks that it evaluates the +file size correctly and prints an accurate message. + +Signed-off-by: Wainer dos Santos Moschetta +Reviewed-by: Caio Carrara +Reviewed-by: Cleber Rosa +Reviewed-by: Eduardo Habkost +Reviewed-by: Philippe Mathieu-Daudé +Tested-by: Philippe Mathieu-Daudé +Message-Id: <20181109182153.5390-1-wainersm@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 82d4c923a580751c86dc0852a7cc8e369a78e8ad) +Signed-off-by: Yash Mankad +Signed-off-by: Danilo C. L. de Paula +--- + tests/acceptance/linux_initrd.py | 48 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + create mode 100644 tests/acceptance/linux_initrd.py + +diff --git a/tests/acceptance/linux_initrd.py b/tests/acceptance/linux_initrd.py +new file mode 100644 +index 0000000..737355c +--- /dev/null ++++ b/tests/acceptance/linux_initrd.py +@@ -0,0 +1,48 @@ ++# Linux initrd acceptance test. ++# ++# Copyright (c) 2018 Red Hat, Inc. ++# ++# Author: ++# Wainer dos Santos Moschetta ++# ++# This work is licensed under the terms of the GNU GPL, version 2 or ++# later. See the COPYING file in the top-level directory. ++ ++import tempfile ++from avocado.utils.process import run ++ ++from avocado_qemu import Test ++ ++ ++class LinuxInitrd(Test): ++ """ ++ Checks QEMU evaluates correctly the initrd file passed as -initrd option. ++ ++ :avocado: enable ++ :avocado: tags=x86_64 ++ """ ++ ++ timeout = 60 ++ ++ def test_with_2gib_file_should_exit_error_msg(self): ++ """ ++ Pretends to boot QEMU with an initrd file with size of 2GiB ++ and expect it exits with error message. ++ """ ++ kernel_url = ('https://mirrors.kernel.org/fedora/releases/28/' ++ 'Everything/x86_64/os/images/pxeboot/vmlinuz') ++ kernel_hash = '238e083e114c48200f80d889f7e32eeb2793e02a' ++ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) ++ max_size = 2 * (1024 ** 3) - 1 ++ ++ with tempfile.NamedTemporaryFile() as initrd: ++ initrd.seek(max_size) ++ initrd.write(b'\0') ++ initrd.flush() ++ cmd = "%s -kernel %s -initrd %s" % (self.qemu_bin, kernel_path, ++ initrd.name) ++ res = run(cmd, ignore_status=True) ++ self.assertEqual(res.exit_status, 1) ++ expected_msg = r'.*initrd is too large.*max: \d+, need %s.*' % ( ++ max_size + 1) ++ self.assertRegex(res.stderr_text, expected_msg) +-- +1.8.3.1 + diff --git a/kvm-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch b/kvm-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch new file mode 100644 index 0000000..47fa62c --- /dev/null +++ b/kvm-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch @@ -0,0 +1,64 @@ +From b5ede4ceec64a7b812f40457771948420cd3780f Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Wed, 6 Feb 2019 03:58:56 +0000 +Subject: [PATCH 4/8] BZ1653590: Require at least 64kiB pages for downstream + guests & hosts + +RH-Author: David Gibson +Message-id: <20190206035856.19058-1-dgibson@redhat.com> +Patchwork-id: 84246 +O-Subject: [RHELAV-8.0/rhel qemu-kvm PATCH] BZ1653590: Require at least 64kiB pages for downstream guests & hosts +Bugzilla: 1653590 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Serhii Popovych +RH-Acked-by: Thomas Huth + +Most current POWER guests require 64kiB page support, so that's the default +for the cap-hpt-max-pagesize option in qemu which limits available guest +page sizes. We warn if the value is set smaller than that, but don't +outright fail upstream, because we need to allow for the possibility of +guest (and/or host) kernels configured for 4kiB page sizes. + +Downstream, however, we simply don't support 4kiB pagesize configured +kernels in guest or host, so we can have qemu simply error out in this +situation. + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1653590 +Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=20089737 +Branch: rhel8/master-3.1.0 +Testing: Attempted to start a guest with cap-hpt-max-page-size=4k and verified + it failed immediately with a qemu error + +Signed-off-by: David Gibson +Signed-off-by: Danilo C. L. de Paula +--- + hw/ppc/spapr_caps.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c +index 64f98ae..ace7325 100644 +--- a/hw/ppc/spapr_caps.c ++++ b/hw/ppc/spapr_caps.c +@@ -325,12 +325,19 @@ void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize, + static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr, + uint8_t val, Error **errp) + { ++#if 0 /* disabled for RHEL */ + if (val < 12) { + error_setg(errp, "Require at least 4kiB hpt-max-page-size"); + return; + } else if (val < 16) { + warn_report("Many guests require at least 64kiB hpt-max-page-size"); + } ++#else /* Only page sizes >=64kiB supported for RHEL */ ++ if (val < 16) { ++ error_setg(errp, "Require at least 64kiB hpt-max-page-size"); ++ return; ++ } ++#endif + + spapr_check_pagesize(spapr, qemu_getrampagesize(), errp); + } +-- +1.8.3.1 + diff --git a/kvm-block-Fix-invalidate_cache-error-path-for-parent-act.patch b/kvm-block-Fix-invalidate_cache-error-path-for-parent-act.patch new file mode 100644 index 0000000..357b528 --- /dev/null +++ b/kvm-block-Fix-invalidate_cache-error-path-for-parent-act.patch @@ -0,0 +1,69 @@ +From d6445c856c6199938eccbd73721c0c8257604557 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 6 Feb 2019 15:13:14 +0000 +Subject: [PATCH 5/8] block: Fix invalidate_cache error path for parent + activation + +RH-Author: Kevin Wolf +Message-id: <20190206151314.4789-2-kwolf@redhat.com> +Patchwork-id: 84251 +O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 1/1] block: Fix invalidate_cache error path for parent activation +Bugzilla: 1673014 +RH-Acked-by: John Snow +RH-Acked-by: Markus Armbruster +RH-Acked-by: Max Reitz + +bdrv_co_invalidate_cache() clears the BDRV_O_INACTIVE flag before +actually activating a node so that the correct permissions etc. are +taken. In case of errors, the flag must be restored so that the next +call to bdrv_co_invalidate_cache() retries activation. + +Restoring the flag was missing in the error path for a failed +parent->role->activate() call. The consequence is that this attempt to +activate all images correctly fails because we still set errp, however +on the next attempt BDRV_O_INACTIVE is already clear, so we return +success without actually retrying the failed action. + +An example where this is observable in practice is migration to a QEMU +instance that has a raw format block node attached to a guest device +with share-rw=off (the default) while another process holds +BLK_PERM_WRITE for the same image. In this case, all activation steps +before parent->role->activate() succeed because raw can tolerate other +writers to the image. Only the parent callback (in particular +blk_root_activate()) tries to implement the share-rw=on property and +requests exclusive write permissions. This fails when the migration +completes and correctly displays an error. However, a manual 'cont' will +incorrectly resume the VM without calling blk_root_activate() again. + +This case is described in more detail in the following bug report: +https://bugzilla.redhat.com/show_bug.cgi?id=1531888 + +Fix this by correctly restoring the BDRV_O_INACTIVE flag in the error +path. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Tested-by: Markus Armbruster +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 78fc3b3a26c145eebcdee992988644974b243a74) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/block.c b/block.c +index 811239c..1ec4512 100644 +--- a/block.c ++++ b/block.c +@@ -4553,6 +4553,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, + if (parent->role->activate) { + parent->role->activate(parent, &local_err); + if (local_err) { ++ bs->open_flags |= BDRV_O_INACTIVE; + error_propagate(errp, local_err); + return; + } +-- +1.8.3.1 + diff --git a/kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch b/kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch new file mode 100644 index 0000000..7bf4e7f --- /dev/null +++ b/kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch @@ -0,0 +1,177 @@ +From 1a283b8cdd349b9085488a516f26f453c8591ce2 Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Tue, 5 Feb 2019 04:47:57 +0000 +Subject: [PATCH 3/8] mmap-alloc: fix hugetlbfs misaligned length in ppc64 + +RH-Author: David Gibson +Message-id: <20190205044757.13591-3-dgibson@redhat.com> +Patchwork-id: 84233 +O-Subject: [RHELAV-8.0 qemu-kvm PATCH 2/2] mmap-alloc: fix hugetlbfs misaligned length in ppc64 +Bugzilla: 1671519 +RH-Acked-by: Pankaj Gupta +RH-Acked-by: Laurent Vivier +RH-Acked-by: Thomas Huth + +From: Murilo Opsfelder Araujo + +The commit 7197fb4058bcb68986bae2bb2c04d6370f3e7218 ("util/mmap-alloc: +fix hugetlb support on ppc64") fixed Huge TLB mappings on ppc64. + +However, we still need to consider the underlying huge page size +during munmap() because it requires that both address and length be a +multiple of the underlying huge page size for Huge TLB mappings. +Quote from "Huge page (Huge TLB) mappings" paragraph under NOTES +section of the munmap(2) manual: + + "For munmap(), addr and length must both be a multiple of the + underlying huge page size." + +On ppc64, the munmap() in qemu_ram_munmap() does not work for Huge TLB +mappings because the mapped segment can be aligned with the underlying +huge page size, not aligned with the native system page size, as +returned by getpagesize(). + +This has the side effect of not releasing huge pages back to the pool +after a hugetlbfs file-backed memory device is hot-unplugged. + +This patch fixes the situation in qemu_ram_mmap() and +qemu_ram_munmap() by considering the underlying page size on ppc64. + +After this patch, memory hot-unplug releases huge pages back to the +pool. + +Fixes: 7197fb4058bcb68986bae2bb2c04d6370f3e7218 +Signed-off-by: Murilo Opsfelder Araujo +Reviewed-by: Greg Kurz +Signed-off-by: David Gibson +(cherry picked from commit 53adb9d43e1abba187387a51f238e878e934c647) + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1671519 + +Signed-off-by: David Gibson +Signed-off-by: Danilo C. L. de Paula +--- + exec.c | 4 ++-- + include/qemu/mmap-alloc.h | 2 +- + util/mmap-alloc.c | 22 ++++++++++++++++------ + util/oslib-posix.c | 2 +- + 4 files changed, 20 insertions(+), 10 deletions(-) + +diff --git a/exec.c b/exec.c +index bb6170d..38eaf0f 100644 +--- a/exec.c ++++ b/exec.c +@@ -1870,7 +1870,7 @@ static void *file_ram_alloc(RAMBlock *block, + if (mem_prealloc) { + os_mem_prealloc(fd, area, memory, smp_cpus, errp); + if (errp && *errp) { +- qemu_ram_munmap(area, memory); ++ qemu_ram_munmap(fd, area, memory); + return NULL; + } + } +@@ -2391,7 +2391,7 @@ static void reclaim_ramblock(RAMBlock *block) + xen_invalidate_map_cache_entry(block->host); + #ifndef _WIN32 + } else if (block->fd >= 0) { +- qemu_ram_munmap(block->host, block->max_length); ++ qemu_ram_munmap(block->fd, block->host, block->max_length); + close(block->fd); + #endif + } else { +diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h +index 50385e3..ef04f0e 100644 +--- a/include/qemu/mmap-alloc.h ++++ b/include/qemu/mmap-alloc.h +@@ -9,6 +9,6 @@ size_t qemu_mempath_getpagesize(const char *mem_path); + + void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared); + +-void qemu_ram_munmap(void *ptr, size_t size); ++void qemu_ram_munmap(int fd, void *ptr, size_t size); + + #endif +diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c +index f71ea03..8565885 100644 +--- a/util/mmap-alloc.c ++++ b/util/mmap-alloc.c +@@ -80,6 +80,7 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + int flags; + int guardfd; + size_t offset; ++ size_t pagesize; + size_t total; + void *guardptr; + void *ptr; +@@ -100,7 +101,8 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + * anonymous memory is OK. + */ + flags = MAP_PRIVATE; +- if (fd == -1 || qemu_fd_getpagesize(fd) == getpagesize()) { ++ pagesize = qemu_fd_getpagesize(fd); ++ if (fd == -1 || pagesize == getpagesize()) { + guardfd = -1; + flags |= MAP_ANONYMOUS; + } else { +@@ -109,6 +111,7 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + } + #else + guardfd = -1; ++ pagesize = getpagesize(); + flags = MAP_PRIVATE | MAP_ANONYMOUS; + #endif + +@@ -120,7 +123,7 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + + assert(is_power_of_2(align)); + /* Always align to host page size */ +- assert(align >= getpagesize()); ++ assert(align >= pagesize); + + flags = MAP_FIXED; + flags |= fd == -1 ? MAP_ANONYMOUS : 0; +@@ -143,17 +146,24 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + * a guard page guarding against potential buffer overflows. + */ + total -= offset; +- if (total > size + getpagesize()) { +- munmap(ptr + size + getpagesize(), total - size - getpagesize()); ++ if (total > size + pagesize) { ++ munmap(ptr + size + pagesize, total - size - pagesize); + } + + return ptr; + } + +-void qemu_ram_munmap(void *ptr, size_t size) ++void qemu_ram_munmap(int fd, void *ptr, size_t size) + { ++ size_t pagesize; ++ + if (ptr) { + /* Unmap both the RAM block and the guard page */ +- munmap(ptr, size + getpagesize()); ++#if defined(__powerpc64__) && defined(__linux__) ++ pagesize = qemu_fd_getpagesize(fd); ++#else ++ pagesize = getpagesize(); ++#endif ++ munmap(ptr, size + pagesize); + } + } +diff --git a/util/oslib-posix.c b/util/oslib-posix.c +index c1bee2a..97b2f3b 100644 +--- a/util/oslib-posix.c ++++ b/util/oslib-posix.c +@@ -226,7 +226,7 @@ void qemu_vfree(void *ptr) + void qemu_anon_ram_free(void *ptr, size_t size) + { + trace_qemu_anon_ram_free(ptr, size); +- qemu_ram_munmap(ptr, size); ++ qemu_ram_munmap(-1, ptr, size); + } + + void qemu_set_block(int fd) +-- +1.8.3.1 + diff --git a/kvm-mmap-alloc-unfold-qemu_ram_mmap.patch b/kvm-mmap-alloc-unfold-qemu_ram_mmap.patch new file mode 100644 index 0000000..3a6dd86 --- /dev/null +++ b/kvm-mmap-alloc-unfold-qemu_ram_mmap.patch @@ -0,0 +1,138 @@ +From 2215d38d1231284cced64d94b4430e92c9e2c017 Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Tue, 5 Feb 2019 04:47:56 +0000 +Subject: [PATCH 2/8] mmap-alloc: unfold qemu_ram_mmap() + +RH-Author: David Gibson +Message-id: <20190205044757.13591-2-dgibson@redhat.com> +Patchwork-id: 84234 +O-Subject: [RHELAV-8.0 qemu-kvm PATCH 1/2] mmap-alloc: unfold qemu_ram_mmap() +Bugzilla: 1671519 +RH-Acked-by: Pankaj Gupta +RH-Acked-by: Laurent Vivier +RH-Acked-by: Serhii Popovych + +From: Murilo Opsfelder Araujo + +Unfold parts of qemu_ram_mmap() for the sake of understanding, moving +declarations to the top, and keeping architecture-specifics in the +ifdef-else blocks. No changes in the function behaviour. + +Give ptr and ptr1 meaningful names: + ptr -> guardptr : pointer to the PROT_NONE guard region + ptr1 -> ptr : pointer to the mapped memory returned to caller + +Signed-off-by: Murilo Opsfelder Araujo +Reviewed-by: Greg Kurz +Signed-off-by: David Gibson +(cherry picked from commit 2044c3e7116eeac0449dcb4a4130cc8f8b9310da) + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1671519 + +Signed-off-by: David Gibson +Signed-off-by: Danilo C. L. de Paula +--- + util/mmap-alloc.c | 53 ++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 34 insertions(+), 19 deletions(-) + +diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c +index fd329ec..f71ea03 100644 +--- a/util/mmap-alloc.c ++++ b/util/mmap-alloc.c +@@ -77,11 +77,19 @@ size_t qemu_mempath_getpagesize(const char *mem_path) + + void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + { ++ int flags; ++ int guardfd; ++ size_t offset; ++ size_t total; ++ void *guardptr; ++ void *ptr; ++ + /* + * Note: this always allocates at least one extra page of virtual address + * space, even if size is already aligned. + */ +- size_t total = size + align; ++ total = size + align; ++ + #if defined(__powerpc64__) && defined(__linux__) + /* On ppc64 mappings in the same segment (aka slice) must share the same + * page size. Since we will be re-allocating part of this segment +@@ -91,16 +99,22 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + * We do this unless we are using the system page size, in which case + * anonymous memory is OK. + */ +- int anonfd = fd == -1 || qemu_fd_getpagesize(fd) == getpagesize() ? -1 : fd; +- int flags = anonfd == -1 ? MAP_ANONYMOUS : MAP_NORESERVE; +- void *ptr = mmap(0, total, PROT_NONE, flags | MAP_PRIVATE, anonfd, 0); ++ flags = MAP_PRIVATE; ++ if (fd == -1 || qemu_fd_getpagesize(fd) == getpagesize()) { ++ guardfd = -1; ++ flags |= MAP_ANONYMOUS; ++ } else { ++ guardfd = fd; ++ flags |= MAP_NORESERVE; ++ } + #else +- void *ptr = mmap(0, total, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ++ guardfd = -1; ++ flags = MAP_PRIVATE | MAP_ANONYMOUS; + #endif +- size_t offset; +- void *ptr1; + +- if (ptr == MAP_FAILED) { ++ guardptr = mmap(0, total, PROT_NONE, flags, guardfd, 0); ++ ++ if (guardptr == MAP_FAILED) { + return MAP_FAILED; + } + +@@ -108,19 +122,20 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + /* Always align to host page size */ + assert(align >= getpagesize()); + +- offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr; +- ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE, +- MAP_FIXED | +- (fd == -1 ? MAP_ANONYMOUS : 0) | +- (shared ? MAP_SHARED : MAP_PRIVATE), +- fd, 0); +- if (ptr1 == MAP_FAILED) { +- munmap(ptr, total); ++ flags = MAP_FIXED; ++ flags |= fd == -1 ? MAP_ANONYMOUS : 0; ++ flags |= shared ? MAP_SHARED : MAP_PRIVATE; ++ offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr; ++ ++ ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, flags, fd, 0); ++ ++ if (ptr == MAP_FAILED) { ++ munmap(guardptr, total); + return MAP_FAILED; + } + + if (offset > 0) { +- munmap(ptr, offset); ++ munmap(guardptr, offset); + } + + /* +@@ -129,10 +144,10 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) + */ + total -= offset; + if (total > size + getpagesize()) { +- munmap(ptr1 + size + getpagesize(), total - size - getpagesize()); ++ munmap(ptr + size + getpagesize(), total - size - getpagesize()); + } + +- return ptr1; ++ return ptr; + } + + void qemu_ram_munmap(void *ptr, size_t size) +-- +1.8.3.1 + diff --git a/kvm-scsi-disk-Acquire-the-AioContext-in-scsi_-_realize.patch b/kvm-scsi-disk-Acquire-the-AioContext-in-scsi_-_realize.patch new file mode 100644 index 0000000..da2e60b --- /dev/null +++ b/kvm-scsi-disk-Acquire-the-AioContext-in-scsi_-_realize.patch @@ -0,0 +1,187 @@ +From acf3927aef42a4a380fa1366b2eca8a8f2b44bc4 Mon Sep 17 00:00:00 2001 +From: Markus Armbruster +Date: Thu, 7 Feb 2019 12:18:18 +0000 +Subject: [PATCH 7/8] scsi-disk: Acquire the AioContext in scsi_*_realize() + +RH-Author: Markus Armbruster +Message-id: <20190207121819.20092-3-armbru@redhat.com> +Patchwork-id: 84291 +O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 2/3] scsi-disk: Acquire the AioContext in scsi_*_realize() +Bugzilla: 1656276 1662508 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Max Reitz +RH-Acked-by: Stefan Hajnoczi + +From: Alberto Garcia + +This fixes a crash when attaching two disks with the same blockdev to +a SCSI device that is using iothreads. Test case included. + +Signed-off-by: Alberto Garcia +Signed-off-by: Kevin Wolf +(cherry picked from commit 3ff35ba391134e4e43ab96152deb38a62e62f858) +Signed-off-by: Danilo C. L. de Paula +--- + hw/scsi/scsi-disk.c | 23 ++++++++++++++++++++--- + tests/qemu-iotests/240 | 18 ++++++++++++++++++ + tests/qemu-iotests/240.out | 16 ++++++++++++++++ + 3 files changed, 54 insertions(+), 3 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index e74e1e7..e6db6d7 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -2389,10 +2389,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) + static void scsi_hd_realize(SCSIDevice *dev, Error **errp) + { + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); ++ AioContext *ctx = NULL; + /* can happen for devices without drive. The error message for missing + * backend will be issued in scsi_realize + */ + if (s->qdev.conf.blk) { ++ ctx = blk_get_aio_context(s->qdev.conf.blk); ++ aio_context_acquire(ctx); + blkconf_blocksizes(&s->qdev.conf); + } + s->qdev.blocksize = s->qdev.conf.logical_block_size; +@@ -2401,11 +2404,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp) + s->product = g_strdup("QEMU HARDDISK"); + } + scsi_realize(&s->qdev, errp); ++ if (ctx) { ++ aio_context_release(ctx); ++ } + } + + static void scsi_cd_realize(SCSIDevice *dev, Error **errp) + { + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); ++ AioContext *ctx; + int ret; + + if (!dev->conf.blk) { +@@ -2416,6 +2423,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) + assert(ret == 0); + } + ++ ctx = blk_get_aio_context(dev->conf.blk); ++ aio_context_acquire(ctx); + s->qdev.blocksize = 2048; + s->qdev.type = TYPE_ROM; + s->features |= 1 << SCSI_DISK_F_REMOVABLE; +@@ -2423,6 +2432,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) + s->product = g_strdup("QEMU CD-ROM"); + } + scsi_realize(&s->qdev, errp); ++ aio_context_release(ctx); + } + + static void scsi_disk_realize(SCSIDevice *dev, Error **errp) +@@ -2561,6 +2571,7 @@ static int get_device_type(SCSIDiskState *s) + static void scsi_block_realize(SCSIDevice *dev, Error **errp) + { + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); ++ AioContext *ctx; + int sg_version; + int rc; + +@@ -2575,6 +2586,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) + "be removed in a future version"); + } + ++ ctx = blk_get_aio_context(s->qdev.conf.blk); ++ aio_context_acquire(ctx); ++ + /* check we are using a driver managing SG_IO (version 3 and after) */ + rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version); + if (rc < 0) { +@@ -2582,18 +2596,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) + if (rc != -EPERM) { + error_append_hint(errp, "Is this a SCSI device?\n"); + } +- return; ++ goto out; + } + if (sg_version < 30000) { + error_setg(errp, "scsi generic interface too old"); +- return; ++ goto out; + } + + /* get device type from INQUIRY data */ + rc = get_device_type(s); + if (rc < 0) { + error_setg(errp, "INQUIRY failed"); +- return; ++ goto out; + } + + /* Make a guess for the block size, we'll fix it when the guest sends. +@@ -2613,6 +2627,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) + + scsi_realize(&s->qdev, errp); + scsi_generic_read_device_inquiry(&s->qdev); ++ ++out: ++ aio_context_release(ctx); + } + + typedef struct SCSIBlockReq { +diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240 +index ead7ee0..5d499c9 100755 +--- a/tests/qemu-iotests/240 ++++ b/tests/qemu-iotests/240 +@@ -83,6 +83,24 @@ run_qemu < +Date: Thu, 7 Feb 2019 12:18:19 +0000 +Subject: [PATCH 8/8] virtio-scsi: Forbid devices with different iothreads + sharing a blockdev + +RH-Author: Markus Armbruster +Message-id: <20190207121819.20092-4-armbru@redhat.com> +Patchwork-id: 84289 +O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 3/3] virtio-scsi: Forbid devices with different iothreads sharing a blockdev +Bugzilla: 1656276 1662508 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Max Reitz +RH-Acked-by: Stefan Hajnoczi + +From: Alberto Garcia + +This patch forbids attaching a disk to a SCSI device if its using a +different AioContext. Test case included. + +Signed-off-by: Alberto Garcia +Signed-off-by: Kevin Wolf +(cherry picked from commit eb97813ff5fd5bdffc8ed9f5be5a3a50eae70a2c) +Signed-off-by: Danilo C. L. de Paula +--- + hw/scsi/virtio-scsi.c | 7 +++++++ + tests/qemu-iotests/240 | 22 ++++++++++++++++++++++ + tests/qemu-iotests/240.out | 20 ++++++++++++++++++++ + 3 files changed, 49 insertions(+) + +diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c +index f0d4f10..66df30d 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -800,9 +800,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, + return; + } + if (s->ctx && !s->dataplane_fenced) { ++ AioContext *ctx; + if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { + return; + } ++ ctx = blk_get_aio_context(sd->conf.blk); ++ if (ctx != s->ctx && ctx != qemu_get_aio_context()) { ++ error_setg(errp, "Cannot attach a blockdev that is using " ++ "a different iothread"); ++ return; ++ } + virtio_scsi_acquire(s); + blk_set_aio_context(sd->conf.blk, s->ctx); + virtio_scsi_release(s); +diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240 +index 5d499c9..65cc3b3 100755 +--- a/tests/qemu-iotests/240 ++++ b/tests/qemu-iotests/240 +@@ -101,6 +101,28 @@ run_qemu < +Date: Thu, 7 Feb 2019 12:18:17 +0000 +Subject: [PATCH 6/8] virtio-scsi: Move BlockBackend back to the main + AioContext on unplug + +RH-Author: Markus Armbruster +Message-id: <20190207121819.20092-2-armbru@redhat.com> +Patchwork-id: 84290 +O-Subject: [RHEL-8.0/AV qemu-kvm PATCH 1/3] virtio-scsi: Move BlockBackend back to the main AioContext on unplug +Bugzilla: 1656276 1662508 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Max Reitz +RH-Acked-by: Stefan Hajnoczi + +From: Alberto Garcia + +This fixes a crash when attaching a disk to a SCSI device using +iothreads, then detaching it and reattaching it again. Test case +included. + +Signed-off-by: Alberto Garcia +Signed-off-by: Kevin Wolf +(cherry picked from commit a6f230c8d13a7ff3a0c7f1097412f44bfd9eff0b) +[Trivial conflict in tests/qemu-iotests/group due to lack of commit +1c4e7b640b resolved] +Signed-off-by: Markus Armbruster + +Signed-off-by: Danilo C. L. de Paula +--- + hw/scsi/virtio-scsi.c | 6 ++++ + tests/qemu-iotests/240 | 89 ++++++++++++++++++++++++++++++++++++++++++++++ + tests/qemu-iotests/240.out | 18 ++++++++++ + tests/qemu-iotests/group | 1 + + 4 files changed, 114 insertions(+) + create mode 100755 tests/qemu-iotests/240 + create mode 100644 tests/qemu-iotests/240.out + +diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c +index 9f754c4..f0d4f10 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -833,6 +833,12 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, + virtio_scsi_release(s); + } + ++ if (s->ctx) { ++ virtio_scsi_acquire(s); ++ blk_set_aio_context(sd->conf.blk, qemu_get_aio_context()); ++ virtio_scsi_release(s); ++ } ++ + qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); + } + +diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240 +new file mode 100755 +index 0000000..ead7ee0 +--- /dev/null ++++ b/tests/qemu-iotests/240 +@@ -0,0 +1,89 @@ ++#!/bin/bash ++# ++# Test hot plugging and unplugging with iothreads ++# ++# Copyright (C) 2019 Igalia, S.L. ++# Author: Alberto Garcia ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++# creator ++owner=berto@igalia.com ++ ++seq=`basename $0` ++echo "QA output created by $seq" ++ ++status=1 # failure is the default! ++ ++# get standard environment, filters and checks ++. ./common.rc ++. ./common.filter ++ ++_supported_fmt generic ++_supported_proto generic ++_supported_os Linux ++ ++do_run_qemu() ++{ ++ echo Testing: "$@" ++ $QEMU -nographic -qmp stdio -serial none "$@" ++ echo ++} ++ ++# Remove QMP events from (pretty-printed) output. Doesn't handle ++# nested dicts correctly, but we don't get any of those in this test. ++_filter_qmp_events() ++{ ++ tr '\n' '\t' | sed -e \ ++ 's/{\s*"timestamp":\s*{[^}]*},\s*"event":[^,}]*\(,\s*"data":\s*{[^}]*}\)\?\s*}\s*//g' \ ++ | tr '\t' '\n' ++} ++ ++run_qemu() ++{ ++ do_run_qemu "$@" 2>&1 | _filter_qmp | _filter_qmp_events ++} ++ ++case "$QEMU_DEFAULT_MACHINE" in ++ s390-ccw-virtio) ++ virtio_scsi=virtio-scsi-ccw ++ ;; ++ *) ++ virtio_scsi=virtio-scsi-pci ++ ;; ++esac ++ ++echo ++echo === Unplug a SCSI disk and then plug it again === ++echo ++ ++run_qemu < - 3.1.0-13.el8 +- kvm-Acceptance-tests-add-Linux-initrd-checking-test.patch [bz#1669922] +- kvm-mmap-alloc-unfold-qemu_ram_mmap.patch [bz#1671519] +- kvm-mmap-alloc-fix-hugetlbfs-misaligned-length-in-ppc64.patch [bz#1671519] +- kvm-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch [bz#1653590] +- kvm-block-Fix-invalidate_cache-error-path-for-parent-act.patch [bz#1673014] +- kvm-virtio-scsi-Move-BlockBackend-back-to-the-main-AioCo.patch [bz#1656276 bz#1662508] +- kvm-scsi-disk-Acquire-the-AioContext-in-scsi_-_realize.patch [bz#1656276 bz#1662508] +- kvm-virtio-scsi-Forbid-devices-with-different-iothreads-.patch [bz#1656276 bz#1662508] +- Resolves: bz#1653590 + ([Fast train]had better stop qemu immediately while guest was making use of an improper page size) +- Resolves: bz#1656276 + (qemu-kvm core dumped after hotplug the deleted disk with iothread parameter) +- Resolves: bz#1662508 + (Qemu core dump when start guest with two disks using same drive) +- Resolves: bz#1669922 + (Backport avocado-qemu tests for QEMU 3.1) +- Resolves: bz#1671519 + (RHEL8.0 Snapshot3 - qemu doesn't free up hugepage memory when hotplug/hotunplug using memory-backend-file (qemu-kvm)) +- Resolves: bz#1673014 + (Local VM and migrated VM on the same host can run with same RAW file as visual disk source while without shareable configured or lock manager enabled) + * Fri Feb 08 2019 Danilo Cesar Lemes de Paula - 3.1.0-12.el8 - Removing kvm-Fix-fsfreeze-hook-path-in-the-man-page.patch [bz#1644985] - kvm-io-ensure-UNIX-client-doesn-t-unlink-server-socket.patch [bz#1665896]