This prevents the emulated SCSI device from trying to DMA more bytes to the
initiator than are expected. Without this, the SCRIPTS code in the emulated LSI
device eventually raises a DMA interrupt for a data overrun when an INQUIRY
command whose buflen exceeds req->cmd.xfer is processed. It's the
responsibility of the client to provide a request buffer and allocation
length that are large enough for the result of the command.

I'm no expert on SCSI (or qemu), but this appears to be more correct behavior
than before, and makes my SCSI INQUIRY commands more successful.

Before patch:

# echo setverbose 2 > /proc/scsi/sym53c8xx/0
# sginfo -s -TT /dev/sda
  cdb:     12 00 00 00 24 00
  inquiry response:
     00 00 05 02 1f 00 00 12 51 45 4d 55 20 20 20 20
     51 45 4d 55 20 48 41 52 44 44 49 53 4b 20 20 20
     31 2e 30 2e
  cdb:     12 01 00 00 04 00
[  237.014083] sd 0:0:0:0: extraneous data discarded.
[  237.014437] sd 0:0:0:0: COMMAND FAILED (87 0 1).
do_scsi_io: opcode=0x12: Host_status=0x07 [DID_ERROR]
No serial number (error doing INQUIRY, supported VPDs)

After:

# echo setverbose 2 > /proc/scsi/sym53c8xx/0
# sginfo -s -TT /dev/sda
  cdb:     12 00 00 00 24 00
  inquiry response:
     00 00 05 02 1f 00 00 12 51 45 4d 55 20 20 20 20
     51 45 4d 55 20 48 41 52 44 44 49 53 4b 20 20 20
     31 2e 30 2e
  cdb:     12 01 00 00 04 00
  cdb:     12 01 80 00 04 00
  cdb:     12 01 80 00 06 00
  inquiry (evpd page (0x80) response:
    00 80 00 02 32 37
Serial Number '27'

Command line:
/usr/bin/qemu-system-x86_64 -S -M pc -enable-kvm -m 1024 -smp 
1,sockets=1,cores=1,threads=1 -nodefconfig -nodefaults -chardev 
socket,id=charmonitor,path=/var/lib/libvirt/qemu/monitor,server,nowait -mon 
chardev=charmonitor,id=monitor,mode=readline -rtc base=utc -boot d -device 
lsi,id=scsi0,bus=pci.0,addr=0x5 -drive 
file=disk.0,if=none,id=drive-scsi0-0-0,format=qcow2 -device 
scsi-disk,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0,serial=27 
-drive file=disk.2,if=none,media=cdrom,id=drive-ide0-0-0,readonly=on,format=raw 
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0  -usb -vnc 
0.0.0.0:80 -vga cirrus

Signed-off-by: Thomas Higdon <thig...@akamai.com>
---
 hw/scsi-disk.c |    3 +++
  1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5d8bf53..71fe2a3 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -477,6 +477,9 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
                  "buffer size %zd\n", page_code, req->cmd.xfer);
             return -1;
         }
+        if (buflen > req->cmd.xfer) {
+            buflen = req->cmd.xfer;
+        }
         /* done with EVPD */
         return buflen;
     }

Reply via email to