Revisión | d35381c87483d49a56e0065dd95d49c79e146809 (tree) |
---|---|
Tiempo | 2009-03-22 08:04:14 |
Autor | aliguori <aliguori@c046...> |
Commiter | aliguori |
Add release tag for 0.10.1 release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/tags/release_0_10_1@6881 c046a42c-6fe2-441c-8c8c-71466251a162
@@ -1,3 +1,30 @@ | ||
1 | +version 0.10.1: | |
2 | + | |
3 | + - virtio-net: allow masking of notifications on empty queue (Alex Williamson) | |
4 | + - e1000: fix rx descriptor low threshold logic (Alex Willaimson) | |
5 | + - x86 tcg: add NULL checks to lsl instruction (Jan Kiszka) | |
6 | + - kvm vga: fix screen corruption with -std-vga and Windows (Avi Kivity) | |
7 | + - kvm vga: fix screen corruption with Ubuntu installations (Glauber Costa) | |
8 | + - virtio-net: check right return size on sg list (Alex Williamson) | |
9 | + - Make qemu_announce_self handle holes (live migration after hotplug) | |
10 | + (Marcelo Tosatti) | |
11 | + - Revert r6804-r6808 (qcow2 allocation info). This series of changes added | |
12 | + a high cost to startup for large qcow2 images (Anthony Liguori) | |
13 | + - qemu-img: fix help message (Aurelien Jarno) | |
14 | + - Fix build for non-default installs of SDL (Anthony Liguori) | |
15 | + - Fix race condition in env->interrupt_request. When using TCG and a dynticks | |
16 | + host timer, this condition could cause TCG to get stuck in an infinite | |
17 | + loop (Aurelien Jarno) | |
18 | + - Fix reading encrypted hard disk passwords during early startup (Jan Kiszka) | |
19 | + - Fix encrypted disk reporting in 'info block' (Jan Kiszka) | |
20 | + - Fix console size with tiny displays (MusicPal) (Jan Kiszka) | |
21 | + - Improve error handling in bdrv_open2 (Jan Kiszka) | |
22 | + - Avoid leaking data in mux'ed character devices (Jan Kiszka) | |
23 | + - Fix initial character device reset (no banner in monitor) (Jan Kiszka) | |
24 | + - Fix cpuid KVM crash on i386 host (Lubomir Rintel) | |
25 | + - Fix SLES10sp2 installation by adding ISTAT1 register to LSI SCSI emulation | |
26 | + (Ryan Harper) | |
27 | + | |
1 | 28 | version 0.10.0: |
2 | 29 | |
3 | 30 | - TCG support (No longer requires GCC 3.x) |
@@ -1 +1 @@ | ||
1 | -0.10.0 | |
1 | +0.10.1 |
@@ -143,10 +143,6 @@ typedef struct BDRVQcowState { | ||
143 | 143 | uint32_t crypt_method_header; |
144 | 144 | AES_KEY aes_encrypt_key; |
145 | 145 | AES_KEY aes_decrypt_key; |
146 | - | |
147 | - int64_t highest_alloc; /* highest cluester allocated (in clusters) */ | |
148 | - int64_t nc_free; /* num of free clusters below highest_alloc */ | |
149 | - | |
150 | 146 | uint64_t snapshots_offset; |
151 | 147 | int snapshots_size; |
152 | 148 | int nb_snapshots; |
@@ -174,8 +170,6 @@ static void free_clusters(BlockDriverState *bs, | ||
174 | 170 | #ifdef DEBUG_ALLOC |
175 | 171 | static void check_refcounts(BlockDriverState *bs); |
176 | 172 | #endif |
177 | -static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free); | |
178 | - | |
179 | 173 | |
180 | 174 | static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) |
181 | 175 | { |
@@ -276,8 +270,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags) | ||
276 | 270 | if (refcount_init(bs) < 0) |
277 | 271 | goto fail; |
278 | 272 | |
279 | - scan_refcount(bs, &s->highest_alloc, &s->nc_free); | |
280 | - | |
281 | 273 | /* read the backing file name */ |
282 | 274 | if (header.backing_file_offset != 0) { |
283 | 275 | len = header.backing_file_size; |
@@ -1646,8 +1638,6 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
1646 | 1638 | bdi->cluster_size = s->cluster_size; |
1647 | 1639 | bdi->vm_state_offset = (int64_t)s->l1_vm_state_index << |
1648 | 1640 | (s->cluster_bits + s->l2_bits); |
1649 | - bdi->highest_alloc = s->highest_alloc << s->cluster_bits; | |
1650 | - bdi->num_free_bytes = s->nc_free << s->cluster_bits; | |
1651 | 1641 | return 0; |
1652 | 1642 | } |
1653 | 1643 |
@@ -2166,39 +2156,6 @@ static int load_refcount_block(BlockDriverState *bs, | ||
2166 | 2156 | return 0; |
2167 | 2157 | } |
2168 | 2158 | |
2169 | -static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free) | |
2170 | -{ | |
2171 | - BDRVQcowState *s = bs->opaque; | |
2172 | - int64_t refcnt_index, cluster_index, cluster_end, h = 0, f = 0; | |
2173 | - int64_t tail = 0; /* do not count last consecutive free entries */ | |
2174 | - | |
2175 | - for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){ | |
2176 | - if (s->refcount_table[refcnt_index] == 0) { | |
2177 | - f += 1 << (s->cluster_bits - REFCOUNT_SHIFT); | |
2178 | - tail += 1 << (s->cluster_bits - REFCOUNT_SHIFT); | |
2179 | - continue; | |
2180 | - } | |
2181 | - cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT); | |
2182 | - cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT); | |
2183 | - for ( ; cluster_index < cluster_end; cluster_index++) { | |
2184 | - if (get_refcount(bs, cluster_index) == 0) { | |
2185 | - f++; | |
2186 | - tail++; | |
2187 | - } | |
2188 | - else { | |
2189 | - h = cluster_index; | |
2190 | - tail = 0; | |
2191 | - } | |
2192 | - } | |
2193 | - } | |
2194 | - | |
2195 | - f -= tail; | |
2196 | - if (free) | |
2197 | - *free = f; | |
2198 | - if (high) | |
2199 | - *high = (h+1); | |
2200 | -} | |
2201 | - | |
2202 | 2159 | static int get_refcount(BlockDriverState *bs, int64_t cluster_index) |
2203 | 2160 | { |
2204 | 2161 | BDRVQcowState *s = bs->opaque; |
@@ -2239,12 +2196,6 @@ retry: | ||
2239 | 2196 | size, |
2240 | 2197 | (s->free_cluster_index - nb_clusters) << s->cluster_bits); |
2241 | 2198 | #endif |
2242 | - | |
2243 | - if (s->highest_alloc < s->free_cluster_index) { | |
2244 | - s->nc_free += (s->free_cluster_index - s->highest_alloc); | |
2245 | - s->highest_alloc = s->free_cluster_index; | |
2246 | - } | |
2247 | - | |
2248 | 2199 | return (s->free_cluster_index - nb_clusters) << s->cluster_bits; |
2249 | 2200 | } |
2250 | 2201 |
@@ -2418,12 +2369,6 @@ static int update_cluster_refcount(BlockDriverState *bs, | ||
2418 | 2369 | block_index = cluster_index & |
2419 | 2370 | ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1); |
2420 | 2371 | refcount = be16_to_cpu(s->refcount_block_cache[block_index]); |
2421 | - | |
2422 | - if (refcount == 1 && addend == -1) | |
2423 | - s->nc_free += 1; | |
2424 | - else if (refcount == 0 && addend == 1) | |
2425 | - s->nc_free -= 1; | |
2426 | - | |
2427 | 2372 | refcount += addend; |
2428 | 2373 | if (refcount < 0 || refcount > 0xffff) |
2429 | 2374 | return -EINVAL; |
@@ -311,8 +311,6 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) | ||
311 | 311 | int ret; |
312 | 312 | |
313 | 313 | bs = bdrv_new(""); |
314 | - if (!bs) | |
315 | - return -ENOMEM; | |
316 | 314 | ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL); |
317 | 315 | if (ret < 0) { |
318 | 316 | bdrv_delete(bs); |
@@ -338,6 +336,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
338 | 336 | bs->read_only = 0; |
339 | 337 | bs->is_temporary = 0; |
340 | 338 | bs->encrypted = 0; |
339 | + bs->valid_key = 0; | |
341 | 340 | |
342 | 341 | if (flags & BDRV_O_SNAPSHOT) { |
343 | 342 | BlockDriverState *bs1; |
@@ -349,12 +348,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
349 | 348 | |
350 | 349 | /* if there is a backing file, use it */ |
351 | 350 | bs1 = bdrv_new(""); |
352 | - if (!bs1) { | |
353 | - return -ENOMEM; | |
354 | - } | |
355 | - if (bdrv_open(bs1, filename, 0) < 0) { | |
351 | + ret = bdrv_open(bs1, filename, 0); | |
352 | + if (ret < 0) { | |
356 | 353 | bdrv_delete(bs1); |
357 | - return -1; | |
354 | + return ret; | |
358 | 355 | } |
359 | 356 | total_size = bdrv_getlength(bs1) >> SECTOR_BITS; |
360 | 357 |
@@ -372,9 +369,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
372 | 369 | else |
373 | 370 | realpath(filename, backing_filename); |
374 | 371 | |
375 | - if (bdrv_create(&bdrv_qcow2, tmp_filename, | |
376 | - total_size, backing_filename, 0) < 0) { | |
377 | - return -1; | |
372 | + ret = bdrv_create(&bdrv_qcow2, tmp_filename, | |
373 | + total_size, backing_filename, 0); | |
374 | + if (ret < 0) { | |
375 | + return ret; | |
378 | 376 | } |
379 | 377 | filename = tmp_filename; |
380 | 378 | bs->is_temporary = 1; |
@@ -383,14 +381,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
383 | 381 | pstrcpy(bs->filename, sizeof(bs->filename), filename); |
384 | 382 | if (flags & BDRV_O_FILE) { |
385 | 383 | drv = find_protocol(filename); |
386 | - if (!drv) | |
387 | - return -ENOENT; | |
388 | - } else { | |
389 | - if (!drv) { | |
390 | - drv = find_image_format(filename); | |
391 | - if (!drv) | |
392 | - return -1; | |
393 | - } | |
384 | + } else if (!drv) { | |
385 | + drv = find_image_format(filename); | |
386 | + } | |
387 | + if (!drv) { | |
388 | + ret = -ENOENT; | |
389 | + goto unlink_and_fail; | |
394 | 390 | } |
395 | 391 | bs->drv = drv; |
396 | 392 | bs->opaque = qemu_mallocz(drv->instance_size); |
@@ -409,6 +405,9 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
409 | 405 | qemu_free(bs->opaque); |
410 | 406 | bs->opaque = NULL; |
411 | 407 | bs->drv = NULL; |
408 | + unlink_and_fail: | |
409 | + if (bs->is_temporary) | |
410 | + unlink(filename); | |
412 | 411 | return ret; |
413 | 412 | } |
414 | 413 | if (drv->bdrv_getlength) { |
@@ -422,15 +421,13 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, | ||
422 | 421 | if (bs->backing_file[0] != '\0') { |
423 | 422 | /* if there is a backing file, use it */ |
424 | 423 | bs->backing_hd = bdrv_new(""); |
425 | - if (!bs->backing_hd) { | |
426 | - fail: | |
427 | - bdrv_close(bs); | |
428 | - return -ENOMEM; | |
429 | - } | |
430 | 424 | path_combine(backing_filename, sizeof(backing_filename), |
431 | 425 | filename, bs->backing_file); |
432 | - if (bdrv_open(bs->backing_hd, backing_filename, open_flags) < 0) | |
433 | - goto fail; | |
426 | + ret = bdrv_open(bs->backing_hd, backing_filename, open_flags); | |
427 | + if (ret < 0) { | |
428 | + bdrv_close(bs); | |
429 | + return ret; | |
430 | + } | |
434 | 431 | } |
435 | 432 | |
436 | 433 | /* call the change callback */ |
@@ -970,6 +967,15 @@ int bdrv_is_encrypted(BlockDriverState *bs) | ||
970 | 967 | return bs->encrypted; |
971 | 968 | } |
972 | 969 | |
970 | +int bdrv_key_required(BlockDriverState *bs) | |
971 | +{ | |
972 | + BlockDriverState *backing_hd = bs->backing_hd; | |
973 | + | |
974 | + if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key) | |
975 | + return 1; | |
976 | + return (bs->encrypted && !bs->valid_key); | |
977 | +} | |
978 | + | |
973 | 979 | int bdrv_set_key(BlockDriverState *bs, const char *key) |
974 | 980 | { |
975 | 981 | int ret; |
@@ -982,7 +988,9 @@ int bdrv_set_key(BlockDriverState *bs, const char *key) | ||
982 | 988 | } |
983 | 989 | if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) |
984 | 990 | return -1; |
985 | - return bs->drv->bdrv_set_key(bs, key); | |
991 | + ret = bs->drv->bdrv_set_key(bs, key); | |
992 | + bs->valid_key = (ret == 0); | |
993 | + return ret; | |
986 | 994 | } |
987 | 995 | |
988 | 996 | void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) |
@@ -1015,12 +1023,12 @@ BlockDriverState *bdrv_find(const char *name) | ||
1015 | 1023 | return NULL; |
1016 | 1024 | } |
1017 | 1025 | |
1018 | -void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque) | |
1026 | +void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) | |
1019 | 1027 | { |
1020 | 1028 | BlockDriverState *bs; |
1021 | 1029 | |
1022 | 1030 | for (bs = bdrv_first; bs != NULL; bs = bs->next) { |
1023 | - it(opaque, bs->device_name); | |
1031 | + it(opaque, bs); | |
1024 | 1032 | } |
1025 | 1033 | } |
1026 | 1034 |
@@ -1105,8 +1113,7 @@ void bdrv_info(void) | ||
1105 | 1113 | } |
1106 | 1114 | term_printf(" ro=%d", bs->read_only); |
1107 | 1115 | term_printf(" drv=%s", bs->drv->format_name); |
1108 | - if (bs->encrypted) | |
1109 | - term_printf(" encrypted"); | |
1116 | + term_printf(" encrypted=%d", bdrv_is_encrypted(bs)); | |
1110 | 1117 | } else { |
1111 | 1118 | term_printf(" [not inserted]"); |
1112 | 1119 | } |
@@ -1118,7 +1125,6 @@ void bdrv_info(void) | ||
1118 | 1125 | void bdrv_info_stats (void) |
1119 | 1126 | { |
1120 | 1127 | BlockDriverState *bs; |
1121 | - BlockDriverInfo bdi; | |
1122 | 1128 | |
1123 | 1129 | for (bs = bdrv_first; bs != NULL; bs = bs->next) { |
1124 | 1130 | term_printf ("%s:" |
@@ -1126,18 +1132,23 @@ void bdrv_info_stats (void) | ||
1126 | 1132 | " wr_bytes=%" PRIu64 |
1127 | 1133 | " rd_operations=%" PRIu64 |
1128 | 1134 | " wr_operations=%" PRIu64 |
1129 | - , | |
1135 | + "\n", | |
1130 | 1136 | bs->device_name, |
1131 | 1137 | bs->rd_bytes, bs->wr_bytes, |
1132 | 1138 | bs->rd_ops, bs->wr_ops); |
1133 | - if (bdrv_get_info(bs, &bdi) == 0) | |
1134 | - term_printf(" high=%" PRId64 | |
1135 | - " bytes_free=%" PRId64, | |
1136 | - bdi.highest_alloc, bdi.num_free_bytes); | |
1137 | - term_printf("\n"); | |
1138 | 1139 | } |
1139 | 1140 | } |
1140 | 1141 | |
1142 | +const char *bdrv_get_encrypted_filename(BlockDriverState *bs) | |
1143 | +{ | |
1144 | + if (bs->backing_hd && bs->backing_hd->encrypted) | |
1145 | + return bs->backing_file; | |
1146 | + else if (bs->encrypted) | |
1147 | + return bs->filename; | |
1148 | + else | |
1149 | + return NULL; | |
1150 | +} | |
1151 | + | |
1141 | 1152 | void bdrv_get_backing_filename(BlockDriverState *bs, |
1142 | 1153 | char *filename, int filename_size) |
1143 | 1154 | { |
@@ -26,8 +26,6 @@ typedef struct BlockDriverInfo { | ||
26 | 26 | int cluster_size; |
27 | 27 | /* offset at which the VM state can be saved (0 if not possible) */ |
28 | 28 | int64_t vm_state_offset; |
29 | - int64_t highest_alloc; /* highest allocated block offset (in bytes) */ | |
30 | - int64_t num_free_bytes; /* below highest_alloc */ | |
31 | 29 | } BlockDriverInfo; |
32 | 30 | |
33 | 31 | typedef struct QEMUSnapshotInfo { |
@@ -103,8 +101,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num, | ||
103 | 101 | BlockDriverCompletionFunc *cb, void *opaque); |
104 | 102 | void bdrv_aio_cancel(BlockDriverAIOCB *acb); |
105 | 103 | |
106 | -int qemu_key_check(BlockDriverState *bs, const char *name); | |
107 | - | |
108 | 104 | /* Ensure contents are flushed to disk. */ |
109 | 105 | void bdrv_flush(BlockDriverState *bs); |
110 | 106 | void bdrv_flush_all(void); |
@@ -141,9 +137,12 @@ void bdrv_set_change_cb(BlockDriverState *bs, | ||
141 | 137 | void (*change_cb)(void *opaque), void *opaque); |
142 | 138 | void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size); |
143 | 139 | BlockDriverState *bdrv_find(const char *name); |
144 | -void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque); | |
140 | +void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), | |
141 | + void *opaque); | |
145 | 142 | int bdrv_is_encrypted(BlockDriverState *bs); |
143 | +int bdrv_key_required(BlockDriverState *bs); | |
146 | 144 | int bdrv_set_key(BlockDriverState *bs, const char *key); |
145 | +int bdrv_query_missing_keys(void); | |
147 | 146 | void bdrv_iterate_format(void (*it)(void *opaque, const char *name), |
148 | 147 | void *opaque); |
149 | 148 | const char *bdrv_get_device_name(BlockDriverState *bs); |
@@ -151,6 +150,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, | ||
151 | 150 | const uint8_t *buf, int nb_sectors); |
152 | 151 | int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); |
153 | 152 | |
153 | +const char *bdrv_get_encrypted_filename(BlockDriverState *bs); | |
154 | 154 | void bdrv_get_backing_filename(BlockDriverState *bs, |
155 | 155 | char *filename, int filename_size); |
156 | 156 | int bdrv_snapshot_create(BlockDriverState *bs, |
@@ -96,6 +96,7 @@ struct BlockDriverState { | ||
96 | 96 | int removable; /* if true, the media can be removed */ |
97 | 97 | int locked; /* if true, the media cannot temporarily be ejected */ |
98 | 98 | int encrypted; /* if true, the media is encrypted */ |
99 | + int valid_key; /* if true, a valid encryption key has been set */ | |
99 | 100 | int sg; /* if true, the device is a /dev/sg* */ |
100 | 101 | /* event callback when inserting/removing */ |
101 | 102 | void (*change_cb)(void *opaque); |
@@ -302,10 +302,9 @@ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1 | ||
302 | 302 | void term_print_filename(const char *filename); |
303 | 303 | void term_flush(void); |
304 | 304 | void term_print_help(void); |
305 | -void monitor_readline(const char *prompt, int is_password, | |
306 | - char *buf, int buf_size); | |
307 | 305 | void monitor_suspend(void); |
308 | 306 | void monitor_resume(void); |
307 | +int monitor_read_bdrv_key(BlockDriverState *bs); | |
309 | 308 | |
310 | 309 | /* readline.c */ |
311 | 310 | typedef void ReadLineFunc(void *opaque, const char *str); |
@@ -27,6 +27,7 @@ | ||
27 | 27 | #include "config.h" |
28 | 28 | #include <setjmp.h> |
29 | 29 | #include <inttypes.h> |
30 | +#include <signal.h> | |
30 | 31 | #include "osdep.h" |
31 | 32 | #include "sys-queue.h" |
32 | 33 |
@@ -170,6 +171,7 @@ typedef struct CPUWatchpoint { | ||
170 | 171 | memory was accessed */ \ |
171 | 172 | uint32_t halted; /* Nonzero if the CPU is in suspend state */ \ |
172 | 173 | uint32_t interrupt_request; \ |
174 | + volatile sig_atomic_t exit_request; \ | |
173 | 175 | /* The meaning of the MMU modes is defined in the target code. */ \ |
174 | 176 | CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \ |
175 | 177 | target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \ |
@@ -311,7 +311,7 @@ int cpu_exec(CPUState *env1) | ||
311 | 311 | env->exception_index = -1; |
312 | 312 | } |
313 | 313 | #ifdef USE_KQEMU |
314 | - if (kqemu_is_ok(env) && env->interrupt_request == 0) { | |
314 | + if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) { | |
315 | 315 | int ret; |
316 | 316 | env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); |
317 | 317 | ret = kqemu_cpu_exec(env); |
@@ -326,7 +326,7 @@ int cpu_exec(CPUState *env1) | ||
326 | 326 | } else if (ret == 2) { |
327 | 327 | /* softmmu execution needed */ |
328 | 328 | } else { |
329 | - if (env->interrupt_request != 0) { | |
329 | + if (env->interrupt_request != 0 || env->exit_request != 0) { | |
330 | 330 | /* hardware interrupt will be executed just after */ |
331 | 331 | } else { |
332 | 332 | /* otherwise, we restart */ |
@@ -525,11 +525,11 @@ int cpu_exec(CPUState *env1) | ||
525 | 525 | the program flow was changed */ |
526 | 526 | next_tb = 0; |
527 | 527 | } |
528 | - if (interrupt_request & CPU_INTERRUPT_EXIT) { | |
529 | - env->interrupt_request &= ~CPU_INTERRUPT_EXIT; | |
530 | - env->exception_index = EXCP_INTERRUPT; | |
531 | - cpu_loop_exit(); | |
532 | - } | |
528 | + } | |
529 | + if (unlikely(env->exit_request)) { | |
530 | + env->exit_request = 0; | |
531 | + env->exception_index = EXCP_INTERRUPT; | |
532 | + cpu_loop_exit(); | |
533 | 533 | } |
534 | 534 | #ifdef DEBUG_EXEC |
535 | 535 | if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { |
@@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1) | ||
599 | 599 | TB, but before it is linked into a potentially |
600 | 600 | infinite loop and becomes env->current_tb. Avoid |
601 | 601 | starting execution if there is a pending interrupt. */ |
602 | - if (unlikely (env->interrupt_request & CPU_INTERRUPT_EXIT)) | |
602 | + if (unlikely (env->exit_request)) | |
603 | 603 | env->current_tb = NULL; |
604 | 604 | |
605 | 605 | while (env->current_tb) { |
@@ -523,6 +523,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id) | ||
523 | 523 | |
524 | 524 | qemu_get_be32s(f, &env->halted); |
525 | 525 | qemu_get_be32s(f, &env->interrupt_request); |
526 | + env->interrupt_request &= ~CPU_INTERRUPT_EXIT; | |
526 | 527 | tlb_flush(env, 1); |
527 | 528 | |
528 | 529 | return 0; |
@@ -1501,9 +1502,12 @@ void cpu_interrupt(CPUState *env, int mask) | ||
1501 | 1502 | #endif |
1502 | 1503 | int old_mask; |
1503 | 1504 | |
1505 | + if (mask & CPU_INTERRUPT_EXIT) { | |
1506 | + env->exit_request = 1; | |
1507 | + mask &= ~CPU_INTERRUPT_EXIT; | |
1508 | + } | |
1509 | + | |
1504 | 1510 | old_mask = env->interrupt_request; |
1505 | - /* FIXME: This is probably not threadsafe. A different thread could | |
1506 | - be in the middle of a read-modify-write operation. */ | |
1507 | 1511 | env->interrupt_request |= mask; |
1508 | 1512 | #if defined(USE_NPTL) |
1509 | 1513 | /* FIXME: TB unchaining isn't SMP safe. For now just ignore the |
@@ -1514,10 +1518,8 @@ void cpu_interrupt(CPUState *env, int mask) | ||
1514 | 1518 | if (use_icount) { |
1515 | 1519 | env->icount_decr.u16.high = 0xffff; |
1516 | 1520 | #ifndef CONFIG_USER_ONLY |
1517 | - /* CPU_INTERRUPT_EXIT isn't a real interrupt. It just means | |
1518 | - an async event happened and we need to process it. */ | |
1519 | 1521 | if (!can_do_io(env) |
1520 | - && (mask & ~(old_mask | CPU_INTERRUPT_EXIT)) != 0) { | |
1522 | + && (mask & ~old_mask) != 0) { | |
1521 | 1523 | cpu_abort(env, "Raised interrupt while not in I/O function"); |
1522 | 1524 | } |
1523 | 1525 | #endif |
@@ -2637,11 +2637,16 @@ static void map_linear_vram(CirrusVGAState *s) | ||
2637 | 2637 | |
2638 | 2638 | s->lfb_vram_mapped = 0; |
2639 | 2639 | |
2640 | + cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000, | |
2641 | + (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_UNASSIGNED); | |
2642 | + cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000, | |
2643 | + (s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_UNASSIGNED); | |
2640 | 2644 | if (!(s->cirrus_srcptr != s->cirrus_srcptr_end) |
2641 | 2645 | && !((s->sr[0x07] & 0x01) == 0) |
2642 | 2646 | && !((s->gr[0x0B] & 0x14) == 0x14) |
2643 | 2647 | && !(s->gr[0x0B] & 0x02)) { |
2644 | 2648 | |
2649 | + vga_dirty_log_stop((VGAState *)s); | |
2645 | 2650 | cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000, |
2646 | 2651 | (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM); |
2647 | 2652 | cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000, |
@@ -666,8 +666,8 @@ e1000_receive(void *opaque, const uint8_t *buf, int size) | ||
666 | 666 | n = E1000_ICS_RXT0; |
667 | 667 | if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH]) |
668 | 668 | rdt += s->mac_reg[RDLEN] / sizeof(desc); |
669 | - if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >= | |
670 | - s->mac_reg[RDLEN]) | |
669 | + if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >> | |
670 | + s->rxbuf_min_shift) | |
671 | 671 | n |= E1000_ICS_RXDMT0; |
672 | 672 | |
673 | 673 | set_ics(s, 0, n); |
@@ -1369,6 +1369,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) | ||
1369 | 1369 | CASE_GET_REG32(dsa, 0x10) |
1370 | 1370 | case 0x14: /* ISTAT0 */ |
1371 | 1371 | return s->istat0; |
1372 | + case 0x15: /* ISTAT1 */ | |
1373 | + return s->istat1; | |
1372 | 1374 | case 0x16: /* MBOX0 */ |
1373 | 1375 | return s->mbox0; |
1374 | 1376 | case 0x17: /* MBOX1 */ |
@@ -11,6 +11,7 @@ | ||
11 | 11 | #include "usb.h" |
12 | 12 | #include "block.h" |
13 | 13 | #include "scsi-disk.h" |
14 | +#include "console.h" | |
14 | 15 | |
15 | 16 | //#define DEBUG_MSD |
16 | 17 |
@@ -513,7 +514,7 @@ static void usb_msd_handle_destroy(USBDevice *dev) | ||
513 | 514 | qemu_free(s); |
514 | 515 | } |
515 | 516 | |
516 | -USBDevice *usb_msd_init(const char *filename) | |
517 | +USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs) | |
517 | 518 | { |
518 | 519 | MSDState *s; |
519 | 520 | BlockDriverState *bdrv; |
@@ -552,9 +553,8 @@ USBDevice *usb_msd_init(const char *filename) | ||
552 | 553 | bdrv = bdrv_new("usb"); |
553 | 554 | if (bdrv_open2(bdrv, filename, 0, drv) < 0) |
554 | 555 | goto fail; |
555 | - if (qemu_key_check(bdrv, filename)) | |
556 | - goto fail; | |
557 | 556 | s->bs = bdrv; |
557 | + *pbs = bdrv; | |
558 | 558 | |
559 | 559 | s->dev.speed = USB_SPEED_FULL; |
560 | 560 | s->dev.handle_packet = usb_generic_handle_packet; |
@@ -21,6 +21,9 @@ | ||
21 | 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
22 | 22 | * THE SOFTWARE. |
23 | 23 | */ |
24 | + | |
25 | +#include "block.h" | |
26 | + | |
24 | 27 | #define USB_TOKEN_SETUP 0x2d |
25 | 28 | #define USB_TOKEN_IN 0x69 /* device -> host */ |
26 | 29 | #define USB_TOKEN_OUT 0xe1 /* host -> device */ |
@@ -250,7 +253,7 @@ USBDevice *usb_keyboard_init(void); | ||
250 | 253 | void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); |
251 | 254 | |
252 | 255 | /* usb-msd.c */ |
253 | -USBDevice *usb_msd_init(const char *filename); | |
256 | +USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs); | |
254 | 257 | |
255 | 258 | /* usb-net.c */ |
256 | 259 | USBDevice *usb_net_init(NICInfo *nd); |
@@ -2482,6 +2482,17 @@ int isa_vga_mm_init(uint8_t *vga_ram_base, | ||
2482 | 2482 | return 0; |
2483 | 2483 | } |
2484 | 2484 | |
2485 | +static void pci_vga_write_config(PCIDevice *d, | |
2486 | + uint32_t address, uint32_t val, int len) | |
2487 | +{ | |
2488 | + PCIVGAState *pvs = container_of(d, PCIVGAState, dev); | |
2489 | + VGAState *s = &pvs->vga_state; | |
2490 | + | |
2491 | + vga_dirty_log_stop(s); | |
2492 | + pci_default_write_config(d, address, val, len); | |
2493 | + vga_dirty_log_start(s); | |
2494 | +} | |
2495 | + | |
2485 | 2496 | int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base, |
2486 | 2497 | unsigned long vga_ram_offset, int vga_ram_size, |
2487 | 2498 | unsigned long vga_bios_offset, int vga_bios_size) |
@@ -2492,7 +2503,7 @@ int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base, | ||
2492 | 2503 | |
2493 | 2504 | d = (PCIVGAState *)pci_register_device(bus, "VGA", |
2494 | 2505 | sizeof(PCIVGAState), |
2495 | - -1, NULL, NULL); | |
2506 | + -1, NULL, pci_vga_write_config); | |
2496 | 2507 | if (!d) |
2497 | 2508 | return -1; |
2498 | 2509 | s = &d->vga_state; |
@@ -228,7 +228,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) | ||
228 | 228 | } |
229 | 229 | |
230 | 230 | if (elem.out_sg[0].iov_len < sizeof(ctrl) || |
231 | - elem.out_sg[elem.in_num - 1].iov_len < sizeof(status)) { | |
231 | + elem.in_sg[elem.in_num - 1].iov_len < sizeof(status)) { | |
232 | 232 | fprintf(stderr, "virtio-net ctrl header not in correct element\n"); |
233 | 233 | exit(1); |
234 | 234 | } |
@@ -726,9 +726,10 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, | ||
726 | 726 | |
727 | 727 | void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) |
728 | 728 | { |
729 | - /* Always notify when queue is empty */ | |
730 | - if ((vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx) && | |
731 | - (vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT)) | |
729 | + /* Always notify when queue is empty (when feature acknowledge) */ | |
730 | + if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) && | |
731 | + (!(vdev->features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) || | |
732 | + (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) | |
732 | 733 | return; |
733 | 734 | |
734 | 735 | vdev->isr |= 0x01; |
@@ -445,7 +445,7 @@ int kvm_cpu_exec(CPUState *env) | ||
445 | 445 | do { |
446 | 446 | kvm_arch_pre_run(env, run); |
447 | 447 | |
448 | - if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) { | |
448 | + if (env->exit_request) { | |
449 | 449 | dprintf("interrupt exit requested\n"); |
450 | 450 | ret = 0; |
451 | 451 | break; |
@@ -512,8 +512,8 @@ int kvm_cpu_exec(CPUState *env) | ||
512 | 512 | } |
513 | 513 | } while (ret > 0); |
514 | 514 | |
515 | - if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) { | |
516 | - env->interrupt_request &= ~CPU_INTERRUPT_EXIT; | |
515 | + if (env->exit_request) { | |
516 | + env->exit_request = 0; | |
517 | 517 | env->exception_index = EXCP_INTERRUPT; |
518 | 518 | } |
519 | 519 |
@@ -76,6 +76,8 @@ static uint8_t term_outbuf[1024]; | ||
76 | 76 | static int term_outbuf_index; |
77 | 77 | |
78 | 78 | static void monitor_start_input(void); |
79 | +static void monitor_readline(const char *prompt, int is_password, | |
80 | + char *buf, int buf_size); | |
79 | 81 | |
80 | 82 | static CPUState *mon_cpu = NULL; |
81 | 83 |
@@ -433,7 +435,7 @@ static void do_change_block(const char *device, const char *filename, const char | ||
433 | 435 | if (eject_device(bs, 0) < 0) |
434 | 436 | return; |
435 | 437 | bdrv_open2(bs, filename, 0, drv); |
436 | - qemu_key_check(bs, filename); | |
438 | + monitor_read_bdrv_key(bs); | |
437 | 439 | } |
438 | 440 | |
439 | 441 | static void do_change_vnc(const char *target, const char *arg) |
@@ -494,9 +496,24 @@ static void do_stop(void) | ||
494 | 496 | vm_stop(EXCP_INTERRUPT); |
495 | 497 | } |
496 | 498 | |
499 | +static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs) | |
500 | +{ | |
501 | + int *err = opaque; | |
502 | + | |
503 | + if (bdrv_key_required(bs)) | |
504 | + *err = monitor_read_bdrv_key(bs); | |
505 | + else | |
506 | + *err = 0; | |
507 | +} | |
508 | + | |
497 | 509 | static void do_cont(void) |
498 | 510 | { |
499 | - vm_start(); | |
511 | + int err = 0; | |
512 | + | |
513 | + bdrv_iterate(encrypted_bdrv_it, &err); | |
514 | + /* only resume the vm if all keys are set and valid */ | |
515 | + if (!err) | |
516 | + vm_start(); | |
500 | 517 | } |
501 | 518 | |
502 | 519 | #ifdef CONFIG_GDBSTUB |
@@ -2679,8 +2696,9 @@ static void file_completion(const char *input) | ||
2679 | 2696 | closedir(ffs); |
2680 | 2697 | } |
2681 | 2698 | |
2682 | -static void block_completion_it(void *opaque, const char *name) | |
2699 | +static void block_completion_it(void *opaque, BlockDriverState *bs) | |
2683 | 2700 | { |
2701 | + const char *name = bdrv_get_device_name(bs); | |
2684 | 2702 | const char *input = opaque; |
2685 | 2703 | |
2686 | 2704 | if (input[0] == '\0' || |
@@ -2891,8 +2909,8 @@ static void monitor_readline_cb(void *opaque, const char *input) | ||
2891 | 2909 | monitor_readline_started = 0; |
2892 | 2910 | } |
2893 | 2911 | |
2894 | -void monitor_readline(const char *prompt, int is_password, | |
2895 | - char *buf, int buf_size) | |
2912 | +static void monitor_readline(const char *prompt, int is_password, | |
2913 | + char *buf, int buf_size) | |
2896 | 2914 | { |
2897 | 2915 | int i; |
2898 | 2916 | int old_focus[MAX_MON]; |
@@ -2922,3 +2940,22 @@ void monitor_readline(const char *prompt, int is_password, | ||
2922 | 2940 | monitor_hd[i]->focus = old_focus[i]; |
2923 | 2941 | } |
2924 | 2942 | } |
2943 | + | |
2944 | +int monitor_read_bdrv_key(BlockDriverState *bs) | |
2945 | +{ | |
2946 | + char password[256]; | |
2947 | + int i; | |
2948 | + | |
2949 | + if (!bdrv_is_encrypted(bs)) | |
2950 | + return 0; | |
2951 | + | |
2952 | + term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs), | |
2953 | + bdrv_get_encrypted_filename(bs)); | |
2954 | + for(i = 0; i < 3; i++) { | |
2955 | + monitor_readline("Password: ", 1, password, sizeof(password)); | |
2956 | + if (bdrv_set_key(bs, password) == 0) | |
2957 | + return 0; | |
2958 | + term_printf("invalid password\n"); | |
2959 | + } | |
2960 | + return -EPERM; | |
2961 | +} |
@@ -101,6 +101,10 @@ | ||
101 | 101 | /***********************************************************/ |
102 | 102 | /* character device */ |
103 | 103 | |
104 | +static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = | |
105 | + TAILQ_HEAD_INITIALIZER(chardevs); | |
106 | +static int initial_reset_issued; | |
107 | + | |
104 | 108 | static void qemu_chr_event(CharDriverState *s, int event) |
105 | 109 | { |
106 | 110 | if (!s->chr_event) |
@@ -118,12 +122,23 @@ static void qemu_chr_reset_bh(void *opaque) | ||
118 | 122 | |
119 | 123 | void qemu_chr_reset(CharDriverState *s) |
120 | 124 | { |
121 | - if (s->bh == NULL) { | |
125 | + if (s->bh == NULL && initial_reset_issued) { | |
122 | 126 | s->bh = qemu_bh_new(qemu_chr_reset_bh, s); |
123 | 127 | qemu_bh_schedule(s->bh); |
124 | 128 | } |
125 | 129 | } |
126 | 130 | |
131 | +void qemu_chr_initial_reset(void) | |
132 | +{ | |
133 | + CharDriverState *chr; | |
134 | + | |
135 | + initial_reset_issued = 1; | |
136 | + | |
137 | + TAILQ_FOREACH(chr, &chardevs, next) { | |
138 | + qemu_chr_reset(chr); | |
139 | + } | |
140 | +} | |
141 | + | |
127 | 142 | int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len) |
128 | 143 | { |
129 | 144 | return s->chr_write(s, buf, len); |
@@ -210,12 +225,15 @@ typedef struct { | ||
210 | 225 | IOEventHandler *chr_event[MAX_MUX]; |
211 | 226 | void *ext_opaque[MAX_MUX]; |
212 | 227 | CharDriverState *drv; |
213 | - unsigned char buffer[MUX_BUFFER_SIZE]; | |
214 | - int prod; | |
215 | - int cons; | |
216 | 228 | int mux_cnt; |
217 | 229 | int term_got_escape; |
218 | 230 | int max_size; |
231 | + /* Intermediate input buffer allows to catch escape sequences even if the | |
232 | + currently active device is not accepting any input - but only until it | |
233 | + is full as well. */ | |
234 | + unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE]; | |
235 | + int prod[MAX_MUX]; | |
236 | + int cons[MAX_MUX]; | |
219 | 237 | } MuxDriver; |
220 | 238 | |
221 | 239 |
@@ -345,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr) | ||
345 | 363 | int m = chr->focus; |
346 | 364 | MuxDriver *d = chr->opaque; |
347 | 365 | |
348 | - while (d->prod != d->cons && | |
366 | + while (d->prod[m] != d->cons[m] && | |
349 | 367 | d->chr_can_read[m] && |
350 | 368 | d->chr_can_read[m](d->ext_opaque[m])) { |
351 | 369 | d->chr_read[m](d->ext_opaque[m], |
352 | - &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1); | |
370 | + &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1); | |
353 | 371 | } |
354 | 372 | } |
355 | 373 |
@@ -357,11 +375,12 @@ static int mux_chr_can_read(void *opaque) | ||
357 | 375 | { |
358 | 376 | CharDriverState *chr = opaque; |
359 | 377 | MuxDriver *d = chr->opaque; |
378 | + int m = chr->focus; | |
360 | 379 | |
361 | - if ((d->prod - d->cons) < MUX_BUFFER_SIZE) | |
380 | + if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE) | |
362 | 381 | return 1; |
363 | - if (d->chr_can_read[chr->focus]) | |
364 | - return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]); | |
382 | + if (d->chr_can_read[m]) | |
383 | + return d->chr_can_read[m](d->ext_opaque[m]); | |
365 | 384 | return 0; |
366 | 385 | } |
367 | 386 |
@@ -376,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size) | ||
376 | 395 | |
377 | 396 | for(i = 0; i < size; i++) |
378 | 397 | if (mux_proc_byte(chr, d, buf[i])) { |
379 | - if (d->prod == d->cons && | |
398 | + if (d->prod[m] == d->cons[m] && | |
380 | 399 | d->chr_can_read[m] && |
381 | 400 | d->chr_can_read[m](d->ext_opaque[m])) |
382 | 401 | d->chr_read[m](d->ext_opaque[m], &buf[i], 1); |
383 | 402 | else |
384 | - d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i]; | |
403 | + d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i]; | |
385 | 404 | } |
386 | 405 | } |
387 | 406 |
@@ -2076,9 +2095,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, | ||
2076 | 2095 | return NULL; |
2077 | 2096 | } |
2078 | 2097 | |
2079 | -static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs | |
2080 | -= TAILQ_HEAD_INITIALIZER(chardevs); | |
2081 | - | |
2082 | 2098 | CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) |
2083 | 2099 | { |
2084 | 2100 | const char *p; |
@@ -74,6 +74,7 @@ void qemu_chr_add_handlers(CharDriverState *s, | ||
74 | 74 | void *opaque); |
75 | 75 | int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); |
76 | 76 | void qemu_chr_reset(CharDriverState *s); |
77 | +void qemu_chr_initial_reset(void); | |
77 | 78 | int qemu_chr_can_read(CharDriverState *s); |
78 | 79 | void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); |
79 | 80 | void qemu_chr_accept_input(CharDriverState *s); |
@@ -74,8 +74,8 @@ static void help(void) | ||
74 | 74 | " differ\n" |
75 | 75 | " 'fmt' is the disk image format. It is guessed automatically in most cases\n" |
76 | 76 | " 'size' is the disk image size in kilobytes. Optional suffixes\n" |
77 | - " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are" | |
78 | - " supported any @code{k} or @code{K} is ignored\n" | |
77 | + " 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n" | |
78 | + " supported any 'k' or 'K' is ignored\n" | |
79 | 79 | " 'output_filename' is the destination disk image filename\n" |
80 | 80 | " 'output_fmt' is the destination format\n" |
81 | 81 | " '-c' indicates that target image must be compressed (qcow format only)\n" |
@@ -730,10 +730,6 @@ static int img_info(int argc, char **argv) | ||
730 | 730 | if (bdrv_get_info(bs, &bdi) >= 0) { |
731 | 731 | if (bdi.cluster_size != 0) |
732 | 732 | printf("cluster_size: %d\n", bdi.cluster_size); |
733 | - if (bdi.highest_alloc) | |
734 | - printf("highest_alloc: %" PRId64 "\n", bdi.highest_alloc); | |
735 | - if (bdi.num_free_bytes) | |
736 | - printf("num_free_bytes: %" PRId64 "\n", bdi.num_free_bytes); | |
737 | 733 | } |
738 | 734 | bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); |
739 | 735 | if (backing_filename[0] != '\0') { |
@@ -118,7 +118,9 @@ void qemu_announce_self(void) | ||
118 | 118 | VLANClientState *vc; |
119 | 119 | uint8_t buf[256]; |
120 | 120 | |
121 | - for (i = 0; i < nb_nics; i++) { | |
121 | + for (i = 0; i < MAX_NICS; i++) { | |
122 | + if (!nd_table[i].used) | |
123 | + continue; | |
122 | 124 | len = announce_self_create(buf, nd_table[i].macaddr); |
123 | 125 | vlan = nd_table[i].vlan; |
124 | 126 | for(vc = vlan->first_client; vc != NULL; vc = vc->next) { |
@@ -27,7 +27,7 @@ | ||
27 | 27 | #include "x_keymap.h" |
28 | 28 | |
29 | 29 | #include <SDL.h> |
30 | -#include <SDL/SDL_syswm.h> | |
30 | +#include <SDL_syswm.h> | |
31 | 31 | |
32 | 32 | #ifndef _WIN32 |
33 | 33 | #include <signal.h> |
@@ -1421,10 +1421,10 @@ static void host_cpuid(uint32_t function, uint32_t count, | ||
1421 | 1421 | #else |
1422 | 1422 | asm volatile("pusha \n\t" |
1423 | 1423 | "cpuid \n\t" |
1424 | - "mov %%eax, 0(%1) \n\t" | |
1425 | - "mov %%ebx, 4(%1) \n\t" | |
1426 | - "mov %%ecx, 8(%1) \n\t" | |
1427 | - "mov %%edx, 12(%1) \n\t" | |
1424 | + "mov %%eax, 0(%2) \n\t" | |
1425 | + "mov %%ebx, 4(%2) \n\t" | |
1426 | + "mov %%ecx, 8(%2) \n\t" | |
1427 | + "mov %%edx, 12(%2) \n\t" | |
1428 | 1428 | "popa" |
1429 | 1429 | : : "a"(function), "c"(count), "S"(vec) |
1430 | 1430 | : "memory", "cc"); |
@@ -3241,6 +3241,8 @@ target_ulong helper_lsl(target_ulong selector1) | ||
3241 | 3241 | |
3242 | 3242 | selector = selector1 & 0xffff; |
3243 | 3243 | eflags = helper_cc_compute_all(CC_OP); |
3244 | + if ((selector & 0xfffc) == 0) | |
3245 | + goto fail; | |
3244 | 3246 | if (load_segment(&e1, &e2, selector) != 0) |
3245 | 3247 | goto fail; |
3246 | 3248 | rpl = selector & 3; |
@@ -201,6 +201,7 @@ ram_addr_t ram_size; | ||
201 | 201 | int nb_nics; |
202 | 202 | NICInfo nd_table[MAX_NICS]; |
203 | 203 | int vm_running; |
204 | +static int autostart; | |
204 | 205 | static int rtc_utc = 1; |
205 | 206 | static int rtc_date_offset = -1; /* -1 means no change */ |
206 | 207 | int cirrus_vga_enabled = 1; |
@@ -2607,11 +2608,13 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque) | ||
2607 | 2608 | bdrv_flags |= BDRV_O_CACHE_WB; |
2608 | 2609 | else if (cache == 3) /* not specified */ |
2609 | 2610 | bdrv_flags |= BDRV_O_CACHE_DEF; |
2610 | - if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) { | |
2611 | + if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) { | |
2611 | 2612 | fprintf(stderr, "qemu: could not open disk image %s\n", |
2612 | 2613 | file); |
2613 | 2614 | return -1; |
2614 | 2615 | } |
2616 | + if (bdrv_key_required(bdrv)) | |
2617 | + autostart = 0; | |
2615 | 2618 | return drives_table_idx; |
2616 | 2619 | } |
2617 | 2620 |
@@ -2658,7 +2661,7 @@ int usb_device_add_dev(USBDevice *dev) | ||
2658 | 2661 | return 0; |
2659 | 2662 | } |
2660 | 2663 | |
2661 | -static int usb_device_add(const char *devname) | |
2664 | +static int usb_device_add(const char *devname, int is_hotplug) | |
2662 | 2665 | { |
2663 | 2666 | const char *p; |
2664 | 2667 | USBDevice *dev; |
@@ -2675,7 +2678,18 @@ static int usb_device_add(const char *devname) | ||
2675 | 2678 | } else if (!strcmp(devname, "keyboard")) { |
2676 | 2679 | dev = usb_keyboard_init(); |
2677 | 2680 | } else if (strstart(devname, "disk:", &p)) { |
2678 | - dev = usb_msd_init(p); | |
2681 | + BlockDriverState *bs; | |
2682 | + | |
2683 | + dev = usb_msd_init(p, &bs); | |
2684 | + if (!dev) | |
2685 | + return -1; | |
2686 | + if (bdrv_key_required(bs)) { | |
2687 | + autostart = 0; | |
2688 | + if (is_hotplug && monitor_read_bdrv_key(bs) < 0) { | |
2689 | + dev->handle_destroy(dev); | |
2690 | + return -1; | |
2691 | + } | |
2692 | + } | |
2679 | 2693 | } else if (!strcmp(devname, "wacom-tablet")) { |
2680 | 2694 | dev = usb_wacom_init(); |
2681 | 2695 | } else if (strstart(devname, "serial:", &p)) { |
@@ -2756,7 +2770,7 @@ static int usb_device_del(const char *devname) | ||
2756 | 2770 | |
2757 | 2771 | void do_usb_add(const char *devname) |
2758 | 2772 | { |
2759 | - usb_device_add(devname); | |
2773 | + usb_device_add(devname, 1); | |
2760 | 2774 | } |
2761 | 2775 | |
2762 | 2776 | void do_usb_del(const char *devname) |
@@ -4334,45 +4348,6 @@ static const QEMUOption qemu_options[] = { | ||
4334 | 4348 | { NULL }, |
4335 | 4349 | }; |
4336 | 4350 | |
4337 | -/* password input */ | |
4338 | - | |
4339 | -int qemu_key_check(BlockDriverState *bs, const char *name) | |
4340 | -{ | |
4341 | - char password[256]; | |
4342 | - int i; | |
4343 | - | |
4344 | - if (!bdrv_is_encrypted(bs)) | |
4345 | - return 0; | |
4346 | - | |
4347 | - term_printf("%s is encrypted.\n", name); | |
4348 | - for(i = 0; i < 3; i++) { | |
4349 | - monitor_readline("Password: ", 1, password, sizeof(password)); | |
4350 | - if (bdrv_set_key(bs, password) == 0) | |
4351 | - return 0; | |
4352 | - term_printf("invalid password\n"); | |
4353 | - } | |
4354 | - return -EPERM; | |
4355 | -} | |
4356 | - | |
4357 | -static BlockDriverState *get_bdrv(int index) | |
4358 | -{ | |
4359 | - if (index > nb_drives) | |
4360 | - return NULL; | |
4361 | - return drives_table[index].bdrv; | |
4362 | -} | |
4363 | - | |
4364 | -static void read_passwords(void) | |
4365 | -{ | |
4366 | - BlockDriverState *bs; | |
4367 | - int i; | |
4368 | - | |
4369 | - for(i = 0; i < 6; i++) { | |
4370 | - bs = get_bdrv(i); | |
4371 | - if (bs) | |
4372 | - qemu_key_check(bs, bdrv_get_device_name(bs)); | |
4373 | - } | |
4374 | -} | |
4375 | - | |
4376 | 4351 | #ifdef HAS_AUDIO |
4377 | 4352 | struct soundhw soundhw[] = { |
4378 | 4353 | #ifdef HAS_AUDIO_CHOICE |
@@ -4639,7 +4614,6 @@ int main(int argc, char **argv, char **envp) | ||
4639 | 4614 | int fds[2]; |
4640 | 4615 | int tb_size; |
4641 | 4616 | const char *pid_file = NULL; |
4642 | - int autostart; | |
4643 | 4617 | const char *incoming = NULL; |
4644 | 4618 | int fd = 0; |
4645 | 4619 | struct passwd *pwd = NULL; |
@@ -4696,7 +4670,7 @@ int main(int argc, char **argv, char **envp) | ||
4696 | 4670 | kernel_cmdline = ""; |
4697 | 4671 | cyls = heads = secs = 0; |
4698 | 4672 | translation = BIOS_ATA_TRANSLATION_AUTO; |
4699 | - monitor_device = "vc"; | |
4673 | + monitor_device = "vc:80Cx24C"; | |
4700 | 4674 | |
4701 | 4675 | serial_devices[0] = "vc:80Cx24C"; |
4702 | 4676 | for(i = 1; i < MAX_SERIAL_PORTS; i++) |
@@ -5637,7 +5611,7 @@ int main(int argc, char **argv, char **envp) | ||
5637 | 5611 | /* init USB devices */ |
5638 | 5612 | if (usb_enabled) { |
5639 | 5613 | for(i = 0; i < usb_devices_index; i++) { |
5640 | - if (usb_device_add(usb_devices[i]) < 0) { | |
5614 | + if (usb_device_add(usb_devices[i], 0) < 0) { | |
5641 | 5615 | fprintf(stderr, "Warning: could not add USB device %s\n", |
5642 | 5616 | usb_devices[i]); |
5643 | 5617 | } |
@@ -5693,6 +5667,7 @@ int main(int argc, char **argv, char **envp) | ||
5693 | 5667 | } |
5694 | 5668 | |
5695 | 5669 | text_consoles_set_display(display_state); |
5670 | + qemu_chr_initial_reset(); | |
5696 | 5671 | |
5697 | 5672 | if (monitor_device && monitor_hd) |
5698 | 5673 | monitor_init(monitor_hd, !nographic); |
@@ -5747,13 +5722,8 @@ int main(int argc, char **argv, char **envp) | ||
5747 | 5722 | qemu_start_incoming_migration(incoming); |
5748 | 5723 | } |
5749 | 5724 | |
5750 | - { | |
5751 | - /* XXX: simplify init */ | |
5752 | - read_passwords(); | |
5753 | - if (autostart) { | |
5754 | - vm_start(); | |
5755 | - } | |
5756 | - } | |
5725 | + if (autostart) | |
5726 | + vm_start(); | |
5757 | 5727 | |
5758 | 5728 | if (daemonize) { |
5759 | 5729 | uint8_t status = 0; |