]> Git Repo - qemu.git/blob - hw/virtio-blk.c
Merge branch 'pci' into for_anthony
[qemu.git] / hw / virtio-blk.c
1 /*
2  * Virtio Block Device
3  *
4  * Copyright IBM, Corp. 2007
5  *
6  * Authors:
7  *  Anthony Liguori   <[email protected]>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  *
12  */
13
14 #include <qemu-common.h>
15 #include "qemu-error.h"
16 #include "trace.h"
17 #include "blockdev.h"
18 #include "virtio-blk.h"
19 #ifdef __linux__
20 # include <scsi/sg.h>
21 #endif
22
23 typedef struct VirtIOBlock
24 {
25     VirtIODevice vdev;
26     BlockDriverState *bs;
27     VirtQueue *vq;
28     void *rq;
29     QEMUBH *bh;
30     BlockConf *conf;
31     unsigned short sector_mask;
32     char sn[BLOCK_SERIAL_STRLEN];
33     DeviceState *qdev;
34 } VirtIOBlock;
35
36 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
37 {
38     return (VirtIOBlock *)vdev;
39 }
40
41 typedef struct VirtIOBlockReq
42 {
43     VirtIOBlock *dev;
44     VirtQueueElement elem;
45     struct virtio_blk_inhdr *in;
46     struct virtio_blk_outhdr *out;
47     struct virtio_scsi_inhdr *scsi;
48     QEMUIOVector qiov;
49     struct VirtIOBlockReq *next;
50 } VirtIOBlockReq;
51
52 static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
53 {
54     VirtIOBlock *s = req->dev;
55
56     trace_virtio_blk_req_complete(req, status);
57
58     req->in->status = status;
59     virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
60     virtio_notify(&s->vdev, s->vq);
61
62     qemu_free(req);
63 }
64
65 static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
66     int is_read)
67 {
68     BlockErrorAction action = bdrv_get_on_error(req->dev->bs, is_read);
69     VirtIOBlock *s = req->dev;
70
71     if (action == BLOCK_ERR_IGNORE) {
72         bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
73         return 0;
74     }
75
76     if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
77             || action == BLOCK_ERR_STOP_ANY) {
78         req->next = s->rq;
79         s->rq = req;
80         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
81         vm_stop(0);
82     } else {
83         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
84         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
85     }
86
87     return 1;
88 }
89
90 static void virtio_blk_rw_complete(void *opaque, int ret)
91 {
92     VirtIOBlockReq *req = opaque;
93
94     trace_virtio_blk_rw_complete(req, ret);
95
96     if (ret) {
97         int is_read = !(req->out->type & VIRTIO_BLK_T_OUT);
98         if (virtio_blk_handle_rw_error(req, -ret, is_read))
99             return;
100     }
101
102     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
103 }
104
105 static void virtio_blk_flush_complete(void *opaque, int ret)
106 {
107     VirtIOBlockReq *req = opaque;
108
109     virtio_blk_req_complete(req, ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK);
110 }
111
112 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
113 {
114     VirtIOBlockReq *req = qemu_malloc(sizeof(*req));
115     req->dev = s;
116     req->qiov.size = 0;
117     req->next = NULL;
118     return req;
119 }
120
121 static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
122 {
123     VirtIOBlockReq *req = virtio_blk_alloc_request(s);
124
125     if (req != NULL) {
126         if (!virtqueue_pop(s->vq, &req->elem)) {
127             qemu_free(req);
128             return NULL;
129         }
130     }
131
132     return req;
133 }
134
135 #ifdef __linux__
136 static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
137 {
138     struct sg_io_hdr hdr;
139     int ret;
140     int status;
141     int i;
142
143     /*
144      * We require at least one output segment each for the virtio_blk_outhdr
145      * and the SCSI command block.
146      *
147      * We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr
148      * and the sense buffer pointer in the input segments.
149      */
150     if (req->elem.out_num < 2 || req->elem.in_num < 3) {
151         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
152         return;
153     }
154
155     /*
156      * No support for bidirection commands yet.
157      */
158     if (req->elem.out_num > 2 && req->elem.in_num > 3) {
159         virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
160         return;
161     }
162
163     /*
164      * The scsi inhdr is placed in the second-to-last input segment, just
165      * before the regular inhdr.
166      */
167     req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base;
168
169     memset(&hdr, 0, sizeof(struct sg_io_hdr));
170     hdr.interface_id = 'S';
171     hdr.cmd_len = req->elem.out_sg[1].iov_len;
172     hdr.cmdp = req->elem.out_sg[1].iov_base;
173     hdr.dxfer_len = 0;
174
175     if (req->elem.out_num > 2) {
176         /*
177          * If there are more than the minimally required 2 output segments
178          * there is write payload starting from the third iovec.
179          */
180         hdr.dxfer_direction = SG_DXFER_TO_DEV;
181         hdr.iovec_count = req->elem.out_num - 2;
182
183         for (i = 0; i < hdr.iovec_count; i++)
184             hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len;
185
186         hdr.dxferp = req->elem.out_sg + 2;
187
188     } else if (req->elem.in_num > 3) {
189         /*
190          * If we have more than 3 input segments the guest wants to actually
191          * read data.
192          */
193         hdr.dxfer_direction = SG_DXFER_FROM_DEV;
194         hdr.iovec_count = req->elem.in_num - 3;
195         for (i = 0; i < hdr.iovec_count; i++)
196             hdr.dxfer_len += req->elem.in_sg[i].iov_len;
197
198         hdr.dxferp = req->elem.in_sg;
199     } else {
200         /*
201          * Some SCSI commands don't actually transfer any data.
202          */
203         hdr.dxfer_direction = SG_DXFER_NONE;
204     }
205
206     hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base;
207     hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len;
208
209     ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr);
210     if (ret) {
211         status = VIRTIO_BLK_S_UNSUPP;
212         hdr.status = ret;
213         hdr.resid = hdr.dxfer_len;
214     } else if (hdr.status) {
215         status = VIRTIO_BLK_S_IOERR;
216     } else {
217         status = VIRTIO_BLK_S_OK;
218     }
219
220     req->scsi->errors = hdr.status;
221     req->scsi->residual = hdr.resid;
222     req->scsi->sense_len = hdr.sb_len_wr;
223     req->scsi->data_len = hdr.dxfer_len;
224
225     virtio_blk_req_complete(req, status);
226 }
227 #else
228 static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
229 {
230     virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
231 }
232 #endif /* __linux__ */
233
234 typedef struct MultiReqBuffer {
235     BlockRequest        blkreq[32];
236     unsigned int        num_writes;
237 } MultiReqBuffer;
238
239 static void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb)
240 {
241     int i, ret;
242
243     if (!mrb->num_writes) {
244         return;
245     }
246
247     ret = bdrv_aio_multiwrite(bs, mrb->blkreq, mrb->num_writes);
248     if (ret != 0) {
249         for (i = 0; i < mrb->num_writes; i++) {
250             if (mrb->blkreq[i].error) {
251                 virtio_blk_rw_complete(mrb->blkreq[i].opaque, -EIO);
252             }
253         }
254     }
255
256     mrb->num_writes = 0;
257 }
258
259 static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
260 {
261     BlockDriverAIOCB *acb;
262
263     /*
264      * Make sure all outstanding writes are posted to the backing device.
265      */
266     virtio_submit_multiwrite(req->dev->bs, mrb);
267
268     acb = bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
269     if (!acb) {
270         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
271     }
272 }
273
274 static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
275 {
276     BlockRequest *blkreq;
277
278     trace_virtio_blk_handle_write(req, req->out->sector, req->qiov.size / 512);
279
280     if (req->out->sector & req->dev->sector_mask) {
281         virtio_blk_rw_complete(req, -EIO);
282         return;
283     }
284
285     if (mrb->num_writes == 32) {
286         virtio_submit_multiwrite(req->dev->bs, mrb);
287     }
288
289     blkreq = &mrb->blkreq[mrb->num_writes];
290     blkreq->sector = req->out->sector;
291     blkreq->nb_sectors = req->qiov.size / BDRV_SECTOR_SIZE;
292     blkreq->qiov = &req->qiov;
293     blkreq->cb = virtio_blk_rw_complete;
294     blkreq->opaque = req;
295     blkreq->error = 0;
296
297     mrb->num_writes++;
298 }
299
300 static void virtio_blk_handle_read(VirtIOBlockReq *req)
301 {
302     BlockDriverAIOCB *acb;
303
304     if (req->out->sector & req->dev->sector_mask) {
305         virtio_blk_rw_complete(req, -EIO);
306         return;
307     }
308
309     acb = bdrv_aio_readv(req->dev->bs, req->out->sector, &req->qiov,
310                          req->qiov.size / BDRV_SECTOR_SIZE,
311                          virtio_blk_rw_complete, req);
312     if (!acb) {
313         virtio_blk_rw_complete(req, -EIO);
314     }
315 }
316
317 static void virtio_blk_handle_request(VirtIOBlockReq *req,
318     MultiReqBuffer *mrb)
319 {
320     if (req->elem.out_num < 1 || req->elem.in_num < 1) {
321         fprintf(stderr, "virtio-blk missing headers\n");
322         exit(1);
323     }
324
325     if (req->elem.out_sg[0].iov_len < sizeof(*req->out) ||
326         req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) {
327         fprintf(stderr, "virtio-blk header not in correct element\n");
328         exit(1);
329     }
330
331     req->out = (void *)req->elem.out_sg[0].iov_base;
332     req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
333
334     if (req->out->type & VIRTIO_BLK_T_FLUSH) {
335         virtio_blk_handle_flush(req, mrb);
336     } else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
337         virtio_blk_handle_scsi(req);
338     } else if (req->out->type & VIRTIO_BLK_T_GET_ID) {
339         VirtIOBlock *s = req->dev;
340
341         memcpy(req->elem.in_sg[0].iov_base, s->sn,
342                MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn)));
343         virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
344     } else if (req->out->type & VIRTIO_BLK_T_OUT) {
345         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
346                                  req->elem.out_num - 1);
347         virtio_blk_handle_write(req, mrb);
348     } else {
349         qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
350                                  req->elem.in_num - 1);
351         virtio_blk_handle_read(req);
352     }
353 }
354
355 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
356 {
357     VirtIOBlock *s = to_virtio_blk(vdev);
358     VirtIOBlockReq *req;
359     MultiReqBuffer mrb = {
360         .num_writes = 0,
361     };
362
363     while ((req = virtio_blk_get_request(s))) {
364         virtio_blk_handle_request(req, &mrb);
365     }
366
367     virtio_submit_multiwrite(s->bs, &mrb);
368
369     /*
370      * FIXME: Want to check for completions before returning to guest mode,
371      * so cached reads and writes are reported as quickly as possible. But
372      * that should be done in the generic block layer.
373      */
374 }
375
376 static void virtio_blk_dma_restart_bh(void *opaque)
377 {
378     VirtIOBlock *s = opaque;
379     VirtIOBlockReq *req = s->rq;
380     MultiReqBuffer mrb = {
381         .num_writes = 0,
382     };
383
384     qemu_bh_delete(s->bh);
385     s->bh = NULL;
386
387     s->rq = NULL;
388
389     while (req) {
390         virtio_blk_handle_request(req, &mrb);
391         req = req->next;
392     }
393
394     virtio_submit_multiwrite(s->bs, &mrb);
395 }
396
397 static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason)
398 {
399     VirtIOBlock *s = opaque;
400
401     if (!running)
402         return;
403
404     if (!s->bh) {
405         s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s);
406         qemu_bh_schedule(s->bh);
407     }
408 }
409
410 static void virtio_blk_reset(VirtIODevice *vdev)
411 {
412     /*
413      * This should cancel pending requests, but can't do nicely until there
414      * are per-device request lists.
415      */
416     qemu_aio_flush();
417 }
418
419 /* coalesce internal state, copy to pci i/o region 0
420  */
421 static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
422 {
423     VirtIOBlock *s = to_virtio_blk(vdev);
424     struct virtio_blk_config blkcfg;
425     uint64_t capacity;
426     int cylinders, heads, secs;
427
428     bdrv_get_geometry(s->bs, &capacity);
429     bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
430     memset(&blkcfg, 0, sizeof(blkcfg));
431     stq_raw(&blkcfg.capacity, capacity);
432     stl_raw(&blkcfg.seg_max, 128 - 2);
433     stw_raw(&blkcfg.cylinders, cylinders);
434     blkcfg.heads = heads;
435     blkcfg.sectors = secs & ~s->sector_mask;
436     blkcfg.blk_size = s->conf->logical_block_size;
437     blkcfg.size_max = 0;
438     blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
439     blkcfg.alignment_offset = 0;
440     blkcfg.min_io_size = s->conf->min_io_size / blkcfg.blk_size;
441     blkcfg.opt_io_size = s->conf->opt_io_size / blkcfg.blk_size;
442     memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
443 }
444
445 static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
446 {
447     VirtIOBlock *s = to_virtio_blk(vdev);
448
449     features |= (1 << VIRTIO_BLK_F_SEG_MAX);
450     features |= (1 << VIRTIO_BLK_F_GEOMETRY);
451     features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
452     features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
453
454     if (bdrv_enable_write_cache(s->bs))
455         features |= (1 << VIRTIO_BLK_F_WCACHE);
456     
457     if (bdrv_is_read_only(s->bs))
458         features |= 1 << VIRTIO_BLK_F_RO;
459
460     return features;
461 }
462
463 static void virtio_blk_save(QEMUFile *f, void *opaque)
464 {
465     VirtIOBlock *s = opaque;
466     VirtIOBlockReq *req = s->rq;
467
468     virtio_save(&s->vdev, f);
469     
470     while (req) {
471         qemu_put_sbyte(f, 1);
472         qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
473         req = req->next;
474     }
475     qemu_put_sbyte(f, 0);
476 }
477
478 static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
479 {
480     VirtIOBlock *s = opaque;
481
482     if (version_id != 2)
483         return -EINVAL;
484
485     virtio_load(&s->vdev, f);
486     while (qemu_get_sbyte(f)) {
487         VirtIOBlockReq *req = virtio_blk_alloc_request(s);
488         qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
489         req->next = s->rq;
490         s->rq = req;
491
492         virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
493             req->elem.in_num, 1);
494         virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
495             req->elem.out_num, 0);
496     }
497
498     return 0;
499 }
500
501 VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
502 {
503     VirtIOBlock *s;
504     int cylinders, heads, secs;
505     static int virtio_blk_id;
506     DriveInfo *dinfo;
507
508     if (!conf->bs) {
509         error_report("virtio-blk-pci: drive property not set");
510         return NULL;
511     }
512     if (!bdrv_is_inserted(conf->bs)) {
513         error_report("Device needs media, but drive is empty");
514         return NULL;
515     }
516
517     s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
518                                           sizeof(struct virtio_blk_config),
519                                           sizeof(VirtIOBlock));
520
521     s->vdev.get_config = virtio_blk_update_config;
522     s->vdev.get_features = virtio_blk_get_features;
523     s->vdev.reset = virtio_blk_reset;
524     s->bs = conf->bs;
525     s->conf = conf;
526     s->rq = NULL;
527     s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
528     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
529
530     /* NB: per existing s/n string convention the string is terminated
531      * by '\0' only when less than sizeof (s->sn)
532      */
533     dinfo = drive_get_by_blockdev(s->bs);
534     strncpy(s->sn, dinfo->serial, sizeof (s->sn));
535
536     s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
537
538     qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
539     s->qdev = dev;
540     register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
541                     virtio_blk_save, virtio_blk_load, s);
542     bdrv_set_removable(s->bs, 0);
543     s->bs->buffer_alignment = conf->logical_block_size;
544
545     return &s->vdev;
546 }
547
548 void virtio_blk_exit(VirtIODevice *vdev)
549 {
550     VirtIOBlock *s = to_virtio_blk(vdev);
551     unregister_savevm(s->qdev, "virtio-blk", s);
552 }
This page took 0.058026 seconds and 4 git commands to generate.