diff mbox series

[v3,5/5] block/scsi: correctly emulate the VPD block limits page

Message ID 20201217165612.942849-6-mlevitsk@redhat.com
State New
Headers show
Series SCSI: fix transfer limits for SCSI passthrough | expand

Commit Message

Maxim Levitsky Dec. 17, 2020, 4:56 p.m. UTC
When the device doesn't support the VPD block limits page, we emulate it even
for SCSI passthrough.

As a part of the emulation we need to add it to the 'Supported VPD Pages'

The code that does this adds it to the page, but it doesn't increase the length
of the data to be copied to the guest, thus the guest never sees the VPD block
limits page as supported.

Bump the transfer size by 1 in this case.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 hw/scsi/scsi-generic.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

Comments

Max Reitz Jan. 7, 2021, 1:44 p.m. UTC | #1
On 17.12.20 17:56, Maxim Levitsky wrote:
> When the device doesn't support the VPD block limits page, we emulate it even
> for SCSI passthrough.
> 
> As a part of the emulation we need to add it to the 'Supported VPD Pages'
> 
> The code that does this adds it to the page, but it doesn't increase the length
> of the data to be copied to the guest, thus the guest never sees the VPD block
> limits page as supported.

Isn’t the problem more generally that if there is a block limits page, 
the last supported page is cut off (which perhaps more likely than not 
is the block limits page (given that it’s 0xb0, which relatively high))?

> Bump the transfer size by 1 in this case.
> 
> Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
> ---
>   hw/scsi/scsi-generic.c | 9 +++++++--
>   1 file changed, 7 insertions(+), 2 deletions(-)

Anyway, looks good to me, though I have a hard time following the code, 
which yields a rather weak:

Reviewed-by: Max Reitz <mreitz@redhat.com>
diff mbox series

Patch

diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 6df67bf889..8f43979cbc 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -134,7 +134,7 @@  static int execute_command(BlockBackend *blk,
     return 0;
 }
 
-static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
+static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
 {
     uint8_t page, page_idx;
 
@@ -200,8 +200,13 @@  static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
                 r->buf[page_idx] = 0xb0;
             }
             stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
+
+            if (len < r->buflen) {
+                len++;
+            }
         }
     }
+    return len;
 }
 
 static int scsi_generic_emulate_block_limits(SCSIGenericReq *r, SCSIDevice *s)
@@ -316,7 +321,7 @@  static void scsi_read_complete(void * opaque, int ret)
         }
     }
     if (r->req.cmd.buf[0] == INQUIRY) {
-        scsi_handle_inquiry_reply(r, s);
+        len = scsi_handle_inquiry_reply(r, s, len);
     }
 
 req_complete: