diff options
author | 2011-05-11 09:29:46 -0400 | |
---|---|---|
committer | 2011-05-11 09:29:46 -0400 | |
commit | d32e8d0b8d9e0ef7cf7ab2e74548982972789dfc (patch) | |
tree | 78e2227555623d6f3121232925b8a78ef36d962c | |
parent | qemu-kvm: Don't break device assignment INTx (diff) | |
parent | Version 0.14.1 (diff) | |
download | qemu-kvm-d32e8d0b8d9e0ef7cf7ab2e74548982972789dfc.tar.gz qemu-kvm-d32e8d0b8d9e0ef7cf7ab2e74548982972789dfc.tar.bz2 qemu-kvm-d32e8d0b8d9e0ef7cf7ab2e74548982972789dfc.zip |
Merge commit 'v0.14.1' into stable-0.14qemu-kvm-0.14.1
* commit 'v0.14.1':
Version 0.14.1
virtio-blk: fail unaligned requests
qed: Fix consistency check on 32-bit hosts
exit if -drive specified is invalid instead of ignoring the "wrong" -drive
vhost: fix dirty page handling
Do not delete BlockDriverState when deleting the drive
vnc: tight: Fix crash after 2GB of output
lan9118: Ignore write to MAC_VLAN1 register
Don't allow multiwrites against a block device without underlying medium
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | block.c | 22 | ||||
-rw-r--r-- | block.h | 1 | ||||
-rw-r--r-- | block/qed-check.c | 4 | ||||
-rw-r--r-- | block/qed.h | 2 | ||||
-rw-r--r-- | blockdev.c | 25 | ||||
-rw-r--r-- | hw/lan9118.c | 6 | ||||
-rw-r--r-- | hw/vhost.c | 4 | ||||
-rw-r--r-- | hw/virtio-blk.c | 8 | ||||
-rw-r--r-- | ui/vnc-enc-tight.c | 5 | ||||
-rw-r--r-- | ui/vnc-enc-zlib.c | 4 | ||||
-rw-r--r-- | vl.c | 4 |
12 files changed, 57 insertions, 30 deletions
@@ -1 +1 @@ -0.14.0 +0.14.1 @@ -697,14 +697,22 @@ void bdrv_close_all(void) } } +/* make a BlockDriverState anonymous by removing from bdrv_state list. + Also, NULL terminate the device_name to prevent double remove */ +void bdrv_make_anon(BlockDriverState *bs) +{ + if (bs->device_name[0] != '\0') { + QTAILQ_REMOVE(&bdrv_states, bs, list); + } + bs->device_name[0] = '\0'; +} + void bdrv_delete(BlockDriverState *bs) { assert(!bs->peer); /* remove from list, if necessary */ - if (bs->device_name[0] != '\0') { - QTAILQ_REMOVE(&bdrv_states, bs, list); - } + bdrv_make_anon(bs); bdrv_close(bs); if (bs->file != NULL) { @@ -2295,6 +2303,14 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) MultiwriteCB *mcb; int i; + /* don't submit writes if we don't have a medium */ + if (bs->drv == NULL) { + for (i = 0; i < num_reqs; i++) { + reqs[i].error = -ENOMEDIUM; + } + return -1; + } + if (num_reqs == 0) { return 0; } @@ -66,6 +66,7 @@ int bdrv_create(BlockDriver *drv, const char* filename, QEMUOptionParameter *options); int bdrv_create_file(const char* filename, QEMUOptionParameter *options); BlockDriverState *bdrv_new(const char *device_name); +void bdrv_make_anon(BlockDriverState *bs); void bdrv_delete(BlockDriverState *bs); int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags); int bdrv_open(BlockDriverState *bs, const char *filename, int flags, diff --git a/block/qed-check.c b/block/qed-check.c index 4600932bf..474c847d1 100644 --- a/block/qed-check.c +++ b/block/qed-check.c @@ -18,7 +18,7 @@ typedef struct { BdrvCheckResult *result; bool fix; /* whether to fix invalid offsets */ - size_t nclusters; + uint64_t nclusters; uint32_t *used_clusters; /* referenced cluster bitmap */ QEDRequest request; @@ -176,7 +176,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table) static void qed_check_for_leaks(QEDCheck *check) { BDRVQEDState *s = check->s; - size_t i; + uint64_t i; for (i = s->header.header_size; i < check->nclusters; i++) { if (!qed_test_bit(check->used_clusters, i)) { diff --git a/block/qed.h b/block/qed.h index 2925e37b1..9f72ad549 100644 --- a/block/qed.h +++ b/block/qed.h @@ -251,7 +251,7 @@ static inline uint64_t qed_offset_into_cluster(BDRVQEDState *s, uint64_t offset) return offset & (s->header.cluster_size - 1); } -static inline unsigned int qed_bytes_to_clusters(BDRVQEDState *s, size_t bytes) +static inline uint64_t qed_bytes_to_clusters(BDRVQEDState *s, uint64_t bytes) { return qed_start_of_cluster(s, bytes + (s->header.cluster_size - 1)) / (s->header.cluster_size - 1); diff --git a/blockdev.c b/blockdev.c index 335a77bab..5a97c09b8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -739,8 +739,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *id = qdict_get_str(qdict, "id"); BlockDriverState *bs; - BlockDriverState **ptr; - Property *prop; bs = bdrv_find(id); if (!bs) { @@ -757,24 +755,17 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) bdrv_flush(bs); bdrv_close(bs); - /* clean up guest state from pointing to host resource by - * finding and removing DeviceState "drive" property */ + /* if we have a device associated with this BlockDriverState (bs->peer) + * then we need to make the drive anonymous until the device + * can be removed. If this is a drive with no device backing + * then we can just get rid of the block driver state right here. + */ if (bs->peer) { - for (prop = bs->peer->info->props; prop && prop->name; prop++) { - if (prop->info->type == PROP_TYPE_DRIVE) { - ptr = qdev_get_prop_ptr(bs->peer, prop); - if (*ptr == bs) { - bdrv_detach(bs, bs->peer); - *ptr = NULL; - break; - } - } - } + bdrv_make_anon(bs); + } else { + drive_uninit(drive_get_by_blockdev(bs)); } - /* clean up host side */ - drive_uninit(drive_get_by_blockdev(bs)); - return 0; } diff --git a/hw/lan9118.c b/hw/lan9118.c index 9cc7952b2..4ce9eb369 100644 --- a/hw/lan9118.c +++ b/hw/lan9118.c @@ -785,6 +785,12 @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val) case MAC_FLOW: s->mac_flow = val & 0xffff0000; break; + case MAC_VLAN1: + /* Writing to this register changes a condition for + * FrameTooLong bit in rx_status. Since we do not set + * FrameTooLong anyway, just ignore write to this. + */ + break; default: hw_error("lan9118: Unimplemented MAC register write: %d = 0x%x\n", s->mac_cmd & 0xf, val); diff --git a/hw/vhost.c b/hw/vhost.c index 38cc3b365..6c194f0f8 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -47,8 +47,10 @@ static void vhost_dev_sync_region(struct vhost_dev *dev, log = __sync_fetch_and_and(from, 0); while ((bit = sizeof(log) > sizeof(int) ? ffsll(log) : ffs(log))) { + ram_addr_t ram_addr; bit -= 1; - cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE); + ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE); + cpu_physical_memory_set_dirty(ram_addr); log &= ~(0x1ull << bit); } addr += VHOST_LOG_CHUNK; diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index ffac5a4d8..114c63888 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -290,6 +290,10 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) virtio_blk_rw_complete(req, -EIO); return; } + if (req->qiov.size % req->dev->conf->logical_block_size) { + virtio_blk_rw_complete(req, -EIO); + return; + } if (mrb->num_writes == 32) { virtio_submit_multiwrite(req->dev->bs, mrb); @@ -317,6 +321,10 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req) virtio_blk_rw_complete(req, -EIO); return; } + if (req->qiov.size % req->dev->conf->logical_block_size) { + virtio_blk_rw_complete(req, -EIO); + return; + } acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov, req->qiov.size / BDRV_SECTOR_SIZE, diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index af45edd87..f9b982e3e 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -848,8 +848,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes, zstream->avail_in = vs->tight.tight.offset; zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset; zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset; + previous_out = zstream->avail_out; zstream->data_type = Z_BINARY; - previous_out = zstream->total_out; /* start encoding */ if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) { @@ -858,7 +858,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes, } vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out; - bytes = zstream->total_out - previous_out; + /* ...how much data has actually been produced by deflate() */ + bytes = previous_out - zstream->avail_out; tight_send_compact_size(vs, bytes); vnc_write(vs, vs->tight.zlib.buffer, bytes); diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c index 3c6e6abf9..e32e4cd8a 100644 --- a/ui/vnc-enc-zlib.c +++ b/ui/vnc-enc-zlib.c @@ -103,8 +103,8 @@ static int vnc_zlib_stop(VncState *vs) zstream->avail_in = vs->zlib.zlib.offset; zstream->next_out = vs->output.buffer + vs->output.offset; zstream->avail_out = vs->output.capacity - vs->output.offset; + previous_out = zstream->avail_out; zstream->data_type = Z_BINARY; - previous_out = zstream->total_out; // start encoding if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) { @@ -113,7 +113,7 @@ static int vnc_zlib_stop(VncState *vs) } vs->output.offset = vs->output.capacity - zstream->avail_out; - return zstream->total_out - previous_out; + return previous_out - zstream->avail_out; } int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) @@ -2090,7 +2090,9 @@ int main(int argc, char **argv, char **envp) HD_OPTS); break; case QEMU_OPTION_drive: - drive_def(optarg); + if (drive_def(optarg) == NULL) { + exit(1); + } break; case QEMU_OPTION_set: if (qemu_set_option(optarg) != 0) |