diff options
138 files changed, 2089 insertions, 1951 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index d12518c08f..aa1dd76dc2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -253,6 +253,7 @@ S: Maintained F: target/s390x/ F: hw/s390x/ F: disas/s390.c +F: tests/tcg/s390x/ L: qemu-s390x@nongnu.org SH4 @@ -1236,7 +1237,8 @@ virtio-ccw M: Cornelia Huck <cohuck@redhat.com> M: Christian Borntraeger <borntraeger@de.ibm.com> S: Supported -F: hw/s390x/virtio-ccw.[hc] +F: hw/s390x/virtio-ccw*.[hc] +F: hw/s390x/vhost-vsock-ccw.c T: git git://github.com/cohuck/qemu.git s390-next T: git git://github.com/borntraeger/qemu.git s390-next L: qemu-s390x@nongnu.org diff --git a/block/backup.c b/block/backup.c index 8630d32926..4d084f6ca6 100644 --- a/block/backup.c +++ b/block/backup.c @@ -380,18 +380,6 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job, } } -typedef struct { - int ret; -} BackupCompleteData; - -static void backup_complete(Job *job, void *opaque) -{ - BackupCompleteData *data = opaque; - - job_completed(job, data->ret, NULL); - g_free(data); -} - static bool coroutine_fn yield_and_check(BackupBlockJob *job) { uint64_t delay_ns; @@ -480,60 +468,59 @@ static void backup_incremental_init_copy_bitmap(BackupBlockJob *job) bdrv_dirty_iter_free(dbi); } -static void coroutine_fn backup_run(void *opaque) +static int coroutine_fn backup_run(Job *job, Error **errp) { - BackupBlockJob *job = opaque; - BackupCompleteData *data; - BlockDriverState *bs = blk_bs(job->common.blk); + BackupBlockJob *s = container_of(job, BackupBlockJob, common.job); + BlockDriverState *bs = blk_bs(s->common.blk); int64_t offset, nb_clusters; int ret = 0; - QLIST_INIT(&job->inflight_reqs); - qemu_co_rwlock_init(&job->flush_rwlock); + QLIST_INIT(&s->inflight_reqs); + qemu_co_rwlock_init(&s->flush_rwlock); - nb_clusters = DIV_ROUND_UP(job->len, job->cluster_size); - job_progress_set_remaining(&job->common.job, job->len); + nb_clusters = DIV_ROUND_UP(s->len, s->cluster_size); + job_progress_set_remaining(job, s->len); - job->copy_bitmap = hbitmap_alloc(nb_clusters, 0); - if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { - backup_incremental_init_copy_bitmap(job); + s->copy_bitmap = hbitmap_alloc(nb_clusters, 0); + if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { + backup_incremental_init_copy_bitmap(s); } else { - hbitmap_set(job->copy_bitmap, 0, nb_clusters); + hbitmap_set(s->copy_bitmap, 0, nb_clusters); } - job->before_write.notify = backup_before_write_notify; - bdrv_add_before_write_notifier(bs, &job->before_write); + s->before_write.notify = backup_before_write_notify; + bdrv_add_before_write_notifier(bs, &s->before_write); - if (job->sync_mode == MIRROR_SYNC_MODE_NONE) { + if (s->sync_mode == MIRROR_SYNC_MODE_NONE) { /* All bits are set in copy_bitmap to allow any cluster to be copied. * This does not actually require them to be copied. */ - while (!job_is_cancelled(&job->common.job)) { + while (!job_is_cancelled(job)) { /* Yield until the job is cancelled. We just let our before_write * notify callback service CoW requests. */ - job_yield(&job->common.job); + job_yield(job); } - } else if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { - ret = backup_run_incremental(job); + } else if (s->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) { + ret = backup_run_incremental(s); } else { /* Both FULL and TOP SYNC_MODE's require copying.. */ - for (offset = 0; offset < job->len; - offset += job->cluster_size) { + for (offset = 0; offset < s->len; + offset += s->cluster_size) { bool error_is_read; int alloced = 0; - if (yield_and_check(job)) { + if (yield_and_check(s)) { break; } - if (job->sync_mode == MIRROR_SYNC_MODE_TOP) { + if (s->sync_mode == MIRROR_SYNC_MODE_TOP) { int i; int64_t n; /* Check to see if these blocks are already in the * backing file. */ - for (i = 0; i < job->cluster_size;) { + for (i = 0; i < s->cluster_size;) { /* bdrv_is_allocated() only returns true/false based * on the first set of sectors it comes across that * are are all in the same state. @@ -542,7 +529,7 @@ static void coroutine_fn backup_run(void *opaque) * needed but at some point that is always the case. */ alloced = bdrv_is_allocated(bs, offset + i, - job->cluster_size - i, &n); + s->cluster_size - i, &n); i += n; if (alloced || n == 0) { @@ -560,33 +547,31 @@ static void coroutine_fn backup_run(void *opaque) if (alloced < 0) { ret = alloced; } else { - ret = backup_do_cow(job, offset, job->cluster_size, + ret = backup_do_cow(s, offset, s->cluster_size, &error_is_read, false); } if (ret < 0) { /* Depending on error action, fail now or retry cluster */ BlockErrorAction action = - backup_error_action(job, error_is_read, -ret); + backup_error_action(s, error_is_read, -ret); if (action == BLOCK_ERROR_ACTION_REPORT) { break; } else { - offset -= job->cluster_size; + offset -= s->cluster_size; continue; } } } } - notifier_with_return_remove(&job->before_write); + notifier_with_return_remove(&s->before_write); /* wait until pending backup_do_cow() calls have completed */ - qemu_co_rwlock_wrlock(&job->flush_rwlock); - qemu_co_rwlock_unlock(&job->flush_rwlock); - hbitmap_free(job->copy_bitmap); + qemu_co_rwlock_wrlock(&s->flush_rwlock); + qemu_co_rwlock_unlock(&s->flush_rwlock); + hbitmap_free(s->copy_bitmap); - data = g_malloc(sizeof(*data)); - data->ret = ret; - job_defer_to_main_loop(&job->common.job, backup_complete, data); + return ret; } static const BlockJobDriver backup_job_driver = { @@ -596,7 +581,7 @@ static const BlockJobDriver backup_job_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = backup_run, + .run = backup_run, .commit = backup_commit, .abort = backup_abort, .clean = backup_clean, diff --git a/block/block-backend.c b/block/block-backend.c index fa120630be..14a1b7ac6a 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -980,8 +980,7 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp) if (tray_was_open != tray_is_open) { char *id = blk_get_attached_dev_id(blk); - qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open, - &error_abort); + qapi_event_send_device_tray_moved(blk_name(blk), id, tray_is_open); g_free(id); } } @@ -1665,8 +1664,7 @@ static void send_qmp_error_event(BlockBackend *blk, qapi_event_send_block_io_error(blk_name(blk), !!bs, bs ? bdrv_get_node_name(bs) : NULL, optype, action, blk_iostatus_is_enabled(blk), - error == ENOSPC, strerror(error), - &error_abort); + error == ENOSPC, strerror(error)); } /* This is done by device models because, while the block layer knows @@ -1782,7 +1780,7 @@ void blk_eject(BlockBackend *blk, bool eject_flag) * the frontend experienced a tray event. */ id = blk_get_attached_dev_id(blk); qapi_event_send_device_tray_moved(blk_name(blk), id, - eject_flag, &error_abort); + eject_flag); g_free(id); } diff --git a/block/commit.c b/block/commit.c index eb414579bd..da69165de3 100644 --- a/block/commit.c +++ b/block/commit.c @@ -68,19 +68,13 @@ static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base, return 0; } -typedef struct { - int ret; -} CommitCompleteData; - -static void commit_complete(Job *job, void *opaque) +static void commit_exit(Job *job) { CommitBlockJob *s = container_of(job, CommitBlockJob, common.job); BlockJob *bjob = &s->common; - CommitCompleteData *data = opaque; BlockDriverState *top = blk_bs(s->top); BlockDriverState *base = blk_bs(s->base); BlockDriverState *commit_top_bs = s->commit_top_bs; - int ret = data->ret; bool remove_commit_top_bs = false; /* Make sure commit_top_bs and top stay around until bdrv_replace_node() */ @@ -91,10 +85,10 @@ static void commit_complete(Job *job, void *opaque) * the normal backing chain can be restored. */ blk_unref(s->base); - if (!job_is_cancelled(job) && ret == 0) { + if (!job_is_cancelled(job) && job->ret == 0) { /* success */ - ret = bdrv_drop_intermediate(s->commit_top_bs, base, - s->backing_file_str); + job->ret = bdrv_drop_intermediate(s->commit_top_bs, base, + s->backing_file_str); } else { /* XXX Can (or should) we somehow keep 'consistent read' blocked even * after the failed/cancelled commit job is gone? If we already wrote @@ -117,9 +111,6 @@ static void commit_complete(Job *job, void *opaque) * bdrv_set_backing_hd() to fail. */ block_job_remove_all_bdrv(bjob); - job_completed(job, ret, NULL); - g_free(data); - /* If bdrv_drop_intermediate() didn't already do that, remove the commit * filter driver from the backing chain. Do this as the final step so that * the 'consistent read' permission can be granted. */ @@ -134,10 +125,9 @@ static void commit_complete(Job *job, void *opaque) bdrv_unref(top); } -static void coroutine_fn commit_run(void *opaque) +static int coroutine_fn commit_run(Job *job, Error **errp) { - CommitBlockJob *s = opaque; - CommitCompleteData *data; + CommitBlockJob *s = container_of(job, CommitBlockJob, common.job); int64_t offset; uint64_t delay_ns = 0; int ret = 0; @@ -210,9 +200,7 @@ static void coroutine_fn commit_run(void *opaque) out: qemu_vfree(buf); - data = g_malloc(sizeof(*data)); - data->ret = ret; - job_defer_to_main_loop(&s->common.job, commit_complete, data); + return ret; } static const BlockJobDriver commit_job_driver = { @@ -222,7 +210,8 @@ static const BlockJobDriver commit_job_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = commit_run, + .run = commit_run, + .exit = commit_exit, }, }; diff --git a/block/create.c b/block/create.c index 915cd41bcc..95341219ef 100644 --- a/block/create.c +++ b/block/create.c @@ -34,33 +34,26 @@ typedef struct BlockdevCreateJob { Job common; BlockDriver *drv; BlockdevCreateOptions *opts; - int ret; - Error *err; } BlockdevCreateJob; -static void blockdev_create_complete(Job *job, void *opaque) +static int coroutine_fn blockdev_create_run(Job *job, Error **errp) { BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common); - - job_completed(job, s->ret, s->err); -} - -static void coroutine_fn blockdev_create_run(void *opaque) -{ - BlockdevCreateJob *s = opaque; + int ret; job_progress_set_remaining(&s->common, 1); - s->ret = s->drv->bdrv_co_create(s->opts, &s->err); + ret = s->drv->bdrv_co_create(s->opts, errp); job_progress_update(&s->common, 1); qapi_free_BlockdevCreateOptions(s->opts); - job_defer_to_main_loop(&s->common, blockdev_create_complete, NULL); + + return ret; } static const JobDriver blockdev_create_job_driver = { .instance_size = sizeof(BlockdevCreateJob), .job_type = JOB_TYPE_CREATE, - .start = blockdev_create_run, + .run = blockdev_create_run, }; void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, diff --git a/block/mirror.c b/block/mirror.c index 6cc10df5c9..b8941db6c1 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -607,26 +607,22 @@ static void mirror_wait_for_all_io(MirrorBlockJob *s) } } -typedef struct { - int ret; -} MirrorExitData; - -static void mirror_exit(Job *job, void *opaque) +static void mirror_exit(Job *job) { MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job); BlockJob *bjob = &s->common; - MirrorExitData *data = opaque; MirrorBDSOpaque *bs_opaque = s->mirror_top_bs->opaque; AioContext *replace_aio_context = NULL; BlockDriverState *src = s->mirror_top_bs->backing->bs; BlockDriverState *target_bs = blk_bs(s->target); BlockDriverState *mirror_top_bs = s->mirror_top_bs; Error *local_err = NULL; + int ret = job->ret; bdrv_release_dirty_bitmap(src, s->dirty_bitmap); - /* Make sure that the source BDS doesn't go away before we called - * job_completed(). */ + /* Make sure that the source BDS doesn't go away during bdrv_replace_node, + * before we can call bdrv_drained_end */ bdrv_ref(src); bdrv_ref(mirror_top_bs); bdrv_ref(target_bs); @@ -652,7 +648,7 @@ static void mirror_exit(Job *job, void *opaque) bdrv_set_backing_hd(target_bs, backing, &local_err); if (local_err) { error_report_err(local_err); - data->ret = -EPERM; + ret = -EPERM; } } } @@ -662,7 +658,7 @@ static void mirror_exit(Job *job, void *opaque) aio_context_acquire(replace_aio_context); } - if (s->should_complete && data->ret == 0) { + if (s->should_complete && ret == 0) { BlockDriverState *to_replace = src; if (s->to_replace) { to_replace = s->to_replace; @@ -679,7 +675,7 @@ static void mirror_exit(Job *job, void *opaque) bdrv_drained_end(target_bs); if (local_err) { error_report_err(local_err); - data->ret = -EPERM; + ret = -EPERM; } } if (s->to_replace) { @@ -710,12 +706,12 @@ static void mirror_exit(Job *job, void *opaque) blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort); bs_opaque->job = NULL; - job_completed(job, data->ret, NULL); - g_free(data); bdrv_drained_end(src); bdrv_unref(mirror_top_bs); bdrv_unref(src); + + job->ret = ret; } static void mirror_throttle(MirrorBlockJob *s) @@ -812,10 +808,9 @@ static int mirror_flush(MirrorBlockJob *s) return ret; } -static void coroutine_fn mirror_run(void *opaque) +static int coroutine_fn mirror_run(Job *job, Error **errp) { - MirrorBlockJob *s = opaque; - MirrorExitData *data; + MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job); BlockDriverState *bs = s->mirror_top_bs->backing->bs; BlockDriverState *target_bs = blk_bs(s->target); bool need_drain = true; @@ -1035,13 +1030,11 @@ immediate_exit: g_free(s->in_flight_bitmap); bdrv_dirty_iter_free(s->dbi); - data = g_malloc(sizeof(*data)); - data->ret = ret; - if (need_drain) { bdrv_drained_begin(bs); } - job_defer_to_main_loop(&s->common.job, mirror_exit, data); + + return ret; } static void mirror_complete(Job *job, Error **errp) @@ -1138,7 +1131,8 @@ static const BlockJobDriver mirror_job_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = mirror_run, + .run = mirror_run, + .exit = mirror_exit, .pause = mirror_pause, .complete = mirror_complete, }, @@ -1154,7 +1148,8 @@ static const BlockJobDriver commit_active_job_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = mirror_run, + .run = mirror_run, + .exit = mirror_exit, .pause = mirror_pause, .complete = mirror_complete, }, diff --git a/block/qcow2.c b/block/qcow2.c index ec9e6238a0..c13153735a 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -4659,7 +4659,7 @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset, *node_name != '\0', node_name, message, offset >= 0, offset, size >= 0, size, - fatal, &error_abort); + fatal); g_free(message); if (fatal) { diff --git a/block/quorum.c b/block/quorum.c index 9152da8c58..eb526cc0f1 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -199,7 +199,7 @@ static void quorum_report_bad(QuorumOpType type, uint64_t offset, } qapi_event_send_quorum_report_bad(type, !!msg, msg, node_name, start_sector, - end_sector - start_sector, &error_abort); + end_sector - start_sector); } static void quorum_report_failure(QuorumAIOCB *acb) @@ -210,7 +210,7 @@ static void quorum_report_failure(QuorumAIOCB *acb) BDRV_SECTOR_SIZE); qapi_event_send_quorum_failure(reference, start_sector, - end_sector - start_sector, &error_abort); + end_sector - start_sector); } static int quorum_vote_error(QuorumAIOCB *acb); diff --git a/block/stream.c b/block/stream.c index 9264b68a1e..67e1e72e23 100644 --- a/block/stream.c +++ b/block/stream.c @@ -54,20 +54,16 @@ static int coroutine_fn stream_populate(BlockBackend *blk, return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ); } -typedef struct { - int ret; -} StreamCompleteData; - -static void stream_complete(Job *job, void *opaque) +static void stream_exit(Job *job) { StreamBlockJob *s = container_of(job, StreamBlockJob, common.job); BlockJob *bjob = &s->common; - StreamCompleteData *data = opaque; BlockDriverState *bs = blk_bs(bjob->blk); BlockDriverState *base = s->base; Error *local_err = NULL; + int ret = job->ret; - if (!job_is_cancelled(job) && bs->backing && data->ret == 0) { + if (!job_is_cancelled(job) && bs->backing && ret == 0) { const char *base_id = NULL, *base_fmt = NULL; if (base) { base_id = s->backing_file_str; @@ -75,11 +71,11 @@ static void stream_complete(Job *job, void *opaque) base_fmt = base->drv->format_name; } } - data->ret = bdrv_change_backing_file(bs, base_id, base_fmt); + ret = bdrv_change_backing_file(bs, base_id, base_fmt); bdrv_set_backing_hd(bs, base, &local_err); if (local_err) { error_report_err(local_err); - data->ret = -EPERM; + ret = -EPERM; goto out; } } @@ -93,14 +89,12 @@ out: } g_free(s->backing_file_str); - job_completed(job, data->ret, NULL); - g_free(data); + job->ret = ret; } -static void coroutine_fn stream_run(void *opaque) +static int coroutine_fn stream_run(Job *job, Error **errp) { - StreamBlockJob *s = opaque; - StreamCompleteData *data; + StreamBlockJob *s = container_of(job, StreamBlockJob, common.job); BlockBackend *blk = s->common.blk; BlockDriverState *bs = blk_bs(blk); BlockDriverState *base = s->base; @@ -203,9 +197,7 @@ static void coroutine_fn stream_run(void *opaque) out: /* Modify backing chain and close BDSes in main loop */ - data = g_malloc(sizeof(*data)); - data->ret = ret; - job_defer_to_main_loop(&s->common.job, stream_complete, data); + return ret; } static const BlockJobDriver stream_job_driver = { @@ -213,7 +205,8 @@ static const BlockJobDriver stream_job_driver = { .instance_size = sizeof(StreamBlockJob), .job_type = JOB_TYPE_STREAM, .free = block_job_free, - .start = stream_run, + .run = stream_run, + .exit = stream_exit, .user_resume = block_job_user_resume, .drain = block_job_drain, }, diff --git a/block/write-threshold.c b/block/write-threshold.c index 1d48fc2077..85b78dc2a9 100644 --- a/block/write-threshold.c +++ b/block/write-threshold.c @@ -63,8 +63,7 @@ static int coroutine_fn before_write_notify(NotifierWithReturn *notifier, qapi_event_send_block_write_threshold( bs->node_name, amount, - bs->write_threshold_offset, - &error_abort); + bs->write_threshold_offset); /* autodisable to avoid flooding the monitor */ write_threshold_disable(bs); diff --git a/blockjob.c b/blockjob.c index be5903aa96..bf7ef48f98 100644 --- a/blockjob.c +++ b/blockjob.c @@ -315,8 +315,7 @@ static void block_job_event_cancelled(Notifier *n, void *opaque) job->job.id, job->job.progress_total, job->job.progress_current, - job->speed, - &error_abort); + job->speed); } static void block_job_event_completed(Notifier *n, void *opaque) @@ -338,8 +337,7 @@ static void block_job_event_completed(Notifier *n, void *opaque) job->job.progress_current, job->speed, !!msg, - msg, - &error_abort); + msg); } static void block_job_event_pending(Notifier *n, void *opaque) @@ -351,8 +349,7 @@ static void block_job_event_pending(Notifier *n, void *opaque) } qapi_event_send_block_job_pending(job_type(&job->job), - job->job.id, - &error_abort); + job->job.id); } static void block_job_event_ready(Notifier *n, void *opaque) @@ -367,7 +364,7 @@ static void block_job_event_ready(Notifier *n, void *opaque) job->job.id, job->job.progress_total, job->job.progress_current, - job->speed, &error_abort); + job->speed); } @@ -494,7 +491,7 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err, qapi_event_send_block_job_error(job->job.id, is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE, - action, &error_abort); + action); } if (action == BLOCK_ERROR_ACTION_STOP) { job_pause(&job->job); @@ -195,8 +195,7 @@ supported_kvm_target() { i386:i386 | i386:x86_64 | i386:x32 | \ x86_64:i386 | x86_64:x86_64 | x86_64:x32 | \ mips:mips | mipsel:mips | \ - ppc:ppc | ppcemb:ppc | ppc64:ppc | \ - ppc:ppc64 | ppcemb:ppc64 | ppc64:ppc64 | \ + ppc:ppc | ppc64:ppc | ppc:ppc64 | ppc64:ppc64 | \ s390x:s390x) return 0 ;; @@ -6951,7 +6950,7 @@ if test "$linux" = "yes" ; then i386|x86_64|x32) linux_arch=x86 ;; - ppcemb|ppc|ppc64) + ppc|ppc64) linux_arch=powerpc ;; s390x) @@ -6981,7 +6980,7 @@ target_name=$(echo $target | cut -d '-' -f 1) target_bigendian="no" case "$target_name" in - armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) + armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -7109,12 +7108,6 @@ case "$target_name" in gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml" target_compiler=$cross_cc_powerpc ;; - ppcemb) - TARGET_BASE_ARCH=ppc - TARGET_ABI_DIR=ppc - gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml" - target_compiler=$cross_cc_ppcemb - ;; ppc64) TARGET_BASE_ARCH=ppc TARGET_ABI_DIR=ppc @@ -1053,7 +1053,7 @@ static int do_vm_stop(RunState state, bool send_stop) runstate_set(state); vm_state_notify(0, state); if (send_stop) { - qapi_event_send_stop(&error_abort); + qapi_event_send_stop(); } } @@ -2107,13 +2107,13 @@ int vm_prepare_start(void) * the STOP event. */ if (runstate_is_running()) { - qapi_event_send_stop(&error_abort); - qapi_event_send_resume(&error_abort); + qapi_event_send_stop(); + qapi_event_send_resume(); return -1; } /* We are sending this now, but the CPUs will be resumed shortly later */ - qapi_event_send_resume(&error_abort); + qapi_event_send_resume(); replay_enable_events(); cpu_enable_ticks(); @@ -2251,7 +2251,6 @@ static CpuInfoArch sysemu_target_to_cpuinfo_arch(SysEmuTarget target) return CPU_INFO_ARCH_X86; case SYS_EMU_TARGET_PPC: - case SYS_EMU_TARGET_PPCEMB: case SYS_EMU_TARGET_PPC64: return CPU_INFO_ARCH_PPC; diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak deleted file mode 100644 index ac44f150c6..0000000000 --- a/default-configs/ppcemb-softmmu.mak +++ /dev/null @@ -1,23 +0,0 @@ -# Default configuration for ppcemb-softmmu - -include pci.mak -include sound.mak -include usb.mak -CONFIG_PPC4XX=y -CONFIG_M48T59=y -CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y -CONFIG_I8257=y -CONFIG_OPENPIC=y -CONFIG_PFLASH_CFI01=y -CONFIG_PFLASH_CFI02=y -CONFIG_PTIMER=y -CONFIG_I8259=y -CONFIG_XILINX=y -CONFIG_XILINX_ETHLITE=y -CONFIG_USB_EHCI_SYSBUS=y -CONFIG_SM501=y -CONFIG_DDC=y -CONFIG_IDE_SII3112=y -CONFIG_I2C=y -CONFIG_BITBANG_I2C=y diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index c2e11465f0..53eaf01f34 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -1035,7 +1035,7 @@ Example: #ifndef EXAMPLE_QAPI_TYPES_H #define EXAMPLE_QAPI_TYPES_H -[Built-in types omitted...] + #include "qapi/qapi-builtin-types.h" typedef struct UserDefOne UserDefOne; @@ -1062,7 +1062,7 @@ Example: UserDefOneList *arg1; }; - #endif + #endif /* EXAMPLE_QAPI_TYPES_H */ $ cat qapi-generated/example-qapi-types.c [Uninteresting stuff omitted...] @@ -1092,6 +1092,8 @@ Example: visit_free(v); } +[Uninteresting stuff omitted...] + === Code generated for visiting QAPI types === These are the visitor functions used to walk through and convert @@ -1118,7 +1120,9 @@ Example: #ifndef EXAMPLE_QAPI_VISIT_H #define EXAMPLE_QAPI_VISIT_H -[Visitors for built-in types omitted...] + #include "qapi/qapi-builtin-visit.h" + #include "example-qapi-types.h" + void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp); void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp); @@ -1126,7 +1130,7 @@ Example: void visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp); - #endif + #endif /* EXAMPLE_QAPI_VISIT_H */ $ cat qapi-generated/example-qapi-visit.c [Uninteresting stuff omitted...] @@ -1219,6 +1223,8 @@ Example: error_propagate(errp, err); } +[Uninteresting stuff omitted...] + === Code generated for commands === These are the marshaling/dispatch functions for the commands defined @@ -1238,18 +1244,17 @@ Example: $ cat qapi-generated/example-qapi-commands.h [Uninteresting stuff omitted...] - #ifndef EXAMPLE_QMP_COMMANDS_H - #define EXAMPLE_QMP_COMMANDS_H + #ifndef EXAMPLE_QAPI_COMMANDS_H + #define EXAMPLE_QAPI_COMMANDS_H #include "example-qapi-types.h" - #include "qapi/qmp/qdict.h" #include "qapi/qmp/dispatch.h" - void example_qmp_init_marshal(QmpCommandList *cmds); UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp); void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp); + void example_qmp_init_marshal(QmpCommandList *cmds); - #endif + #endif /* EXAMPLE_QAPI_COMMANDS_H */ $ cat qapi-generated/example-qapi-commands.c [Uninteresting stuff omitted...] @@ -1316,6 +1321,8 @@ Example: qmp_marshal_my_command, QCO_NO_OPTIONS); } +[Uninteresting stuff omitted...] + === Code generated for events === This is the code related to events defined in the schema, providing @@ -1333,14 +1340,14 @@ Example: $ cat qapi-generated/example-qapi-events.h [Uninteresting stuff omitted...] - #ifndef EXAMPLE_QAPI_EVENT_H - #define EXAMPLE_QAPI_EVENT_H + #ifndef EXAMPLE_QAPI_EVENTS_H + #define EXAMPLE_QAPI_EVENTS_H - #include "qapi/qmp/qdict.h" + #include "qapi/util.h" #include "example-qapi-types.h" - void qapi_event_send_my_event(Error **errp); + void qapi_event_send_my_event(void); typedef enum example_QAPIEvent { EXAMPLE_QAPI_EVENT_MY_EVENT = 0, @@ -1348,18 +1355,17 @@ Example: } example_QAPIEvent; #define example_QAPIEvent_str(val) \ - qapi_enum_lookup(example_QAPIEvent_lookup, (val)) + qapi_enum_lookup(&example_QAPIEvent_lookup, (val)) - extern const char *const example_QAPIEvent_lookup[]; + extern const QEnumLookup example_QAPIEvent_lookup; - #endif + #endif /* EXAMPLE_QAPI_EVENTS_H */ $ cat qapi-generated/example-qapi-events.c [Uninteresting stuff omitted...] - void qapi_event_send_my_event(Error **errp) + void qapi_event_send_my_event(void) { QDict *qmp; - Error *err = NULL; QMPEventFuncEmit emit; emit = qmp_event_get_func_emit(); @@ -1369,9 +1375,8 @@ Example: qmp = qmp_event_build_dict("MY_EVENT"); - emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp, &err); + emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp); - error_propagate(errp, err); qobject_unref(qmp); } @@ -1382,6 +1387,8 @@ Example: .size = EXAMPLE_QAPI_EVENT__MAX }; +[Uninteresting stuff omitted...] + === Code generated for introspection === The following files are created: @@ -1396,30 +1403,93 @@ Example: $ cat qapi-generated/example-qapi-introspect.h [Uninteresting stuff omitted...] - #ifndef EXAMPLE_QMP_INTROSPECT_H - #define EXAMPLE_QMP_INTROSPECT_H + #ifndef EXAMPLE_QAPI_INTROSPECT_H + #define EXAMPLE_QAPI_INTROSPECT_H - extern const QLitObject qmp_schema_qlit; + #include "qapi/qmp/qlit.h" - #endif + extern const QLitObject example_qmp_schema_qlit; + + #endif /* EXAMPLE_QAPI_INTROSPECT_H */ $ cat qapi-generated/example-qapi-introspect.c [Uninteresting stuff omitted...] const QLitObject example_qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) { QLIT_QDICT(((QLitDictEntry[]) { - { "arg-type", QLIT_QSTR("0") }, - { "meta-type", QLIT_QSTR("event") }, - { "name", QLIT_QSTR("Event") }, - { } + { "arg-type", QLIT_QSTR("0"), }, + { "meta-type", QLIT_QSTR("command"), }, + { "name", QLIT_QSTR("my-command"), }, + { "ret-type", QLIT_QSTR("1"), }, + {} })), QLIT_QDICT(((QLitDictEntry[]) { + { "arg-type", QLIT_QSTR("2"), }, + { "meta-type", QLIT_QSTR("event"), }, + { "name", QLIT_QSTR("MY_EVENT"), }, + {} + })), + /* "0" = q_obj_my-command-arg */ + QLIT_QDICT(((QLitDictEntry[]) { + { "members", QLIT_QLIST(((QLitObject[]) { + QLIT_QDICT(((QLitDictEntry[]) { + { "name", QLIT_QSTR("arg1"), }, + { "type", QLIT_QSTR("[1]"), }, + {} + })), + {} + })), }, + { "meta-type", QLIT_QSTR("object"), }, + { "name", QLIT_QSTR("0"), }, + {} + })), + /* "1" = UserDefOne */ + QLIT_QDICT(((QLitDictEntry[]) { { "members", QLIT_QLIST(((QLitObject[]) { - { } - })) }, - { "meta-type", QLIT_QSTR("object") }, - { "name", QLIT_QSTR("0") }, - { } + QLIT_QDICT(((QLitDictEntry[]) { + { "name", QLIT_QSTR("integer"), }, + { "type", QLIT_QSTR("int"), }, + {} + })), + QLIT_QDICT(((QLitDictEntry[]) { + { "default", QLIT_QNULL, }, + { "name", QLIT_QSTR("string"), }, + { "type", QLIT_QSTR("str"), }, + {} + })), + {} + })), }, + { "meta-type", QLIT_QSTR("object"), }, + { "name", QLIT_QSTR("1"), }, + {} })), - ... - { } + /* "2" = q_empty */ + QLIT_QDICT(((QLitDictEntry[]) { + { "members", QLIT_QLIST(((QLitObject[]) { + {} + })), }, + { "meta-type", QLIT_QSTR("object"), }, + { "name", QLIT_QSTR("2"), }, + {} + })), + QLIT_QDICT(((QLitDictEntry[]) { + { "element-type", QLIT_QSTR("1"), }, + { "meta-type", QLIT_QSTR("array"), }, + { "name", QLIT_QSTR("[1]"), }, + {} + })), + QLIT_QDICT(((QLitDictEntry[]) { + { "json-type", QLIT_QSTR("int"), }, + { "meta-type", QLIT_QSTR("builtin"), }, + { "name", QLIT_QSTR("int"), }, + {} + })), + QLIT_QDICT(((QLitDictEntry[]) { + { "json-type", QLIT_QSTR("string"), }, + { "meta-type", QLIT_QSTR("builtin"), }, + { "name", QLIT_QSTR("str"), }, + {} + })), + {} })); + +[Uninteresting stuff omitted...] diff --git a/docs/interop/live-block-operations.rst b/docs/interop/live-block-operations.rst index 734252bc80..48afdc7927 100644 --- a/docs/interop/live-block-operations.rst +++ b/docs/interop/live-block-operations.rst @@ -129,7 +129,7 @@ To show some example invocations of command-line, we will use the following invocation of QEMU, with a QMP server running over UNIX socket:: - $ ./x86_64-softmmu/qemu-system-x86_64 -display none -nodefconfig \ + $ ./x86_64-softmmu/qemu-system-x86_64 -display none -no-user-config \ -M q35 -nodefaults -m 512 \ -blockdev node-name=node-A,driver=qcow2,file.driver=file,file.node-name=file,file.filename=./a.qcow2 \ -device virtio-blk,drive=node-A,id=virtio0 \ @@ -694,7 +694,7 @@ instance, with the following invocation. (As noted earlier, for simplicity's sake, the destination QEMU is started on the same host, but it could be located elsewhere):: - $ ./x86_64-softmmu/qemu-system-x86_64 -display none -nodefconfig \ + $ ./x86_64-softmmu/qemu-system-x86_64 -display none -no-user-config \ -M q35 -nodefaults -m 512 \ -blockdev node-name=node-TargetDisk,driver=qcow2,file.driver=file,file.node-name=file,file.filename=./target-disk.qcow2 \ -device virtio-blk,drive=node-TargetDisk,id=virtio0 \ diff --git a/docs/virtio-balloon-stats.txt b/docs/virtio-balloon-stats.txt index 9985e1dffc..1732cc8c8a 100644 --- a/docs/virtio-balloon-stats.txt +++ b/docs/virtio-balloon-stats.txt @@ -61,9 +61,9 @@ It's also important to note the following: respond to the request the timer will never be re-armed, which has the same effect as disabling polling -Here are a few examples. QEMU is started with '-balloon virtio', which -generates '/machine/peripheral-anon/device[1]' as the QOM path for the -balloon device. +Here are a few examples. QEMU is started with '-device virtio-balloon', +which generates '/machine/peripheral-anon/device[1]' as the QOM path for +the balloon device. Enable polling with 2 seconds interval: @@ -1890,8 +1890,7 @@ static void dump_process(DumpState *s, Error **errp) /* should never fail */ assert(result); qapi_event_send_dump_completed(result, !!local_err, (local_err ? \ - error_get_pretty(local_err) : NULL), - &error_abort); + error_get_pretty(local_err) : NULL)); qapi_free_DumpQueryResult(result); error_propagate(errp, local_err); diff --git a/hw/acpi/core.c b/hw/acpi/core.c index b8d39012cd..aafdc61648 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -570,7 +570,7 @@ static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) break; default: if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ - qapi_event_send_suspend_disk(&error_abort); + qapi_event_send_suspend_disk(); qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } break; diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index 5ae595ecbe..d19b7722f0 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -160,7 +160,7 @@ static void cpu_hotplug_wr(void *opaque, hwaddr addr, uint64_t data, cdev = &cpu_st->devs[cpu_st->selector]; cdev->ost_status = data; info = acpi_cpu_device_status(cpu_st->selector, cdev); - qapi_event_send_acpi_device_ost(info, &error_abort); + qapi_event_send_acpi_device_ost(info); qapi_free_ACPIOSTInfo(info); trace_cpuhp_acpi_write_ost_status(cpu_st->selector, cdev->ost_status); diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 0ff1712c4c..8c7c1013f3 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -161,7 +161,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, /* TODO: implement memory removal on guest signal */ info = acpi_memory_device_status(mem_st->selector, mdev); - qapi_event_send_acpi_device_ost(info, &error_abort); + qapi_event_send_acpi_device_ost(info); qapi_free_ACPIOSTInfo(info); break; case 0x14: /* set is_* fields */ @@ -185,8 +185,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, if (local_err) { trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector); qapi_event_send_mem_unplug_error(dev->id, - error_get_pretty(local_err), - &error_abort); + error_get_pretty(local_err)); error_free(local_err); break; } diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index 679a824888..2cbe1d4ed5 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -114,8 +114,7 @@ static void set_guest_connected(VirtIOSerialPort *port, int guest_connected) } if (dev->id) { - qapi_event_send_vserport_change(dev->id, guest_connected, - &error_abort); + qapi_event_send_vserport_change(dev->id, guest_connected); } } diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 529b82de18..36b788a66b 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -1000,8 +1000,7 @@ static void device_finalize(Object *obj) if (dev->pending_deleted_event) { g_assert(dev->canonical_path); - qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path, - &error_abort); + qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path); g_free(dev->canonical_path); dev->canonical_path = NULL; } diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index f011ea5b00..083b3172da 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -1272,8 +1272,6 @@ static void exynos4210_fimd_update(void *opaque) uint8_t *host_fb_addr; bool is_dirty = false; const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1; - const int global_height = ((s->vidtcon[2] >> FIMD_VIDTCON2_VER_SHIFT) & - FIMD_VIDTCON2_SIZE_MASK) + 1; if (!s || !s->console || !s->enabled || surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) { @@ -1329,7 +1327,7 @@ static void exynos4210_fimd_update(void *opaque) fimd_copy_line_toqemu(global_width, s->ifb + global_width * line * RGBA_SIZE, d + global_width * line * bpp); } - dpy_gfx_update(s->console, 0, 0, global_width, global_height); + dpy_gfx_update_full(s->console); } s->invalidate = false; s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND; diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index fbc2b2422d..8ad7e5d824 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -229,7 +229,7 @@ static void g364fb_draw_blank(G364State *s) d += surface_stride(surface); } - dpy_gfx_update(s->con, 0, 0, s->width, s->height); + dpy_gfx_update_full(s->con); s->blanked = 1; } diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index 3c97d56434..eb7933d2a3 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -214,8 +214,7 @@ static void jazz_led_update_display(void *opaque) } s->state = REDRAW_NONE; - dpy_gfx_update(s->con, 0, 0, - surface_width(surface), surface_height(surface)); + dpy_gfx_update_full(s->con); } static void jazz_led_invalidate_display(void *opaque) diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c index 8392e59493..3360be6f84 100644 --- a/hw/display/tc6393xb.c +++ b/hw/display/tc6393xb.c @@ -461,7 +461,7 @@ static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update) return; } - dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height); + dpy_gfx_update_full(s->con); } static void tc6393xb_draw_blank(TC6393xbState *s, int full_update) @@ -480,7 +480,7 @@ static void tc6393xb_draw_blank(TC6393xbState *s, int full_update) d += surface_stride(surface); } - dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height); + dpy_gfx_update_full(s->con); } static void tc6393xb_update_display(void *opaque) diff --git a/hw/display/vga.c b/hw/display/vga.c index 802cfd47db..3ba3f6853c 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1745,8 +1745,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update) memset(d, 0, w); d += surface_stride(surface); } - dpy_gfx_update(s->con, 0, 0, - s->last_scr_width, s->last_scr_height); + dpy_gfx_update_full(s->con); } #define GMODE_TEXT 0 diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c index 3558f38fe8..55d76405a9 100644 --- a/hw/display/virtio-gpu-3d.c +++ b/hw/display/virtio-gpu-3d.c @@ -86,7 +86,7 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g, &res_iovs, &num_iovs); if (res_iovs != NULL && num_iovs != 0) { - virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs); + virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs); } virgl_renderer_resource_unref(unref.resource_id); } @@ -291,7 +291,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g, VIRTIO_GPU_FILL_CMD(att_rb); trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id); - ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, NULL, &res_iovs); + ret = virtio_gpu_create_mapping_iov(g, &att_rb, cmd, NULL, &res_iovs); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; @@ -301,7 +301,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g, res_iovs, att_rb.nr_entries); if (ret != 0) - virtio_gpu_cleanup_mapping_iov(res_iovs, att_rb.nr_entries); + virtio_gpu_cleanup_mapping_iov(g, res_iovs, att_rb.nr_entries); } static void virgl_resource_detach_backing(VirtIOGPU *g, @@ -320,7 +320,7 @@ static void virgl_resource_detach_backing(VirtIOGPU *g, if (res_iovs == NULL || num_iovs == 0) { return; } - virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs); + virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs); } diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 3ddd29c0de..7be3a9d404 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -17,6 +17,7 @@ #include "qemu/iov.h" #include "ui/console.h" #include "trace.h" +#include "sysemu/dma.h" #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-gpu.h" #include "hw/virtio/virtio-bus.h" @@ -29,7 +30,8 @@ static struct virtio_gpu_simple_resource* virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id); -static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res); +static void virtio_gpu_cleanup_mapping(VirtIOGPU *g, + struct virtio_gpu_simple_resource *res); static void virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr) @@ -421,11 +423,6 @@ static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id) scanout->height ?: 480, "Guest disabled display."); } - - if (g->disable_scanout) { - g->disable_scanout(g, scanout_id); - } - dpy_gfx_replace_surface(scanout->con, ds); scanout->resource_id = 0; scanout->ds = NULL; @@ -447,7 +444,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g, } pixman_image_unref(res->image); - virtio_gpu_cleanup_mapping(res); + virtio_gpu_cleanup_mapping(g, res); QTAILQ_REMOVE(&g->reslist, res, next); g->hostmem -= res->hostmem; g_free(res); @@ -693,7 +690,8 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, scanout->height = ss.r.height; } -int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, +int virtio_gpu_create_mapping_iov(VirtIOGPU *g, + struct virtio_gpu_resource_attach_backing *ab, struct virtio_gpu_ctrl_command *cmd, uint64_t **addr, struct iovec **iov) { @@ -729,7 +727,8 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, uint32_t l = le32_to_cpu(ents[i].length); hwaddr len = l; (*iov)[i].iov_len = l; - (*iov)[i].iov_base = cpu_physical_memory_map(a, &len, 1); + (*iov)[i].iov_base = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, + a, &len, DMA_DIRECTION_TO_DEVICE); if (addr) { (*addr)[i] = a; } @@ -737,7 +736,7 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" " resource %d element %d\n", __func__, ab->resource_id, i); - virtio_gpu_cleanup_mapping_iov(*iov, i); + virtio_gpu_cleanup_mapping_iov(g, *iov, i); g_free(ents); *iov = NULL; if (addr) { @@ -751,20 +750,24 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, return 0; } -void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count) +void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g, + struct iovec *iov, uint32_t count) { int i; for (i = 0; i < count; i++) { - cpu_physical_memory_unmap(iov[i].iov_base, iov[i].iov_len, 1, - iov[i].iov_len); + dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, + iov[i].iov_base, iov[i].iov_len, + DMA_DIRECTION_TO_DEVICE, + iov[i].iov_len); } g_free(iov); } -static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res) +static void virtio_gpu_cleanup_mapping(VirtIOGPU *g, + struct virtio_gpu_simple_resource *res) { - virtio_gpu_cleanup_mapping_iov(res->iov, res->iov_cnt); + virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt); res->iov = NULL; res->iov_cnt = 0; g_free(res->addrs); @@ -796,7 +799,7 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g, return; } - ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov); + ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs, &res->iov); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; @@ -823,7 +826,7 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g, cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; return; } - virtio_gpu_cleanup_mapping(res); + virtio_gpu_cleanup_mapping(g, res); } static void virtio_gpu_simple_process_cmd(VirtIOGPU *g, @@ -1148,16 +1151,21 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, for (i = 0; i < res->iov_cnt; i++) { hwaddr len = res->iov[i].iov_len; res->iov[i].iov_base = - cpu_physical_memory_map(res->addrs[i], &len, 1); + dma_memory_map(VIRTIO_DEVICE(g)->dma_as, + res->addrs[i], &len, DMA_DIRECTION_TO_DEVICE); + if (!res->iov[i].iov_base || len != res->iov[i].iov_len) { /* Clean up the half-a-mapping we just created... */ if (res->iov[i].iov_base) { - cpu_physical_memory_unmap(res->iov[i].iov_base, - len, 0, 0); + dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, + res->iov[i].iov_base, + res->iov[i].iov_len, + DMA_DIRECTION_TO_DEVICE, + res->iov[i].iov_len); } /* ...and the mappings for previous loop iterations */ res->iov_cnt = i; - virtio_gpu_cleanup_mapping(res); + virtio_gpu_cleanup_mapping(g, res); pixman_image_unref(res->image); g_free(res); return -EINVAL; @@ -1187,7 +1195,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, } dpy_gfx_replace_surface(scanout->con, scanout->ds); - dpy_gfx_update(scanout->con, 0, 0, scanout->width, scanout->height); + dpy_gfx_update_full(scanout->con); if (scanout->cursor.resource_id) { update_cursor(g, &scanout->cursor); } @@ -1205,11 +1213,6 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) Error *local_err = NULL; int i; - if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) { - error_setg(errp, "virtio-gpu does not support vIOMMU yet"); - return; - } - if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) { error_setg(errp, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS); return; @@ -1289,7 +1292,7 @@ static void virtio_gpu_instance_init(Object *obj) { } -static void virtio_gpu_reset(VirtIODevice *vdev) +void virtio_gpu_reset(VirtIODevice *vdev) { VirtIOGPU *g = VIRTIO_GPU(vdev); struct virtio_gpu_simple_resource *res, *tmp; diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index 701d980872..1e601c1a3b 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -75,16 +75,6 @@ static void virtio_vga_gl_block(void *opaque, bool block) } } -static void virtio_vga_disable_scanout(VirtIOGPU *g, int scanout_id) -{ - VirtIOVGA *vvga = container_of(g, VirtIOVGA, vdev); - - if (scanout_id == 0) { - /* reset surface if needed */ - vvga->vga.graphic_mode = -1; - } -} - static const GraphicHwOps virtio_vga_ops = { .invalidate = virtio_vga_invalidate_display, .gfx_update = virtio_vga_update_display, @@ -166,7 +156,6 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp) vvga->vga_mrs, true); vga->con = g->scanout[0].con; - g->disable_scanout = virtio_vga_disable_scanout; graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga); for (i = 0; i < g->conf.max_outputs; i++) { @@ -179,8 +168,12 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp) static void virtio_vga_reset(DeviceState *dev) { VirtIOVGA *vvga = VIRTIO_VGA(dev); - vvga->vdev.enable = 0; + /* reset virtio-gpu */ + virtio_gpu_reset(VIRTIO_DEVICE(&vvga->vdev)); + + /* reset vga */ + vga_common_reset(&vvga->vga); vga_dirty_log_start(&vvga->vga); } diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 0bbb78b9a6..afbf1c5973 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -1116,7 +1116,6 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s) static void vmsvga_update_display(void *opaque) { struct vmsvga_state_s *s = opaque; - DisplaySurface *surface; if (!s->enable || !s->config) { /* in standard vga mode */ @@ -1125,15 +1124,13 @@ static void vmsvga_update_display(void *opaque) } vmsvga_check_size(s); - surface = qemu_console_surface(s->vga.con); vmsvga_fifo_run(s); vmsvga_update_rect_flush(s); if (s->invalidated) { s->invalidated = 0; - dpy_gfx_update(s->vga.con, 0, 0, - surface_width(surface), surface_height(surface)); + dpy_gfx_update_full(s->vga.con); } } diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 6439bd05ef..cc0f9bc9cc 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1186,8 +1186,7 @@ static void xlnx_dp_update_display(void *opaque) /* * XXX: We might want to update only what changed. */ - dpy_gfx_update(s->console, 0, 0, surface_width(s->g_plane.surface), - surface_height(s->g_plane.surface)); + dpy_gfx_update_full(s->console); } static const GraphicHwOps xlnx_dp_gfx_ops = { diff --git a/hw/ide/macio.c b/hw/ide/macio.c index d3a85cba3b..bab8c45a43 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -26,6 +26,7 @@ #include "hw/hw.h" #include "hw/ppc/mac.h" #include "hw/ppc/mac_dbdma.h" +#include "hw/misc/macio/macio.h" #include "sysemu/block-backend.h" #include "sysemu/dma.h" @@ -460,6 +461,7 @@ static void macio_ide_initfn(Object *obj) static Property macio_ide_properties[] = { DEFINE_PROP_UINT32("channel", MACIOIDEState, channel, 0), + DEFINE_PROP_UINT32("addr", MACIOIDEState, addr, -1), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 52aa3775f4..94da85c8d7 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -90,6 +90,15 @@ static void macio_bar_setup(MacIOState *s) macio_escc_legacy_setup(s); } +static void macio_init_child_obj(MacIOState *s, const char *childname, + void *child, size_t childsize, + const char *childtype) +{ + object_initialize_child(OBJECT(s), childname, child, childsize, childtype, + &error_abort, NULL); + qdev_set_parent_bus(DEVICE(child), BUS(&s->macio_bus)); +} + static void macio_common_realize(PCIDevice *d, Error **errp) { MacIOState *s = MACIO(d); @@ -210,10 +219,11 @@ static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size, int index) { gchar *name = g_strdup_printf("ide[%i]", index); + uint32_t addr = 0x1f000 + ((index + 1) * 0x1000); - sysbus_init_child_obj(OBJECT(s), name, ide, ide_size, TYPE_MACIO_IDE); - memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000), - &ide->mem); + macio_init_child_obj(s, name, ide, ide_size, TYPE_MACIO_IDE); + qdev_prop_set_uint32(DEVICE(ide), "addr", addr); + memory_region_add_subregion(&s->bar, addr, &ide->mem); g_free(name); } @@ -229,7 +239,7 @@ static void macio_oldworld_init(Object *obj) qdev_prop_allow_set_link_before_realize, 0, NULL); - sysbus_init_child_obj(obj, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA); + macio_init_child_obj(s, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA); object_initialize(&os->nvram, sizeof(os->nvram), TYPE_MACIO_NVRAM); dev = DEVICE(&os->nvram); @@ -340,7 +350,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) object_property_set_link(OBJECT(&s->pmu), OBJECT(sysbus_dev), "gpio", &error_abort); qdev_prop_set_bit(DEVICE(&s->pmu), "has-adb", ns->has_adb); - qdev_set_parent_bus(DEVICE(&s->pmu), sysbus_get_default()); + qdev_set_parent_bus(DEVICE(&s->pmu), BUS(&s->macio_bus)); object_property_add_child(OBJECT(s), "pmu", OBJECT(&s->pmu), NULL); object_property_set_bool(OBJECT(&s->pmu), true, "realized", &err); @@ -356,7 +366,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) } else { /* CUDA */ object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA); - qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); + qdev_set_parent_bus(DEVICE(&s->cuda), BUS(&s->macio_bus)); object_property_add_child(OBJECT(s), "cuda", OBJECT(&s->cuda), NULL); qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency", s->frequency); @@ -385,8 +395,8 @@ static void macio_newworld_init(Object *obj) qdev_prop_allow_set_link_before_realize, 0, NULL); - sysbus_init_child_obj(obj, "gpio", &ns->gpio, sizeof(ns->gpio), - TYPE_MACIO_GPIO); + macio_init_child_obj(s, "gpio", &ns->gpio, sizeof(ns->gpio), + TYPE_MACIO_GPIO); for (i = 0; i < 2; i++) { macio_init_ide(s, &ns->ide[i], sizeof(ns->ide[i]), i); @@ -399,10 +409,13 @@ static void macio_instance_init(Object *obj) memory_region_init(&s->bar, obj, "macio", 0x80000); - sysbus_init_child_obj(obj, "dbdma", &s->dbdma, sizeof(s->dbdma), - TYPE_MAC_DBDMA); + qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS, + DEVICE(obj), "macio.0"); - sysbus_init_child_obj(obj, "escc", &s->escc, sizeof(s->escc), TYPE_ESCC); + macio_init_child_obj(s, "dbdma", &s->dbdma, sizeof(s->dbdma), + TYPE_MAC_DBDMA); + + macio_init_child_obj(s, "escc", &s->escc, sizeof(s->escc), TYPE_ESCC); } static const VMStateDescription vmstate_macio_oldworld = { @@ -470,6 +483,12 @@ static void macio_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } +static const TypeInfo macio_bus_info = { + .name = TYPE_MACIO_BUS, + .parent = TYPE_BUS, + .instance_size = sizeof(MacIOBusState), +}; + static const TypeInfo macio_oldworld_type_info = { .name = TYPE_OLDWORLD_MACIO, .parent = TYPE_MACIO, @@ -501,6 +520,7 @@ static const TypeInfo macio_type_info = { static void macio_register_types(void) { + type_register_static(&macio_bus_info); type_register_static(&macio_type_info); type_register_static(&macio_oldworld_type_info); type_register_static(&macio_newworld_type_info); diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index f154756e85..4bdd5b8532 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -329,7 +329,7 @@ static void rxfilter_notify(NetClientState *nc) if (nc->rxfilter_notify_enabled) { gchar *path = object_get_canonical_path(OBJECT(n->qdev)); qapi_event_send_nic_rx_filter_changed(!!n->netclient_name, - n->netclient_name, path, &error_abort); + n->netclient_name, path); g_free(path); /* disable event notification to avoid events flooding */ diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 4810a4de79..5a151e93e9 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -37,6 +37,7 @@ typedef struct GrackleState { PCIHostState parent_obj; + uint32_t ofw_addr; HeathrowState *pic; qemu_irq irqs[4]; MemoryRegion pci_mmio; @@ -146,12 +147,28 @@ static const TypeInfo grackle_pci_info = { }, }; +static char *grackle_ofw_unit_address(const SysBusDevice *dev) +{ + GrackleState *s = GRACKLE_PCI_HOST_BRIDGE(dev); + + return g_strdup_printf("%x", s->ofw_addr); +} + +static Property grackle_properties[] = { + DEFINE_PROP_UINT32("ofw-addr", GrackleState, ofw_addr, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void grackle_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = grackle_realize; + dc->props = grackle_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = grackle_ofw_unit_address; } static const TypeInfo grackle_host_info = { diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index a843aa7b36..1378c5c7fb 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -118,6 +118,13 @@ static void pci_unin_init_irqs(UNINHostState *s) } } +static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev) +{ + UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); + + return g_strdup_printf("%x", s->ofw_addr); +} + static void pci_unin_main_realize(DeviceState *dev, Error **errp) { UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); @@ -455,12 +462,21 @@ static const TypeInfo unin_internal_pci_host_info = { }, }; +static Property pci_unin_main_pci_host_props[] = { + DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void pci_unin_main_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = pci_unin_main_realize; + dc->props = pci_unin_main_pci_host_props; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address; } static const TypeInfo pci_unin_main_info = { diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 41fd289e81..a741300ac9 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -86,32 +86,6 @@ typedef struct Core99MachineState { uint8_t via_config; } Core99MachineState; -/* MacIO */ -#define TYPE_MACIO_IDE "macio-ide" -#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) - -typedef struct MACIOIDEState { - /*< private >*/ - SysBusDevice parent_obj; - /*< public >*/ - uint32_t channel; - qemu_irq real_ide_irq; - qemu_irq real_dma_irq; - qemu_irq ide_irq; - qemu_irq dma_irq; - - MemoryRegion mem; - IDEBus bus; - IDEDMA dma; - void *dbdma; - bool dma_active; - uint32_t timing_reg; - uint32_t irq_reg; -} MACIOIDEState; - -void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); -void macio_ide_register_dma(MACIOIDEState *ide); - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index a6b95f024c..a630cb81cd 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -64,6 +64,7 @@ #include "hw/ppc/openpic.h" #include "hw/ide.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" @@ -344,6 +345,7 @@ static void ppc_core99_init(MachineState *machine) /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); @@ -520,6 +522,54 @@ static void ppc_core99_init(MachineState *machine) qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + MACIOIDEState *macio_ide; + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-newworld")) { + pci = PCI_DEVICE(dev); + return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn)); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) { + macio_ide = MACIO_IDE(dev); + return g_strdup_printf("ata-3@%x", macio_ide->addr); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup("cdrom"); + } + + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static int core99_kvm_type(const char *arg) { /* Always force PR KVM */ @@ -529,6 +579,7 @@ static int core99_kvm_type(const char *arg) static void core99_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Mac99 based PowerMAC"; mc->init = ppc_core99_init; @@ -542,6 +593,8 @@ static void core99_machine_class_init(ObjectClass *oc, void *data) #else mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9"); #endif + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = core99_fw_dev_path; } static char *core99_get_via_config(Object *obj, Error **errp) @@ -598,7 +651,11 @@ static const TypeInfo core99_machine_info = { .parent = TYPE_MACHINE, .class_init = core99_machine_class_init, .instance_init = core99_instance_init, - .instance_size = sizeof(Core99MachineState) + .instance_size = sizeof(Core99MachineState), + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void mac_machine_register_types(void) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 80b5525775..9891c325a9 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -42,6 +42,7 @@ #include "hw/misc/macio/macio.h" #include "hw/ide.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" @@ -254,6 +255,7 @@ static void ppc_heathrow_init(MachineState *machine) /* Grackle PCI host bridge */ dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(dev, "ofw-addr", 0x80000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); @@ -372,6 +374,54 @@ static void ppc_heathrow_init(MachineState *machine) qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + MACIOIDEState *macio_ide; + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-oldworld")) { + pci = PCI_DEVICE(dev); + return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn)); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) { + macio_ide = MACIO_IDE(dev); + return g_strdup_printf("ata-3@%x", macio_ide->addr); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup("cdrom"); + } + + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static int heathrow_kvm_type(const char *arg) { /* Always force PR KVM */ @@ -381,6 +431,7 @@ static int heathrow_kvm_type(const char *arg) static void heathrow_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Heathrow based PowerMAC"; mc->init = ppc_heathrow_init; @@ -394,12 +445,18 @@ static void heathrow_class_init(ObjectClass *oc, void *data) mc->kvm_type = heathrow_kvm_type; mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("750_v3.1"); mc->default_display = "std"; + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = heathrow_fw_dev_path; } static const TypeInfo ppc_heathrow_machine_info = { .name = MACHINE_TYPE_NAME("g3beige"), .parent = TYPE_MACHINE, - .class_init = heathrow_class_init + .class_init = heathrow_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void ppc_heathrow_register_types(void) diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index f5a9c24b6c..3be3fe4432 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -162,13 +162,6 @@ static void ref405ep_init(MachineState *machine) DriveInfo *dinfo; MemoryRegion *sysmem = get_system_memory(); -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* XXX: fix this */ memory_region_allocate_system_memory(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000); @@ -463,13 +456,6 @@ static void taihu_405ep_init(MachineState *machine) int fl_idx, fl_sectors; DriveInfo *dinfo; -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* RAM is soldered to the board so the size cannot be changed */ ram_size = 0x08000000; memory_region_allocate_system_memory(ram, NULL, "taihu_405ep.ram", diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 3d4c43b8cc..f5720f979e 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -195,13 +195,6 @@ static void bamboo_init(MachineState *machine) exit(1); } -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - qemu_register_reset(main_cpu_reset, cpu); ppc_booke_timers_init(cpu, 400000000, 0); ppc_dcr_init(env, NULL, NULL); diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 9c77183006..250fb86795 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -419,13 +419,6 @@ static void sam460ex_init(MachineState *machine) exit(1); } -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - qemu_register_reset(main_cpu_reset, cpu); boot_info = g_malloc0(sizeof(*boot_info)); env->load_info = boot_info; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4edb6c7d16..4a9dd4d9bc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -607,6 +607,7 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) spapr_populate_cpu_dt(cs, fdt, offset, spapr); } + g_free(rev); } static uint32_t spapr_pc_dimm_node(MemoryDeviceInfoList *list, ram_addr_t addr) @@ -2479,6 +2480,8 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID, &error_fatal); object_property_set_bool(core, true, "realized", &error_fatal); + + object_unref(core); } } } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 876f0b3d9d..2398ce62c0 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -34,16 +34,16 @@ static void spapr_cpu_reset(void *opaque) cpu_reset(cs); - /* Set compatibility mode to match the boot CPU, which was either set - * by the machine reset code or by CAS. This should never fail. - */ - ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); - /* All CPUs start halted. CPU0 is unhalted from the machine level * reset code and the rest are explicitly started up by the guest * using an RTAS call */ cs->halted = 1; + /* Set compatibility mode to match the boot CPU, which was either set + * by the machine reset code or by CAS. This should never fail. + */ + ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); + env->spr[SPR_HIOR] = 0; lpcr = env->spr[SPR_LPCR]; @@ -90,6 +90,7 @@ void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r env->nip = nip; env->gpr[3] = r3; + kvmppc_set_reg_ppc_online(cpu, 1); CPU(cpu)->halted = 0; /* Enable Power-saving mode Exit Cause exceptions */ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] | pcc->lpcr_pm); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5cd676e443..6bcb4f419b 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1559,7 +1559,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) sPAPRMachineState *spapr = (sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(), TYPE_SPAPR_MACHINE); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + sPAPRMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL; SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 4ac96bc94b..d6a0952154 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -33,6 +33,7 @@ #include "sysemu/device_tree.h" #include "sysemu/cpus.h" #include "sysemu/hw_accel.h" +#include "kvm_ppc.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" @@ -207,6 +208,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr, * guest */ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); cs->halted = 1; + kvmppc_set_reg_ppc_online(cpu, 0); qemu_cpu_kick(cs); } diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index a37360537e..cd049f389d 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c @@ -118,7 +118,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr, } /* Generate a monitor event for the change */ - qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort); + qapi_event_send_rtc_change(qemu_timedate_diff(&tm)); host_ns = qemu_clock_get_ns(rtc_clock); diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 7891464cd9..ee9b4b4490 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -211,13 +211,6 @@ static void virtex_init(MachineState *machine) int kernel_size; int i; -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* init CPUs */ cpu = ppc440_init_xilinx(&ram_size, 1, machine->cpu_type, 400000000); env = &cpu->env; diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c index a91aeb97ab..f635e6ff67 100644 --- a/hw/riscv/sifive_plic.c +++ b/hw/riscv/sifive_plic.c @@ -81,36 +81,32 @@ static void sifive_plic_print_state(SiFivePLICState *plic) } } -static -void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool pending) +static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value) { - qemu_mutex_lock(&plic->lock); - uint32_t word = irq >> 5; - if (pending) { - plic->pending[word] |= (1 << (irq & 31)); - } else { - plic->pending[word] &= ~(1 << (irq & 31)); - } - qemu_mutex_unlock(&plic->lock); + uint32_t old, new, cmp = atomic_read(a); + + do { + old = cmp; + new = (old & ~mask) | (value & mask); + cmp = atomic_cmpxchg(a, old, new); + } while (old != cmp); + + return old; } -static -void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool claimed) +static void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool level) { - qemu_mutex_lock(&plic->lock); - uint32_t word = irq >> 5; - if (claimed) { - plic->claimed[word] |= (1 << (irq & 31)); - } else { - plic->claimed[word] &= ~(1 << (irq & 31)); - } - qemu_mutex_unlock(&plic->lock); + atomic_set_masked(&plic->pending[irq >> 5], 1 << (irq & 31), -!!level); } -static -int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid) +static void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool level) { - int i, j, count = 0; + atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level); +} + +static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid) +{ + int i, j; for (i = 0; i < plic->bitfield_words; i++) { uint32_t pending_enabled_not_claimed = (plic->pending[i] & ~plic->claimed[i]) & @@ -123,11 +119,11 @@ int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid) uint32_t prio = plic->source_priority[irq]; int enabled = pending_enabled_not_claimed & (1 << j); if (enabled && prio > plic->target_priority[addrid]) { - count++; + return 1; } } } - return count; + return 0; } static void sifive_plic_update(SiFivePLICState *plic) @@ -143,7 +139,7 @@ static void sifive_plic_update(SiFivePLICState *plic) if (!env) { continue; } - int level = sifive_plic_num_irqs_pending(plic, addrid) > 0; + int level = sifive_plic_irqs_pending(plic, addrid); switch (mode) { case PLICMode_M: riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level); @@ -439,7 +435,6 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp) memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic, TYPE_SIFIVE_PLIC, plic->aperture_size); parse_hart_config(plic); - qemu_mutex_init(&plic->lock); plic->bitfield_words = (plic->num_sources + 31) >> 5; plic->source_priority = g_new0(uint32_t, plic->num_sources); plic->target_priority = g_new(uint32_t, plic->num_addrs); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index c8c056c50b..eb857c434e 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -90,7 +90,7 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap, qemu_fdt_add_subnode(fdt, "/soc"); qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); - qemu_fdt_setprop_string(fdt, "/soc", "compatible", "ucbbar,spike-bare-soc"); + qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 248bbdffd3..e8ba4d192d 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -121,7 +121,7 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, qemu_fdt_add_subnode(fdt, "/soc"); qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); - qemu_fdt_setprop_string(fdt, "/soc", "compatible", "riscv-virtio-soc"); + qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index 93282f7c59..5dbc00ce9b 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -8,6 +8,17 @@ obj-y += css.o obj-y += s390-virtio-ccw.o obj-y += 3270-ccw.o obj-y += virtio-ccw.o +obj-$(CONFIG_VIRTIO_SERIAL) += virtio-ccw-serial.o +obj-$(CONFIG_VIRTIO_BALLOON) += virtio-ccw-balloon.o +obj-$(CONFIG_VIRTIO_SCSI) += virtio-ccw-scsi.o +obj-$(CONFIG_VIRTIO_RNG) += virtio-ccw-rng.o +obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-ccw-crypto.o +obj-$(CONFIG_VIRTIO_GPU) += virtio-ccw-gpu.o +obj-$(CONFIG_VIRTIO_INPUT) += virtio-ccw-input.o +obj-$(CONFIG_VIRTIO_NET) += virtio-ccw-net.o +obj-$(CONFIG_VIRTIO_BLK) += virtio-ccw-blk.o +obj-$(call land,$(CONFIG_VIRTIO_9P),$(CONFIG_VIRTFS)) += virtio-ccw-9p.o +obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-ccw.o obj-y += css-bridge.o obj-y += ccw-device.o obj-$(CONFIG_PCI) += s390-pci-bus.o s390-pci-inst.o diff --git a/hw/s390x/vhost-vsock-ccw.c b/hw/s390x/vhost-vsock-ccw.c new file mode 100644 index 0000000000..cddc5cf652 --- /dev/null +++ b/hw/s390x/vhost-vsock-ccw.c @@ -0,0 +1,60 @@ +/* + * vhost vsock ccw implementation + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static Property vhost_vsock_ccw_properties[] = { + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void vhost_vsock_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VHostVSockCCWState *dev = VHOST_VSOCK_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = vhost_vsock_ccw_realize; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->props = vhost_vsock_ccw_properties; +} + +static void vhost_vsock_ccw_instance_init(Object *obj) +{ + VHostVSockCCWState *dev = VHOST_VSOCK_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VHOST_VSOCK); +} + +static const TypeInfo vhost_vsock_ccw_info = { + .name = TYPE_VHOST_VSOCK_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VHostVSockCCWState), + .instance_init = vhost_vsock_ccw_instance_init, + .class_init = vhost_vsock_ccw_class_init, +}; + +static void vhost_vsock_ccw_register(void) +{ + type_register_static(&vhost_vsock_ccw_info); +} + +type_init(vhost_vsock_ccw_register) diff --git a/hw/s390x/virtio-ccw-9p.c b/hw/s390x/virtio-ccw-9p.c new file mode 100644 index 0000000000..d6be172596 --- /dev/null +++ b/hw/s390x/virtio-ccw-9p.c @@ -0,0 +1,65 @@ +/* + * virtio ccw 9p implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Pierre Morel <pmorel@linux.vnet.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_9p_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + V9fsCCWState *dev = VIRTIO_9P_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_ccw_9p_instance_init(Object *obj) +{ + V9fsCCWState *dev = VIRTIO_9P_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_9P); +} + +static Property virtio_ccw_9p_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_9p_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_9p_realize; + dc->props = virtio_ccw_9p_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo virtio_ccw_9p_info = { + .name = TYPE_VIRTIO_9P_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(V9fsCCWState), + .instance_init = virtio_ccw_9p_instance_init, + .class_init = virtio_ccw_9p_class_init, +}; + +static void virtio_ccw_9p_register(void) +{ + type_register_static(&virtio_ccw_9p_info); +} + +type_init(virtio_ccw_9p_register) diff --git a/hw/s390x/virtio-ccw-balloon.c b/hw/s390x/virtio-ccw-balloon.c new file mode 100644 index 0000000000..28d171ac0c --- /dev/null +++ b/hw/s390x/virtio-ccw-balloon.c @@ -0,0 +1,70 @@ +/* + * virtio ccw balloon implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_balloon_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_ccw_balloon_instance_init(Object *obj) +{ + VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_BALLOON); + object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev), + "guest-stats", &error_abort); + object_property_add_alias(obj, "guest-stats-polling-interval", + OBJECT(&dev->vdev), + "guest-stats-polling-interval", &error_abort); +} + +static Property virtio_ccw_balloon_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_balloon_realize; + dc->props = virtio_ccw_balloon_properties; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); +} + +static const TypeInfo virtio_ccw_balloon = { + .name = TYPE_VIRTIO_BALLOON_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIOBalloonCcw), + .instance_init = virtio_ccw_balloon_instance_init, + .class_init = virtio_ccw_balloon_class_init, +}; + +static void virtio_ccw_balloon_register(void) +{ + type_register_static(&virtio_ccw_balloon); +} + +type_init(virtio_ccw_balloon_register) diff --git a/hw/s390x/virtio-ccw-blk.c b/hw/s390x/virtio-ccw-blk.c new file mode 100644 index 0000000000..1f3d09a75a --- /dev/null +++ b/hw/s390x/virtio-ccw-blk.c @@ -0,0 +1,67 @@ +/* + * virtio ccw block implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_blk_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_ccw_blk_instance_init(Object *obj) +{ + VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_BLK); + object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), + "bootindex", &error_abort); +} + +static Property virtio_ccw_blk_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_blk_realize; + dc->props = virtio_ccw_blk_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo virtio_ccw_blk = { + .name = TYPE_VIRTIO_BLK_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIOBlkCcw), + .instance_init = virtio_ccw_blk_instance_init, + .class_init = virtio_ccw_blk_class_init, +}; + +static void virtio_ccw_blk_register(void) +{ + type_register_static(&virtio_ccw_blk); +} + +type_init(virtio_ccw_blk_register) diff --git a/hw/s390x/virtio-ccw-crypto.c b/hw/s390x/virtio-ccw-crypto.c new file mode 100644 index 0000000000..aab6a958f2 --- /dev/null +++ b/hw/s390x/virtio-ccw-crypto.c @@ -0,0 +1,75 @@ +/* + * virtio ccw crypto implementation + * + * Copyright 2012, 2015 IBM Corp. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_crypto_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + object_property_set_link(OBJECT(vdev), + OBJECT(dev->vdev.conf.cryptodev), "cryptodev", + NULL); +} + +static void virtio_ccw_crypto_instance_init(Object *obj) +{ + VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(obj); + VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); + + ccw_dev->force_revision_1 = true; + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_CRYPTO); +} + +static Property virtio_ccw_crypto_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_crypto_realize; + dc->props = virtio_ccw_crypto_properties; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); +} + +static const TypeInfo virtio_ccw_crypto = { + .name = TYPE_VIRTIO_CRYPTO_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIOCryptoCcw), + .instance_init = virtio_ccw_crypto_instance_init, + .class_init = virtio_ccw_crypto_class_init, +}; + +static void virtio_ccw_crypto_register(void) +{ + type_register_static(&virtio_ccw_crypto); +} + +type_init(virtio_ccw_crypto_register) diff --git a/hw/s390x/virtio-ccw-gpu.c b/hw/s390x/virtio-ccw-gpu.c new file mode 100644 index 0000000000..71869b7fbd --- /dev/null +++ b/hw/s390x/virtio-ccw-gpu.c @@ -0,0 +1,67 @@ +/* + * virtio ccw gpu implementation + * + * Copyright 2012, 2015 IBM Corp. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_gpu_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIOGPUCcw *dev = VIRTIO_GPU_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_ccw_gpu_instance_init(Object *obj) +{ + VirtIOGPUCcw *dev = VIRTIO_GPU_CCW(obj); + VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); + + ccw_dev->force_revision_1 = true; + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_GPU); +} + +static Property virtio_ccw_gpu_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_gpu_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_gpu_realize; + dc->props = virtio_ccw_gpu_properties; + dc->hotpluggable = false; + set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); +} + +static const TypeInfo virtio_ccw_gpu = { + .name = TYPE_VIRTIO_GPU_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIOGPUCcw), + .instance_init = virtio_ccw_gpu_instance_init, + .class_init = virtio_ccw_gpu_class_init, +}; + +static void virtio_ccw_gpu_register(void) +{ + type_register_static(&virtio_ccw_gpu); +} + +type_init(virtio_ccw_gpu_register) diff --git a/hw/s390x/virtio-ccw-input.c b/hw/s390x/virtio-ccw-input.c new file mode 100644 index 0000000000..79c87cb3f2 --- /dev/null +++ b/hw/s390x/virtio-ccw-input.c @@ -0,0 +1,118 @@ +/* + * virtio ccw scsi implementation + * + * Copyright 2012, 2015 IBM Corp. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_input_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIOInputCcw *dev = VIRTIO_INPUT_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static Property virtio_ccw_input_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_input_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_input_realize; + dc->props = virtio_ccw_input_properties; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static void virtio_ccw_keyboard_instance_init(Object *obj) +{ + VirtIOInputHIDCcw *dev = VIRTIO_INPUT_HID_CCW(obj); + VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); + + ccw_dev->force_revision_1 = true; + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_KEYBOARD); +} + +static void virtio_ccw_mouse_instance_init(Object *obj) +{ + VirtIOInputHIDCcw *dev = VIRTIO_INPUT_HID_CCW(obj); + VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); + + ccw_dev->force_revision_1 = true; + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_MOUSE); +} + +static void virtio_ccw_tablet_instance_init(Object *obj) +{ + VirtIOInputHIDCcw *dev = VIRTIO_INPUT_HID_CCW(obj); + VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); + + ccw_dev->force_revision_1 = true; + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_TABLET); +} + +static const TypeInfo virtio_ccw_input = { + .name = TYPE_VIRTIO_INPUT_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIOInputCcw), + .class_init = virtio_ccw_input_class_init, + .abstract = true, +}; + +static const TypeInfo virtio_ccw_input_hid = { + .name = TYPE_VIRTIO_INPUT_HID_CCW, + .parent = TYPE_VIRTIO_INPUT_CCW, + .instance_size = sizeof(VirtIOInputHIDCcw), + .abstract = true, +}; + +static const TypeInfo virtio_ccw_keyboard = { + .name = TYPE_VIRTIO_KEYBOARD_CCW, + .parent = TYPE_VIRTIO_INPUT_HID_CCW, + .instance_size = sizeof(VirtIOInputHIDCcw), + .instance_init = virtio_ccw_keyboard_instance_init, +}; + +static const TypeInfo virtio_ccw_mouse = { + .name = TYPE_VIRTIO_MOUSE_CCW, + .parent = TYPE_VIRTIO_INPUT_HID_CCW, + .instance_size = sizeof(VirtIOInputHIDCcw), + .instance_init = virtio_ccw_mouse_instance_init, +}; + +static const TypeInfo virtio_ccw_tablet = { + .name = TYPE_VIRTIO_TABLET_CCW, + .parent = TYPE_VIRTIO_INPUT_HID_CCW, + .instance_size = sizeof(VirtIOInputHIDCcw), + .instance_init = virtio_ccw_tablet_instance_init, +}; + +static void virtio_ccw_input_register(void) +{ + type_register_static(&virtio_ccw_input); + type_register_static(&virtio_ccw_input_hid); + type_register_static(&virtio_ccw_keyboard); + type_register_static(&virtio_ccw_mouse); + type_register_static(&virtio_ccw_tablet); +} + +type_init(virtio_ccw_input_register) diff --git a/hw/s390x/virtio-ccw-net.c b/hw/s390x/virtio-ccw-net.c new file mode 100644 index 0000000000..0c0410c643 --- /dev/null +++ b/hw/s390x/virtio-ccw-net.c @@ -0,0 +1,70 @@ +/* + * virtio ccw net implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_net_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + DeviceState *qdev = DEVICE(ccw_dev); + VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + virtio_net_set_netclient_name(&dev->vdev, qdev->id, + object_get_typename(OBJECT(qdev))); + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_ccw_net_instance_init(Object *obj) +{ + VirtIONetCcw *dev = VIRTIO_NET_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_NET); + object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), + "bootindex", &error_abort); +} + +static Property virtio_ccw_net_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_net_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_net_realize; + dc->props = virtio_ccw_net_properties; + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); +} + +static const TypeInfo virtio_ccw_net = { + .name = TYPE_VIRTIO_NET_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIONetCcw), + .instance_init = virtio_ccw_net_instance_init, + .class_init = virtio_ccw_net_class_init, +}; + +static void virtio_ccw_net_register(void) +{ + type_register_static(&virtio_ccw_net); +} + +type_init(virtio_ccw_net_register) diff --git a/hw/s390x/virtio-ccw-rng.c b/hw/s390x/virtio-ccw-rng.c new file mode 100644 index 0000000000..3f6abccef8 --- /dev/null +++ b/hw/s390x/virtio-ccw-rng.c @@ -0,0 +1,74 @@ +/* + * virtio ccw random number generator implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + Error *err = NULL; + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + object_property_set_link(OBJECT(dev), + OBJECT(dev->vdev.conf.rng), "rng", + NULL); +} + +static void virtio_ccw_rng_instance_init(Object *obj) +{ + VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_RNG); +} + +static Property virtio_ccw_rng_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_rng_realize; + dc->props = virtio_ccw_rng_properties; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); +} + +static const TypeInfo virtio_ccw_rng = { + .name = TYPE_VIRTIO_RNG_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIORNGCcw), + .instance_init = virtio_ccw_rng_instance_init, + .class_init = virtio_ccw_rng_class_init, +}; + +static void virtio_ccw_rng_register(void) +{ + type_register_static(&virtio_ccw_rng); +} + +type_init(virtio_ccw_rng_register) diff --git a/hw/s390x/virtio-ccw-scsi.c b/hw/s390x/virtio-ccw-scsi.c new file mode 100644 index 0000000000..c9a804fa25 --- /dev/null +++ b/hw/s390x/virtio-ccw-scsi.c @@ -0,0 +1,125 @@ +/* + * virtio ccw scsi implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "qapi/error.h" +#include "virtio-ccw.h" + +static void virtio_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + DeviceState *qdev = DEVICE(ccw_dev); + char *bus_name; + + /* + * For command line compatibility, this sets the virtio-scsi-device bus + * name as before. + */ + if (qdev->id) { + bus_name = g_strdup_printf("%s.0", qdev->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void virtio_ccw_scsi_instance_init(Object *obj) +{ + VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_SCSI); +} + +static Property virtio_ccw_scsi_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_scsi_realize; + dc->props = virtio_ccw_scsi_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo virtio_ccw_scsi = { + .name = TYPE_VIRTIO_SCSI_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtIOSCSICcw), + .instance_init = virtio_ccw_scsi_instance_init, + .class_init = virtio_ccw_scsi_class_init, +}; + +#ifdef CONFIG_VHOST_SCSI + +static void vhost_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + +static void vhost_ccw_scsi_instance_init(Object *obj) +{ + VHostSCSICcw *dev = VHOST_SCSI_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VHOST_SCSI); +} + +static Property vhost_ccw_scsi_properties[] = { + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = vhost_ccw_scsi_realize; + dc->props = vhost_ccw_scsi_properties; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + +static const TypeInfo vhost_ccw_scsi = { + .name = TYPE_VHOST_SCSI_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VHostSCSICcw), + .instance_init = vhost_ccw_scsi_instance_init, + .class_init = vhost_ccw_scsi_class_init, +}; + +#endif + +static void virtio_ccw_scsi_register(void) +{ + type_register_static(&virtio_ccw_scsi); +#ifdef CONFIG_VHOST_SCSI + type_register_static(&vhost_ccw_scsi); +#endif +} + +type_init(virtio_ccw_scsi_register) diff --git a/hw/s390x/virtio-ccw-serial.c b/hw/s390x/virtio-ccw-serial.c new file mode 100644 index 0000000000..3851fc9c9b --- /dev/null +++ b/hw/s390x/virtio-ccw-serial.c @@ -0,0 +1,78 @@ +/* + * virtio ccw serial implementation + * + * Copyright 2012, 2015 IBM Corp. + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/virtio-serial.h" +#include "virtio-ccw.h" + +static void virtio_ccw_serial_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + DeviceState *proxy = DEVICE(ccw_dev); + char *bus_name; + + /* + * For command line compatibility, this sets the virtio-serial-device bus + * name as before. + */ + if (proxy->id) { + bus_name = g_strdup_printf("%s.0", proxy->id); + virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); + g_free(bus_name); + } + + qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); + object_property_set_bool(OBJECT(vdev), true, "realized", errp); +} + + +static void virtio_ccw_serial_instance_init(Object *obj) +{ + VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_SERIAL); +} + +static Property virtio_ccw_serial_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + k->realize = virtio_ccw_serial_realize; + dc->props = virtio_ccw_serial_properties; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static const TypeInfo virtio_ccw_serial = { + .name = TYPE_VIRTIO_SERIAL_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VirtioSerialCcw), + .instance_init = virtio_ccw_serial_instance_init, + .class_init = virtio_ccw_serial_class_init, +}; + +static void virtio_ccw_serial_register(void) +{ + type_register_static(&virtio_ccw_serial); +} + +type_init(virtio_ccw_serial_register) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 2713b7feaa..212b3d3dea 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -17,7 +17,6 @@ #include "sysemu/kvm.h" #include "net/net.h" #include "hw/virtio/virtio.h" -#include "hw/virtio/virtio-serial.h" #include "hw/virtio/virtio-net.h" #include "hw/sysbus.h" #include "qemu/bitops.h" @@ -747,11 +746,16 @@ out_err: g_free(sch); } -static void virtio_ccw_unrealize(VirtioCcwDevice *dev, Error **errp) +static void virtio_ccw_device_unrealize(VirtioCcwDevice *dev, Error **errp) { + VirtIOCCWDeviceClass *dc = VIRTIO_CCW_DEVICE_GET_CLASS(dev); CcwDevice *ccw_dev = CCW_DEVICE(dev); SubchDev *sch = ccw_dev->sch; + if (dc->unrealize) { + dc->unrealize(dev, errp); + } + if (sch) { css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL); g_free(sch); @@ -763,201 +767,6 @@ static void virtio_ccw_unrealize(VirtioCcwDevice *dev, Error **errp) } } -static void virtio_ccw_net_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - DeviceState *qdev = DEVICE(ccw_dev); - VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - virtio_net_set_netclient_name(&dev->vdev, qdev->id, - object_get_typename(OBJECT(qdev))); - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void virtio_ccw_net_instance_init(Object *obj) -{ - VirtIONetCcw *dev = VIRTIO_NET_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_NET); - object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), - "bootindex", &error_abort); -} - -static void virtio_ccw_blk_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void virtio_ccw_blk_instance_init(Object *obj) -{ - VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_BLK); - object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), - "bootindex", &error_abort); -} - -static void virtio_ccw_serial_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - DeviceState *proxy = DEVICE(ccw_dev); - char *bus_name; - - /* - * For command line compatibility, this sets the virtio-serial-device bus - * name as before. - */ - if (proxy->id) { - bus_name = g_strdup_printf("%s.0", proxy->id); - virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); - g_free(bus_name); - } - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - - -static void virtio_ccw_serial_instance_init(Object *obj) -{ - VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_SERIAL); -} - -static void virtio_ccw_balloon_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void virtio_ccw_balloon_instance_init(Object *obj) -{ - VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_BALLOON); - object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev), - "guest-stats", &error_abort); - object_property_add_alias(obj, "guest-stats-polling-interval", - OBJECT(&dev->vdev), - "guest-stats-polling-interval", &error_abort); -} - -static void virtio_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - DeviceState *qdev = DEVICE(ccw_dev); - char *bus_name; - - /* - * For command line compatibility, this sets the virtio-scsi-device bus - * name as before. - */ - if (qdev->id) { - bus_name = g_strdup_printf("%s.0", qdev->id); - virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name); - g_free(bus_name); - } - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void virtio_ccw_scsi_instance_init(Object *obj) -{ - VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_SCSI); -} - -#ifdef CONFIG_VHOST_SCSI -static void vhost_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void vhost_ccw_scsi_instance_init(Object *obj) -{ - VHostSCSICcw *dev = VHOST_SCSI_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VHOST_SCSI); -} -#endif - -static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - Error *err = NULL; - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - - object_property_set_link(OBJECT(dev), - OBJECT(dev->vdev.conf.rng), "rng", - NULL); -} - -static void virtio_ccw_crypto_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - Error *err = NULL; - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", &err); - if (err) { - error_propagate(errp, err); - return; - } - - object_property_set_link(OBJECT(vdev), - OBJECT(dev->vdev.conf.cryptodev), "cryptodev", - NULL); -} - -static void virtio_ccw_gpu_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIOGPUCcw *dev = VIRTIO_GPU_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void virtio_ccw_input_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VirtIOInputCcw *dev = VIRTIO_INPUT_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - /* DeviceState to VirtioCcwDevice. Note: used on datapath, * be careful and test performance if you change this. */ @@ -1332,363 +1141,6 @@ static void virtio_ccw_device_unplugged(DeviceState *d) } /**************** Virtio-ccw Bus Device Descriptions *******************/ -static Property virtio_ccw_net_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_net_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_net_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_net_properties; - set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); -} - -static const TypeInfo virtio_ccw_net = { - .name = TYPE_VIRTIO_NET_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIONetCcw), - .instance_init = virtio_ccw_net_instance_init, - .class_init = virtio_ccw_net_class_init, -}; - -static Property virtio_ccw_blk_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_blk_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_blk_properties; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo virtio_ccw_blk = { - .name = TYPE_VIRTIO_BLK_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIOBlkCcw), - .instance_init = virtio_ccw_blk_instance_init, - .class_init = virtio_ccw_blk_class_init, -}; - -static Property virtio_ccw_serial_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_serial_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_serial_properties; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); -} - -static const TypeInfo virtio_ccw_serial = { - .name = TYPE_VIRTIO_SERIAL_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtioSerialCcw), - .instance_init = virtio_ccw_serial_instance_init, - .class_init = virtio_ccw_serial_class_init, -}; - -static Property virtio_ccw_balloon_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_balloon_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_balloon_properties; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); -} - -static const TypeInfo virtio_ccw_balloon = { - .name = TYPE_VIRTIO_BALLOON_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIOBalloonCcw), - .instance_init = virtio_ccw_balloon_instance_init, - .class_init = virtio_ccw_balloon_class_init, -}; - -static Property virtio_ccw_scsi_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_scsi_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_scsi_properties; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo virtio_ccw_scsi = { - .name = TYPE_VIRTIO_SCSI_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIOSCSICcw), - .instance_init = virtio_ccw_scsi_instance_init, - .class_init = virtio_ccw_scsi_class_init, -}; - -#ifdef CONFIG_VHOST_SCSI -static Property vhost_ccw_scsi_properties[] = { - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = vhost_ccw_scsi_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = vhost_ccw_scsi_properties; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo vhost_ccw_scsi = { - .name = TYPE_VHOST_SCSI_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VHostSCSICcw), - .instance_init = vhost_ccw_scsi_instance_init, - .class_init = vhost_ccw_scsi_class_init, -}; -#endif - -static void virtio_ccw_rng_instance_init(Object *obj) -{ - VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_RNG); -} - -static Property virtio_ccw_rng_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_rng_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_rng_properties; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); -} - -static const TypeInfo virtio_ccw_rng = { - .name = TYPE_VIRTIO_RNG_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIORNGCcw), - .instance_init = virtio_ccw_rng_instance_init, - .class_init = virtio_ccw_rng_class_init, -}; - -static Property virtio_ccw_crypto_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_crypto_instance_init(Object *obj) -{ - VirtIOCryptoCcw *dev = VIRTIO_CRYPTO_CCW(obj); - VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); - - ccw_dev->force_revision_1 = true; - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_CRYPTO); -} - -static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_crypto_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_crypto_properties; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); -} - -static const TypeInfo virtio_ccw_crypto = { - .name = TYPE_VIRTIO_CRYPTO_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIOCryptoCcw), - .instance_init = virtio_ccw_crypto_instance_init, - .class_init = virtio_ccw_crypto_class_init, -}; - -static Property virtio_ccw_gpu_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_gpu_instance_init(Object *obj) -{ - VirtIOGPUCcw *dev = VIRTIO_GPU_CCW(obj); - VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); - - ccw_dev->force_revision_1 = true; - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_GPU); -} - -static void virtio_ccw_gpu_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_gpu_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_gpu_properties; - dc->hotpluggable = false; - set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); -} - -static const TypeInfo virtio_ccw_gpu = { - .name = TYPE_VIRTIO_GPU_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIOGPUCcw), - .instance_init = virtio_ccw_gpu_instance_init, - .class_init = virtio_ccw_gpu_class_init, -}; - -static Property virtio_ccw_input_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_input_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = virtio_ccw_input_realize; - k->unrealize = virtio_ccw_unrealize; - dc->props = virtio_ccw_input_properties; - set_bit(DEVICE_CATEGORY_INPUT, dc->categories); -} - -static void virtio_ccw_keyboard_instance_init(Object *obj) -{ - VirtIOInputHIDCcw *dev = VIRTIO_INPUT_HID_CCW(obj); - VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); - - ccw_dev->force_revision_1 = true; - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_KEYBOARD); -} - -static void virtio_ccw_mouse_instance_init(Object *obj) -{ - VirtIOInputHIDCcw *dev = VIRTIO_INPUT_HID_CCW(obj); - VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); - - ccw_dev->force_revision_1 = true; - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_MOUSE); -} - -static void virtio_ccw_tablet_instance_init(Object *obj) -{ - VirtIOInputHIDCcw *dev = VIRTIO_INPUT_HID_CCW(obj); - VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); - - ccw_dev->force_revision_1 = true; - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_TABLET); -} - -static const TypeInfo virtio_ccw_input = { - .name = TYPE_VIRTIO_INPUT_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VirtIOInputCcw), - .class_init = virtio_ccw_input_class_init, - .abstract = true, -}; - -static const TypeInfo virtio_ccw_input_hid = { - .name = TYPE_VIRTIO_INPUT_HID_CCW, - .parent = TYPE_VIRTIO_INPUT_CCW, - .instance_size = sizeof(VirtIOInputHIDCcw), - .abstract = true, -}; - -static const TypeInfo virtio_ccw_keyboard = { - .name = TYPE_VIRTIO_KEYBOARD_CCW, - .parent = TYPE_VIRTIO_INPUT_HID_CCW, - .instance_size = sizeof(VirtIOInputHIDCcw), - .instance_init = virtio_ccw_keyboard_instance_init, -}; - -static const TypeInfo virtio_ccw_mouse = { - .name = TYPE_VIRTIO_MOUSE_CCW, - .parent = TYPE_VIRTIO_INPUT_HID_CCW, - .instance_size = sizeof(VirtIOInputHIDCcw), - .instance_init = virtio_ccw_mouse_instance_init, -}; - -static const TypeInfo virtio_ccw_tablet = { - .name = TYPE_VIRTIO_TABLET_CCW, - .parent = TYPE_VIRTIO_INPUT_HID_CCW, - .instance_size = sizeof(VirtIOInputHIDCcw), - .instance_init = virtio_ccw_tablet_instance_init, -}; - static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp) { VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev; @@ -1700,9 +1152,8 @@ static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp) static void virtio_ccw_busdev_unrealize(DeviceState *dev, Error **errp) { VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev; - VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev); - _info->unrealize(_dev, errp); + virtio_ccw_device_unrealize(_dev, errp); } static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev, @@ -1775,123 +1226,10 @@ static const TypeInfo virtio_ccw_bus_info = { .class_init = virtio_ccw_bus_class_init, }; -#ifdef CONFIG_VIRTFS -static Property virtio_ccw_9p_properties[] = { - DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void virtio_ccw_9p_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - V9fsCCWState *dev = VIRTIO_9P_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void virtio_ccw_9p_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->unrealize = virtio_ccw_unrealize; - k->realize = virtio_ccw_9p_realize; - dc->props = virtio_ccw_9p_properties; - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static void virtio_ccw_9p_instance_init(Object *obj) -{ - V9fsCCWState *dev = VIRTIO_9P_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VIRTIO_9P); -} - -static const TypeInfo virtio_ccw_9p_info = { - .name = TYPE_VIRTIO_9P_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(V9fsCCWState), - .instance_init = virtio_ccw_9p_instance_init, - .class_init = virtio_ccw_9p_class_init, -}; -#endif - -#ifdef CONFIG_VHOST_VSOCK - -static Property vhost_vsock_ccw_properties[] = { - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), - DEFINE_PROP_END_OF_LIST(), -}; - -static void vhost_vsock_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp) -{ - VHostVSockCCWState *dev = VHOST_VSOCK_CCW(ccw_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - - qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus)); - object_property_set_bool(OBJECT(vdev), true, "realized", errp); -} - -static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); - - k->realize = vhost_vsock_ccw_realize; - k->unrealize = virtio_ccw_unrealize; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); - dc->props = vhost_vsock_ccw_properties; -} - -static void vhost_vsock_ccw_instance_init(Object *obj) -{ - VHostVSockCCWState *dev = VHOST_VSOCK_CCW(obj); - - virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), - TYPE_VHOST_VSOCK); -} - -static const TypeInfo vhost_vsock_ccw_info = { - .name = TYPE_VHOST_VSOCK_CCW, - .parent = TYPE_VIRTIO_CCW_DEVICE, - .instance_size = sizeof(VHostVSockCCWState), - .instance_init = vhost_vsock_ccw_instance_init, - .class_init = vhost_vsock_ccw_class_init, -}; -#endif - static void virtio_ccw_register(void) { type_register_static(&virtio_ccw_bus_info); type_register_static(&virtio_ccw_device_info); - type_register_static(&virtio_ccw_serial); - type_register_static(&virtio_ccw_blk); - type_register_static(&virtio_ccw_net); - type_register_static(&virtio_ccw_balloon); - type_register_static(&virtio_ccw_scsi); -#ifdef CONFIG_VHOST_SCSI - type_register_static(&vhost_ccw_scsi); -#endif - type_register_static(&virtio_ccw_rng); -#ifdef CONFIG_VIRTFS - type_register_static(&virtio_ccw_9p_info); -#endif -#ifdef CONFIG_VHOST_VSOCK - type_register_static(&vhost_vsock_ccw_info); -#endif - type_register_static(&virtio_ccw_crypto); - type_register_static(&virtio_ccw_gpu); - type_register_static(&virtio_ccw_input); - type_register_static(&virtio_ccw_input_hid); - type_register_static(&virtio_ccw_keyboard); - type_register_static(&virtio_ccw_mouse); - type_register_static(&virtio_ccw_tablet); } type_init(virtio_ccw_register) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index a504f0308d..acee47da0e 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -635,7 +635,7 @@ static void rtc_set_time(RTCState *s) s->base_rtc = mktimegm(&tm); s->last_update = qemu_clock_get_ns(rtc_clock); - qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort); + qapi_event_send_rtc_change(qemu_timedate_diff(&tm)); } static void rtc_set_cmos(RTCState *s, const struct tm *tm) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index b5425080c5..1728e4f83a 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -365,8 +365,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, dev->actual = le32_to_cpu(config.actual); if (dev->actual != oldactual) { qapi_event_send_balloon_change(vm_ram_size - - ((ram_addr_t) dev->actual << VIRTIO_BALLOON_PFN_SHIFT), - &error_abort); + ((ram_addr_t) dev->actual << VIRTIO_BALLOON_PFN_SHIFT)); } trace_virtio_balloon_set_config(dev->actual, oldactual); } diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c index 6e8ba061d8..33e6c20184 100644 --- a/hw/watchdog/watchdog.c +++ b/hw/watchdog/watchdog.c @@ -102,17 +102,17 @@ void watchdog_perform_action(void) { switch (watchdog_action) { case WATCHDOG_ACTION_RESET: /* same as 'system_reset' in monitor */ - qapi_event_send_watchdog(WATCHDOG_ACTION_RESET, &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_RESET); qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); break; case WATCHDOG_ACTION_SHUTDOWN: /* same as 'system_powerdown' in monitor */ - qapi_event_send_watchdog(WATCHDOG_ACTION_SHUTDOWN, &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_SHUTDOWN); qemu_system_powerdown_request(); break; case WATCHDOG_ACTION_POWEROFF: /* same as 'quit' command in monitor */ - qapi_event_send_watchdog(WATCHDOG_ACTION_POWEROFF, &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_POWEROFF); exit(0); case WATCHDOG_ACTION_PAUSE: /* same as 'stop' command in monitor */ @@ -120,22 +120,21 @@ void watchdog_perform_action(void) * you would get a deadlock. Bypass the problem. */ qemu_system_vmstop_request_prepare(); - qapi_event_send_watchdog(WATCHDOG_ACTION_PAUSE, &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_PAUSE); qemu_system_vmstop_request(RUN_STATE_WATCHDOG); break; case WATCHDOG_ACTION_DEBUG: - qapi_event_send_watchdog(WATCHDOG_ACTION_DEBUG, &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_DEBUG); fprintf(stderr, "watchdog: timer fired\n"); break; case WATCHDOG_ACTION_NONE: - qapi_event_send_watchdog(WATCHDOG_ACTION_NONE, &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_NONE); break; case WATCHDOG_ACTION_INJECT_NMI: - qapi_event_send_watchdog(WATCHDOG_ACTION_INJECT_NMI, - &error_abort); + qapi_event_send_watchdog(WATCHDOG_ACTION_INJECT_NMI); nmi_monitor_handle(0, NULL); break; diff --git a/include/exec/poison.h b/include/exec/poison.h index 41cd2eb1d8..97d3b56640 100644 --- a/include/exec/poison.h +++ b/include/exec/poison.h @@ -24,7 +24,6 @@ #pragma GCC poison TARGET_NIOS2 #pragma GCC poison TARGET_OPENRISC #pragma GCC poison TARGET_PPC -#pragma GCC poison TARGET_PPCEMB #pragma GCC poison TARGET_PPC64 #pragma GCC poison TARGET_ABI32 #pragma GCC poison TARGET_S390X diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index cfaa145500..970058b6ed 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -34,6 +34,42 @@ #include "hw/ppc/mac_dbdma.h" #include "hw/ppc/openpic.h" +/* MacIO virtual bus */ +#define TYPE_MACIO_BUS "macio-bus" +#define MACIO_BUS(obj) OBJECT_CHECK(MacIOBusState, (obj), TYPE_MACIO_BUS) + +typedef struct MacIOBusState { + /*< private >*/ + BusState parent_obj; +} MacIOBusState; + +/* MacIO IDE */ +#define TYPE_MACIO_IDE "macio-ide" +#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) + +typedef struct MACIOIDEState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + uint32_t addr; + uint32_t channel; + qemu_irq real_ide_irq; + qemu_irq real_dma_irq; + qemu_irq ide_irq; + qemu_irq dma_irq; + + MemoryRegion mem; + IDEBus bus; + IDEDMA dma; + void *dbdma; + bool dma_active; + uint32_t timing_reg; + uint32_t irq_reg; +} MACIOIDEState; + +void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); +void macio_ide_register_dma(MACIOIDEState *ide); + #define TYPE_MACIO "macio" #define MACIO(obj) OBJECT_CHECK(MacIOState, (obj), TYPE_MACIO) @@ -42,6 +78,7 @@ typedef struct MacIOState { PCIDevice parent; /*< public >*/ + MacIOBusState macio_bus; MemoryRegion bar; CUDAState cuda; PMUState pmu; diff --git a/include/hw/pci-host/uninorth.h b/include/hw/pci-host/uninorth.h index 2a1cf9f284..060324536a 100644 --- a/include/hw/pci-host/uninorth.h +++ b/include/hw/pci-host/uninorth.h @@ -49,6 +49,7 @@ typedef struct UNINHostState { PCIHostState parent_obj; + uint32_t ofw_addr; OpenPICState *pic; qemu_irq irqs[4]; MemoryRegion pci_mmio; diff --git a/include/hw/riscv/sifive_plic.h b/include/hw/riscv/sifive_plic.h index 2f2af7e686..688cd97f82 100644 --- a/include/hw/riscv/sifive_plic.h +++ b/include/hw/riscv/sifive_plic.h @@ -55,7 +55,6 @@ typedef struct SiFivePLICState { uint32_t *pending; uint32_t *claimed; uint32_t *enable; - QemuMutex lock; /* config */ char *hart_config; diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index d0321672f4..c8c599f1b9 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -125,7 +125,6 @@ typedef struct VirtIOGPU { uint32_t bytes_3d; } stats; - void (*disable_scanout)(struct VirtIOGPU *g, int scanout_id); Error *migration_blocker; } VirtIOGPU; @@ -150,6 +149,7 @@ extern const GraphicHwOps virtio_gpu_ops; } while (0) /* virtio-gpu.c */ +void virtio_gpu_reset(VirtIODevice *vdev); void virtio_gpu_ctrl_response(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd, struct virtio_gpu_ctrl_hdr *resp, @@ -159,10 +159,12 @@ void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g, enum virtio_gpu_ctrl_type type); void virtio_gpu_get_display_info(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); -int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, +int virtio_gpu_create_mapping_iov(VirtIOGPU *g, + struct virtio_gpu_resource_attach_backing *ab, struct virtio_gpu_ctrl_command *cmd, uint64_t **addr, struct iovec **iov); -void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count); +void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g, + struct iovec *iov, uint32_t count); void virtio_gpu_process_cmdq(VirtIOGPU *g); /* virtio-gpu-3d.c */ diff --git a/include/net/net.h b/include/net/net.h index 1425960f76..7936d53d2f 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -201,9 +201,6 @@ extern NICInfo nd_table[MAX_NICS]; extern const char *host_net_devices[]; /* from net.c */ -extern const char *legacy_tftp_prefix; -extern const char *legacy_bootp_filename; - int net_client_parse(QemuOptsList *opts_list, const char *str); int net_init_clients(Error **errp); void net_check_clients(void); diff --git a/include/net/slirp.h b/include/net/slirp.h index 4d63d74da4..bad3e1e241 100644 --- a/include/net/slirp.h +++ b/include/net/slirp.h @@ -30,10 +30,6 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict); void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict); -int net_slirp_redir(const char *redir_str); - -int net_slirp_smb(const char *exported_dir); - void hmp_info_usernet(Monitor *mon, const QDict *qdict); #endif diff --git a/include/qapi/qmp-event.h b/include/qapi/qmp-event.h index 0c87ad833e..23e588ccf8 100644 --- a/include/qapi/qmp-event.h +++ b/include/qapi/qmp-event.h @@ -14,8 +14,7 @@ #ifndef QMP_EVENT_H #define QMP_EVENT_H - -typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp); +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict); void qmp_event_set_func_emit(QMPEventFuncEmit emit); diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 4e2e749faf..68a528a9aa 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -50,7 +50,7 @@ bool qmp_has_success_response(const QmpCommand *cmd); QDict *qmp_error_response(Error *err); QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request, bool allow_oob); -bool qmp_is_oob(QDict *dict); +bool qmp_is_oob(const QDict *dict); typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque); diff --git a/include/qemu/job.h b/include/qemu/job.h index 18c9223e31..e0cff702b7 100644 --- a/include/qemu/job.h +++ b/include/qemu/job.h @@ -124,12 +124,20 @@ typedef struct Job { /** Estimated progress_current value at the completion of the job */ int64_t progress_total; - /** Error string for a failed job (NULL if, and only if, job->ret == 0) */ - char *error; - - /** ret code passed to job_completed. */ + /** + * Return code from @run and/or @prepare callback(s). + * Not final until the job has reached the CONCLUDED status. + * 0 on success, -errno on failure. + */ int ret; + /** + * Error object for a failed job. + * If job->ret is nonzero and an error object was not set, it will be set + * to strerror(-job->ret) during job_completed. + */ + Error *err; + /** The completion function that will be called when the job completes. */ BlockCompletionFunc *cb; @@ -168,8 +176,17 @@ struct JobDriver { /** Enum describing the operation */ JobType job_type; - /** Mandatory: Entrypoint for the Coroutine. */ - CoroutineEntry *start; + /** + * Mandatory: Entrypoint for the Coroutine. + * + * This callback will be invoked when moving from CREATED to RUNNING. + * + * If this callback returns nonzero, the job transaction it is part of is + * aborted. If it returns zero, the job moves into the WAITING state. If it + * is the last job to complete in its transaction, all jobs in the + * transaction move from WAITING to PENDING. + */ + int coroutine_fn (*run)(Job *job, Error **errp); /** * If the callback is not NULL, it will be invoked when the job transitions @@ -205,6 +222,17 @@ struct JobDriver { void (*drain)(Job *job); /** + * If the callback is not NULL, exit will be invoked from the main thread + * when the job's coroutine has finished, but before transactional + * convergence; before @prepare or @abort. + * + * FIXME TODO: This callback is only temporary to transition remaining jobs + * to prepare/commit/abort/clean callbacks and will be removed before 3.1. + * is released. + */ + void (*exit)(Job *job); + + /** * If the callback is not NULL, prepare will be invoked when all the jobs * belonging to the same transaction complete; or upon this job's completion * if it is not in a transaction. @@ -481,19 +509,6 @@ void job_early_fail(Job *job); /** Moves the @job from RUNNING to READY */ void job_transition_to_ready(Job *job); -/** - * @job: The job being completed. - * @ret: The status code. - * @error: The error message for a failing job (only with @ret < 0). If @ret is - * negative, but NULL is given for @error, strerror() is used. - * - * Marks @job as completed. If @ret is non-zero, the job transaction it is part - * of is aborted. If @ret is zero, the job moves into the WAITING state. If it - * is the last job to complete in its transaction, all jobs in the transaction - * move from WAITING to PENDING. - */ -void job_completed(Job *job, int ret, Error *error); - /** Asynchronously complete the specified @job. */ void job_complete(Job *job, Error **errp); @@ -553,23 +568,6 @@ void job_finalize(Job *job, Error **errp); */ void job_dismiss(Job **job, Error **errp); -typedef void JobDeferToMainLoopFn(Job *job, void *opaque); - -/** - * @job: The job - * @fn: The function to run in the main loop - * @opaque: The opaque value that is passed to @fn - * - * This function must be called by the main job coroutine just before it - * returns. @fn is executed in the main loop with the job AioContext acquired. - * - * Block jobs must call bdrv_unref(), bdrv_close(), and anything that uses - * bdrv_drain_all() in the main loop. - * - * The @job AioContext is held while @fn executes. - */ -void job_defer_to_main_loop(Job *job, JobDeferToMainLoopFn *fn, void *opaque); - /** * Synchronously finishes the given @job. If @finish is given, it is called to * trigger completion or cancellation of the job. @@ -146,8 +146,9 @@ static JobInfo *job_query_single(Job *job, Error **errp) .status = job->status, .current_progress = job->progress_current, .total_progress = job->progress_total, - .has_error = !!job->error, - .error = g_strdup(job->error), + .has_error = !!job->err, + .error = job->err ? \ + g_strdup(error_get_pretty(job->err)) : NULL, }; return info; @@ -174,7 +174,7 @@ static void job_state_transition(Job *job, JobStatus s1) job->status = s1; if (!job_is_internal(job) && s1 != s0) { - qapi_event_send_job_status_change(job->id, job->status, &error_abort); + qapi_event_send_job_status_change(job->id, job->status); } } @@ -369,7 +369,7 @@ void job_unref(Job *job) QLIST_REMOVE(job, job_list); - g_free(job->error); + error_free(job->err); g_free(job->id); g_free(job); } @@ -535,6 +535,20 @@ void job_drain(Job *job) } } +static void job_completed(Job *job); + +static void job_exit(void *opaque) +{ + Job *job = (Job *)opaque; + AioContext *aio_context = job->aio_context; + + if (job->driver->exit) { + aio_context_acquire(aio_context); + job->driver->exit(job); + aio_context_release(aio_context); + } + job_completed(job); +} /** * All jobs must allow a pause point before entering their job proper. This @@ -544,16 +558,18 @@ static void coroutine_fn job_co_entry(void *opaque) { Job *job = opaque; - assert(job && job->driver && job->driver->start); + assert(job && job->driver && job->driver->run); job_pause_point(job); - job->driver->start(job); + job->ret = job->driver->run(job, &job->err); + job->deferred_to_main_loop = true; + aio_bh_schedule_oneshot(qemu_get_aio_context(), job_exit, job); } void job_start(Job *job) { assert(job && !job_started(job) && job->paused && - job->driver && job->driver->start); + job->driver && job->driver->run); job->co = qemu_coroutine_create(job_co_entry, job); job->pause_count--; job->busy = true; @@ -666,8 +682,8 @@ static void job_update_rc(Job *job) job->ret = -ECANCELED; } if (job->ret) { - if (!job->error) { - job->error = g_strdup(strerror(-job->ret)); + if (!job->err) { + error_setg(&job->err, "%s", strerror(-job->ret)); } job_state_transition(job, JOB_STATUS_ABORTING); } @@ -865,19 +881,12 @@ static void job_completed_txn_success(Job *job) } } -void job_completed(Job *job, int ret, Error *error) +static void job_completed(Job *job) { assert(job && job->txn && !job_is_completed(job)); - job->ret = ret; - if (error) { - assert(job->ret < 0); - job->error = g_strdup(error_get_pretty(error)); - error_free(error); - } - job_update_rc(job); - trace_job_completed(job, ret, job->ret); + trace_job_completed(job, job->ret); if (job->ret) { job_completed_txn_abort(job); } else { @@ -893,7 +902,7 @@ void job_cancel(Job *job, bool force) } job_cancel_async(job, force); if (!job_started(job)) { - job_completed(job, -ECANCELED, NULL); + job_completed(job); } else if (job->deferred_to_main_loop) { job_completed_txn_abort(job); } else { @@ -956,38 +965,6 @@ void job_complete(Job *job, Error **errp) job->driver->complete(job, errp); } - -typedef struct { - Job *job; - JobDeferToMainLoopFn *fn; - void *opaque; -} JobDeferToMainLoopData; - -static void job_defer_to_main_loop_bh(void *opaque) -{ - JobDeferToMainLoopData *data = opaque; - Job *job = data->job; - AioContext *aio_context = job->aio_context; - - aio_context_acquire(aio_context); - data->fn(data->job, data->opaque); - aio_context_release(aio_context); - - g_free(data); -} - -void job_defer_to_main_loop(Job *job, JobDeferToMainLoopFn *fn, void *opaque) -{ - JobDeferToMainLoopData *data = g_malloc(sizeof(*data)); - data->job = job; - data->fn = fn; - data->opaque = opaque; - job->deferred_to_main_loop = true; - - aio_bh_schedule_oneshot(qemu_get_aio_context(), - job_defer_to_main_loop_bh, data); -} - int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp) { Error *local_err = NULL; diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8638612aec..e97c4cde49 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -710,6 +710,7 @@ enum { QEMU_PPC_FEATURE2_HAS_EBB = 0x10000000, /* Event Base Branching */ QEMU_PPC_FEATURE2_HAS_ISEL = 0x08000000, /* Integer Select */ QEMU_PPC_FEATURE2_HAS_TAR = 0x04000000, /* Target Address Register */ + QEMU_PPC_FEATURE2_ARCH_3_00 = 0x00800000, /* ISA 3.00 */ }; #define ELF_HWCAP get_elf_hwcap() @@ -764,6 +765,7 @@ static uint32_t get_elf_hwcap2(void) GET_FEATURE2(PPC2_BCTAR_ISA207, QEMU_PPC_FEATURE2_HAS_TAR); GET_FEATURE2((PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07); + GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00); #undef GET_FEATURE #undef GET_FEATURE2 diff --git a/migration/migration.c b/migration/migration.c index 4b316ec343..05d0a7296a 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -204,7 +204,7 @@ void migration_incoming_state_destroy(void) static void migrate_generate_event(int new_state) { if (migrate_use_events()) { - qapi_event_send_migration(new_state, &error_abort); + qapi_event_send_migration(new_state); } } @@ -302,7 +302,7 @@ void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p; - qapi_event_send_migration(MIGRATION_STATUS_SETUP, &error_abort); + qapi_event_send_migration(MIGRATION_STATUS_SETUP); if (!strcmp(uri, "defer")) { deferred_incoming_migration(errp); } else if (strstart(uri, "tcp:", &p)) { diff --git a/migration/ram.c b/migration/ram.c index 79c89425a3..f6fd8e5e09 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -1670,7 +1670,7 @@ static void migration_bitmap_sync(RAMState *rs) rs->bytes_xfer_prev = bytes_xfer_now; } if (migrate_use_events()) { - qapi_event_send_migration_pass(ram_counters.dirty_sync_count, NULL); + qapi_event_send_migration_pass(ram_counters.dirty_sync_count); } } @@ -182,8 +182,6 @@ typedef struct { QemuMutex qmp_queue_lock; /* Input queue that holds all the parsed QMP requests */ GQueue *qmp_requests; - /* Output queue contains all the QMP responses in order */ - GQueue *qmp_responses; } MonitorQMP; /* @@ -247,9 +245,6 @@ IOThread *mon_iothread; /* Bottom half to dispatch the requests received from I/O thread */ QEMUBH *qmp_dispatcher_bh; -/* Bottom half to deliver the responses back to clients */ -QEMUBH *qmp_respond_bh; - struct QMPRequest { /* Owner of the request */ Monitor *mon; @@ -261,12 +256,6 @@ struct QMPRequest { */ QObject *req; Error *err; - /* - * Whether we need to resume the monitor afterward. This flag is - * used to emulate the old QMP server behavior that the current - * command must be completed before execution of the next one. - */ - bool need_resume; }; typedef struct QMPRequest QMPRequest; @@ -375,19 +364,10 @@ static void monitor_qmp_cleanup_req_queue_locked(Monitor *mon) } } -/* Caller must hold the mon->qmp.qmp_queue_lock */ -static void monitor_qmp_cleanup_resp_queue_locked(Monitor *mon) -{ - while (!g_queue_is_empty(mon->qmp.qmp_responses)) { - qobject_unref((QDict *)g_queue_pop_head(mon->qmp.qmp_responses)); - } -} - static void monitor_qmp_cleanup_queues(Monitor *mon) { qemu_mutex_lock(&mon->qmp.qmp_queue_lock); monitor_qmp_cleanup_req_queue_locked(mon); - monitor_qmp_cleanup_resp_queue_locked(mon); qemu_mutex_unlock(&mon->qmp.qmp_queue_lock); } @@ -503,9 +483,9 @@ int monitor_fprintf(FILE *stream, const char *fmt, ...) return 0; } -static void qmp_send_response(Monitor *mon, QDict *rsp) +static void qmp_send_response(Monitor *mon, const QDict *rsp) { - QObject *data = QOBJECT(rsp); + const QObject *data = QOBJECT(rsp); QString *json; json = mon->flags & MONITOR_USE_PRETTY ? qobject_to_json_pretty(data) : @@ -518,85 +498,6 @@ static void qmp_send_response(Monitor *mon, QDict *rsp) qobject_unref(json); } -static void qmp_queue_response(Monitor *mon, QDict *rsp) -{ - if (mon->use_io_thread) { - /* - * Push a reference to the response queue. The I/O thread - * drains that queue and emits. - */ - qemu_mutex_lock(&mon->qmp.qmp_queue_lock); - g_queue_push_tail(mon->qmp.qmp_responses, qobject_ref(rsp)); - qemu_mutex_unlock(&mon->qmp.qmp_queue_lock); - qemu_bh_schedule(qmp_respond_bh); - } else { - /* - * Not using monitor I/O thread, i.e. we are in the main thread. - * Emit right away. - */ - qmp_send_response(mon, rsp); - } -} - -struct QMPResponse { - Monitor *mon; - QDict *data; -}; -typedef struct QMPResponse QMPResponse; - -static QDict *monitor_qmp_response_pop_one(Monitor *mon) -{ - QDict *data; - - qemu_mutex_lock(&mon->qmp.qmp_queue_lock); - data = g_queue_pop_head(mon->qmp.qmp_responses); - qemu_mutex_unlock(&mon->qmp.qmp_queue_lock); - - return data; -} - -static void monitor_qmp_response_flush(Monitor *mon) -{ - QDict *data; - - while ((data = monitor_qmp_response_pop_one(mon))) { - qmp_send_response(mon, data); - qobject_unref(data); - } -} - -/* - * Pop a QMPResponse from any monitor's response queue into @response. - * Return false if all the queues are empty; else true. - */ -static bool monitor_qmp_response_pop_any(QMPResponse *response) -{ - Monitor *mon; - QDict *data = NULL; - - qemu_mutex_lock(&monitor_lock); - QTAILQ_FOREACH(mon, &mon_list, entry) { - data = monitor_qmp_response_pop_one(mon); - if (data) { - response->mon = mon; - response->data = data; - break; - } - } - qemu_mutex_unlock(&monitor_lock); - return data != NULL; -} - -static void monitor_qmp_bh_responder(void *opaque) -{ - QMPResponse response; - - while (monitor_qmp_response_pop_any(&response)) { - qmp_send_response(response.mon, response.data); - qobject_unref(response.data); - } -} - static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = { /* Limit guest-triggerable events to 1 per second */ [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS }, @@ -620,7 +521,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) QTAILQ_FOREACH(mon, &mon_list, entry) { if (monitor_is_qmp(mon) && mon->qmp.commands != &qmp_cap_negotiation_commands) { - qmp_queue_response(mon, qdict); + qmp_send_response(mon, qdict); } } } @@ -688,7 +589,7 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict) } static void -monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp) +monitor_qapi_event_queue(QAPIEvent event, QDict *qdict) { /* * monitor_qapi_event_queue_no_reenter() is not reentrant: it @@ -818,7 +719,6 @@ static void monitor_data_init(Monitor *mon, bool skip_flush, mon->skip_flush = skip_flush; mon->use_io_thread = use_io_thread; mon->qmp.qmp_requests = g_queue_new(); - mon->qmp.qmp_responses = g_queue_new(); } static void monitor_data_destroy(Monitor *mon) @@ -833,9 +733,7 @@ static void monitor_data_destroy(Monitor *mon) qemu_mutex_destroy(&mon->mon_lock); qemu_mutex_destroy(&mon->qmp.qmp_queue_lock); monitor_qmp_cleanup_req_queue_locked(mon); - monitor_qmp_cleanup_resp_queue_locked(mon); g_queue_free(mon->qmp.qmp_requests); - g_queue_free(mon->qmp.qmp_responses); } char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, @@ -4152,7 +4050,7 @@ static void monitor_qmp_respond(Monitor *mon, QDict *rsp, QObject *id) qdict_put_obj(rsp, "id", qobject_ref(id)); } - qmp_queue_response(mon, rsp); + qmp_send_response(mon, rsp); } } @@ -4227,11 +4125,14 @@ static void monitor_qmp_bh_dispatcher(void *data) { QMPRequest *req_obj = monitor_qmp_requests_pop_any(); QDict *rsp; + bool need_resume; if (!req_obj) { return; } + /* qmp_oob_enabled() might change after "qmp_capabilities" */ + need_resume = !qmp_oob_enabled(req_obj->mon); if (req_obj->req) { trace_monitor_qmp_cmd_in_band(qobject_get_try_str(req_obj->id) ?: ""); monitor_qmp_dispatch(req_obj->mon, req_obj->req, req_obj->id); @@ -4243,7 +4144,7 @@ static void monitor_qmp_bh_dispatcher(void *data) qobject_unref(rsp); } - if (req_obj->need_resume) { + if (need_resume) { /* Pairs with the monitor_suspend() in handle_qmp_command() */ monitor_resume(req_obj->mon); } @@ -4291,7 +4192,6 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) req_obj->id = id; req_obj->req = req; req_obj->err = err; - req_obj->need_resume = false; /* Protect qmp_requests and fetching its length. */ qemu_mutex_lock(&mon->qmp.qmp_queue_lock); @@ -4304,7 +4204,6 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) */ if (!qmp_oob_enabled(mon)) { monitor_suspend(mon); - req_obj->need_resume = true; } else { /* Drop the request if queue is full. */ if (mon->qmp.qmp_requests->length >= QMP_REQ_QUEUE_LEN_MAX) { @@ -4316,8 +4215,7 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) * that command was dropped. */ qapi_event_send_command_dropped(id, - COMMAND_DROP_REASON_QUEUE_FULL, - &error_abort); + COMMAND_DROP_REASON_QUEUE_FULL); qmp_request_free(req_obj); return; } @@ -4411,6 +4309,7 @@ void monitor_resume(Monitor *mon) assert(mon->rs); readline_show_prompt(mon->rs); } + qemu_chr_fe_accept_input(&mon->chr); } trace_monitor_suspend(mon, -1); } @@ -4444,7 +4343,7 @@ static void monitor_qmp_event(void *opaque, int event) mon->qmp.commands = &qmp_cap_negotiation_commands; monitor_qmp_caps_reset(mon); data = qmp_greeting(mon); - qmp_queue_response(mon, data); + qmp_send_response(mon, data); qobject_unref(data); mon_refcount++; break; @@ -4455,7 +4354,6 @@ static void monitor_qmp_event(void *opaque, int event) * stdio, it's possible that stdout is still open when stdin * is closed. */ - monitor_qmp_response_flush(mon); monitor_qmp_cleanup_queues(mon); json_message_parser_destroy(&mon->qmp.parser); json_message_parser_init(&mon->qmp.parser, handle_qmp_command, @@ -4558,15 +4456,6 @@ static void monitor_iothread_init(void) qmp_dispatcher_bh = aio_bh_new(iohandler_get_aio_context(), monitor_qmp_bh_dispatcher, NULL); - - /* - * The responder BH must be run in the monitor I/O thread, so that - * monitors that are using the I/O thread have their output - * written by the I/O thread. - */ - qmp_respond_bh = aio_bh_new(monitor_get_aio_context(), - monitor_qmp_bh_responder, - NULL); } void monitor_init_globals(void) @@ -4631,15 +4520,9 @@ static void monitor_qmp_setup_handlers_bh(void *opaque) Monitor *mon = opaque; GMainContext *context; - if (mon->use_io_thread) { - /* Use @mon_iothread context */ - context = monitor_get_io_context(); - assert(context); - } else { - /* Use default main loop context */ - context = NULL; - } - + assert(mon->use_io_thread); + context = monitor_get_io_context(); + assert(context); qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_qmp_read, monitor_qmp_event, NULL, mon, context, true); monitor_list_append(mon); @@ -4719,12 +4602,6 @@ void monitor_cleanup(void) */ iothread_stop(mon_iothread); - /* - * Flush all response queues. Note that even after this flush, - * data may remain in output buffers. - */ - monitor_qmp_bh_responder(NULL); - /* Flush output buffers and destroy monitors */ qemu_mutex_lock(&monitor_lock); QTAILQ_FOREACH_SAFE(mon, &mon_list, entry, next) { @@ -4738,8 +4615,6 @@ void monitor_cleanup(void) /* QEMUBHs needs to be deleted before destroying the I/O thread */ qemu_bh_delete(qmp_dispatcher_bh); qmp_dispatcher_bh = NULL; - qemu_bh_delete(qmp_respond_bh); - qmp_respond_bh = NULL; iothread_destroy(mon_iothread); mon_iothread = NULL; diff --git a/net/slirp.c b/net/slirp.c index 1e14318b4d..c18060f778 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -67,13 +67,11 @@ static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) /* slirp network adapter */ #define SLIRP_CFG_HOSTFWD 1 -#define SLIRP_CFG_LEGACY 2 struct slirp_config_str { struct slirp_config_str *next; int flags; char str[1024]; - int legacy_format; }; typedef struct SlirpState { @@ -87,19 +85,13 @@ typedef struct SlirpState { } SlirpState; static struct slirp_config_str *slirp_configs; -const char *legacy_tftp_prefix; -const char *legacy_bootp_filename; static QTAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks = QTAILQ_HEAD_INITIALIZER(slirp_stacks); -static int slirp_hostfwd(SlirpState *s, const char *redir_str, - int legacy_format, Error **errp); -static int slirp_guestfwd(SlirpState *s, const char *config_str, - int legacy_format, Error **errp); +static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp); +static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp); #ifndef _WIN32 -static const char *legacy_smb_export; - static int slirp_smb(SlirpState *s, const char *exported_dir, struct in_addr vserver_addr, Error **errp); static void slirp_smb_cleanup(SlirpState *s); @@ -196,13 +188,6 @@ static int net_slirp_init(NetClientState *peer, const char *model, return -1; } - if (!tftp_export) { - tftp_export = legacy_tftp_prefix; - } - if (!bootfile) { - bootfile = legacy_bootp_filename; - } - if (vnetwork) { if (get_str_sep(buf, sizeof(buf), &vnetwork, '/') < 0) { if (!inet_aton(vnetwork, &net)) { @@ -382,21 +367,16 @@ static int net_slirp_init(NetClientState *peer, const char *model, for (config = slirp_configs; config; config = config->next) { if (config->flags & SLIRP_CFG_HOSTFWD) { - if (slirp_hostfwd(s, config->str, - config->flags & SLIRP_CFG_LEGACY, errp) < 0) { + if (slirp_hostfwd(s, config->str, errp) < 0) { goto error; } } else { - if (slirp_guestfwd(s, config->str, - config->flags & SLIRP_CFG_LEGACY, errp) < 0) { + if (slirp_guestfwd(s, config->str, errp) < 0) { goto error; } } } #ifndef _WIN32 - if (!smb_export) { - smb_export = legacy_smb_export; - } if (smb_export) { if (slirp_smb(s, smb_export, smbsrv, errp) < 0) { goto error; @@ -506,8 +486,7 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict) monitor_printf(mon, "invalid format\n"); } -static int slirp_hostfwd(SlirpState *s, const char *redir_str, - int legacy_format, Error **errp) +static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp) { struct in_addr host_addr = { .s_addr = INADDR_ANY }; struct in_addr guest_addr = { .s_addr = 0 }; @@ -532,18 +511,16 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, goto fail_syntax; } - if (!legacy_format) { - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - fail_reason = "Missing : separator"; - goto fail_syntax; - } - if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) { - fail_reason = "Bad host address"; - goto fail_syntax; - } + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + fail_reason = "Missing : separator"; + goto fail_syntax; + } + if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) { + fail_reason = "Bad host address"; + goto fail_syntax; } - if (get_str_sep(buf, sizeof(buf), &p, legacy_format ? ':' : '-') < 0) { + if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) { fail_reason = "Bad host port separator"; goto fail_syntax; } @@ -602,35 +579,13 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict) } if (s) { Error *err = NULL; - if (slirp_hostfwd(s, redir_str, 0, &err) < 0) { + if (slirp_hostfwd(s, redir_str, &err) < 0) { error_report_err(err); } } } -int net_slirp_redir(const char *redir_str) -{ - struct slirp_config_str *config; - Error *err = NULL; - int res; - - if (QTAILQ_EMPTY(&slirp_stacks)) { - config = g_malloc(sizeof(*config)); - pstrcpy(config->str, sizeof(config->str), redir_str); - config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY; - config->next = slirp_configs; - slirp_configs = config; - return 0; - } - - res = slirp_hostfwd(QTAILQ_FIRST(&slirp_stacks), redir_str, 1, &err); - if (res < 0) { - error_report_err(err); - } - return res; -} - #ifndef _WIN32 /* automatic user mode samba server configuration */ @@ -746,28 +701,6 @@ static int slirp_smb(SlirpState* s, const char *exported_dir, return 0; } -/* automatic user mode samba server configuration (legacy interface) */ -int net_slirp_smb(const char *exported_dir) -{ - struct in_addr vserver_addr = { .s_addr = 0 }; - - if (legacy_smb_export) { - fprintf(stderr, "-smb given twice\n"); - return -1; - } - legacy_smb_export = exported_dir; - if (!QTAILQ_EMPTY(&slirp_stacks)) { - Error *err = NULL; - int res = slirp_smb(QTAILQ_FIRST(&slirp_stacks), exported_dir, - vserver_addr, &err); - if (res < 0) { - error_report_err(err); - } - return res; - } - return 0; -} - #endif /* !defined(_WIN32) */ struct GuestFwd { @@ -789,8 +722,7 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size); } -static int slirp_guestfwd(SlirpState *s, const char *config_str, - int legacy_format, Error **errp) +static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp) { struct in_addr server = { .s_addr = 0 }; struct GuestFwd *fwd; @@ -800,26 +732,20 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, int port; p = config_str; - if (legacy_format) { - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - goto fail_syntax; - } - } else { - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - goto fail_syntax; - } - if (strcmp(buf, "tcp") && buf[0] != '\0') { - goto fail_syntax; - } - if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { - goto fail_syntax; - } - if (buf[0] != '\0' && !inet_aton(buf, &server)) { - goto fail_syntax; - } - if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) { - goto fail_syntax; - } + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + if (strcmp(buf, "tcp") && buf[0] != '\0') { + goto fail_syntax; + } + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + if (buf[0] != '\0' && !inet_aton(buf, &server)) { + goto fail_syntax; + } + if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) { + goto fail_syntax; } port = strtol(buf, &end, 10); if (*end != '\0' || port < 1 || port > 65535) { diff --git a/os-posix.c b/os-posix.c index 9ce6f74513..8f39447dd4 100644 --- a/os-posix.c +++ b/os-posix.c @@ -168,14 +168,6 @@ static bool os_parse_runas_uid_gid(const char *optarg) int os_parse_cmd_args(int index, const char *optarg) { switch (index) { -#ifdef CONFIG_SLIRP - case QEMU_OPTION_smb: - error_report("The -smb option is deprecated. " - "Please use '-netdev user,smb=...' instead."); - if (net_slirp_smb(optarg) < 0) - exit(1); - break; -#endif case QEMU_OPTION_runas: user_pwd = getpwnam(optarg); if (user_pwd) { diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc Binary files differindex a39cbe57ca..819983852b 100644 --- a/pc-bios/openbios-ppc +++ b/pc-bios/openbios-ppc diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32 Binary files differindex 7163ba8b3b..4123bc40d7 100644 --- a/pc-bios/openbios-sparc32 +++ b/pc-bios/openbios-sparc32 diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64 Binary files differindex 0a9a338f78..35c99911fe 100644 --- a/pc-bios/openbios-sparc64 +++ b/pc-bios/openbios-sparc64 diff --git a/qapi/common.json b/qapi/common.json index c367adc4b6..50ac121d25 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -146,6 +146,6 @@ 'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32', 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc', - 'ppc64', 'ppcemb', 'riscv32', 'riscv64', 's390x', 'sh4', + 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4', 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32', 'x86_64', 'xtensa', 'xtensaeb' ] } diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index d8da1a62de..1d922e04f7 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -155,7 +155,7 @@ QDict *qmp_error_response(Error *err) /* * Does @qdict look like a command to be run out-of-band? */ -bool qmp_is_oob(QDict *dict) +bool qmp_is_oob(const QDict *dict) { return qdict_haskey(dict, "exec-oob") && !qdict_haskey(dict, "execute"); diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index 1b9c007f12..a43fcf4835 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -40,40 +40,6 @@ which is the default. The ``-no-kvm'' argument is now a synonym for setting ``-machine accel=tcg''. -@subsection -tftp (since 2.6.0) - -The ``-tftp /some/dir'' argument is replaced by either -``-netdev user,id=x,tftp=/some/dir '' (for pluggable NICs, accompanied -with ``-device ...,netdev=x''), or ``-nic user,tftp=/some/dir'' -(for embedded NICs). The new syntax allows different settings to be -provided per NIC. - -@subsection -bootp (since 2.6.0) - -The ``-bootp /some/file'' argument is replaced by either -``-netdev user,id=x,bootp=/some/file '' (for pluggable NICs, accompanied -with ``-device ...,netdev=x''), or ``-nic user,bootp=/some/file'' -(for embedded NICs). The new syntax allows different settings to be -provided per NIC. - -@subsection -redir (since 2.6.0) - -The ``-redir [tcp|udp]:hostport:[guestaddr]:guestport'' argument is -replaced by either -``-netdev user,id=x,hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport'' -(for pluggable NICs, accompanied with ``-device ...,netdev=x'') or -``-nic user,hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport'' -(for embedded NICs). The new syntax allows different settings to be -provided per NIC. - -@subsection -smb (since 2.6.0) - -The ``-smb /some/dir'' argument is replaced by either -``-netdev user,id=x,smb=/some/dir '' (for pluggable NICs, accompanied -with ``-device ...,netdev=x''), or ``-nic user,smb=/some/dir'' -(for embedded NICs). The new syntax allows different settings to be -provided per NIC. - @subsection -usbdevice (since 2.10.0) The ``-usbdevice DEV'' argument is now a synonym for setting @@ -82,15 +48,6 @@ would automatically enable USB support on the machine type. If using the new syntax, USB support must be explicitly enabled via the ``-machine usb=on'' argument. -@subsection -nodefconfig (since 2.11.0) - -The ``-nodefconfig`` argument is a synonym for ``-no-user-config``. - -@subsection -balloon (since 2.12.0) - -The @option{--balloon virtio} argument has been superseded by -@option{--device virtio-balloon}. - @subsection -fsdev handle (since 2.12.0) The ``handle'' fsdev backend does not support symlinks and causes the 9p @@ -105,19 +62,6 @@ The @code{--no-frame} argument works with SDL 1.2 only. The other user interfaces never implemented this in the first place. So this will be removed together with SDL 1.2 support. -@subsection -rtc-td-hack (since 2.12.0) - -The @code{-rtc-td-hack} option has been replaced by -@code{-rtc driftfix=slew}. - -@subsection -localtime (since 2.12.0) - -The @code{-localtime} option has been replaced by @code{-rtc base=localtime}. - -@subsection -startdate (since 2.12.0) - -The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}. - @subsection -virtioconsole (since 3.0.0) Option @option{-virtioconsole} has been replaced by @@ -162,12 +106,6 @@ replaced by the ``target'' output member. The ``ivshmem'' device type is replaced by either the ``ivshmem-plain'' or ``ivshmem-doorbell`` device types. -@subsection Page size support < 4k for embedded PowerPC CPUs (since 2.12.0) - -qemu-system-ppcemb will be removed. qemu-system-ppc (or qemu-system-ppc64) -should be used instead. That means that embedded 4xx PowerPC CPUs will not -support page sizes < 4096 any longer. - @section System emulator machines @subsection pc-0.10 and pc-0.11 (since 3.0) diff --git a/qemu-options.hx b/qemu-options.hx index 654ef484d9..a642ad297f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -454,16 +454,6 @@ modprobe i810_audio clocking=48000 @end example ETEXI -DEF("balloon", HAS_ARG, QEMU_OPTION_balloon, - "-balloon virtio[,addr=str]\n" - " enable virtio balloon device (deprecated)\n", QEMU_ARCH_ALL) -STEXI -@item -balloon virtio[,addr=@var{addr}] -@findex -balloon -Enable virtio balloon device, optionally with PCI address @var{addr}. This -option is deprecated, use @option{-device virtio-balloon} instead. -ETEXI - DEF("device", HAS_ARG, QEMU_OPTION_device, "-device driver[,prop[=value][,...]]\n" " add device (based on driver)\n" @@ -1721,9 +1711,6 @@ Windows 2000 is installed, you no longer need this option (this option slows down the IDE transfers). ETEXI -HXCOMM Deprecated by -rtc -DEF("rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack, "", QEMU_ARCH_I386) - DEF("no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk, "-no-fd-bootchk disable boot signature checking for floppy disks\n", QEMU_ARCH_I386) @@ -1826,16 +1813,6 @@ STEXI @table @option ETEXI -HXCOMM Legacy slirp options (now moved to -net user): -#ifdef CONFIG_SLIRP -DEF("tftp", HAS_ARG, QEMU_OPTION_tftp, "", QEMU_ARCH_ALL) -DEF("bootp", HAS_ARG, QEMU_OPTION_bootp, "", QEMU_ARCH_ALL) -DEF("redir", HAS_ARG, QEMU_OPTION_redir, "", QEMU_ARCH_ALL) -#ifndef _WIN32 -DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL) -#endif -#endif - DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, #ifdef CONFIG_SLIRP "-netdev user,id=str[,ipv4[=on|off]][,net=addr[/mask]][,host=addr]\n" @@ -2163,11 +2140,6 @@ qemu-system-i386 -nic 'user,id=n1,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10 @end table -Note: Legacy stand-alone options -tftp, -bootp, -smb and -redir are still -processed and applied to -net user. Mixing them with the new configuration -syntax gives undefined results. Their use for new applications is discouraged -as they will be removed from future versions. - @item -netdev tap,id=@var{id}[,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}][,br=@var{bridge}][,helper=@var{helper}] Configure a host TAP network backend with ID @var{id}. @@ -3481,10 +3453,6 @@ ETEXI HXCOMM Silently ignored for compatibility DEF("clock", HAS_ARG, QEMU_OPTION_clock, "", QEMU_ARCH_ALL) -HXCOMM Options deprecated by -rtc -DEF("localtime", 0, QEMU_OPTION_localtime, "", QEMU_ARCH_ALL) -DEF("startdate", HAS_ARG, QEMU_OPTION_startdate, "", QEMU_ARCH_ALL) - DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \ "-rtc [base=utc|localtime|date][,clock=host|rt|vm][,driftfix=none|slew]\n" \ " set the RTC base and clock, enable drift fix for clock ticks (x86 only)\n", @@ -3843,8 +3811,7 @@ Write device configuration to @var{file}. The @var{file} can be either filename command line and device configuration into file or dash @code{-}) character to print the output to stdout. This can be later used as input file for @code{-readconfig} option. ETEXI -HXCOMM Deprecated, same as -no-user-config -DEF("nodefconfig", 0, QEMU_OPTION_nodefconfig, "", QEMU_ARCH_ALL) + DEF("no-user-config", 0, QEMU_OPTION_nouserconfig, "-no-user-config\n" " do not load default user-provided config files at startup\n", @@ -3855,6 +3822,7 @@ STEXI The @code{-no-user-config} option makes QEMU not load any of the user-provided config files on @var{sysconfdir}. ETEXI + DEF("trace", HAS_ARG, QEMU_OPTION_trace, "-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n" " specify tracing options\n", diff --git a/roms/openbios b/roms/openbios -Subproject 8fe6f5f96f6ca39f1f62200be7fa130e929f13f +Subproject a1280807a335cc93a4fffb6461c6419cb7a42e9 diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 02c5c6767a..7b62a4c7b0 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -2070,16 +2070,14 @@ extern const QEnumLookup %(c_name)s_lookup; return ret -def build_params(arg_type, boxed, extra): - if not arg_type: - assert not boxed - return extra +def build_params(arg_type, boxed, extra=None): ret = '' sep = '' if boxed: + assert arg_type ret += '%s arg' % arg_type.c_param_type() sep = ', ' - else: + elif arg_type: assert not arg_type.variants for memb in arg_type.members: ret += sep @@ -2090,7 +2088,7 @@ def build_params(arg_type, boxed, extra): c_name(memb.name)) if extra: ret += sep + extra - return ret + return ret if ret else 'void' # @@ -2220,6 +2218,7 @@ class QAPIGenC(QAPIGenCCode): def _bottom(self, fname): return mcgen(''' + /* Dummy declaration to prevent empty .o file */ char dummy_%(name)s; ''', diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index 764ef177ab..2ed7902424 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -18,7 +18,7 @@ from qapi.common import * def build_event_send_proto(name, arg_type, boxed): return 'void qapi_event_send_%(c_name)s(%(param)s)' % { 'c_name': c_name(name.lower()), - 'param': build_params(arg_type, boxed, 'Error **errp')} + 'param': build_params(arg_type, boxed)} def gen_event_send_decl(name, arg_type, boxed): @@ -70,7 +70,6 @@ def gen_event_send(name, arg_type, boxed, event_enum_name): %(proto)s { QDict *qmp; - Error *err = NULL; QMPEventFuncEmit emit; ''', proto=build_event_send_proto(name, arg_type, boxed)) @@ -103,45 +102,35 @@ def gen_event_send(name, arg_type, boxed, event_enum_name): ''') if not arg_type.is_implicit(): ret += mcgen(''' - visit_type_%(c_name)s(v, "%(name)s", &arg, &err); + visit_type_%(c_name)s(v, "%(name)s", &arg, &error_abort); ''', name=name, c_name=arg_type.c_name()) else: ret += mcgen(''' - visit_start_struct(v, "%(name)s", NULL, 0, &err); - if (err) { - goto out; - } - visit_type_%(c_name)s_members(v, ¶m, &err); - if (!err) { - visit_check_struct(v, &err); - } + visit_start_struct(v, "%(name)s", NULL, 0, &error_abort); + visit_type_%(c_name)s_members(v, ¶m, &error_abort); + visit_check_struct(v, &error_abort); visit_end_struct(v, NULL); ''', name=name, c_name=arg_type.c_name()) ret += mcgen(''' - if (err) { - goto out; - } visit_complete(v, &obj); qdict_put_obj(qmp, "data", obj); ''') ret += mcgen(''' - emit(%(c_enum)s, qmp, &err); + emit(%(c_enum)s, qmp); ''', c_enum=c_enum_const(event_enum_name, name)) if arg_type and not arg_type.is_empty(): ret += mcgen(''' -out: visit_free(v); ''') ret += mcgen(''' - error_propagate(errp, err); qobject_unref(qmp); } ''') diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 189a4edaba..67d6106f77 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -19,12 +19,17 @@ def to_qlit(obj, level=0, suppress_first_indent=False): return level * 4 * ' ' if isinstance(obj, tuple): - ifobj, ifcond = obj - ret = gen_if(ifcond) + ifobj, extra = obj + ifcond = extra.get('if') + comment = extra.get('comment') + ret = '' + if comment: + ret += indent(level) + '/* %s */\n' % comment + if ifcond: + ret += gen_if(ifcond) ret += to_qlit(ifobj, level) - endif = gen_endif(ifcond) - if endif: - ret += '\n' + endif + if ifcond: + ret += '\n' + gen_endif(ifcond) return ret ret = '' @@ -89,7 +94,6 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor): for typ in self._used_types: typ.visit(self) # generate C - # TODO can generate awfully long lines name = c_name(self._prefix, protect=False) + 'qmp_schema_qlit' self._genh.add(mcgen(''' #include "qapi/qmp/qlit.h" @@ -129,8 +133,8 @@ const QLitObject %(c_name)s = %(c_string)s; if typ not in self._used_types: self._used_types.append(typ) # Clients should examine commands and events, not types. Hide - # type names to reduce the temptation. Also saves a few - # characters. + # type names as integers to reduce the temptation. Also, it + # saves a few characters on the wire. if isinstance(typ, QAPISchemaBuiltinType): return typ.name if isinstance(typ, QAPISchemaArrayType): @@ -138,11 +142,21 @@ const QLitObject %(c_name)s = %(c_string)s; return self._name(typ.name) def _gen_qlit(self, name, mtype, obj, ifcond): + extra = {} if mtype not in ('command', 'event', 'builtin', 'array'): + if not self._unmask: + # Output a comment to make it easy to map masked names + # back to the source when reading the generated output. + extra['comment'] = '"%s" = %s' % (self._name(name), name) name = self._name(name) obj['name'] = name obj['meta-type'] = mtype - self._qlits.append((obj, ifcond)) + if ifcond: + extra['if'] = ifcond + if extra: + self._qlits.append((obj, extra)) + else: + self._qlits.append(obj) def _gen_member(self, member): ret = {'name': member.name, 'type': self._use_type(member.type)} @@ -185,7 +199,7 @@ const QLitObject %(c_name)s = %(c_string)s; arg_type = arg_type or self._schema.the_empty_object_type ret_type = ret_type or self._schema.the_empty_object_type obj = {'arg-type': self._use_type(arg_type), - 'ret-type': self._use_type(ret_type) } + 'ret-type': self._use_type(ret_type)} if allow_oob: obj['allow-oob'] = allow_oob self._gen_qlit(name, 'command', obj, ifcond) diff --git a/scsi/pr-manager-helper.c b/scsi/pr-manager-helper.c index 3027dde60d..438380fced 100644 --- a/scsi/pr-manager-helper.c +++ b/scsi/pr-manager-helper.c @@ -44,8 +44,7 @@ static void pr_manager_send_status_changed_event(PRManagerHelper *pr_mgr) char *id = object_get_canonical_path_component(OBJECT(pr_mgr)); if (id) { - qapi_event_send_pr_manager_status_changed(id, !!pr_mgr->ioc, - &error_abort); + qapi_event_send_pr_manager_status_changed(id, !!pr_mgr->ioc); g_free(id); } } diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 433a71e484..4ea67692e2 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -24,8 +24,6 @@ #ifdef TARGET_PPC64 #define TYPE_POWERPC_CPU "powerpc64-cpu" -#elif defined(TARGET_PPCEMB) -#define TYPE_POWERPC_CPU "embedded-powerpc-cpu" #else #define TYPE_POWERPC_CPU "powerpc-cpu" #endif diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ec149349e2..b5b8f6f440 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -52,23 +52,7 @@ #else /* defined (TARGET_PPC64) */ /* PowerPC 32 definitions */ #define TARGET_LONG_BITS 32 - -#if defined(TARGET_PPCEMB) -/* Specific definitions for PowerPC embedded */ -/* BookE have 36 bits physical address space */ -#if defined(CONFIG_USER_ONLY) -/* It looks like a lot of Linux programs assume page size - * is 4kB long. This is evil, but we have to deal with it... - */ -#define TARGET_PAGE_BITS 12 -#else /* defined(CONFIG_USER_ONLY) */ -/* Pages can be 1 kB small */ -#define TARGET_PAGE_BITS 10 -#endif /* defined(CONFIG_USER_ONLY) */ -#else /* defined(TARGET_PPCEMB) */ -/* "standard" PowerPC 32 definitions */ #define TARGET_PAGE_BITS 12 -#endif /* defined(TARGET_PPCEMB) */ #define TARGET_PHYS_ADDR_SPACE_BITS 36 #define TARGET_VIRT_ADDR_SPACE_BITS 32 diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 9211ee2ee1..30aeafa7de 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1315,9 +1315,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) return 0; } -#if defined(TARGET_PPCEMB) -#define PPC_INPUT_INT PPC40x_INPUT_INT -#elif defined(TARGET_PPC64) +#if defined(TARGET_PPC64) #define PPC_INPUT_INT PPC970_INPUT_INT #else #define PPC_INPUT_INT PPC6xx_INPUT_INT @@ -2785,3 +2783,12 @@ bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu) return !kvmppc_is_pr(cs->kvm_state); } + +void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online) +{ + CPUState *cs = CPU(cpu); + + if (kvm_enabled()) { + kvm_set_one_reg(cs, KVM_REG_PPC_ONLINE, &online); + } +} diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 657582bb32..f696c6e498 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -72,6 +72,7 @@ bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu); bool kvmppc_hpt_needs_host_contiguous_pages(void); void kvm_check_mmu(PowerPCCPU *cpu, Error **errp); +void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online); #else @@ -187,6 +188,12 @@ static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, return 0; } +static inline void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, + unsigned int online) +{ + return; +} + #ifndef CONFIG_USER_ONLY static inline bool kvmppc_spapr_use_multitce(void) { diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index e6739e6c24..04f8317ea1 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -2363,12 +2363,12 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry, tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT) & PPC4XX_TLBHI_SIZE_MASK); /* We cannot handle TLB size < TARGET_PAGE_SIZE. - * If this ever occurs, one should use the ppcemb target instead - * of the ppc or ppc64 one + * If this ever occurs, we should implement TARGET_PAGE_BITS_VARY */ if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) { cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u " - "are not supported (%d)\n", + "are not supported (%d)\n" + "Please implement TARGET_PAGE_BITS_VARY\n", tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7)); } tlb->EPN = val & ~(tlb->size - 1); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index d920d3e538..263e63cb03 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9647,17 +9647,6 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu) return 0; } -static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc) -{ -#ifdef TARGET_PPCEMB - return pcc->mmu_model == POWERPC_MMU_BOOKE || - pcc->mmu_model == POWERPC_MMU_SOFT_4xx || - pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z; -#else - return true; -#endif -} - static void ppc_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -9681,8 +9670,6 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) } } - assert(ppc_cpu_is_valid(pcc)); - create_ppc_opcodes(cpu, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); @@ -9933,10 +9920,6 @@ static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) return -1; } - if (!ppc_cpu_is_valid(pcc)) { - return -1; - } - return pcc->pvr == pvr ? 0 : -1; } @@ -9967,10 +9950,6 @@ static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b) return -1; } - if (!ppc_cpu_is_valid(pcc)) { - return -1; - } - if (pcc->pvr_match(pcc, pvr)) { return 0; } @@ -10036,11 +10015,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) g_free(typename); g_free(cpu_model); - if (oc && ppc_cpu_is_valid(POWERPC_CPU_CLASS(oc))) { - return oc; - } - - return NULL; + return oc; } static void ppc_cpu_parse_featurestr(const char *type, char *features, @@ -10146,9 +10121,6 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data) char *name; int i; - if (!ppc_cpu_is_valid(pcc)) { - return; - } if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) { return; } @@ -10206,11 +10178,6 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) const char *typename; CpuDefinitionInfoList *entry; CpuDefinitionInfo *info; - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - if (!ppc_cpu_is_valid(pcc)) { - return; - } typename = object_class_get_name(oc); info = g_malloc0(sizeof(*info)); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 34abc383e3..d4f36295f0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -24,12 +24,12 @@ #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */ #if defined(TARGET_RISCV64) #define TARGET_LONG_BITS 64 -#define TARGET_PHYS_ADDR_SPACE_BITS 50 -#define TARGET_VIRT_ADDR_SPACE_BITS 39 +#define TARGET_PHYS_ADDR_SPACE_BITS 56 /* 44-bit PPN */ +#define TARGET_VIRT_ADDR_SPACE_BITS 48 /* sv48 */ #elif defined(TARGET_RISCV32) #define TARGET_LONG_BITS 32 -#define TARGET_PHYS_ADDR_SPACE_BITS 34 -#define TARGET_VIRT_ADDR_SPACE_BITS 32 +#define TARGET_PHYS_ADDR_SPACE_BITS 34 /* 22-bit PPN */ +#define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */ #endif #define TCG_GUEST_DEFAULT_MO 0 @@ -251,7 +251,6 @@ int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, char *riscv_isa_string(RISCVCPU *cpu); void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf); -#define cpu_init(cpu_model) cpu_generic_init(TYPE_RISCV_CPU, cpu_model) #define cpu_signal_handler cpu_riscv_signal_handler #define cpu_list riscv_cpu_list #define cpu_mmu_index riscv_cpu_mmu_index diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 64aa097181..12b4757088 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -407,5 +407,3 @@ #define PTE_SOFT 0x300 /* Reserved for Software */ #define PTE_PPN_SHIFT 10 - -#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) diff --git a/target/riscv/helper.c b/target/riscv/helper.c index 29e1a603dc..63b3386b76 100644 --- a/target/riscv/helper.c +++ b/target/riscv/helper.c @@ -35,28 +35,18 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) } #ifndef CONFIG_USER_ONLY -/* - * Return RISC-V IRQ number if an interrupt should be taken, else -1. - * Used in cpu-exec.c - * - * Adapted from Spike's processor_t::take_interrupt() - */ -static int riscv_cpu_hw_interrupts_pending(CPURISCVState *env) +static int riscv_cpu_local_irq_pending(CPURISCVState *env) { - target_ulong pending_interrupts = atomic_read(&env->mip) & env->mie; - - target_ulong mie = get_field(env->mstatus, MSTATUS_MIE); - target_ulong m_enabled = env->priv < PRV_M || (env->priv == PRV_M && mie); - target_ulong enabled_interrupts = pending_interrupts & - ~env->mideleg & -m_enabled; - - target_ulong sie = get_field(env->mstatus, MSTATUS_SIE); - target_ulong s_enabled = env->priv < PRV_S || (env->priv == PRV_S && sie); - enabled_interrupts |= pending_interrupts & env->mideleg & - -s_enabled; - - if (enabled_interrupts) { - return ctz64(enabled_interrupts); /* since non-zero */ + target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE); + target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE); + target_ulong pending = atomic_read(&env->mip) & env->mie; + target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie); + target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && mstatus_sie); + target_ulong irqs = (pending & ~env->mideleg & -mie) | + (pending & env->mideleg & -sie); + + if (irqs) { + return ctz64(irqs); /* since non-zero */ } else { return EXCP_NONE; /* indicates no pending interrupt */ } @@ -69,7 +59,7 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request) if (interrupt_request & CPU_INTERRUPT_HARD) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; - int interruptno = riscv_cpu_hw_interrupts_pending(env); + int interruptno = riscv_cpu_local_irq_pending(env); if (interruptno >= 0) { cs->exception_index = RISCV_EXCP_INT_FLAG | interruptno; riscv_cpu_do_interrupt(cs); @@ -185,16 +175,39 @@ restart: #endif target_ulong ppn = pte >> PTE_PPN_SHIFT; - if (PTE_TABLE(pte)) { /* next level of page table */ + if (!(pte & PTE_V)) { + /* Invalid PTE */ + return TRANSLATE_FAIL; + } else if (!(pte & (PTE_R | PTE_W | PTE_X))) { + /* Inner PTE, continue walking */ base = ppn << PGSHIFT; - } else if ((pte & PTE_U) ? (mode == PRV_S) && !sum : !(mode == PRV_S)) { - break; - } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) { - break; - } else if (access_type == MMU_INST_FETCH ? !(pte & PTE_X) : - access_type == MMU_DATA_LOAD ? !(pte & PTE_R) && - !(mxr && (pte & PTE_X)) : !((pte & PTE_R) && (pte & PTE_W))) { - break; + } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) { + /* Reserved leaf PTE flags: PTE_W */ + return TRANSLATE_FAIL; + } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) { + /* Reserved leaf PTE flags: PTE_W + PTE_X */ + return TRANSLATE_FAIL; + } else if ((pte & PTE_U) && ((mode != PRV_U) && + (!sum || access_type == MMU_INST_FETCH))) { + /* User PTE flags when not U mode and mstatus.SUM is not set, + or the access type is an instruction fetch */ + return TRANSLATE_FAIL; + } else if (!(pte & PTE_U) && (mode != PRV_S)) { + /* Supervisor PTE flags when not S mode */ + return TRANSLATE_FAIL; + } else if (ppn & ((1ULL << ptshift) - 1)) { + /* Misaligned PPN */ + return TRANSLATE_FAIL; + } else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) || + ((pte & PTE_X) && mxr))) { + /* Read access check failed */ + return TRANSLATE_FAIL; + } else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) { + /* Write access check failed */ + return TRANSLATE_FAIL; + } else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) { + /* Fetch access check failed */ + return TRANSLATE_FAIL; } else { /* if necessary, set accessed and dirty bits. */ target_ulong updated_pte = pte | PTE_A | @@ -202,16 +215,19 @@ restart: /* Page table updates need to be atomic with MTTCG enabled */ if (updated_pte != pte) { - /* if accessed or dirty bits need updating, and the PTE is - * in RAM, then we do so atomically with a compare and swap. - * if the PTE is in IO space, then it can't be updated. - * if the PTE changed, then we must re-walk the page table - as the PTE is no longer valid */ + /* + * - if accessed or dirty bits need updating, and the PTE is + * in RAM, then we do so atomically with a compare and swap. + * - if the PTE is in IO space or ROM, then it can't be updated + * and we return TRANSLATE_FAIL. + * - if the PTE changed by the time we went to update it, then + * it is no longer valid and we must re-walk the page table. + */ MemoryRegion *mr; hwaddr l = sizeof(target_ulong), addr1; mr = address_space_translate(cs->as, pte_addr, &addr1, &l, false, MEMTXATTRS_UNSPECIFIED); - if (memory_access_is_direct(mr, true)) { + if (memory_region_is_ram(mr)) { target_ulong *pte_pa = qemu_map_ram_ptr(mr->ram_block, addr1); #if TCG_OVERSIZED_GUEST @@ -239,15 +255,15 @@ restart: target_ulong vpn = addr >> PGSHIFT; *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT; - if ((pte & PTE_R)) { + /* set permissions on the TLB entry */ + if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) { *prot |= PAGE_READ; } if ((pte & PTE_X)) { *prot |= PAGE_EXEC; } - /* only add write permission on stores or if the page - is already dirty, so that we don't miss further - page table walks to update the dirty bit */ + /* add write permission on stores or if the page is already dirty, + so that we TLB miss on later writes to update the dirty bit */ if ((pte & PTE_W) && (access_type == MMU_DATA_STORE || (pte & PTE_D))) { *prot |= PAGE_WRITE; diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 0b6be74f2d..18d7b6d147 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -135,7 +135,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) if (ctx->base.singlestep_enabled) { gen_exception_debug(); } else { - tcg_gen_exit_tb(NULL, 0); + tcg_gen_lookup_and_goto_ptr(); } } } @@ -548,7 +548,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc, if (rd != 0) { tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn); } - tcg_gen_exit_tb(NULL, 0); + tcg_gen_lookup_and_goto_ptr(); if (misaligned) { gen_set_label(misaligned); @@ -1868,12 +1868,7 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) switch (ctx->base.is_jmp) { case DISAS_TOO_MANY: - tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); - if (ctx->base.singlestep_enabled) { - gen_exception_debug(); - } else { - tcg_gen_exit_tb(NULL, 0); - } + gen_goto_tb(ctx, 0, ctx->base.pc_next); break; case DISAS_NORETURN: break; diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 5c6f33ed9c..9c7b434fca 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -102,6 +102,9 @@ D(0x9400, NI, SI, Z, la1, i2_8u, new, 0, ni, nz64, MO_UB) D(0xeb54, NIY, SIY, LD, la1, i2_8u, new, 0, ni, nz64, MO_UB) +/* BRANCH AND LINK */ + C(0x0500, BALR, RR_a, Z, 0, r2_nz, r1, 0, bal, 0) + C(0x4500, BAL, RX_a, Z, 0, a2, r1, 0, bal, 0) /* BRANCH AND SAVE */ C(0x0d00, BASR, RR_a, Z, 0, r2_nz, r1, 0, bas, 0) C(0x4d00, BAS, RX_a, Z, 0, a2, r1, 0, bas, 0) diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index e21a47fb4d..bacae4f503 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -1019,15 +1019,15 @@ void HELPER(pack)(CPUS390XState *env, uint32_t len, uint64_t dest, uint64_t src) len_src--; /* now pack every value */ - while (len_dest >= 0) { + while (len_dest > 0) { b = 0; - if (len_src > 0) { + if (len_src >= 0) { b = cpu_ldub_data_ra(env, src, ra) & 0x0f; src--; len_src--; } - if (len_src > 0) { + if (len_src >= 0) { b |= cpu_ldub_data_ra(env, src, ra) << 4; src--; len_src--; @@ -1299,12 +1299,26 @@ static inline uint32_t do_helper_trt(CPUS390XState *env, int len, return 0; } +static uint32_t do_helper_trt_fwd(CPUS390XState *env, uint32_t len, + uint64_t array, uint64_t trans, + uintptr_t ra) +{ + return do_helper_trt(env, len, array, trans, 1, ra); +} + uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array, uint64_t trans) { return do_helper_trt(env, len, array, trans, 1, GETPC()); } +static uint32_t do_helper_trt_bkwd(CPUS390XState *env, uint32_t len, + uint64_t array, uint64_t trans, + uintptr_t ra) +{ + return do_helper_trt(env, len, array, trans, -1, ra); +} + uint32_t HELPER(trtr)(CPUS390XState *env, uint32_t len, uint64_t array, uint64_t trans) { @@ -1442,7 +1456,7 @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1, } /* Sanity check the alignments. */ - if (extract32(a1, 0, 4 << fc) || extract32(a2, 0, 1 << sc)) { + if (extract32(a1, 0, fc + 2) || extract32(a2, 0, sc)) { goto spec_exception; } @@ -2193,12 +2207,14 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr) typedef uint32_t (*dx_helper)(CPUS390XState *, uint32_t, uint64_t, uint64_t, uintptr_t); static const dx_helper dx[16] = { + [0x0] = do_helper_trt_bkwd, [0x2] = do_helper_mvc, [0x4] = do_helper_nc, [0x5] = do_helper_clc, [0x6] = do_helper_oc, [0x7] = do_helper_xc, [0xc] = do_helper_tr, + [0xd] = do_helper_trt_fwd, }; dx_helper helper = dx[opc & 0xf]; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 57c03cbf58..7363aabf3a 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -84,14 +84,21 @@ static uint64_t inline_branch_hit[CC_OP_MAX]; static uint64_t inline_branch_miss[CC_OP_MAX]; #endif -static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc) +static void pc_to_link_info(TCGv_i64 out, DisasContext *s, uint64_t pc) { - if (!(s->base.tb->flags & FLAG_MASK_64)) { - if (s->base.tb->flags & FLAG_MASK_32) { - return pc | 0x80000000; + TCGv_i64 tmp; + + if (s->base.tb->flags & FLAG_MASK_32) { + if (s->base.tb->flags & FLAG_MASK_64) { + tcg_gen_movi_i64(out, pc); + return; } + pc |= 0x80000000; } - return pc; + assert(!(s->base.tb->flags & FLAG_MASK_64)); + tmp = tcg_const_i64(pc); + tcg_gen_deposit_i64(out, out, tmp, 0, 32); + tcg_temp_free_i64(tmp); } static TCGv_i64 psw_addr; @@ -835,7 +842,7 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) cond = TCG_COND_NE; c->u.s32.b = tcg_const_i32(1); break; - case 0x8 | 0x2: /* cc == 0 ||Â cc == 2 => (cc & 1) == 0 */ + case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */ cond = TCG_COND_EQ; c->g1 = false; c->u.s32.a = tcg_temp_new_i32(); @@ -854,7 +861,7 @@ static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask) cond = TCG_COND_NE; c->u.s32.b = tcg_const_i32(0); break; - case 0x4 | 0x1: /* cc == 1 ||Â cc == 3 => (cc & 1) != 0 */ + case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */ cond = TCG_COND_NE; c->g1 = false; c->u.s32.a = tcg_temp_new_i32(); @@ -1453,7 +1460,40 @@ static DisasJumpType op_ni(DisasContext *s, DisasOps *o) static DisasJumpType op_bas(DisasContext *s, DisasOps *o) { - tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->pc_tmp)); + pc_to_link_info(o->out, s, s->pc_tmp); + if (o->in2) { + tcg_gen_mov_i64(psw_addr, o->in2); + per_branch(s, false); + return DISAS_PC_UPDATED; + } else { + return DISAS_NEXT; + } +} + +static void save_link_info(DisasContext *s, DisasOps *o) +{ + TCGv_i64 t; + + if (s->base.tb->flags & (FLAG_MASK_32 | FLAG_MASK_64)) { + pc_to_link_info(o->out, s, s->pc_tmp); + return; + } + gen_op_calc_cc(s); + tcg_gen_andi_i64(o->out, o->out, 0xffffffff00000000ull); + tcg_gen_ori_i64(o->out, o->out, ((s->ilen / 2) << 30) | s->pc_tmp); + t = tcg_temp_new_i64(); + tcg_gen_shri_i64(t, psw_mask, 16); + tcg_gen_andi_i64(t, t, 0x0f000000); + tcg_gen_or_i64(o->out, o->out, t); + tcg_gen_extu_i32_i64(t, cc_op); + tcg_gen_shli_i64(t, t, 28); + tcg_gen_or_i64(o->out, o->out, t); + tcg_temp_free_i64(t); +} + +static DisasJumpType op_bal(DisasContext *s, DisasOps *o) +{ + save_link_info(s, o); if (o->in2) { tcg_gen_mov_i64(psw_addr, o->in2); per_branch(s, false); @@ -1465,7 +1505,7 @@ static DisasJumpType op_bas(DisasContext *s, DisasOps *o) static DisasJumpType op_basi(DisasContext *s, DisasOps *o) { - tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->pc_tmp)); + pc_to_link_info(o->out, s, s->pc_tmp); return help_goto_direct(s, s->base.pc_next + 2 * get_field(s->fields, i2)); } @@ -2018,9 +2058,9 @@ static DisasJumpType op_csst(DisasContext *s, DisasOps *o) TCGv_i32 t_r3 = tcg_const_i32(r3); if (tb_cflags(s->base.tb) & CF_PARALLEL) { - gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->in1, o->in2); + gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->addr1, o->in2); } else { - gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2); + gen_helper_csst(cc_op, cpu_env, t_r3, o->addr1, o->in2); } tcg_temp_free_i32(t_r3); @@ -2404,20 +2444,17 @@ static DisasJumpType op_insi(DisasContext *s, DisasOps *o) static DisasJumpType op_ipm(DisasContext *s, DisasOps *o) { - TCGv_i64 t1; + TCGv_i64 t1, t2; gen_op_calc_cc(s); - tcg_gen_andi_i64(o->out, o->out, ~0xff000000ull); - t1 = tcg_temp_new_i64(); - tcg_gen_shli_i64(t1, psw_mask, 20); - tcg_gen_shri_i64(t1, t1, 36); - tcg_gen_or_i64(o->out, o->out, t1); - - tcg_gen_extu_i32_i64(t1, cc_op); - tcg_gen_shli_i64(t1, t1, 28); - tcg_gen_or_i64(o->out, o->out, t1); + tcg_gen_extract_i64(t1, psw_mask, 40, 4); + t2 = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(t2, cc_op); + tcg_gen_deposit_i64(t1, t1, t2, 4, 60); + tcg_gen_deposit_i64(o->out, o->out, t1, 24, 8); tcg_temp_free_i64(t1); + tcg_temp_free_i64(t2); return DISAS_NEXT; } diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c index 673c10140f..4a1a0889c8 100644 --- a/tests/drive_del-test.c +++ b/tests/drive_del-test.c @@ -67,7 +67,6 @@ static void test_after_failed_device_add(void) { char driver[32]; QDict *response; - QDict *error; snprintf(driver, sizeof(driver), "virtio-blk-%s", qvirtio_get_dev_type()); @@ -83,9 +82,7 @@ static void test_after_failed_device_add(void) " 'drive': 'drive0'" "}}", driver); g_assert(response); - error = qdict_get_qdict(response, "error"); - g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, "GenericError"); - qobject_unref(response); + qmp_assert_error_class(response, "GenericError"); /* Delete the drive */ drive_del(); diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c index 013ca68581..c514187344 100644 --- a/tests/libqos/libqos.c +++ b/tests/libqos/libqos.c @@ -185,22 +185,12 @@ void mkimg(const char *file, const char *fmt, unsigned size_mb) cli = g_strdup_printf("%s create -f %s %s %uM", qemu_img_abs_path, fmt, file, size_mb); ret = g_spawn_command_line_sync(cli, &out, &out2, &rc, &err); - if (err) { + if (err || !g_spawn_check_exit_status(rc, &err)) { fprintf(stderr, "%s\n", err->message); g_error_free(err); } g_assert(ret && !err); - /* In glib 2.34, we have g_spawn_check_exit_status. in 2.12, we don't. - * glib 2.43.91 implementation assumes that any non-zero is an error for - * windows, but uses extra precautions for Linux. However, - * 0 is only possible if the program exited normally, so that should be - * sufficient for our purposes on all platforms, here. */ - if (rc) { - fprintf(stderr, "qemu-img returned status code %d\n", rc); - } - g_assert(!rc); - g_free(out); g_free(out2); g_free(cli); diff --git a/tests/libqtest.c b/tests/libqtest.c index d635c5bea0..2cd5736642 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -1194,3 +1194,14 @@ bool qmp_rsp_is_err(QDict *rsp) qobject_unref(rsp); return !!error; } + +void qmp_assert_error_class(QDict *rsp, const char *class) +{ + QDict *error = qdict_get_qdict(rsp, "error"); + + g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, class); + g_assert_nonnull(qdict_get_try_str(error, "desc")); + g_assert(!qdict_haskey(rsp, "return")); + + qobject_unref(rsp); +} diff --git a/tests/libqtest.h b/tests/libqtest.h index 36d5caecd4..ed88ff99d5 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -1004,4 +1004,13 @@ void qtest_qmp_device_del(const char *id); */ bool qmp_rsp_is_err(QDict *rsp); +/** + * qmp_assert_error_class: + * @rsp: QMP response to check for error + * @class: an error class + * + * Assert the response has the given error class and discard @rsp. + */ +void qmp_assert_error_class(QDict *rsp, const char *class); + #endif diff --git a/tests/machine-none-test.c b/tests/machine-none-test.c index 7e72466354..2b3b750500 100644 --- a/tests/machine-none-test.c +++ b/tests/machine-none-test.c @@ -44,7 +44,6 @@ static struct arch2cpu cpus_map[] = { { "or1k", "or1200" }, { "ppc", "604" }, { "ppc64", "power8e_v2.1" }, - { "ppcemb", "440epb" }, { "s390x", "qemu" }, { "sh4", "sh7750r" }, { "sh4eb", "sh7751r" }, diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 11aa4c8f8d..fb03163430 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -137,6 +137,8 @@ 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' } +{ 'command': 'cmd-success-response', 'data': {}, 'success-response': false } + # Returning a non-dictionary requires a name from the whitelist { 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 0da92455da..218ac7d556 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -156,6 +156,8 @@ object q_obj_user_def_cmd2-arg member ud1b: UserDefOne optional=True command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo gen=True success_response=True boxed=False oob=False preconfig=False +command cmd-success-response None -> None + gen=True success_response=False boxed=False oob=False preconfig=False object q_obj_guest-get-time-arg member a: int optional=False member b: int optional=True diff --git a/tests/qmp-cmd-test.c b/tests/qmp-cmd-test.c index c5b70df974..d12cac539c 100644 --- a/tests/qmp-cmd-test.c +++ b/tests/qmp-cmd-test.c @@ -197,6 +197,19 @@ static void add_query_tests(QmpSchema *schema) } } +static void test_object_add_without_props(void) +{ + QTestState *qts; + QDict *resp; + + qts = qtest_init(common_args); + resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" + " {'qom-type': 'memory-backend-ram', 'id': 'ram1' } }"); + g_assert_nonnull(resp); + qmp_assert_error_class(resp, "GenericError"); + qtest_quit(qts); +} + int main(int argc, char *argv[]) { QmpSchema schema; @@ -206,6 +219,11 @@ int main(int argc, char *argv[]) qmp_schema_init(&schema); add_query_tests(&schema); + + qtest_add_func("qmp/object-add-without-props", + test_object_add_without_props); + /* TODO: add coverage of generic object-add failure modes */ + ret = g_test_run(); qmp_schema_cleanup(&schema); diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 4ae2245484..b3472281ae 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -21,15 +21,6 @@ const char common_args[] = "-nodefaults -machine none"; -static const char *get_error_class(QDict *resp) -{ - QDict *error = qdict_get_qdict(resp, "error"); - const char *desc = qdict_get_try_str(error, "desc"); - - g_assert(desc); - return error ? qdict_get_try_str(error, "class") : NULL; -} - static void test_version(QObject *version) { Visitor *v; @@ -42,15 +33,12 @@ static void test_version(QObject *version) visit_free(v); } -static bool recovered(QTestState *qts) +static void assert_recovered(QTestState *qts) { QDict *resp; - bool ret; resp = qtest_qmp(qts, "{ 'execute': 'no-such-cmd' }"); - ret = !strcmp(get_error_class(resp), "CommandNotFound"); - qobject_unref(resp); - return ret; + qmp_assert_error_class(resp, "CommandNotFound"); } static void test_malformed(QTestState *qts) @@ -60,73 +48,61 @@ static void test_malformed(QTestState *qts) /* syntax error */ qtest_qmp_send_raw(qts, "{]\n"); resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); - g_assert(recovered(qts)); + qmp_assert_error_class(resp, "GenericError"); + assert_recovered(qts); /* lexical error: impossible byte outside string */ qtest_qmp_send_raw(qts, "{\xFF"); resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); - g_assert(recovered(qts)); + qmp_assert_error_class(resp, "GenericError"); + assert_recovered(qts); /* lexical error: funny control character outside string */ qtest_qmp_send_raw(qts, "{\x01"); resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); - g_assert(recovered(qts)); + qmp_assert_error_class(resp, "GenericError"); + assert_recovered(qts); /* lexical error: impossible byte in string */ qtest_qmp_send_raw(qts, "{'bad \xFF"); resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); - g_assert(recovered(qts)); + qmp_assert_error_class(resp, "GenericError"); + assert_recovered(qts); /* lexical error: control character in string */ qtest_qmp_send_raw(qts, "{'execute': 'nonexistent', 'id':'\n"); resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); - g_assert(recovered(qts)); + qmp_assert_error_class(resp, "GenericError"); + assert_recovered(qts); /* lexical error: interpolation */ qtest_qmp_send_raw(qts, "%%p\n"); /* two errors, one for "%", one for "p" */ resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); resp = qtest_qmp_receive(qts); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); - g_assert(recovered(qts)); + qmp_assert_error_class(resp, "GenericError"); + assert_recovered(qts); /* Not even a dictionary */ resp = qtest_qmp(qts, "null"); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); /* No "execute" key */ resp = qtest_qmp(qts, "{}"); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); /* "execute" isn't a string */ resp = qtest_qmp(qts, "{ 'execute': true }"); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); /* "arguments" isn't a dictionary */ resp = qtest_qmp(qts, "{ 'execute': 'no-such-cmd', 'arguments': [] }"); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); /* extra key */ resp = qtest_qmp(qts, "{ 'execute': 'no-such-cmd', 'extra': true }"); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); } static void test_qmp_protocol(void) @@ -148,8 +124,7 @@ static void test_qmp_protocol(void) /* Test valid command before handshake */ resp = qtest_qmp(qts, "{ 'execute': 'query-version' }"); - g_assert_cmpstr(get_error_class(resp), ==, "CommandNotFound"); - qobject_unref(resp); + qmp_assert_error_class(resp, "CommandNotFound"); /* Test malformed commands before handshake */ test_malformed(qts); @@ -162,8 +137,7 @@ static void test_qmp_protocol(void) /* Test repeated handshake */ resp = qtest_qmp(qts, "{ 'execute': 'qmp_capabilities' }"); - g_assert_cmpstr(get_error_class(resp), ==, "CommandNotFound"); - qobject_unref(resp); + qmp_assert_error_class(resp, "CommandNotFound"); /* Test valid command */ resp = qtest_qmp(qts, "{ 'execute': 'query-version' }"); @@ -182,9 +156,8 @@ static void test_qmp_protocol(void) /* Test command failure with 'id' */ resp = qtest_qmp(qts, "{ 'execute': 'human-monitor-command', 'id': 2 }"); - g_assert_cmpstr(get_error_class(resp), ==, "GenericError"); g_assert_cmpint(qdict_get_int(resp, "id"), ==, 2); - qobject_unref(resp); + qmp_assert_error_class(resp, "GenericError"); qtest_quit(qts); } diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target new file mode 100644 index 0000000000..151dc075aa --- /dev/null +++ b/tests/tcg/s390x/Makefile.target @@ -0,0 +1,8 @@ +VPATH+=$(SRC_PATH)/tests/tcg/s390x +CFLAGS+=-march=zEC12 -m64 +TESTS+=hello-s390x +TESTS+=csst +TESTS+=ipm +TESTS+=exrl-trt +TESTS+=exrl-trtr +TESTS+=pack diff --git a/tests/tcg/s390x/csst.c b/tests/tcg/s390x/csst.c new file mode 100644 index 0000000000..1dae9071fb --- /dev/null +++ b/tests/tcg/s390x/csst.c @@ -0,0 +1,43 @@ +#include <stdint.h> +#include <unistd.h> + +int main(void) +{ + uint64_t parmlist[] = { + 0xfedcba9876543210ull, + 0, + 0x7777777777777777ull, + 0, + }; + uint64_t op1 = 0x0123456789abcdefull; + uint64_t op2 = 0; + uint64_t op3 = op1; + uint64_t cc; + + asm volatile( + " lghi %%r0,%[flags]\n" + " la %%r1,%[parmlist]\n" + " csst %[op1],%[op2],%[op3]\n" + " ipm %[cc]\n" + : [op1] "+m" (op1), + [op2] "+m" (op2), + [op3] "+r" (op3), + [cc] "=r" (cc) + : [flags] "K" (0x0301), + [parmlist] "m" (parmlist) + : "r0", "r1", "cc", "memory"); + cc = (cc >> 28) & 3; + if (cc) { + write(1, "bad cc\n", 7); + return 1; + } + if (op1 != parmlist[0]) { + write(1, "bad op1\n", 8); + return 1; + } + if (op2 != parmlist[2]) { + write(1, "bad op2\n", 8); + return 1; + } + return 0; +} diff --git a/tests/tcg/s390x/exrl-trt.c b/tests/tcg/s390x/exrl-trt.c new file mode 100644 index 0000000000..3c5323aecb --- /dev/null +++ b/tests/tcg/s390x/exrl-trt.c @@ -0,0 +1,48 @@ +#include <stdint.h> +#include <unistd.h> + +int main(void) +{ + char op1[] = "hello"; + char op2[256]; + uint64_t r1 = 0xffffffffffffffffull; + uint64_t r2 = 0xffffffffffffffffull; + uint64_t cc; + int i; + + for (i = 0; i < 256; i++) { + if (i == 0) { + op2[i] = 0xaa; + } else { + op2[i] = 0; + } + } + asm volatile( + " j 2f\n" + "1: trt 0(1,%[op1]),0(%[op2])\n" + "2: exrl %[op1_len],1b\n" + " lgr %[r1],%%r1\n" + " lgr %[r2],%%r2\n" + " ipm %[cc]\n" + : [r1] "+r" (r1), + [r2] "+r" (r2), + [cc] "=r" (cc) + : [op1] "r" (&op1), + [op1_len] "r" (5), + [op2] "r" (&op2) + : "r1", "r2", "cc"); + cc = (cc >> 28) & 3; + if (cc != 2) { + write(1, "bad cc\n", 7); + return 1; + } + if ((char *)r1 != &op1[5]) { + write(1, "bad r1\n", 7); + return 1; + } + if (r2 != 0xffffffffffffffaaull) { + write(1, "bad r2\n", 7); + return 1; + } + return 0; +} diff --git a/tests/tcg/s390x/exrl-trtr.c b/tests/tcg/s390x/exrl-trtr.c new file mode 100644 index 0000000000..c33153ad7e --- /dev/null +++ b/tests/tcg/s390x/exrl-trtr.c @@ -0,0 +1,48 @@ +#include <stdint.h> +#include <unistd.h> + +int main(void) +{ + char op1[] = {0, 1, 2, 3}; + char op2[256]; + uint64_t r1 = 0xffffffffffffffffull; + uint64_t r2 = 0xffffffffffffffffull; + uint64_t cc; + int i; + + for (i = 0; i < 256; i++) { + if (i == 1) { + op2[i] = 0xbb; + } else { + op2[i] = 0; + } + } + asm volatile( + " j 2f\n" + "1: trtr 3(1,%[op1]),0(%[op2])\n" + "2: exrl %[op1_len],1b\n" + " lgr %[r1],%%r1\n" + " lgr %[r2],%%r2\n" + " ipm %[cc]\n" + : [r1] "+r" (r1), + [r2] "+r" (r2), + [cc] "=r" (cc) + : [op1] "r" (&op1), + [op1_len] "r" (3), + [op2] "r" (&op2) + : "r1", "r2", "cc"); + cc = (cc >> 28) & 3; + if (cc != 1) { + write(1, "bad cc\n", 7); + return 1; + } + if ((char *)r1 != &op1[1]) { + write(1, "bad r1\n", 7); + return 1; + } + if (r2 != 0xffffffffffffffbbull) { + write(1, "bad r2\n", 7); + return 1; + } + return 0; +} diff --git a/tests/tcg/s390x/hello-s390x.c b/tests/tcg/s390x/hello-s390x.c new file mode 100644 index 0000000000..3dc0a05f2b --- /dev/null +++ b/tests/tcg/s390x/hello-s390x.c @@ -0,0 +1,7 @@ +#include <unistd.h> + +int main(void) +{ + write(1, "hello\n", 6); + return 0; +} diff --git a/tests/tcg/s390x/ipm.c b/tests/tcg/s390x/ipm.c new file mode 100644 index 0000000000..742f3a18c5 --- /dev/null +++ b/tests/tcg/s390x/ipm.c @@ -0,0 +1,22 @@ +#include <stdint.h> +#include <unistd.h> + +int main(void) +{ + uint32_t op1 = 0x55555555; + uint32_t op2 = 0x44444444; + uint64_t cc = 0xffffffffffffffffull; + + asm volatile( + " clc 0(4,%[op1]),0(%[op2])\n" + " ipm %[cc]\n" + : [cc] "+r" (cc) + : [op1] "r" (&op1), + [op2] "r" (&op2) + : "cc"); + if (cc != 0xffffffff20ffffffull) { + write(1, "bad cc\n", 7); + return 1; + } + return 0; +} diff --git a/tests/tcg/s390x/pack.c b/tests/tcg/s390x/pack.c new file mode 100644 index 0000000000..4be36f29a7 --- /dev/null +++ b/tests/tcg/s390x/pack.c @@ -0,0 +1,21 @@ +#include <unistd.h> + +int main(void) +{ + char data[] = {0xaa, 0xaa, 0xf1, 0xf2, 0xf3, 0xc4, 0xaa, 0xaa}; + char exp[] = {0xaa, 0xaa, 0x00, 0x01, 0x23, 0x4c, 0xaa, 0xaa}; + int i; + + asm volatile( + " pack 2(4,%[data]),2(4,%[data])\n" + : + : [data] "r" (&data[0]) + : "memory"); + for (i = 0; i < 8; i++) { + if (data[i] != exp[i]) { + write(1, "bad data\n", 9); + return 1; + } + } + return 0; +} diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c index 17bb8508ae..89ac15e88a 100644 --- a/tests/test-bdrv-drain.c +++ b/tests/test-bdrv-drain.c @@ -752,14 +752,9 @@ typedef struct TestBlockJob { bool should_complete; } TestBlockJob; -static void test_job_completed(Job *job, void *opaque) +static int coroutine_fn test_job_run(Job *job, Error **errp) { - job_completed(job, 0, NULL); -} - -static void coroutine_fn test_job_start(void *opaque) -{ - TestBlockJob *s = opaque; + TestBlockJob *s = container_of(job, TestBlockJob, common.job); job_transition_to_ready(&s->common.job); while (!s->should_complete) { @@ -770,7 +765,7 @@ static void coroutine_fn test_job_start(void *opaque) job_pause_point(&s->common.job); } - job_defer_to_main_loop(&s->common.job, test_job_completed, NULL); + return 0; } static void test_job_complete(Job *job, Error **errp) @@ -785,7 +780,7 @@ BlockJobDriver test_job_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = test_job_start, + .run = test_job_run, .complete = test_job_complete, }, }; @@ -948,6 +943,7 @@ static void coroutine_fn test_co_delete_by_drain(void *opaque) } dbdd->done = true; + g_free(buffer); } /** diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c index 58d9b87fb2..ef29f35e44 100644 --- a/tests/test-blockjob-txn.c +++ b/tests/test-blockjob-txn.c @@ -24,39 +24,31 @@ typedef struct { int *result; } TestBlockJob; -static void test_block_job_complete(Job *job, void *opaque) +static void test_block_job_exit(Job *job) { BlockJob *bjob = container_of(job, BlockJob, job); BlockDriverState *bs = blk_bs(bjob->blk); - int rc = (intptr_t)opaque; - if (job_is_cancelled(job)) { - rc = -ECANCELED; - } - - job_completed(job, rc, NULL); bdrv_unref(bs); } -static void coroutine_fn test_block_job_run(void *opaque) +static int coroutine_fn test_block_job_run(Job *job, Error **errp) { - TestBlockJob *s = opaque; - BlockJob *job = &s->common; + TestBlockJob *s = container_of(job, TestBlockJob, common.job); while (s->iterations--) { if (s->use_timer) { - job_sleep_ns(&job->job, 0); + job_sleep_ns(job, 0); } else { - job_yield(&job->job); + job_yield(job); } - if (job_is_cancelled(&job->job)) { + if (job_is_cancelled(job)) { break; } } - job_defer_to_main_loop(&job->job, test_block_job_complete, - (void *)(intptr_t)s->rc); + return s->rc; } typedef struct { @@ -80,7 +72,8 @@ static const BlockJobDriver test_block_job_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = test_block_job_run, + .run = test_block_job_run, + .exit = test_block_job_exit, }, }; diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c index cb42f06e61..ad4a65bc78 100644 --- a/tests/test-blockjob.c +++ b/tests/test-blockjob.c @@ -163,11 +163,10 @@ typedef struct CancelJob { bool completed; } CancelJob; -static void cancel_job_completed(Job *job, void *opaque) +static void cancel_job_exit(Job *job) { - CancelJob *s = opaque; + CancelJob *s = container_of(job, CancelJob, common.job); s->completed = true; - job_completed(job, 0, NULL); } static void cancel_job_complete(Job *job, Error **errp) @@ -176,13 +175,13 @@ static void cancel_job_complete(Job *job, Error **errp) s->should_complete = true; } -static void coroutine_fn cancel_job_start(void *opaque) +static int coroutine_fn cancel_job_run(Job *job, Error **errp) { - CancelJob *s = opaque; + CancelJob *s = container_of(job, CancelJob, common.job); while (!s->should_complete) { if (job_is_cancelled(&s->common.job)) { - goto defer; + return 0; } if (!job_is_ready(&s->common.job) && s->should_converge) { @@ -192,8 +191,7 @@ static void coroutine_fn cancel_job_start(void *opaque) job_sleep_ns(&s->common.job, 100000); } - defer: - job_defer_to_main_loop(&s->common.job, cancel_job_completed, s); + return 0; } static const BlockJobDriver test_cancel_driver = { @@ -202,7 +200,8 @@ static const BlockJobDriver test_cancel_driver = { .free = block_job_free, .user_resume = block_job_user_resume, .drain = block_job_drain, - .start = cancel_job_start, + .run = cancel_job_run, + .exit = cancel_job_exit, .complete = cancel_job_complete, }, }; diff --git a/tests/test-qga.c b/tests/test-qga.c index f69cdf6c03..3d6377436a 100644 --- a/tests/test-qga.c +++ b/tests/test-qga.c @@ -244,17 +244,12 @@ static void test_qga_invalid_id(gconstpointer fix) static void test_qga_invalid_oob(gconstpointer fix) { const TestFixture *fixture = fix; - QDict *ret, *error; - const char *class; + QDict *ret; ret = qmp_fd(fixture->fd, "{'exec-oob': 'guest-ping'}"); g_assert_nonnull(ret); - error = qdict_get_qdict(ret, "error"); - class = qdict_get_try_str(error, "class"); - g_assert_cmpstr(class, ==, "GenericError"); - - qobject_unref(ret); + qmp_assert_error_class(ret, "GenericError"); } static void test_qga_invalid_args(gconstpointer fix) diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index ab414fa0c9..4ab2b6e5ce 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -32,6 +32,10 @@ void qmp_test_flags_command(Error **errp) { } +void qmp_cmd_success_response(Error **errp) +{ +} + Empty2 *qmp_user_def_cmd0(Error **errp) { return g_new0(Empty2, 1); @@ -153,6 +157,17 @@ static void test_dispatch_cmd_failure(void) qobject_unref(req); } +static void test_dispatch_cmd_success_response(void) +{ + QDict *req = qdict_new(); + QDict *resp; + + qdict_put_str(req, "execute", "cmd-success-response"); + resp = qmp_dispatch(&qmp_commands, QOBJECT(req), false); + g_assert_null(resp); + qobject_unref(req); +} + static QObject *test_qmp_dispatch(QDict *req) { QDict *resp; @@ -289,6 +304,8 @@ int main(int argc, char **argv) g_test_add_func("/qmp/dispatch_cmd", test_dispatch_cmd); g_test_add_func("/qmp/dispatch_cmd_failure", test_dispatch_cmd_failure); g_test_add_func("/qmp/dispatch_cmd_io", test_dispatch_cmd_io); + g_test_add_func("/qmp/dispatch_cmd_success_response", + test_dispatch_cmd_success_response); g_test_add_func("/qmp/dealloc_types", test_dealloc_types); g_test_add_func("/qmp/dealloc_partial", test_dealloc_partial); diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c index 8677094ad1..9cddd72adb 100644 --- a/tests/test-qmp-event.c +++ b/tests/test-qmp-event.c @@ -95,7 +95,7 @@ static bool qdict_cmp_simple(QDict *a, QDict *b) /* This function is hooked as final emit function, which can verify the correctness. */ -static void event_test_emit(test_QAPIEvent event, QDict *d, Error **errp) +static void event_test_emit(test_QAPIEvent event, QDict *d) { QDict *t; int64_t s, ms; @@ -156,7 +156,7 @@ static void test_event_a(TestEventData *data, QDict *d; d = data->expect; qdict_put_str(d, "event", "EVENT_A"); - qapi_event_send_event_a(&error_abort); + qapi_event_send_event_a(); } static void test_event_b(TestEventData *data, @@ -165,7 +165,7 @@ static void test_event_b(TestEventData *data, QDict *d; d = data->expect; qdict_put_str(d, "event", "EVENT_B"); - qapi_event_send_event_b(&error_abort); + qapi_event_send_event_b(); } static void test_event_c(TestEventData *data, @@ -191,7 +191,7 @@ static void test_event_c(TestEventData *data, qdict_put_str(d, "event", "EVENT_C"); qdict_put(d, "data", d_data); - qapi_event_send_event_c(true, 1, true, &b, "test2", &error_abort); + qapi_event_send_event_c(true, 1, true, &b, "test2"); g_free(b.string); } @@ -233,8 +233,7 @@ static void test_event_d(TestEventData *data, qdict_put_str(d, "event", "EVENT_D"); qdict_put(d, "data", d_data); - qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3, - &error_abort); + qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3); g_free(struct1.string); g_free(a.string); diff --git a/trace-events b/trace-events index c445f54773..4fd2cb4b97 100644 --- a/trace-events +++ b/trace-events @@ -107,7 +107,7 @@ gdbstub_err_checksum_incorrect(uint8_t expected, uint8_t got) "got command packe # job.c job_state_transition(void *job, int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)" job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)" -job_completed(void *job, int ret, int jret) "job %p ret %d corrected ret %d" +job_completed(void *job, int ret) "job %p ret %d" # job-qmp.c qmp_job_cancel(void *job) "job %p" diff --git a/ui/spice-core.c b/ui/spice-core.c index f8c0878529..a4fbbc3898 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -218,8 +218,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info) switch (event) { case SPICE_CHANNEL_EVENT_CONNECTED: qapi_event_send_spice_connected(qapi_SpiceServerInfo_base(server), - qapi_SpiceChannel_base(client), - &error_abort); + qapi_SpiceChannel_base(client)); break; case SPICE_CHANNEL_EVENT_INITIALIZED: if (auth) { @@ -228,13 +227,12 @@ static void channel_event(int event, SpiceChannelEventInfo *info) } add_channel_info(client, info); channel_list_add(info); - qapi_event_send_spice_initialized(server, client, &error_abort); + qapi_event_send_spice_initialized(server, client); break; case SPICE_CHANNEL_EVENT_DISCONNECTED: channel_list_del(info); qapi_event_send_spice_disconnected(qapi_SpiceServerInfo_base(server), - qapi_SpiceChannel_base(client), - &error_abort); + qapi_SpiceChannel_base(client)); break; default: break; @@ -287,7 +285,7 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin) static void migrate_end_complete_cb(SpiceMigrateInstance *sin) { - qapi_event_send_spice_migrate_completed(&error_abort); + qapi_event_send_spice_migrate_completed(); spice_migration_completed = true; } @@ -296,14 +296,13 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event) switch (event) { case QAPI_EVENT_VNC_CONNECTED: - qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info), - &error_abort); + qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info)); break; case QAPI_EVENT_VNC_INITIALIZED: - qapi_event_send_vnc_initialized(si, vs->info, &error_abort); + qapi_event_send_vnc_initialized(si, vs->info); break; case QAPI_EVENT_VNC_DISCONNECTED: - qapi_event_send_vnc_disconnected(si, vs->info, &error_abort); + qapi_event_send_vnc_disconnected(si, vs->info); break; default: break; @@ -823,44 +823,33 @@ int qemu_timedate_diff(struct tm *tm) return seconds - qemu_time(); } -static void configure_rtc_date_offset(const char *startdate, int legacy) +static void configure_rtc_date_offset(const char *startdate) { time_t rtc_start_date; struct tm tm; - if (!strcmp(startdate, "now") && legacy) { - rtc_date_offset = -1; + if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) { + /* OK */ + } else if (sscanf(startdate, "%d-%d-%d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday) == 3) { + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; } else { - if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday, - &tm.tm_hour, - &tm.tm_min, - &tm.tm_sec) == 6) { - /* OK */ - } else if (sscanf(startdate, "%d-%d-%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday) == 3) { - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - } else { - goto date_fail; - } - tm.tm_year -= 1900; - tm.tm_mon--; - rtc_start_date = mktimegm(&tm); - if (rtc_start_date == -1) { - date_fail: - error_report("invalid date format"); - error_printf("valid formats: " - "'2006-06-17T16:01:21' or '2006-06-17'\n"); - exit(1); - } - rtc_date_offset = qemu_time() - rtc_start_date; + goto date_fail; + } + tm.tm_year -= 1900; + tm.tm_mon--; + rtc_start_date = mktimegm(&tm); + if (rtc_start_date == -1) { + date_fail: + error_report("invalid date format"); + error_printf("valid formats: " + "'2006-06-17T16:01:21' or '2006-06-17'\n"); + exit(1); } + rtc_date_offset = qemu_time() - rtc_start_date; } static void configure_rtc(QemuOpts *opts) @@ -878,7 +867,7 @@ static void configure_rtc(QemuOpts *opts) "-rtc base=localtime"); replay_add_blocker(blocker); } else { - configure_rtc_date_offset(value, 0); + configure_rtc_date_offset(value); } } value = qemu_opt_get(opts, "clock"); @@ -1647,8 +1636,7 @@ void qemu_system_reset(ShutdownCause reason) qemu_devices_reset(); } if (reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) { - qapi_event_send_reset(shutdown_caused_by_guest(reason), - &error_abort); + qapi_event_send_reset(shutdown_caused_by_guest(reason)); } cpu_synchronize_all_post_reset(); } @@ -1661,11 +1649,11 @@ void qemu_system_guest_panicked(GuestPanicInformation *info) current_cpu->crash_occurred = true; } qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, - !!info, info, &error_abort); + !!info, info); vm_stop(RUN_STATE_GUEST_PANICKED); if (!no_shutdown) { qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF, - !!info, info, &error_abort); + !!info, info); qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC); } @@ -1706,7 +1694,7 @@ static void qemu_system_suspend(void) pause_all_vcpus(); notifier_list_notify(&suspend_notifiers, NULL); runstate_set(RUN_STATE_SUSPENDED); - qapi_event_send_suspend(&error_abort); + qapi_event_send_suspend(); } void qemu_system_suspend_request(void) @@ -1776,7 +1764,7 @@ void qemu_system_shutdown_request(ShutdownCause reason) static void qemu_system_powerdown(void) { - qapi_event_send_powerdown(&error_abort); + qapi_event_send_powerdown(); notifier_list_notify(&powerdown_notifiers, NULL); } @@ -1819,8 +1807,7 @@ static bool main_loop_should_exit(void) request = qemu_shutdown_requested(); if (request) { qemu_kill_report(); - qapi_event_send_shutdown(shutdown_caused_by_guest(request), - &error_abort); + qapi_event_send_shutdown(shutdown_caused_by_guest(request)); if (no_shutdown) { vm_stop(RUN_STATE_SHUTDOWN); } else { @@ -1843,7 +1830,7 @@ static bool main_loop_should_exit(void) notifier_list_notify(&wakeup_notifiers, &wakeup_reason); wakeup_reason = QEMU_WAKEUP_REASON_NONE; resume_all_vcpus(); - qapi_event_send_wakeup(&error_abort); + qapi_event_send_wakeup(); } if (qemu_powerdown_requested()) { qemu_system_powerdown(); @@ -2127,36 +2114,6 @@ static void parse_display(const char *p) } } -static int balloon_parse(const char *arg) -{ - QemuOpts *opts; - - warn_report("This option is deprecated. " - "Use '--device virtio-balloon' to enable the balloon device."); - - if (strcmp(arg, "none") == 0) { - return 0; - } - - if (!strncmp(arg, "virtio", 6)) { - if (arg[6] == ',') { - /* have params -> parse them */ - opts = qemu_opts_parse_noisily(qemu_find_opts("device"), arg + 7, - false); - if (!opts) - return -1; - } else { - /* create empty opts */ - opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, - &error_abort); - } - qemu_opt_set(opts, "driver", "virtio-balloon", &error_abort); - return 0; - } - - return -1; -} - char *qemu_find_file(int type, const char *name) { int i; @@ -3029,7 +2986,6 @@ int main(int argc, char **argv, char **envp) popt = lookup_opt(argc, argv, &optarg, &optind); switch (popt->index) { - case QEMU_OPTION_nodefconfig: case QEMU_OPTION_nouserconfig: userconfig = false; break; @@ -3210,24 +3166,6 @@ int main(int argc, char **argv, char **envp) } break; #endif -#ifdef CONFIG_SLIRP - case QEMU_OPTION_tftp: - error_report("The -tftp option is deprecated. " - "Please use '-netdev user,tftp=...' instead."); - legacy_tftp_prefix = optarg; - break; - case QEMU_OPTION_bootp: - error_report("The -bootp option is deprecated. " - "Please use '-netdev user,bootfile=...' instead."); - legacy_bootp_filename = optarg; - break; - case QEMU_OPTION_redir: - error_report("The -redir option is deprecated. " - "Please use '-netdev user,hostfwd=...' instead."); - if (net_slirp_redir(optarg) < 0) - exit(1); - break; -#endif case QEMU_OPTION_bt: add_device_config(DEV_BT, optarg); break; @@ -3300,11 +3238,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_k: keyboard_layout = optarg; break; - case QEMU_OPTION_localtime: - rtc_utc = 0; - warn_report("This option is deprecated, " - "use '-rtc base=localtime' instead."); - break; case QEMU_OPTION_vga: vga_model = optarg; default_vga = 0; @@ -3557,18 +3490,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_win2k_hack: win2k_install_hack = 1; break; - case QEMU_OPTION_rtc_td_hack: { - static GlobalProperty slew_lost_ticks = { - .driver = "mc146818rtc", - .property = "lost_tick_policy", - .value = "slew", - }; - - qdev_prop_register_global(&slew_lost_ticks); - warn_report("This option is deprecated, " - "use '-rtc driftfix=slew' instead."); - break; - } case QEMU_OPTION_acpitable: opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"), optarg, true); @@ -3660,12 +3581,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_no_hpet: no_hpet = 1; break; - case QEMU_OPTION_balloon: - if (balloon_parse(optarg) < 0) { - error_report("unknown -balloon argument %s", optarg); - exit(1); - } - break; case QEMU_OPTION_no_reboot: no_reboot = 1; break; @@ -3760,10 +3675,6 @@ int main(int argc, char **argv, char **envp) */ warn_report("This option is ignored and will be removed soon"); break; - case QEMU_OPTION_startdate: - warn_report("This option is deprecated, use '-rtc base=' instead."); - configure_rtc_date_offset(optarg, 1); - break; case QEMU_OPTION_rtc: opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg, false); @@ -3963,7 +3874,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_enable_sync_profile: qsp_enable(); break; - case QEMU_OPTION_nodefconfig: case QEMU_OPTION_nouserconfig: /* Nothing to be parsed here. Especially, do not error out below. */ break; |