Compare commits
102 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c2b0926634 | ||
|
b316937d38 | ||
|
5b5c7bf8e5 | ||
|
6df8cd2e27 | ||
|
ff2fff6211 | ||
|
83a66746c0 | ||
|
39639d81e3 | ||
|
6e64c4e6f1 | ||
|
73c1527f96 | ||
|
b466e1731b | ||
|
6a47ae2d41 | ||
|
5f0681e1c3 | ||
|
75eb0f5dbb | ||
|
b495764ae8 | ||
|
21640bf6e0 | ||
|
6bbb939a80 | ||
|
178ed9aad3 | ||
|
0505d48c83 | ||
|
0073781fea | ||
|
175117c159 | ||
|
aa58eedb35 | ||
|
e6c172ad9e | ||
|
07ede68671 | ||
|
2fbad1f944 | ||
|
dee284885a | ||
|
ad0983b5d1 | ||
|
b3729b2ec2 | ||
|
1b9ea8961a | ||
|
cdeb85cf24 | ||
|
b28d7b585a | ||
|
cd2f44cc3e | ||
|
844470158c | ||
|
05c5febf8c | ||
|
de98dc9539 | ||
|
0c80570170 | ||
|
14b51b6718 | ||
|
ea227e222b | ||
|
aae114b7ed | ||
|
cfa86bcb7d | ||
|
b57b7ec340 | ||
|
f8c61ebdd2 | ||
|
c448fb7651 | ||
|
8239a583c1 | ||
|
cb91dce13e | ||
|
b2f1d90530 | ||
|
5a6af97243 | ||
|
90de7a03bb | ||
|
57248587af | ||
|
ff830f9d88 | ||
|
82e8913341 | ||
|
38e6e1c6a3 | ||
|
4bcf40b288 | ||
|
8bf7738ff2 | ||
|
8100812711 | ||
|
cf0276b7c0 | ||
|
b5ad76a709 | ||
|
20dc758b7f | ||
|
0077793a00 | ||
|
c4164eae39 | ||
|
8c64b47eeb | ||
|
aa383e9a83 | ||
|
f06c87b119 | ||
|
eb5388e260 | ||
|
83f81f344f | ||
|
b6bd501d6a | ||
|
0369529b37 | ||
|
c29bf825ee | ||
|
e2d402d0a1 | ||
|
4d492e8909 | ||
|
45c46f20c6 | ||
|
c4379ce8ef | ||
|
a95569d24f | ||
|
15905fde7b | ||
|
f1a842948a | ||
|
09d552b40f | ||
|
d754428b9b | ||
|
5d350980f6 | ||
|
ff1f973003 | ||
|
0b2d2e094a | ||
|
4a58f3c2d8 | ||
|
96c6cf6d30 | ||
|
b5fc105016 | ||
|
e1cf5a23d1 | ||
|
490a0f887e | ||
|
e4fb3debc3 | ||
|
7fb768ea30 | ||
|
2151206778 | ||
|
c35ba0d9e4 | ||
|
61048e1942 | ||
|
a9ed61533f | ||
|
3807aeb1d4 | ||
|
ff3bd5e4bb | ||
|
d6af26d6ce | ||
|
8bb90ee80a | ||
|
562d6b4f7f | ||
|
9a72433843 | ||
|
00dd2b22f6 | ||
|
80f4d021f0 | ||
|
074e347138 | ||
|
9e8d994111 | ||
|
a56b9cfd86 | ||
|
07178559a9 |
@@ -191,9 +191,9 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
|
||||
audio_detach_capture (hw);
|
||||
#endif
|
||||
QLIST_REMOVE (hw, entries);
|
||||
glue (hw->pcm_ops->fini_, TYPE) (hw);
|
||||
glue (s->nb_hw_voices_, TYPE) += 1;
|
||||
glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
|
||||
glue (hw->pcm_ops->fini_, TYPE) (hw);
|
||||
g_free (hw);
|
||||
*hwp = NULL;
|
||||
}
|
||||
|
@@ -169,6 +169,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
|
||||
if (b->opened) {
|
||||
error_set(errp, QERR_PERMISSION_DENIED);
|
||||
} else {
|
||||
g_free(s->chr_name);
|
||||
s->chr_name = g_strdup(value);
|
||||
}
|
||||
}
|
||||
|
@@ -652,6 +652,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
|
||||
{
|
||||
int ret;
|
||||
int64_t last_ftell = qemu_ftell(f);
|
||||
int64_t delta_ftell;
|
||||
|
||||
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
|
||||
block_mig_state.submitted, block_mig_state.transferred);
|
||||
@@ -701,7 +702,14 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
|
||||
}
|
||||
|
||||
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
|
||||
return qemu_ftell(f) - last_ftell;
|
||||
delta_ftell = qemu_ftell(f) - last_ftell;
|
||||
if (delta_ftell > 0) {
|
||||
return 1;
|
||||
} else if (delta_ftell < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Called with iothread lock taken. */
|
||||
@@ -756,8 +764,8 @@ static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
|
||||
block_mig_state.read_done * BLOCK_SIZE;
|
||||
|
||||
/* Report at least one block pending during bulk phase */
|
||||
if (pending == 0 && !block_mig_state.bulk_completed) {
|
||||
pending = BLOCK_SIZE;
|
||||
if (pending <= max_size && !block_mig_state.bulk_completed) {
|
||||
pending = max_size + BLOCK_SIZE;
|
||||
}
|
||||
blk_mig_unlock();
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
36
block.c
36
block.c
@@ -633,7 +633,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
}
|
||||
|
||||
if (!path_has_protocol(filename) || !allow_protocol_prefix) {
|
||||
return bdrv_find_format("file");
|
||||
return &bdrv_file;
|
||||
}
|
||||
|
||||
p = strchr(filename, ':');
|
||||
@@ -662,12 +662,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
|
||||
|
||||
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
|
||||
if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
|
||||
drv = bdrv_find_format("raw");
|
||||
if (!drv) {
|
||||
error_setg(errp, "Could not find raw image format");
|
||||
ret = -ENOENT;
|
||||
}
|
||||
*pdrv = drv;
|
||||
*pdrv = &bdrv_raw;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1182,7 +1177,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
|
||||
{
|
||||
char *backing_filename = g_malloc0(PATH_MAX);
|
||||
int ret = 0;
|
||||
BlockDriver *back_drv = NULL;
|
||||
BlockDriverState *backing_hd;
|
||||
Error *local_err = NULL;
|
||||
|
||||
@@ -1215,14 +1209,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
|
||||
|
||||
backing_hd = bdrv_new("", errp);
|
||||
|
||||
if (bs->backing_format[0] != '\0') {
|
||||
back_drv = bdrv_find_format(bs->backing_format);
|
||||
if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
|
||||
qdict_put(options, "driver", qstring_from_str(bs->backing_format));
|
||||
}
|
||||
|
||||
assert(bs->backing_hd == NULL);
|
||||
ret = bdrv_open(&backing_hd,
|
||||
*backing_filename ? backing_filename : NULL, NULL, options,
|
||||
bdrv_backing_flags(bs->open_flags), back_drv, &local_err);
|
||||
bdrv_backing_flags(bs->open_flags), NULL, &local_err);
|
||||
if (ret < 0) {
|
||||
bdrv_unref(backing_hd);
|
||||
backing_hd = NULL;
|
||||
@@ -1296,7 +1290,6 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
||||
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
|
||||
char *tmp_filename = g_malloc0(PATH_MAX + 1);
|
||||
int64_t total_size;
|
||||
BlockDriver *bdrv_qcow2;
|
||||
QemuOpts *opts = NULL;
|
||||
QDict *snapshot_options;
|
||||
BlockDriverState *bs_snapshot;
|
||||
@@ -1322,11 +1315,10 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdrv_qcow2 = bdrv_find_format("qcow2");
|
||||
opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
|
||||
opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0,
|
||||
&error_abort);
|
||||
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
|
||||
ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
|
||||
ret = bdrv_create(&bdrv_qcow2, tmp_filename, opts, &local_err);
|
||||
qemu_opts_del(opts);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not create temporary overlay "
|
||||
@@ -1346,7 +1338,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
||||
bs_snapshot = bdrv_new("", &error_abort);
|
||||
|
||||
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
|
||||
flags, bdrv_qcow2, &local_err);
|
||||
flags, &bdrv_qcow2, &local_err);
|
||||
if (ret < 0) {
|
||||
error_propagate(errp, local_err);
|
||||
goto out;
|
||||
@@ -5535,6 +5527,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!drv->create_opts) {
|
||||
error_setg(errp, "Format driver '%s' does not support image creation",
|
||||
drv->format_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!proto_drv->create_opts) {
|
||||
error_setg(errp, "Protocol driver '%s' does not support image creation",
|
||||
proto_drv->format_name);
|
||||
return;
|
||||
}
|
||||
|
||||
create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
||||
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
||||
|
||||
|
@@ -526,6 +526,25 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
|
||||
return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
|
||||
}
|
||||
|
||||
static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
BlkdebugRule *rule = NULL;
|
||||
|
||||
QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
|
||||
if (rule->options.inject.sector == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rule && rule->options.inject.error) {
|
||||
return inject_error(bs, cb, opaque, rule);
|
||||
}
|
||||
|
||||
return bdrv_aio_flush(bs->file, cb, opaque);
|
||||
}
|
||||
|
||||
|
||||
static void blkdebug_close(BlockDriverState *bs)
|
||||
{
|
||||
@@ -703,6 +722,7 @@ static BlockDriver bdrv_blkdebug = {
|
||||
|
||||
.bdrv_aio_readv = blkdebug_aio_readv,
|
||||
.bdrv_aio_writev = blkdebug_aio_writev,
|
||||
.bdrv_aio_flush = blkdebug_aio_flush,
|
||||
|
||||
.bdrv_debug_event = blkdebug_debug_event,
|
||||
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
|
||||
|
15
block/nfs.c
15
block/nfs.c
@@ -401,6 +401,19 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QemuOptsList nfs_create_opts = {
|
||||
.name = "nfs-create-opts",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(nfs_create_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = BLOCK_OPT_SIZE,
|
||||
.type = QEMU_OPT_SIZE,
|
||||
.help = "Virtual disk size"
|
||||
},
|
||||
{ /* end of list */ }
|
||||
}
|
||||
};
|
||||
|
||||
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -461,6 +474,8 @@ static BlockDriver bdrv_nfs = {
|
||||
|
||||
.instance_size = sizeof(NFSClient),
|
||||
.bdrv_needs_filename = true,
|
||||
.create_opts = &nfs_create_opts,
|
||||
|
||||
.bdrv_has_zero_init = nfs_has_zero_init,
|
||||
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
|
||||
.bdrv_truncate = nfs_file_truncate,
|
||||
|
@@ -158,12 +158,14 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
|
||||
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
uint64_t buf[L1_ENTRIES_PER_SECTOR];
|
||||
uint64_t buf[L1_ENTRIES_PER_SECTOR] = { 0 };
|
||||
int l1_start_index;
|
||||
int i, ret;
|
||||
|
||||
l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
|
||||
for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) {
|
||||
for (i = 0; i < L1_ENTRIES_PER_SECTOR && l1_start_index + i < s->l1_size;
|
||||
i++)
|
||||
{
|
||||
buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
|
||||
}
|
||||
|
||||
@@ -1200,7 +1202,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
|
||||
again:
|
||||
start = offset;
|
||||
remaining = *num << BDRV_SECTOR_BITS;
|
||||
remaining = (uint64_t)*num << BDRV_SECTOR_BITS;
|
||||
cluster_offset = 0;
|
||||
*host_offset = 0;
|
||||
cur_bytes = 0;
|
||||
|
@@ -114,7 +114,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
#ifdef DEBUG_EXT
|
||||
printf("ext.magic = 0x%x\n", ext.magic);
|
||||
#endif
|
||||
if (ext.len > end_offset - offset) {
|
||||
if (offset > end_offset || ext.len > end_offset - offset) {
|
||||
error_setg(errp, "Header extension too large");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1275,10 +1275,23 @@ static void qcow2_close(BlockDriverState *bs)
|
||||
s->l1_table = NULL;
|
||||
|
||||
if (!(bs->open_flags & BDRV_O_INCOMING)) {
|
||||
qcow2_cache_flush(bs, s->l2_table_cache);
|
||||
qcow2_cache_flush(bs, s->refcount_block_cache);
|
||||
int ret1, ret2;
|
||||
|
||||
qcow2_mark_clean(bs);
|
||||
ret1 = qcow2_cache_flush(bs, s->l2_table_cache);
|
||||
ret2 = qcow2_cache_flush(bs, s->refcount_block_cache);
|
||||
|
||||
if (ret1) {
|
||||
error_report("Failed to flush the L2 table cache: %s",
|
||||
strerror(-ret1));
|
||||
}
|
||||
if (ret2) {
|
||||
error_report("Failed to flush the refcount block cache: %s",
|
||||
strerror(-ret2));
|
||||
}
|
||||
|
||||
if (!ret1 && !ret2) {
|
||||
qcow2_mark_clean(bs);
|
||||
}
|
||||
}
|
||||
|
||||
qcow2_cache_destroy(bs, s->l2_table_cache);
|
||||
@@ -1712,10 +1725,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
* refcount of the cluster that is occupied by the header and the refcount
|
||||
* table)
|
||||
*/
|
||||
BlockDriver* drv = bdrv_find_format("qcow2");
|
||||
assert(drv != NULL);
|
||||
ret = bdrv_open(&bs, filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err);
|
||||
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH,
|
||||
&bdrv_qcow2, &local_err);
|
||||
if (ret < 0) {
|
||||
error_propagate(errp, local_err);
|
||||
goto out;
|
||||
@@ -1767,7 +1779,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
|
||||
ret = bdrv_open(&bs, filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
|
||||
drv, &local_err);
|
||||
&bdrv_qcow2, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
goto out;
|
||||
@@ -1948,8 +1960,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
||||
sector based I/Os */
|
||||
cluster_offset = bdrv_getlength(bs->file);
|
||||
cluster_offset = (cluster_offset + 511) & ~511;
|
||||
bdrv_truncate(bs->file, cluster_offset);
|
||||
return 0;
|
||||
return bdrv_truncate(bs->file, cluster_offset);
|
||||
}
|
||||
|
||||
if (nb_sectors != s->cluster_sectors) {
|
||||
@@ -2404,7 +2415,7 @@ static QemuOptsList qcow2_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_qcow2 = {
|
||||
BlockDriver bdrv_qcow2 = {
|
||||
.format_name = "qcow2",
|
||||
.instance_size = sizeof(BDRVQcowState),
|
||||
.bdrv_probe = qcow2_probe,
|
||||
|
@@ -447,6 +447,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
s->has_write_zeroes = true;
|
||||
|
||||
if (fstat(s->fd, &st) < 0) {
|
||||
ret = -errno;
|
||||
error_setg_errno(errp, errno, "Could not stat file");
|
||||
goto fail;
|
||||
}
|
||||
@@ -1585,7 +1586,7 @@ static QemuOptsList raw_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_file = {
|
||||
BlockDriver bdrv_file = {
|
||||
.format_name = "file",
|
||||
.protocol_name = "file",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
|
@@ -540,7 +540,7 @@ static QemuOptsList raw_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_file = {
|
||||
BlockDriver bdrv_file = {
|
||||
.format_name = "file",
|
||||
.protocol_name = "file",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
|
@@ -173,7 +173,7 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_raw = {
|
||||
BlockDriver bdrv_raw = {
|
||||
.format_name = "raw",
|
||||
.bdrv_probe = &raw_probe,
|
||||
.bdrv_reopen_prepare = &raw_reopen_prepare,
|
||||
|
@@ -236,6 +236,10 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
|
||||
error_setg(errp, "snapshot_id and name are both NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* drain all pending i/o before deleting snapshot */
|
||||
bdrv_drain_all();
|
||||
|
||||
if (drv->bdrv_snapshot_delete) {
|
||||
return drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
|
||||
}
|
||||
|
@@ -2926,6 +2926,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
|
||||
}
|
||||
|
||||
bdrv_qcow = bdrv_find_format("qcow");
|
||||
if (!bdrv_qcow) {
|
||||
error_setg(errp, "Failed to locate qcow driver");
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
|
||||
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
|
||||
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
|
||||
|
9
cpus.c
9
cpus.c
@@ -523,6 +523,15 @@ void cpu_synchronize_all_post_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_clean_all_dirty(void)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
cpu_clean_state(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_vm_stop(RunState state)
|
||||
{
|
||||
int ret = 0;
|
||||
|
7
exec.c
7
exec.c
@@ -1130,6 +1130,7 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
|
||||
error:
|
||||
if (mem_prealloc) {
|
||||
error_report("%s\n", error_get_pretty(*errp));
|
||||
exit(1);
|
||||
}
|
||||
return NULL;
|
||||
@@ -2008,10 +2009,8 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
static void invalidate_and_set_dirty(hwaddr addr,
|
||||
hwaddr length)
|
||||
{
|
||||
if (cpu_physical_memory_is_clean(addr)) {
|
||||
/* invalidate code */
|
||||
tb_invalidate_phys_page_range(addr, addr + length, 0);
|
||||
/* set dirty bit */
|
||||
if (cpu_physical_memory_range_includes_clean(addr, length)) {
|
||||
tb_invalidate_phys_range(addr, addr + length, 0);
|
||||
cpu_physical_memory_set_dirty_range_nocode(addr, length);
|
||||
}
|
||||
xen_modified_memory(addr, length);
|
||||
|
@@ -1707,7 +1707,7 @@ int gdbserver_start(const char *device)
|
||||
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
|
||||
|
||||
/* Initialize a monitor terminal for gdb */
|
||||
mon_chr = g_malloc0(sizeof(*mon_chr));
|
||||
mon_chr = qemu_chr_alloc();
|
||||
mon_chr->chr_write = gdb_monitor_write;
|
||||
monitor_init(mon_chr, 0);
|
||||
} else {
|
||||
|
@@ -508,7 +508,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
||||
entry = elf_entry;
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
|
||||
&is_linux);
|
||||
&is_linux, NULL, NULL);
|
||||
}
|
||||
if (kernel_size < 0) {
|
||||
entry = info->loader_start + kernel_load_offset;
|
||||
|
@@ -371,7 +371,7 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
|
||||
2, base, 2, size);
|
||||
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
|
||||
GIC_FDT_IRQ_TYPE_SPI, irq,
|
||||
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
|
||||
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
|
||||
vbi->clock_phandle, vbi->clock_phandle);
|
||||
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
|
||||
@@ -396,7 +396,7 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
|
||||
2, base, 2, size);
|
||||
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
|
||||
GIC_FDT_IRQ_TYPE_SPI, irq,
|
||||
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
|
||||
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
|
||||
qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
|
||||
g_free(nodename);
|
||||
|
@@ -456,7 +456,9 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
|
||||
|
||||
/* Load a U-Boot image. */
|
||||
static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
int *is_linux, uint8_t image_type)
|
||||
int *is_linux, uint8_t image_type,
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque)
|
||||
{
|
||||
int fd;
|
||||
int size;
|
||||
@@ -490,6 +492,9 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
switch (hdr->ih_type) {
|
||||
case IH_TYPE_KERNEL:
|
||||
address = hdr->ih_load;
|
||||
if (translate_fn) {
|
||||
address = translate_fn(translate_opaque, address);
|
||||
}
|
||||
if (loadaddr) {
|
||||
*loadaddr = hdr->ih_load;
|
||||
}
|
||||
@@ -566,15 +571,19 @@ out:
|
||||
}
|
||||
|
||||
int load_uimage(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
int *is_linux)
|
||||
int *is_linux,
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque)
|
||||
{
|
||||
return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL);
|
||||
return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL,
|
||||
translate_fn, translate_opaque);
|
||||
}
|
||||
|
||||
/* Load a ramdisk. */
|
||||
int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz)
|
||||
{
|
||||
return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK);
|
||||
return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -24,6 +24,7 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->accel);
|
||||
ms->accel = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -79,6 +80,7 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->kernel_filename);
|
||||
ms->kernel_filename = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -93,6 +95,7 @@ static void machine_set_initrd(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->initrd_filename);
|
||||
ms->initrd_filename = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -107,6 +110,7 @@ static void machine_set_append(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->kernel_cmdline);
|
||||
ms->kernel_cmdline = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -121,6 +125,7 @@ static void machine_set_dtb(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->dtb);
|
||||
ms->dtb = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -135,6 +140,7 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->dumpdtb);
|
||||
ms->dumpdtb = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -176,6 +182,7 @@ static void machine_set_dt_compatible(Object *obj, const char *value, Error **er
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->dt_compatible);
|
||||
ms->dt_compatible = g_strdup(value);
|
||||
}
|
||||
|
||||
@@ -232,6 +239,7 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
MachineState *ms = MACHINE(obj);
|
||||
|
||||
g_free(ms->firmware);
|
||||
ms->firmware = g_strdup(value);
|
||||
}
|
||||
|
||||
|
@@ -834,12 +834,14 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
|
||||
dc->realize(dev, &local_err);
|
||||
}
|
||||
|
||||
if (dev->parent_bus && dev->parent_bus->hotplug_handler &&
|
||||
local_err == NULL) {
|
||||
if (local_err != NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
|
||||
hotplug_handler_plug(dev->parent_bus->hotplug_handler,
|
||||
dev, &local_err);
|
||||
} else if (local_err == NULL &&
|
||||
object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
|
||||
} else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
|
||||
HotplugHandler *hotplug_ctrl;
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
@@ -852,47 +854,69 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
if (qdev_get_vmsd(dev) && local_err == NULL) {
|
||||
if (local_err != NULL) {
|
||||
goto post_realize_fail;
|
||||
}
|
||||
|
||||
if (qdev_get_vmsd(dev)) {
|
||||
vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
|
||||
dev->instance_id_alias,
|
||||
dev->alias_required_for_version);
|
||||
}
|
||||
if (local_err == NULL) {
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
object_property_set_bool(OBJECT(bus), true, "realized",
|
||||
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
object_property_set_bool(OBJECT(bus), true, "realized",
|
||||
&local_err);
|
||||
if (local_err != NULL) {
|
||||
break;
|
||||
}
|
||||
if (local_err != NULL) {
|
||||
goto child_realize_fail;
|
||||
}
|
||||
}
|
||||
if (dev->hotplugged && local_err == NULL) {
|
||||
if (dev->hotplugged) {
|
||||
device_reset(dev);
|
||||
}
|
||||
dev->pending_deleted_event = false;
|
||||
} else if (!value && dev->realized) {
|
||||
Error **local_errp = NULL;
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
local_errp = local_err ? NULL : &local_err;
|
||||
object_property_set_bool(OBJECT(bus), false, "realized",
|
||||
&local_err);
|
||||
if (local_err != NULL) {
|
||||
break;
|
||||
}
|
||||
local_errp);
|
||||
}
|
||||
if (qdev_get_vmsd(dev) && local_err == NULL) {
|
||||
if (qdev_get_vmsd(dev)) {
|
||||
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
|
||||
}
|
||||
if (dc->unrealize && local_err == NULL) {
|
||||
dc->unrealize(dev, &local_err);
|
||||
if (dc->unrealize) {
|
||||
local_errp = local_err ? NULL : &local_err;
|
||||
dc->unrealize(dev, local_errp);
|
||||
}
|
||||
dev->pending_deleted_event = true;
|
||||
}
|
||||
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->realized = value;
|
||||
return;
|
||||
|
||||
child_realize_fail:
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
object_property_set_bool(OBJECT(bus), false, "realized",
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (qdev_get_vmsd(dev)) {
|
||||
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
|
||||
}
|
||||
|
||||
post_realize_fail:
|
||||
if (dc->unrealize) {
|
||||
dc->unrealize(dev, NULL);
|
||||
}
|
||||
|
||||
fail:
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
static bool device_get_hotpluggable(Object *obj, Error **errp)
|
||||
|
@@ -292,8 +292,59 @@ enum {
|
||||
SVGA_CURSOR_ON_RESTORE_TO_FB = 3,
|
||||
};
|
||||
|
||||
static inline bool vmsvga_verify_rect(DisplaySurface *surface,
|
||||
const char *name,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
if (x < 0) {
|
||||
fprintf(stderr, "%s: x was < 0 (%d)\n", name, x);
|
||||
return false;
|
||||
}
|
||||
if (x > SVGA_MAX_WIDTH) {
|
||||
fprintf(stderr, "%s: x was > %d (%d)\n", name, SVGA_MAX_WIDTH, x);
|
||||
return false;
|
||||
}
|
||||
if (w < 0) {
|
||||
fprintf(stderr, "%s: w was < 0 (%d)\n", name, w);
|
||||
return false;
|
||||
}
|
||||
if (w > SVGA_MAX_WIDTH) {
|
||||
fprintf(stderr, "%s: w was > %d (%d)\n", name, SVGA_MAX_WIDTH, w);
|
||||
return false;
|
||||
}
|
||||
if (x + w > surface_width(surface)) {
|
||||
fprintf(stderr, "%s: width was > %d (x: %d, w: %d)\n",
|
||||
name, surface_width(surface), x, w);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
fprintf(stderr, "%s: y was < 0 (%d)\n", name, y);
|
||||
return false;
|
||||
}
|
||||
if (y > SVGA_MAX_HEIGHT) {
|
||||
fprintf(stderr, "%s: y was > %d (%d)\n", name, SVGA_MAX_HEIGHT, y);
|
||||
return false;
|
||||
}
|
||||
if (h < 0) {
|
||||
fprintf(stderr, "%s: h was < 0 (%d)\n", name, h);
|
||||
return false;
|
||||
}
|
||||
if (h > SVGA_MAX_HEIGHT) {
|
||||
fprintf(stderr, "%s: h was > %d (%d)\n", name, SVGA_MAX_HEIGHT, h);
|
||||
return false;
|
||||
}
|
||||
if (y + h > surface_height(surface)) {
|
||||
fprintf(stderr, "%s: update height > %d (y: %d, h: %d)\n",
|
||||
name, surface_height(surface), y, h);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
|
||||
int x, int y, int w, int h)
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
DisplaySurface *surface = qemu_console_surface(s->vga.con);
|
||||
int line;
|
||||
@@ -303,36 +354,12 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
|
||||
uint8_t *src;
|
||||
uint8_t *dst;
|
||||
|
||||
if (x < 0) {
|
||||
fprintf(stderr, "%s: update x was < 0 (%d)\n", __func__, x);
|
||||
w += x;
|
||||
if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
|
||||
/* go for a fullscreen update as fallback */
|
||||
x = 0;
|
||||
}
|
||||
if (w < 0) {
|
||||
fprintf(stderr, "%s: update w was < 0 (%d)\n", __func__, w);
|
||||
w = 0;
|
||||
}
|
||||
if (x + w > surface_width(surface)) {
|
||||
fprintf(stderr, "%s: update width too large x: %d, w: %d\n",
|
||||
__func__, x, w);
|
||||
x = MIN(x, surface_width(surface));
|
||||
w = surface_width(surface) - x;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
fprintf(stderr, "%s: update y was < 0 (%d)\n", __func__, y);
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (h < 0) {
|
||||
fprintf(stderr, "%s: update h was < 0 (%d)\n", __func__, h);
|
||||
h = 0;
|
||||
}
|
||||
if (y + h > surface_height(surface)) {
|
||||
fprintf(stderr, "%s: update height too large y: %d, h: %d\n",
|
||||
__func__, y, h);
|
||||
y = MIN(y, surface_height(surface));
|
||||
h = surface_height(surface) - y;
|
||||
w = surface_width(surface);
|
||||
h = surface_height(surface);
|
||||
}
|
||||
|
||||
bypl = surface_stride(surface);
|
||||
@@ -377,7 +404,7 @@ static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
|
||||
}
|
||||
|
||||
#ifdef HW_RECT_ACCEL
|
||||
static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
|
||||
static inline int vmsvga_copy_rect(struct vmsvga_state_s *s,
|
||||
int x0, int y0, int x1, int y1, int w, int h)
|
||||
{
|
||||
DisplaySurface *surface = qemu_console_surface(s->vga.con);
|
||||
@@ -388,6 +415,13 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
|
||||
int line = h;
|
||||
uint8_t *ptr[2];
|
||||
|
||||
if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/src", x0, y0, w, h)) {
|
||||
return -1;
|
||||
}
|
||||
if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/dst", x1, y1, w, h)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (y1 > y0) {
|
||||
ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1);
|
||||
ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1);
|
||||
@@ -403,11 +437,12 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
|
||||
}
|
||||
|
||||
vmsvga_update_rect_delayed(s, x1, y1, w, h);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HW_FILL_ACCEL
|
||||
static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
|
||||
static inline int vmsvga_fill_rect(struct vmsvga_state_s *s,
|
||||
uint32_t c, int x, int y, int w, int h)
|
||||
{
|
||||
DisplaySurface *surface = qemu_console_surface(s->vga.con);
|
||||
@@ -420,6 +455,10 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
|
||||
uint8_t *src;
|
||||
uint8_t col[4];
|
||||
|
||||
if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
col[0] = c;
|
||||
col[1] = c >> 8;
|
||||
col[2] = c >> 16;
|
||||
@@ -444,6 +483,7 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
|
||||
}
|
||||
|
||||
vmsvga_update_rect_delayed(s, x, y, w, h);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -576,12 +616,12 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
|
||||
width = vmsvga_fifo_read(s);
|
||||
height = vmsvga_fifo_read(s);
|
||||
#ifdef HW_FILL_ACCEL
|
||||
vmsvga_fill_rect(s, colour, x, y, width, height);
|
||||
break;
|
||||
#else
|
||||
if (vmsvga_fill_rect(s, colour, x, y, width, height) == 0) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
args = 0;
|
||||
goto badcmd;
|
||||
#endif
|
||||
|
||||
case SVGA_CMD_RECT_COPY:
|
||||
len -= 7;
|
||||
@@ -596,12 +636,12 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
|
||||
width = vmsvga_fifo_read(s);
|
||||
height = vmsvga_fifo_read(s);
|
||||
#ifdef HW_RECT_ACCEL
|
||||
vmsvga_copy_rect(s, x, y, dx, dy, width, height);
|
||||
break;
|
||||
#else
|
||||
if (vmsvga_copy_rect(s, x, y, dx, dy, width, height) == 0) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
args = 0;
|
||||
goto badcmd;
|
||||
#endif
|
||||
|
||||
case SVGA_CMD_DEFINE_CURSOR:
|
||||
len -= 8;
|
||||
|
@@ -1228,8 +1228,7 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
|
||||
}
|
||||
|
||||
static void
|
||||
build_srat(GArray *table_data, GArray *linker,
|
||||
AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
|
||||
build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
|
||||
{
|
||||
AcpiSystemResourceAffinityTable *srat;
|
||||
AcpiSratProcessorAffinity *core;
|
||||
@@ -1259,11 +1258,7 @@ build_srat(GArray *table_data, GArray *linker,
|
||||
core->proximity_lo = curnode;
|
||||
memset(core->proximity_hi, 0, 3);
|
||||
core->local_sapic_eid = 0;
|
||||
if (test_bit(i, cpu->found_cpus)) {
|
||||
core->flags = cpu_to_le32(1);
|
||||
} else {
|
||||
core->flags = cpu_to_le32(0);
|
||||
}
|
||||
core->flags = cpu_to_le32(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1539,7 +1534,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
||||
}
|
||||
if (guest_info->numa_nodes) {
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
build_srat(tables->table_data, tables->linker, &cpu, guest_info);
|
||||
build_srat(tables->table_data, tables->linker, guest_info);
|
||||
}
|
||||
if (acpi_get_mcfg(&mcfg)) {
|
||||
acpi_add_table(table_offsets, tables->table_data);
|
||||
|
@@ -14,8 +14,10 @@
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/kvm/clock.h"
|
||||
|
||||
@@ -34,6 +36,48 @@ typedef struct KVMClockState {
|
||||
bool clock_valid;
|
||||
} KVMClockState;
|
||||
|
||||
struct pvclock_vcpu_time_info {
|
||||
uint32_t version;
|
||||
uint32_t pad0;
|
||||
uint64_t tsc_timestamp;
|
||||
uint64_t system_time;
|
||||
uint32_t tsc_to_system_mul;
|
||||
int8_t tsc_shift;
|
||||
uint8_t flags;
|
||||
uint8_t pad[2];
|
||||
} __attribute__((__packed__)); /* 32 bytes */
|
||||
|
||||
static uint64_t kvmclock_current_nsec(KVMClockState *s)
|
||||
{
|
||||
CPUState *cpu = first_cpu;
|
||||
CPUX86State *env = cpu->env_ptr;
|
||||
hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL;
|
||||
uint64_t migration_tsc = env->tsc;
|
||||
struct pvclock_vcpu_time_info time;
|
||||
uint64_t delta;
|
||||
uint64_t nsec_lo;
|
||||
uint64_t nsec_hi;
|
||||
uint64_t nsec;
|
||||
|
||||
if (!(env->system_time_msr & 1ULL)) {
|
||||
/* KVM clock not active */
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
|
||||
|
||||
assert(time.tsc_timestamp <= migration_tsc);
|
||||
delta = migration_tsc - time.tsc_timestamp;
|
||||
if (time.tsc_shift < 0) {
|
||||
delta >>= -time.tsc_shift;
|
||||
} else {
|
||||
delta <<= time.tsc_shift;
|
||||
}
|
||||
|
||||
mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul);
|
||||
nsec = (nsec_lo >> 32) | (nsec_hi << 32);
|
||||
return nsec + time.system_time;
|
||||
}
|
||||
|
||||
static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
RunState state)
|
||||
@@ -45,9 +89,15 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
|
||||
if (running) {
|
||||
struct kvm_clock_data data;
|
||||
uint64_t time_at_migration = kvmclock_current_nsec(s);
|
||||
|
||||
s->clock_valid = false;
|
||||
|
||||
/* We can't rely on the migrated clock value, just discard it */
|
||||
if (time_at_migration) {
|
||||
s->clock = time_at_migration;
|
||||
}
|
||||
|
||||
data.clock = s->clock;
|
||||
data.flags = 0;
|
||||
ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
|
||||
@@ -75,6 +125,23 @@ static void kvmclock_vm_state_change(void *opaque, int running,
|
||||
if (s->clock_valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_synchronize_all_states();
|
||||
/* In theory, the cpu_synchronize_all_states() call above wouldn't
|
||||
* affect the rest of the code, as the VCPU state inside CPUState
|
||||
* is supposed to always match the VCPU state on the kernel side.
|
||||
*
|
||||
* In practice, calling cpu_synchronize_state() too soon will load the
|
||||
* kernel-side APIC state into X86CPU.apic_state too early, APIC state
|
||||
* won't be reloaded later because CPUState.vcpu_dirty==true, and
|
||||
* outdated APIC state may be migrated to another host.
|
||||
*
|
||||
* The real fix would be to make sure outdated APIC state is read
|
||||
* from the kernel again when necessary. While this is not fixed, we
|
||||
* need the cpu_clean_all_dirty() call below.
|
||||
*/
|
||||
cpu_clean_all_dirty();
|
||||
|
||||
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
|
||||
|
@@ -72,8 +72,10 @@
|
||||
#define DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
|
||||
unsigned acpi_data_size = 0x20000;
|
||||
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
|
||||
* (128K) and other BIOS datastructures (less than 4K reported to be used at
|
||||
* the moment, 32K should be enough for a while). */
|
||||
unsigned acpi_data_size = 0x20000 + 0x8000;
|
||||
void pc_set_legacy_acpi_data_size(void)
|
||||
{
|
||||
acpi_data_size = 0x10000;
|
||||
|
@@ -646,7 +646,7 @@ static QEMUMachine pc_machine_v1_1 = {
|
||||
.property = "class",\
|
||||
.value = stringify(PCI_CLASS_MEMORY_RAM),\
|
||||
},{\
|
||||
.driver = "apic",\
|
||||
.driver = "apic-common",\
|
||||
.property = "vapic",\
|
||||
.value = "off",\
|
||||
},{\
|
||||
|
@@ -821,7 +821,7 @@ void smbios_get_tables(uint8_t **tables, size_t *tables_len,
|
||||
smbios_build_type_2_table();
|
||||
smbios_build_type_3_table();
|
||||
|
||||
smbios_smp_sockets = smp_cpus / (smp_cores * smp_threads);
|
||||
smbios_smp_sockets = DIV_ROUND_UP(smp_cpus, smp_cores * smp_threads);
|
||||
assert(smbios_smp_sockets >= 1);
|
||||
|
||||
for (i = 0; i < smbios_smp_sockets; i++) {
|
||||
|
@@ -2299,7 +2299,7 @@ static int ide_drive_post_load(void *opaque, int version_id)
|
||||
{
|
||||
IDEState *s = opaque;
|
||||
|
||||
if (s->identify_set) {
|
||||
if (s->bs && s->identify_set) {
|
||||
bdrv_set_enable_write_cache(s->bs, !!(s->identify_data[85] & (1 << 5)));
|
||||
}
|
||||
return 0;
|
||||
|
@@ -74,7 +74,8 @@ static void an5206_init(MachineState *machine)
|
||||
NULL, NULL, 1, ELF_MACHINE, 0);
|
||||
entry = elf_entry;
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,
|
||||
|
@@ -50,7 +50,8 @@ static void dummy_m68k_init(MachineState *machine)
|
||||
NULL, NULL, 1, ELF_MACHINE, 0);
|
||||
entry = elf_entry;
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_image_targphys(kernel_filename,
|
||||
|
@@ -279,7 +279,8 @@ static void mcf5208evb_init(MachineState *machine)
|
||||
NULL, NULL, 1, ELF_MACHINE, 0);
|
||||
entry = elf_entry;
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
|
||||
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_image_targphys(kernel_filename, 0x40000000,
|
||||
|
@@ -252,7 +252,7 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
|
||||
error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set");
|
||||
return;
|
||||
}
|
||||
if (dimm->node >= nb_numa_nodes) {
|
||||
if ((nb_numa_nodes > 0) && (dimm->node >= nb_numa_nodes)) {
|
||||
error_setg(errp, "'DIMM property " PC_DIMM_NODE_PROP " has value %"
|
||||
PRIu32 "' which exceeds the number of numa nodes: %d",
|
||||
dimm->node, nb_numa_nodes);
|
||||
|
@@ -154,7 +154,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
|
||||
if (kernel_size < 0) {
|
||||
hwaddr uentry, loadaddr;
|
||||
|
||||
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0);
|
||||
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
|
||||
NULL, NULL);
|
||||
boot_info.bootstrap_pc = uentry;
|
||||
high = (loadaddr + kernel_size + 3) & ~3;
|
||||
}
|
||||
|
@@ -24,10 +24,12 @@
|
||||
#include "migration/migration.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
#include "qemu/fifo8.h"
|
||||
#include "sysemu/char.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define PCI_VENDOR_ID_IVSHMEM PCI_VENDOR_ID_REDHAT_QUMRANET
|
||||
#define PCI_DEVICE_ID_IVSHMEM 0x1110
|
||||
@@ -73,6 +75,7 @@ typedef struct IVShmemState {
|
||||
|
||||
CharDriverState **eventfd_chr;
|
||||
CharDriverState *server_chr;
|
||||
Fifo8 incoming_fifo;
|
||||
MemoryRegion ivshmem_mmio;
|
||||
|
||||
/* We might need to register the BAR before we actually have the memory.
|
||||
@@ -383,6 +386,9 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
|
||||
if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
|
||||
return;
|
||||
}
|
||||
if (posn < 0 || posn >= s->nb_peers) {
|
||||
return;
|
||||
}
|
||||
|
||||
guest_curr_max = s->peers[posn].nb_eventfds;
|
||||
|
||||
@@ -401,14 +407,24 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
|
||||
|
||||
/* this function increase the dynamic storage need to store data about other
|
||||
* guests */
|
||||
static void increase_dynamic_storage(IVShmemState *s, int new_min_size) {
|
||||
static int increase_dynamic_storage(IVShmemState *s, int new_min_size)
|
||||
{
|
||||
|
||||
int j, old_nb_alloc;
|
||||
|
||||
/* check for integer overflow */
|
||||
if (new_min_size >= INT_MAX / sizeof(Peer) - 1 || new_min_size <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
old_nb_alloc = s->nb_peers;
|
||||
|
||||
while (new_min_size >= s->nb_peers)
|
||||
s->nb_peers = s->nb_peers * 2;
|
||||
if (new_min_size >= s->nb_peers) {
|
||||
/* +1 because #new_min_size is used as last array index */
|
||||
s->nb_peers = new_min_size + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
IVSHMEM_DPRINTF("bumping storage to %d guests\n", s->nb_peers);
|
||||
s->peers = g_realloc(s->peers, s->nb_peers * sizeof(Peer));
|
||||
@@ -418,23 +434,57 @@ static void increase_dynamic_storage(IVShmemState *s, int new_min_size) {
|
||||
s->peers[j].eventfds = NULL;
|
||||
s->peers[j].nb_eventfds = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
|
||||
static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
IVShmemState *s = opaque;
|
||||
int incoming_fd, tmp_fd;
|
||||
int guest_max_eventfd;
|
||||
long incoming_posn;
|
||||
|
||||
memcpy(&incoming_posn, buf, sizeof(long));
|
||||
if (fifo8_is_empty(&s->incoming_fifo) && size == sizeof(incoming_posn)) {
|
||||
memcpy(&incoming_posn, buf, size);
|
||||
} else {
|
||||
const uint8_t *p;
|
||||
uint32_t num;
|
||||
|
||||
IVSHMEM_DPRINTF("short read of %d bytes\n", size);
|
||||
num = MAX(size, sizeof(long) - fifo8_num_used(&s->incoming_fifo));
|
||||
fifo8_push_all(&s->incoming_fifo, buf, num);
|
||||
if (fifo8_num_used(&s->incoming_fifo) < sizeof(incoming_posn)) {
|
||||
return;
|
||||
}
|
||||
size -= num;
|
||||
buf += num;
|
||||
p = fifo8_pop_buf(&s->incoming_fifo, sizeof(incoming_posn), &num);
|
||||
g_assert(num == sizeof(incoming_posn));
|
||||
memcpy(&incoming_posn, p, sizeof(incoming_posn));
|
||||
if (size > 0) {
|
||||
fifo8_push_all(&s->incoming_fifo, buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
if (incoming_posn < -1) {
|
||||
IVSHMEM_DPRINTF("invalid incoming_posn %ld\n", incoming_posn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* pick off s->server_chr->msgfd and store it, posn should accompany msg */
|
||||
tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr);
|
||||
IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd);
|
||||
|
||||
/* make sure we have enough space for this guest */
|
||||
if (incoming_posn >= s->nb_peers) {
|
||||
increase_dynamic_storage(s, incoming_posn);
|
||||
if (increase_dynamic_storage(s, incoming_posn) < 0) {
|
||||
error_report("increase_dynamic_storage() failed");
|
||||
if (tmp_fd != -1) {
|
||||
close(tmp_fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_fd == -1) {
|
||||
@@ -458,6 +508,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
|
||||
if (incoming_fd == -1) {
|
||||
fprintf(stderr, "could not allocate file descriptor %s\n",
|
||||
strerror(errno));
|
||||
close(tmp_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -659,6 +710,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
|
||||
s->ivshmem_size = ivshmem_get_size(s);
|
||||
}
|
||||
|
||||
fifo8_create(&s->incoming_fifo, sizeof(long));
|
||||
|
||||
register_savevm(DEVICE(dev), "ivshmem", 0, 0, ivshmem_save, ivshmem_load,
|
||||
dev);
|
||||
|
||||
@@ -795,6 +848,7 @@ static void pci_ivshmem_uninit(PCIDevice *dev)
|
||||
memory_region_destroy(&s->ivshmem);
|
||||
memory_region_destroy(&s->bar);
|
||||
unregister_savevm(DEVICE(dev), "ivshmem", s);
|
||||
fifo8_destroy(&s->incoming_fifo);
|
||||
}
|
||||
|
||||
static Property ivshmem_properties[] = {
|
||||
|
@@ -163,11 +163,11 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
||||
if (r < 0) {
|
||||
goto fail;
|
||||
}
|
||||
if (!qemu_has_vnet_hdr_len(options->net_backend,
|
||||
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
|
||||
net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
|
||||
}
|
||||
if (backend_kernel) {
|
||||
if (!qemu_has_vnet_hdr_len(options->net_backend,
|
||||
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
|
||||
net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
|
||||
}
|
||||
if (~net->dev.features & net->dev.backend_features) {
|
||||
fprintf(stderr, "vhost lacks feature mask %" PRIu64
|
||||
" for backend\n",
|
||||
|
@@ -798,7 +798,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
|
||||
VirtQueueElement elem;
|
||||
size_t s;
|
||||
struct iovec *iov;
|
||||
struct iovec *iov, *iov2;
|
||||
unsigned int iov_cnt;
|
||||
|
||||
while (virtqueue_pop(vq, &elem)) {
|
||||
@@ -808,8 +808,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
iov = elem.out_sg;
|
||||
iov_cnt = elem.out_num;
|
||||
iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
|
||||
s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
|
||||
iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
|
||||
if (s != sizeof(ctrl)) {
|
||||
@@ -833,6 +833,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
||||
virtqueue_push(vq, &elem, sizeof(status));
|
||||
virtio_notify(vdev, vq);
|
||||
g_free(iov2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,8 +1126,6 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
|
||||
return num_packets;
|
||||
}
|
||||
|
||||
assert(vdev->vm_running);
|
||||
|
||||
if (q->async_tx.elem.out_num) {
|
||||
virtio_queue_set_notification(q->tx_vq, 0);
|
||||
return num_packets;
|
||||
|
@@ -72,7 +72,7 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
|
||||
entry = elf_entry;
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_uimage(kernel_filename,
|
||||
&entry, NULL, NULL);
|
||||
&entry, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_image_targphys(kernel_filename,
|
||||
|
@@ -291,7 +291,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
|
||||
"notify vector 0x%x"
|
||||
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
|
||||
vector, msg.address, msg.data);
|
||||
stl_le_phys(&address_space_memory, msg.address, msg.data);
|
||||
stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
|
||||
}
|
||||
|
||||
/* Normally called by pci_default_write_config(). */
|
||||
|
@@ -439,7 +439,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
|
||||
|
||||
msg = msix_get_message(dev, vector);
|
||||
|
||||
stl_le_phys(&address_space_memory, msg.address, msg.data);
|
||||
stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
|
||||
}
|
||||
|
||||
void msix_reset(PCIDevice *dev)
|
||||
|
@@ -830,7 +830,8 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
|
||||
* Hrm. No ELF image? Try a uImage, maybe someone is giving us an
|
||||
* ePAPR compliant kernel
|
||||
*/
|
||||
kernel_size = load_uimage(filename, &bios_entry, &loadaddr, NULL);
|
||||
kernel_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
|
||||
NULL, NULL);
|
||||
if (kernel_size < 0) {
|
||||
fprintf(stderr, "qemu: could not load firmware '%s'\n", filename);
|
||||
exit(1);
|
||||
|
@@ -253,7 +253,8 @@ static void bamboo_init(MachineState *machine)
|
||||
|
||||
/* Load kernel. */
|
||||
if (kernel_filename) {
|
||||
success = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
|
||||
success = load_uimage(kernel_filename, &entry, &loadaddr, NULL,
|
||||
NULL, NULL);
|
||||
if (success < 0) {
|
||||
success = load_elf(kernel_filename, NULL, NULL, &elf_entry,
|
||||
&elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
|
||||
|
@@ -172,9 +172,9 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
|
||||
return tcet;
|
||||
}
|
||||
|
||||
static void spapr_tce_table_finalize(Object *obj)
|
||||
static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(obj);
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
|
||||
QLIST_REMOVE(tcet, list);
|
||||
|
||||
@@ -419,6 +419,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
dc->init = spapr_tce_table_realize;
|
||||
dc->reset = spapr_tce_reset;
|
||||
dc->unrealize = spapr_tce_table_unrealize;
|
||||
|
||||
QLIST_INIT(&spapr_tce_tables);
|
||||
|
||||
@@ -434,7 +435,6 @@ static TypeInfo spapr_tce_table_info = {
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(sPAPRTCETable),
|
||||
.class_init = spapr_tce_table_class_init,
|
||||
.instance_finalize = spapr_tce_table_finalize,
|
||||
};
|
||||
|
||||
static void register_types(void)
|
||||
|
@@ -700,28 +700,34 @@ static const VMStateDescription vmstate_spapr_pci_msi = {
|
||||
},
|
||||
};
|
||||
|
||||
static void spapr_pci_fill_msi_devs(gpointer key, gpointer value,
|
||||
gpointer opaque)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
|
||||
sphb->msi_devs[sphb->msi_devs_num].key = *(uint32_t *)key;
|
||||
sphb->msi_devs[sphb->msi_devs_num].value = *(spapr_pci_msi *)value;
|
||||
sphb->msi_devs_num++;
|
||||
}
|
||||
|
||||
static void spapr_pci_pre_save(void *opaque)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
int i;
|
||||
int msi_devs_num;
|
||||
|
||||
if (sphb->msi_devs) {
|
||||
g_free(sphb->msi_devs);
|
||||
sphb->msi_devs = NULL;
|
||||
}
|
||||
sphb->msi_devs_num = g_hash_table_size(sphb->msi);
|
||||
if (!sphb->msi_devs_num) {
|
||||
sphb->msi_devs_num = 0;
|
||||
msi_devs_num = g_hash_table_size(sphb->msi);
|
||||
if (!msi_devs_num) {
|
||||
return;
|
||||
}
|
||||
sphb->msi_devs = g_malloc(sphb->msi_devs_num * sizeof(spapr_pci_msi_mig));
|
||||
sphb->msi_devs = g_malloc(msi_devs_num * sizeof(spapr_pci_msi_mig));
|
||||
|
||||
g_hash_table_iter_init(&iter, sphb->msi);
|
||||
for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) {
|
||||
sphb->msi_devs[i].key = *(uint32_t *) key;
|
||||
sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
|
||||
}
|
||||
g_hash_table_foreach(sphb->msi, spapr_pci_fill_msi_devs, sphb);
|
||||
assert(sphb->msi_devs_num == msi_devs_num);
|
||||
}
|
||||
|
||||
static int spapr_pci_post_load(void *opaque, int version_id)
|
||||
|
@@ -161,6 +161,8 @@ static void s390_virtio_net_instance_init(Object *obj)
|
||||
VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
|
||||
@@ -224,6 +226,8 @@ static void s390_virtio_serial_instance_init(Object *obj)
|
||||
VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
}
|
||||
|
||||
static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
|
||||
@@ -256,6 +260,8 @@ static void s390_virtio_scsi_instance_init(Object *obj)
|
||||
VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VHOST_SCSI
|
||||
@@ -277,6 +283,8 @@ static void s390_vhost_scsi_instance_init(Object *obj)
|
||||
VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -303,6 +311,8 @@ static void s390_virtio_rng_instance_init(Object *obj)
|
||||
VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&dev->vdev.conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
@@ -493,10 +503,8 @@ static unsigned virtio_s390_get_features(DeviceState *d)
|
||||
/**************** S390 Virtio Bus Device Descriptions *******************/
|
||||
|
||||
static Property s390_virtio_net_properties[] = {
|
||||
DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf),
|
||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
|
||||
DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
|
||||
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -533,7 +541,6 @@ static const TypeInfo s390_virtio_blk = {
|
||||
};
|
||||
|
||||
static Property s390_virtio_serial_properties[] = {
|
||||
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialS390, vdev.serial),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -556,7 +563,6 @@ static const TypeInfo s390_virtio_serial = {
|
||||
|
||||
static Property s390_virtio_rng_properties[] = {
|
||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
|
||||
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -614,7 +620,6 @@ static const TypeInfo virtio_s390_device_info = {
|
||||
};
|
||||
|
||||
static Property s390_virtio_scsi_properties[] = {
|
||||
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf),
|
||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
|
||||
DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
@@ -640,7 +645,6 @@ static const TypeInfo s390_virtio_scsi = {
|
||||
#ifdef CONFIG_VHOST_SCSI
|
||||
static Property s390_vhost_scsi_properties[] = {
|
||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
|
||||
DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@@ -794,6 +794,8 @@ static void virtio_ccw_net_instance_init(Object *obj)
|
||||
VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
|
||||
@@ -850,6 +852,8 @@ static void virtio_ccw_serial_instance_init(Object *obj)
|
||||
VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
}
|
||||
|
||||
static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
|
||||
@@ -896,7 +900,7 @@ static void virtio_ccw_balloon_instance_init(Object *obj)
|
||||
VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
object_property_add(obj, "guest-stats", "guest statistics",
|
||||
balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
|
||||
|
||||
@@ -936,6 +940,8 @@ static void virtio_ccw_scsi_instance_init(Object *obj)
|
||||
VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VHOST_SCSI
|
||||
@@ -957,6 +963,8 @@ static void vhost_ccw_scsi_instance_init(Object *obj)
|
||||
VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1374,8 +1382,6 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
|
||||
static Property virtio_ccw_net_properties[] = {
|
||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
|
||||
DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
@@ -1428,7 +1434,6 @@ static const TypeInfo virtio_ccw_blk = {
|
||||
|
||||
static Property virtio_ccw_serial_properties[] = {
|
||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
@@ -1481,7 +1486,6 @@ static const TypeInfo virtio_ccw_balloon = {
|
||||
|
||||
static Property virtio_ccw_scsi_properties[] = {
|
||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
|
||||
DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
@@ -1510,7 +1514,6 @@ static const TypeInfo virtio_ccw_scsi = {
|
||||
#ifdef CONFIG_VHOST_SCSI
|
||||
static Property vhost_ccw_scsi_properties[] = {
|
||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1539,6 +1542,8 @@ static void virtio_ccw_rng_instance_init(Object *obj)
|
||||
VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&dev->vdev.conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
@@ -1547,7 +1552,6 @@ static void virtio_ccw_rng_instance_init(Object *obj)
|
||||
|
||||
static Property virtio_ccw_rng_properties[] = {
|
||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
@@ -268,6 +268,8 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
|
||||
/* update status registers */
|
||||
pci->dma_regs[DMA_WBC] -= len;
|
||||
pci->dma_regs[DMA_WAC] += len;
|
||||
if (pci->dma_regs[DMA_WBC] == 0)
|
||||
pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
|
||||
}
|
||||
|
||||
static void esp_pci_dma_memory_read(void *opaque, uint8_t *buf, int len)
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/virtio-scsi.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
|
||||
/* Features supported by host kernel. */
|
||||
static const int kernel_feature_bits[] = {
|
||||
@@ -163,8 +164,8 @@ static void vhost_scsi_set_config(VirtIODevice *vdev,
|
||||
VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
|
||||
|
||||
if ((uint32_t) ldl_p(&scsiconf->sense_size) != vs->sense_size ||
|
||||
(uint32_t) ldl_p(&scsiconf->cdb_size) != vs->cdb_size) {
|
||||
if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size ||
|
||||
(uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) {
|
||||
error_report("vhost-scsi does not support changing the sense data and CDB sizes");
|
||||
exit(1);
|
||||
}
|
||||
|
@@ -135,6 +135,7 @@ static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
|
||||
static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
|
||||
unsigned req_size, unsigned resp_size)
|
||||
{
|
||||
VirtIODevice *vdev = (VirtIODevice *) req->dev;
|
||||
size_t in_size, out_size;
|
||||
|
||||
if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
|
||||
@@ -147,8 +148,24 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
|
||||
resp_size) < resp_size) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->resp_size = resp_size;
|
||||
|
||||
/* Old BIOSes left some padding by mistake after the req_size/resp_size.
|
||||
* As a workaround, always consider the first buffer as the virtio-scsi
|
||||
* request/response, making the payload start at the second element
|
||||
* of the iovec.
|
||||
*
|
||||
* The actual length of the response header, stored in req->resp_size,
|
||||
* does not change.
|
||||
*
|
||||
* TODO: always disable this workaround for virtio 1.0 devices.
|
||||
*/
|
||||
if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
|
||||
req_size = req->elem.out_sg[0].iov_len;
|
||||
resp_size = req->elem.in_sg[0].iov_len;
|
||||
}
|
||||
|
||||
out_size = qemu_sgl_concat(req, req->elem.out_sg,
|
||||
&req->elem.out_addr[0], req->elem.out_num,
|
||||
req_size);
|
||||
@@ -400,7 +417,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
|
||||
sense_len = scsi_req_get_sense(r, sense, sizeof(sense));
|
||||
sense_len = MIN(sense_len, req->resp_iov.size - sizeof(req->resp.cmd));
|
||||
qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd),
|
||||
&req->resp, sense_len);
|
||||
sense, sense_len);
|
||||
req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len);
|
||||
}
|
||||
virtio_scsi_complete_cmd_req(req);
|
||||
|
@@ -499,6 +499,7 @@ enum xhci_flags {
|
||||
XHCI_FLAG_USE_MSI = 1,
|
||||
XHCI_FLAG_USE_MSI_X,
|
||||
XHCI_FLAG_SS_FIRST,
|
||||
XHCI_FLAG_FORCE_PCIE_ENDCAP,
|
||||
};
|
||||
|
||||
static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
|
||||
@@ -3626,7 +3627,8 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
|
||||
&xhci->mem);
|
||||
|
||||
if (pci_bus_is_express(dev->bus)) {
|
||||
if (pci_bus_is_express(dev->bus) ||
|
||||
xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
|
||||
ret = pcie_endpoint_cap_init(dev, 0xa0);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
@@ -3818,6 +3820,8 @@ static Property xhci_properties[] = {
|
||||
DEFINE_PROP_BIT("msix", XHCIState, flags, XHCI_FLAG_USE_MSI_X, true),
|
||||
DEFINE_PROP_BIT("superspeed-ports-first",
|
||||
XHCIState, flags, XHCI_FLAG_SS_FIRST, true),
|
||||
DEFINE_PROP_BIT("force-pcie-endcap", XHCIState, flags,
|
||||
XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
|
||||
DEFINE_PROP_UINT32("intrs", XHCIState, numintrs, MAXINTRS),
|
||||
DEFINE_PROP_UINT32("slots", XHCIState, numslots, MAXSLOTS),
|
||||
DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4),
|
||||
|
@@ -87,7 +87,7 @@ static void balloon_stats_destroy_timer(VirtIOBalloon *s)
|
||||
}
|
||||
}
|
||||
|
||||
static void balloon_stats_change_timer(VirtIOBalloon *s, int secs)
|
||||
static void balloon_stats_change_timer(VirtIOBalloon *s, int64_t secs)
|
||||
{
|
||||
timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000);
|
||||
}
|
||||
@@ -170,6 +170,11 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > UINT_MAX) {
|
||||
error_setg(errp, "timer value is too big");
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == s->stats_poll_interval) {
|
||||
return;
|
||||
}
|
||||
|
@@ -314,6 +314,16 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
msix_unuse_all_vectors(&proxy->pci_dev);
|
||||
}
|
||||
|
||||
/* Linux before 2.6.34 drives the device without enabling
|
||||
the PCI device bus master bit. Enable it automatically
|
||||
for the guest. This is a PCI spec violation but so is
|
||||
initiating DMA with bus master bit clear. */
|
||||
if (val == (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)) {
|
||||
pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
|
||||
proxy->pci_dev.config[PCI_COMMAND] |
|
||||
PCI_COMMAND_MASTER, 1);
|
||||
}
|
||||
|
||||
/* Linux before 2.6.34 sets the device as OK without enabling
|
||||
the PCI device bus master bit. In this case we need to disable
|
||||
some safety checks. */
|
||||
@@ -914,7 +924,6 @@ static Property virtio_9p_pci_properties[] = {
|
||||
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
|
||||
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
|
||||
DEFINE_VIRTIO_9P_PROPERTIES(V9fsPCIState, vdev.fsconf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -938,6 +947,8 @@ static void virtio_9p_pci_instance_init(Object *obj)
|
||||
V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_9P);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_9p_pci_info = {
|
||||
@@ -1127,7 +1138,6 @@ static Property virtio_scsi_pci_properties[] = {
|
||||
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
|
||||
DEV_NVECTORS_UNSPECIFIED),
|
||||
DEFINE_VIRTIO_SCSI_FEATURES(VirtIOPCIProxy, host_features),
|
||||
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIPCI, vdev.parent_obj.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1179,6 +1189,8 @@ static void virtio_scsi_pci_instance_init(Object *obj)
|
||||
VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_scsi_pci_info = {
|
||||
@@ -1195,7 +1207,6 @@ static const TypeInfo virtio_scsi_pci_info = {
|
||||
static Property vhost_scsi_pci_properties[] = {
|
||||
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
|
||||
DEV_NVECTORS_UNSPECIFIED),
|
||||
DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIPCI, vdev.parent_obj.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1235,6 +1246,8 @@ static void vhost_scsi_pci_instance_init(Object *obj)
|
||||
VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
static const TypeInfo vhost_scsi_pci_info = {
|
||||
@@ -1315,7 +1328,7 @@ static void virtio_balloon_pci_instance_init(Object *obj)
|
||||
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
object_property_add(obj, "guest-stats", "guest statistics",
|
||||
balloon_pci_stats_get_all, NULL, NULL, dev,
|
||||
NULL);
|
||||
@@ -1377,7 +1390,6 @@ static Property virtio_serial_pci_properties[] = {
|
||||
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
|
||||
DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
|
||||
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialPCI, vdev.serial),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1400,6 +1412,8 @@ static void virtio_serial_pci_instance_init(Object *obj)
|
||||
VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_serial_pci_info = {
|
||||
@@ -1417,8 +1431,6 @@ static Property virtio_net_properties[] = {
|
||||
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
|
||||
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
|
||||
DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
|
||||
DEFINE_NIC_PROPERTIES(VirtIONetPCI, vdev.nic_conf),
|
||||
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetPCI, vdev.net_conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1459,6 +1471,8 @@ static void virtio_net_pci_instance_init(Object *obj)
|
||||
VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_net_pci_info = {
|
||||
@@ -1472,7 +1486,6 @@ static const TypeInfo virtio_net_pci_info = {
|
||||
/* virtio-rng-pci */
|
||||
|
||||
static Property virtio_rng_pci_properties[] = {
|
||||
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORngPCI, vdev.conf),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1514,6 +1527,8 @@ static void virtio_rng_initfn(Object *obj)
|
||||
VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
|
||||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
|
||||
object_unref(OBJECT(&dev->vdev));
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&dev->vdev.conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
|
@@ -1108,10 +1108,7 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
|
||||
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
|
||||
|
||||
if (running) {
|
||||
vdev->vm_running = running;
|
||||
}
|
||||
vdev->vm_running = running;
|
||||
|
||||
if (backend_run) {
|
||||
virtio_set_status(vdev, vdev->status);
|
||||
@@ -1124,10 +1121,6 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
|
||||
if (!backend_run) {
|
||||
virtio_set_status(vdev, vdev->status);
|
||||
}
|
||||
|
||||
if (!running) {
|
||||
vdev->vm_running = running;
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_init(VirtIODevice *vdev, const char *name,
|
||||
|
@@ -325,7 +325,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
|
||||
} else {
|
||||
hwaddr ep;
|
||||
int is_linux;
|
||||
success = load_uimage(kernel_filename, &ep, NULL, &is_linux);
|
||||
success = load_uimage(kernel_filename, &ep, NULL, &is_linux,
|
||||
translate_phys_addr, cpu);
|
||||
if (success > 0 && is_linux) {
|
||||
entry_point = ep;
|
||||
} else {
|
||||
|
@@ -395,6 +395,14 @@ struct BlockDriverState {
|
||||
Error *backing_blocker;
|
||||
};
|
||||
|
||||
|
||||
/* Essential block drivers which must always be statically linked into qemu, and
|
||||
* which therefore can be accessed without using bdrv_find_format() */
|
||||
extern BlockDriver bdrv_file;
|
||||
extern BlockDriver bdrv_raw;
|
||||
extern BlockDriver bdrv_qcow2;
|
||||
|
||||
|
||||
int get_tmp_filename(char *filename, int size);
|
||||
|
||||
void bdrv_set_io_limits(BlockDriverState *bs,
|
||||
|
@@ -49,6 +49,21 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start,
|
||||
return next < end;
|
||||
}
|
||||
|
||||
static inline bool cpu_physical_memory_get_clean(ram_addr_t start,
|
||||
ram_addr_t length,
|
||||
unsigned client)
|
||||
{
|
||||
unsigned long end, page, next;
|
||||
|
||||
assert(client < DIRTY_MEMORY_NUM);
|
||||
|
||||
end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
|
||||
page = start >> TARGET_PAGE_BITS;
|
||||
next = find_next_zero_bit(ram_list.dirty_memory[client], end, page);
|
||||
|
||||
return next < end;
|
||||
}
|
||||
|
||||
static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr,
|
||||
unsigned client)
|
||||
{
|
||||
@@ -64,6 +79,16 @@ static inline bool cpu_physical_memory_is_clean(ram_addr_t addr)
|
||||
return !(vga && code && migration);
|
||||
}
|
||||
|
||||
static inline bool cpu_physical_memory_range_includes_clean(ram_addr_t start,
|
||||
ram_addr_t length)
|
||||
{
|
||||
bool vga = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_VGA);
|
||||
bool code = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_CODE);
|
||||
bool migration =
|
||||
cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_MIGRATION);
|
||||
return vga || code || migration;
|
||||
}
|
||||
|
||||
static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
|
||||
unsigned client)
|
||||
{
|
||||
|
@@ -317,6 +317,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||
.property = "superspeed-ports-first",\
|
||||
.value = "off",\
|
||||
},\
|
||||
{\
|
||||
.driver = "nec-usb-xhci",\
|
||||
.property = "force-pcie-endcap",\
|
||||
.value = "on",\
|
||||
},\
|
||||
{\
|
||||
.driver = "pci-serial",\
|
||||
.property = "prog_if",\
|
||||
|
@@ -28,7 +28,9 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
|
||||
int load_aout(const char *filename, hwaddr addr, int max_sz,
|
||||
int bswap_needed, hwaddr target_page_size);
|
||||
int load_uimage(const char *filename, hwaddr *ep,
|
||||
hwaddr *loadaddr, int *is_linux);
|
||||
hwaddr *loadaddr, int *is_linux,
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque);
|
||||
|
||||
/**
|
||||
* load_ramdisk:
|
||||
|
@@ -55,6 +55,8 @@ struct Visitor
|
||||
void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
||||
/* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
|
||||
void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|
||||
bool (*start_union)(Visitor *v, bool data_present, Error **errp);
|
||||
void (*end_union)(Visitor *v, bool data_present, Error **errp);
|
||||
};
|
||||
|
||||
void input_type_enum(Visitor *v, int *obj, const char *strings[],
|
||||
|
@@ -58,5 +58,7 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
|
||||
void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
|
||||
void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
|
||||
void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
|
||||
bool visit_start_union(Visitor *v, bool data_present, Error **errp);
|
||||
void visit_end_union(Visitor *v, bool data_present, Error **errp);
|
||||
|
||||
#endif
|
||||
|
@@ -122,11 +122,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef atomic_read
|
||||
#define atomic_read(ptr) (*(__typeof__(*ptr) *volatile) (ptr))
|
||||
#define atomic_read(ptr) (*(__typeof__(*ptr) volatile*) (ptr))
|
||||
#endif
|
||||
|
||||
#ifndef atomic_set
|
||||
#define atomic_set(ptr, i) ((*(__typeof__(*ptr) *volatile) (ptr)) = (i))
|
||||
#define atomic_set(ptr, i) ((*(__typeof__(*ptr) volatile*) (ptr)) = (i))
|
||||
#endif
|
||||
|
||||
/* These have the same semantics as Java volatile variables.
|
||||
|
@@ -10,6 +10,7 @@ void cpu_stop_current(void);
|
||||
void cpu_synchronize_all_states(void);
|
||||
void cpu_synchronize_all_post_reset(void);
|
||||
void cpu_synchronize_all_post_init(void);
|
||||
void cpu_clean_all_dirty(void);
|
||||
|
||||
void qtest_clock_warp(int64_t dest);
|
||||
|
||||
|
@@ -348,6 +348,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
|
||||
void kvm_cpu_synchronize_state(CPUState *cpu);
|
||||
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
|
||||
void kvm_cpu_synchronize_post_init(CPUState *cpu);
|
||||
void kvm_cpu_clean_state(CPUState *cpu);
|
||||
|
||||
/* generic hooks - to be moved/refactored once there are more users */
|
||||
|
||||
@@ -372,6 +373,13 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cpu_clean_state(CPUState *cpu)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
kvm_cpu_clean_state(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
|
||||
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
|
||||
void kvm_irqchip_release_virq(KVMState *s, int virq);
|
||||
|
11
kvm-all.c
11
kvm-all.c
@@ -617,8 +617,10 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
|
||||
unsigned delta;
|
||||
|
||||
/* kvm works in page size chunks, but the function may be called
|
||||
with sub-page size and unaligned start address. */
|
||||
delta = TARGET_PAGE_ALIGN(size) - size;
|
||||
with sub-page size and unaligned start address. Pad the start
|
||||
address to next and truncate size to previous page boundary. */
|
||||
delta = (TARGET_PAGE_SIZE - (start_addr & ~TARGET_PAGE_MASK));
|
||||
delta &= ~TARGET_PAGE_MASK;
|
||||
if (delta > size) {
|
||||
return;
|
||||
}
|
||||
@@ -1681,6 +1683,11 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
|
||||
cpu->kvm_vcpu_dirty = false;
|
||||
}
|
||||
|
||||
void kvm_cpu_clean_state(CPUState *cpu)
|
||||
{
|
||||
cpu->kvm_vcpu_dirty = false;
|
||||
}
|
||||
|
||||
int kvm_cpu_exec(CPUState *cpu)
|
||||
{
|
||||
struct kvm_run *run = cpu->kvm_run;
|
||||
|
@@ -115,6 +115,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
|
||||
VCardAppletPrivate *applet_private;
|
||||
int size, next;
|
||||
unsigned char *sign_buffer;
|
||||
bool retain_sign_buffer = FALSE;
|
||||
vcard_7816_status_t status;
|
||||
VCardStatus ret = VCARD_FAIL;
|
||||
|
||||
@@ -178,6 +179,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
|
||||
pki_applet->sign_buffer = sign_buffer;
|
||||
pki_applet->sign_buffer_len = size;
|
||||
*response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
|
||||
retain_sign_buffer = TRUE;
|
||||
break;
|
||||
case 0x00:
|
||||
/* we now have the whole buffer, do the operation, result will be
|
||||
@@ -200,9 +202,11 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
|
||||
VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
|
||||
break;
|
||||
}
|
||||
g_free(sign_buffer);
|
||||
pki_applet->sign_buffer = NULL;
|
||||
pki_applet->sign_buffer_len = 0;
|
||||
if (!retain_sign_buffer) {
|
||||
g_free(sign_buffer);
|
||||
pki_applet->sign_buffer = NULL;
|
||||
pki_applet->sign_buffer_len = 0;
|
||||
}
|
||||
ret = VCARD_DONE;
|
||||
break;
|
||||
case CAC_READ_BUFFER:
|
||||
|
@@ -597,7 +597,7 @@ connect_to_qemu(
|
||||
const char *port
|
||||
) {
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *server;
|
||||
struct addrinfo *server = NULL;
|
||||
int ret, sock;
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
@@ -629,9 +629,14 @@ connect_to_qemu(
|
||||
if (verbose) {
|
||||
printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader));
|
||||
}
|
||||
|
||||
freeaddrinfo(server);
|
||||
return sock;
|
||||
|
||||
cleanup_socket:
|
||||
if (server) {
|
||||
freeaddrinfo(server);
|
||||
}
|
||||
closesocket(sock);
|
||||
return -1;
|
||||
}
|
||||
|
@@ -5243,6 +5243,7 @@ static void monitor_event(void *opaque, int event)
|
||||
monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
|
||||
"information\n", QEMU_VERSION);
|
||||
if (!mon->mux_out) {
|
||||
readline_restart(mon->rs);
|
||||
readline_show_prompt(mon->rs);
|
||||
}
|
||||
mon->reset_seen = 1;
|
||||
|
@@ -660,7 +660,6 @@ int net_init_l2tpv3(const NetClientOptions *opts,
|
||||
if (fd == -1) {
|
||||
fd = -errno;
|
||||
error_report("l2tpv3_open : socket creation failed, errno = %d", -fd);
|
||||
freeaddrinfo(result);
|
||||
goto outerr;
|
||||
}
|
||||
if (bind(fd, (struct sockaddr *) result->ai_addr, result->ai_addrlen)) {
|
||||
|
Binary file not shown.
@@ -76,14 +76,71 @@ boot_kernel:
|
||||
|
||||
|
||||
copy_kernel:
|
||||
/* Read info block in low memory (0x10000 or 0x90000) */
|
||||
read_fw FW_CFG_SETUP_ADDR
|
||||
shr $4, %eax
|
||||
mov %eax, %es
|
||||
xor %edi, %edi
|
||||
read_fw_blob_addr32_edi(FW_CFG_SETUP)
|
||||
|
||||
cmpw $0x203, %es:0x206 // if protocol >= 0x203
|
||||
jae 1f // have initrd_max
|
||||
movl $0x37ffffff, %es:0x22c // else assume 0x37ffffff
|
||||
1:
|
||||
|
||||
/* Check if using kernel-specified initrd address */
|
||||
read_fw FW_CFG_INITRD_ADDR
|
||||
mov %eax, %edi // (load_kernel wants it in %edi)
|
||||
read_fw FW_CFG_INITRD_SIZE // find end of initrd
|
||||
add %edi, %eax
|
||||
xor %es:0x22c, %eax // if it matches es:0x22c
|
||||
and $-4096, %eax // (apart from padding for page)
|
||||
jz load_kernel // then initrd is not at top
|
||||
// of memory
|
||||
|
||||
/* pc.c placed the initrd at end of memory. Compute a better
|
||||
* initrd address based on e801 data.
|
||||
*/
|
||||
mov $0xe801, %ax
|
||||
xor %cx, %cx
|
||||
xor %dx, %dx
|
||||
int $0x15
|
||||
|
||||
/* Output could be in AX/BX or CX/DX */
|
||||
or %cx, %cx
|
||||
jnz 1f
|
||||
or %dx, %dx
|
||||
jnz 1f
|
||||
mov %ax, %cx
|
||||
mov %bx, %dx
|
||||
1:
|
||||
|
||||
or %dx, %dx
|
||||
jnz 2f
|
||||
addw $1024, %cx /* add 1 MB */
|
||||
movzwl %cx, %edi
|
||||
shll $10, %edi /* convert to bytes */
|
||||
jmp 3f
|
||||
|
||||
2:
|
||||
addw $16777216 >> 16, %dx /* add 16 MB */
|
||||
movzwl %dx, %edi
|
||||
shll $16, %edi /* convert to bytes */
|
||||
|
||||
3:
|
||||
read_fw FW_CFG_INITRD_SIZE
|
||||
subl %eax, %edi
|
||||
andl $-4096, %edi /* EDI = start of initrd */
|
||||
movl %edi, %es:0x218 /* put it in the header */
|
||||
|
||||
load_kernel:
|
||||
/* We need to load the kernel into memory we can't access in 16 bit
|
||||
mode, so let's get into 32 bit mode, write the kernel and jump
|
||||
back again. */
|
||||
|
||||
/* Reserve space on the stack for our GDT descriptor. */
|
||||
mov %esp, %ebp
|
||||
sub $16, %esp
|
||||
mov %esp, %ebp
|
||||
sub $16, %esp
|
||||
|
||||
/* Now create the GDT descriptor */
|
||||
movw $((3 * 8) - 1), -16(%bp)
|
||||
@@ -108,10 +165,9 @@ copy_kernel:
|
||||
/* We're now running in 16-bit CS, but 32-bit ES! */
|
||||
|
||||
/* Load kernel and initrd */
|
||||
read_fw_blob_addr32_edi(FW_CFG_INITRD)
|
||||
read_fw_blob_addr32(FW_CFG_KERNEL)
|
||||
read_fw_blob_addr32(FW_CFG_INITRD)
|
||||
read_fw_blob_addr32(FW_CFG_CMDLINE)
|
||||
read_fw_blob_addr32(FW_CFG_SETUP)
|
||||
|
||||
/* And now jump into Linux! */
|
||||
mov $0, %eax
|
||||
|
@@ -51,8 +51,6 @@
|
||||
.endm
|
||||
|
||||
#define read_fw_blob_pre(var) \
|
||||
read_fw var ## _ADDR; \
|
||||
mov %eax, %edi; \
|
||||
read_fw var ## _SIZE; \
|
||||
mov %eax, %ecx; \
|
||||
mov $var ## _DATA, %ax; \
|
||||
@@ -68,6 +66,8 @@
|
||||
* Clobbers: %eax, %edx, %es, %ecx, %edi
|
||||
*/
|
||||
#define read_fw_blob(var) \
|
||||
read_fw var ## _ADDR; \
|
||||
mov %eax, %edi; \
|
||||
read_fw_blob_pre(var); \
|
||||
/* old as(1) doesn't like this insn so emit the bytes instead: \
|
||||
rep insb (%dx), %es:(%edi); \
|
||||
@@ -80,7 +80,22 @@
|
||||
*
|
||||
* Clobbers: %eax, %edx, %es, %ecx, %edi
|
||||
*/
|
||||
#define read_fw_blob_addr32(var) \
|
||||
#define read_fw_blob_addr32(var) \
|
||||
read_fw var ## _ADDR; \
|
||||
mov %eax, %edi; \
|
||||
read_fw_blob_pre(var); \
|
||||
/* old as(1) doesn't like this insn so emit the bytes instead: \
|
||||
addr32 rep insb (%dx), %es:(%edi); \
|
||||
*/ \
|
||||
.dc.b 0x67,0xf3,0x6c
|
||||
|
||||
/*
|
||||
* Read a blob from the fw_cfg device in forced addr32 mode, address is in %edi.
|
||||
* Requires _SIZE and _DATA values for the parameter.
|
||||
*
|
||||
* Clobbers: %eax, %edx, %edi, %es, %ecx
|
||||
*/
|
||||
#define read_fw_blob_addr32_edi(var) \
|
||||
read_fw_blob_pre(var); \
|
||||
/* old as(1) doesn't like this insn so emit the bytes instead: \
|
||||
addr32 rep insb (%dx), %es:(%edi); \
|
||||
|
@@ -162,6 +162,31 @@ static void qapi_dealloc_type_enum(Visitor *v, int *obj, const char *strings[],
|
||||
{
|
||||
}
|
||||
|
||||
/* If there's no data present, the dealloc visitor has nothing to free.
|
||||
* Thus, indicate to visitor code that the subsequent union fields can
|
||||
* be skipped. This is not an error condition, since the cleanup of the
|
||||
* rest of an object can continue unhindered, so leave errp unset in
|
||||
* these cases.
|
||||
*
|
||||
* NOTE: In cases where we're attempting to deallocate an object that
|
||||
* may have missing fields, the field indicating the union type may
|
||||
* be missing. In such a case, it's possible we don't have enough
|
||||
* information to differentiate data_present == false from a case where
|
||||
* data *is* present but happens to be a scalar with a value of 0.
|
||||
* This is okay, since in the case of the dealloc visitor there's no
|
||||
* work that needs to done in either situation.
|
||||
*
|
||||
* The current inability in QAPI code to more thoroughly verify a union
|
||||
* type in such cases will likely need to be addressed if we wish to
|
||||
* implement this interface for other types of visitors in the future,
|
||||
* however.
|
||||
*/
|
||||
static bool qapi_dealloc_start_union(Visitor *v, bool data_present,
|
||||
Error **errp)
|
||||
{
|
||||
return data_present;
|
||||
}
|
||||
|
||||
Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
|
||||
{
|
||||
return &v->visitor;
|
||||
@@ -191,6 +216,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
|
||||
v->visitor.type_str = qapi_dealloc_type_str;
|
||||
v->visitor.type_number = qapi_dealloc_type_number;
|
||||
v->visitor.type_size = qapi_dealloc_type_size;
|
||||
v->visitor.start_union = qapi_dealloc_start_union;
|
||||
|
||||
QTAILQ_INIT(&v->stack);
|
||||
|
||||
|
@@ -58,6 +58,21 @@ void visit_end_list(Visitor *v, Error **errp)
|
||||
v->end_list(v, errp);
|
||||
}
|
||||
|
||||
bool visit_start_union(Visitor *v, bool data_present, Error **errp)
|
||||
{
|
||||
if (v->start_union) {
|
||||
return v->start_union(v, data_present, errp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void visit_end_union(Visitor *v, bool data_present, Error **errp)
|
||||
{
|
||||
if (v->end_union) {
|
||||
v->end_union(v, data_present, errp);
|
||||
}
|
||||
}
|
||||
|
||||
void visit_optional(Visitor *v, bool *present, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
|
21
qemu-img.c
21
qemu-img.c
@@ -1378,6 +1378,20 @@ static int img_convert(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!drv->create_opts) {
|
||||
error_report("Format driver '%s' does not support image creation",
|
||||
drv->format_name);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!proto_drv->create_opts) {
|
||||
error_report("Protocol driver '%s' does not support image creation",
|
||||
proto_drv->format_name);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
||||
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
||||
|
||||
@@ -2761,6 +2775,13 @@ static int img_amend(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!bs->drv->create_opts) {
|
||||
error_report("Format driver '%s' does not support any options to amend",
|
||||
fmt);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);
|
||||
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
|
||||
if (options && qemu_opts_do_parse(opts, options, NULL)) {
|
||||
|
11
savevm.c
11
savevm.c
@@ -1245,19 +1245,18 @@ int load_vmstate(const char *name)
|
||||
|
||||
void do_delvm(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockDriverState *bs, *bs1;
|
||||
BlockDriverState *bs;
|
||||
Error *err = NULL;
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
|
||||
bs = find_vmstate_bs();
|
||||
if (!bs) {
|
||||
if (!find_vmstate_bs()) {
|
||||
monitor_printf(mon, "No block device supports snapshots\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bs1 = NULL;
|
||||
while ((bs1 = bdrv_next(bs1))) {
|
||||
if (bdrv_can_snapshot(bs1)) {
|
||||
bs = NULL;
|
||||
while ((bs = bdrv_next(bs))) {
|
||||
if (bdrv_can_snapshot(bs)) {
|
||||
bdrv_snapshot_delete_by_id_or_name(bs, name, &err);
|
||||
if (err) {
|
||||
monitor_printf(mon,
|
||||
|
@@ -357,6 +357,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
if (err) {
|
||||
goto out_obj;
|
||||
}
|
||||
if (!visit_start_union(m, !!(*obj)->data, &err) || err) {
|
||||
goto out_obj;
|
||||
}
|
||||
switch ((*obj)->kind) {
|
||||
''',
|
||||
disc_type = disc_type,
|
||||
@@ -385,6 +388,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
||||
out_obj:
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
visit_end_union(m, !!(*obj)->data, &err);
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
}
|
||||
visit_end_struct(m, &err);
|
||||
out:
|
||||
|
@@ -152,7 +152,7 @@ udp_input(register struct mbuf *m, int iphlen)
|
||||
* Locate pcb for datagram.
|
||||
*/
|
||||
so = slirp->udp_last_so;
|
||||
if (so->so_lport != uh->uh_sport ||
|
||||
if (so == &slirp->udb || so->so_lport != uh->uh_sport ||
|
||||
so->so_laddr.s_addr != ip->ip_src.s_addr) {
|
||||
struct socket *tmp;
|
||||
|
||||
|
@@ -471,6 +471,12 @@ static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env,
|
||||
env->itlb[wi] + ei;
|
||||
}
|
||||
|
||||
static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
|
||||
{
|
||||
return env->sregs[WINDOW_START] |
|
||||
(env->sregs[WINDOW_START] << env->config->nareg / 4);
|
||||
}
|
||||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_MODE0_SUFFIX _ring0
|
||||
#define MMU_MODE1_SUFFIX _ring1
|
||||
|
@@ -235,6 +235,12 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
|
||||
pc, env->sregs[PS]);
|
||||
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
|
||||
} else {
|
||||
uint32_t windowstart = xtensa_replicate_windowstart(env) >>
|
||||
(env->sregs[WINDOW_BASE] + 1);
|
||||
|
||||
if (windowstart & ((1 << callinc) - 1)) {
|
||||
HELPER(window_check)(env, pc, callinc);
|
||||
}
|
||||
env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - (imm << 3);
|
||||
rotate_window(env, callinc);
|
||||
env->sregs[WINDOW_START] |=
|
||||
|
@@ -884,6 +884,11 @@ static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
|
||||
return m;
|
||||
}
|
||||
|
||||
static inline unsigned xtensa_op0_insn_len(unsigned op0)
|
||||
{
|
||||
return op0 >= 8 ? 2 : 3;
|
||||
}
|
||||
|
||||
static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
{
|
||||
#define HAS_OPTION_BITS(opt) do { \
|
||||
@@ -986,6 +991,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
uint8_t b0 = cpu_ldub_code(env, dc->pc);
|
||||
uint8_t b1 = cpu_ldub_code(env, dc->pc + 1);
|
||||
uint8_t b2 = 0;
|
||||
unsigned len = xtensa_op0_insn_len(OP0);
|
||||
|
||||
static const uint32_t B4CONST[] = {
|
||||
0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
|
||||
@@ -995,13 +1001,19 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
|
||||
};
|
||||
|
||||
if (OP0 >= 8) {
|
||||
dc->next_pc = dc->pc + 2;
|
||||
switch (len) {
|
||||
case 2:
|
||||
HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
|
||||
} else {
|
||||
dc->next_pc = dc->pc + 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
b2 = cpu_ldub_code(env, dc->pc + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
RESERVED();
|
||||
}
|
||||
dc->next_pc = dc->pc + len;
|
||||
|
||||
switch (OP0) {
|
||||
case 0: /*QRST*/
|
||||
@@ -2946,6 +2958,12 @@ invalid_opcode:
|
||||
#undef HAS_OPTION
|
||||
}
|
||||
|
||||
static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
|
||||
{
|
||||
uint8_t b0 = cpu_ldub_code(env, dc->pc);
|
||||
return xtensa_op0_insn_len(OP0);
|
||||
}
|
||||
|
||||
static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
@@ -3078,6 +3096,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
|
||||
} while (dc.is_jmp == DISAS_NEXT &&
|
||||
insn_count < max_insns &&
|
||||
dc.pc < next_page_start &&
|
||||
dc.pc + xtensa_insn_len(env, &dc) <= next_page_start &&
|
||||
tcg_ctx.gen_opc_ptr < gen_opc_end);
|
||||
|
||||
reset_litbase(&dc);
|
||||
|
@@ -1302,7 +1302,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
|
||||
so we can reuse that for the base. */
|
||||
base = (TARGET_LONG_BITS == 32 ? TCG_REG_A1 : TCG_REG_A2);
|
||||
tcg_out_tlb_load(s, base, addr_regl, addr_regh, mem_index,
|
||||
s_bits, label_ptr, 1);
|
||||
s_bits, label_ptr, 0);
|
||||
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
|
||||
add_qemu_ldst_label(s, 0, opc, data_regl, data_regh, addr_regl, addr_regh,
|
||||
mem_index, s->code_ptr, label_ptr);
|
||||
|
@@ -187,7 +187,8 @@ check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
|
||||
|
||||
# qom-test works for all sysemu architectures:
|
||||
$(foreach target,$(SYSEMU_TARGET_LIST), \
|
||||
$(eval check-qtest-$(target)-y += tests/qom-test$(EXESUF)))
|
||||
$(if $(findstring tests/qom-test$(EXESUF), $(check-qtest-$(target)-y)),, \
|
||||
$(eval check-qtest-$(target)-y += tests/qom-test$(EXESUF))))
|
||||
|
||||
check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
|
||||
comments.json empty.json funny-char.json indented-expr.json \
|
||||
|
@@ -33,6 +33,9 @@
|
||||
{ 'type': 'UserDefB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'type': 'UserDefC',
|
||||
'data': { 'string1': 'str', 'string2': 'str' } }
|
||||
|
||||
{ 'union': 'UserDefUnion',
|
||||
'base': 'UserDefZero',
|
||||
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
|
||||
@@ -47,6 +50,13 @@
|
||||
# FIXME generated struct UserDefFlatUnion has members for direct base
|
||||
# UserDefOne, but lacks members for indirect base UserDefZero
|
||||
|
||||
# this variant of UserDefFlatUnion defaults to a union that uses fields with
|
||||
# allocated types to test corner cases in the cleanup/dealloc visitor
|
||||
{ 'union': 'UserDefFlatUnion2',
|
||||
'base': 'UserDefUnionBase',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 'UserDefA' } }
|
||||
|
||||
{ 'union': 'UserDefAnonUnion',
|
||||
'discriminator': {},
|
||||
'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
|
||||
|
@@ -6,9 +6,11 @@
|
||||
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
|
||||
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
|
||||
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
|
||||
OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
|
||||
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), ('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
|
||||
OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), ('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
|
||||
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
|
||||
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
|
||||
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
|
||||
@@ -32,6 +34,7 @@
|
||||
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
|
||||
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
|
||||
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
|
||||
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
|
||||
OrderedDict([('type', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
|
||||
|
@@ -14,6 +14,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -21,6 +23,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -38,6 +42,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -45,6 +51,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_update; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -70,7 +78,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 5; imm: off; once: off; write
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -78,7 +90,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 5; imm: off; once: off; write -b
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -102,7 +118,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 28; imm: off; once: off; write
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
read failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -110,12 +130,17 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
Event: l2_load; errno: 28; imm: off; once: off; write -b
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
read failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: on; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -123,6 +148,7 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: on; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -130,6 +156,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -137,6 +165,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -144,6 +174,7 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: on; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -151,6 +182,7 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: on; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -158,6 +190,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -165,6 +199,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_update; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
127 leaked clusters were found on the image.
|
||||
@@ -182,11 +218,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc.write; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc.write; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -204,11 +244,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc.write; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l2_alloc.write; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
1 leaked clusters were found on the image.
|
||||
@@ -226,11 +270,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -246,11 +294,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: write_aio; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -266,11 +318,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -286,51 +342,67 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_load; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 5; imm: off; once: on; write
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 5; imm: off; once: on; write -b
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 28; imm: off; once: on; write
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 28; imm: off; once: on; write -b
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -346,11 +418,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -366,11 +442,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -386,11 +466,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 5; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -406,11 +490,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
|
||||
@@ -429,6 +517,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
55 leaked clusters were found on the image.
|
||||
@@ -436,6 +526,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
251 leaked clusters were found on the image.
|
||||
@@ -453,11 +545,15 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.write; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.write; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -473,6 +569,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
11 leaked clusters were found on the image.
|
||||
@@ -480,6 +578,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
23 leaked clusters were found on the image.
|
||||
@@ -497,6 +597,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
11 leaked clusters were found on the image.
|
||||
@@ -504,6 +606,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
23 leaked clusters were found on the image.
|
||||
@@ -521,6 +625,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
11 leaked clusters were found on the image.
|
||||
@@ -528,6 +634,8 @@ This means waste of disk space, but no harm to data.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write -b
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
23 leaked clusters were found on the image.
|
||||
@@ -543,6 +651,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow.alloc_table; errno: 5; imm: off; once: off
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -553,6 +663,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow.alloc_table; errno: 28; imm: off; once: off
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -563,6 +675,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow.write_table; errno: 5; imm: off; once: off
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -573,6 +687,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow.write_table; errno: 28; imm: off; once: off
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
@@ -583,6 +699,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow.activate_table; errno: 5; imm: off; once: off
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
write failed: Input/output error
|
||||
|
||||
96 leaked clusters were found on the image.
|
||||
@@ -595,6 +713,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
Event: l1_grow.activate_table; errno: 28; imm: off; once: off
|
||||
Failed to flush the L2 table cache: No space left on device
|
||||
Failed to flush the refcount block cache: No space left on device
|
||||
write failed: No space left on device
|
||||
|
||||
96 leaked clusters were found on the image.
|
||||
|
@@ -30,10 +30,14 @@ blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0
|
||||
|
||||
=== Testing blkdebug through filename ===
|
||||
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
|
||||
=== Testing blkdebug through file blockref ===
|
||||
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
|
||||
=== Testing blkdebug on existing block device ===
|
||||
@@ -48,6 +52,8 @@ read failed: Input/output error
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
|
||||
qemu-system-x86_64: Failed to flush the L2 table cache: Input/output error
|
||||
qemu-system-x86_64: Failed to flush the refcount block cache: Input/output error
|
||||
|
||||
|
||||
=== Testing blkverify on existing block device ===
|
||||
@@ -86,5 +92,7 @@ read failed: Input/output error
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
|
||||
qemu-system-x86_64: Failed to flush the L2 table cache: Input/output error
|
||||
qemu-system-x86_64: Failed to flush the refcount block cache: Input/output error
|
||||
|
||||
*** done
|
||||
|
@@ -78,6 +78,8 @@ poke_file "$TEST_IMG" "$offset_backing_file_offset" "\xff\xff\xff\xff\xff\xff\xf
|
||||
poke_file "$TEST_IMG" "$offset_ext_magic" "\x12\x34\x56\x78"
|
||||
poke_file "$TEST_IMG" "$offset_ext_size" "\x7f\xff\xff\xff"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x$(printf %x $offset_ext_size)"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
|
@@ -13,6 +13,8 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
|
||||
no file open, try 'help open'
|
||||
qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
|
||||
no file open, try 'help open'
|
||||
qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
|
||||
no file open, try 'help open'
|
||||
|
||||
== Huge refcount table size ==
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
|
@@ -218,6 +218,23 @@ run_qemu <<EOF
|
||||
{ "execute": "quit" }
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo === Missing driver ===
|
||||
echo
|
||||
|
||||
_make_test_img -o encryption=on $size
|
||||
run_qemu -S <<EOF
|
||||
{ "execute": "qmp_capabilities" }
|
||||
{ "execute": "blockdev-add",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"id": "disk"
|
||||
}
|
||||
}
|
||||
}
|
||||
{ "execute": "quit" }
|
||||
EOF
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
|
@@ -64,4 +64,17 @@ QMP_VERSION
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
|
||||
|
||||
|
||||
=== Missing driver ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
|
||||
Testing: -S
|
||||
QMP_VERSION
|
||||
{"return": {}}
|
||||
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'driver', expected: string"}}
|
||||
{"return": {}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
|
||||
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
|
||||
|
||||
*** done
|
||||
|
@@ -24,6 +24,8 @@ read 512/512 bytes at offset 0
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
wrote 512/512 bytes at offset 229376
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
Failed to flush the L2 table cache: Input/output error
|
||||
Failed to flush the refcount block cache: Input/output error
|
||||
read failed: Input/output error
|
||||
|
||||
=== Testing qemu-img info output ===
|
||||
|
76
tests/qemu-iotests/113
Executable file
76
tests/qemu-iotests/113
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Test case for accessing creation options on image formats and
|
||||
# protocols not supporting image creation
|
||||
#
|
||||
# Copyright (C) 2014 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=mreitz@redhat.com
|
||||
|
||||
seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
# We can only test one format here because we need its sample file
|
||||
_supported_fmt bochs
|
||||
_supported_proto nbd
|
||||
_supported_os Linux
|
||||
|
||||
echo
|
||||
echo '=== Unsupported image creation in qemu-img create ==='
|
||||
echo
|
||||
|
||||
$QEMU_IMG create -f $IMGFMT nbd://example.com 2>&1 64M | _filter_imgfmt
|
||||
|
||||
echo
|
||||
echo '=== Unsupported image creation in qemu-img convert ==='
|
||||
echo
|
||||
|
||||
# We could use any input image format here, but this is a bochs test, so just
|
||||
# use the bochs image
|
||||
_use_sample_img empty.bochs.bz2
|
||||
$QEMU_IMG convert -f $IMGFMT -O $IMGFMT "$TEST_IMG" nbd://example.com 2>&1 \
|
||||
| _filter_imgfmt
|
||||
|
||||
echo
|
||||
echo '=== Unsupported format in qemu-img amend ==='
|
||||
echo
|
||||
|
||||
# The protocol does not matter here
|
||||
_use_sample_img empty.bochs.bz2
|
||||
$QEMU_IMG amend -f $IMGFMT -o foo=bar "$TEST_IMG" 2>&1 | _filter_imgfmt
|
||||
|
||||
|
||||
# success, all done
|
||||
echo
|
||||
echo '*** done'
|
||||
rm -f $seq.full
|
||||
status=0
|
15
tests/qemu-iotests/113.out
Normal file
15
tests/qemu-iotests/113.out
Normal file
@@ -0,0 +1,15 @@
|
||||
QA output created by 113
|
||||
|
||||
=== Unsupported image creation in qemu-img create ===
|
||||
|
||||
qemu-img: nbd://example.com: Format driver 'IMGFMT' does not support image creation
|
||||
|
||||
=== Unsupported image creation in qemu-img convert ===
|
||||
|
||||
qemu-img: Format driver 'IMGFMT' does not support image creation
|
||||
|
||||
=== Unsupported format in qemu-img amend ===
|
||||
|
||||
qemu-img: Format driver 'IMGFMT' does not support any options to amend
|
||||
|
||||
*** done
|
61
tests/qemu-iotests/114
Executable file
61
tests/qemu-iotests/114
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Test invalid backing file format in qcow2 images
|
||||
#
|
||||
# Copyright (C) 2014 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=kwolf@redhat.com
|
||||
|
||||
seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
_supported_fmt qcow2
|
||||
_supported_proto generic
|
||||
_supported_os Linux
|
||||
|
||||
|
||||
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
|
||||
_make_test_img -b "$TEST_IMG.base" 64M
|
||||
|
||||
# Set an invalid backing file format
|
||||
$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0xE2792ACA "foo"
|
||||
_img_info
|
||||
|
||||
# Try opening the image. Should fail (and not probe) in the first case, but
|
||||
# overriding the backing file format should be possible.
|
||||
$QEMU_IO -c "open $TEST_IMG" -c "read 0 4k" 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
$QEMU_IO -c "open -o backing.driver=$IMGFMT $TEST_IMG" -c "read 0 4k" | _filter_qemu_io
|
||||
|
||||
# success, all done
|
||||
echo '*** done'
|
||||
rm -f $seq.full
|
||||
status=0
|
13
tests/qemu-iotests/114.out
Normal file
13
tests/qemu-iotests/114.out
Normal file
@@ -0,0 +1,13 @@
|
||||
QA output created by 114
|
||||
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 64M (67108864 bytes)
|
||||
cluster_size: 65536
|
||||
backing file: TEST_DIR/t.IMGFMT.base
|
||||
backing file format: foo
|
||||
qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
|
||||
read 4096/4096 bytes at offset 0
|
||||
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
*** done
|
@@ -189,7 +189,9 @@ _cleanup_test_img()
|
||||
case "$IMGPROTO" in
|
||||
|
||||
nbd)
|
||||
kill $QEMU_NBD_PID
|
||||
if [ -n "$QEMU_NBD_PID" ]; then
|
||||
kill $QEMU_NBD_PID
|
||||
fi
|
||||
rm -f "$TEST_IMG_FILE"
|
||||
;;
|
||||
file)
|
||||
|
@@ -101,3 +101,5 @@
|
||||
092 rw auto quick
|
||||
095 rw auto quick
|
||||
101 rw auto quick
|
||||
113 rw auto quick
|
||||
114 rw auto quick
|
||||
|
@@ -7,6 +7,10 @@ import string
|
||||
class QcowHeaderExtension:
|
||||
|
||||
def __init__(self, magic, length, data):
|
||||
if length % 8 != 0:
|
||||
padding = 8 - (length % 8)
|
||||
data += "\0" * padding
|
||||
|
||||
self.magic = magic
|
||||
self.length = length
|
||||
self.data = data
|
||||
|
@@ -641,7 +641,7 @@ test cross_page_tb
|
||||
witlb a2, a3
|
||||
wdtlb a2, a3
|
||||
|
||||
movi a2, 0x00007ffd
|
||||
movi a2, 0x00007ffc
|
||||
movi a3, 20f
|
||||
movi a4, 21f
|
||||
sub a4, a4, a3
|
||||
@@ -651,7 +651,7 @@ test cross_page_tb
|
||||
addi a2, a2, 1
|
||||
addi a3, a3, 1
|
||||
1:
|
||||
movi a2, 0x00007ffd
|
||||
movi a2, 0x00007ffc
|
||||
movi a3, 0x00008000
|
||||
/* DTLB: OK, ITLB: OK */
|
||||
jx a2
|
||||
@@ -668,10 +668,10 @@ test cross_page_tb
|
||||
movi a3, 1
|
||||
assert eq, a2, a3
|
||||
rsr a2, epc1
|
||||
movi a3, 0x8000
|
||||
movi a3, 0x7fff
|
||||
assert eq, a2, a3
|
||||
rsr a2, excsave1
|
||||
movi a3, 0x00007ffd
|
||||
movi a3, 0x00007ffc
|
||||
assert ne, a2, a3
|
||||
|
||||
reset_ps
|
||||
@@ -680,7 +680,7 @@ test cross_page_tb
|
||||
movi a2, 0x0400000c /* PPN */
|
||||
movi a3, 0x00008000 /* VPN */
|
||||
wdtlb a2, a3
|
||||
movi a2, 0x00007ffd
|
||||
movi a2, 0x00007ffc
|
||||
movi a3, 0x00008000
|
||||
/* DTLB: FAIL, ITLB: OK */
|
||||
jx a2
|
||||
@@ -689,10 +689,10 @@ test cross_page_tb
|
||||
movi a3, 28
|
||||
assert eq, a2, a3
|
||||
rsr a2, epc1
|
||||
movi a3, 0x7ffd
|
||||
movi a3, 0x7ffc
|
||||
assert eq, a2, a3
|
||||
rsr a2, excsave1
|
||||
movi a3, 0x00007ffd
|
||||
movi a3, 0x00007ffc
|
||||
assert eq, a2, a3
|
||||
|
||||
reset_ps
|
||||
@@ -703,7 +703,7 @@ test cross_page_tb
|
||||
witlb a2, a3
|
||||
movi a2, 0x04000003 /* PPN */
|
||||
wdtlb a2, a3
|
||||
movi a2, 0x00007ffd
|
||||
movi a2, 0x00007ffc
|
||||
movi a3, 0x00008000
|
||||
/* DTLB: OK, ITLB: FAIL */
|
||||
jx a2
|
||||
@@ -712,10 +712,10 @@ test cross_page_tb
|
||||
movi a3, 20
|
||||
assert eq, a2, a3
|
||||
rsr a2, epc1
|
||||
movi a3, 0x8000
|
||||
movi a3, 0x7fff
|
||||
assert eq, a2, a3
|
||||
rsr a2, excsave1
|
||||
movi a3, 0x00007ffd
|
||||
movi a3, 0x00007ffc
|
||||
assert ne, a2, a3
|
||||
|
||||
reset_ps
|
||||
@@ -724,7 +724,7 @@ test cross_page_tb
|
||||
movi a2, 0x0400000c /* PPN */
|
||||
movi a3, 0x00008000 /* VPN */
|
||||
wdtlb a2, a3
|
||||
movi a2, 0x00007ffd
|
||||
movi a2, 0x00007ffc
|
||||
movi a3, 0x00008000
|
||||
/* DTLB: FAIL, ITLB: FAIL */
|
||||
jx a2
|
||||
@@ -733,10 +733,10 @@ test cross_page_tb
|
||||
movi a3, 28
|
||||
assert eq, a2, a3
|
||||
rsr a2, epc1
|
||||
movi a3, 0x7ffd
|
||||
movi a3, 0x7ffc
|
||||
assert eq, a2, a3
|
||||
rsr a2, excsave1
|
||||
movi a3, 0x00007ffd
|
||||
movi a3, 0x00007ffc
|
||||
assert eq, a2, a3
|
||||
test_end
|
||||
|
||||
|
@@ -260,6 +260,21 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
|
||||
qapi_free_UserDefFlatUnion(tmp);
|
||||
}
|
||||
|
||||
static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
UserDefFlatUnion2 *tmp = NULL;
|
||||
Error *err = NULL;
|
||||
Visitor *v;
|
||||
|
||||
/* test situation where discriminator field ('enum1' here) is missing */
|
||||
v = validate_test_init(data, "{ 'string': 'c', 'string1': 'd', 'string2': 'e' }");
|
||||
|
||||
visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
|
||||
g_assert(err);
|
||||
qapi_free_UserDefFlatUnion2(tmp);
|
||||
}
|
||||
|
||||
static void test_validate_fail_union_anon(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
@@ -310,6 +325,8 @@ int main(int argc, char **argv)
|
||||
&testdata, test_validate_fail_union);
|
||||
validate_test_add("/visitor/input-strict/fail/union-flat",
|
||||
&testdata, test_validate_fail_union_flat);
|
||||
validate_test_add("/visitor/input-strict/fail/union-flat-no-discriminator",
|
||||
&testdata, test_validate_fail_union_flat_no_discrim);
|
||||
validate_test_add("/visitor/input-strict/fail/union-anon",
|
||||
&testdata, test_validate_fail_union_anon);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user