diff --git a/SOURCES/kvm-hw-scsi-support-SCSI-2-passthrough-without-PI.patch b/SOURCES/kvm-hw-scsi-support-SCSI-2-passthrough-without-PI.patch new file mode 100644 index 0000000..fc7874c --- /dev/null +++ b/SOURCES/kvm-hw-scsi-support-SCSI-2-passthrough-without-PI.patch @@ -0,0 +1,137 @@ +From 968575c7d427c476522e8bfef0aeb3a0bc09fb4a Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Mon, 25 Jun 2018 04:18:24 +0200 +Subject: [PATCH 2/3] hw/scsi: support SCSI-2 passthrough without PI + +RH-Author: David Gibson +Message-id: <20180625041824.5072-3-dgibson@redhat.com> +Patchwork-id: 81030 +O-Subject: [RHEL-7.5.z qemu-kvm-ma PATCH 2/2] hw/scsi: support SCSI-2 passthrough without PI +Bugzilla: 1593193 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laszlo Ersek + +From: Daniel Henrique Barboza + +QEMU SCSI code makes assumptions about how the PROTECT and BYTCHK +works in the protocol, denying support for PI (Protection +Information) in case the guest OS requests it. However, in SCSI versions 2 +and older, there is no PI concept in the protocol. + +This means that when dealing with such devices: + +- there is no PROTECT bit in byte 5 of the standard INQUIRY response. The +whole byte is marked as "Reserved"; + +- there is no RDPROTECT in byte 2 of READ. We have 'Logical Unit Number' +in this field instead; + +- there is no VRPROTECT in byte 2 of VERIFY. We have 'Logical Unit Number' +in this field instead. This also means that the BYTCHK bit in this case +is not related to PI. + +Since QEMU does not consider these changes, a SCSI passthrough using +a SCSI-2 device will not work. It will mistake these fields with +PI information and return Illegal Request SCSI SENSE thinking +that the driver is asking for PI support. + +This patch fixes it by adding a new attribute called 'scsi_version' +that is read from the standard INQUIRY response of passthrough +devices. This allows for a version verification before applying +conditions related to PI that doesn't apply for older versions. + +Reported-by: Dac Nguyen +Signed-off-by: Daniel Henrique Barboza +Message-Id: <20180327211451.14647-1-danielhb@linux.vnet.ibm.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 29e560f00e2bc1b5731c8276031aaf192de55d9d) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + hw/scsi/scsi-disk.c | 2 +- + hw/scsi/scsi-generic.c | 47 ++++++++++++++++++++++++++++++++++++----------- + 2 files changed, 37 insertions(+), 12 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index f906ffb..d89e4f0 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -3011,7 +3011,7 @@ static Property scsi_block_properties[] = { + DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), + DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, +- 5), ++ -1), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c +index fe11efe..e38829a 100644 +--- a/hw/scsi/scsi-generic.c ++++ b/hw/scsi/scsi-generic.c +@@ -194,17 +194,40 @@ static void scsi_read_complete(void * opaque, int ret) + r->buf[3] |= 0x80; + } + } +- if (s->type == TYPE_DISK && +- r->req.cmd.buf[0] == INQUIRY && +- r->req.cmd.buf[2] == 0xb0) { +- uint32_t max_transfer = +- blk_get_max_transfer(s->conf.blk) / s->blocksize; +- +- assert(max_transfer); +- stl_be_p(&r->buf[8], max_transfer); +- /* Also take care of the opt xfer len. */ +- stl_be_p(&r->buf[12], +- MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12]))); ++ if (r->req.cmd.buf[0] == INQUIRY) { ++ /* ++ * EVPD set to zero returns the standard INQUIRY data. ++ * ++ * Check if scsi_version is unset (-1) to avoid re-defining it ++ * each time an INQUIRY with standard data is received. ++ * scsi_version is initialized with -1 in scsi_generic_reset ++ * and scsi_disk_reset, making sure that we'll set the ++ * scsi_version after a reset. If the version field of the ++ * INQUIRY response somehow changes after a guest reboot, ++ * we'll be able to keep track of it. ++ * ++ * On SCSI-2 and older, first 3 bits of byte 2 is the ++ * ANSI-approved version, while on later versions the ++ * whole byte 2 contains the version. Check if we're dealing ++ * with a newer version and, in that case, assign the ++ * whole byte. ++ */ ++ if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) { ++ s->scsi_version = r->buf[2] & 0x07; ++ if (s->scsi_version > 2) { ++ s->scsi_version = r->buf[2]; ++ } ++ } ++ if (s->type == TYPE_DISK && r->req.cmd.buf[2] == 0xb0) { ++ uint32_t max_transfer = ++ blk_get_max_transfer(s->conf.blk) / s->blocksize; ++ ++ assert(max_transfer); ++ stl_be_p(&r->buf[8], max_transfer); ++ /* Also take care of the opt xfer len. */ ++ stl_be_p(&r->buf[12], ++ MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12]))); ++ } + } + scsi_req_data(&r->req, len); + scsi_req_unref(&r->req); +@@ -552,6 +575,8 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) + + DPRINTF("block size %d\n", s->blocksize); + ++ /* Only used by scsi-block, but initialize it nevertheless to be clean. */ ++ s->default_scsi_version = -1; + scsi_generic_read_device_identification(s); + } + +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-fix-storage-attributes-migration-for-non-small.patch b/SOURCES/kvm-s390x-fix-storage-attributes-migration-for-non-small.patch new file mode 100644 index 0000000..6e5cfd6 --- /dev/null +++ b/SOURCES/kvm-s390x-fix-storage-attributes-migration-for-non-small.patch @@ -0,0 +1,65 @@ +From 56c0724bf309a7d6d89f2aba0d38147b1e77954f Mon Sep 17 00:00:00 2001 +From: Cornelia Huck +Date: Fri, 29 Jun 2018 12:57:01 +0200 +Subject: [PATCH 3/3] s390x: fix storage attributes migration for non-small + guests + +RH-Author: Cornelia Huck +Message-id: <20180629125701.12755-1-cohuck@redhat.com> +Patchwork-id: 81166 +O-Subject: [RHEL-7.5.z qemu-kvm-ma PATCH] s390x: fix storage attributes migration for non-small guests +Bugzilla: 1596553 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Miroslav Rezanina + +From: Claudio Imbrenda + +Fix storage attribute migration so that it does not fail for guests +with more than a few GB of RAM. +With such guests, the index in the buffer would go out of bounds, +usually by large amounts, thus receiving -EFAULT from the kernel. +Migration itself would be successful, but storage attributes would then +not be migrated completely. + +This patch fixes the out of bounds access, and thus migration of all +storage attributes when the guest have large amounts of memory. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Claudio Imbrenda +Fixes: 903fd80b03243476 ("s390x/migration: Storage attributes device") +Message-Id: <1516297904-18188-1-git-send-email-imbrenda@linux.vnet.ibm.com> +Reviewed-by: Christian Borntraeger +Signed-off-by: Cornelia Huck +(cherry picked from commit 46fa893355e0bd88f3c59b886f0d75cbd5f0bbbe) +Signed-off-by: Cornelia Huck +Signed-off-by: Miroslav Rezanina +--- + hw/s390x/s390-stattrib-kvm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c +index bc0274d..1212c47 100644 +--- a/hw/s390x/s390-stattrib-kvm.c ++++ b/hw/s390x/s390-stattrib-kvm.c +@@ -115,7 +115,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa) + for (cx = 0; cx + len <= max; cx += len) { + clog.start_gfn = cx; + clog.count = len; +- clog.values = (uint64_t)(sas->incoming_buffer + cx * len); ++ clog.values = (uint64_t)(sas->incoming_buffer + cx); + r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog); + if (r) { + error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r)); +@@ -125,7 +125,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa) + if (cx < max) { + clog.start_gfn = cx; + clog.count = max - cx; +- clog.values = (uint64_t)(sas->incoming_buffer + cx * len); ++ clog.values = (uint64_t)(sas->incoming_buffer + cx); + r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog); + if (r) { + error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r)); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-scsi-disk-allow-customizing-the-SCSI-version.patch b/SOURCES/kvm-scsi-disk-allow-customizing-the-SCSI-version.patch new file mode 100644 index 0000000..8ef8ebd --- /dev/null +++ b/SOURCES/kvm-scsi-disk-allow-customizing-the-SCSI-version.patch @@ -0,0 +1,168 @@ +From f4684bd23bf0cd262d0d355a33bae1e9edd0fb5a Mon Sep 17 00:00:00 2001 +From: David Gibson +Date: Mon, 25 Jun 2018 04:18:23 +0200 +Subject: [PATCH 1/3] scsi-disk: allow customizing the SCSI version + +RH-Author: David Gibson +Message-id: <20180625041824.5072-2-dgibson@redhat.com> +Patchwork-id: 81032 +O-Subject: [RHEL-7.5.z qemu-kvm-ma PATCH 1/2] scsi-disk: allow customizing the SCSI version +Bugzilla: 1593193 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Laszlo Ersek + +From: Paolo Bonzini + +We would like to have different behavior for passthrough devices +depending on the SCSI version they expose. To prepare for that, +allow the user of emulated devices to specify the desired SCSI +level, and adjust the emulation according to the property value. +The next patch will set the level for scsi-block and scsi-generic +devices. + +Based on a patch by Daniel Henrique Barboza +. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2343be0d7ee8a6e02c2bf99d0243492085c8d399) + +Signed-off-by: David Gibson +Signed-off-by: Miroslav Rezanina +--- + hw/scsi/scsi-disk.c | 29 ++++++++++++++++++++++++----- + hw/scsi/scsi-generic.c | 1 + + include/hw/scsi/scsi.h | 2 ++ + 3 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 25cbd7b..f906ffb 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -800,7 +800,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) + * block characteristics VPD page by default. Not all of SPC-3 + * is actually implemented, but we're good enough. + */ +- outbuf[2] = 5; ++ outbuf[2] = s->qdev.default_scsi_version; + outbuf[3] = 2 | 0x10; /* Format 2, HiSup */ + + if (buflen > 36) { +@@ -2168,7 +2168,11 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) + case READ_12: + case READ_16: + DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len); +- if (r->req.cmd.buf[1] & 0xe0) { ++ /* Protection information is not supported. For SCSI versions 2 and ++ * older (as determined by snooping the guest's INQUIRY commands), ++ * there is no RD/WR/VRPROTECT, so skip this check in these versions. ++ */ ++ if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) { + goto illegal_request; + } + if (!check_lba_range(s, r->req.cmd.lba, len)) { +@@ -2199,7 +2203,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) + * As far as DMA is concerned, we can treat it the same as a write; + * scsi_block_do_sgio will send VERIFY commands. + */ +- if (r->req.cmd.buf[1] & 0xe0) { ++ if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) { + goto illegal_request; + } + if (!check_lba_range(s, r->req.cmd.lba, len)) { +@@ -2245,6 +2249,8 @@ static void scsi_disk_reset(DeviceState *dev) + /* reset tray statuses */ + s->tray_locked = 0; + s->tray_open = 0; ++ ++ s->qdev.scsi_version = s->qdev.default_scsi_version; + } + + static void scsi_disk_resize_cb(void *opaque) +@@ -2785,6 +2791,8 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf) + static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf) + { + SCSIBlockReq *r = (SCSIBlockReq *)req; ++ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); ++ + r->cmd = req->cmd.buf[0]; + switch (r->cmd >> 5) { + case 0: +@@ -2810,8 +2818,11 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf) + abort(); + } + +- if (r->cdb1 & 0xe0) { +- /* Protection information is not supported. */ ++ /* Protection information is not supported. For SCSI versions 2 and ++ * older (as determined by snooping the guest's INQUIRY commands), ++ * there is no RD/WR/VRPROTECT, so skip this check in these versions. ++ */ ++ if (s->qdev.scsi_version > 2 && (req->cmd.buf[1] & 0xe0)) { + scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD)); + return 0; + } +@@ -2923,6 +2934,8 @@ static Property scsi_hd_properties[] = { + DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size, + DEFAULT_MAX_IO_SIZE), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), ++ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, ++ 5), + DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf), + DEFINE_PROP_END_OF_LIST(), + }; +@@ -2968,6 +2981,8 @@ static Property scsi_cd_properties[] = { + DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0), + DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size, + DEFAULT_MAX_IO_SIZE), ++ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, ++ 5), + DEFINE_PROP_END_OF_LIST(), + }; + +@@ -2995,6 +3010,8 @@ static Property scsi_block_properties[] = { + DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), + DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), ++ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, ++ 5), + DEFINE_PROP_END_OF_LIST(), + }; + +@@ -3035,6 +3052,8 @@ static Property scsi_disk_properties[] = { + DEFAULT_MAX_UNMAP_SIZE), + DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size, + DEFAULT_MAX_IO_SIZE), ++ DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, ++ 5), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c +index ba70c0d..fe11efe 100644 +--- a/hw/scsi/scsi-generic.c ++++ b/hw/scsi/scsi-generic.c +@@ -474,6 +474,7 @@ static void scsi_generic_reset(DeviceState *dev) + { + SCSIDevice *s = SCSI_DEVICE(dev); + ++ s->scsi_version = s->default_scsi_version; + scsi_device_purge_requests(s, SENSE_CODE(RESET)); + } + +diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h +index 802a647..73ff391 100644 +--- a/include/hw/scsi/scsi.h ++++ b/include/hw/scsi/scsi.h +@@ -85,6 +85,8 @@ struct SCSIDevice + uint64_t max_lba; + uint64_t wwn; + uint64_t port_wwn; ++ int scsi_version; ++ int default_scsi_version; + }; + + extern const VMStateDescription vmstate_scsi_device; +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index 9f7889a..98eb28e 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -106,7 +106,7 @@ Obsoletes: %1%{rhel_ma_suffix} < %{obsoletes_version2} \ Summary: QEMU is a machine emulator and virtualizer Name: %{pkgname}%{?pkgsuffix} Version: 2.10.0 -Release: 21%{?dist}.2 +Release: 21%{?dist}.3 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 License: GPLv2+ and LGPLv2+ and BSD @@ -1057,6 +1057,12 @@ Patch450: kvm-iotests-Add-regression-test-for-commit-base-locking.patch Patch451: kvm-vga-add-ram_addr_t-cast.patch # For bz#1566878 - CVE-2018-7858 qemu-kvm-ma: Qemu: cirrus: OOB access when updating vga display [rhel-7] [rhel-7.5.z] Patch452: kvm-vga-fix-region-calculation.patch +# For bz#1593193 - Pegas1.1 - SCSI pass-thru of aacraid RAID1 is inaccessible (qemu-kvm-ma) [rhel-7.5.z] +Patch453: kvm-scsi-disk-allow-customizing-the-SCSI-version.patch +# For bz#1593193 - Pegas1.1 - SCSI pass-thru of aacraid RAID1 is inaccessible (qemu-kvm-ma) [rhel-7.5.z] +Patch454: kvm-hw-scsi-support-SCSI-2-passthrough-without-PI.patch +# For bz#1596553 - RHEL-Alt-7.5 - qemu has error during migration of larger guests [rhel-7.5.z] +Patch455: kvm-s390x-fix-storage-attributes-migration-for-non-small.patch BuildRequires: zlib-devel BuildRequires: glib2-devel @@ -1686,6 +1692,9 @@ cp %{SOURCE29} pc-bios %patch450 -p1 %patch451 -p1 %patch452 -p1 +%patch453 -p1 +%patch454 -p1 +%patch455 -p1 # for tscdeadline_latency.flat %ifarch x86_64 @@ -2184,6 +2193,15 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Mon Jul 02 2018 Miroslav Rezanina - ma-2.10.0-21.el7_5.3 +- kvm-scsi-disk-allow-customizing-the-SCSI-version.patch [bz#1593193] +- kvm-hw-scsi-support-SCSI-2-passthrough-without-PI.patch [bz#1593193] +- kvm-s390x-fix-storage-attributes-migration-for-non-small.patch [bz#1596553] +- Resolves: bz#1593193 + (Pegas1.1 - SCSI pass-thru of aacraid RAID1 is inaccessible (qemu-kvm-ma) [rhel-7.5.z]) +- Resolves: bz#1596553 + (RHEL-Alt-7.5 - qemu has error during migration of larger guests [rhel-7.5.z]) + * Fri Apr 13 2018 Miroslav Rezanina - ma-2.10.0-21.el7_5.2 - kvm-block-Fix-flags-in-reopen-queue.patch [bz#1557206] - kvm-iotests-Add-regression-test-for-commit-base-locking.patch [bz#1557206]