26ba25
From 3fcc45e3b9a204454910832f2c9a7fcfc28a0d07 Mon Sep 17 00:00:00 2001
26ba25
From: Paolo Bonzini <pbonzini@redhat.com>
26ba25
Date: Thu, 20 Dec 2018 12:31:00 +0000
26ba25
Subject: [PATCH 5/8] scsi-generic: keep VPD page list sorted
26ba25
26ba25
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
26ba25
Message-id: <20181220123103.29579-6-pbonzini@redhat.com>
26ba25
Patchwork-id: 83714
26ba25
O-Subject: [PATCH 5/8] scsi-generic: keep VPD page list sorted
26ba25
Bugzilla: 1639957
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
26ba25
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
26ba25
26ba25
Block limits emulation is just placing 0xb0 as the final byte of the
26ba25
VPD pages list.  However, VPD page numbers must be sorted, so change
26ba25
that to an in-place insert.  Since I couldn't find any disk that triggered
26ba25
the loop more than once, this was tested by adding manually 0xb1
26ba25
at the end of the list and checking that 0xb0 was added before.
26ba25
26ba25
Reported-by: Max Reitz <mreitz@redhat.com>
26ba25
Reviewed-by: Max Reitz <mreitz@redhat.com>
26ba25
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26ba25
(cherry picked from commit 6c219fc8a112fc69b29f59ea2c7865717ff6e3e0)
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 hw/scsi/scsi-generic.c | 19 +++++++++++++++----
26ba25
 1 file changed, 15 insertions(+), 4 deletions(-)
26ba25
26ba25
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
26ba25
index 4266003..98c6a34 100644
26ba25
--- a/hw/scsi/scsi-generic.c
26ba25
+++ b/hw/scsi/scsi-generic.c
26ba25
@@ -145,7 +145,7 @@ static int execute_command(BlockBackend *blk,
26ba25
 
26ba25
 static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
26ba25
 {
26ba25
-    uint8_t page, page_len;
26ba25
+    uint8_t page, page_idx;
26ba25
 
26ba25
     /*
26ba25
      *  EVPD set to zero returns the standard INQUIRY data.
26ba25
@@ -191,10 +191,21 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
26ba25
              *
26ba25
              * This way, the guest kernel will be aware of the support
26ba25
              * and will use it to proper setup the SCSI device.
26ba25
+             *
26ba25
+             * VPD page numbers must be sorted, so insert 0xb0 at the
26ba25
+             * right place with an in-place insert.  After the initialization
26ba25
+             * part of the for loop is executed, the device response is
26ba25
+             * at r[0] to r[page_idx - 1].
26ba25
              */
26ba25
-            page_len = r->buf[3];
26ba25
-            r->buf[page_len + 4] = 0xb0;
26ba25
-            r->buf[3] = ++page_len;
26ba25
+            for (page_idx = lduw_be_p(r->buf + 2) + 4;
26ba25
+                 page_idx > 4 && r->buf[page_idx - 1] >= 0xb0;
26ba25
+                 page_idx--) {
26ba25
+                if (page_idx < r->buflen) {
26ba25
+                    r->buf[page_idx] = r->buf[page_idx - 1];
26ba25
+                }
26ba25
+            }
26ba25
+            r->buf[page_idx] = 0xb0;
26ba25
+            stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
26ba25
         }
26ba25
     }
26ba25
 }
26ba25
-- 
26ba25
1.8.3.1
26ba25