Block patches for stable-0.13
The following changes since commit 96638e706cd431528690cf611adcb04e1bc3255d:
ide: Avoid canceling IDE DMA (2010-08-03 16:39:54 +0200)
are available in the git repository at:
git://repo.or.cz/qemu/kevin.git for-stable-0.13
Andrew de Quincey (1):
posix-aio-compat: Fix async_conmtext for ioctl
Kevin Wolf (4):
virtio: Factor virtqueue_map_sg out
virtio-blk: Fix migration of queued requests
block: Fix image re-open in bdrv_commit qemu-img rebase: Open new backing file read-only
Loïc Minier (1):
vvfat: fat_chksum(): fix access above array bounds
block.c | 13 +++++++++---- block/vvfat.c | 2 +- hw/virtio-blk.c | 5 +++++ hw/virtio.c | 38 ++++++++++++++++++++++++-------------- hw/virtio.h | 3 +++ posix-aio-compat.c | 1 + qemu-img.c | 2 +- 7 files changed, 44 insertions(+), 20 deletions(-)
PATCH 1/6 virtio: Factor virtqueue_map_sg out
Separate the mapping of requests to host memory from the descriptor iteration. The next patch will make use of it in a different context.
--- hw/virtio.c | 38 ++++++++++++++++++++++++-------------- hw/virtio.h | 3 +++ 2 files changed, 27 insertions(+), 14 deletions(-)
hw/virtio.c +24 -14
@@ -360,11 +360,26 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)return 0 ; } +void virtqueue_map_sg (struct iovec *sg,target_phys_addr_t *addr, +size_t num_sg,int is_write) +{ +unsigned int i; +target_phys_addr_t len; + +for (i =0 ; i < num_sg; i++) { + len = sg[i].iov_len; + sg[i].iov_base =cpu_physical_memory_map (addr[i], &len, is_write); +if (sg[i].iov_base ==NULL || len != sg[i].iov_len) { +fprintf (stderr,"virtio: trying to map MMIO memory\n" ); +exit (1 ); + } + } +} +int virtqueue_pop (VirtQueue *vq,VirtQueueElement *elem) {unsigned int i, head, max;target_phys_addr_t desc_pa = vq->vring.desc; -target_phys_addr_t len;if (!virtqueue_num_heads (vq, vq->last_avail_idx))return 0 ;
@@ -388,28 +403,19 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) i =0 ; } +/* Collect all the descriptors */ do { struct iovec *sg; - int is_write = 0; if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) { elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i); sg = &elem->in_sg[elem->in_num++]; - is_write = 1; - } else + } else { + elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i); sg = &elem->out_sg[elem->out_num++]; + } - /* Grab the first descriptor, and check it's OK. */ sg->iov_len = vring_desc_len(desc_pa, i); - len = sg->iov_len; - - sg->iov_base = cpu_physical_memory_map(vring_desc_addr(desc_pa, i), - &len, is_write); - - if (sg->iov_base == NULL || len != sg->iov_len) { - fprintf(stderr, "virtio: trying to map MMIO memory\n"); - exit(1); - } /* If we've got too many, that implies a descriptor loop. */ if ((elem->in_num + elem->out_num) > max) {
@@ -418,6 +424,10 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) } }while ((i =virtqueue_next_desc (desc_pa, i, max)) != max); +/* Now map what we have collected */ +virtqueue_map_sg (elem->in_sg, elem->in_addr, elem->in_num,1 ); +virtqueue_map_sg (elem->out_sg, elem->out_addr, elem->out_num,0 ); + elem->index = head; vq->inuse++;
hw/virtio.h +3 -0
@@ -81,6 +81,7 @@ typedef struct VirtQueueElementunsigned int out_num;unsigned int in_num;target_phys_addr_t in_addr[VIRTQUEUE_MAX_SIZE ]; +target_phys_addr_t out_addr[VIRTQUEUE_MAX_SIZE ];struct iovec in_sg[VIRTQUEUE_MAX_SIZE ];struct iovec out_sg[VIRTQUEUE_MAX_SIZE ]; } VirtQueueElement;
@@ -142,6 +143,8 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count);void virtqueue_fill (VirtQueue *vq,const VirtQueueElement *elem,unsigned int len,unsigned int idx); +void virtqueue_map_sg (struct iovec *sg,target_phys_addr_t *addr, +size_t num_sg,int is_write);int virtqueue_pop (VirtQueue *vq,VirtQueueElement *elem);int virtqueue_avail_bytes (VirtQueue *vq,int in_bytes,int out_bytes);
Signature · 1 line
1.7.2.2
PATCH 2/6 virtio-blk: Fix migration of queued requests
In reply to Kevin Wolfin_sg[].iovec and out_sg[].ioved are pointer to (source) host memory and therefore invalid after migration. When loading the device state we must create a new mapping on the destination host.
--- hw/virtio-blk.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
hw/virtio-blk.c +5 -0
@@ -480,6 +480,11 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)qemu_get_buffer (f, (unsigned char *)&req->elem,sizeof (req->elem)); req->next = s->rq; s->rq = req; + +virtqueue_map_sg (req->elem.in_sg, req->elem.in_addr, + req->elem.in_num,1 ); +virtqueue_map_sg (req->elem.out_sg, req->elem.out_addr, + req->elem.out_num,0 ); }return 0 ;
Signature · 1 line
1.7.2.2
PATCH 3/6 block: Fix image re-open in bdrv_commit
In reply to Kevin WolfArguably we should re-open the backing file with the backing file format and not with the format of the snapshot image.
Conflicts:
block.c
--- block.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-)
block.c +9 -4
@@ -743,6 +743,7 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)int bdrv_commit (BlockDriverState *bs) {BlockDriver *drv = bs->drv; +BlockDriver *backing_drv;int64_t i, total_sectors;int n, j, ro, open_flags;int ret =0 , rw_ret =0 ;
@@ -760,7 +761,8 @@ int bdrv_commit(BlockDriverState *bs)if (bs->backing_hd->keep_read_only) {return -EACCES ; } - + + backing_drv = bs->backing_hd->drv; ro = bs->backing_hd->read_only;strncpy (filename, bs->backing_hd->filename,sizeof (filename)); open_flags = bs->backing_hd->open_flags;
@@ -770,12 +772,14 @@ int bdrv_commit(BlockDriverState *bs)bdrv_delete (bs->backing_hd); bs->backing_hd =NULL ; bs_rw =bdrv_new ("" ); - rw_ret =bdrv_open (bs_rw, filename, open_flags |BDRV_O_RDWR , drv); + rw_ret =bdrv_open (bs_rw, filename, open_flags |BDRV_O_RDWR , + backing_drv);if (rw_ret <0 ) {bdrv_delete (bs_rw);/* try to re-open read-only */ bs_ro =bdrv_new ("" ); - ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR , drv); + ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR , + backing_drv);if (ret <0 ) {bdrv_delete (bs_ro);/* drive not functional anymore */
@@ -827,7 +831,8 @@ ro_cleanup:bdrv_delete (bs->backing_hd); bs->backing_hd =NULL ; bs_ro =bdrv_new ("" ); - ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR , drv); + ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR , + backing_drv);if (ret <0 ) {bdrv_delete (bs_ro);/* drive not functional anymore */
Signature · 1 line
1.7.2.2
PATCH 4/6 qemu-img rebase: Open new backing file read-only
In reply to Kevin WolfWe never write to a backing file, so opening rw is useless. It just means that you can't rebase on top of a file for which you don't have write permissions.
--- qemu-img.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
qemu-img.c +1 -1
@@ -1286,7 +1286,7 @@ static int img_rebase(int argc, char **argv) } bs_new_backing =bdrv_new ("new_backing" ); - ret =bdrv_open (bs_new_backing, out_baseimg,BDRV_O_FLAGS |BDRV_O_RDWR , + ret =bdrv_open (bs_new_backing, out_baseimg,BDRV_O_FLAGS , new_backing_drv);if (ret) {error ("Could not open new backing file '%s'" , out_baseimg);
Signature · 1 line
1.7.2.2
PATCH 5/6 vvfat: fat_chksum(): fix access above array bounds
In reply to Kevin WolfFrom: Loïc Minier <[email protected]>
--- block/vvfat.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
block/vvfat.c +1 -1
@@ -512,7 +512,7 @@ static inline uint8_t fat_chksum(const direntry_t* entry)for (i=0 ;i<11 ;i++) {unsigned char c; - c = (i <=8 ) ? entry->name[i] : entry->extension[i-8 ]; + c = (i <8 ) ? entry->name[i] : entry->extension[i-8 ]; chksum=(((chksum&0xfe )>>1 )|((chksum&0x01 )?0x80 :0 )) + c; }
Signature · 1 line
1.7.2.2
PATCH 6/6 posix-aio-compat: Fix async_conmtext for ioctl
In reply to Kevin WolfFrom: Andrew de Quincey <[email protected]>
Set the async_context_id field when queuing an async ioctl call
--- posix-aio-compat.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
posix-aio-compat.c +1 -0
@@ -599,6 +599,7 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd, acb->aio_type =QEMU_AIO_IOCTL ; acb->aio_fildes = fd; acb->ev_signo =SIGUSR2 ; + acb->async_context_id =get_async_context_id (); acb->aio_offset =0 ; acb->aio_ioctl_buf = buf; acb->aio_ioctl_cmd = req;
Signature · 1 line
1.7.2.2