[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/3] virtio-scsi: Don't exit on bad request
From: |
Fam Zheng |
Subject: |
[Qemu-devel] [PATCH 3/3] virtio-scsi: Don't exit on bad request |
Date: |
Tue, 22 Apr 2014 16:55:17 +0800 |
Set "broken" flag on vdev if there is a bad request, and ignore all
further requests. The guest will find this device inresponsive, it's a
little better for guest because now it gets a chance to reset the
device, instead of disappearing.
Signed-off-by: Fam Zheng <address@hidden>
---
hw/scsi/virtio-scsi.c | 40 +++++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index b0d7517..a51f7f3 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -71,10 +71,12 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
virtio_notify(vdev, vq);
}
-static void virtio_scsi_bad_req(void)
+static void virtio_scsi_bad_req(VirtIOSCSIReq *req)
{
+ VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);
+
error_report("wrong size for virtio-scsi headers");
- exit(1);
+ virtio_set_broken(vdev);
}
static void qemu_sgl_init_external(VirtIOSCSIReq *req, struct iovec *sg,
@@ -271,11 +273,14 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev,
VirtQueue *vq)
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
VirtIOSCSIReq *req;
+ if (virtio_broken(vdev)) {
+ return;
+ }
while ((req = virtio_scsi_pop_req(s, vq))) {
int out_size, in_size;
if (req->elem.out_num < 1 || req->elem.in_num < 1) {
- virtio_scsi_bad_req();
- continue;
+ virtio_scsi_bad_req(req);
+ return;
}
out_size = req->elem.out_sg[0].iov_len;
@@ -283,7 +288,8 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev,
VirtQueue *vq)
if (req->req.tmf->type == VIRTIO_SCSI_T_TMF) {
if (out_size < sizeof(VirtIOSCSICtrlTMFReq) ||
in_size < sizeof(VirtIOSCSICtrlTMFResp)) {
- virtio_scsi_bad_req();
+ virtio_scsi_bad_req(req);
+ return;
}
virtio_scsi_do_tmf(s, req);
@@ -291,7 +297,8 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev,
VirtQueue *vq)
req->req.tmf->type == VIRTIO_SCSI_T_AN_SUBSCRIBE) {
if (out_size < sizeof(VirtIOSCSICtrlANReq) ||
in_size < sizeof(VirtIOSCSICtrlANResp)) {
- virtio_scsi_bad_req();
+ virtio_scsi_bad_req(req);
+ return;
}
req->resp.an->event_actual = 0;
req->resp.an->response = VIRTIO_SCSI_S_OK;
@@ -362,18 +369,23 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev,
VirtQueue *vq)
VirtIOSCSIReq *req;
int n;
+ if (virtio_broken(vdev)) {
+ return;
+ }
while ((req = virtio_scsi_pop_req(s, vq))) {
SCSIDevice *d;
int out_size, in_size;
if (req->elem.out_num < 1 || req->elem.in_num < 1) {
- virtio_scsi_bad_req();
+ virtio_scsi_bad_req(req);
+ return;
}
out_size = req->elem.out_sg[0].iov_len;
in_size = req->elem.in_sg[0].iov_len;
if (out_size < sizeof(VirtIOSCSICmdReq) + vs->cdb_size ||
in_size < sizeof(VirtIOSCSICmdResp) + vs->sense_size) {
- virtio_scsi_bad_req();
+ virtio_scsi_bad_req(req);
+ return;
}
if (req->elem.out_num > 1 && req->elem.in_num > 1) {
@@ -437,7 +449,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
if ((uint32_t) ldl_raw(&scsiconf->sense_size) >= 65536 ||
(uint32_t) ldl_raw(&scsiconf->cdb_size) >= 256) {
error_report("bad data written to virtio-scsi configuration space");
- exit(1);
+ virtio_set_broken(vdev);
+ return;
}
vs->sense_size = ldl_raw(&scsiconf->sense_size);
@@ -504,7 +517,8 @@ static void virtio_scsi_push_event(VirtIOSCSI *s,
SCSIDevice *dev,
}
if (req->elem.out_num || req->elem.in_num != 1) {
- virtio_scsi_bad_req();
+ virtio_scsi_bad_req(req);
+ return;
}
if (s->events_dropped) {
@@ -514,7 +528,8 @@ static void virtio_scsi_push_event(VirtIOSCSI *s,
SCSIDevice *dev,
in_size = req->elem.in_sg[0].iov_len;
if (in_size < sizeof(VirtIOSCSIEvent)) {
- virtio_scsi_bad_req();
+ virtio_scsi_bad_req(req);
+ return;
}
evt = req->resp.event;
@@ -540,6 +555,9 @@ static void virtio_scsi_handle_event(VirtIODevice *vdev,
VirtQueue *vq)
{
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
+ if (virtio_broken(vdev)) {
+ return;
+ }
if (s->events_dropped) {
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
}
--
1.9.2
- Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, (continued)
Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, Michael S. Tsirkin, 2014/04/27
- Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, Peter Maydell, 2014/04/27
- Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, Michael S. Tsirkin, 2014/04/27
- Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, Fam Zheng, 2014/04/27
- Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, Michael S. Tsirkin, 2014/04/27
- Re: [Qemu-devel] [PATCH 1/3] virtio: Introduce VirtIODevice.broken, Paolo Bonzini, 2014/04/29
[Qemu-devel] [PATCH 3/3] virtio-scsi: Don't exit on bad request,
Fam Zheng <=
[Qemu-devel] [PATCH 2/3] virtio-blk: Don't exit on invalid VQ data, Fam Zheng, 2014/04/22
Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Michael S. Tsirkin, 2014/04/22
- Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Fam Zheng, 2014/04/22
- Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Michael S. Tsirkin, 2014/04/23
- Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Markus Armbruster, 2014/04/24
- Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Michael S. Tsirkin, 2014/04/25
- Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Kevin Wolf, 2014/04/24
- Re: [Qemu-devel] [PATCH 0/3] virtio: Eliminate "exit(1)" upon invalid request in virtio-blk and virtio-scsi, Michael S. Tsirkin, 2014/04/24