Blame SOURCES/kvm-scsi-generic-keep-VPD-page-list-sorted.patch

7711c0
From 4967a91c66070002024af212794ddff2acaa0ad1 Mon Sep 17 00:00:00 2001
7711c0
From: Paolo Bonzini <pbonzini@redhat.com>
7711c0
Date: Wed, 7 Nov 2018 18:00:04 +0100
7711c0
Subject: [PATCH 30/34] scsi-generic: keep VPD page list sorted
7711c0
MIME-Version: 1.0
7711c0
Content-Type: text/plain; charset=UTF-8
7711c0
Content-Transfer-Encoding: 8bit
7711c0
7711c0
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
7711c0
Message-id: <20181107180007.22954-7-pbonzini@redhat.com>
7711c0
Patchwork-id: 82944
7711c0
O-Subject: [RHEL7.6.z qemu-kvm-rhev PATCH 6/9] scsi-generic: keep VPD page list sorted
7711c0
Bugzilla: 1566195
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7711c0
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7711c0
7711c0
Block limits emulation is just placing 0xb0 as the final byte of the
7711c0
VPD pages list.  However, VPD page numbers must be sorted, so change
7711c0
that to an in-place insert.  Since I couldn't find any disk that triggered
7711c0
the loop more than once, this was tested by adding manually 0xb1
7711c0
at the end of the list and checking that 0xb0 was added before.
7711c0
7711c0
Reported-by: Max Reitz <mreitz@redhat.com>
7711c0
Reviewed-by: Max Reitz <mreitz@redhat.com>
7711c0
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7711c0
(cherry picked from commit 6c219fc8a112fc69b29f59ea2c7865717ff6e3e0)
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 hw/scsi/scsi-generic.c | 19 +++++++++++++++----
7711c0
 1 file changed, 15 insertions(+), 4 deletions(-)
7711c0
7711c0
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
7711c0
index 4266003..98c6a34 100644
7711c0
--- a/hw/scsi/scsi-generic.c
7711c0
+++ b/hw/scsi/scsi-generic.c
7711c0
@@ -145,7 +145,7 @@ static int execute_command(BlockBackend *blk,
7711c0
 
7711c0
 static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
7711c0
 {
7711c0
-    uint8_t page, page_len;
7711c0
+    uint8_t page, page_idx;
7711c0
 
7711c0
     /*
7711c0
      *  EVPD set to zero returns the standard INQUIRY data.
7711c0
@@ -191,10 +191,21 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
7711c0
              *
7711c0
              * This way, the guest kernel will be aware of the support
7711c0
              * and will use it to proper setup the SCSI device.
7711c0
+             *
7711c0
+             * VPD page numbers must be sorted, so insert 0xb0 at the
7711c0
+             * right place with an in-place insert.  After the initialization
7711c0
+             * part of the for loop is executed, the device response is
7711c0
+             * at r[0] to r[page_idx - 1].
7711c0
              */
7711c0
-            page_len = r->buf[3];
7711c0
-            r->buf[page_len + 4] = 0xb0;
7711c0
-            r->buf[3] = ++page_len;
7711c0
+            for (page_idx = lduw_be_p(r->buf + 2) + 4;
7711c0
+                 page_idx > 4 && r->buf[page_idx - 1] >= 0xb0;
7711c0
+                 page_idx--) {
7711c0
+                if (page_idx < r->buflen) {
7711c0
+                    r->buf[page_idx] = r->buf[page_idx - 1];
7711c0
+                }
7711c0
+            }
7711c0
+            r->buf[page_idx] = 0xb0;
7711c0
+            stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
7711c0
         }
7711c0
     }
7711c0
 }
7711c0
-- 
7711c0
1.8.3.1
7711c0