diff mbox

SCSI-GENERIC: Specify the xfer direction for UNMAP/WRITESAME16/ATAPASSTHROUGH command

Message ID 1335620976-29951-2-git-send-email-ronniesahlberg@gmail.com
State New
Headers show

Commit Message

ronnie sahlberg April 28, 2012, 1:49 p.m. UTC
scsi_cmd_xfer_mode() is used to specify the xfer direction for SCSI commands that come in from the guest.
If the direction is set incorrectly this will eventually cause QEMU to kernel-panic the guest.

Add UNMAP/WRITESAME16/ATAPASSTHROUGH as commands that send data to the device.

Without this change, recent kernels will send both UNMAP as well as ATAPASSTHROUGH commands to any /dev/sg* device, which due to the incorrect xfer direction very quickly causes the guest kernel to crash.

Example causing a crash without the patch applied:

./x86_64-softmmu/qemu-system-x86_64 -m 1024 -enable-kvm -cdrom linuxmint-12-gnome-dvd-64bit.iso -drive file=/dev/sg4,if=scsi,bus=0,unit=6

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
---
 hw/scsi-bus.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

Comments

Paolo Bonzini April 28, 2012, 2:29 p.m. UTC | #1
Il 28/04/2012 15:49, Ronnie Sahlberg ha scritto:
> scsi_cmd_xfer_mode() is used to specify the xfer direction for SCSI commands that come in from the guest.
> If the direction is set incorrectly this will eventually cause QEMU to kernel-panic the guest.
> 
> Add UNMAP/WRITESAME16/ATAPASSTHROUGH as commands that send data to the device.
> 
> Without this change, recent kernels will send both UNMAP as well as ATAPASSTHROUGH commands to any /dev/sg* device, which due to the incorrect xfer direction very quickly causes the guest kernel to crash.
> 
> Example causing a crash without the patch applied:
> 
> ./x86_64-softmmu/qemu-system-x86_64 -m 1024 -enable-kvm -cdrom linuxmint-12-gnome-dvd-64bit.iso -drive file=/dev/sg4,if=scsi,bus=0,unit=6
> 
> Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
> ---
>  hw/scsi-bus.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
> index dbdb99c..bca2be8 100644
> --- a/hw/scsi-bus.c
> +++ b/hw/scsi-bus.c
> @@ -920,6 +920,8 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
>      case UPDATE_BLOCK:
>      case WRITE_LONG_10:
>      case WRITE_SAME_10:
> +    case WRITE_SAME_16:
> +    case UNMAP:
>      case SEARCH_HIGH_12:
>      case SEARCH_EQUAL_12:
>      case SEARCH_LOW_12:
> @@ -929,6 +931,7 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
>      case SEND_DVD_STRUCTURE:
>      case PERSISTENT_RESERVE_OUT:
>      case MAINTENANCE_OUT:
> +    case ATA_PASSTHROUGH:
>          cmd->mode = SCSI_XFER_TO_DEV;
>          break;
>      default:

Applied to scsi-next, thanks!

Paolo
diff mbox

Patch

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index dbdb99c..bca2be8 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -920,6 +920,8 @@  static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case UPDATE_BLOCK:
     case WRITE_LONG_10:
     case WRITE_SAME_10:
+    case WRITE_SAME_16:
+    case UNMAP:
     case SEARCH_HIGH_12:
     case SEARCH_EQUAL_12:
     case SEARCH_LOW_12:
@@ -929,6 +931,7 @@  static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case SEND_DVD_STRUCTURE:
     case PERSISTENT_RESERVE_OUT:
     case MAINTENANCE_OUT:
+    case ATA_PASSTHROUGH:
         cmd->mode = SCSI_XFER_TO_DEV;
         break;
     default: