From c0024a82577d14564b300dad440437d352ae6a26 Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:01:46 +0000 Subject: lsi: add ISTAT1 register read (Ryan Harper) SLES10 SP2 installer complains when probing a scsi disk and exits qemu when failing to read one of the registers. lsi_scsi: error: readb 0x15 -- Ryan Harper Software Engineer; Linux Technology Center IBM Corp., Austin, Tx ryanh@us.ibm.com diffstat output: lsi53c895a.c | 2 ++ 1 files changed, 2 insertions(+) Signed-off-by: Ryan Harper --- Subject: [PATCH] lsi: add ISTAT1 register read From: Ryan Harper Cc: kvm@vger.kernel.org SLES10 SP2 installer complains when probing a scsi disk and exits qemu when failing to read one of the registers. lsi_scsi: error: readb 0x15 Signed-off-by: Ryan Harper Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6690 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/lsi53c895a.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 36ee28e714..1f4f8b7ef7 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -1369,6 +1369,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) CASE_GET_REG32(dsa, 0x10) case 0x14: /* ISTAT0 */ return s->istat0; + case 0x15: /* ISTAT1 */ + return s->istat1; case 0x16: /* MBOX0 */ return s->mbox0; case 0x17: /* MBOX1 */ -- cgit v1.2.3 From 8ae0978ed54cdc1d55130af4dc32b362cd75706c Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:01:53 +0000 Subject: Fix cpuid KVM crash on i386 (Lubomir Rintel) Cpuid should return into vec, not overwrite past address in count. Changeset 6565 broke this. Signed-off-by: Lubomir Rintel Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6691 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index c0fc556c70..82137039d1 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1421,10 +1421,10 @@ static void host_cpuid(uint32_t function, uint32_t count, #else asm volatile("pusha \n\t" "cpuid \n\t" - "mov %%eax, 0(%1) \n\t" - "mov %%ebx, 4(%1) \n\t" - "mov %%ecx, 8(%1) \n\t" - "mov %%edx, 12(%1) \n\t" + "mov %%eax, 0(%2) \n\t" + "mov %%ebx, 4(%2) \n\t" + "mov %%ecx, 8(%2) \n\t" + "mov %%edx, 12(%2) \n\t" "popa" : : "a"(function), "c"(count), "S"(vec) : "memory", "cc"); -- cgit v1.2.3 From 249139f4e6e9ff8dfd2086d4e3fdfda8b1c53bac Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:04 +0000 Subject: char: Fix initial reset (Jan Kiszka) Recent changes to the graphical console initialization broke the initial CHR_EVENT_RESET distribution. The reset BHs generated on char device initialization are now already consumed during machine init (ide init ... -> qemu_aio_wait -> qemu_bh_poll). Therefore, this patch moves the initial qemu_chr_reset calls into a separate funtion which is called after machine init. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6692 c046a42c-6fe2-441c-8c8c-71466251a162 --- qemu-char.c | 20 ++++++++++++++++---- qemu-char.h | 1 + vl.c | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 7cdeffd61e..1332863ed3 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -101,6 +101,10 @@ /***********************************************************/ /* character device */ +static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = + TAILQ_HEAD_INITIALIZER(chardevs); +static int initial_reset_issued; + static void qemu_chr_event(CharDriverState *s, int event) { if (!s->chr_event) @@ -118,12 +122,23 @@ static void qemu_chr_reset_bh(void *opaque) void qemu_chr_reset(CharDriverState *s) { - if (s->bh == NULL) { + if (s->bh == NULL && initial_reset_issued) { s->bh = qemu_bh_new(qemu_chr_reset_bh, s); qemu_bh_schedule(s->bh); } } +void qemu_chr_initial_reset(void) +{ + CharDriverState *chr; + + initial_reset_issued = 1; + + TAILQ_FOREACH(chr, &chardevs, next) { + qemu_chr_reset(chr); + } +} + int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len) { return s->chr_write(s, buf, len); @@ -2076,9 +2091,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, return NULL; } -static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs -= TAILQ_HEAD_INITIALIZER(chardevs); - CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) { const char *p; diff --git a/qemu-char.h b/qemu-char.h index bc0fcf3259..9ff6b99c45 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -74,6 +74,7 @@ void qemu_chr_add_handlers(CharDriverState *s, void *opaque); int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); void qemu_chr_reset(CharDriverState *s); +void qemu_chr_initial_reset(void); int qemu_chr_can_read(CharDriverState *s); void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); void qemu_chr_accept_input(CharDriverState *s); diff --git a/vl.c b/vl.c index d3863c493b..9ba6bc451a 100644 --- a/vl.c +++ b/vl.c @@ -5693,6 +5693,7 @@ int main(int argc, char **argv, char **envp) } text_consoles_set_display(display_state); + qemu_chr_initial_reset(); if (monitor_device && monitor_hd) monitor_init(monitor_hd, !nographic); -- cgit v1.2.3 From af8222c0f859f4ef5dbacb37db8a65c695bb9d3e Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:07 +0000 Subject: char-mux: Use separate input buffers (Jan Kiszka) Currently, the intermediate input buffer of mux'ed character devices records data across all sub-devices. This has the side effect that we easily leak data recorded over one sub-devices to another once we switch the focus. Avoid data loss and confusion by defining exclusive buffers. Note: In contrast to the original author's claim, the buffering concept still breaks down when the fifo of the currently active sub-device is full. As we cannot accept futher data from this point on without risking to loose it, we will also miss escape sequences, just like without all that buffering. In short: There is no reliable escape sequence handling without infinite buffers or the risk of loosing some data. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6693 c046a42c-6fe2-441c-8c8c-71466251a162 --- qemu-char.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 1332863ed3..1fd3aefe38 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -225,12 +225,15 @@ typedef struct { IOEventHandler *chr_event[MAX_MUX]; void *ext_opaque[MAX_MUX]; CharDriverState *drv; - unsigned char buffer[MUX_BUFFER_SIZE]; - int prod; - int cons; int mux_cnt; int term_got_escape; int max_size; + /* Intermediate input buffer allows to catch escape sequences even if the + currently active device is not accepting any input - but only until it + is full as well. */ + unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE]; + int prod[MAX_MUX]; + int cons[MAX_MUX]; } MuxDriver; @@ -360,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr) int m = chr->focus; MuxDriver *d = chr->opaque; - while (d->prod != d->cons && + while (d->prod[m] != d->cons[m] && d->chr_can_read[m] && d->chr_can_read[m](d->ext_opaque[m])) { d->chr_read[m](d->ext_opaque[m], - &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1); + &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1); } } @@ -372,11 +375,12 @@ static int mux_chr_can_read(void *opaque) { CharDriverState *chr = opaque; MuxDriver *d = chr->opaque; + int m = chr->focus; - if ((d->prod - d->cons) < MUX_BUFFER_SIZE) + if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) return 1; - if (d->chr_can_read[chr->focus]) - return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]); + if (d->chr_can_read[m]) + return d->chr_can_read[m](d->ext_opaque[m]); return 0; } @@ -391,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size) for(i = 0; i < size; i++) if (mux_proc_byte(chr, d, buf[i])) { - if (d->prod == d->cons && + if (d->prod[m] == d->cons[m] && d->chr_can_read[m] && d->chr_can_read[m](d->ext_opaque[m])) d->chr_read[m](d->ext_opaque[m], &buf[i], 1); else - d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i]; + d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i]; } } -- cgit v1.2.3 From 295b492cfa65f4cfbe65ad35ac77b3b2a7c9aa2e Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:11 +0000 Subject: block: Polish error handling of brdv_open2 (Jan Kiszka) Make sure that we always delete temporary disk images on error, remove obsolete malloc error checks and return proper error codes. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6694 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/block.c b/block.c index 7c744c7409..892c47ad81 100644 --- a/block.c +++ b/block.c @@ -311,8 +311,6 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) int ret; bs = bdrv_new(""); - if (!bs) - return -ENOMEM; ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL); if (ret < 0) { bdrv_delete(bs); @@ -349,12 +347,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, /* if there is a backing file, use it */ bs1 = bdrv_new(""); - if (!bs1) { - return -ENOMEM; - } - if (bdrv_open(bs1, filename, 0) < 0) { + ret = bdrv_open(bs1, filename, 0); + if (ret < 0) { bdrv_delete(bs1); - return -1; + return ret; } total_size = bdrv_getlength(bs1) >> SECTOR_BITS; @@ -372,9 +368,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, else realpath(filename, backing_filename); - if (bdrv_create(&bdrv_qcow2, tmp_filename, - total_size, backing_filename, 0) < 0) { - return -1; + ret = bdrv_create(&bdrv_qcow2, tmp_filename, + total_size, backing_filename, 0); + if (ret < 0) { + return ret; } filename = tmp_filename; bs->is_temporary = 1; @@ -383,14 +380,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, pstrcpy(bs->filename, sizeof(bs->filename), filename); if (flags & BDRV_O_FILE) { drv = find_protocol(filename); - if (!drv) - return -ENOENT; - } else { - if (!drv) { - drv = find_image_format(filename); - if (!drv) - return -1; - } + } else if (!drv) { + drv = find_image_format(filename); + } + if (!drv) { + ret = -ENOENT; + goto unlink_and_fail; } bs->drv = drv; bs->opaque = qemu_mallocz(drv->instance_size); @@ -409,6 +404,9 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, qemu_free(bs->opaque); bs->opaque = NULL; bs->drv = NULL; + unlink_and_fail: + if (bs->is_temporary) + unlink(filename); return ret; } if (drv->bdrv_getlength) { @@ -422,15 +420,13 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (bs->backing_file[0] != '\0') { /* if there is a backing file, use it */ bs->backing_hd = bdrv_new(""); - if (!bs->backing_hd) { - fail: - bdrv_close(bs); - return -ENOMEM; - } path_combine(backing_filename, sizeof(backing_filename), filename, bs->backing_file); - if (bdrv_open(bs->backing_hd, backing_filename, open_flags) < 0) - goto fail; + ret = bdrv_open(bs->backing_hd, backing_filename, open_flags); + if (ret < 0) { + bdrv_close(bs); + return ret; + } } /* call the change callback */ -- cgit v1.2.3 From cb5745c52905b014f658b489655584173a8e17d9 Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:15 +0000 Subject: block: Improve bdrv_iterate (Jan Kiszka) Make bdrv_iterate more useful by passing the BlockDriverState to the iterator instead of the device name. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6695 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 4 ++-- block.h | 3 ++- monitor.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index 892c47ad81..6bbc389ff0 100644 --- a/block.c +++ b/block.c @@ -1011,12 +1011,12 @@ BlockDriverState *bdrv_find(const char *name) return NULL; } -void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque) +void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) { BlockDriverState *bs; for (bs = bdrv_first; bs != NULL; bs = bs->next) { - it(opaque, bs->device_name); + it(opaque, bs); } } diff --git a/block.h b/block.h index e1927dd1d7..aa26ef3982 100644 --- a/block.h +++ b/block.h @@ -141,7 +141,8 @@ void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque); void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size); BlockDriverState *bdrv_find(const char *name); -void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque); +void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), + void *opaque); int bdrv_is_encrypted(BlockDriverState *bs); int bdrv_set_key(BlockDriverState *bs, const char *key); void bdrv_iterate_format(void (*it)(void *opaque, const char *name), diff --git a/monitor.c b/monitor.c index 513eca9daa..2d1b86e3c7 100644 --- a/monitor.c +++ b/monitor.c @@ -2679,8 +2679,9 @@ static void file_completion(const char *input) closedir(ffs); } -static void block_completion_it(void *opaque, const char *name) +static void block_completion_it(void *opaque, BlockDriverState *bs) { + const char *name = bdrv_get_device_name(bs); const char *input = opaque; if (input[0] == '\0' || -- cgit v1.2.3 From 49780457810325f0fd40811bfda7f4ec391de7a7 Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:19 +0000 Subject: block: Introduce bdrv_get_encrypted_filename (Jan Kiszka) Introduce bdrv_get_encrypted_filename service to allow more informative password prompting. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6696 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 10 ++++++++++ block.h | 1 + 2 files changed, 11 insertions(+) diff --git a/block.c b/block.c index 6bbc389ff0..e35c9a65aa 100644 --- a/block.c +++ b/block.c @@ -1134,6 +1134,16 @@ void bdrv_info_stats (void) } } +const char *bdrv_get_encrypted_filename(BlockDriverState *bs) +{ + if (bs->backing_hd && bs->backing_hd->encrypted) + return bs->backing_file; + else if (bs->encrypted) + return bs->filename; + else + return NULL; +} + void bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size) { diff --git a/block.h b/block.h index aa26ef3982..a01fa31b0c 100644 --- a/block.h +++ b/block.h @@ -152,6 +152,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); +const char *bdrv_get_encrypted_filename(BlockDriverState *bs); void bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size); int bdrv_snapshot_create(BlockDriverState *bs, -- cgit v1.2.3 From e36fb2a3a25f07301230f37d80e9dfdb3fe531f4 Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:30 +0000 Subject: monitor: Use reasonable default virtual console size (Jan Kiszka) If a target uses a tiny display (like the MusicPal), the default monitor is currently set to the same size. Fix this by applying the same defaults like already used serial and virtio consoles. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6697 c046a42c-6fe2-441c-8c8c-71466251a162 --- vl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vl.c b/vl.c index 9ba6bc451a..0f06aa9fd2 100644 --- a/vl.c +++ b/vl.c @@ -4696,7 +4696,7 @@ int main(int argc, char **argv, char **envp) kernel_cmdline = ""; cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; - monitor_device = "vc"; + monitor_device = "vc:80Cx24C"; serial_devices[0] = "vc:80Cx24C"; for(i = 1; i < MAX_SERIAL_PORTS; i++) -- cgit v1.2.3 From d3be2b2f71e616f18dc20af570c84ebdf091b4e7 Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:36 +0000 Subject: monitor: Report encrypted disks in snapshot mode (Jan Kiszka) If the backing file is encrypted, 'info block' currently does not report the disk as encrypted. Fix this by using the standard API to check disk encryption mode. Moreover, switch to a canonical output format. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6698 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/block.c b/block.c index e35c9a65aa..5f3f780fbe 100644 --- a/block.c +++ b/block.c @@ -1101,8 +1101,7 @@ void bdrv_info(void) } term_printf(" ro=%d", bs->read_only); term_printf(" drv=%s", bs->drv->format_name); - if (bs->encrypted) - term_printf(" encrypted"); + term_printf(" encrypted=%d", bdrv_is_encrypted(bs)); } else { term_printf(" [not inserted]"); } -- cgit v1.2.3 From b786b7ccbd375c052ffa9d3a818b88ee4870849c Mon Sep 17 00:00:00 2001 From: aliguori Date: Thu, 5 Mar 2009 19:42:40 +0000 Subject: monitor: Rework early disk password inquiry (Jan Kiszka) Reading the passwords for encrypted hard disks during early startup is broken (I guess for quiet a while now): - No monitor terminal is ready for input at this point - Forcing all mux'ed terminals into monitor mode can confuse other users of that channels To overcome these issues and to lay the ground for a clean decoupling of monitor terminals, this patch changes the initial password inquiry as follows: - Prevent autostart if there is some encrypted disk - Once the user tries to resume the VM, prompt for all missing passwords - Only resume if all passwords were accepted Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6699 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 14 +++++++++++- block.h | 4 ++-- block_int.h | 1 + console.h | 3 +-- hw/usb-msd.c | 6 ++--- hw/usb.h | 5 ++++- monitor.c | 44 ++++++++++++++++++++++++++++++++---- vl.c | 73 +++++++++++++++++------------------------------------------- 8 files changed, 85 insertions(+), 65 deletions(-) diff --git a/block.c b/block.c index 5f3f780fbe..78ab2d0462 100644 --- a/block.c +++ b/block.c @@ -336,6 +336,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, bs->read_only = 0; bs->is_temporary = 0; bs->encrypted = 0; + bs->valid_key = 0; if (flags & BDRV_O_SNAPSHOT) { BlockDriverState *bs1; @@ -966,6 +967,15 @@ int bdrv_is_encrypted(BlockDriverState *bs) return bs->encrypted; } +int bdrv_key_required(BlockDriverState *bs) +{ + BlockDriverState *backing_hd = bs->backing_hd; + + if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) + return 1; + return (bs->encrypted && !bs->valid_key); +} + int bdrv_set_key(BlockDriverState *bs, const char *key) { int ret; @@ -978,7 +988,9 @@ int bdrv_set_key(BlockDriverState *bs, const char *key) } if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) return -1; - return bs->drv->bdrv_set_key(bs, key); + ret = bs->drv->bdrv_set_key(bs, key); + bs->valid_key = (ret == 0); + return ret; } void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) diff --git a/block.h b/block.h index a01fa31b0c..5c6eaf937c 100644 --- a/block.h +++ b/block.h @@ -103,8 +103,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num, BlockDriverCompletionFunc *cb, void *opaque); void bdrv_aio_cancel(BlockDriverAIOCB *acb); -int qemu_key_check(BlockDriverState *bs, const char *name); - /* Ensure contents are flushed to disk. */ void bdrv_flush(BlockDriverState *bs); void bdrv_flush_all(void); @@ -144,7 +142,9 @@ BlockDriverState *bdrv_find(const char *name); void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque); int bdrv_is_encrypted(BlockDriverState *bs); +int bdrv_key_required(BlockDriverState *bs); int bdrv_set_key(BlockDriverState *bs, const char *key); +int bdrv_query_missing_keys(void); void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque); const char *bdrv_get_device_name(BlockDriverState *bs); diff --git a/block_int.h b/block_int.h index e1943aaa64..44eb280684 100644 --- a/block_int.h +++ b/block_int.h @@ -96,6 +96,7 @@ struct BlockDriverState { int removable; /* if true, the media can be removed */ int locked; /* if true, the media cannot temporarily be ejected */ int encrypted; /* if true, the media is encrypted */ + int valid_key; /* if true, a valid encryption key has been set */ int sg; /* if true, the device is a /dev/sg* */ /* event callback when inserting/removing */ void (*change_cb)(void *opaque); diff --git a/console.h b/console.h index 8f438e93f7..0c86852c4e 100644 --- a/console.h +++ b/console.h @@ -302,10 +302,9 @@ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1 void term_print_filename(const char *filename); void term_flush(void); void term_print_help(void); -void monitor_readline(const char *prompt, int is_password, - char *buf, int buf_size); void monitor_suspend(void); void monitor_resume(void); +int monitor_read_bdrv_key(BlockDriverState *bs); /* readline.c */ typedef void ReadLineFunc(void *opaque, const char *str); diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 342b0e873a..0c8d9cca83 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -11,6 +11,7 @@ #include "usb.h" #include "block.h" #include "scsi-disk.h" +#include "console.h" //#define DEBUG_MSD @@ -513,7 +514,7 @@ static void usb_msd_handle_destroy(USBDevice *dev) qemu_free(s); } -USBDevice *usb_msd_init(const char *filename) +USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs) { MSDState *s; BlockDriverState *bdrv; @@ -552,9 +553,8 @@ USBDevice *usb_msd_init(const char *filename) bdrv = bdrv_new("usb"); if (bdrv_open2(bdrv, filename, 0, drv) < 0) goto fail; - if (qemu_key_check(bdrv, filename)) - goto fail; s->bs = bdrv; + *pbs = bdrv; s->dev.speed = USB_SPEED_FULL; s->dev.handle_packet = usb_generic_handle_packet; diff --git a/hw/usb.h b/hw/usb.h index 4204808a00..4cd832d492 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -21,6 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + +#include "block.h" + #define USB_TOKEN_SETUP 0x2d #define USB_TOKEN_IN 0x69 /* device -> host */ #define USB_TOKEN_OUT 0xe1 /* host -> device */ @@ -250,7 +253,7 @@ USBDevice *usb_keyboard_init(void); void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); /* usb-msd.c */ -USBDevice *usb_msd_init(const char *filename); +USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs); /* usb-net.c */ USBDevice *usb_net_init(NICInfo *nd); diff --git a/monitor.c b/monitor.c index 2d1b86e3c7..914938c7f6 100644 --- a/monitor.c +++ b/monitor.c @@ -76,6 +76,8 @@ static uint8_t term_outbuf[1024]; static int term_outbuf_index; static void monitor_start_input(void); +static void monitor_readline(const char *prompt, int is_password, + char *buf, int buf_size); static CPUState *mon_cpu = NULL; @@ -433,7 +435,7 @@ static void do_change_block(const char *device, const char *filename, const char if (eject_device(bs, 0) < 0) return; bdrv_open2(bs, filename, 0, drv); - qemu_key_check(bs, filename); + monitor_read_bdrv_key(bs); } static void do_change_vnc(const char *target, const char *arg) @@ -494,9 +496,24 @@ static void do_stop(void) vm_stop(EXCP_INTERRUPT); } +static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs) +{ + int *err = opaque; + + if (bdrv_key_required(bs)) + *err = monitor_read_bdrv_key(bs); + else + *err = 0; +} + static void do_cont(void) { - vm_start(); + int err = 0; + + bdrv_iterate(encrypted_bdrv_it, &err); + /* only resume the vm if all keys are set and valid */ + if (!err) + vm_start(); } #ifdef CONFIG_GDBSTUB @@ -2892,8 +2909,8 @@ static void monitor_readline_cb(void *opaque, const char *input) monitor_readline_started = 0; } -void monitor_readline(const char *prompt, int is_password, - char *buf, int buf_size) +static void monitor_readline(const char *prompt, int is_password, + char *buf, int buf_size) { int i; int old_focus[MAX_MON]; @@ -2923,3 +2940,22 @@ void monitor_readline(const char *prompt, int is_password, monitor_hd[i]->focus = old_focus[i]; } } + +int monitor_read_bdrv_key(BlockDriverState *bs) +{ + char password[256]; + int i; + + if (!bdrv_is_encrypted(bs)) + return 0; + + term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs), + bdrv_get_encrypted_filename(bs)); + for(i = 0; i < 3; i++) { + monitor_readline("Password: ", 1, password, sizeof(password)); + if (bdrv_set_key(bs, password) == 0) + return 0; + term_printf("invalid password\n"); + } + return -EPERM; +} diff --git a/vl.c b/vl.c index 0f06aa9fd2..aaeff23faf 100644 --- a/vl.c +++ b/vl.c @@ -201,6 +201,7 @@ ram_addr_t ram_size; int nb_nics; NICInfo nd_table[MAX_NICS]; int vm_running; +static int autostart; static int rtc_utc = 1; static int rtc_date_offset = -1; /* -1 means no change */ int cirrus_vga_enabled = 1; @@ -2607,11 +2608,13 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque) bdrv_flags |= BDRV_O_CACHE_WB; else if (cache == 3) /* not specified */ bdrv_flags |= BDRV_O_CACHE_DEF; - if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) { + if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) { fprintf(stderr, "qemu: could not open disk image %s\n", file); return -1; } + if (bdrv_key_required(bdrv)) + autostart = 0; return drives_table_idx; } @@ -2658,7 +2661,7 @@ int usb_device_add_dev(USBDevice *dev) return 0; } -static int usb_device_add(const char *devname) +static int usb_device_add(const char *devname, int is_hotplug) { const char *p; USBDevice *dev; @@ -2675,7 +2678,18 @@ static int usb_device_add(const char *devname) } else if (!strcmp(devname, "keyboard")) { dev = usb_keyboard_init(); } else if (strstart(devname, "disk:", &p)) { - dev = usb_msd_init(p); + BlockDriverState *bs; + + dev = usb_msd_init(p, &bs); + if (!dev) + return -1; + if (bdrv_key_required(bs)) { + autostart = 0; + if (is_hotplug && monitor_read_bdrv_key(bs) < 0) { + dev->handle_destroy(dev); + return -1; + } + } } else if (!strcmp(devname, "wacom-tablet")) { dev = usb_wacom_init(); } else if (strstart(devname, "serial:", &p)) { @@ -2756,7 +2770,7 @@ static int usb_device_del(const char *devname) void do_usb_add(const char *devname) { - usb_device_add(devname); + usb_device_add(devname, 1); } void do_usb_del(const char *devname) @@ -4334,45 +4348,6 @@ static const QEMUOption qemu_options[] = { { NULL }, }; -/* password input */ - -int qemu_key_check(BlockDriverState *bs, const char *name) -{ - char password[256]; - int i; - - if (!bdrv_is_encrypted(bs)) - return 0; - - term_printf("%s is encrypted.\n", name); - for(i = 0; i < 3; i++) { - monitor_readline("Password: ", 1, password, sizeof(password)); - if (bdrv_set_key(bs, password) == 0) - return 0; - term_printf("invalid password\n"); - } - return -EPERM; -} - -static BlockDriverState *get_bdrv(int index) -{ - if (index > nb_drives) - return NULL; - return drives_table[index].bdrv; -} - -static void read_passwords(void) -{ - BlockDriverState *bs; - int i; - - for(i = 0; i < 6; i++) { - bs = get_bdrv(i); - if (bs) - qemu_key_check(bs, bdrv_get_device_name(bs)); - } -} - #ifdef HAS_AUDIO struct soundhw soundhw[] = { #ifdef HAS_AUDIO_CHOICE @@ -4639,7 +4614,6 @@ int main(int argc, char **argv, char **envp) int fds[2]; int tb_size; const char *pid_file = NULL; - int autostart; const char *incoming = NULL; int fd = 0; struct passwd *pwd = NULL; @@ -5637,7 +5611,7 @@ int main(int argc, char **argv, char **envp) /* init USB devices */ if (usb_enabled) { for(i = 0; i < usb_devices_index; i++) { - if (usb_device_add(usb_devices[i]) < 0) { + if (usb_device_add(usb_devices[i], 0) < 0) { fprintf(stderr, "Warning: could not add USB device %s\n", usb_devices[i]); } @@ -5748,13 +5722,8 @@ int main(int argc, char **argv, char **envp) qemu_start_incoming_migration(incoming); } - { - /* XXX: simplify init */ - read_passwords(); - if (autostart) { - vm_start(); - } - } + if (autostart) + vm_start(); if (daemonize) { uint8_t status = 0; -- cgit v1.2.3 From 8a11f5ff08a2c351d6262617ee50a7a7c8d11f68 Mon Sep 17 00:00:00 2001 From: aurel32 Date: Fri, 6 Mar 2009 21:49:37 +0000 Subject: Fix race condition on access to env->interrupt_request env->interrupt_request is accessed as the bit level from both main code and signal handler, making a race condition possible even on CISC CPU. This causes freeze of QEMU under high load when running the dyntick clock. The patch below move the bit corresponding to CPU_INTERRUPT_EXIT in a separate variable, declared as volatile sig_atomic_t, so it should be work even on RISC CPU. We may want to move the cpu_interrupt(env, CPU_INTERRUPT_EXIT) case in its own function and get rid of CPU_INTERRUPT_EXIT. That can be done later, I wanted to keep the patch short for easier review. Signed-off-by: Aurelien Jarno git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6729 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-defs.h | 2 ++ cpu-exec.c | 16 ++++++++-------- exec.c | 11 ++++++----- kvm-all.c | 6 +++--- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index 758fa9f2ca..aa46fc3bce 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -27,6 +27,7 @@ #include "config.h" #include #include +#include #include "osdep.h" #include "sys-queue.h" @@ -170,6 +171,7 @@ typedef struct CPUWatchpoint { memory was accessed */ \ uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ uint32_t interrupt_request; \ + volatile sig_atomic_t exit_request; \ /* The meaning of the MMU modes is defined in the target code. */ \ CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \ target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \ diff --git a/cpu-exec.c b/cpu-exec.c index f7be38df50..7607e240b5 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -311,7 +311,7 @@ int cpu_exec(CPUState *env1) env->exception_index = -1; } #ifdef USE_KQEMU - if (kqemu_is_ok(env) && env->interrupt_request == 0) { + if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) { int ret; env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); ret = kqemu_cpu_exec(env); @@ -326,7 +326,7 @@ int cpu_exec(CPUState *env1) } else if (ret == 2) { /* softmmu execution needed */ } else { - if (env->interrupt_request != 0) { + if (env->interrupt_request != 0 || env->exit_request != 0) { /* hardware interrupt will be executed just after */ } else { /* otherwise, we restart */ @@ -525,11 +525,11 @@ int cpu_exec(CPUState *env1) the program flow was changed */ next_tb = 0; } - if (interrupt_request & CPU_INTERRUPT_EXIT) { - env->interrupt_request &= ~CPU_INTERRUPT_EXIT; - env->exception_index = EXCP_INTERRUPT; - cpu_loop_exit(); - } + } + if (unlikely(env->exit_request)) { + env->exit_request = 0; + env->exception_index = EXCP_INTERRUPT; + cpu_loop_exit(); } #ifdef DEBUG_EXEC if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { @@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1) TB, but before it is linked into a potentially infinite loop and becomes env->current_tb. Avoid starting execution if there is a pending interrupt. */ - if (unlikely (env->interrupt_request & CPU_INTERRUPT_EXIT)) + if (unlikely (env->exit_request)) env->current_tb = NULL; while (env->current_tb) { diff --git a/exec.c b/exec.c index f4a071e0f3..902031c48d 100644 --- a/exec.c +++ b/exec.c @@ -1501,9 +1501,12 @@ void cpu_interrupt(CPUState *env, int mask) #endif int old_mask; + if (mask & CPU_INTERRUPT_EXIT) { + env->exit_request = 1; + mask &= ~CPU_INTERRUPT_EXIT; + } + old_mask = env->interrupt_request; - /* FIXME: This is probably not threadsafe. A different thread could - be in the middle of a read-modify-write operation. */ env->interrupt_request |= mask; #if defined(USE_NPTL) /* FIXME: TB unchaining isn't SMP safe. For now just ignore the @@ -1514,10 +1517,8 @@ void cpu_interrupt(CPUState *env, int mask) if (use_icount) { env->icount_decr.u16.high = 0xffff; #ifndef CONFIG_USER_ONLY - /* CPU_INTERRUPT_EXIT isn't a real interrupt. It just means - an async event happened and we need to process it. */ if (!can_do_io(env) - && (mask & ~(old_mask | CPU_INTERRUPT_EXIT)) != 0) { + && (mask & ~old_mask) != 0) { cpu_abort(env, "Raised interrupt while not in I/O function"); } #endif diff --git a/kvm-all.c b/kvm-all.c index 0b1742709b..28c9c07ccb 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -445,7 +445,7 @@ int kvm_cpu_exec(CPUState *env) do { kvm_arch_pre_run(env, run); - if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) { + if (env->exit_request) { dprintf("interrupt exit requested\n"); ret = 0; break; @@ -512,8 +512,8 @@ int kvm_cpu_exec(CPUState *env) } } while (ret > 0); - if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) { - env->interrupt_request &= ~CPU_INTERRUPT_EXIT; + if (env->exit_request) { + env->exit_request = 0; env->exception_index = EXCP_INTERRUPT; } -- cgit v1.2.3 From d9aa1fce5a7a1bf642fc94743cdfc5efa29df21f Mon Sep 17 00:00:00 2001 From: aurel32 Date: Sat, 7 Mar 2009 21:08:39 +0000 Subject: Clear CPU_INTERRUPT_EXIT on VM load CPU_INTERRUPT_EXIT is not set anymore in env->interrupt_request since revision 6729. Make sure the bit is cleared on VM load. Signed-off-by: Aurelien Jarno git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6760 c046a42c-6fe2-441c-8c8c-71466251a162 --- exec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/exec.c b/exec.c index 902031c48d..37468399fc 100644 --- a/exec.c +++ b/exec.c @@ -523,6 +523,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be32s(f, &env->halted); qemu_get_be32s(f, &env->interrupt_request); + env->interrupt_request &= ~CPU_INTERRUPT_EXIT; tlb_flush(env, 1); return 0; -- cgit v1.2.3 From b96a313d3d6c98db61609422a0f2bbbc660d8431 Mon Sep 17 00:00:00 2001 From: aliguori Date: Sun, 8 Mar 2009 15:04:13 +0000 Subject: Remove unnecessary prefix on SDL_syswm.h. This fixes the build for certain installs of SDL. Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6781 c046a42c-6fe2-441c-8c8c-71466251a162 --- sdl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdl.c b/sdl.c index c685b81f6f..ba56957131 100644 --- a/sdl.c +++ b/sdl.c @@ -27,7 +27,7 @@ #include "x_keymap.h" #include -#include +#include #ifndef _WIN32 #include -- cgit v1.2.3 From f902c4192e11c0f1d00844e8f3e266aabe00068f Mon Sep 17 00:00:00 2001 From: aurel32 Date: Sun, 8 Mar 2009 19:52:43 +0000 Subject: qemu-img: fix help message Signed-off-by: Aurelien Jarno git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6788 c046a42c-6fe2-441c-8c8c-71466251a162 --- qemu-img.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index d83ffe3ee9..fb81ea723b 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -74,8 +74,8 @@ static void help(void) " differ\n" " 'fmt' is the disk image format. It is guessed automatically in most cases\n" " 'size' is the disk image size in kilobytes. Optional suffixes\n" - " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are" - " supported any @code{k} or @code{K} is ignored\n" + " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n" + " supported any 'k' or 'K' is ignored\n" " 'output_filename' is the destination disk image filename\n" " 'output_fmt' is the destination format\n" " '-c' indicates that target image must be compressed (qcow format only)\n" -- cgit v1.2.3 From 4ca9f3dd7139057a2105de7c423f24228e3ea874 Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 11 Mar 2009 20:15:55 +0000 Subject: Revert r6408 This series is broken by design as it requires expensive IO operations at open time causing very long delays when starting a virtual machine for the first time. Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6817 c046a42c-6fe2-441c-8c8c-71466251a162 --- qemu-img.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index fb81ea723b..efbb9b6be8 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -730,10 +730,6 @@ static int img_info(int argc, char **argv) if (bdrv_get_info(bs, &bdi) >= 0) { if (bdi.cluster_size != 0) printf("cluster_size: %d\n", bdi.cluster_size); - if (bdi.highest_alloc) - printf("highest_alloc: %" PRId64 "\n", bdi.highest_alloc); - if (bdi.num_free_bytes) - printf("num_free_bytes: %" PRId64 "\n", bdi.num_free_bytes); } bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); if (backing_filename[0] != '\0') { -- cgit v1.2.3 From 9cecf0f57067d51d33fb881236e8218864cd1dd4 Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 11 Mar 2009 20:16:01 +0000 Subject: Revert r6407 This series is broken by design as it requires expensive IO operations at open time causing very long delays when starting a virtual machine for the first time. Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6818 c046a42c-6fe2-441c-8c8c-71466251a162 --- block-qcow2.c | 36 ++++++++---------------------------- block.c | 5 ++--- block.h | 1 - 3 files changed, 10 insertions(+), 32 deletions(-) diff --git a/block-qcow2.c b/block-qcow2.c index 465dcd6d42..85e9cd78a3 100644 --- a/block-qcow2.c +++ b/block-qcow2.c @@ -145,7 +145,6 @@ typedef struct BDRVQcowState { AES_KEY aes_decrypt_key; int64_t highest_alloc; /* highest cluester allocated (in clusters) */ - int64_t nc_free; /* num of free clusters below highest_alloc */ uint64_t snapshots_offset; int snapshots_size; @@ -174,7 +173,7 @@ static void free_clusters(BlockDriverState *bs, #ifdef DEBUG_ALLOC static void check_refcounts(BlockDriverState *bs); #endif -static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free); +static void scan_refcount(BlockDriverState *bs, int64_t *high); static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) @@ -276,7 +275,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags) if (refcount_init(bs) < 0) goto fail; - scan_refcount(bs, &s->highest_alloc, &s->nc_free); + scan_refcount(bs, &s->highest_alloc); /* read the backing file name */ if (header.backing_file_offset != 0) { @@ -1647,7 +1646,6 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) bdi->vm_state_offset = (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); bdi->highest_alloc = s->highest_alloc << s->cluster_bits; - bdi->num_free_bytes = s->nc_free << s->cluster_bits; return 0; } @@ -2166,35 +2164,25 @@ static int load_refcount_block(BlockDriverState *bs, return 0; } -static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free) +static void scan_refcount(BlockDriverState *bs, int64_t *high) { BDRVQcowState *s = bs->opaque; - int64_t refcnt_index, cluster_index, cluster_end, h = 0, f = 0; - int64_t tail = 0; /* do not count last consecutive free entries */ + int64_t refcnt_index, cluster_index, cluster_end, h = 0; for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){ if (s->refcount_table[refcnt_index] == 0) { - f += 1 << (s->cluster_bits - REFCOUNT_SHIFT); - tail += 1 << (s->cluster_bits - REFCOUNT_SHIFT); continue; } cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT); cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT); for ( ; cluster_index < cluster_end; cluster_index++) { - if (get_refcount(bs, cluster_index) == 0) { - f++; - tail++; - } - else { + if (get_refcount(bs, cluster_index) == 0) + /* do nothing -- reserved for free counting */; + else h = cluster_index; - tail = 0; - } } } - f -= tail; - if (free) - *free = f; if (high) *high = (h+1); } @@ -2240,10 +2228,8 @@ retry: (s->free_cluster_index - nb_clusters) << s->cluster_bits); #endif - if (s->highest_alloc < s->free_cluster_index) { - s->nc_free += (s->free_cluster_index - s->highest_alloc); + if (s->highest_alloc < s->free_cluster_index) s->highest_alloc = s->free_cluster_index; - } return (s->free_cluster_index - nb_clusters) << s->cluster_bits; } @@ -2418,12 +2404,6 @@ static int update_cluster_refcount(BlockDriverState *bs, block_index = cluster_index & ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); refcount = be16_to_cpu(s->refcount_block_cache[block_index]); - - if (refcount == 1 && addend == -1) - s->nc_free += 1; - else if (refcount == 0 && addend == 1) - s->nc_free -= 1; - refcount += addend; if (refcount < 0 || refcount > 0xffff) return -EINVAL; diff --git a/block.c b/block.c index 78ab2d0462..08012a9984 100644 --- a/block.c +++ b/block.c @@ -1138,9 +1138,8 @@ void bdrv_info_stats (void) bs->rd_bytes, bs->wr_bytes, bs->rd_ops, bs->wr_ops); if (bdrv_get_info(bs, &bdi) == 0) - term_printf(" high=%" PRId64 - " bytes_free=%" PRId64, - bdi.highest_alloc, bdi.num_free_bytes); + term_printf(" high=%" PRId64, + bdi.highest_alloc); term_printf("\n"); } } diff --git a/block.h b/block.h index 5c6eaf937c..fbce8a2c0c 100644 --- a/block.h +++ b/block.h @@ -27,7 +27,6 @@ typedef struct BlockDriverInfo { /* offset at which the VM state can be saved (0 if not possible) */ int64_t vm_state_offset; int64_t highest_alloc; /* highest allocated block offset (in bytes) */ - int64_t num_free_bytes; /* below highest_alloc */ } BlockDriverInfo; typedef struct QEMUSnapshotInfo { -- cgit v1.2.3 From 414c078104b62170353b6ffe0ab8f01374bcc073 Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 11 Mar 2009 20:16:05 +0000 Subject: Revert r6406 This series is broken by design as it requires expensive IO operations at open time causing very long delays when starting a virtual machine for the first time. Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6819 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/block.c b/block.c index 08012a9984..bcd8431f1e 100644 --- a/block.c +++ b/block.c @@ -1125,7 +1125,6 @@ void bdrv_info(void) void bdrv_info_stats (void) { BlockDriverState *bs; - BlockDriverInfo bdi; for (bs = bdrv_first; bs != NULL; bs = bs->next) { term_printf ("%s:" @@ -1133,14 +1132,10 @@ void bdrv_info_stats (void) " wr_bytes=%" PRIu64 " rd_operations=%" PRIu64 " wr_operations=%" PRIu64 - , + "\n", bs->device_name, bs->rd_bytes, bs->wr_bytes, bs->rd_ops, bs->wr_ops); - if (bdrv_get_info(bs, &bdi) == 0) - term_printf(" high=%" PRId64, - bdi.highest_alloc); - term_printf("\n"); } } -- cgit v1.2.3 From 523faf1b924a89b412aa9a87d7ed0b34a1259428 Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 11 Mar 2009 20:16:12 +0000 Subject: Revert r6405 This series is broken by design as it requires expensive IO operations at open time causing very long delays when starting a virtual machine for the first time. Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6820 c046a42c-6fe2-441c-8c8c-71466251a162 --- block-qcow2.c | 1 - block.h | 1 - 2 files changed, 2 deletions(-) diff --git a/block-qcow2.c b/block-qcow2.c index 85e9cd78a3..7cfa62b89a 100644 --- a/block-qcow2.c +++ b/block-qcow2.c @@ -1645,7 +1645,6 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) bdi->cluster_size = s->cluster_size; bdi->vm_state_offset = (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); - bdi->highest_alloc = s->highest_alloc << s->cluster_bits; return 0; } diff --git a/block.h b/block.h index fbce8a2c0c..702403f6c3 100644 --- a/block.h +++ b/block.h @@ -26,7 +26,6 @@ typedef struct BlockDriverInfo { int cluster_size; /* offset at which the VM state can be saved (0 if not possible) */ int64_t vm_state_offset; - int64_t highest_alloc; /* highest allocated block offset (in bytes) */ } BlockDriverInfo; typedef struct QEMUSnapshotInfo { -- cgit v1.2.3 From 0f56231dcea933fffc082735e02a52f339fc8d7c Mon Sep 17 00:00:00 2001 From: aliguori Date: Wed, 11 Mar 2009 20:16:16 +0000 Subject: Revert r6404 This series is broken by design as it requires expensive IO operations at open time causing very long delays when starting a virtual machine for the first time. Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6821 c046a42c-6fe2-441c-8c8c-71466251a162 --- block-qcow2.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/block-qcow2.c b/block-qcow2.c index 7cfa62b89a..957e419cae 100644 --- a/block-qcow2.c +++ b/block-qcow2.c @@ -143,9 +143,6 @@ typedef struct BDRVQcowState { uint32_t crypt_method_header; AES_KEY aes_encrypt_key; AES_KEY aes_decrypt_key; - - int64_t highest_alloc; /* highest cluester allocated (in clusters) */ - uint64_t snapshots_offset; int snapshots_size; int nb_snapshots; @@ -173,8 +170,6 @@ static void free_clusters(BlockDriverState *bs, #ifdef DEBUG_ALLOC static void check_refcounts(BlockDriverState *bs); #endif -static void scan_refcount(BlockDriverState *bs, int64_t *high); - static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) { @@ -275,8 +270,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags) if (refcount_init(bs) < 0) goto fail; - scan_refcount(bs, &s->highest_alloc); - /* read the backing file name */ if (header.backing_file_offset != 0) { len = header.backing_file_size; @@ -2163,29 +2156,6 @@ static int load_refcount_block(BlockDriverState *bs, return 0; } -static void scan_refcount(BlockDriverState *bs, int64_t *high) -{ - BDRVQcowState *s = bs->opaque; - int64_t refcnt_index, cluster_index, cluster_end, h = 0; - - for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){ - if (s->refcount_table[refcnt_index] == 0) { - continue; - } - cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT); - cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT); - for ( ; cluster_index < cluster_end; cluster_index++) { - if (get_refcount(bs, cluster_index) == 0) - /* do nothing -- reserved for free counting */; - else - h = cluster_index; - } - } - - if (high) - *high = (h+1); -} - static int get_refcount(BlockDriverState *bs, int64_t cluster_index) { BDRVQcowState *s = bs->opaque; @@ -2226,10 +2196,6 @@ retry: size, (s->free_cluster_index - nb_clusters) << s->cluster_bits); #endif - - if (s->highest_alloc < s->free_cluster_index) - s->highest_alloc = s->free_cluster_index; - return (s->free_cluster_index - nb_clusters) << s->cluster_bits; } -- cgit v1.2.3 From 4827c90ceff8db7de6627c57a8bb7b56daf3fc55 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 13 Mar 2009 16:18:57 +0000 Subject: make qemu_announce_self handle non contiguous net tables (Marcelo Tosatti) With hotplug nd_table might contain holes. Noticed by Eduardo Habkost. Signed-off-by: Marcelo Tosatti Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6846 c046a42c-6fe2-441c-8c8c-71466251a162 --- savevm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/savevm.c b/savevm.c index 3eb2000ab2..3b4941448b 100644 --- a/savevm.c +++ b/savevm.c @@ -118,7 +118,9 @@ void qemu_announce_self(void) VLANClientState *vc; uint8_t buf[256]; - for (i = 0; i < nb_nics; i++) { + for (i = 0; i < MAX_NICS; i++) { + if (!nd_table[i].used) + continue; len = announce_self_create(buf, nd_table[i].macaddr); vlan = nd_table[i].vlan; for(vc = vlan->first_client; vc != NULL; vc = vc->next) { -- cgit v1.2.3 From 3df962a30d182596a7de633d7d779b16ccf133e8 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 13 Mar 2009 16:19:04 +0000 Subject: qemu:virtio-net: Check return size on the correct sg list (Alex Williamson) When checking that the size of the control virtqueue return field is sufficient, use the correct sg list. Signed-off-by: Alex Williamson Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6847 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/virtio-net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index e83d1019c1..ad55bb7610 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -228,7 +228,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) } if (elem.out_sg[0].iov_len < sizeof(ctrl) || - elem.out_sg[elem.in_num - 1].iov_len < sizeof(status)) { + elem.in_sg[elem.in_num - 1].iov_len < sizeof(status)) { fprintf(stderr, "virtio-net ctrl header not in correct element\n"); exit(1); } -- cgit v1.2.3 From 15d4afd55beb0d1d546fe793d8e7d975e0e8d086 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 13 Mar 2009 16:22:40 +0000 Subject: Update changelog Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6848 c046a42c-6fe2-441c-8c8c-71466251a162 --- Changelog | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Changelog b/Changelog index 12edd70d8c..9659be4efb 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,25 @@ +version 0.10.1: + + - virtio-net: check right return size on sg list (Alex Williamson) + - Make qemu_announce_self handle holes (live migration after hotplug) + (Marcelo Tosatti) + - Revert r6804-r6808 (qcow2 allocation info). This series of changes added + a high cost to startup for large qcow2 images (Anthony Liguori) + - qemu-img: fix help message (Aurelien Jarno) + - Fix build for non-default installs of SDL (Anthony Liguori) + - Fix race condition in env->interrupt_request. When using TCG and a dynticks + host timer, this condition could cause TCG to get stuck in an infinite + loop (Aurelien Jarno) + - Fix reading encrypted hard disk passwords during early startup (Jan Kiszka) + - Fix encrypted disk reporting in 'info block' (Jan Kiszka) + - Fix console size with tiny displays (MusicPal) (Jan Kiszka) + - Improve error handling in bdrv_open2 (Jan Kiszka) + - Avoid leaking data in mux'ed character devices (Jan Kiszka) + - Fix initial character device reset (no banner in monitor) (Jan Kiszka) + - Fix cpuid KVM crash on i386 host (Lubomir Rintel) + - Fix SLES10sp2 installation by adding ISTAT1 register to LSI SCSI emulation + (Ryan Harper) + version 0.10.0: - TCG support (No longer requires GCC 3.x) -- cgit v1.2.3 From 21fd8325122bcbb4c330e8505fb50f48b7da0643 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 13 Mar 2009 18:11:17 +0000 Subject: stop dirty logging while updating cirrus bank memory (Glauber Costa) Otherwise, slot tracking gets confused. This fixes a screen corruption bug with Ubuntu guest installation. Signed-off-by: Glauber Costa Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6853 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/cirrus_vga.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 8aade84846..2ff80d3316 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2637,11 +2637,16 @@ static void map_linear_vram(CirrusVGAState *s) s->lfb_vram_mapped = 0; + cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000, + (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_UNASSIGNED); + cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000, + (s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_UNASSIGNED); if (!(s->cirrus_srcptr != s->cirrus_srcptr_end) && !((s->sr[0x07] & 0x01) == 0) && !((s->gr[0x0B] & 0x14) == 0x14) && !(s->gr[0x0B] & 0x02)) { + vga_dirty_log_stop((VGAState *)s); cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000, (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM); cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000, -- cgit v1.2.3 From 5389a9df5363a683ecf8b11fdfc2e6a657d5ad5d Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 13 Mar 2009 18:11:21 +0000 Subject: temporarily disable logging around pci config writes (Avi Kivity) A pci config write may remap the vga linear frame buffer, confusing the memory slot dirty logging logic. Fixed Windows with -vga std. Signed-off-by: Avi Kivity Sigend-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6854 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/vga.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/vga.c b/hw/vga.c index 98c2234f6b..044b339161 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -2482,6 +2482,17 @@ int isa_vga_mm_init(uint8_t *vga_ram_base, return 0; } +static void pci_vga_write_config(PCIDevice *d, + uint32_t address, uint32_t val, int len) +{ + PCIVGAState *pvs = container_of(d, PCIVGAState, dev); + VGAState *s = &pvs->vga_state; + + vga_dirty_log_stop(s); + pci_default_write_config(d, address, val, len); + vga_dirty_log_start(s); +} + int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size, unsigned long vga_bios_offset, int vga_bios_size) @@ -2492,7 +2503,7 @@ int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base, d = (PCIVGAState *)pci_register_device(bus, "VGA", sizeof(PCIVGAState), - -1, NULL, NULL); + -1, NULL, pci_vga_write_config); if (!d) return -1; s = &d->vga_state; -- cgit v1.2.3 From 0e39d3f89b796dc3bc80409309c738a01d8c20d2 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 20 Mar 2009 16:18:35 +0000 Subject: x86: Add NULL check to lsl (Jan Kiszka) According to the Intel specs, lsl performs a check against NULL for the provided selector, just like lar does. helper_lar() includes the corresponding code, helper_lsl() was lacking it so far. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6866 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/op_helper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 25e079b8fd..be092637a0 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -3241,6 +3241,8 @@ target_ulong helper_lsl(target_ulong selector1) selector = selector1 & 0xffff; eflags = helper_cc_compute_all(CC_OP); + if ((selector & 0xfffc) == 0) + goto fail; if (load_segment(&e1, &e2, selector) != 0) goto fail; rpl = selector & 3; -- cgit v1.2.3 From e58843d0f117b2a30d27552b509d7cf24a0c4ba6 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 20 Mar 2009 16:18:39 +0000 Subject: e1000: Fix RX descriptor low threshold interrupt logic (Alex Williamson) The RXDMT0 interrupt is supposed to fire when the number of free RX descriptors drops to some fraction of the total descriptors. However in practice, it seems like we're adding this interrupt cause on every RX. Fix the logic to treat (tail - head) as the number of free entries rather than the number of used entries. Signed-off-by: Alex Williamson Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6867 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/e1000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index e6155d6a69..1644201d6e 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -666,8 +666,8 @@ e1000_receive(void *opaque, const uint8_t *buf, int size) n = E1000_ICS_RXT0; if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH]) rdt += s->mac_reg[RDLEN] / sizeof(desc); - if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >= - s->mac_reg[RDLEN]) + if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >> + s->rxbuf_min_shift) n |= E1000_ICS_RXDMT0; set_ics(s, 0, n); -- cgit v1.2.3 From 7c14db42cb46625283828d47bbc157548fc3a751 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 20 Mar 2009 16:18:45 +0000 Subject: virtio: Allow guest to defer VIRTIO_F_NOTIFY_ON_EMPTY (Alex Williamson) There may be cases where the guest does not want the avail queue interrupt, even when it's empty. For the virtio-net case, the guest may use a different buffering scheme or decide polling for used buffers is more efficient. This can be accomplished by simply checking for whether the guest has acknowledged the existing notify on empty flag. Signed-off-by: Alex Williamson Signed-off-by: Anthony Liguori git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6868 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/virtio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/virtio.c b/hw/virtio.c index b94ab0f054..08ea16dee5 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -726,9 +726,10 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) { - /* Always notify when queue is empty */ - if ((vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx) && - (vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT)) + /* Always notify when queue is empty (when feature acknowledge) */ + if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) && + (!(vdev->features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) || + (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) return; vdev->isr |= 0x01; -- cgit v1.2.3 From 00614a4cb462e8c9b29a5d982d2b0ffa481657c4 Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 20 Mar 2009 16:22:31 +0000 Subject: Update Changelog git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6869 c046a42c-6fe2-441c-8c8c-71466251a162 --- Changelog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Changelog b/Changelog index 9659be4efb..06bbbbf726 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,10 @@ version 0.10.1: + - virtio-net: allow masking of notifications on empty queue (Alex Williamson) + - e1000: fix rx descriptor low threshold logic (Alex Willaimson) + - x86 tcg: add NULL checks to lsl instruction (Jan Kiszka) + - kvm vga: fix screen corruption with -std-vga and Windows (Avi Kivity) + - kvm vga: fix screen corruption with Ubuntu installations (Glauber Costa) - virtio-net: check right return size on sg list (Alex Williamson) - Make qemu_announce_self handle holes (live migration after hotplug) (Marcelo Tosatti) -- cgit v1.2.3 -- cgit v1.2.3