diff options
315 files changed, 2538 insertions, 1839 deletions
@@ -50,7 +50,7 @@ endif include $(SRC_PATH)/rules.mak -GENERATED_HEADERS = config-host.h qemu-options.def +GENERATED_HEADERS = qemu-version.h config-host.h qemu-options.def GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c GENERATED_HEADERS += qmp-introspect.h @@ -82,7 +82,7 @@ Makefile: ; configure: ; .PHONY: all clean cscope distclean dvi html info install install-doc \ - pdf recurse-all speed test dist msi + pdf recurse-all speed test dist msi FORCE $(call set-vpath, $(SRC_PATH)) @@ -117,7 +117,7 @@ endif -include $(SUBDIR_DEVICES_MAK_DEP) -%/config-devices.mak: default-configs/%.mak +%/config-devices.mak: default-configs/%.mak $(SRC_PATH)/scripts/make_device_config.sh $(call quiet-command, \ $(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $< $*-config-devices.mak.d $@ > $@.tmp, " GEN $@.tmp") $(call quiet-command, if test -f $@; then \ @@ -162,14 +162,34 @@ dummy := $(call unnest-vars,, \ common-obj-m) ifneq ($(wildcard config-host.mak),) -include $(SRC_PATH)/tests/Makefile +include $(SRC_PATH)/tests/Makefile.include endif all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules +qemu-version.h: FORCE + $(call quiet-command, \ + (cd $(SRC_PATH); \ + printf '#define QEMU_PKGVERSION '; \ + if test -n "$(PKGVERSION)"; then \ + printf '"$(PKGVERSION)"\n'; \ + else \ + if test -d .git; then \ + printf '" ('; \ + git describe --match 'v*' 2>/dev/null | tr -d '\n'; \ + if ! git diff-index --quiet HEAD &>/dev/null; then \ + printf -- '-dirty'; \ + fi; \ + printf ')"\n'; \ + else \ + printf '""\n'; \ + fi; \ + fi) > $@.tmp) + $(call quiet-command, cmp --quiet $@ $@.tmp || mv $@.tmp $@) + config-host.h: config-host.h-timestamp config-host.h-timestamp: config-host.mak -qemu-options.def: $(SRC_PATH)/qemu-options.hx +qemu-options.def: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) @@ -241,7 +261,7 @@ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o libqemuutil.a libqemustub.a fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o libqemuutil.a libqemustub.a fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap -qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx +qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") qemu-ga$(EXESUF): LIBS = $(LIBS_QGA) @@ -524,19 +544,19 @@ TEXIFLAG=$(if $(V),,--quiet) %.pdf: %.texi $(call quiet-command,texi2pdf $(TEXIFLAG) -I . $<," GEN $@") -qemu-options.texi: $(SRC_PATH)/qemu-options.hx +qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") -qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx +qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") -qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx +qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") -qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx +qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -q < $< > $@," GEN $@") -qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx +qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi diff --git a/Makefile.target b/Makefile.target index 5b80dd7fc9..495b474931 100644 --- a/Makefile.target +++ b/Makefile.target @@ -206,13 +206,13 @@ endif gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@") -hmp-commands.h: $(SRC_PATH)/hmp-commands.hx +hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") -hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx +hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") -qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx +qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") clean: @@ -1018,7 +1018,7 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file, assert(bdrv_opt_mem_align(bs) != 0); assert(bdrv_min_mem_align(bs) != 0); - assert((bs->request_alignment != 0) || bdrv_is_sg(bs)); + assert(is_power_of_2(bs->request_alignment) || bdrv_is_sg(bs)); qemu_opts_del(opts); return 0; diff --git a/block/blkreplay.c b/block/blkreplay.c index 42f1813af1..525c2d54e0 100755 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -103,11 +103,11 @@ static int coroutine_fn blkreplay_co_writev(BlockDriverState *bs, return ret; } -static int coroutine_fn blkreplay_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { uint64_t reqid = request_id++; - int ret = bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags); + int ret = bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags); block_request_create(reqid, bs, qemu_coroutine_self()); qemu_coroutine_yield(); @@ -147,7 +147,7 @@ static BlockDriver bdrv_blkreplay = { .bdrv_co_readv = blkreplay_co_readv, .bdrv_co_writev = blkreplay_co_writev, - .bdrv_co_write_zeroes = blkreplay_co_write_zeroes, + .bdrv_co_pwrite_zeroes = blkreplay_co_pwrite_zeroes, .bdrv_co_discard = blkreplay_co_discard, .bdrv_co_flush = blkreplay_co_flush, }; diff --git a/block/dmg.c b/block/dmg.c index 1ea5f22d82..06eb5138f3 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -32,7 +32,6 @@ #ifdef CONFIG_BZIP2 #include <bzlib.h> #endif -#include <glib.h> enum { /* Limit chunk sizes to prevent unreasonable amounts of memory being used diff --git a/block/gluster.c b/block/gluster.c index a8aaacf645..d361d8e847 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -454,14 +454,12 @@ static void qemu_gluster_reopen_abort(BDRVReopenState *state) } #ifdef CONFIG_GLUSTERFS_ZEROFILL -static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static coroutine_fn int qemu_gluster_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int size, BdrvRequestFlags flags) { int ret; GlusterAIOCB acb; BDRVGlusterState *s = bs->opaque; - off_t size = nb_sectors * BDRV_SECTOR_SIZE; - off_t offset = sector_num * BDRV_SECTOR_SIZE; acb.size = size; acb.ret = 0; @@ -769,7 +767,7 @@ static BlockDriver bdrv_gluster = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; @@ -796,7 +794,7 @@ static BlockDriver bdrv_gluster_tcp = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; @@ -823,7 +821,7 @@ static BlockDriver bdrv_gluster_unix = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; @@ -850,7 +848,7 @@ static BlockDriver bdrv_gluster_rdma = { .bdrv_co_discard = qemu_gluster_co_discard, #endif #ifdef CONFIG_GLUSTERFS_ZEROFILL - .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qemu_gluster_co_pwrite_zeroes, #endif .create_opts = &qemu_gluster_create_opts, }; diff --git a/block/io.c b/block/io.c index 2d832aa532..fb99a7151c 100644 --- a/block/io.c +++ b/block/io.c @@ -42,8 +42,8 @@ static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, void *opaque, bool is_write); static void coroutine_fn bdrv_co_do_rw(void *opaque); -static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); +static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags); static void bdrv_parent_drained_begin(BlockDriverState *bs) { @@ -620,18 +620,25 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num, return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true, 0); } -int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags) { - return bdrv_rw_co(bs, sector_num, NULL, nb_sectors, true, - BDRV_REQ_ZERO_WRITE | flags); + QEMUIOVector qiov; + struct iovec iov = { + .iov_base = NULL, + .iov_len = count, + }; + + qemu_iovec_init_external(&qiov, &iov, 1); + return bdrv_prwv_co(bs, offset, &qiov, true, + BDRV_REQ_ZERO_WRITE | flags); } /* - * Completely zero out a block device with the help of bdrv_write_zeroes. + * Completely zero out a block device with the help of bdrv_pwrite_zeroes. * The operation is sped up by checking the block status and only writing * zeroes to the device if they currently do not return zeroes. Optional - * flags are passed through to bdrv_write_zeroes (e.g. BDRV_REQ_MAY_UNMAP, + * flags are passed through to bdrv_pwrite_zeroes (e.g. BDRV_REQ_MAY_UNMAP, * BDRV_REQ_FUA). * * Returns < 0 on error, 0 on success. For error codes see bdrv_write(). @@ -662,7 +669,8 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) sector_num += n; continue; } - ret = bdrv_write_zeroes(bs, sector_num, n, flags); + ret = bdrv_pwrite_zeroes(bs, sector_num << BDRV_SECTOR_BITS, + n << BDRV_SECTOR_BITS, flags); if (ret < 0) { error_report("error writing zeroes at sector %" PRId64 ": %s", sector_num, strerror(-ret)); @@ -808,7 +816,9 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, int ret; if (drv->bdrv_co_pwritev) { - ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags); + ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, + flags & bs->supported_write_flags); + flags &= ~bs->supported_write_flags; goto emulate_flags; } @@ -893,10 +903,12 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs, goto err; } - if (drv->bdrv_co_write_zeroes && + if (drv->bdrv_co_pwrite_zeroes && buffer_is_zero(bounce_buffer, iov.iov_len)) { - ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num, - cluster_nb_sectors, 0); + ret = bdrv_co_do_pwrite_zeroes(bs, + cluster_sector_num * BDRV_SECTOR_SIZE, + cluster_nb_sectors * BDRV_SECTOR_SIZE, + 0); } else { /* This does not change the data on the disk, it is not necessary * to flush even in cache=writethrough mode. @@ -1110,36 +1122,40 @@ int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, #define MAX_WRITE_ZEROES_BOUNCE_BUFFER 32768 -static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { BlockDriver *drv = bs->drv; QEMUIOVector qiov; struct iovec iov = {0}; int ret = 0; bool need_flush = false; + int head = 0; + int tail = 0; - int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_write_zeroes, - BDRV_REQUEST_MAX_SECTORS); + int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX); + int alignment = MAX(bs->bl.pwrite_zeroes_alignment ?: 1, + bs->request_alignment); - while (nb_sectors > 0 && !ret) { - int num = nb_sectors; + assert(is_power_of_2(alignment)); + head = offset & (alignment - 1); + tail = (offset + count) & (alignment - 1); + max_write_zeroes &= ~(alignment - 1); + + while (count > 0 && !ret) { + int num = count; /* Align request. Block drivers can expect the "bulk" of the request - * to be aligned. + * to be aligned, and that unaligned requests do not cross cluster + * boundaries. */ - if (bs->bl.write_zeroes_alignment - && num > bs->bl.write_zeroes_alignment) { - if (sector_num % bs->bl.write_zeroes_alignment != 0) { - /* Make a small request up to the first aligned sector. */ - num = bs->bl.write_zeroes_alignment; - num -= sector_num % bs->bl.write_zeroes_alignment; - } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) { - /* Shorten the request to the last aligned sector. num cannot - * underflow because num > bs->bl.write_zeroes_alignment. - */ - num -= (sector_num + num) % bs->bl.write_zeroes_alignment; - } + if (head) { + /* Make a small request up to the first aligned sector. */ + num = MIN(count, alignment - head); + head = 0; + } else if (tail && num > alignment) { + /* Shorten the request to the last aligned sector. */ + num -= tail; } /* limit request size */ @@ -1149,9 +1165,9 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, ret = -ENOTSUP; /* First try the efficient write zeroes operation */ - if (drv->bdrv_co_write_zeroes) { - ret = drv->bdrv_co_write_zeroes(bs, sector_num, num, - flags & bs->supported_zero_flags); + if (drv->bdrv_co_pwrite_zeroes) { + ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num, + flags & bs->supported_zero_flags); if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) && !(bs->supported_zero_flags & BDRV_REQ_FUA)) { need_flush = true; @@ -1173,33 +1189,31 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, write_flags &= ~BDRV_REQ_FUA; need_flush = true; } - num = MIN(num, max_xfer_len); - iov.iov_len = num * BDRV_SECTOR_SIZE; + num = MIN(num, max_xfer_len << BDRV_SECTOR_BITS); + iov.iov_len = num; if (iov.iov_base == NULL) { - iov.iov_base = qemu_try_blockalign(bs, num * BDRV_SECTOR_SIZE); + iov.iov_base = qemu_try_blockalign(bs, num); if (iov.iov_base == NULL) { ret = -ENOMEM; goto fail; } - memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE); + memset(iov.iov_base, 0, num); } qemu_iovec_init_external(&qiov, &iov, 1); - ret = bdrv_driver_pwritev(bs, sector_num * BDRV_SECTOR_SIZE, - num * BDRV_SECTOR_SIZE, &qiov, - write_flags); + ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags); /* Keep bounce buffer around if it is big enough for all * all future requests. */ - if (num < max_xfer_len) { + if (num < max_xfer_len << BDRV_SECTOR_BITS) { qemu_vfree(iov.iov_base); iov.iov_base = NULL; } } - sector_num += num; - nb_sectors -= num; + offset += num; + count -= num; } fail: @@ -1237,7 +1251,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs, ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req); if (!ret && bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF && - !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_write_zeroes && + !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes && qemu_iovec_is_zero(qiov)) { flags |= BDRV_REQ_ZERO_WRITE; if (bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP) { @@ -1249,7 +1263,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs, /* Do nothing, write notifier decided to fail this request */ } else if (flags & BDRV_REQ_ZERO_WRITE) { bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO); - ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors, flags); + ret = bdrv_co_do_pwrite_zeroes(bs, sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS, flags); } else { bdrv_debug_event(bs, BLKDBG_PWRITEV); ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, flags); @@ -1427,6 +1442,14 @@ int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, bytes += offset & (align - 1); offset = offset & ~(align - 1); + + /* We have read the tail already if the request is smaller + * than one aligned block. + */ + if (bytes < align) { + qemu_iovec_add(&local_qiov, head_buf + bytes, align - bytes); + bytes = align; + } } if ((offset + bytes) & (align - 1)) { @@ -1502,18 +1525,18 @@ int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov, 0); } -int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - BdrvRequestFlags flags) +int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, + BdrvRequestFlags flags) { - trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags); + trace_bdrv_co_pwrite_zeroes(bs, offset, count, flags); if (!(bs->open_flags & BDRV_O_UNMAP)) { flags &= ~BDRV_REQ_MAY_UNMAP; } - return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL, - BDRV_REQ_ZERO_WRITE | flags); + return bdrv_co_pwritev(bs, offset, count, NULL, + BDRV_REQ_ZERO_WRITE | flags); } typedef struct BdrvCoGetBlockStatusData { @@ -1865,17 +1888,6 @@ BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, cb, opaque, true); } -BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags, - BlockCompletionFunc *cb, void *opaque) -{ - trace_bdrv_aio_write_zeroes(bs, sector_num, nb_sectors, flags, opaque); - - return bdrv_co_aio_rw_vector(bs, sector_num, NULL, nb_sectors, - BDRV_REQ_ZERO_WRITE | flags, - cb, opaque, true); -} - void bdrv_aio_cancel(BlockAIOCB *acb) { qemu_aio_ref(acb); @@ -1905,6 +1917,27 @@ void bdrv_aio_cancel_async(BlockAIOCB *acb) /**************************************************************/ /* async block device emulation */ +typedef struct BlockRequest { + union { + /* Used during read, write, trim */ + struct { + int64_t sector; + int nb_sectors; + int flags; + QEMUIOVector *qiov; + }; + /* Used during ioctl */ + struct { + int req; + void *buf; + }; + }; + BlockCompletionFunc *cb; + void *opaque; + + int error; +} BlockRequest; + typedef struct BlockAIOCBCoroutine { BlockAIOCB common; BlockRequest req; @@ -2309,19 +2342,6 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) return rwco.ret; } -typedef struct { - CoroutineIOCompletion *co; - QEMUBH *bh; -} BdrvIoctlCompletionData; - -static void bdrv_ioctl_bh_cb(void *opaque) -{ - BdrvIoctlCompletionData *data = opaque; - - bdrv_co_io_em_complete(data->co, -ENOTSUP); - qemu_bh_delete(data->bh); -} - static int bdrv_co_do_ioctl(BlockDriverState *bs, int req, void *buf) { BlockDriver *drv = bs->drv; @@ -2339,11 +2359,8 @@ static int bdrv_co_do_ioctl(BlockDriverState *bs, int req, void *buf) acb = drv->bdrv_aio_ioctl(bs, req, buf, bdrv_co_io_em_complete, &co); if (!acb) { - BdrvIoctlCompletionData *data = g_new(BdrvIoctlCompletionData, 1); - data->bh = aio_bh_new(bdrv_get_aio_context(bs), - bdrv_ioctl_bh_cb, data); - data->co = &co; - qemu_bh_schedule(data->bh); + co.ret = -ENOTSUP; + goto out; } qemu_coroutine_yield(); out: diff --git a/block/iscsi.c b/block/iscsi.c index e7d5f7b0c3..7e78adea15 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -401,18 +401,26 @@ static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun) return sector * BDRV_SECTOR_SIZE / iscsilun->block_size; } -static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors, - IscsiLun *iscsilun) +static bool is_byte_request_lun_aligned(int64_t offset, int count, + IscsiLun *iscsilun) { - if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size || - (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) { - error_report("iSCSI misaligned request: " - "iscsilun->block_size %u, sector_num %" PRIi64 - ", nb_sectors %d", - iscsilun->block_size, sector_num, nb_sectors); - return 0; - } - return 1; + if (offset % iscsilun->block_size || count % iscsilun->block_size) { + error_report("iSCSI misaligned request: " + "iscsilun->block_size %u, offset %" PRIi64 + ", count %d", + iscsilun->block_size, offset, count); + return false; + } + return true; +} + +static bool is_sector_request_lun_aligned(int64_t sector_num, int nb_sectors, + IscsiLun *iscsilun) +{ + assert(nb_sectors < BDRV_REQUEST_MAX_SECTORS); + return is_byte_request_lun_aligned(sector_num << BDRV_SECTOR_BITS, + nb_sectors << BDRV_SECTOR_BITS, + iscsilun); } static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun) @@ -461,7 +469,7 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors, if (fua) { assert(iscsilun->dpofua); } - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -541,7 +549,7 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs, iscsi_co_init_iscsitask(iscsilun, &iTask); - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { ret = -EINVAL; goto out; } @@ -638,7 +646,7 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs, uint64_t lba; uint32_t num_sectors; - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -926,7 +934,7 @@ coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num, struct IscsiTask iTask; struct unmap_list list; - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { + if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } @@ -977,8 +985,8 @@ retry: } static int -coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags) { IscsiLun *iscsilun = bs->opaque; struct IscsiTask iTask; @@ -986,8 +994,8 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, uint32_t nb_blocks; bool use_16_for_ws = iscsilun->use_16_for_rw; - if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { - return -EINVAL; + if (!is_byte_request_lun_aligned(offset, count, iscsilun)) { + return -ENOTSUP; } if (flags & BDRV_REQ_MAY_UNMAP) { @@ -1008,8 +1016,8 @@ coroutine_fn iscsi_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, return -ENOTSUP; } - lba = sector_qemu2lun(sector_num, iscsilun); - nb_blocks = sector_qemu2lun(nb_sectors, iscsilun); + lba = offset / iscsilun->block_size; + nb_blocks = count / iscsilun->block_size; if (iscsilun->zeroblock == NULL) { iscsilun->zeroblock = g_try_malloc0(iscsilun->block_size); @@ -1065,9 +1073,11 @@ retry: } if (flags & BDRV_REQ_MAY_UNMAP) { - iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors); + iscsi_allocationmap_clear(iscsilun, offset >> BDRV_SECTOR_BITS, + count >> BDRV_SECTOR_BITS); } else { - iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors); + iscsi_allocationmap_set(iscsilun, offset >> BDRV_SECTOR_BITS, + count >> BDRV_SECTOR_BITS); } return 0; @@ -1711,15 +1721,19 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp) } bs->bl.discard_alignment = sector_limits_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun); + } else { + bs->bl.discard_alignment = iscsilun->block_size >> BDRV_SECTOR_BITS; } - if (iscsilun->bl.max_ws_len < 0xffffffff) { - bs->bl.max_write_zeroes = - sector_limits_lun2qemu(iscsilun->bl.max_ws_len, iscsilun); + if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) { + bs->bl.max_pwrite_zeroes = + iscsilun->bl.max_ws_len * iscsilun->block_size; } if (iscsilun->lbp.lbpws) { - bs->bl.write_zeroes_alignment = - sector_limits_lun2qemu(iscsilun->bl.opt_unmap_gran, iscsilun); + bs->bl.pwrite_zeroes_alignment = + iscsilun->bl.opt_unmap_gran * iscsilun->block_size; + } else { + bs->bl.pwrite_zeroes_alignment = iscsilun->block_size; } bs->bl.opt_transfer_length = sector_limits_lun2qemu(iscsilun->bl.opt_xfer_len, iscsilun); @@ -1852,7 +1866,7 @@ static BlockDriver bdrv_iscsi = { .bdrv_co_get_block_status = iscsi_co_get_block_status, .bdrv_co_discard = iscsi_co_discard, - .bdrv_co_write_zeroes = iscsi_co_write_zeroes, + .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes, .bdrv_co_readv = iscsi_co_readv, .bdrv_co_writev_flags = iscsi_co_writev_flags, .bdrv_co_flush_to_disk = iscsi_co_flush, diff --git a/block/parallels.c b/block/parallels.c index 99fc0f77ef..d6a1a616b6 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -204,13 +204,15 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, return -EINVAL; } - to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx; + to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx; space = to_allocate * s->tracks; if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) { int ret; space += s->prealloc_size; if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { - ret = bdrv_write_zeroes(bs->file->bs, s->data_end, space, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, + s->data_end << BDRV_SECTOR_BITS, + space << BDRV_SECTOR_BITS, 0); } else { ret = bdrv_truncate(bs->file->bs, (s->data_end + space) << BDRV_SECTOR_BITS); diff --git a/block/qcow.c b/block/qcow.c index cb4bf0299f..c5cf813469 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -868,8 +868,8 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) } tmp = g_malloc0(BDRV_SECTOR_SIZE); - for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/ - BDRV_SECTOR_SIZE); i++) { + for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE); + i++) { ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, tmp, BDRV_SECTOR_SIZE, 0); if (ret != BDRV_SECTOR_SIZE) { diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 0fe8edae41..208a060421 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -226,7 +226,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) return 0; } -int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) +int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c) { BDRVQcow2State *s = bs->opaque; int result = 0; @@ -242,8 +242,15 @@ int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) } } + return result; +} + +int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) +{ + int result = qcow2_cache_write(bs, c); + if (result == 0) { - ret = bdrv_flush(bs->file->bs); + int ret = bdrv_flush(bs->file->bs); if (ret < 0) { result = ret; } diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 892e0fbfbf..b04bfafd65 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1765,8 +1765,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table, goto fail; } - ret = bdrv_write_zeroes(bs->file->bs, offset / BDRV_SECTOR_SIZE, - s->cluster_sectors, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, offset, s->cluster_size, 0); if (ret < 0) { if (!preallocated) { qcow2_free_clusters(bs, offset, s->cluster_size, @@ -1868,8 +1867,8 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs, } for (i = 0; i < s->nb_snapshots; i++) { - int l1_sectors = (s->snapshots[i].l1_size * sizeof(uint64_t) + - BDRV_SECTOR_SIZE - 1) / BDRV_SECTOR_SIZE; + int l1_sectors = DIV_ROUND_UP(s->snapshots[i].l1_size * + sizeof(uint64_t), BDRV_SECTOR_SIZE); l1_table = g_realloc(l1_table, l1_sectors * BDRV_SECTOR_SIZE); diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 7fa972a383..66f187a74b 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -490,14 +490,12 @@ static int alloc_refcount_block(BlockDriverState *bs, uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t)); blocks_clusters = 1 + - ((table_clusters + s->refcount_block_size - 1) - / s->refcount_block_size); + DIV_ROUND_UP(table_clusters, s->refcount_block_size); uint64_t meta_clusters = table_clusters + blocks_clusters; last_table_size = table_size; table_size = next_refcount_table_size(s, blocks_used + - ((meta_clusters + s->refcount_block_size - 1) - / s->refcount_block_size)); + DIV_ROUND_UP(meta_clusters, s->refcount_block_size)); } while (last_table_size != table_size); diff --git a/block/qcow2.c b/block/qcow2.c index c9306a78c1..6f5fb810e4 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1193,7 +1193,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQcow2State *s = bs->opaque; - bs->bl.write_zeroes_alignment = s->cluster_sectors; + bs->bl.pwrite_zeroes_alignment = s->cluster_size; } static int qcow2_set_key(BlockDriverState *bs, const char *key) @@ -2406,65 +2406,55 @@ finish: } -static bool is_zero_cluster(BlockDriverState *bs, int64_t start) +static bool is_zero_sectors(BlockDriverState *bs, int64_t start, + uint32_t count) { - BDRVQcow2State *s = bs->opaque; int nr; BlockDriverState *file; - int64_t res = bdrv_get_block_status_above(bs, NULL, start, - s->cluster_sectors, &nr, &file); - return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == s->cluster_sectors; -} - -static bool is_zero_cluster_top_locked(BlockDriverState *bs, int64_t start) -{ - BDRVQcow2State *s = bs->opaque; - int nr = s->cluster_sectors; - uint64_t off; - int ret; + int64_t res; - ret = qcow2_get_cluster_offset(bs, start << BDRV_SECTOR_BITS, &nr, &off); - assert(nr == s->cluster_sectors); - return ret == QCOW2_CLUSTER_UNALLOCATED || ret == QCOW2_CLUSTER_ZERO; + if (!count) { + return true; + } + res = bdrv_get_block_status_above(bs, NULL, start, count, + &nr, &file); + return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == count; } -static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { int ret; BDRVQcow2State *s = bs->opaque; - int head = sector_num % s->cluster_sectors; - int tail = (sector_num + nb_sectors) % s->cluster_sectors; + uint32_t head = offset % s->cluster_size; + uint32_t tail = (offset + count) % s->cluster_size; - if (head != 0 || tail != 0) { - int64_t cl_end = -1; + trace_qcow2_pwrite_zeroes_start_req(qemu_coroutine_self(), offset, count); - sector_num -= head; - nb_sectors += head; + if (head || tail) { + int64_t cl_start = (offset - head) >> BDRV_SECTOR_BITS; + uint64_t off; + int nr; - if (tail != 0) { - nb_sectors += s->cluster_sectors - tail; - } + assert(head + count <= s->cluster_size); - if (!is_zero_cluster(bs, sector_num)) { + /* check whether remainder of cluster already reads as zero */ + if (!(is_zero_sectors(bs, cl_start, + DIV_ROUND_UP(head, BDRV_SECTOR_SIZE)) && + is_zero_sectors(bs, (offset + count) >> BDRV_SECTOR_BITS, + DIV_ROUND_UP(-tail & (s->cluster_size - 1), + BDRV_SECTOR_SIZE)))) { return -ENOTSUP; } - if (nb_sectors > s->cluster_sectors) { - /* Technically the request can cover 2 clusters, f.e. 4k write - at s->cluster_sectors - 2k offset. One of these cluster can - be zeroed, one unallocated */ - cl_end = sector_num + nb_sectors - s->cluster_sectors; - if (!is_zero_cluster(bs, cl_end)) { - return -ENOTSUP; - } - } - qemu_co_mutex_lock(&s->lock); /* We can have new write after previous check */ - if (!is_zero_cluster_top_locked(bs, sector_num) || - (cl_end > 0 && !is_zero_cluster_top_locked(bs, cl_end))) { + offset = cl_start << BDRV_SECTOR_BITS; + count = s->cluster_size; + nr = s->cluster_sectors; + ret = qcow2_get_cluster_offset(bs, offset, &nr, &off); + if (ret != QCOW2_CLUSTER_UNALLOCATED && ret != QCOW2_CLUSTER_ZERO) { qemu_co_mutex_unlock(&s->lock); return -ENOTSUP; } @@ -2472,8 +2462,10 @@ static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs, qemu_co_mutex_lock(&s->lock); } + trace_qcow2_pwrite_zeroes(qemu_coroutine_self(), offset, count); + /* Whatever is left can use real zero clusters */ - ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS, nb_sectors); + ret = qcow2_zero_clusters(bs, offset, count >> BDRV_SECTOR_BITS); qemu_co_mutex_unlock(&s->lock); return ret; @@ -2664,8 +2656,8 @@ static int make_completely_empty(BlockDriverState *bs) /* After this call, neither the in-memory nor the on-disk refcount * information accurately describe the actual references */ - ret = bdrv_write_zeroes(bs->file->bs, s->l1_table_offset / BDRV_SECTOR_SIZE, - l1_clusters * s->cluster_sectors, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, s->l1_table_offset, + l1_clusters * s->cluster_size, 0); if (ret < 0) { goto fail_broken_refcounts; } @@ -2678,9 +2670,8 @@ static int make_completely_empty(BlockDriverState *bs) * overwrite parts of the existing refcount and L1 table, which is not * an issue because the dirty flag is set, complete data loss is in fact * desired and partial data loss is consequently fine as well */ - ret = bdrv_write_zeroes(bs->file->bs, s->cluster_size / BDRV_SECTOR_SIZE, - (2 + l1_clusters) * s->cluster_size / - BDRV_SECTOR_SIZE, 0); + ret = bdrv_pwrite_zeroes(bs->file->bs, s->cluster_size, + (2 + l1_clusters) * s->cluster_size, 0); /* This call (even if it failed overall) may have overwritten on-disk * refcount structures; in that case, the in-memory refcount information * will probably differ from the on-disk information which makes the BDS @@ -2822,14 +2813,14 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) int ret; qemu_co_mutex_lock(&s->lock); - ret = qcow2_cache_flush(bs, s->l2_table_cache); + ret = qcow2_cache_write(bs, s->l2_table_cache); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); return ret; } if (qcow2_need_accurate_refcounts(s)) { - ret = qcow2_cache_flush(bs, s->refcount_block_cache); + ret = qcow2_cache_write(bs, s->refcount_block_cache); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); return ret; @@ -3381,7 +3372,7 @@ BlockDriver bdrv_qcow2 = { .bdrv_co_writev = qcow2_co_writev, .bdrv_co_flush_to_os = qcow2_co_flush_to_os, - .bdrv_co_write_zeroes = qcow2_co_write_zeroes, + .bdrv_co_pwrite_zeroes = qcow2_co_pwrite_zeroes, .bdrv_co_discard = qcow2_co_discard, .bdrv_truncate = qcow2_truncate, .bdrv_write_compressed = qcow2_write_compressed, diff --git a/block/qcow2.h b/block/qcow2.h index a063a3c1a1..7db9795d44 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -583,6 +583,7 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c); void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c, void *table); int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); +int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c); int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, Qcow2Cache *dependency); void qcow2_cache_depends_on_flush(Qcow2Cache *c); diff --git a/block/qed-check.c b/block/qed-check.c index 622f308976..dcd4f036b8 100644 --- a/block/qed-check.c +++ b/block/qed-check.c @@ -234,8 +234,7 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) } check.result->bfi.total_clusters = - (s->header.image_size + s->header.cluster_size - 1) / - s->header.cluster_size; + DIV_ROUND_UP(s->header.image_size, s->header.cluster_size); ret = qed_check_l1_table(&check, s->l1_table); if (ret == 0) { /* Only check for leaks if entire image was scanned successfully */ diff --git a/block/qed.c b/block/qed.c index b591d4a3fc..12068061ac 100644 --- a/block/qed.c +++ b/block/qed.c @@ -143,8 +143,7 @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb, * them, and write back. */ - int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) / - BDRV_SECTOR_SIZE; + int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE); size_t len = nsectors * BDRV_SECTOR_SIZE; QEDWriteHeaderCB *write_header_cb = gencb_alloc(sizeof(*write_header_cb), cb, opaque); @@ -518,7 +517,7 @@ static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQEDState *s = bs->opaque; - bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS; + bs->bl.pwrite_zeroes_alignment = s->header.cluster_size; } /* We have nothing to do for QED reopen, stubs just return @@ -1419,7 +1418,7 @@ typedef struct { bool done; } QEDWriteZeroesCB; -static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret) +static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret) { QEDWriteZeroesCB *cb = opaque; @@ -1430,10 +1429,10 @@ static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret) } } -static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, + int count, + BdrvRequestFlags flags) { BlockAIOCB *blockacb; BDRVQEDState *s = bs->opaque; @@ -1441,25 +1440,22 @@ static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, QEMUIOVector qiov; struct iovec iov; - /* Refuse if there are untouched backing file sectors */ - if (bs->backing) { - if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) { - return -ENOTSUP; - } - if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) { - return -ENOTSUP; - } + /* Fall back if the request is not aligned */ + if (qed_offset_into_cluster(s, offset) || + qed_offset_into_cluster(s, count)) { + return -ENOTSUP; } /* Zero writes start without an I/O buffer. If a buffer becomes necessary * then it will be allocated during request processing. */ - iov.iov_base = NULL, - iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE, + iov.iov_base = NULL; + iov.iov_len = count; qemu_iovec_init_external(&qiov, &iov, 1); - blockacb = qed_aio_setup(bs, sector_num, &qiov, nb_sectors, - qed_co_write_zeroes_cb, &cb, + blockacb = qed_aio_setup(bs, offset >> BDRV_SECTOR_BITS, &qiov, + count >> BDRV_SECTOR_BITS, + qed_co_pwrite_zeroes_cb, &cb, QED_AIOCB_WRITE | QED_AIOCB_ZERO); if (!blockacb) { return -EIO; @@ -1664,7 +1660,7 @@ static BlockDriver bdrv_qed = { .bdrv_co_get_block_status = bdrv_qed_co_get_block_status, .bdrv_aio_readv = bdrv_qed_aio_readv, .bdrv_aio_writev = bdrv_qed_aio_writev, - .bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes, + .bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes, .bdrv_truncate = bdrv_qed_truncate, .bdrv_getlength = bdrv_qed_getlength, .bdrv_get_info = bdrv_qed_get_info, diff --git a/block/raw-posix.c b/block/raw-posix.c index a4f5a1ba5f..ce2e20f203 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -729,9 +729,33 @@ static void raw_reopen_abort(BDRVReopenState *state) state->opaque = NULL; } +static int hdev_get_max_transfer_length(int fd) +{ +#ifdef BLKSECTGET + int max_sectors = 0; + if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) { + return max_sectors; + } else { + return -errno; + } +#else + return -ENOSYS; +#endif +} + static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s = bs->opaque; + struct stat st; + + if (!fstat(s->fd, &st)) { + if (S_ISBLK(st.st_mode)) { + int ret = hdev_get_max_transfer_length(s->fd); + if (ret >= 0) { + bs->bl.max_transfer_length = ret; + } + } + } raw_probe_alignment(bs, s->fd, errp); bs->bl.min_mem_alignment = s->buf_align; @@ -1252,8 +1276,8 @@ static int aio_worker(void *arg) } static int paio_submit_co(BlockDriverState *bs, int fd, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - int type) + int64_t offset, QEMUIOVector *qiov, + int count, int type) { RawPosixAIOData *acb = g_new(RawPosixAIOData, 1); ThreadPool *pool; @@ -1262,16 +1286,16 @@ static int paio_submit_co(BlockDriverState *bs, int fd, acb->aio_type = type; acb->aio_fildes = fd; - acb->aio_nbytes = nb_sectors * BDRV_SECTOR_SIZE; - acb->aio_offset = sector_num * BDRV_SECTOR_SIZE; + acb->aio_nbytes = count; + acb->aio_offset = offset; if (qiov) { acb->aio_iov = qiov->iov; acb->aio_niov = qiov->niov; - assert(qiov->size == acb->aio_nbytes); + assert(qiov->size == count); } - trace_paio_submit_co(sector_num, nb_sectors, type); + trace_paio_submit_co(offset, count, type); pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); return thread_pool_submit_co(pool, aio_worker, acb); } @@ -1868,17 +1892,17 @@ static coroutine_fn BlockAIOCB *raw_aio_discard(BlockDriverState *bs, cb, opaque, QEMU_AIO_DISCARD); } -static int coroutine_fn raw_co_write_zeroes( - BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags) +static int coroutine_fn raw_co_pwrite_zeroes( + BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags) { BDRVRawState *s = bs->opaque; if (!(flags & BDRV_REQ_MAY_UNMAP)) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_WRITE_ZEROES); } else if (s->discard_zeroes) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_DISCARD); } return -ENOTSUP; @@ -1931,7 +1955,7 @@ BlockDriver bdrv_file = { .bdrv_create = raw_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = raw_co_get_block_status, - .bdrv_co_write_zeroes = raw_co_write_zeroes, + .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, @@ -2293,8 +2317,8 @@ static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs, cb, opaque, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); } -static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) +static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags) { BDRVRawState *s = bs->opaque; int rc; @@ -2304,10 +2328,10 @@ static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, return rc; } if (!(flags & BDRV_REQ_MAY_UNMAP)) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV); } else if (s->discard_zeroes) { - return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors, + return paio_submit_co(bs, s->fd, offset, NULL, count, QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); } return -ENOTSUP; @@ -2379,7 +2403,7 @@ static BlockDriver bdrv_host_device = { .bdrv_reopen_abort = raw_reopen_abort, .bdrv_create = hdev_create, .create_opts = &raw_create_opts, - .bdrv_co_write_zeroes = hdev_co_write_zeroes, + .bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 3385ed448d..b1d5237135 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -127,11 +127,11 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, (sector_num << BDRV_SECTOR_BITS); } -static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int count, + BdrvRequestFlags flags) { - return bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags); + return bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags); } static int coroutine_fn raw_co_discard(BlockDriverState *bs, @@ -252,7 +252,7 @@ BlockDriver bdrv_raw = { .bdrv_create = &raw_create, .bdrv_co_readv = &raw_co_readv, .bdrv_co_writev_flags = &raw_co_writev_flags, - .bdrv_co_write_zeroes = &raw_co_write_zeroes, + .bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes, .bdrv_co_discard = &raw_co_discard, .bdrv_co_get_block_status = &raw_co_get_block_status, .bdrv_truncate = &raw_truncate, diff --git a/block/snapshot.c b/block/snapshot.c index 6e6e34fcf4..da89d2b085 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -409,9 +409,6 @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs, if (bdrv_can_snapshot(bs) && bdrv_snapshot_find(bs, snapshot, name) >= 0) { ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err); - if (ret < 0) { - goto fail; - } } aio_context_release(ctx); if (ret < 0) { diff --git a/block/vhdx.c b/block/vhdx.c index c0d24a24ee..f5605a2ff4 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -27,7 +27,6 @@ #include "migration/migration.h" #include <uuid/uuid.h> -#include <glib.h> /* Options for VHDX creation */ diff --git a/block/vmdk.c b/block/vmdk.c index 372e5edc15..ee09423b46 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -34,7 +34,6 @@ #include "migration/migration.h" #include "qemu/cutils.h" #include <zlib.h> -#include <glib.h> #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V') @@ -998,9 +997,9 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) for (i = 0; i < s->num_extents; i++) { if (!s->extents[i].flat) { - bs->bl.write_zeroes_alignment = - MAX(bs->bl.write_zeroes_alignment, - s->extents[i].cluster_sectors); + bs->bl.pwrite_zeroes_alignment = + MAX(bs->bl.pwrite_zeroes_alignment, + s->extents[i].cluster_sectors << BDRV_SECTOR_BITS); } } } @@ -1704,15 +1703,13 @@ static int vmdk_write_compressed(BlockDriverState *bs, } } -static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, + int bytes, + BdrvRequestFlags flags) { int ret; BDRVVmdkState *s = bs->opaque; - uint64_t offset = sector_num * BDRV_SECTOR_SIZE; - uint64_t bytes = nb_sectors * BDRV_SECTOR_SIZE; qemu_co_mutex_lock(&s->lock); /* write zeroes could fail if sectors not aligned to cluster, test it with @@ -2403,7 +2400,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_co_preadv = vmdk_co_preadv, .bdrv_co_pwritev = vmdk_co_pwritev, .bdrv_write_compressed = vmdk_write_compressed, - .bdrv_co_write_zeroes = vmdk_co_write_zeroes, + .bdrv_co_pwrite_zeroes = vmdk_co_pwrite_zeroes, .bdrv_close = vmdk_close, .bdrv_create = vmdk_create, .bdrv_co_flush_to_disk = vmdk_co_flush, diff --git a/block/vvfat.c b/block/vvfat.c index a39dbe67e2..6d2e21ce11 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1960,8 +1960,7 @@ DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i)) /* check file size with FAT */ cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2); if (cluster_count != - (le32_to_cpu(direntries[i].size) + s->cluster_size - - 1) / s->cluster_size) { + DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) { DLOG(fprintf(stderr, "Cluster count mismatch\n")); goto fail; } diff --git a/blockdev.c b/blockdev.c index 717785eb8d..7fd515a4fa 100644 --- a/blockdev.c +++ b/blockdev.c @@ -56,6 +56,8 @@ static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states); +static int do_open_tray(const char *device, bool force, Error **errp); + static const char *const if_name[IF_COUNT] = { [IF_NONE] = "none", [IF_IDE] = "ide", @@ -2274,8 +2276,6 @@ exit: block_job_txn_unref(block_job_txn); } -static int do_open_tray(const char *device, bool force, Error **errp); - void qmp_eject(const char *device, bool has_force, bool force, Error **errp) { Error *local_err = NULL; @@ -2286,16 +2286,11 @@ void qmp_eject(const char *device, bool has_force, bool force, Error **errp) } rc = do_open_tray(device, force, &local_err); - if (local_err) { + if (rc && rc != -ENOSYS) { error_propagate(errp, local_err); return; } - - if (rc == EINPROGRESS) { - error_setg(errp, "Device '%s' is locked and force was not specified, " - "wait for tray to open and try again", device); - return; - } + error_free(local_err); qmp_x_blockdev_remove_medium(device, errp); } @@ -2324,11 +2319,16 @@ void qmp_block_passwd(bool has_device, const char *device, aio_context_release(aio_context); } -/** - * returns -errno on fatal error, +errno for non-fatal situations. - * errp will always be set when the return code is negative. - * May return +ENOSYS if the device has no tray, - * or +EINPROGRESS if the tray is locked and the guest has been notified. +/* + * Attempt to open the tray of @device. + * If @force, ignore its tray lock. + * Else, if the tray is locked, don't open it, but ask the guest to open it. + * On error, store an error through @errp and return -errno. + * If @device does not exist, return -ENODEV. + * If it has no removable media, return -ENOTSUP. + * If it has no tray, return -ENOSYS. + * If the guest was asked to open the tray, return -EINPROGRESS. + * Else, return 0. */ static int do_open_tray(const char *device, bool force, Error **errp) { @@ -2348,8 +2348,8 @@ static int do_open_tray(const char *device, bool force, Error **errp) } if (!blk_dev_has_tray(blk)) { - /* Ignore this command on tray-less devices */ - return ENOSYS; + error_setg(errp, "Device '%s' does not have a tray", device); + return -ENOSYS; } if (blk_dev_is_tray_open(blk)) { @@ -2366,7 +2366,9 @@ static int do_open_tray(const char *device, bool force, Error **errp) } if (locked && !force) { - return EINPROGRESS; + error_setg(errp, "Device '%s' is locked and force was not specified, " + "wait for tray to open and try again", device); + return -EINPROGRESS; } return 0; @@ -2375,10 +2377,18 @@ static int do_open_tray(const char *device, bool force, Error **errp) void qmp_blockdev_open_tray(const char *device, bool has_force, bool force, Error **errp) { + Error *local_err = NULL; + int rc; + if (!has_force) { force = false; } - do_open_tray(device, force, errp); + rc = do_open_tray(device, force, &local_err); + if (rc && rc != -ENOSYS && rc != -EINPROGRESS) { + error_propagate(errp, local_err); + return; + } + error_free(local_err); } void qmp_blockdev_close_tray(const char *device, Error **errp) @@ -3335,7 +3345,7 @@ void do_blockdev_backup(const char *device, const char *target, BlockdevOnError on_target_error, BlockJobTxn *txn, Error **errp) { - BlockBackend *blk, *target_blk; + BlockBackend *blk; BlockDriverState *bs; BlockDriverState *target_bs; Error *local_err = NULL; @@ -3366,19 +3376,22 @@ void do_blockdev_backup(const char *device, const char *target, } bs = blk_bs(blk); - target_blk = blk_by_name(target); - if (!target_blk) { - error_setg(errp, "Device '%s' not found", target); + target_bs = bdrv_lookup_bs(target, target, errp); + if (!target_bs) { goto out; } - if (!blk_is_available(target_blk)) { - error_setg(errp, "Device '%s' has no medium", target); - goto out; + if (bdrv_get_aio_context(target_bs) != aio_context) { + if (!bdrv_has_blk(target_bs)) { + /* The target BDS is not attached, we can safely move it to another + * AioContext. */ + bdrv_set_aio_context(target_bs, aio_context); + } else { + error_setg(errp, "Target is attached to a different thread from " + "source."); + goto out; + } } - target_bs = blk_bs(target_blk); - - bdrv_set_aio_context(target_bs, aio_context); backup_start(bs, target_bs, speed, sync, NULL, on_source_error, on_target_error, block_job_cb, bs, txn, &local_err); if (local_err != NULL) { @@ -31,6 +31,7 @@ TMPCXX="${TMPDIR1}/${TMPB}.cxx" TMPL="${TMPDIR1}/${TMPB}.lo" TMPA="${TMPDIR1}/lib${TMPB}.la" TMPE="${TMPDIR1}/${TMPB}.exe" +TMPMO="${TMPDIR1}/${TMPB}.mo" rm -f config.log @@ -164,7 +165,7 @@ have_backend () { } # default parameters -source_path=`dirname "$0"` +source_path=$(dirname "$0") cpu="" iasl="iasl" interp_prefix="/usr/gnemul/qemu-%M" @@ -323,7 +324,7 @@ jemalloc="no" # parse CC options first for opt do - optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` + optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') case "$opt" in --cross-prefix=*) cross_prefix="$optarg" ;; @@ -398,7 +399,7 @@ if test "$debug_info" = "yes"; then fi # make source path absolute -source_path=`cd "$source_path"; pwd` +source_path=$(cd "$source_path"; pwd) # running configure in the source tree? # we know that's the case if configure is there. @@ -443,7 +444,7 @@ elif check_define __sun__ ; then elif check_define __HAIKU__ ; then targetos='Haiku' else - targetos=`uname -s` + targetos=$(uname -s) fi # Some host OSes need non-standard checks for which CPU to use. @@ -461,7 +462,7 @@ Darwin) fi ;; SunOS) - # `uname -m` returns i86pc even on an x86_64 box, so default based on isainfo + # $(uname -m) returns i86pc even on an x86_64 box, so default based on isainfo if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then cpu="x86_64" fi @@ -507,7 +508,7 @@ elif check_define __aarch64__ ; then elif check_define __hppa__ ; then cpu="hppa" else - cpu=`uname -m` + cpu=$(uname -m) fi ARCH= @@ -627,7 +628,7 @@ SunOS) ld="gld" smbd="${SMBD-/usr/sfw/sbin/smbd}" needs_libsunmath="no" - solarisrev=`uname -r | cut -f2 -d.` + solarisrev=$(uname -r | cut -f2 -d.) if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then if test "$solarisrev" -le 9 ; then if test -f /opt/SUNWspro/prod/lib/libsunmath.so.1; then @@ -722,7 +723,7 @@ fi werror="" for opt do - optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` + optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') case "$opt" in --help|-h) show_help=yes ;; @@ -846,9 +847,9 @@ for opt do ;; --audio-drv-list=*) audio_drv_list="$optarg" ;; - --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=`echo "$optarg" | sed -e 's/,/ /g'` + --block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=$(echo "$optarg" | sed -e 's/,/ /g') ;; - --block-drv-ro-whitelist=*) block_drv_ro_whitelist=`echo "$optarg" | sed -e 's/,/ /g'` + --block-drv-ro-whitelist=*) block_drv_ro_whitelist=$(echo "$optarg" | sed -e 's/,/ /g') ;; --enable-debug-tcg) debug_tcg="yes" ;; @@ -943,7 +944,7 @@ for opt do ;; --enable-cocoa) cocoa="yes" ; - audio_drv_list="coreaudio `echo $audio_drv_list | sed s,coreaudio,,g`" + audio_drv_list="coreaudio $(echo $audio_drv_list | sed s,coreaudio,,g)" ;; --disable-system) softmmu="no" ;; @@ -1388,7 +1389,7 @@ fi # Consult white-list to determine whether to enable werror # by default. Only enable by default for git builds -z_version=`cut -f3 -d. $source_path/VERSION` +z_version=$(cut -f3 -d. $source_path/VERSION) if test -z "$werror" ; then if test -d "$source_path/.git" -a \ @@ -1617,7 +1618,7 @@ if test "$solaris" = "yes" ; then "install fileutils from www.blastwave.org using pkg-get -i fileutils" \ "to get ginstall which is used by default (which lives in /opt/csw/bin)" fi - if test "`path_of $install`" = "/usr/sbin/install" ; then + if test "$(path_of $install)" = "/usr/sbin/install" ; then error_exit "Solaris /usr/sbin/install is not an appropriate install program." \ "try ginstall from the GNU fileutils available from www.blastwave.org" \ "using pkg-get -i fileutils, or use --install=/usr/ucb/install" @@ -1636,7 +1637,7 @@ fi if test -z "${target_list+xxx}" ; then target_list="$default_target_list" else - target_list=`echo "$target_list" | sed -e 's/,/ /g'` + target_list=$(echo "$target_list" | sed -e 's/,/ /g') fi # Check that we recognised the target name; this allows a more @@ -1886,8 +1887,8 @@ if test "$seccomp" != "no" ; then if test "$libseccomp_minver" != "" && $pkg_config --atleast-version=$libseccomp_minver libseccomp ; then - libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`" - QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`" + libs_softmmu="$libs_softmmu $($pkg_config --libs libseccomp)" + QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags libseccomp)" seccomp="yes" else if test "$seccomp" = "yes" ; then @@ -2127,8 +2128,8 @@ fi x11_cflags= x11_libs=-lX11 if $pkg_config --exists "x11"; then - x11_cflags=`$pkg_config --cflags x11` - x11_libs=`$pkg_config --libs x11` + x11_cflags=$($pkg_config --cflags x11) + x11_libs=$($pkg_config --libs x11) fi ########################################## @@ -2155,9 +2156,9 @@ if test "$gtk" != "no"; then gtkversion="2.18.0" fi if $pkg_config --exists "$gtkpackage >= $gtkversion"; then - gtk_cflags=`$pkg_config --cflags $gtkpackage` - gtk_libs=`$pkg_config --libs $gtkpackage` - gtk_version=`$pkg_config --modversion $gtkpackage` + gtk_cflags=$($pkg_config --cflags $gtkpackage) + gtk_libs=$($pkg_config --libs $gtkpackage) + gtk_version=$($pkg_config --modversion $gtkpackage) if $pkg_config --exists "$gtkx11package >= $gtkversion"; then gtk_cflags="$gtk_cflags $x11_cflags" gtk_libs="$gtk_libs $x11_libs" @@ -2195,8 +2196,8 @@ gnutls_gcrypt=no gnutls_nettle=no if test "$gnutls" != "no"; then if gnutls_works; then - gnutls_cflags=`$pkg_config --cflags gnutls` - gnutls_libs=`$pkg_config --libs gnutls` + gnutls_cflags=$($pkg_config --cflags gnutls) + gnutls_libs=$($pkg_config --libs gnutls) libs_softmmu="$gnutls_libs $libs_softmmu" libs_tools="$gnutls_libs $libs_tools" QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags" @@ -2220,7 +2221,7 @@ if test "$gnutls" != "no"; then gnutls_gcrypt=no gnutls_nettle=yes elif $pkg_config --exists 'gnutls >= 2.12'; then - case `$pkg_config --libs --static gnutls` in + case $($pkg_config --libs --static gnutls) in *gcrypt*) gnutls_gcrypt=yes gnutls_nettle=no @@ -2281,7 +2282,7 @@ has_libgcrypt_config() { if test -n "$cross_prefix" then - host=`libgcrypt-config --host` + host=$(libgcrypt-config --host) if test "$host-" != $cross_prefix then return 1 @@ -2293,8 +2294,8 @@ has_libgcrypt_config() { if test "$gcrypt" != "no"; then if has_libgcrypt_config; then - gcrypt_cflags=`libgcrypt-config --cflags` - gcrypt_libs=`libgcrypt-config --libs` + gcrypt_cflags=$(libgcrypt-config --cflags) + gcrypt_libs=$(libgcrypt-config --libs) # Debian has remove -lgpg-error from libgcrypt-config # as it "spreads unnecessary dependencies" which in # turn breaks static builds... @@ -2334,15 +2335,16 @@ fi if test "$nettle" != "no"; then if $pkg_config --exists "nettle"; then - nettle_cflags=`$pkg_config --cflags nettle` - nettle_libs=`$pkg_config --libs nettle` - nettle_version=`$pkg_config --modversion nettle` + nettle_cflags=$($pkg_config --cflags nettle) + nettle_libs=$($pkg_config --libs nettle) + nettle_version=$($pkg_config --modversion nettle) libs_softmmu="$nettle_libs $libs_softmmu" libs_tools="$nettle_libs $libs_tools" QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags" nettle="yes" cat > $TMPC << EOF +#include <stddef.h> #include <nettle/pbkdf2.h> int main(void) { pbkdf2_hmac_sha256(8, NULL, 1000, 8, NULL, 8, NULL); @@ -2373,8 +2375,8 @@ tasn1=yes tasn1_cflags="" tasn1_libs="" if $pkg_config --exists "libtasn1"; then - tasn1_cflags=`$pkg_config --cflags libtasn1` - tasn1_libs=`$pkg_config --libs libtasn1` + tasn1_cflags=$($pkg_config --cflags libtasn1) + tasn1_libs=$($pkg_config --libs libtasn1) else tasn1=no fi @@ -2404,9 +2406,9 @@ if test "$vte" != "no"; then vteminversion="0.24.0" fi if $pkg_config --exists "$vtepackage >= $vteminversion"; then - vte_cflags=`$pkg_config --cflags $vtepackage` - vte_libs=`$pkg_config --libs $vtepackage` - vteversion=`$pkg_config --modversion $vtepackage` + vte_cflags=$($pkg_config --cflags $vtepackage) + vte_libs=$($pkg_config --libs $vtepackage) + vteversion=$($pkg_config --modversion $vtepackage) libs_softmmu="$vte_libs $libs_softmmu" vte="yes" elif test "$vte" = "yes"; then @@ -2447,16 +2449,16 @@ else error_exit "Unknown sdlabi $sdlabi, must be 1.2 or 2.0" fi -if test "`basename $sdl_config`" != $sdlconfigname && ! has ${sdl_config}; then +if test "$(basename $sdl_config)" != $sdlconfigname && ! has ${sdl_config}; then sdl_config=$sdlconfigname fi if $pkg_config $sdlname --exists; then sdlconfig="$pkg_config $sdlname" - sdlversion=`$sdlconfig --modversion 2>/dev/null` + sdlversion=$($sdlconfig --modversion 2>/dev/null) elif has ${sdl_config}; then sdlconfig="$sdl_config" - sdlversion=`$sdlconfig --version` + sdlversion=$($sdlconfig --version) else if test "$sdl" = "yes" ; then feature_not_found "sdl" "Install SDL devel" @@ -2474,14 +2476,14 @@ if test "$sdl" != "no" ; then #undef main /* We don't want SDL to override our main() */ int main( void ) { return SDL_Init (SDL_INIT_VIDEO); } EOF - sdl_cflags=`$sdlconfig --cflags 2> /dev/null` + sdl_cflags=$($sdlconfig --cflags 2>/dev/null) if test "$static" = "yes" ; then - sdl_libs=`$sdlconfig --static-libs 2>/dev/null` + sdl_libs=$($sdlconfig --static-libs 2>/dev/null) else - sdl_libs=`$sdlconfig --libs 2> /dev/null` + sdl_libs=$($sdlconfig --libs 2>/dev/null) fi if compile_prog "$sdl_cflags" "$sdl_libs" ; then - if test `echo $sdlversion | sed 's/[^0-9]//g'` -lt 121 ; then + if test $(echo $sdlversion | sed 's/[^0-9]//g') -lt 121 ; then sdl_too_old=yes else sdl=yes @@ -2490,8 +2492,8 @@ EOF # static link with sdl ? (note: sdl.pc's --static --libs is broken) if test "$sdl" = "yes" -a "$static" = "yes" ; then if test $? = 0 && echo $sdl_libs | grep -- -laa > /dev/null; then - sdl_libs="$sdl_libs `aalib-config --static-libs 2>/dev/null`" - sdl_cflags="$sdl_cflags `aalib-config --cflags 2>/dev/null`" + sdl_libs="$sdl_libs $(aalib-config --static-libs 2>/dev/null)" + sdl_cflags="$sdl_cflags $(aalib-config --cflags 2>/dev/null)" fi if compile_prog "$sdl_cflags" "$sdl_libs" ; then : @@ -2608,8 +2610,8 @@ int main(void) { } EOF if $pkg_config libpng --exists; then - vnc_png_cflags=`$pkg_config libpng --cflags` - vnc_png_libs=`$pkg_config libpng --libs` + vnc_png_cflags=$($pkg_config libpng --cflags) + vnc_png_libs=$($pkg_config libpng --libs) else vnc_png_cflags="" vnc_png_libs="-lpng" @@ -2803,7 +2805,7 @@ EOF fi } -audio_drv_list=`echo "$audio_drv_list" | sed -e 's/,/ /g'` +audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/,/ /g') for drv in $audio_drv_list; do case $drv in alsa) @@ -2915,8 +2917,8 @@ if test "$curl" != "no" ; then #include <curl/curl.h> int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; } EOF - curl_cflags=`$curlconfig --cflags 2>/dev/null` - curl_libs=`$curlconfig --libs 2>/dev/null` + curl_cflags=$($curlconfig --cflags 2>/dev/null) + curl_libs=$($curlconfig --libs 2>/dev/null) if compile_prog "$curl_cflags" "$curl_libs" ; then curl=yes else @@ -2934,8 +2936,8 @@ if test "$bluez" != "no" ; then #include <bluetooth/bluetooth.h> int main(void) { return bt_error(0); } EOF - bluez_cflags=`$pkg_config --cflags bluez 2> /dev/null` - bluez_libs=`$pkg_config --libs bluez 2> /dev/null` + bluez_cflags=$($pkg_config --cflags bluez 2>/dev/null) + bluez_libs=$($pkg_config --libs bluez 2>/dev/null) if compile_prog "$bluez_cflags" "$bluez_libs" ; then bluez=yes libs_softmmu="$bluez_libs $libs_softmmu" @@ -2958,8 +2960,8 @@ fi for i in $glib_modules; do if $pkg_config --atleast-version=$glib_req_ver $i; then - glib_cflags=`$pkg_config --cflags $i` - glib_libs=`$pkg_config --libs $i` + glib_cflags=$($pkg_config --cflags $i) + glib_libs=$($pkg_config --libs $i) CFLAGS="$glib_cflags $CFLAGS" LIBS="$glib_libs $LIBS" libs_qga="$glib_libs $libs_qga" @@ -3048,8 +3050,8 @@ if test "$pixman" = "none"; then pixman_libs= elif test "$pixman" = "system"; then # pixman version has been checked above - pixman_cflags=`$pkg_config --cflags pixman-1` - pixman_libs=`$pkg_config --libs pixman-1` + pixman_cflags=$($pkg_config --cflags pixman-1) + pixman_libs=$($pkg_config --libs pixman-1) else if test ! -d ${source_path}/pixman/pixman; then error_exit "pixman >= 0.21.8 not present. Your options:" \ @@ -3165,8 +3167,8 @@ fi min_libssh2_version=1.2.8 if test "$libssh2" != "no" ; then if $pkg_config --atleast-version=$min_libssh2_version libssh2; then - libssh2_cflags=`$pkg_config libssh2 --cflags` - libssh2_libs=`$pkg_config libssh2 --libs` + libssh2_cflags=$($pkg_config libssh2 --cflags) + libssh2_libs=$($pkg_config libssh2 --libs) libssh2=yes else if test "$libssh2" = "yes" ; then @@ -3417,8 +3419,8 @@ fi if test "$glusterfs" != "no" ; then if $pkg_config --atleast-version=3 glusterfs-api; then glusterfs="yes" - glusterfs_cflags=`$pkg_config --cflags glusterfs-api` - glusterfs_libs=`$pkg_config --libs glusterfs-api` + glusterfs_cflags=$($pkg_config --cflags glusterfs-api) + glusterfs_libs=$($pkg_config --libs glusterfs-api) if $pkg_config --atleast-version=4 glusterfs-api; then glusterfs_xlator_opt="yes" fi @@ -4211,12 +4213,12 @@ int main(void) { return 0; } EOF if compile_prog "" "" ; then if $pkg_config lttng-ust --exists; then - lttng_ust_libs=`$pkg_config --libs lttng-ust` + lttng_ust_libs=$($pkg_config --libs lttng-ust) else lttng_ust_libs="-llttng-ust" fi if $pkg_config liburcu-bp --exists; then - urcu_bp_libs=`$pkg_config --libs liburcu-bp` + urcu_bp_libs=$($pkg_config --libs liburcu-bp) else urcu_bp_libs="-lurcu-bp" fi @@ -4512,6 +4514,8 @@ if compile_prog "" "" ; then have_fsxattr=yes fi +########################################## +# check if rtnetlink.h exists and is useful have_rtnetlink=no cat > $TMPC << EOF #include <linux/rtnetlink.h> @@ -4523,6 +4527,25 @@ if compile_prog "" "" ; then have_rtnetlink=yes fi +################################################# +# Sparc implicitly links with --relax, which is +# incompatible with -r, so --no-relax should be +# given. It does no harm to give it on other +# platforms too. + +# Note: the prototype is needed since QEMU_CFLAGS +# contains -Wmissing-prototypes +cat > $TMPC << EOF +extern int foo(void); +int foo(void) { return 0; } +EOF +if ! compile_object ""; then + error_exit "Failed to compile object file for LD_REL_FLAGS test" +fi +if do_cc -nostdlib -Wl,-r -Wl,--no-relax -o $TMPMO $TMPO; then + LD_REL_FLAGS="-Wl,--no-relax" +fi + ########################################## # End of CC checks # After here, no more $cc or $ld runs @@ -4667,10 +4690,10 @@ if test "$guest_agent_msi" = "yes"; then fi if test "$QEMU_GA_VERSION" = ""; then - QEMU_GA_VERSION=`cat $source_path/VERSION` + QEMU_GA_VERSION=$(cat $source_path/VERSION) fi - QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=`$pkg_config --variable=prefix glib-2.0`/bin" + QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=$($pkg_config --variable=prefix glib-2.0)/bin" case "$cpu" in x86_64) @@ -4744,16 +4767,16 @@ QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS" libs_softmmu="$pixman_libs $libs_softmmu" echo "Install prefix $prefix" -echo "BIOS directory `eval echo $qemu_datadir`" -echo "binary directory `eval echo $bindir`" -echo "library directory `eval echo $libdir`" -echo "module directory `eval echo $qemu_moddir`" -echo "libexec directory `eval echo $libexecdir`" -echo "include directory `eval echo $includedir`" -echo "config directory `eval echo $sysconfdir`" +echo "BIOS directory $(eval echo $qemu_datadir)" +echo "binary directory $(eval echo $bindir)" +echo "library directory $(eval echo $libdir)" +echo "module directory $(eval echo $qemu_moddir)" +echo "libexec directory $(eval echo $libexecdir)" +echo "include directory $(eval echo $includedir)" +echo "config directory $(eval echo $sysconfdir)" if test "$mingw32" = "no" ; then -echo "local state directory `eval echo $local_statedir`" -echo "Manual directory `eval echo $mandir`" +echo "local state directory $(eval echo $local_statedir)" +echo "Manual directory $(eval echo $mandir)" echo "ELF interp prefix $interp_prefix" else echo "local state directory queried at runtime" @@ -4788,16 +4811,16 @@ if test "$darwin" = "yes" ; then echo "Cocoa support $cocoa" fi echo "pixman $pixman" -echo "SDL support $sdl `echo_version $sdl $sdlversion`" -echo "GTK support $gtk `echo_version $gtk $gtk_version`" +echo "SDL support $sdl $(echo_version $sdl $sdlversion)" +echo "GTK support $gtk $(echo_version $gtk $gtk_version)" echo "GTK GL support $gtk_gl" -echo "VTE support $vte `echo_version $vte $vteversion`" +echo "VTE support $vte $(echo_version $vte $vteversion)" echo "GNUTLS support $gnutls" echo "GNUTLS hash $gnutls_hash" echo "GNUTLS rnd $gnutls_rnd" echo "libgcrypt $gcrypt" echo "libgcrypt kdf $gcrypt_kdf" -echo "nettle $nettle `echo_version $nettle $nettle_version`" +echo "nettle $nettle $(echo_version $nettle $nettle_version)" echo "nettle kdf $nettle_kdf" echo "libtasn1 $tasn1" echo "curses support $curses" @@ -4848,7 +4871,7 @@ echo "Trace backends $trace_backends" if have_backend "simple"; then echo "Trace output file $trace_file-<pid>" fi -echo "spice support $spice `echo_version $spice $spice_protocol_version/$spice_server_version`" +echo "spice support $spice $(echo_version $spice $spice_protocol_version/$spice_server_version)" echo "rbd support $rbd" echo "xfsctl support $xfs" echo "smartcard support $smartcard" @@ -4927,7 +4950,7 @@ if test "$bigendian" = "yes" ; then fi if test "$mingw32" = "yes" ; then echo "CONFIG_WIN32=y" >> $config_host_mak - rc_version=`cat $source_path/VERSION` + rc_version=$(cat $source_path/VERSION) version_major=${rc_version%%.*} rc_version=${rc_version#*.} version_minor=${rc_version%%.*} @@ -5003,7 +5026,7 @@ if test "$cap_ng" = "yes" ; then fi echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak for drv in $audio_drv_list; do - def=CONFIG_`echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]'` + def=CONFIG_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]') echo "$def=y" >> $config_host_mak done if test "$audio_pt_int" = "yes" ; then @@ -5035,7 +5058,7 @@ fi if test "$xfs" = "yes" ; then echo "CONFIG_XFS=y" >> $config_host_mak fi -qemu_version=`head $source_path/VERSION` +qemu_version=$(head $source_path/VERSION) echo "VERSION=$qemu_version" >>$config_host_mak echo "PKGVERSION=$pkgversion" >>$config_host_mak echo "SRC_PATH=$source_path" >> $config_host_mak @@ -5046,7 +5069,7 @@ fi if test "$modules" = "yes"; then # $shacmd can generate a hash started with digit, which the compiler doesn't # like as an symbol. So prefix it with an underscore - echo "CONFIG_STAMP=_`(echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ `" >> $config_host_mak + echo "CONFIG_STAMP=_$( (echo $qemu_version; echo $pkgversion; cat $0) | $shacmd - | cut -f1 -d\ )" >> $config_host_mak echo "CONFIG_MODULES=y" >> $config_host_mak fi if test "$sdl" = "yes" ; then @@ -5527,6 +5550,7 @@ else fi echo "LDFLAGS=$LDFLAGS" >> $config_host_mak echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak +echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak echo "LIBS+=$LIBS" >> $config_host_mak echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak echo "EXESUF=$EXESUF" >> $config_host_mak @@ -5575,7 +5599,7 @@ fi for target in $target_list; do target_dir="$target" config_target_mak=$target_dir/config-target.mak -target_name=`echo $target | cut -d '-' -f 1` +target_name=$(echo $target | cut -d '-' -f 1) target_bigendian="no" case "$target_name" in @@ -5615,7 +5639,7 @@ mkdir -p $target_dir echo "# Automatically generated by configure - do not modify" > $config_target_mak bflt="no" -interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_name/g"` +interp_prefix1=$(echo "$interp_prefix" | sed "s/%M/$target_name/g") gdb_xml_files="" TARGET_ARCH="$target_name" @@ -5741,7 +5765,7 @@ upper() { echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]' } -target_arch_name="`upper $TARGET_ARCH`" +target_arch_name="$(upper $TARGET_ARCH)" echo "TARGET_$target_arch_name=y" >> $config_target_mak echo "TARGET_NAME=$target_name" >> $config_target_mak echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak @@ -5957,11 +5981,11 @@ for bios_file in \ $source_path/pc-bios/u-boot.* \ $source_path/pc-bios/palcode-* do - FILES="$FILES pc-bios/`basename $bios_file`" + FILES="$FILES pc-bios/$(basename $bios_file)" done -for test_file in `find $source_path/tests/acpi-test-data -type f` +for test_file in $(find $source_path/tests/acpi-test-data -type f) do - FILES="$FILES tests/acpi-test-data`echo $test_file | sed -e 's/.*acpi-test-data//'`" + FILES="$FILES tests/acpi-test-data$(echo $test_file | sed -e 's/.*acpi-test-data//')" done mkdir -p $DIRS for f in $FILES ; do diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 17c4300f11..63649f1091 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -1081,8 +1081,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, luks->header.key_slots[i].key_offset = (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / QCRYPTO_BLOCK_LUKS_SECTOR_SIZE) + - (ROUND_UP(((splitkeylen + (QCRYPTO_BLOCK_LUKS_SECTOR_SIZE - 1)) / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE), + (ROUND_UP(DIV_ROUND_UP(splitkeylen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE), (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) * i); } @@ -1182,8 +1181,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, luks->header.payload_offset = (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / QCRYPTO_BLOCK_LUKS_SECTOR_SIZE) + - (ROUND_UP(((splitkeylen + (QCRYPTO_BLOCK_LUKS_SECTOR_SIZE - 1)) / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE), + (ROUND_UP(DIV_ROUND_UP(splitkeylen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE), (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) * QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS); diff --git a/docs/multi-thread-compression.txt b/docs/multi-thread-compression.txt index 3d477c3bd2..d0caaf7b3b 100644 --- a/docs/multi-thread-compression.txt +++ b/docs/multi-thread-compression.txt @@ -110,7 +110,7 @@ Usage ===== 1. Verify both the source and destination QEMU are able to support the multiple thread compression migration: - {qemu} info_migrate_capabilities + {qemu} info migrate_capabilities {qemu} ... compress: off ... 2. Activate compression on the source: diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index d7d6987821..eff207502f 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -322,7 +322,7 @@ enum. The value for each branch can be of any type. A flat union definition avoids nesting on the wire, and specifies a set of common members that occur in all variants of the union. The -'base' key must specifiy either a type name (the type must be a +'base' key must specify either a type name (the type must be a struct, not a union), or a dictionary representing an anonymous type. All branches of the union must be complex types, and the top-level members of the union dictionary on the wire will be combination of diff --git a/docs/throttle.txt b/docs/throttle.txt index 06ed9b3943..26d4d5107f 100644 --- a/docs/throttle.txt +++ b/docs/throttle.txt @@ -39,7 +39,7 @@ the parameters for both cases: | throttling.bps-write | bps_wr | |-----------------------+-----------------------| -It is possible to set limits for both IOPS and bps and the same time, +It is possible to set limits for both IOPS and bps at the same time, and for each case we can decide whether to have separate read and write limits or not, but note that if iops-total is set then neither iops-read nor iops-write can be set. The same applies to bps-total and @@ -235,7 +235,7 @@ consider the following values: - Water leaks from the bucket at a rate of 100 IOPS. - Water can be added to the bucket at a rate of 2000 IOPS. - The size of the bucket is 2000 x 60 = 120000 - - If 'iops-total-max-length' is unset then the bucket size is 100. + - If 'iops-total-max' is unset then the bucket size is 100 x 60. The bucket is initially empty, therefore water can be added until it's full at a rate of 2000 IOPS (the burst rate). Once the bucket is full diff --git a/fsdev/9p-iov-marshal.c b/fsdev/9p-iov-marshal.c index fb40bdf0d5..fce1ee9e55 100644 --- a/fsdev/9p-iov-marshal.c +++ b/fsdev/9p-iov-marshal.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <glib/gprintf.h> #include <utime.h> #include <sys/uio.h> diff --git a/fsdev/9p-marshal.c b/fsdev/9p-marshal.c index 183d3667c6..f56ef0e60c 100644 --- a/fsdev/9p-marshal.c +++ b/fsdev/9p-marshal.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <glib/gprintf.h> #include <dirent.h> #include <utime.h> diff --git a/fsdev/virtfs-proxy-helper.texi b/fsdev/virtfs-proxy-helper.texi index 6eb2d5096a..f4cbb60623 100644 --- a/fsdev/virtfs-proxy-helper.texi +++ b/fsdev/virtfs-proxy-helper.texi @@ -15,7 +15,7 @@ provide access to files beyond 9p export path. 2) Running QEMU with root privilege could be a security issue. -To overcome above issues, following approach is used: A new filesytem +To overcome above issues, following approach is used: A new filesystem type 'proxy' is introduced. Proxy FS uses chroot + socket combination for securing the vulnerability known with following symbolic links. Intention of adding a new filesystem type is to allow qemu to run @@ -1618,7 +1618,7 @@ static int gdbserver_open(int port) close(fd); return -1; } - ret = listen(fd, 0); + ret = listen(fd, 1); if (ret < 0) { perror("listen"); close(fd); diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 46d787627a..d2030fdf56 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -4,7 +4,6 @@ #include <dirent.h> #include <utime.h> #include <sys/resource.h> -#include <glib.h> #include "fsdev/file-op-9p.h" #include "fsdev/9p-iov-marshal.h" #include "qemu/thread.h" diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs index faee86c5c4..66bd72702b 100644 --- a/hw/acpi/Makefile.objs +++ b/hw/acpi/Makefile.objs @@ -1,6 +1,6 @@ common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o -common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o cpu_hotplug_acpi_table.o +common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o common-obj-$(CONFIG_ACPI) += acpi_interface.o diff --git a/hw/acpi/acpi_interface.c b/hw/acpi/acpi_interface.c index d82131326a..6583917b8e 100644 --- a/hw/acpi/acpi_interface.c +++ b/hw/acpi/acpi_interface.c @@ -2,6 +2,15 @@ #include "hw/acpi/acpi_dev_interface.h" #include "qemu/module.h" +void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event) +{ + AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(dev); + if (adevc->send_event) { + AcpiDeviceIf *adev = ACPI_DEVICE_IF(dev); + adevc->send_event(adev, event); + } +} + static void register_types(void) { static const TypeInfo acpi_dev_if_info = { diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index cedb74e7cf..123160a94e 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -24,7 +24,6 @@ #include "hw/acpi/aml-build.h" #include "qemu/bswap.h" #include "qemu/bitops.h" -#include "hw/acpi/bios-linker-loader.h" static GArray *build_alloc_array(void) { @@ -406,6 +405,15 @@ Aml *aml_return(Aml *val) return var; } +/* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */ +Aml *aml_debug(void) +{ + Aml *var = aml_alloc(); + build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */ + build_append_byte(var->buf, 0x31); /* DebugOp */ + return var; +} + /* * ACPI 1.0b: 16.2.3 Data Objects Encoding: * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp @@ -1407,6 +1415,14 @@ Aml *aml_unicode(const char *str) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */ +Aml *aml_refof(Aml *arg) +{ + Aml *var = aml_opcode(0x71 /* RefOfOp */); + aml_append(var, arg); + return var; +} + /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */ Aml *aml_derefof(Aml *arg) { @@ -1473,10 +1489,12 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target) } void -build_header(GArray *linker, GArray *table_data, +build_header(BIOSLinker *linker, GArray *table_data, AcpiTableHeader *h, const char *sig, int len, uint8_t rev, const char *oem_id, const char *oem_table_id) { + unsigned tbl_offset = (char *)h - table_data->data; + unsigned checksum_offset = (char *)&h->checksum - table_data->data; memcpy(&h->signature, sig, 4); h->length = cpu_to_le32(len); h->revision = rev; @@ -1497,10 +1515,9 @@ build_header(GArray *linker, GArray *table_data, h->oem_revision = cpu_to_le32(1); memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4); h->asl_compiler_revision = cpu_to_le32(1); - h->checksum = 0; /* Checksum to be filled in by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE, - table_data, h, len, &h->checksum); + tbl_offset, len, checksum_offset); } void *acpi_data_push(GArray *table_data, unsigned size) @@ -1518,7 +1535,7 @@ unsigned acpi_data_len(GArray *table) void acpi_add_table(GArray *table_offsets, GArray *table_data) { - uint32_t offset = cpu_to_le32(table_data->len); + uint32_t offset = table_data->len; g_array_append_val(table_offsets, offset); } @@ -1532,8 +1549,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables) void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) { - void *linker_data = bios_linker_loader_cleanup(tables->linker); - g_free(linker_data); + bios_linker_loader_cleanup(tables->linker); g_array_free(tables->rsdp, true); g_array_free(tables->table_data, true); g_array_free(tables->tcpalog, mfre); @@ -1541,24 +1557,26 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) /* Build rsdt table */ void -build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets, +build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, const char *oem_id, const char *oem_table_id) { - AcpiRsdtDescriptorRev1 *rsdt; - size_t rsdt_len; int i; - const int table_data_len = (sizeof(uint32_t) * table_offsets->len); + unsigned rsdt_entries_offset; + AcpiRsdtDescriptorRev1 *rsdt; + const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len); + const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]); + const size_t rsdt_len = sizeof(*rsdt) + table_data_len; - rsdt_len = sizeof(*rsdt) + table_data_len; rsdt = acpi_data_push(table_data, rsdt_len); - memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len); + rsdt_entries_offset = (char *)rsdt->table_offset_entry - table_data->data; for (i = 0; i < table_offsets->len; ++i) { + uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i); + uint32_t rsdt_entry_offset = rsdt_entries_offset + rsdt_entry_size * i; + /* rsdt->table_offset_entry to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, - ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &rsdt->table_offset_entry[i], - sizeof(uint32_t)); + ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size, + ACPI_BUILD_TABLE_FILE, ref_tbl_offset); } build_header(linker, table_data, (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id); diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c index 5153ab151b..d963ebe241 100644 --- a/hw/acpi/bios-linker-loader.c +++ b/hw/acpi/bios-linker-loader.c @@ -96,134 +96,170 @@ enum { }; /* - * bios_linker_loader_init: allocate a new linker file blob array. + * BiosLinkerFileEntry: + * + * An internal type used for book-keeping file entries + */ +typedef struct BiosLinkerFileEntry { + char *name; /* file name */ + GArray *blob; /* data accosiated with @name */ +} BiosLinkerFileEntry; + +/* + * bios_linker_loader_init: allocate a new linker object instance. * * After initialization, linker commands can be added, and will - * be stored in the array. + * be stored in the linker.cmd_blob array. */ -GArray *bios_linker_loader_init(void) +BIOSLinker *bios_linker_loader_init(void) { - return g_array_new(false, true /* clear */, 1); + BIOSLinker *linker = g_new(BIOSLinker, 1); + + linker->cmd_blob = g_array_new(false, true /* clear */, 1); + linker->file_list = g_array_new(false, true /* clear */, + sizeof(BiosLinkerFileEntry)); + return linker; } -/* Free linker wrapper and return the linker array. */ -void *bios_linker_loader_cleanup(GArray *linker) +/* Free linker wrapper */ +void bios_linker_loader_cleanup(BIOSLinker *linker) { - return g_array_free(linker, false); + int i; + BiosLinkerFileEntry *entry; + + g_array_free(linker->cmd_blob, true); + + for (i = 0; i < linker->file_list->len; i++) { + entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i); + g_free(entry->name); + } + g_array_free(linker->file_list, true); + g_free(linker); +} + +static const BiosLinkerFileEntry * +bios_linker_find_file(const BIOSLinker *linker, const char *name) +{ + int i; + BiosLinkerFileEntry *entry; + + for (i = 0; i < linker->file_list->len; i++) { + entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i); + if (!strcmp(entry->name, name)) { + return entry; + } + } + return NULL; } /* * bios_linker_loader_alloc: ask guest to load file into guest memory. * - * @linker: linker file blob array - * @file: file to be loaded + * @linker: linker object instance + * @file_name: name of the file blob to be loaded + * @file_blob: pointer to blob corresponding to @file_name * @alloc_align: required minimal alignment in bytes. Must be a power of 2. * @alloc_fseg: request allocation in FSEG zone (useful for the RSDP ACPI table) * * Note: this command must precede any other linker command using this file. */ -void bios_linker_loader_alloc(GArray *linker, - const char *file, +void bios_linker_loader_alloc(BIOSLinker *linker, + const char *file_name, + GArray *file_blob, uint32_t alloc_align, bool alloc_fseg) { BiosLinkerLoaderEntry entry; + BiosLinkerFileEntry file = { g_strdup(file_name), file_blob}; assert(!(alloc_align & (alloc_align - 1))); + assert(!bios_linker_find_file(linker, file_name)); + g_array_append_val(linker->file_list, file); + memset(&entry, 0, sizeof entry); - strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1); + strncpy(entry.alloc.file, file_name, sizeof entry.alloc.file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE); entry.alloc.align = cpu_to_le32(alloc_align); entry.alloc.zone = alloc_fseg ? BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG : BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH; /* Alloc entries must come first, so prepend them */ - g_array_prepend_vals(linker, &entry, sizeof entry); + g_array_prepend_vals(linker->cmd_blob, &entry, sizeof entry); } /* - * bios_linker_loader_add_checksum: ask guest to add checksum of file data - * into (same) file at the specified pointer. + * bios_linker_loader_add_checksum: ask guest to add checksum of ACPI + * table in the specified file at the specified offset. * * Checksum calculation simply sums -X for each byte X in the range * using 8-bit math (i.e. ACPI checksum). * - * @linker: linker file blob array + * @linker: linker object instance * @file: file that includes the checksum to be calculated * and the data to be checksummed - * @table: @file blob contents - * @start, @size: range of data to checksum - * @checksum: location of the checksum to be patched within file blob - * - * Notes: - * - checksum byte initial value must have been pushed into @table - * and reside at address @checksum. - * - @size bytes must have been pushed into @table and reside at address - * @start. - * - Guest calculates checksum of specified range of data, result is added to - * initial value at @checksum into copy of @file in Guest memory. - * - Range might include the checksum itself. - * - To avoid confusion, caller must always put 0x0 at @checksum. - * - @file must be loaded into Guest memory using bios_linker_loader_alloc + * @start_offset, @size: range of data in the file to checksum, + * relative to the start of file blob + * @checksum_offset: location of the checksum to be patched within file blob, + * relative to the start of file blob */ -void bios_linker_loader_add_checksum(GArray *linker, const char *file, - GArray *table, - void *start, unsigned size, - uint8_t *checksum) +void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file_name, + unsigned start_offset, unsigned size, + unsigned checksum_offset) { BiosLinkerLoaderEntry entry; - ptrdiff_t checksum_offset = (gchar *)checksum - table->data; - ptrdiff_t start_offset = (gchar *)start - table->data; + const BiosLinkerFileEntry *file = bios_linker_find_file(linker, file_name); - assert(checksum_offset >= 0); - assert(start_offset >= 0); - assert(checksum_offset + 1 <= table->len); - assert(start_offset + size <= table->len); - assert(*checksum == 0x0); + assert(file); + assert(start_offset < file->blob->len); + assert(start_offset + size <= file->blob->len); + assert(checksum_offset >= start_offset); + assert(checksum_offset + 1 <= start_offset + size); + *(file->blob->data + checksum_offset) = 0; memset(&entry, 0, sizeof entry); - strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1); + strncpy(entry.cksum.file, file_name, sizeof entry.cksum.file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM); entry.cksum.offset = cpu_to_le32(checksum_offset); entry.cksum.start = cpu_to_le32(start_offset); entry.cksum.length = cpu_to_le32(size); - g_array_append_vals(linker, &entry, sizeof entry); + g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); } /* - * bios_linker_loader_add_pointer: ask guest to add address of source file - * into destination file at the specified pointer. + * bios_linker_loader_add_pointer: ask guest to patch address in + * destination file with a pointer to source file * - * @linker: linker file blob array + * @linker: linker object instance * @dest_file: destination file that must be changed + * @dst_patched_offset: location within destination file blob to be patched + * with the pointer to @src_file+@src_offset (i.e. source + * blob allocated in guest memory + @src_offset), in bytes + * @dst_patched_offset_size: size of the pointer to be patched + * at @dst_patched_offset in @dest_file blob, in bytes * @src_file: source file who's address must be taken - * @table: @dest_file blob contents array - * @pointer: location of the pointer to be patched within destination file blob - * @pointer_size: size of pointer to be patched, in bytes - * - * Notes: - * - @pointer_size bytes must have been pushed into @table - * and reside at address @pointer. - * - Guest address is added to initial value at @pointer - * into copy of @dest_file in Guest memory. - * e.g. to get start of src_file in guest memory, put 0x0 there - * to get address of a field at offset 0x10 in src_file, put 0x10 there - * - Both @dest_file and @src_file must be - * loaded into Guest memory using bios_linker_loader_alloc + * @src_offset: location within source file blob to which + * @dest_file+@dst_patched_offset will point to after + * firmware's executed ADD_POINTER command */ -void bios_linker_loader_add_pointer(GArray *linker, +void bios_linker_loader_add_pointer(BIOSLinker *linker, const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, const char *src_file, - GArray *table, void *pointer, - uint8_t pointer_size) + uint32_t src_offset) { + uint64_t le_src_offset; BiosLinkerLoaderEntry entry; - ptrdiff_t offset = (gchar *)pointer - table->data; + const BiosLinkerFileEntry *dst_file = + bios_linker_find_file(linker, dest_file); + const BiosLinkerFileEntry *source_file = + bios_linker_find_file(linker, src_file); - assert(offset >= 0); - assert(offset + pointer_size <= table->len); + assert(dst_patched_offset < dst_file->blob->len); + assert(dst_patched_offset + dst_patched_size <= dst_file->blob->len); + assert(src_offset < source_file->blob->len); memset(&entry, 0, sizeof entry); strncpy(entry.pointer.dest_file, dest_file, @@ -231,10 +267,14 @@ void bios_linker_loader_add_pointer(GArray *linker, strncpy(entry.pointer.src_file, src_file, sizeof entry.pointer.src_file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER); - entry.pointer.offset = cpu_to_le32(offset); - entry.pointer.size = pointer_size; - assert(pointer_size == 1 || pointer_size == 2 || - pointer_size == 4 || pointer_size == 8); + entry.pointer.offset = cpu_to_le32(dst_patched_offset); + entry.pointer.size = dst_patched_size; + assert(dst_patched_size == 1 || dst_patched_size == 2 || + dst_patched_size == 4 || dst_patched_size == 8); + + le_src_offset = cpu_to_le64(src_offset); + memcpy(dst_file->blob->data + dst_patched_offset, + &le_src_offset, dst_patched_size); - g_array_append_vals(linker, &entry, sizeof entry); + g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); } diff --git a/hw/acpi/core.c b/hw/acpi/core.c index 1ffd155c11..d24b9a98c8 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -698,7 +698,7 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr) } void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq, - AcpiGPEStatusBits status) + AcpiEventStatusBits status) { ar->gpe.sts[0] |= status; acpi_update_sci(ar, irq); diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 4d86743fde..fe75bd9ac9 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -14,6 +14,14 @@ #include "hw/acpi/cpu_hotplug.h" #include "qapi/error.h" #include "qom/cpu.h" +#include "hw/i386/pc.h" + +#define CPU_EJECT_METHOD "CPEJ" +#define CPU_MAT_METHOD "CPMA" +#define CPU_ON_BITMAP "CPON" +#define CPU_STATUS_METHOD "CPST" +#define CPU_STATUS_MAP "PRS" +#define CPU_SCAN_METHOD "PRSC" static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) { @@ -54,19 +62,18 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu, g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); } -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, - AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp) { acpi_set_cpu_present_bit(g, CPU(dev), errp); if (*errp != NULL) { return; } - - acpi_send_gpe_event(ar, irq, ACPI_CPU_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_CPU_HOTPLUG_STATUS); } -void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, - AcpiCpuHotplug *gpe_cpu, uint16_t base) +void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base) { CPUState *cpu; @@ -77,3 +84,230 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN); memory_region_add_subregion(parent, base, &gpe_cpu->io); } + +void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine, + uint16_t io_base) +{ + Aml *dev; + Aml *crs; + Aml *pkg; + Aml *field; + Aml *method; + Aml *if_ctx; + Aml *else_ctx; + int i, apic_idx; + Aml *sb_scope = aml_scope("_SB"); + uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}; + Aml *cpu_id = aml_arg(1); + Aml *apic_id = aml_arg(0); + Aml *cpu_on = aml_local(0); + Aml *madt = aml_local(1); + Aml *cpus_map = aml_name(CPU_ON_BITMAP); + Aml *zero = aml_int(0); + Aml *one = aml_int(1); + MachineClass *mc = MACHINE_GET_CLASS(machine); + CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); + PCMachineState *pcms = PC_MACHINE(machine); + + /* + * _MAT method - creates an madt apic buffer + * apic_id = Arg0 = Local APIC ID + * cpu_id = Arg1 = Processor ID + * cpu_on = Local0 = CPON flag for this cpu + * madt = Local1 = Buffer (in madt apic form) to return + */ + method = aml_method(CPU_MAT_METHOD, 2, AML_NOTSERIALIZED); + aml_append(method, + aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on)); + aml_append(method, + aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt)); + /* Update the processor id, lapic id, and enable/disable status */ + aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2)))); + aml_append(method, aml_store(apic_id, aml_index(madt, aml_int(3)))); + aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4)))); + aml_append(method, aml_return(madt)); + aml_append(sb_scope, method); + + /* + * _STA method - return ON status of cpu + * apic_id = Arg0 = Local APIC ID + * cpu_on = Local0 = CPON flag for this cpu + */ + method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED); + aml_append(method, + aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on)); + if_ctx = aml_if(cpu_on); + { + aml_append(if_ctx, aml_return(aml_int(0xF))); + } + aml_append(method, if_ctx); + else_ctx = aml_else(); + { + aml_append(else_ctx, aml_return(zero)); + } + aml_append(method, else_ctx); + aml_append(sb_scope, method); + + method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED); + aml_append(method, aml_sleep(200)); + aml_append(sb_scope, method); + + method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED); + { + Aml *while_ctx, *if_ctx2, *else_ctx2; + Aml *bus_check_evt = aml_int(1); + Aml *remove_evt = aml_int(3); + Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */ + Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */ + Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */ + Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */ + Aml *status = aml_local(3); /* Local3 = active state for cpu */ + + aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map)); + aml_append(method, aml_store(zero, byte)); + aml_append(method, aml_store(zero, idx)); + + /* While (idx < SizeOf(CPON)) */ + while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map))); + aml_append(while_ctx, + aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on)); + + if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL)); + { + /* Shift down previously read bitmap byte */ + aml_append(if_ctx, aml_shiftright(byte, one, byte)); + } + aml_append(while_ctx, if_ctx); + + else_ctx = aml_else(); + { + /* Read next byte from cpu bitmap */ + aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map, + aml_shiftright(idx, aml_int(3), NULL))), byte)); + } + aml_append(while_ctx, else_ctx); + + aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status)); + if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status))); + { + /* State change - update CPON with new state */ + aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx))); + if_ctx2 = aml_if(aml_equal(status, one)); + { + aml_append(if_ctx2, + aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt)); + } + aml_append(if_ctx, if_ctx2); + else_ctx2 = aml_else(); + { + aml_append(else_ctx2, + aml_call2(AML_NOTIFY_METHOD, idx, remove_evt)); + } + } + aml_append(if_ctx, else_ctx2); + aml_append(while_ctx, if_ctx); + + aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */ + aml_append(method, while_ctx); + } + aml_append(sb_scope, method); + + /* The current AML generator can cover the APIC ID range [0..255], + * inclusive, for VCPU hotplug. */ + QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256); + g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT); + + /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */ + dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06"))); + aml_append(dev, + aml_name_decl("_UID", aml_string("CPU Hotplug resources")) + ); + /* device present, functioning, decoding, not shown in UI */ + aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); + crs = aml_resource_template(); + aml_append(crs, + aml_io(AML_DECODE16, io_base, io_base, 1, ACPI_GPE_PROC_LEN) + ); + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(sb_scope, dev); + /* declare CPU hotplug MMIO region and PRS field to access it */ + aml_append(sb_scope, aml_operation_region( + "PRST", AML_SYSTEM_IO, aml_int(io_base), ACPI_GPE_PROC_LEN)); + field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); + aml_append(field, aml_named_field("PRS", 256)); + aml_append(sb_scope, field); + + /* build Processor object for each processor */ + for (i = 0; i < apic_ids->len; i++) { + int apic_id = apic_ids->cpus[i].arch_id; + + assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT); + + dev = aml_processor(i, 0, 0, "CP%.02X", apic_id); + + method = aml_method("_MAT", 0, AML_NOTSERIALIZED); + aml_append(method, + aml_return(aml_call2(CPU_MAT_METHOD, aml_int(apic_id), aml_int(i)) + )); + aml_append(dev, method); + + method = aml_method("_STA", 0, AML_NOTSERIALIZED); + aml_append(method, + aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id)))); + aml_append(dev, method); + + method = aml_method("_EJ0", 1, AML_NOTSERIALIZED); + aml_append(method, + aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id), + aml_arg(0))) + ); + aml_append(dev, method); + + aml_append(sb_scope, dev); + } + + /* build this code: + * Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...} + */ + /* Arg0 = APIC ID */ + method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED); + for (i = 0; i < apic_ids->len; i++) { + int apic_id = apic_ids->cpus[i].arch_id; + + if_ctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id))); + aml_append(if_ctx, + aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1)) + ); + aml_append(method, if_ctx); + } + aml_append(sb_scope, method); + + /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" + * + * Note: The ability to create variable-sized packages was first + * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages + * ith up to 255 elements. Windows guests up to win2k8 fail when + * VarPackageOp is used. + */ + pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) : + aml_varpackage(pcms->apic_id_limit); + + for (i = 0, apic_idx = 0; i < apic_ids->len; i++) { + int apic_id = apic_ids->cpus[i].arch_id; + + for (; apic_idx < apic_id; apic_idx++) { + aml_append(pkg, aml_int(0)); + } + aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0)); + apic_idx = apic_id + 1; + } + aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg)); + g_free(apic_ids); + + aml_append(ctx, sb_scope); + + method = aml_method("\\_GPE._E02", 0, AML_NOTSERIALIZED); + aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); + aml_append(ctx, method); +} diff --git a/hw/acpi/cpu_hotplug_acpi_table.c b/hw/acpi/cpu_hotplug_acpi_table.c deleted file mode 100644 index 97bb1092a2..0000000000 --- a/hw/acpi/cpu_hotplug_acpi_table.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "qemu/osdep.h" -#include "hw/acpi/cpu_hotplug.h" - -void build_cpu_hotplug_aml(Aml *ctx) -{ - Aml *method; - Aml *if_ctx; - Aml *else_ctx; - Aml *sb_scope = aml_scope("_SB"); - uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}; - Aml *cpu_id = aml_arg(0); - Aml *cpu_on = aml_local(0); - Aml *madt = aml_local(1); - Aml *cpus_map = aml_name(CPU_ON_BITMAP); - Aml *zero = aml_int(0); - Aml *one = aml_int(1); - - /* - * _MAT method - creates an madt apic buffer - * cpu_id = Arg0 = Processor ID = Local APIC ID - * cpu_on = Local0 = CPON flag for this cpu - * madt = Local1 = Buffer (in madt apic form) to return - */ - method = aml_method(CPU_MAT_METHOD, 1, AML_NOTSERIALIZED); - aml_append(method, - aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on)); - aml_append(method, - aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt)); - /* Update the processor id, lapic id, and enable/disable status */ - aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2)))); - aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(3)))); - aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4)))); - aml_append(method, aml_return(madt)); - aml_append(sb_scope, method); - - /* - * _STA method - return ON status of cpu - * cpu_id = Arg0 = Processor ID = Local APIC ID - * cpu_on = Local0 = CPON flag for this cpu - */ - method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED); - aml_append(method, - aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on)); - if_ctx = aml_if(cpu_on); - { - aml_append(if_ctx, aml_return(aml_int(0xF))); - } - aml_append(method, if_ctx); - else_ctx = aml_else(); - { - aml_append(else_ctx, aml_return(zero)); - } - aml_append(method, else_ctx); - aml_append(sb_scope, method); - - method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED); - aml_append(method, aml_sleep(200)); - aml_append(sb_scope, method); - - method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED); - { - Aml *while_ctx, *if_ctx2, *else_ctx2; - Aml *bus_check_evt = aml_int(1); - Aml *remove_evt = aml_int(3); - Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */ - Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */ - Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */ - Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */ - Aml *status = aml_local(3); /* Local3 = active state for cpu */ - - aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map)); - aml_append(method, aml_store(zero, byte)); - aml_append(method, aml_store(zero, idx)); - - /* While (idx < SizeOf(CPON)) */ - while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map))); - aml_append(while_ctx, - aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on)); - - if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL)); - { - /* Shift down previously read bitmap byte */ - aml_append(if_ctx, aml_shiftright(byte, one, byte)); - } - aml_append(while_ctx, if_ctx); - - else_ctx = aml_else(); - { - /* Read next byte from cpu bitmap */ - aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map, - aml_shiftright(idx, aml_int(3), NULL))), byte)); - } - aml_append(while_ctx, else_ctx); - - aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status)); - if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status))); - { - /* State change - update CPON with new state */ - aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx))); - if_ctx2 = aml_if(aml_equal(status, one)); - { - aml_append(if_ctx2, - aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt)); - } - aml_append(if_ctx, if_ctx2); - else_ctx2 = aml_else(); - { - aml_append(else_ctx2, - aml_call2(AML_NOTIFY_METHOD, idx, remove_evt)); - } - } - aml_append(if_ctx, else_ctx2); - aml_append(while_ctx, if_ctx); - - aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */ - aml_append(method, while_ctx); - } - aml_append(sb_scope, method); - - aml_append(ctx, sb_scope); -} diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 27e978f5fd..853c9c4eb7 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -273,8 +273,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, pm->powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(&pm->powerdown_notifier); - acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), - &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); + legacy_acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), + OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); if (pm->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), @@ -430,39 +430,47 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) NULL); } -void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) +void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) { - if (pm->acpi_memory_hotplug.is_enabled && + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + + if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug, + acpi_memory_plug_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { - acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp); + legacy_acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.gpe_cpu, dev, errp); } else { error_setg(errp, "acpi: device plug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); } } -void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, - Error **errp) +void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) { - if (pm->acpi_memory_hotplug.is_enabled && + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + + if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq, - &pm->acpi_memory_hotplug, dev, errp); + acpi_memory_unplug_request_cb(hotplug_dev, + &lpc->pm.acpi_memory_hotplug, dev, + errp); } else { error_setg(errp, "acpi: device unplug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); } } -void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, +void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - if (pm->acpi_memory_hotplug.is_enabled && + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + + if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp); + acpi_memory_unplug_cb(&lpc->pm.acpi_memory_hotplug, dev, errp); } else { error_setg(errp, "acpi: device unplug for not supported device" " type: %s", object_get_typename(OBJECT(dev))); diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index f65a3a21ef..ec4e64b361 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -228,7 +228,7 @@ acpi_memory_slot_status(MemHotplugState *mem_st, return &mem_st->devs[slot]; } -void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, +void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { MemStatus *mdev; @@ -247,13 +247,11 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, mdev->is_enabled = true; if (dev->hotplugged) { mdev->is_inserting = true; - - /* do ACPI magic */ - acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); } } -void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, +void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { @@ -265,9 +263,7 @@ void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, } mdev->is_removing = true; - - /* Do ACPI magic */ - acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); } void acpi_memory_unplug_cb(MemHotplugState *mem_st, diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index fb925dccae..b4c22627df 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -353,7 +353,7 @@ static GArray *nvdimm_build_device_structure(GSList *device_list) } static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets, - GArray *table_data, GArray *linker) + GArray *table_data, BIOSLinker *linker) { GArray *structures = nvdimm_build_device_structure(device_list); unsigned int header; @@ -579,7 +579,8 @@ static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev) } static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, - GArray *table_data, GArray *linker) + GArray *table_data, BIOSLinker *linker, + GArray *dsm_dma_arrea) { Aml *ssdt, *sb_scope, *dev, *field; int mem_addr_offset, nvdimm_ssdt; @@ -678,12 +679,12 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, mem_addr_offset = build_append_named_dword(table_data, NVDIMM_ACPI_MEM_ADDR); - bios_linker_loader_alloc(linker, NVDIMM_DSM_MEM_FILE, sizeof(NvdimmDsmIn), - false /* high memory */); - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - NVDIMM_DSM_MEM_FILE, table_data, - table_data->data + mem_addr_offset, - sizeof(uint32_t)); + bios_linker_loader_alloc(linker, + NVDIMM_DSM_MEM_FILE, dsm_dma_arrea, + sizeof(NvdimmDsmIn), false /* high memory */); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, mem_addr_offset, sizeof(uint32_t), + NVDIMM_DSM_MEM_FILE, 0); build_header(linker, table_data, (void *)(table_data->data + nvdimm_ssdt), "SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM"); @@ -691,7 +692,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, } void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, - GArray *linker) + BIOSLinker *linker, GArray *dsm_dma_arrea) { GSList *device_list; @@ -701,6 +702,7 @@ void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, return; } nvdimm_build_nfit(device_list, table_offsets, table_data, linker); - nvdimm_build_ssdt(device_list, table_offsets, table_data, linker); + nvdimm_build_ssdt(device_list, table_offsets, table_data, linker, + dsm_dma_arrea); g_slist_free(device_list); } diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 71f4c4e14b..d957d1e30d 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -182,7 +182,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s) acpi_pcihp_update(s); } -void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, +void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, DeviceState *dev, Error **errp) { PCIDevice *pdev = PCI_DEVICE(dev); @@ -202,11 +202,10 @@ void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, } s->acpi_pcihp_pci_status[bsel].up |= (1U << slot); - - acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } -void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, +void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, DeviceState *dev, Error **errp) { PCIDevice *pdev = PCI_DEVICE(dev); @@ -219,8 +218,7 @@ void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, } s->acpi_pcihp_pci_status[bsel].down |= (1U << slot); - - acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b3e3bb306a..c48cb1b91a 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -348,12 +348,11 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev, if (s->acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_plug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, dev, errp); + acpi_memory_plug_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { - acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, - errp); + acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { - acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp); + legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp); } else { error_setg(errp, "acpi: device plug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -367,10 +366,10 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, if (s->acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_unplug_request_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, + acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { - acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, + acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp); } else { error_setg(errp, "acpi: device unplug request for not supported device" @@ -571,8 +570,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent, s->use_acpi_pci_hotplug); - acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu, - PIIX4_CPU_HOTPLUG_IO_BASE); + legacy_acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu, + PIIX4_CPU_HOTPLUG_IO_BASE); if (s->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug); @@ -586,6 +585,13 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) acpi_memory_ospm_status(&s->acpi_memory_hotplug, list); } +static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) +{ + PIIX4PMState *s = PIIX4_PM(adev); + + acpi_send_gpe_event(&s->ar, s->irq, ev); +} + static Property piix4_pm_properties[] = { DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), @@ -624,6 +630,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) hc->unplug_request = piix4_device_unplug_request_cb; hc->unplug = piix4_device_unplug_cb; adevc->ospm_status = piix4_ospm_status; + adevc->send_event = piix4_send_gpe; } static const TypeInfo piix4_pm_info = { diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 83a54203b8..735ab864a0 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -354,11 +354,14 @@ static void acpi_dsdt_add_power_button(Aml *scope) /* RSDP */ static GArray * -build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); + unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address); + unsigned rsdt_pa_offset = + (char *)&rsdp->rsdt_physical_address - rsdp_table->data; - bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16, + bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16, true /* fseg memory */); memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature)); @@ -366,24 +369,21 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) rsdp->length = cpu_to_le32(sizeof(*rsdp)); rsdp->revision = 0x02; - /* Point to RSDT */ - rsdp->rsdt_physical_address = cpu_to_le32(rsdt); /* Address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, - ACPI_BUILD_TABLE_FILE, - rsdp_table, &rsdp->rsdt_physical_address, - sizeof rsdp->rsdt_physical_address); - rsdp->checksum = 0; + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size, + ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset); + /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, - rsdp_table, rsdp, sizeof *rsdp, - &rsdp->checksum); + (char *)rsdp - rsdp_table->data, sizeof *rsdp, + (char *)&rsdp->checksum - rsdp_table->data); return rsdp_table; } static void -build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { AcpiSerialPortConsoleRedirection *spcr; const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART]; @@ -416,7 +416,7 @@ build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) } static void -build_srat(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { AcpiSystemResourceAffinityTable *srat; AcpiSratProcessorGiccAffinity *core; @@ -456,13 +456,12 @@ build_srat(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) mem_base += numa_info[i].node_mem; } - build_header(linker, table_data, - (void *)(table_data->data + srat_start), "SRAT", + build_header(linker, table_data, (void *)srat, "SRAT", table_data->len - srat_start, 3, NULL, NULL); } static void -build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { AcpiTableMcfg *mcfg; const MemMapEntry *memmap = guest_info->memmap; @@ -482,7 +481,7 @@ build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) /* GTDT */ static void -build_gtdt(GArray *table_data, GArray *linker) +build_gtdt(GArray *table_data, BIOSLinker *linker) { int gtdt_start = table_data->len; AcpiGenericTimerTable *gtdt; @@ -508,7 +507,7 @@ build_gtdt(GArray *table_data, GArray *linker) /* MADT */ static void -build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { int madt_start = table_data->len; const MemMapEntry *memmap = guest_info->memmap; @@ -567,9 +566,10 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) /* FADT */ static void -build_fadt(GArray *table_data, GArray *linker, unsigned dsdt) +build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset) { AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt)); + unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data; /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */ fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI); @@ -579,12 +579,10 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt) /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */ fadt->minor_revision = 0x1; - fadt->dsdt = cpu_to_le32(dsdt); /* DSDT address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &fadt->dsdt, - sizeof fadt->dsdt); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt), + ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset); build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL); @@ -592,7 +590,7 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt) /* DSDT */ static void -build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { Aml *scope, *dsdt; const MemMapEntry *memmap = guest_info->memmap; @@ -652,7 +650,8 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables) table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); - bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE, + bios_linker_loader_alloc(tables->linker, + ACPI_BUILD_TABLE_FILE, tables_blob, 64, false /* high memory */); /* @@ -731,7 +730,7 @@ static void virt_acpi_build_update(void *build_opaque) acpi_ram_update(build_state->table_mr, tables.table_data); acpi_ram_update(build_state->rsdp_mr, tables.rsdp); - acpi_ram_update(build_state->linker_mr, tables.linker); + acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); acpi_build_tables_cleanup(&tables, true); @@ -789,7 +788,8 @@ void virt_acpi_setup(VirtGuestInfo *guest_info) assert(build_state->table_mr != NULL); build_state->linker_mr = - acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); + acpi_add_rom_blob(build_state, tables.linker->cmd_blob, + "etc/table-loader", 0); fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); diff --git a/hw/audio/gus.c b/hw/audio/gus.c index 9dd6947bee..6c02646773 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -144,7 +144,7 @@ static void GUS_callback (void *opaque, int free) s->left = samples; reset: - gus_irqgen (&s->emu, muldiv64 (net, 1000000, s->freq)); + gus_irqgen (&s->emu, (uint64_t)net * 1000000 / s->freq); } int GUS_irqrequest (GUSEmuState *emu, int hwirq, int n) diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index f9afc8edad..d2599604d1 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -35,7 +35,7 @@ #define PCSPK_BUF_LEN 1792 #define PCSPK_SAMPLE_RATE 32000 #define PCSPK_MAX_FREQ (PCSPK_SAMPLE_RATE >> 1) -#define PCSPK_MIN_COUNT ((PIT_FREQ + PCSPK_MAX_FREQ - 1) / PCSPK_MAX_FREQ) +#define PCSPK_MIN_COUNT DIV_ROUND_UP(PIT_FREQ, PCSPK_MAX_FREQ) #define PC_SPEAKER(obj) OBJECT_CHECK(PCSpkState, (obj), TYPE_PC_SPEAKER) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 3cb97c9a29..2073f9a270 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -37,8 +37,6 @@ struct VirtIOBlockDataPlane { EventNotifier *guest_notifier; /* irq */ QEMUBH *bh; /* bh for guest notification */ - Notifier insert_notifier, remove_notifier; - /* Note that these EventNotifiers are assigned by value. This is * fine as long as you do not call event_notifier_cleanup on them * (because you don't own the file descriptor or handle; you just @@ -46,9 +44,6 @@ struct VirtIOBlockDataPlane { */ IOThread *iothread; AioContext *ctx; - - /* Operation blocker on BDS */ - Error *blocker; }; /* Raise an interrupt to signal guest, if necessary */ @@ -68,54 +63,6 @@ static void notify_guest_bh(void *opaque) event_notifier_set(s->guest_notifier); } -static void data_plane_set_up_op_blockers(VirtIOBlockDataPlane *s) -{ - assert(!s->blocker); - error_setg(&s->blocker, "block device is in use by data plane"); - blk_op_block_all(s->conf->conf.blk, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_COMMIT_SOURCE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_COMMIT_TARGET, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, - s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, - s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, - s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_MIRROR_SOURCE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker); -} - -static void data_plane_remove_op_blockers(VirtIOBlockDataPlane *s) -{ - if (s->blocker) { - blk_op_unblock_all(s->conf->conf.blk, s->blocker); - error_free(s->blocker); - s->blocker = NULL; - } -} - -static void data_plane_blk_insert_notifier(Notifier *n, void *data) -{ - VirtIOBlockDataPlane *s = container_of(n, VirtIOBlockDataPlane, - insert_notifier); - assert(s->conf->conf.blk == data); - data_plane_set_up_op_blockers(s); -} - -static void data_plane_blk_remove_notifier(Notifier *n, void *data) -{ - VirtIOBlockDataPlane *s = container_of(n, VirtIOBlockDataPlane, - remove_notifier); - assert(s->conf->conf.blk == data); - data_plane_remove_op_blockers(s); -} - /* Context: QEMU global mutex held */ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, VirtIOBlockDataPlane **dataplane, @@ -158,13 +105,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, s->ctx = iothread_get_aio_context(s->iothread); s->bh = aio_bh_new(s->ctx, notify_guest_bh, s); - s->insert_notifier.notify = data_plane_blk_insert_notifier; - s->remove_notifier.notify = data_plane_blk_remove_notifier; - blk_add_insert_bs_notifier(conf->conf.blk, &s->insert_notifier); - blk_add_remove_bs_notifier(conf->conf.blk, &s->remove_notifier); - - data_plane_set_up_op_blockers(s); - *dataplane = s; } @@ -176,9 +116,6 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) } virtio_blk_data_plane_stop(s); - data_plane_remove_op_blockers(s); - notifier_remove(&s->insert_notifier); - notifier_remove(&s->remove_notifier); qemu_bh_delete(s->bh); object_unref(OBJECT(s->iothread)); g_free(s); diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c index 7909d5041e..1d9f7ee000 100644 --- a/hw/block/tc58128.c +++ b/hw/block/tc58128.c @@ -45,7 +45,7 @@ static void init_dev(tc58128_dev * dev, const char *filename) } } else { /* Build first block with number of blocks */ - blocks = (ret + 528 * 32 - 1) / (528 * 32); + blocks = DIV_ROUND_UP(ret, 528 * 32); dev->flash_contents[0] = blocks & 0xff; dev->flash_contents[1] = (blocks >> 8) & 0xff; dev->flash_contents[2] = (blocks >> 16) & 0xff; diff --git a/hw/char/escc.c b/hw/char/escc.c index 8e6a7df465..31a5f902f9 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -989,18 +989,13 @@ static void escc_init1(Object *obj) SysBusDevice *dev = SYS_BUS_DEVICE(obj); unsigned int i; - s->chn[0].disabled = s->disabled; - s->chn[1].disabled = s->disabled; for (i = 0; i < 2; i++) { sysbus_init_irq(dev, &s->chn[i].irq); s->chn[i].chn = 1 - i; - s->chn[i].clock = s->frequency / 2; } s->chn[0].otherchn = &s->chn[1]; s->chn[1].otherchn = &s->chn[0]; - memory_region_init_io(&s->mmio, obj, &escc_mem_ops, s, "escc", - ESCC_SIZE << s->it_shift); sysbus_init_mmio(dev, &s->mmio); } @@ -1009,8 +1004,15 @@ static void escc_realize(DeviceState *dev, Error **errp) ESCCState *s = ESCC(dev); unsigned int i; + s->chn[0].disabled = s->disabled; + s->chn[1].disabled = s->disabled; + + memory_region_init_io(&s->mmio, OBJECT(dev), &escc_mem_ops, s, "escc", + ESCC_SIZE << s->it_shift); + for (i = 0; i < 2; i++) { if (s->chn[i].chr) { + s->chn[i].clock = s->frequency / 2; qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, serial_receive1, serial_event, &s->chn[i]); } diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 853162b670..0a05a5295c 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -58,9 +58,6 @@ const char *qdev_fw_name(DeviceState *dev) return object_get_typename(OBJECT(dev)); } -static void qdev_property_add_legacy(DeviceState *dev, Property *prop, - Error **errp); - static void bus_remove_child(BusState *bus, DeviceState *child) { BusChild *kid; @@ -733,13 +730,20 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v, } /** - * @qdev_add_legacy_property - adds a legacy property + * qdev_property_add_legacy: + * @dev: Device to add the property to. + * @prop: The qdev property definition. + * @errp: location to store error information. + * + * Add a legacy QOM property to @dev for qdev property @prop. + * On error, store error in @errp. * - * Do not use this is new code! Properties added through this interface will - * be given names and types in the "legacy" namespace. + * Legacy properties are string versions of QOM properties. The format of + * the string depends on the property type. Legacy properties are only + * needed for "info qtree". * - * Legacy properties are string versions of other OOM properties. The format - * of the string depends on the property type. + * Do not use this is new code! QOM Properties added through this interface + * will be given names in the "legacy" namespace. */ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp) @@ -762,10 +766,14 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, } /** - * @qdev_property_add_static - add a @Property to a device. + * qdev_property_add_static: + * @dev: Device to add the property to. + * @prop: The qdev property definition. + * @errp: location to store error information. * - * Static properties access data in a struct. The actual type of the - * property and the field depends on the property type. + * Add a static QOM property to @dev for qdev property @prop. + * On error, store error in @errp. Static properties access data in a struct. + * The type of the QOM property is derived from prop->info. */ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp) diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 9866dfda5f..570b0977c3 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -472,9 +472,9 @@ static int xenfb_map_fb(struct XenFB *xenfb) xenfb->pixels = NULL; } - xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; + xenfb->fbpages = DIV_ROUND_UP(xenfb->fb_len, XC_PAGE_SIZE); n_fbdirs = xenfb->fbpages * mode / 8; - n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; + n_fbdirs = DIV_ROUND_UP(n_fbdirs, XC_PAGE_SIZE); pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs); fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 279f0d7d05..8ca203211a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -23,7 +23,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "acpi-build.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/bitmap.h" #include "qemu/error-report.h" @@ -94,7 +93,6 @@ typedef struct AcpiPmInfo { uint32_t gpe0_blk_len; uint32_t io_base; uint16_t cpu_hp_io_base; - uint16_t cpu_hp_io_len; uint16_t mem_hp_io_base; uint16_t mem_hp_io_len; uint16_t pcihp_io_base; @@ -142,7 +140,6 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) } assert(obj); - pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN; pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE; pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN; @@ -262,7 +259,7 @@ static void acpi_align_size(GArray *blob, unsigned align) /* FACS */ static void -build_facs(GArray *table_data, GArray *linker) +build_facs(GArray *table_data, BIOSLinker *linker) { AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs); memcpy(&facs->signature, "FACS", 4); @@ -307,34 +304,31 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm) /* FADT */ static void -build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm, - unsigned facs, unsigned dsdt, +build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, + unsigned facs_tbl_offset, unsigned dsdt_tbl_offset, const char *oem_id, const char *oem_table_id) { AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt)); + unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data; + unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data; - fadt->firmware_ctrl = cpu_to_le32(facs); /* FACS address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &fadt->firmware_ctrl, - sizeof fadt->firmware_ctrl); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->firmware_ctrl), + ACPI_BUILD_TABLE_FILE, facs_tbl_offset); - fadt->dsdt = cpu_to_le32(dsdt); /* DSDT address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &fadt->dsdt, - sizeof fadt->dsdt); - fadt_setup(fadt, pm); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt), + ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset); build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id); } static void -build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms) +build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) { MachineClass *mc = MACHINE_GET_CLASS(pcms); CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms)); @@ -356,7 +350,7 @@ build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms) apic->type = ACPI_APIC_PROCESSOR; apic->length = sizeof(*apic); - apic->processor_id = apic_id; + apic->processor_id = i; apic->local_apic_id = apic_id; if (apic_ids->cpus[i].cpu != NULL) { apic->flags = cpu_to_le32(1); @@ -943,114 +937,6 @@ static Aml *build_crs(PCIHostState *host, return crs; } -static void build_processor_devices(Aml *sb_scope, MachineState *machine, - AcpiPmInfo *pm) -{ - int i, apic_idx; - Aml *dev; - Aml *crs; - Aml *pkg; - Aml *field; - Aml *ifctx; - Aml *method; - MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); - PCMachineState *pcms = PC_MACHINE(machine); - - /* The current AML generator can cover the APIC ID range [0..255], - * inclusive, for VCPU hotplug. */ - QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256); - g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT); - - /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */ - dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06"))); - aml_append(dev, - aml_name_decl("_UID", aml_string("CPU Hotplug resources")) - ); - /* device present, functioning, decoding, not shown in UI */ - aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); - crs = aml_resource_template(); - aml_append(crs, - aml_io(AML_DECODE16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1, - pm->cpu_hp_io_len) - ); - aml_append(dev, aml_name_decl("_CRS", crs)); - aml_append(sb_scope, dev); - /* declare CPU hotplug MMIO region and PRS field to access it */ - aml_append(sb_scope, aml_operation_region( - "PRST", AML_SYSTEM_IO, aml_int(pm->cpu_hp_io_base), pm->cpu_hp_io_len)); - field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); - aml_append(field, aml_named_field("PRS", 256)); - aml_append(sb_scope, field); - - /* build Processor object for each processor */ - for (i = 0; i < apic_ids->len; i++) { - int apic_id = apic_ids->cpus[i].arch_id; - - assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT); - - dev = aml_processor(apic_id, 0, 0, "CP%.02X", apic_id); - - method = aml_method("_MAT", 0, AML_NOTSERIALIZED); - aml_append(method, - aml_return(aml_call1(CPU_MAT_METHOD, aml_int(apic_id)))); - aml_append(dev, method); - - method = aml_method("_STA", 0, AML_NOTSERIALIZED); - aml_append(method, - aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id)))); - aml_append(dev, method); - - method = aml_method("_EJ0", 1, AML_NOTSERIALIZED); - aml_append(method, - aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id), - aml_arg(0))) - ); - aml_append(dev, method); - - aml_append(sb_scope, dev); - } - - /* build this code: - * Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...} - */ - /* Arg0 = Processor ID = APIC ID */ - method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED); - for (i = 0; i < apic_ids->len; i++) { - int apic_id = apic_ids->cpus[i].arch_id; - - ifctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id))); - aml_append(ifctx, - aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1)) - ); - aml_append(method, ifctx); - } - aml_append(sb_scope, method); - - /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" - * - * Note: The ability to create variable-sized packages was first - * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages - * ith up to 255 elements. Windows guests up to win2k8 fail when - * VarPackageOp is used. - */ - pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) : - aml_varpackage(pcms->apic_id_limit); - - for (i = 0, apic_idx = 0; i < apic_ids->len; i++) { - int apic_id = apic_ids->cpus[i].arch_id; - - for (; apic_idx < apic_id; apic_idx++) { - aml_append(pkg, aml_int(0)); - } - aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0)); - apic_idx = apic_id + 1; - } - aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg)); - g_free(apic_ids); -} - static void build_memory_devices(Aml *sb_scope, int nr_mem, uint16_t io_base, uint16_t io_len) { @@ -1979,7 +1865,7 @@ static Aml *build_q35_osc_method(void) } static void -build_dsdt(GArray *table_data, GArray *linker, +build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, PcPciInfo *pci, MachineState *machine) { @@ -2043,7 +1929,7 @@ build_dsdt(GArray *table_data, GArray *linker, build_q35_pci0_int(dsdt); } - build_cpu_hotplug_aml(dsdt); + build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base); build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base, pm->mem_hp_io_len); @@ -2051,8 +1937,6 @@ build_dsdt(GArray *table_data, GArray *linker, { aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); - aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED)); - if (misc->is_piix4) { method = aml_method("_E01", 0, AML_NOTSERIALIZED); aml_append(method, @@ -2060,30 +1944,11 @@ build_dsdt(GArray *table_data, GArray *linker, aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); aml_append(scope, method); - } else { - aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED)); } - method = aml_method("_E02", 0, AML_NOTSERIALIZED); - aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); - aml_append(scope, method); - method = aml_method("_E03", 0, AML_NOTSERIALIZED); aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); aml_append(scope, method); - - aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED)); } aml_append(dsdt, scope); @@ -2322,8 +2187,6 @@ build_dsdt(GArray *table_data, GArray *linker, sb_scope = aml_scope("\\_SB"); { - build_processor_devices(sb_scope, machine, pm); - build_memory_devices(sb_scope, nr_mem, pm->mem_hp_io_base, pm->mem_hp_io_len); @@ -2373,7 +2236,7 @@ build_dsdt(GArray *table_data, GArray *linker, } static void -build_hpet(GArray *table_data, GArray *linker) +build_hpet(GArray *table_data, BIOSLinker *linker) { Acpi20Hpet *hpet; @@ -2388,32 +2251,31 @@ build_hpet(GArray *table_data, GArray *linker) } static void -build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog) +build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) { Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa); - uint64_t log_area_start_address = acpi_data_len(tcpalog); + unsigned log_addr_size = sizeof(tcpa->log_area_start_address); + unsigned log_addr_offset = + (char *)&tcpa->log_area_start_address - table_data->data; tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT); tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE); - tcpa->log_area_start_address = cpu_to_le64(log_area_start_address); + acpi_data_push(tcpalog, le32_to_cpu(tcpa->log_area_minimum_length)); - bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1, + bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1, false /* high memory */); /* log area start address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TPMLOG_FILE, - table_data, &tcpa->log_area_start_address, - sizeof(tcpa->log_area_start_address)); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, log_addr_offset, log_addr_size, + ACPI_BUILD_TPMLOG_FILE, 0); build_header(linker, table_data, (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL); - - acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE); } static void -build_tpm2(GArray *table_data, GArray *linker) +build_tpm2(GArray *table_data, BIOSLinker *linker) { Acpi20TPM2 *tpm2_ptr; @@ -2428,7 +2290,7 @@ build_tpm2(GArray *table_data, GArray *linker) } static void -build_srat(GArray *table_data, GArray *linker, MachineState *machine) +build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) { AcpiSystemResourceAffinityTable *srat; AcpiSratProcessorAffinity *core; @@ -2525,7 +2387,7 @@ build_srat(GArray *table_data, GArray *linker, MachineState *machine) } static void -build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info) +build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info) { AcpiTableMcfg *mcfg; const char *sig; @@ -2554,7 +2416,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info) } static void -build_dmar_q35(GArray *table_data, GArray *linker) +build_dmar_q35(GArray *table_data, BIOSLinker *linker) { int dmar_start = table_data->len; @@ -2578,26 +2440,27 @@ build_dmar_q35(GArray *table_data, GArray *linker) } static GArray * -build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); + unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address); + unsigned rsdt_pa_offset = + (char *)&rsdp->rsdt_physical_address - rsdp_table->data; - bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16, + bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16, true /* fseg memory */); memcpy(&rsdp->signature, "RSD PTR ", 8); memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6); - rsdp->rsdt_physical_address = cpu_to_le32(rsdt); /* Address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, - ACPI_BUILD_TABLE_FILE, - rsdp_table, &rsdp->rsdt_physical_address, - sizeof rsdp->rsdt_physical_address); - rsdp->checksum = 0; + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size, + ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset); + /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, - rsdp_table, rsdp, sizeof *rsdp, - &rsdp->checksum); + (char *)rsdp - rsdp_table->data, sizeof *rsdp, + (char *)&rsdp->checksum - rsdp_table->data); return rsdp_table; } @@ -2670,7 +2533,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) sizeof(uint32_t)); ACPI_BUILD_DPRINTF("init ACPI tables\n"); - bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE, + bios_linker_loader_alloc(tables->linker, + ACPI_BUILD_TABLE_FILE, tables_blob, 64 /* Ensure FACS is aligned */, false /* high memory */); @@ -2727,7 +2591,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) build_dmar_q35(tables_blob, tables->linker); } if (pcms->acpi_nvdimm_state.is_enabled) { - nvdimm_build_acpi(table_offsets, tables_blob, tables->linker); + nvdimm_build_acpi(table_offsets, tables_blob, tables->linker, + pcms->acpi_nvdimm_state.dsm_mem); } /* Add tables supplied by user (if any) */ @@ -2790,7 +2655,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE); } - acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE); + acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); /* Cleanup memory that's no longer used. */ g_array_free(table_offsets, true); @@ -2830,7 +2695,7 @@ static void acpi_build_update(void *build_opaque) acpi_ram_update(build_state->rsdp_mr, tables.rsdp); } - acpi_ram_update(build_state->linker_mr, tables.linker); + acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); acpi_build_tables_cleanup(&tables, true); } @@ -2894,7 +2759,8 @@ void acpi_setup(void) assert(build_state->table_mr != NULL); build_state->linker_mr = - acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); + acpi_add_rom_blob(build_state, tables.linker->cmd_blob, + "etc/table-loader", 0); fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e29ccc8341..7198ed533c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -765,8 +765,6 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) acpi_tables, acpi_tables_len); fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override()); - pc_build_smbios(fw_cfg); - fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, &e820_reserve, sizeof(e820_reserve)); fw_cfg_add_file(fw_cfg, "etc/e820", e820_table, @@ -1149,14 +1147,6 @@ void pc_cpus_init(PCMachineState *pcms) smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } -/* pci-info ROM file. Little endian format */ -typedef struct PcRomPciInfo { - uint64_t w32_min; - uint64_t w32_max; - uint64_t w64_min; - uint64_t w64_max; -} PcRomPciInfo; - static void pc_machine_done(Notifier *notifier, void *data) { @@ -1182,6 +1172,9 @@ void pc_machine_done(Notifier *notifier, void *data) } acpi_setup(); + if (pcms->fw_cfg) { + pc_build_smbios(pcms->fw_cfg); + } } void pc_guest_info_init(PCMachineState *pcms) @@ -1893,7 +1886,7 @@ static void pc_machine_initfn(Object *obj) pc_machine_get_hotplug_memory_region_size, NULL, NULL, NULL, &error_abort); - pcms->max_ram_below_4g = 1ULL << 32; /* 4G */ + pcms->max_ram_below_4g = 0xe0000000; /* 3.5G */ object_property_add(obj, PC_MACHINE_MAX_RAM_BELOW_4G, "size", pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g, diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 24e7042680..14dd0cc774 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "hw/hw.h" #include "hw/loader.h" @@ -87,29 +86,46 @@ static void pc_init1(MachineState *machine, MemoryRegion *rom_memory; ram_addr_t lowmem; - /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). - * If it doesn't, we need to split it in chunks below and above 4G. - * In any case, try to make sure that guest addresses aligned at - * 1G boundaries get mapped to host addresses aligned at 1G boundaries. - * For old machine types, use whatever split we used historically to avoid - * breaking migration. - */ - if (machine->ram_size >= 0xe0000000) { - lowmem = pcmc->gigabyte_align ? 0xc0000000 : 0xe0000000; - } else { - lowmem = 0xe0000000; - } - - /* Handle the machine opt max-ram-below-4g. It is basically doing - * min(qemu limit, user limit). + /* + * Calculate ram split, for memory below and above 4G. It's a bit + * complicated for backward compatibility reasons ... + * + * - Traditional split is 3.5G (lowmem = 0xe0000000). This is the + * default value for max_ram_below_4g now. + * + * - Then, to gigabyte align the memory, we move the split to 3G + * (lowmem = 0xc0000000). But only in case we have to split in + * the first place, i.e. ram_size is larger than (traditional) + * lowmem. And for new machine types (gigabyte_align = true) + * only, for live migration compatibility reasons. + * + * - Next the max-ram-below-4g option was added, which allowed to + * reduce lowmem to a smaller value, to allow a larger PCI I/O + * window below 4G. qemu doesn't enforce gigabyte alignment here, + * but prints a warning. + * + * - Finally max-ram-below-4g got updated to also allow raising lowmem, + * so legacy non-PAE guests can get as much memory as possible in + * the 32bit address space below 4G. + * + * Examples: + * qemu -M pc-1.7 -m 4G (old default) -> 3584M low, 512M high + * qemu -M pc -m 4G (new default) -> 3072M low, 1024M high + * qemu -M pc,max-ram-below-4g=2G -m 4G -> 2048M low, 2048M high + * qemu -M pc,max-ram-below-4g=4G -m 3968M -> 3968M low (=4G-128M) */ - if (lowmem > pcms->max_ram_below_4g) { - lowmem = pcms->max_ram_below_4g; - if (machine->ram_size - lowmem > lowmem && - lowmem & ((1ULL << 30) - 1)) { - error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64 - ") not a multiple of 1G; possible bad performance.", - pcms->max_ram_below_4g); + lowmem = pcms->max_ram_below_4g; + if (machine->ram_size >= pcms->max_ram_below_4g) { + if (pcmc->gigabyte_align) { + if (lowmem > 0xc0000000) { + lowmem = 0xc0000000; + } + if (lowmem & ((1ULL << 30) - 1)) { + error_report("Warning: Large machine and max_ram_below_4g " + "(%" PRIu64 ") not a multiple of 1G; " + "possible bad performance.", + pcms->max_ram_below_4g); + } } } diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 42ad68a1c0..78c10a0406 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -271,7 +271,8 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) if (s->lba == -1) { /* Non-block ATAPI transfer - just copy to RAM */ s->io_buffer_size = MIN(s->io_buffer_size, io->len); - cpu_physical_memory_write(io->addr, s->io_buffer, s->io_buffer_size); + dma_memory_write(&address_space_memory, io->addr, s->io_buffer, + s->io_buffer_size); ide_atapi_cmd_ok(s); m->dma_active = false; goto done; diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c index 725d5b62c5..2370e7485f 100644 --- a/hw/intc/aspeed_vic.c +++ b/hw/intc/aspeed_vic.c @@ -28,7 +28,6 @@ */ #include "qemu/osdep.h" -#include <inttypes.h> #include "hw/intc/aspeed_vic.h" #include "qemu/bitops.h" #include "qemu/log.h" diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c index 6adec1e990..f09f217e78 100644 --- a/hw/ipmi/ipmi.c +++ b/hw/ipmi/ipmi.c @@ -30,6 +30,13 @@ #include "qom/object_interfaces.h" #include "qapi/visitor.h" +static uint32_t ipmi_current_uuid = 1; + +uint32_t ipmi_next_uuid(void) +{ + return ipmi_current_uuid++; +} + static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly) { switch (op) { @@ -122,30 +129,3 @@ static void ipmi_register_types(void) } type_init(ipmi_register_types) - -static IPMIFwInfo *ipmi_fw_info; -static unsigned int ipmi_fw_info_len; - -static uint32_t current_uuid = 1; - -void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp) -{ - info->uuid = current_uuid++; - ipmi_fw_info = g_realloc(ipmi_fw_info, - sizeof(*ipmi_fw_info) * (ipmi_fw_info_len + 1)); - ipmi_fw_info[ipmi_fw_info_len] = *info; -} - -IPMIFwInfo *ipmi_first_fwinfo(void) -{ - return ipmi_fw_info; -} - -IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current) -{ - current++; - if (current >= &ipmi_fw_info[ipmi_fw_info_len]) { - return NULL; - } - return current; -} diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index fe12112a2f..157879e177 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -190,7 +190,7 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b, if (ibe->outlen) { /* We already have a command queued. Shouldn't ever happen. */ fprintf(stderr, "IPMI KCS: Got command when not finished with the" - " previous commmand\n"); + " previous command\n"); abort(); } diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index aaea12ecdd..f03661715c 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -390,16 +390,6 @@ static void ipmi_bt_init(IPMIInterface *ii, Error **errp) memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3); } -static void ipmi_bt_class_init(IPMIInterfaceClass *iic) -{ - iic->init = ipmi_bt_init; - iic->set_atn = ipmi_bt_set_atn; - iic->handle_rsp = ipmi_bt_handle_rsp; - iic->handle_if_event = ipmi_bt_handle_event; - iic->set_irq_enable = ipmi_bt_set_irq_enable; - iic->reset = ipmi_bt_handle_reset; -} - #define TYPE_ISA_IPMI_BT "isa-ipmi-bt" #define ISA_IPMI_BT(obj) OBJECT_CHECK(ISAIPMIBTDevice, (obj), \ @@ -409,9 +399,38 @@ typedef struct ISAIPMIBTDevice { ISADevice dev; int32_t isairq; IPMIBT bt; - IPMIFwInfo fwinfo; + uint32_t uuid; } ISAIPMIBTDevice; +static void ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info) +{ + ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii); + + info->interface_name = "bt"; + info->interface_type = IPMI_SMBIOS_BT; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->base_address = iib->bt.io_base; + info->register_length = iib->bt.io_length; + info->register_spacing = 1; + info->memspace = IPMI_MEMSPACE_IO; + info->irq_type = IPMI_LEVEL_IRQ; + info->interrupt_number = iib->isairq; + info->i2c_slave_address = iib->bt.bmc->slave_addr; + info->uuid = iib->uuid; +} + +static void ipmi_bt_class_init(IPMIInterfaceClass *iic) +{ + iic->init = ipmi_bt_init; + iic->set_atn = ipmi_bt_set_atn; + iic->handle_rsp = ipmi_bt_handle_rsp; + iic->handle_if_event = ipmi_bt_handle_event; + iic->set_irq_enable = ipmi_bt_set_irq_enable; + iic->reset = ipmi_bt_handle_reset; + iic->get_fwinfo = ipmi_bt_get_fwinfo; +} + static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) { ISADevice *isadev = ISA_DEVICE(dev); @@ -424,6 +443,8 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) return; } + iib->uuid = ipmi_next_uuid(); + iib->bt.bmc->intf = ii; iic->init(ii, errp); @@ -438,20 +459,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length); isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base); - - iib->fwinfo.interface_name = "bt"; - iib->fwinfo.interface_type = IPMI_SMBIOS_BT; - iib->fwinfo.ipmi_spec_major_revision = 2; - iib->fwinfo.ipmi_spec_minor_revision = 0; - iib->fwinfo.base_address = iib->bt.io_base; - iib->fwinfo.register_length = iib->bt.io_length; - iib->fwinfo.register_spacing = 1; - iib->fwinfo.memspace = IPMI_MEMSPACE_IO; - iib->fwinfo.irq_type = IPMI_LEVEL_IRQ; - iib->fwinfo.interrupt_number = iib->isairq; - iib->fwinfo.acpi_parent = "\\_SB.PCI0.ISA"; - iib->fwinfo.i2c_slave_address = iib->bt.bmc->slave_addr; - ipmi_add_fwinfo(&iib->fwinfo, errp); } static const VMStateDescription vmstate_ISAIPMIBTDevice = { diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index 2742ce06c4..9a38f8a28a 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -354,16 +354,6 @@ static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2); } -static void ipmi_kcs_class_init(IPMIInterfaceClass *iic) -{ - iic->init = ipmi_kcs_init; - iic->set_atn = ipmi_kcs_set_atn; - iic->handle_rsp = ipmi_kcs_handle_rsp; - iic->handle_if_event = ipmi_kcs_handle_event; - iic->set_irq_enable = ipmi_kcs_set_irq_enable; -} - - #define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs" #define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \ TYPE_ISA_IPMI_KCS) @@ -372,9 +362,37 @@ typedef struct ISAIPMIKCSDevice { ISADevice dev; int32_t isairq; IPMIKCS kcs; - IPMIFwInfo fwinfo; + uint32_t uuid; } ISAIPMIKCSDevice; +static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info) +{ + ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii); + + info->interface_name = "kcs"; + info->interface_type = IPMI_SMBIOS_KCS; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->base_address = iik->kcs.io_base; + info->i2c_slave_address = iik->kcs.bmc->slave_addr; + info->register_length = iik->kcs.io_length; + info->register_spacing = 1; + info->memspace = IPMI_MEMSPACE_IO; + info->irq_type = IPMI_LEVEL_IRQ; + info->interrupt_number = iik->isairq; + info->uuid = iik->uuid; +} + +static void ipmi_kcs_class_init(IPMIInterfaceClass *iic) +{ + iic->init = ipmi_kcs_init; + iic->set_atn = ipmi_kcs_set_atn; + iic->handle_rsp = ipmi_kcs_handle_rsp; + iic->handle_if_event = ipmi_kcs_handle_event; + iic->set_irq_enable = ipmi_kcs_set_irq_enable; + iic->get_fwinfo = ipmi_kcs_get_fwinfo; +} + static void ipmi_isa_realize(DeviceState *dev, Error **errp) { ISADevice *isadev = ISA_DEVICE(dev); @@ -387,6 +405,8 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) return; } + iik->uuid = ipmi_next_uuid(); + iik->kcs.bmc->intf = ii; iic->init(ii, errp); @@ -401,20 +421,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length); isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base); - - iik->fwinfo.interface_name = "kcs"; - iik->fwinfo.interface_type = IPMI_SMBIOS_KCS; - iik->fwinfo.ipmi_spec_major_revision = 2; - iik->fwinfo.ipmi_spec_minor_revision = 0; - iik->fwinfo.base_address = iik->kcs.io_base; - iik->fwinfo.i2c_slave_address = iik->kcs.bmc->slave_addr; - iik->fwinfo.register_length = iik->kcs.io_length; - iik->fwinfo.register_spacing = 1; - iik->fwinfo.memspace = IPMI_MEMSPACE_IO; - iik->fwinfo.irq_type = IPMI_LEVEL_IRQ; - iik->fwinfo.interrupt_number = iik->isairq; - iik->fwinfo.acpi_parent = "\\_SB.PCI0.ISA"; - ipmi_add_fwinfo(&iik->fwinfo, errp); } const VMStateDescription vmstate_ISAIPMIKCSDevice = { diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 4f8ca45f6d..213741bc21 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -97,8 +97,8 @@ static void ich9_cc_update(ICH9LPCState *lpc) /* * D30: DMI2PCI bridge - * It is arbitrarily decided how INTx lines of PCI devicesbehind the bridge - * are connected to pirq lines. Our choice is PIRQ[E-H]. + * It is arbitrarily decided how INTx lines of PCI devices behind + * the bridge are connected to pirq lines. Our choice is PIRQ[E-H]. * INT[A-D] are connected to PIRQ[E-H] */ for (pci_intx = 0; pci_intx < PCI_NUM_PINS; pci_intx++) { @@ -637,30 +637,6 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) 1); } -static void ich9_device_plug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - - ich9_pm_device_plug_cb(&lpc->pm, dev, errp); -} - -static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - - ich9_pm_device_unplug_request_cb(&lpc->pm, dev, errp); -} - -static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - - ich9_pm_device_unplug_cb(&lpc->pm, dev, errp); -} - static bool ich9_rst_cnt_needed(void *opaque) { ICH9LPCState *lpc = opaque; @@ -703,6 +679,13 @@ static Property ich9_lpc_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void ich9_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) +{ + ICH9LPCState *s = ICH9_LPC_DEVICE(adev); + + acpi_send_gpe_event(&s->pm.acpi_regs, s->pm.irq, ev); +} + static void ich9_lpc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -726,10 +709,11 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) * pc_q35_init() */ dc->cannot_instantiate_with_device_add_yet = true; - hc->plug = ich9_device_plug_cb; - hc->unplug_request = ich9_device_unplug_request_cb; - hc->unplug = ich9_device_unplug_cb; + hc->plug = ich9_pm_device_plug_cb; + hc->unplug_request = ich9_pm_device_unplug_request_cb; + hc->unplug = ich9_pm_device_unplug_cb; adevc->ospm_status = ich9_pm_ospm_status; + adevc->send_event = ich9_send_gpe; } static const TypeInfo ich9_lpc_info = { diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 9e7de56829..6de2275986 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -354,8 +354,9 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, int64_t value; MemoryRegion *mr; PCDIMMDevice *dimm = PC_DIMM(obj); + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj); - mr = host_memory_backend_get_memory(dimm->hostmem, errp); + mr = ddc->get_memory_region(dimm); value = memory_region_size(mr); visit_type_int(v, name, &value, errp); @@ -399,6 +400,7 @@ static void pc_dimm_init(Object *obj) static void pc_dimm_realize(DeviceState *dev, Error **errp) { PCDIMMDevice *dimm = PC_DIMM(dev); + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); if (!dimm->hostmem) { error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set"); @@ -411,6 +413,10 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp) dimm->node, nb_numa_nodes ? nb_numa_nodes : 1); return; } + + if (ddc->realize) { + ddc->realize(dimm, errp); + } } static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 5632743d36..f116f9c36d 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -42,6 +42,7 @@ #include "hw/ppc/mac_dbdma.h" #include "qemu/main-loop.h" #include "qemu/log.h" +#include "sysemu/dma.h" /* debug DBDMA */ //#define DEBUG_DBDMA @@ -81,8 +82,8 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch) { DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n", ch->regs[DBDMA_CMDPTR_LO]); - cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO], - &ch->current, sizeof(dbdma_cmd)); + dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], + &ch->current, sizeof(dbdma_cmd)); } static void dbdma_cmdptr_save(DBDMA_channel *ch) @@ -92,8 +93,8 @@ static void dbdma_cmdptr_save(DBDMA_channel *ch) DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n", le16_to_cpu(ch->current.xfer_status), le16_to_cpu(ch->current.res_count)); - cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO], - &ch->current, sizeof(dbdma_cmd)); + dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], + &ch->current, sizeof(dbdma_cmd)); } static void kill_channel(DBDMA_channel *ch) @@ -353,7 +354,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr, return; } - cpu_physical_memory_read(addr, &val, len); + dma_memory_read(&address_space_memory, addr, &val, len); if (len == 2) val = (val << 16) | (current->cmd_dep & 0x0000ffff); @@ -398,7 +399,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr, else if (len == 1) val >>= 24; - cpu_physical_memory_write(addr, &val, len); + dma_memory_write(&address_space_memory, addr, &val, len); if (conditional_wait(ch)) goto wait; diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 36e3dbe347..1202371271 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -311,11 +311,9 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val) */ mit_delay = (mit_delay < 500) ? 500 : mit_delay; - if (mit_delay) { - s->mit_timer_on = 1; - timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - mit_delay * 256); - } + s->mit_timer_on = 1; + timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + mit_delay * 256); s->mit_ide = 0; } } diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c index 0a134ebca8..9b1e0d2441 100644 --- a/hw/net/rocker/rocker_of_dpa.c +++ b/hw/net/rocker/rocker_of_dpa.c @@ -103,9 +103,8 @@ typedef struct of_dpa_flow_key { /* Width of key which includes field 'f' in u64s, rounded up */ #define FLOW_KEY_WIDTH(f) \ - ((offsetof(OfDpaFlowKey, f) + \ - sizeof(((OfDpaFlowKey *)0)->f) + \ - sizeof(uint64_t) - 1) / sizeof(uint64_t)) + DIV_ROUND_UP(offsetof(OfDpaFlowKey, f) + sizeof(((OfDpaFlowKey *)0)->f), \ + sizeof(uint64_t)) typedef struct of_dpa_flow_action { uint32_t goto_tbl; diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index cdbdfb5320..74a0079ca6 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -729,15 +729,20 @@ static int get_fw_cfg_order(FWCfgState *s, const char *name) { int i; - if (s->fw_cfg_order_override > 0) - return s->fw_cfg_order_override; + if (s->fw_cfg_order_override > 0) { + return s->fw_cfg_order_override; + } for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) { - if (fw_cfg_order[i].name == NULL) - continue; - if (strcmp(name, fw_cfg_order[i].name) == 0) - return fw_cfg_order[i].order; + if (fw_cfg_order[i].name == NULL) { + continue; + } + + if (strcmp(name, fw_cfg_order[i].name) == 0) { + return fw_cfg_order[i].order; + } } + /* Stick unknown stuff at the end. */ error_report("warning: Unknown firmware file in legacy mode: %s\n", name); return FW_CFG_ORDER_OVERRIDE_LAST; diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index cdf9f258ae..1bcf740f0e 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -880,7 +880,7 @@ static int timebase_post_load(void *opaque, int version_id) host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST); ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns); migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff); - migration_duration_tb = muldiv64(migration_duration_ns, freq, + migration_duration_tb = muldiv64(freq, migration_duration_ns, NANOSECONDS_PER_SECOND); guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 44e401ae99..0636642341 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1816,11 +1816,21 @@ static void ppc_spapr_init(MachineState *machine) /* initialize hotplug memory address space */ if (machine->ram_size < machine->maxram_size) { ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size; + /* + * Limit the number of hotpluggable memory slots to half the number + * slots that KVM supports, leaving the other half for PCI and other + * devices. However ensure that number of slots doesn't drop below 32. + */ + int max_memslots = kvm_enabled() ? kvm_get_max_memslots() / 2 : + SPAPR_MAX_RAM_SLOTS; - if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) { + if (max_memslots < SPAPR_MAX_RAM_SLOTS) { + max_memslots = SPAPR_MAX_RAM_SLOTS; + } + if (machine->ram_slots > max_memslots) { error_report("Specified number of memory slots %" PRIu64" exceeds max supported %d", - machine->ram_slots, SPAPR_MAX_RAM_SLOTS); + machine->ram_slots, max_memslots); exit(1); } @@ -2344,18 +2354,36 @@ static const TypeInfo spapr_machine_info = { type_init(spapr_machine_register_##suffix) /* + * pseries-2.7 + */ +static void spapr_machine_2_7_instance_options(MachineState *machine) +{ +} + +static void spapr_machine_2_7_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(2_7, "2.7", true); + +/* * pseries-2.6 */ +#define SPAPR_COMPAT_2_6 \ + HW_COMPAT_2_6 + static void spapr_machine_2_6_instance_options(MachineState *machine) { } static void spapr_machine_2_6_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_2_7_class_options(mc); + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6); } -DEFINE_SPAPR_MACHINE(2_6, "2.6", true); +DEFINE_SPAPR_MACHINE(2_6, "2.6", false); /* * pseries-2.5 diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 96bb0181a7..a3cc5722f1 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -17,6 +17,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "hw/hw.h" #include "qemu/log.h" #include "sysemu/kvm.h" @@ -137,33 +138,92 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr, return ret; } +static void spapr_tce_table_pre_save(void *opaque) +{ + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); + + tcet->mig_table = tcet->table; + tcet->mig_nb_table = tcet->nb_table; + + trace_spapr_iommu_pre_save(tcet->liobn, tcet->mig_nb_table, + tcet->bus_offset, tcet->page_shift); +} + static int spapr_tce_table_post_load(void *opaque, int version_id) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); + uint32_t old_nb_table = tcet->nb_table; + uint64_t old_bus_offset = tcet->bus_offset; + uint32_t old_page_shift = tcet->page_shift; if (tcet->vdev) { spapr_vio_set_bypass(tcet->vdev, tcet->bypass); } + if (tcet->mig_nb_table != tcet->nb_table) { + spapr_tce_table_disable(tcet); + } + + if (tcet->mig_nb_table) { + if (!tcet->nb_table) { + spapr_tce_table_enable(tcet, old_page_shift, old_bus_offset, + tcet->mig_nb_table); + } + + memcpy(tcet->table, tcet->mig_table, + tcet->nb_table * sizeof(tcet->table[0])); + + free(tcet->mig_table); + tcet->mig_table = NULL; + } + + trace_spapr_iommu_post_load(tcet->liobn, old_nb_table, tcet->nb_table, + tcet->bus_offset, tcet->page_shift); + return 0; } +static bool spapr_tce_table_ex_needed(void *opaque) +{ + sPAPRTCETable *tcet = opaque; + + return tcet->bus_offset || tcet->page_shift != 0xC; +} + +static const VMStateDescription vmstate_spapr_tce_table_ex = { + .name = "spapr_iommu_ex", + .version_id = 1, + .minimum_version_id = 1, + .needed = spapr_tce_table_ex_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(bus_offset, sPAPRTCETable), + VMSTATE_UINT32(page_shift, sPAPRTCETable), + VMSTATE_END_OF_LIST() + }, +}; + static const VMStateDescription vmstate_spapr_tce_table = { .name = "spapr_iommu", .version_id = 2, .minimum_version_id = 2, + .pre_save = spapr_tce_table_pre_save, .post_load = spapr_tce_table_post_load, .fields = (VMStateField []) { /* Sanity check */ VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), - VMSTATE_UINT32_EQUAL(nb_table, sPAPRTCETable), /* IOMMU state */ + VMSTATE_UINT32(mig_nb_table, sPAPRTCETable), VMSTATE_BOOL(bypass, sPAPRTCETable), - VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, vmstate_info_uint64, uint64_t), + VMSTATE_VARRAY_UINT32_ALLOC(mig_table, sPAPRTCETable, mig_nb_table, 0, + vmstate_info_uint64, uint64_t), VMSTATE_END_OF_LIST() }, + .subsections = (const VMStateDescription*[]) { + &vmstate_spapr_tce_table_ex, + NULL + } }; static MemoryRegionIOMMUOps spapr_iommu_ops = { @@ -173,17 +233,16 @@ static MemoryRegionIOMMUOps spapr_iommu_ops = { static int spapr_tce_table_realize(DeviceState *dev) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); + Object *tcetobj = OBJECT(tcet); + char tmp[32]; tcet->fd = -1; - tcet->table = spapr_tce_alloc_table(tcet->liobn, - tcet->page_shift, - tcet->nb_table, - &tcet->fd, - tcet->need_vfio); + tcet->need_vfio = false; + snprintf(tmp, sizeof(tmp), "tce-root-%x", tcet->liobn); + memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX); - memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops, - "iommu-spapr", - (uint64_t)tcet->nb_table << tcet->page_shift); + snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn); + memory_region_init_iommu(&tcet->iommu, tcetobj, &spapr_iommu_ops, tmp, 0); QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); @@ -225,14 +284,10 @@ void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio) tcet->table = newtable; } -sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, - uint64_t bus_offset, - uint32_t page_shift, - uint32_t nb_table, - bool need_vfio) +sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn) { sPAPRTCETable *tcet; - char tmp[64]; + char tmp[32]; if (spapr_tce_find_by_liobn(liobn)) { fprintf(stderr, "Attempted to create TCE table with duplicate" @@ -240,16 +295,8 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, return NULL; } - if (!nb_table) { - return NULL; - } - tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE)); tcet->liobn = liobn; - tcet->bus_offset = bus_offset; - tcet->page_shift = page_shift; - tcet->nb_table = nb_table; - tcet->need_vfio = need_vfio; snprintf(tmp, sizeof(tmp), "tce-table-%x", liobn); object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL); @@ -259,19 +306,58 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, return tcet; } +void spapr_tce_table_enable(sPAPRTCETable *tcet, + uint32_t page_shift, uint64_t bus_offset, + uint32_t nb_table) +{ + if (tcet->nb_table) { + error_report("Warning: trying to enable already enabled TCE table"); + return; + } + + tcet->bus_offset = bus_offset; + tcet->page_shift = page_shift; + tcet->nb_table = nb_table; + tcet->table = spapr_tce_alloc_table(tcet->liobn, + tcet->page_shift, + tcet->nb_table, + &tcet->fd, + tcet->need_vfio); + + memory_region_set_size(&tcet->iommu, + (uint64_t)tcet->nb_table << tcet->page_shift); + memory_region_add_subregion(&tcet->root, tcet->bus_offset, &tcet->iommu); +} + +void spapr_tce_table_disable(sPAPRTCETable *tcet) +{ + if (!tcet->nb_table) { + return; + } + + memory_region_del_subregion(&tcet->root, &tcet->iommu); + memory_region_set_size(&tcet->iommu, 0); + + spapr_tce_free_table(tcet->table, tcet->fd, tcet->nb_table); + tcet->fd = -1; + tcet->table = NULL; + tcet->bus_offset = 0; + tcet->page_shift = 0; + tcet->nb_table = 0; +} + static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); QLIST_REMOVE(tcet, list); - spapr_tce_free_table(tcet->table, tcet->fd, tcet->nb_table); - tcet->fd = -1; + spapr_tce_table_disable(tcet); } MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet) { - return &tcet->iommu; + return &tcet->root; } static void spapr_tce_reset(DeviceState *dev) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 856aec7f51..9f28fb3829 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1310,7 +1310,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) PCIBus *bus; uint64_t msi_window_size = 4096; sPAPRTCETable *tcet; - uint32_t nb_table; if (sphb->index != (uint32_t)-1) { hwaddr windows_base; @@ -1462,18 +1461,15 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) } } - nb_table = sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT; - tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn, - 0, SPAPR_TCE_PAGE_SHIFT, nb_table, false); + tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn); if (!tcet) { error_setg(errp, "Unable to create TCE table for %s", sphb->dtbusname); return; } - /* Register default 32bit DMA window */ - memory_region_add_subregion(&sphb->iommu_root, sphb->dma_win_addr, - spapr_tce_get_iommu(tcet)); + memory_region_add_subregion_overlap(&sphb->iommu_root, 0, + spapr_tce_get_iommu(tcet), 0); sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); } @@ -1489,8 +1485,25 @@ static int spapr_phb_children_reset(Object *child, void *opaque) return 0; } +void spapr_phb_dma_reset(sPAPRPHBState *sphb) +{ + sPAPRTCETable *tcet = spapr_tce_find_by_liobn(sphb->dma_liobn); + + if (tcet && tcet->nb_table) { + spapr_tce_table_disable(tcet); + } + + /* Register default 32bit DMA window */ + spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr, + sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT); +} + static void spapr_phb_reset(DeviceState *qdev) { + sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev); + + spapr_phb_dma_reset(sphb); + /* Reset the IOMMU state */ object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL); @@ -1624,7 +1637,6 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data) dc->reset = spapr_phb_reset; dc->vmsd = &vmstate_spapr_pci; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); - dc->cannot_instantiate_with_device_add_yet = false; hp->plug = spapr_phb_hot_plug_child; hp->unplug = spapr_phb_hot_unplug_child; } diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index d084aedadf..3d9b9c60f4 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -483,11 +483,9 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) memory_region_add_subregion_overlap(&dev->mrroot, 0, &dev->mrbypass, 1); address_space_init(&dev->as, &dev->mrroot, qdev->id); - dev->tcet = spapr_tce_new_table(qdev, liobn, - 0, - SPAPR_TCE_PAGE_SHIFT, - pc->rtce_window_size >> - SPAPR_TCE_PAGE_SHIFT, false); + dev->tcet = spapr_tce_new_table(qdev, liobn); + spapr_tce_table_enable(dev->tcet, SPAPR_TCE_PAGE_SHIFT, 0, + pc->rtce_window_size >> SPAPR_TCE_PAGE_SHIFT); dev->tcet->vdev = dev; memory_region_add_subregion_overlap(&dev->mrroot, 0, spapr_tce_get_iommu(dev->tcet), 2); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index a1c1ed9496..2b68e5e87d 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1476,7 +1476,7 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp) int n = virtio_get_num_queues(vdev); if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) { - error_setg(errp, "The nubmer of virtqueues %d " + error_setg(errp, "The number of virtqueues %d " "exceeds ccw limit %d", n, VIRTIO_CCW_QUEUE_MAX); return; diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 591c8172d5..3adb685177 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -400,19 +400,17 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr) trace_esp_mem_readb(saddr, s->rregs[saddr]); switch (saddr) { case ESP_FIFO: - if (s->ti_size > 0) { + if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { + /* Data out. */ + qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n"); + s->rregs[ESP_FIFO] = 0; + esp_raise_irq(s); + } else if (s->ti_rptr < s->ti_wptr) { s->ti_size--; - if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { - /* Data out. */ - qemu_log_mask(LOG_UNIMP, - "esp: PIO data read not implemented\n"); - s->rregs[ESP_FIFO] = 0; - } else { - s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; - } + s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; esp_raise_irq(s); } - if (s->ti_size == 0) { + if (s->ti_rptr == s->ti_wptr) { s->ti_rptr = 0; s->ti_wptr = 0; } @@ -456,7 +454,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) } else { trace_esp_error_fifo_overrun(); } - } else if (s->ti_size == TI_BUFSZ - 1) { + } else if (s->ti_wptr == TI_BUFSZ - 1) { trace_esp_error_fifo_overrun(); } else { s->ti_size++; diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index cc66d36186..a9ffc32682 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -773,6 +773,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd) ptr = memory_region_get_ram_ptr(&pci_dev->rom); memcpy(biosver, ptr + 0x41, 31); + biosver[31] = 0; memcpy(info.image_component[1].name, "BIOS", 4); memcpy(info.image_component[1].version, biosver, strlen((const char *)biosver)); diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index ab7cf9cbf8..188196990e 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2740,6 +2740,7 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf) /* 10-byte CDB. */ r->cdb1 = req->cmd.buf[1]; r->group_number = req->cmd.buf[6]; + break; case 4: /* 12-byte CDB. */ r->cdb1 = req->cmd.buf[1]; @@ -2842,6 +2843,7 @@ static const TypeInfo scsi_disk_base_info = { .class_init = scsi_disk_base_class_initfn, .instance_size = sizeof(SCSIDiskState), .class_size = sizeof(SCSIDiskClass), + .abstract = true, }; #define DEFINE_SCSI_DISK_PROPERTIES() \ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 30415c6a92..71d09d3ef3 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -185,7 +185,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq) { VirtIOSCSIReq *req = sreq->hba_private; VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev); - uint32_t n = virtio_queue_get_id(req->vq) - 2; + uint32_t n = virtio_get_queue_index(req->vq) - 2; assert(n < vs->conf.num_queues); qemu_put_be32s(f, &n); @@ -773,22 +773,6 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) } } -static void virtio_scsi_blk_insert_notifier(Notifier *n, void *data) -{ - VirtIOSCSIBlkChangeNotifier *cn = DO_UPCAST(VirtIOSCSIBlkChangeNotifier, - n, n); - assert(cn->sd->conf.blk == data); - blk_op_block_all(cn->sd->conf.blk, cn->s->blocker); -} - -static void virtio_scsi_blk_remove_notifier(Notifier *n, void *data) -{ - VirtIOSCSIBlkChangeNotifier *cn = DO_UPCAST(VirtIOSCSIBlkChangeNotifier, - n, n); - assert(cn->sd->conf.blk == data); - blk_op_unblock_all(cn->sd->conf.blk, cn->s->blocker); -} - static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -797,29 +781,13 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, SCSIDevice *sd = SCSI_DEVICE(dev); if (s->ctx && !s->dataplane_fenced) { - VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier; - if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { return; } - blk_op_block_all(sd->conf.blk, s->blocker); aio_context_acquire(s->ctx); blk_set_aio_context(sd->conf.blk, s->ctx); aio_context_release(s->ctx); - insert_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1); - insert_notifier->n.notify = virtio_scsi_blk_insert_notifier; - insert_notifier->s = s; - insert_notifier->sd = sd; - blk_add_insert_bs_notifier(sd->conf.blk, &insert_notifier->n); - QTAILQ_INSERT_TAIL(&s->insert_notifiers, insert_notifier, next); - - remove_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1); - remove_notifier->n.notify = virtio_scsi_blk_remove_notifier; - remove_notifier->s = s; - remove_notifier->sd = sd; - blk_add_remove_bs_notifier(sd->conf.blk, &remove_notifier->n); - QTAILQ_INSERT_TAIL(&s->remove_notifiers, remove_notifier, next); } if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { @@ -835,7 +803,6 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); VirtIOSCSI *s = VIRTIO_SCSI(vdev); SCSIDevice *sd = SCSI_DEVICE(dev); - VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier; if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { virtio_scsi_push_event(s, sd, @@ -843,28 +810,6 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VIRTIO_SCSI_EVT_RESET_REMOVED); } - if (s->ctx) { - blk_op_unblock_all(sd->conf.blk, s->blocker); - } - - QTAILQ_FOREACH(insert_notifier, &s->insert_notifiers, next) { - if (insert_notifier->sd == sd) { - notifier_remove(&insert_notifier->n); - QTAILQ_REMOVE(&s->insert_notifiers, insert_notifier, next); - g_free(insert_notifier); - break; - } - } - - QTAILQ_FOREACH(remove_notifier, &s->remove_notifiers, next) { - if (remove_notifier->sd == sd) { - notifier_remove(&remove_notifier->n); - QTAILQ_REMOVE(&s->remove_notifiers, remove_notifier, next); - g_free(remove_notifier); - break; - } - } - qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); } @@ -950,11 +895,6 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1, virtio_scsi_save, virtio_scsi_load, s); - - error_setg(&s->blocker, "block device is in use by data plane"); - - QTAILQ_INIT(&s->insert_notifiers); - QTAILQ_INIT(&s->remove_notifiers); } static void virtio_scsi_instance_init(Object *obj) @@ -980,8 +920,6 @@ static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp) { VirtIOSCSI *s = VIRTIO_SCSI(dev); - error_free(s->blocker); - unregister_savevm(dev, "virtio-scsi", s); virtio_scsi_common_unrealize(dev, errp); } diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 2ac0fd3e48..a11b8b4b21 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -22,7 +22,6 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "config-target.h" #include "qemu/cutils.h" #include "qemu/bcd.h" #include "hw/hw.h" diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c index 3a43863042..5e3e8a6d70 100644 --- a/hw/timer/omap_gptimer.c +++ b/hw/timer/omap_gptimer.c @@ -133,8 +133,8 @@ static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer) timer_mod(timer->timer, timer->time + expires); if (timer->ce && timer->match_val >= timer->val) { - matches = muldiv64(timer->match_val - timer->val, - timer->ticks_per_sec, timer->rate); + matches = muldiv64(timer->ticks_per_sec, + timer->match_val - timer->val, timer->rate); timer_mod(timer->match, timer->time + matches); } else timer_del(timer->match); diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 16d9ff7b4b..fa5703832c 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -1474,7 +1474,7 @@ static uint32_t ohci_get_frame_remaining(OHCIState *ohci) if (tks >= usb_frame_time) return (ohci->frt << 31); - tks = muldiv64(1, tks, usb_bit_time); + tks = tks / usb_bit_time; fr = (uint16_t)(ohci->fi - tks); return (ohci->frt << 31) | fr; diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 8d8054037f..8ec8484349 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -542,9 +542,9 @@ static void usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p, start_iso.pkts_per_urb = 32; } - start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size + - start_iso.pkts_per_urb - 1) / - start_iso.pkts_per_urb; + start_iso.no_urbs = DIV_ROUND_UP( + dev->endpoint[EP2I(ep)].bufpq_target_size, + start_iso.pkts_per_urb); /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest as overflow buffer. Also see the usbredir protocol documentation */ if (!(ep & USB_DIR_IN)) { diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 4400718154..81cc5b0ae3 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -767,15 +767,11 @@ static inline bool vhost_needs_vring_endian(VirtIODevice *vdev) if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { return false; } -#ifdef TARGET_IS_BIENDIAN #ifdef HOST_WORDS_BIGENDIAN return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE; #else return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG; #endif -#else - return false; -#endif } static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev, diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 30ede3d1cc..7ed06eafa6 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1062,13 +1062,6 @@ int virtio_get_num_queues(VirtIODevice *vdev) return i; } -int virtio_queue_get_id(VirtQueue *vq) -{ - VirtIODevice *vdev = vq->vdev; - assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_QUEUE_MAX]); - return vq - &vdev->vq[0]; -} - void virtio_queue_set_align(VirtIODevice *vdev, int n, int align) { BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index ccf65fd8ad..2bed64f15b 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -122,8 +122,8 @@ void xtensa_rearm_ccompare_timer(CPUXtensaState *env) } env->wake_ccount = wake_ccount; timer_mod(env->ccompare_timer, env->halt_clock + - muldiv64(wake_ccount - env->sregs[CCOUNT], - 1000000, env->config->clock_freq_khz)); + (uint64_t)(wake_ccount - env->sregs[CCOUNT]) * + 1000000 / env->config->clock_freq_khz); } static void xtensa_ccompare_cb(void *opaque) diff --git a/include/block/block.h b/include/block/block.h index 70ea29947c..54cca28bac 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -33,7 +33,7 @@ typedef struct BlockDriverInfo { * True if the driver can optimize writing zeroes by unmapping * sectors. This is equivalent to the BLKDISCARDZEROES ioctl in Linux * with the difference that in qemu a discard is allowed to silently - * fail. Therefore we have to use bdrv_write_zeroes with the + * fail. Therefore we have to use bdrv_pwrite_zeroes with the * BDRV_REQ_MAY_UNMAP flag for an optimized zero write with unmapping. * After this call the driver has to guarantee that the contents read * back as zero. It is additionally required that the block device is @@ -227,11 +227,8 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); -int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags); -BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags, - BlockCompletionFunc *cb, void *opaque); +int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags); int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags); int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf, int count); @@ -250,8 +247,8 @@ int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, * function is not suitable for zeroing the entire image in a single request * because it may allocate memory for the entire region. */ -int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, BdrvRequestFlags flags); +int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, + int count, BdrvRequestFlags flags); BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_get_backing_file_depth(BlockDriverState *bs); @@ -323,27 +320,6 @@ BlockAIOCB *bdrv_aio_discard(BlockDriverState *bs, void bdrv_aio_cancel(BlockAIOCB *acb); void bdrv_aio_cancel_async(BlockAIOCB *acb); -typedef struct BlockRequest { - /* Fields to be filled by caller */ - union { - struct { - int64_t sector; - int nb_sectors; - int flags; - QEMUIOVector *qiov; - }; - struct { - int req; - void *buf; - }; - }; - BlockCompletionFunc *cb; - void *opaque; - - /* Filled by block layer */ - int error; -} BlockRequest; - /* sg packet commands */ int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf); BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index 30a97178c8..8a4963c4fe 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -163,8 +163,8 @@ struct BlockDriver { * function pointer may be NULL or return -ENOSUP and .bdrv_co_writev() * will be called instead. */ - int coroutine_fn (*bdrv_co_write_zeroes)(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); + int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs, + int64_t offset, int count, BdrvRequestFlags flags); int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs, @@ -328,11 +328,13 @@ typedef struct BlockLimits { /* optimal alignment for discard requests in sectors */ int64_t discard_alignment; - /* maximum number of sectors that can zeroized at once */ - int max_write_zeroes; + /* maximum number of bytes that can zeroized at once (since it is + * signed, it must be < 2G, if set) */ + int32_t max_pwrite_zeroes; - /* optimal alignment for write zeroes requests in sectors */ - int64_t write_zeroes_alignment; + /* optimal alignment for write zeroes requests in bytes, must be + * power of 2, and less than max_pwrite_zeroes if that is set */ + uint32_t pwrite_zeroes_alignment; /* optimal transfer length in sectors */ int opt_transfer_length; @@ -454,7 +456,7 @@ struct BlockDriverState { unsigned int request_alignment; /* Flags honored during pwrite (so far: BDRV_REQ_FUA) */ unsigned int supported_write_flags; - /* Flags honored during write_zeroes (so far: BDRV_REQ_FUA, + /* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA, * BDRV_REQ_MAY_UNMAP) */ unsigned int supported_zero_flags; diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 86d28070b8..00ac4184cc 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -397,7 +397,7 @@ int block_job_complete_sync(BlockJob *job, Error **errp); * @job: The job whose I/O status should be reset. * * Reset I/O status on @job and on BlockDriverState objects it uses, - * other than job->bs. + * other than job->blk. */ void block_job_iostatus_reset(BlockJob *job); diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 3911576431..9f38edf419 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -34,14 +34,9 @@ /* some important defines: * - * WORDS_ALIGNED : if defined, the host cpu can only make word aligned - * memory accesses. - * * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and * otherwise little endian. * - * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet)) - * * TARGET_WORDS_BIGENDIAN : same for target cpu */ diff --git a/include/exec/hwaddr.h b/include/exec/hwaddr.h index bb41588b9d..a71c93cc81 100644 --- a/include/exec/hwaddr.h +++ b/include/exec/hwaddr.h @@ -3,7 +3,6 @@ #ifndef HWADDR_H #define HWADDR_H -#include <inttypes.h> #define HWADDR_BITS 64 /* hwaddr is the type of a physical address (its size can diff --git a/include/exec/user/thunk.h b/include/exec/user/thunk.h index ad1d60266e..f19ef4b230 100644 --- a/include/exec/user/thunk.h +++ b/include/exec/user/thunk.h @@ -60,10 +60,10 @@ typedef struct { /* Translation table for bitmasks... */ typedef struct bitmask_transtbl { - unsigned int x86_mask; - unsigned int x86_bits; - unsigned int alpha_mask; - unsigned int alpha_bits; + unsigned int target_mask; + unsigned int target_bits; + unsigned int host_mask; + unsigned int host_bits; } bitmask_transtbl; void thunk_register_struct(int id, const char *name, const argtype *types); @@ -71,7 +71,6 @@ void thunk_register_struct_direct(int id, const char *name, const StructEntry *se1); const argtype *thunk_convert(void *dst, const void *src, const argtype *type_ptr, int to_host); -#ifndef NO_THUNK_TYPE_SIZE extern StructEntry *struct_entries; @@ -178,11 +177,9 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host) } } -#endif /* NO_THUNK_TYPE_SIZE */ - -unsigned int target_to_host_bitmask(unsigned int x86_mask, +unsigned int target_to_host_bitmask(unsigned int target_mask, const bitmask_transtbl * trans_tbl); -unsigned int host_to_target_bitmask(unsigned int alpha_mask, +unsigned int host_to_target_bitmask(unsigned int host_mask, const bitmask_transtbl * trans_tbl); void thunk_init(unsigned int max_structs); diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index dc6ee00885..c717f157fe 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -23,6 +23,7 @@ #include "qemu/option.h" #include "exec/memory.h" #include "hw/irq.h" +#include "hw/acpi/acpi_dev_interface.h" /* * current device naming scheme supports up to 256 memory devices @@ -89,13 +90,6 @@ /* PM2_CNT */ #define ACPI_BITMASK_ARB_DISABLE 0x0001 -/* These values are part of guest ABI, and can not be changed */ -typedef enum { - ACPI_PCI_HOTPLUG_STATUS = 2, - ACPI_CPU_HOTPLUG_STATUS = 4, - ACPI_MEMORY_HOTPLUG_STATUS = 8, -} AcpiGPEStatusBits; - /* structs */ typedef struct ACPIPMTimer ACPIPMTimer; typedef struct ACPIPM1EVT ACPIPM1EVT; @@ -172,7 +166,7 @@ void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val); uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr); void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq, - AcpiGPEStatusBits status); + AcpiEventStatusBits status); void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq); diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h index f245f8d236..a0c4a336f2 100644 --- a/include/hw/acpi/acpi_dev_interface.h +++ b/include/hw/acpi/acpi_dev_interface.h @@ -4,6 +4,13 @@ #include "qom/object.h" #include "qapi-types.h" +/* These values are part of guest ABI, and can not be changed */ +typedef enum { + ACPI_PCI_HOTPLUG_STATUS = 2, + ACPI_CPU_HOTPLUG_STATUS = 4, + ACPI_MEMORY_HOTPLUG_STATUS = 8, +} AcpiEventStatusBits; + #define TYPE_ACPI_DEVICE_IF "acpi-device-interface" #define ACPI_DEVICE_IF_CLASS(klass) \ @@ -22,11 +29,14 @@ typedef struct AcpiDeviceIf { Object Parent; } AcpiDeviceIf; +void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event); + /** * AcpiDeviceIfClass: * * ospm_status: returns status of ACPI device objects, reported * via _OST method if device supports it. + * send_event: inject a specified event into guest * * Interface is designed for providing unified interface * to generic ACPI functionality that could be used without @@ -39,5 +49,6 @@ typedef struct AcpiDeviceIfClass { /* <public> */ void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); + void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev); } AcpiDeviceIfClass; #endif diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 7eb51c7885..10c09ca29f 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -1,8 +1,8 @@ #ifndef HW_ACPI_GEN_UTILS_H #define HW_ACPI_GEN_UTILS_H -#include <glib.h> #include "hw/acpi/acpi-defs.h" +#include "hw/acpi/bios-linker-loader.h" /* Reserve RAM space for tables: add another order of magnitude. */ #define ACPI_BUILD_TABLE_MAX_SIZE 0x200000 @@ -210,7 +210,7 @@ struct AcpiBuildTables { GArray *table_data; GArray *rsdp; GArray *tcpalog; - GArray *linker; + BIOSLinker *linker; } AcpiBuildTables; /** @@ -252,6 +252,7 @@ void aml_append(Aml *parent_ctx, Aml *child); /* non block AML object primitives */ Aml *aml_name(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_name_decl(const char *name, Aml *val); +Aml *aml_debug(void); Aml *aml_return(Aml *val); Aml *aml_int(const uint64_t val); Aml *aml_arg(int pos); @@ -358,12 +359,13 @@ Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name); Aml *aml_varpackage(uint32_t num_elements); Aml *aml_touuid(const char *uuid); Aml *aml_unicode(const char *str); +Aml *aml_refof(Aml *arg); Aml *aml_derefof(Aml *arg); Aml *aml_sizeof(Aml *arg); Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target); void -build_header(GArray *linker, GArray *table_data, +build_header(BIOSLinker *linker, GArray *table_data, AcpiTableHeader *h, const char *sig, int len, uint8_t rev, const char *oem_id, const char *oem_table_id); void *acpi_data_push(GArray *table_data, unsigned size); @@ -372,7 +374,7 @@ void acpi_add_table(GArray *table_offsets, GArray *table_data); void acpi_build_tables_init(AcpiBuildTables *tables); void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre); void -build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets, +build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, const char *oem_id, const char *oem_table_id); int diff --git a/include/hw/acpi/bios-linker-loader.h b/include/hw/acpi/bios-linker-loader.h index 82f1af6433..fa1e5d1a4e 100644 --- a/include/hw/acpi/bios-linker-loader.h +++ b/include/hw/acpi/bios-linker-loader.h @@ -1,25 +1,30 @@ #ifndef BIOS_LINKER_LOADER_H #define BIOS_LINKER_LOADER_H -#include <glib.h> -GArray *bios_linker_loader_init(void); +typedef struct BIOSLinker { + GArray *cmd_blob; + GArray *file_list; +} BIOSLinker; -void bios_linker_loader_alloc(GArray *linker, - const char *file, +BIOSLinker *bios_linker_loader_init(void); + +void bios_linker_loader_alloc(BIOSLinker *linker, + const char *file_name, + GArray *file_blob, uint32_t alloc_align, bool alloc_fseg); -void bios_linker_loader_add_checksum(GArray *linker, const char *file, - GArray *table, - void *start, unsigned size, - uint8_t *checksum); +void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file, + unsigned start_offset, unsigned size, + unsigned checksum_offset); -void bios_linker_loader_add_pointer(GArray *linker, +void bios_linker_loader_add_pointer(BIOSLinker *linker, const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, const char *src_file, - GArray *table, void *pointer, - uint8_t pointer_size); + uint32_t src_offset); -void *bios_linker_loader_cleanup(GArray *linker); +void bios_linker_loader_cleanup(BIOSLinker *linker); #endif diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index f22640e389..6fef67ec14 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -15,24 +15,19 @@ #include "hw/acpi/acpi.h" #include "hw/acpi/pc-hotplug.h" #include "hw/acpi/aml-build.h" +#include "hw/hotplug.h" typedef struct AcpiCpuHotplug { MemoryRegion io; uint8_t sts[ACPI_GPE_PROC_LEN]; } AcpiCpuHotplug; -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, - AcpiCpuHotplug *g, DeviceState *dev, Error **errp); +void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp); -void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, - AcpiCpuHotplug *gpe_cpu, uint16_t base); +void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base); -#define CPU_EJECT_METHOD "CPEJ" -#define CPU_MAT_METHOD "CPMA" -#define CPU_ON_BITMAP "CPON" -#define CPU_STATUS_METHOD "CPST" -#define CPU_STATUS_MAP "PRS" -#define CPU_SCAN_METHOD "PRSC" - -void build_cpu_hotplug_aml(Aml *ctx); +void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine, + uint16_t io_base); #endif diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 63fa198145..bbd657c59b 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -69,10 +69,11 @@ extern const VMStateDescription vmstate_ich9_pm; void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); -void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp); -void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, - Error **errp); -void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, +void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); +void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp); +void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h index 3a646b12e0..d2c7452397 100644 --- a/include/hw/acpi/memory_hotplug.h +++ b/include/hw/acpi/memory_hotplug.h @@ -32,9 +32,9 @@ typedef struct MemHotplugState { void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, MemHotplugState *state); -void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, +void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp); -void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, +void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp); void acpi_memory_unplug_cb(MemHotplugState *mem_st, diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h index 79a43923e8..04528b78d9 100644 --- a/include/hw/acpi/pcihp.h +++ b/include/hw/acpi/pcihp.h @@ -29,6 +29,7 @@ #include "hw/acpi/acpi.h" #include "migration/vmstate.h" +#include "hw/hotplug.h" #define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base" #define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len" @@ -56,9 +57,9 @@ typedef struct AcpiPciHpState { void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root, MemoryRegion *address_space_io, bool bridges_enabled); -void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, +void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, DeviceState *dev, Error **errp); -void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, +void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, DeviceState *dev, Error **errp); /* Called on reset */ diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index d04dcdcfb3..88233c3077 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -35,7 +35,7 @@ typedef struct ICH9LPCState { /* (pci device, intx) -> pirq * In real chipset case, the unused slots are never used - * as ICH9 supports only D25-D32 irq routing. + * as ICH9 supports only D25-D31 irq routing. * On the other hand in qemu case, any slot/function can be populated * via command line option. * So fallback interrupt routing for any devices in any slots is necessary. @@ -181,7 +181,7 @@ Object *ich9_lpc_find(void); #define ICH9_SATA1_DEV 31 #define ICH9_SATA1_FUNC 2 -/* D30:F1 power management I/O registers +/* D31:F0 power management I/O registers offset from the address ICH9_LPC_PMBASE */ /* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */ diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h index 74a2b5af96..91b83b5bb0 100644 --- a/include/hw/ipmi/ipmi.h +++ b/include/hw/ipmi/ipmi.h @@ -65,6 +65,40 @@ enum ipmi_op { #define IPMI_SMBIOS_BT 0x03 #define IPMI_SMBIOS_SSIF 0x04 +/* + * Used for transferring information to interfaces that add + * entries to firmware tables. + */ +typedef struct IPMIFwInfo { + const char *interface_name; + int interface_type; + uint8_t ipmi_spec_major_revision; + uint8_t ipmi_spec_minor_revision; + uint8_t i2c_slave_address; + uint32_t uuid; + + uint64_t base_address; + uint64_t register_length; + uint8_t register_spacing; + enum { + IPMI_MEMSPACE_IO, + IPMI_MEMSPACE_MEM32, + IPMI_MEMSPACE_MEM64, + IPMI_MEMSPACE_SMBUS + } memspace; + + int interrupt_number; + enum { + IPMI_LEVEL_IRQ, + IPMI_EDGE_IRQ + } irq_type; +} IPMIFwInfo; + +/* + * Called by each instantiated IPMI interface device to get it's uuid. + */ +uint32_t ipmi_next_uuid(void); + /* IPMI Interface types (KCS, SMIC, BT) are prefixed with this */ #define TYPE_IPMI_INTERFACE_PREFIX "ipmi-interface-" @@ -127,6 +161,11 @@ typedef struct IPMIInterfaceClass { * Set by the owner to hold the backend data for the interface. */ void *(*get_backend_data)(struct IPMIInterface *s); + + /* + * Return the firmware info for a device. + */ + void (*get_fwinfo)(struct IPMIInterface *s, IPMIFwInfo *info); } IPMIInterfaceClass; /* @@ -168,41 +207,6 @@ typedef struct IPMIBmcClass { */ void ipmi_bmc_find_and_link(Object *obj, Object **bmc); -/* - * Used for transferring information to interfaces that add - * entries to firmware tables. - */ -typedef struct IPMIFwInfo { - const char *interface_name; - int interface_type; - uint8_t ipmi_spec_major_revision; - uint8_t ipmi_spec_minor_revision; - uint8_t i2c_slave_address; - uint32_t uuid; - - uint64_t base_address; - uint64_t register_length; - uint8_t register_spacing; - enum { - IPMI_MEMSPACE_IO, - IPMI_MEMSPACE_MEM32, - IPMI_MEMSPACE_MEM64, - IPMI_MEMSPACE_SMBUS - } memspace; - - int interrupt_number; - enum { - IPMI_LEVEL_IRQ, - IPMI_EDGE_IRQ - } irq_type; - - const char *acpi_parent; -} IPMIFwInfo; - -void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp); -IPMIFwInfo *ipmi_first_fwinfo(void); -IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current); - #ifdef IPMI_DEBUG #define ipmi_debug(fs, ...) \ fprintf(stderr, "IPMI (%s): " fs, __func__, ##__VA_ARGS__) diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h index 517de9c366..60ee92b85a 100644 --- a/include/hw/mem/nvdimm.h +++ b/include/hw/mem/nvdimm.h @@ -24,6 +24,7 @@ #define QEMU_NVDIMM_H #include "hw/mem/pc-dimm.h" +#include "hw/acpi/bios-linker-loader.h" #define NVDIMM_DEBUG 0 #define nvdimm_debug(fmt, ...) \ @@ -58,5 +59,5 @@ typedef struct AcpiNVDIMMState AcpiNVDIMMState; void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io, FWCfgState *fw_cfg, Object *owner); void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, - GArray *linker); + BIOSLinker *linker, GArray *dsm_dma_arrea); #endif diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index 8cdc3266b3..67e92d8f7b 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -58,13 +58,17 @@ typedef struct PCDIMMDevice { /** * PCDIMMDeviceClass: - * @get_memory_region: returns #MemoryRegion associated with @dimm + * @realize: called after common dimm is realized so that the dimm based + * devices get the chance to do specified operations. + * @get_memory_region: returns #MemoryRegion associated with @dimm which + * is directly mapped into the physical address space of guest */ typedef struct PCDIMMDeviceClass { /* private */ DeviceClass parent_class; /* public */ + void (*realize)(PCDIMMDevice *dimm, Error **errp); MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm); } PCDIMMDeviceClass; diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 03ee006406..7848366b2a 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -147,4 +147,6 @@ static inline void spapr_phb_vfio_reset(DeviceState *qdev) } #endif +void spapr_phb_dma_reset(sPAPRPHBState *sphb); + #endif /* __HW_SPAPR_PCI_H__ */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 815d5eec45..971df3d0df 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -539,10 +539,12 @@ struct sPAPRTCETable { uint64_t bus_offset; uint32_t page_shift; uint64_t *table; + uint32_t mig_nb_table; + uint64_t *mig_table; bool bypass; bool need_vfio; int fd; - MemoryRegion iommu; + MemoryRegion root, iommu; struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */ QLIST_ENTRY(sPAPRTCETable) list; }; @@ -561,11 +563,11 @@ void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq); int spapr_h_cas_compose_response(sPAPRMachineState *sm, target_ulong addr, target_ulong size, bool cpu_update, bool memory_update); -sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, - uint64_t bus_offset, - uint32_t page_shift, - uint32_t nb_table, - bool need_vfio); +sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn); +void spapr_tce_table_enable(sPAPRTCETable *tcet, + uint32_t page_shift, uint64_t bus_offset, + uint32_t nb_table); +void spapr_tce_table_disable(sPAPRTCETable *tcet); void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio); MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet); diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 0586cacceb..034b75acc5 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -197,8 +197,14 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, Property *prop, const char *value); /** - * @qdev_property_add_static - add a @Property to a device referencing a - * field in a struct. + * qdev_property_add_static: + * @dev: Device to add the property to. + * @prop: The qdev property definition. + * @errp: location to store error information. + * + * Add a static QOM property to @dev for qdev property @prop. + * On error, store error in @errp. Static properties access data in a struct. + * The type of the QOM property is derived from prop->info. */ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp); diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h index 8dc84f5203..4b28038146 100644 --- a/include/hw/virtio/virtio-access.h +++ b/include/hw/virtio/virtio-access.h @@ -17,9 +17,13 @@ #include "hw/virtio/virtio.h" #include "exec/address-spaces.h" +#if defined(TARGET_PPC64) || defined(TARGET_ARM) +#define LEGACY_VIRTIO_IS_BIENDIAN 1 +#endif + static inline bool virtio_access_is_big_endian(VirtIODevice *vdev) { -#if defined(TARGET_IS_BIENDIAN) +#if defined(LEGACY_VIRTIO_IS_BIENDIAN) return virtio_is_big_endian(vdev); #elif defined(TARGET_WORDS_BIGENDIAN) if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index ba2f5ce07c..b5156694e5 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -68,13 +68,6 @@ typedef struct VirtIOSCSICommon { VirtQueue **cmd_vqs; } VirtIOSCSICommon; -typedef struct VirtIOSCSIBlkChangeNotifier { - Notifier n; - struct VirtIOSCSI *s; - SCSIDevice *sd; - QTAILQ_ENTRY(VirtIOSCSIBlkChangeNotifier) next; -} VirtIOSCSIBlkChangeNotifier; - typedef struct VirtIOSCSI { VirtIOSCSICommon parent_obj; @@ -85,14 +78,10 @@ typedef struct VirtIOSCSI { /* Fields for dataplane below */ AioContext *ctx; /* one iothread per virtio-scsi-pci for now */ - QTAILQ_HEAD(, VirtIOSCSIBlkChangeNotifier) insert_notifiers; - QTAILQ_HEAD(, VirtIOSCSIBlkChangeNotifier) remove_notifiers; - bool dataplane_started; bool dataplane_starting; bool dataplane_stopping; bool dataplane_fenced; - Error *blocker; uint32_t host_features; } VirtIOSCSI; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 6a37065c23..96b581dc91 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -243,7 +243,6 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx); void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n); VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n); uint16_t virtio_get_queue_index(VirtQueue *vq); -int virtio_queue_get_id(VirtQueue *vq); EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq); void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, bool with_irqfd); diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 30ecc441de..6c65811aee 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -386,6 +386,16 @@ extern const VMStateInfo vmstate_info_bitmap; .offset = vmstate_offset_pointer(_state, _field, _type), \ } +#define VMSTATE_VARRAY_UINT32_ALLOC(_field, _state, _field_num, _version, _info, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_VARRAY_UINT32|VMS_POINTER|VMS_ALLOC, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + #define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ diff --git a/include/qemu-common.h b/include/qemu-common.h index 835cbc68b8..1f2cb94318 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -14,10 +14,6 @@ #include "qemu/fprintf-fn.h" -#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__) -#define WORDS_ALIGNED -#endif - #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) #include "qemu/option.h" diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h index 0e33fa5d9d..ec5146f84e 100644 --- a/include/qemu/bitmap.h +++ b/include/qemu/bitmap.h @@ -12,7 +12,6 @@ #ifndef BITMAP_H #define BITMAP_H -#include <glib.h> #include "qemu/bitops.h" diff --git a/include/qemu/fifo32.h b/include/qemu/fifo32.h index 2e5a0ccddf..4e9fd1b5ef 100644 --- a/include/qemu/fifo32.h +++ b/include/qemu/fifo32.h @@ -15,7 +15,6 @@ #ifndef FIFO32_H #define FIFO32_H -#include "qemu/osdep.h" #include "qemu/fifo8.h" typedef struct { diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h index 1cdae0d0ed..3de7d4ec55 100644 --- a/include/qemu/host-utils.h +++ b/include/qemu/host-utils.h @@ -486,7 +486,7 @@ static inline uint64_t revbit64(uint64_t x) static inline bool is_power_of_2(uint64_t value) { if (!value) { - return 0; + return false; } return !(value & (value - 1)); diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 56d3a682a9..83ae2808be 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -23,7 +23,6 @@ * IBM's contributions to this file may be relicensed under LGPLv2 or later. */ -#include <glib.h> #include "qemu/thread.h" #include "qemu/queue.h" diff --git a/include/qom/object.h b/include/qom/object.h index 21bb5ff149..99de539e7c 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -14,7 +14,6 @@ #ifndef QEMU_OBJECT_H #define QEMU_OBJECT_H -#include <glib.h> #include "qapi-types.h" #include "qemu/queue.h" diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 65569ed438..ad6f837bb4 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -527,4 +527,5 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source); * Returns: 0 on success, or a negative errno on failure. */ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target); +int kvm_get_max_memslots(void); #endif diff --git a/include/sysemu/tpm_backend_int.h b/include/sysemu/tpm_backend_int.h index 40f693a0cc..cc0dcb3fd2 100644 --- a/include/sysemu/tpm_backend_int.h +++ b/include/sysemu/tpm_backend_int.h @@ -22,7 +22,6 @@ #ifndef TPM_TPM_BACKEND_H #define TPM_TPM_BACKEND_H -#include <glib.h> typedef struct TPMBackendThread { GThreadPool *pool; @@ -126,6 +126,13 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_LAST_INFO }; +int kvm_get_max_memslots(void) +{ + KVMState *s = KVM_STATE(current_machine->accelerator); + + return s->nr_slots; +} + static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml) { KVMState *s = kvm_state; diff --git a/linux-user/main.c b/linux-user/main.c index 150a356e8d..f8a8764ae9 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -17,6 +17,7 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qemu-version.h" #include <sys/mman.h> #include <sys/syscall.h> #include <sys/resource.h> diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bd8095c819..71ccbd9c5e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -914,7 +914,7 @@ static inline abi_long copy_from_user_fdset(fd_set *fds, int i, nw, j, k; abi_ulong b, *target_fds; - nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; + nw = DIV_ROUND_UP(n, TARGET_ABI_BITS); if (!(target_fds = lock_user(VERIFY_READ, target_fds_addr, sizeof(abi_ulong) * nw, @@ -961,7 +961,7 @@ static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr, abi_long v; abi_ulong *target_fds; - nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; + nw = DIV_ROUND_UP(n, TARGET_ABI_BITS); if (!(target_fds = lock_user(VERIFY_WRITE, target_fds_addr, sizeof(abi_ulong) * nw, diff --git a/memory_mapping.c b/memory_mapping.c index 2354b2b7f3..e3e0d95172 100644 --- a/memory_mapping.c +++ b/memory_mapping.c @@ -13,7 +13,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include <glib.h> #include "qemu-common.h" #include "cpu.h" diff --git a/migration/block.c b/migration/block.c index e0628d187f..ebc10e628d 100644 --- a/migration/block.c +++ b/migration/block.c @@ -52,7 +52,8 @@ typedef struct BlkMigDevState { /* Written during setup phase. Can be read without a lock. */ - BlockDriverState *bs; + BlockBackend *blk; + char *blk_name; int shared_base; int64_t total_sectors; QSIMPLEQ_ENTRY(BlkMigDevState) entry; @@ -145,9 +146,9 @@ static void blk_send(QEMUFile *f, BlkMigBlock * blk) | flags); /* device name */ - len = strlen(bdrv_get_device_name(blk->bmds->bs)); + len = strlen(blk->bmds->blk_name); qemu_put_byte(f, len); - qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len); + qemu_put_buffer(f, (uint8_t *) blk->bmds->blk_name, len); /* if a block is zero we need to flush here since the network * bandwidth is now a lot higher than the storage device bandwidth. @@ -201,7 +202,7 @@ static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector) { int64_t chunk = sector / (int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK; - if (sector < bdrv_nb_sectors(bmds->bs)) { + if (sector < blk_nb_sectors(bmds->blk)) { return !!(bmds->aio_bitmap[chunk / (sizeof(unsigned long) * 8)] & (1UL << (chunk % (sizeof(unsigned long) * 8)))); } else { @@ -235,10 +236,10 @@ static void bmds_set_aio_inflight(BlkMigDevState *bmds, int64_t sector_num, static void alloc_aio_bitmap(BlkMigDevState *bmds) { - BlockDriverState *bs = bmds->bs; + BlockBackend *bb = bmds->blk; int64_t bitmap_size; - bitmap_size = bdrv_nb_sectors(bs) + BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; + bitmap_size = blk_nb_sectors(bb) + BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; bmds->aio_bitmap = g_malloc0(bitmap_size); @@ -268,19 +269,19 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) { int64_t total_sectors = bmds->total_sectors; int64_t cur_sector = bmds->cur_sector; - BlockDriverState *bs = bmds->bs; + BlockBackend *bb = bmds->blk; BlkMigBlock *blk; int nr_sectors; if (bmds->shared_base) { qemu_mutex_lock_iothread(); - aio_context_acquire(bdrv_get_aio_context(bs)); + aio_context_acquire(blk_get_aio_context(bb)); while (cur_sector < total_sectors && - !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH, - &nr_sectors)) { + !bdrv_is_allocated(blk_bs(bb), cur_sector, + MAX_IS_ALLOCATED_SEARCH, &nr_sectors)) { cur_sector += nr_sectors; } - aio_context_release(bdrv_get_aio_context(bs)); + aio_context_release(blk_get_aio_context(bb)); qemu_mutex_unlock_iothread(); } @@ -323,12 +324,12 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) * without the need to acquire the AioContext. */ qemu_mutex_lock_iothread(); - aio_context_acquire(bdrv_get_aio_context(bmds->bs)); - blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); + aio_context_acquire(blk_get_aio_context(bmds->blk)); + blk->aiocb = blk_aio_preadv(bb, cur_sector * BDRV_SECTOR_SIZE, &blk->qiov, + 0, blk_mig_read_cb, blk); bdrv_reset_dirty_bitmap(bmds->dirty_bitmap, cur_sector, nr_sectors); - aio_context_release(bdrv_get_aio_context(bmds->bs)); + aio_context_release(blk_get_aio_context(bmds->blk)); qemu_mutex_unlock_iothread(); bmds->cur_sector = cur_sector + nr_sectors; @@ -343,10 +344,10 @@ static int set_dirty_tracking(void) int ret; QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - aio_context_acquire(bdrv_get_aio_context(bmds->bs)); - bmds->dirty_bitmap = bdrv_create_dirty_bitmap(bmds->bs, BLOCK_SIZE, - NULL, NULL); - aio_context_release(bdrv_get_aio_context(bmds->bs)); + aio_context_acquire(blk_get_aio_context(bmds->blk)); + bmds->dirty_bitmap = bdrv_create_dirty_bitmap(blk_bs(bmds->blk), + BLOCK_SIZE, NULL, NULL); + aio_context_release(blk_get_aio_context(bmds->blk)); if (!bmds->dirty_bitmap) { ret = -errno; goto fail; @@ -357,9 +358,9 @@ static int set_dirty_tracking(void) fail: QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { if (bmds->dirty_bitmap) { - aio_context_acquire(bdrv_get_aio_context(bmds->bs)); - bdrv_release_dirty_bitmap(bmds->bs, bmds->dirty_bitmap); - aio_context_release(bdrv_get_aio_context(bmds->bs)); + aio_context_acquire(blk_get_aio_context(bmds->blk)); + bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap); + aio_context_release(blk_get_aio_context(bmds->blk)); } } return ret; @@ -372,9 +373,9 @@ static void unset_dirty_tracking(void) BlkMigDevState *bmds; QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - aio_context_acquire(bdrv_get_aio_context(bmds->bs)); - bdrv_release_dirty_bitmap(bmds->bs, bmds->dirty_bitmap); - aio_context_release(bdrv_get_aio_context(bmds->bs)); + aio_context_acquire(blk_get_aio_context(bmds->blk)); + bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap); + aio_context_release(blk_get_aio_context(bmds->blk)); } } @@ -384,6 +385,11 @@ static void init_blk_migration(QEMUFile *f) BlkMigDevState *bmds; int64_t sectors; BdrvNextIterator it; + int i, num_bs = 0; + struct { + BlkMigDevState *bmds; + BlockDriverState *bs; + } *bmds_bs; block_mig_state.submitted = 0; block_mig_state.read_done = 0; @@ -393,27 +399,32 @@ static void init_blk_migration(QEMUFile *f) block_mig_state.bulk_completed = 0; block_mig_state.zero_blocks = migrate_zero_blocks(); - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { + num_bs++; + } + bmds_bs = g_malloc0(num_bs * sizeof(*bmds_bs)); + + for (i = 0, bs = bdrv_first(&it); bs; bs = bdrv_next(&it), i++) { if (bdrv_is_read_only(bs)) { continue; } sectors = bdrv_nb_sectors(bs); if (sectors <= 0) { - return; + goto out; } bmds = g_new0(BlkMigDevState, 1); - bmds->bs = bs; + bmds->blk = blk_new(); + bmds->blk_name = g_strdup(bdrv_get_device_name(bs)); bmds->bulk_completed = 0; bmds->total_sectors = sectors; bmds->completed_sectors = 0; bmds->shared_base = block_mig_state.shared_base; - alloc_aio_bitmap(bmds); - error_setg(&bmds->blocker, "block device is in use by migration"); - bdrv_op_block_all(bs, bmds->blocker); - bdrv_ref(bs); + + assert(i < num_bs); + bmds_bs[i].bmds = bmds; + bmds_bs[i].bs = bs; block_mig_state.total_sector_sum += sectors; @@ -426,6 +437,24 @@ static void init_blk_migration(QEMUFile *f) QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry); } + + /* Can only insert new BDSes now because doing so while iterating block + * devices may end up in a deadlock (iterating the new BDSes, too). */ + for (i = 0; i < num_bs; i++) { + BlkMigDevState *bmds = bmds_bs[i].bmds; + BlockDriverState *bs = bmds_bs[i].bs; + + if (bmds) { + blk_insert_bs(bmds->blk, bs); + + alloc_aio_bitmap(bmds); + error_setg(&bmds->blocker, "block device is in use by migration"); + bdrv_op_block_all(bs, bmds->blocker); + } + } + +out: + g_free(bmds_bs); } /* Called with no lock taken. */ @@ -482,6 +511,7 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, int is_async) { BlkMigBlock *blk; + BlockDriverState *bs = blk_bs(bmds->blk); int64_t total_sectors = bmds->total_sectors; int64_t sector; int nr_sectors; @@ -491,11 +521,11 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, blk_mig_lock(); if (bmds_aio_inflight(bmds, sector)) { blk_mig_unlock(); - bdrv_drain(bmds->bs); + blk_drain(bmds->blk); } else { blk_mig_unlock(); } - if (bdrv_get_dirty(bmds->bs, bmds->dirty_bitmap, sector)) { + if (bdrv_get_dirty(bs, bmds->dirty_bitmap, sector)) { if (total_sectors - sector < BDRV_SECTORS_PER_DIRTY_CHUNK) { nr_sectors = total_sectors - sector; @@ -513,15 +543,18 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov, - nr_sectors, blk_mig_read_cb, blk); + blk->aiocb = blk_aio_preadv(bmds->blk, + sector * BDRV_SECTOR_SIZE, + &blk->qiov, 0, blk_mig_read_cb, + blk); blk_mig_lock(); block_mig_state.submitted++; bmds_set_aio_inflight(bmds, sector, nr_sectors, 1); blk_mig_unlock(); } else { - ret = bdrv_read(bmds->bs, sector, blk->buf, nr_sectors); + ret = blk_pread(bmds->blk, sector * BDRV_SECTOR_SIZE, blk->buf, + nr_sectors * BDRV_SECTOR_SIZE); if (ret < 0) { goto error; } @@ -559,9 +592,9 @@ static int blk_mig_save_dirty_block(QEMUFile *f, int is_async) int ret = 1; QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - aio_context_acquire(bdrv_get_aio_context(bmds->bs)); + aio_context_acquire(blk_get_aio_context(bmds->blk)); ret = mig_save_device_dirty(f, bmds, is_async); - aio_context_release(bdrv_get_aio_context(bmds->bs)); + aio_context_release(blk_get_aio_context(bmds->blk)); if (ret <= 0) { break; } @@ -619,9 +652,9 @@ static int64_t get_remaining_dirty(void) int64_t dirty = 0; QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - aio_context_acquire(bdrv_get_aio_context(bmds->bs)); + aio_context_acquire(blk_get_aio_context(bmds->blk)); dirty += bdrv_get_dirty_count(bmds->dirty_bitmap); - aio_context_release(bdrv_get_aio_context(bmds->bs)); + aio_context_release(blk_get_aio_context(bmds->blk)); } return dirty << BDRV_SECTOR_BITS; @@ -641,15 +674,16 @@ static void block_migration_cleanup(void *opaque) while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry); - bdrv_op_unblock_all(bmds->bs, bmds->blocker); + bdrv_op_unblock_all(blk_bs(bmds->blk), bmds->blocker); error_free(bmds->blocker); - /* Save ctx, because bmds->bs can disappear during bdrv_unref. */ - ctx = bdrv_get_aio_context(bmds->bs); + /* Save ctx, because bmds->blk can disappear during blk_unref. */ + ctx = blk_get_aio_context(bmds->blk); aio_context_acquire(ctx); - bdrv_unref(bmds->bs); + blk_unref(bmds->blk); aio_context_release(ctx); + g_free(bmds->blk_name); g_free(bmds->aio_bitmap); g_free(bmds); } @@ -827,8 +861,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) int len, flags; char device_name[256]; int64_t addr; - BlockDriverState *bs, *bs_prev = NULL; - BlockBackend *blk; + BlockBackend *blk, *blk_prev = NULL;; Error *local_err = NULL; uint8_t *buf; int64_t total_sectors = 0; @@ -853,23 +886,17 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) device_name); return -EINVAL; } - bs = blk_bs(blk); - if (!bs) { - fprintf(stderr, "Block device %s has no medium\n", - device_name); - return -EINVAL; - } - if (bs != bs_prev) { - bs_prev = bs; - total_sectors = bdrv_nb_sectors(bs); + if (blk != blk_prev) { + blk_prev = blk; + total_sectors = blk_nb_sectors(blk); if (total_sectors <= 0) { error_report("Error getting length of block device %s", device_name); return -EINVAL; } - bdrv_invalidate_cache(bs, &local_err); + blk_invalidate_cache(blk, &local_err); if (local_err) { error_report_err(local_err); return -EINVAL; @@ -883,12 +910,14 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) } if (flags & BLK_MIG_FLAG_ZERO_BLOCK) { - ret = bdrv_write_zeroes(bs, addr, nr_sectors, + ret = blk_pwrite_zeroes(blk, addr * BDRV_SECTOR_SIZE, + nr_sectors * BDRV_SECTOR_SIZE, BDRV_REQ_MAY_UNMAP); } else { buf = g_malloc(BLOCK_SIZE); qemu_get_buffer(f, buf, BLOCK_SIZE); - ret = bdrv_write(bs, addr, buf, nr_sectors); + ret = blk_pwrite(blk, addr * BDRV_SECTOR_SIZE, buf, + nr_sectors * BDRV_SECTOR_SIZE, 0); g_free(buf); } diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index cf7dcd25d4..47250b675d 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -17,7 +17,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "migration/migration.h" @@ -320,7 +320,7 @@ static void monitor_flush_locked(Monitor *mon) return; } if (rc > 0) { - /* partinal write */ + /* partial write */ QString *tmp = qstring_from_str(buf + rc); QDECREF(mon->outbuf); mon->outbuf = tmp; diff --git a/page_cache.c b/page_cache.c index 37a66e497b..a2809db2f5 100644 --- a/page_cache.c +++ b/page_cache.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/host-utils.h" diff --git a/po/Makefile b/po/Makefile index b271f79ba2..7bab09dce2 100644 --- a/po/Makefile +++ b/po/Makefile @@ -32,7 +32,7 @@ update: $(SRCS) build: $(OBJS) clean: - $(RM) $(OBJS) + rm -f $(OBJS) install: $(OBJS) for obj in $(OBJS); do \ diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index 4332a6818d..68b24c98b0 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/dispatch.h" static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands = diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c index 830fb9e269..5396fbfbb6 100644 --- a/qemu-bridge-helper.c +++ b/qemu-bridge-helper.c @@ -15,7 +15,6 @@ #include "qemu/osdep.h" -#include <glib.h> #include <sys/ioctl.h> #include <sys/socket.h> diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index e7cded6e24..7e95b2da79 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -9,6 +9,12 @@ STEXI @table @option ETEXI +DEF("bench", img_bench, + "bench [-c count] [-d depth] [-f fmt] [--flush-interval=flush_interval] [-n] [--no-drain] [-o offset] [--pattern=pattern] [-q] [-s buffer_size] [-S step_size] [-t cache] [-w] filename") +STEXI +@item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] [--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] [--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] @var{filename} +ETEXI + DEF("check", img_check, "check [-q] [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename") STEXI diff --git a/qemu-img.c b/qemu-img.c index 4b56ad36aa..251386b49d 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qemu-version.h" #include "qapi/error.h" #include "qapi-visit.h" #include "qapi/qmp-output-visitor.h" @@ -53,6 +54,9 @@ enum { OPTION_BACKING_CHAIN = 257, OPTION_OBJECT = 258, OPTION_IMAGE_OPTS = 259, + OPTION_PATTERN = 260, + OPTION_FLUSH_INTERVAL = 261, + OPTION_NO_DRAIN = 262, }; typedef enum OutputFormat { @@ -3459,6 +3463,332 @@ out_no_progress: return 0; } +typedef struct BenchData { + BlockBackend *blk; + uint64_t image_size; + bool write; + int bufsize; + int step; + int nrreq; + int n; + int flush_interval; + bool drain_on_flush; + uint8_t *buf; + QEMUIOVector *qiov; + + int in_flight; + bool in_flush; + uint64_t offset; +} BenchData; + +static void bench_undrained_flush_cb(void *opaque, int ret) +{ + if (ret < 0) { + error_report("Failed flush request: %s\n", strerror(-ret)); + exit(EXIT_FAILURE); + } +} + +static void bench_cb(void *opaque, int ret) +{ + BenchData *b = opaque; + BlockAIOCB *acb; + + if (ret < 0) { + error_report("Failed request: %s\n", strerror(-ret)); + exit(EXIT_FAILURE); + } + + if (b->in_flush) { + /* Just finished a flush with drained queue: Start next requests */ + assert(b->in_flight == 0); + b->in_flush = false; + } else if (b->in_flight > 0) { + int remaining = b->n - b->in_flight; + + b->n--; + b->in_flight--; + + /* Time for flush? Drain queue if requested, then flush */ + if (b->flush_interval && remaining % b->flush_interval == 0) { + if (!b->in_flight || !b->drain_on_flush) { + BlockCompletionFunc *cb; + + if (b->drain_on_flush) { + b->in_flush = true; + cb = bench_cb; + } else { + cb = bench_undrained_flush_cb; + } + + acb = blk_aio_flush(b->blk, cb, b); + if (!acb) { + error_report("Failed to issue flush request"); + exit(EXIT_FAILURE); + } + } + if (b->drain_on_flush) { + return; + } + } + } + + while (b->n > b->in_flight && b->in_flight < b->nrreq) { + if (b->write) { + acb = blk_aio_pwritev(b->blk, b->offset, b->qiov, 0, + bench_cb, b); + } else { + acb = blk_aio_preadv(b->blk, b->offset, b->qiov, 0, + bench_cb, b); + } + if (!acb) { + error_report("Failed to issue request"); + exit(EXIT_FAILURE); + } + b->in_flight++; + b->offset += b->step; + b->offset %= b->image_size; + } +} + +static int img_bench(int argc, char **argv) +{ + int c, ret = 0; + const char *fmt = NULL, *filename; + bool quiet = false; + bool image_opts = false; + bool is_write = false; + int count = 75000; + int depth = 64; + int64_t offset = 0; + size_t bufsize = 4096; + int pattern = 0; + size_t step = 0; + int flush_interval = 0; + bool drain_on_flush = true; + int64_t image_size; + BlockBackend *blk = NULL; + BenchData data = {}; + int flags = 0; + bool writethrough; + struct timeval t1, t2; + int i; + + for (;;) { + static const struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"flush-interval", required_argument, 0, OPTION_FLUSH_INTERVAL}, + {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, + {"pattern", required_argument, 0, OPTION_PATTERN}, + {"no-drain", no_argument, 0, OPTION_NO_DRAIN}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, "hc:d:f:no:qs:S:t:w", long_options, NULL); + if (c == -1) { + break; + } + + switch (c) { + case 'h': + case '?': + help(); + break; + case 'c': + { + char *end; + errno = 0; + count = strtoul(optarg, &end, 0); + if (errno || *end || count > INT_MAX) { + error_report("Invalid request count specified"); + return 1; + } + break; + } + case 'd': + { + char *end; + errno = 0; + depth = strtoul(optarg, &end, 0); + if (errno || *end || depth > INT_MAX) { + error_report("Invalid queue depth specified"); + return 1; + } + break; + } + case 'f': + fmt = optarg; + break; + case 'n': + flags |= BDRV_O_NATIVE_AIO; + break; + case 'o': + { + char *end; + errno = 0; + offset = qemu_strtosz_suffix(optarg, &end, + QEMU_STRTOSZ_DEFSUFFIX_B); + if (offset < 0|| *end) { + error_report("Invalid offset specified"); + return 1; + } + break; + } + break; + case 'q': + quiet = true; + break; + case 's': + { + int64_t sval; + char *end; + + sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B); + if (sval < 0 || sval > INT_MAX || *end) { + error_report("Invalid buffer size specified"); + return 1; + } + + bufsize = sval; + break; + } + case 'S': + { + int64_t sval; + char *end; + + sval = qemu_strtosz_suffix(optarg, &end, QEMU_STRTOSZ_DEFSUFFIX_B); + if (sval < 0 || sval > INT_MAX || *end) { + error_report("Invalid step size specified"); + return 1; + } + + step = sval; + break; + } + case 't': + ret = bdrv_parse_cache_mode(optarg, &flags, &writethrough); + if (ret < 0) { + error_report("Invalid cache mode"); + ret = -1; + goto out; + } + break; + case 'w': + flags |= BDRV_O_RDWR; + is_write = true; + break; + case OPTION_PATTERN: + { + char *end; + errno = 0; + pattern = strtoul(optarg, &end, 0); + if (errno || *end || pattern > 0xff) { + error_report("Invalid pattern byte specified"); + return 1; + } + break; + } + case OPTION_FLUSH_INTERVAL: + { + char *end; + errno = 0; + flush_interval = strtoul(optarg, &end, 0); + if (errno || *end || flush_interval > INT_MAX) { + error_report("Invalid flush interval specified"); + return 1; + } + break; + } + case OPTION_NO_DRAIN: + drain_on_flush = false; + break; + case OPTION_IMAGE_OPTS: + image_opts = true; + break; + } + } + + if (optind != argc - 1) { + error_exit("Expecting one image file name"); + } + filename = argv[argc - 1]; + + if (!is_write && flush_interval) { + error_report("--flush-interval is only available in write tests"); + ret = -1; + goto out; + } + if (flush_interval && flush_interval < depth) { + error_report("Flush interval can't be smaller than depth"); + ret = -1; + goto out; + } + + blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet); + if (!blk) { + ret = -1; + goto out; + } + + image_size = blk_getlength(blk); + if (image_size < 0) { + ret = image_size; + goto out; + } + + data = (BenchData) { + .blk = blk, + .image_size = image_size, + .bufsize = bufsize, + .step = step ?: bufsize, + .nrreq = depth, + .n = count, + .offset = offset, + .write = is_write, + .flush_interval = flush_interval, + .drain_on_flush = drain_on_flush, + }; + printf("Sending %d %s requests, %d bytes each, %d in parallel " + "(starting at offset %" PRId64 ", step size %d)\n", + data.n, data.write ? "write" : "read", data.bufsize, data.nrreq, + data.offset, data.step); + if (flush_interval) { + printf("Sending flush every %d requests\n", flush_interval); + } + + data.buf = blk_blockalign(blk, data.nrreq * data.bufsize); + memset(data.buf, pattern, data.nrreq * data.bufsize); + + data.qiov = g_new(QEMUIOVector, data.nrreq); + for (i = 0; i < data.nrreq; i++) { + qemu_iovec_init(&data.qiov[i], 1); + qemu_iovec_add(&data.qiov[i], + data.buf + i * data.bufsize, data.bufsize); + } + + gettimeofday(&t1, NULL); + bench_cb(&data, 0); + + while (data.n > 0) { + main_loop_wait(false); + } + gettimeofday(&t2, NULL); + + printf("Run completed in %3.3f seconds.\n", + (t2.tv_sec - t1.tv_sec) + + ((double)(t2.tv_usec - t1.tv_usec) / 1000000)); + +out: + qemu_vfree(data.buf); + blk_unref(blk); + + if (ret) { + return 1; + } + return 0; +} + + static const img_cmd_t img_cmds[] = { #define DEF(option, callback, arg_string) \ { option, callback }, diff --git a/qemu-img.texi b/qemu-img.texi index afaebdd408..cbe50e9b88 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -131,6 +131,30 @@ Skip the creation of the target volume Command description: @table @option +@item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] [--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] [--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] @var{filename} + +Run a simple sequential I/O benchmark on the specified image. If @code{-w} is +specified, a write test is performed, otherwise a read test is performed. + +A total number of @var{count} I/O requests is performed, each @var{buffer_size} +bytes in size, and with @var{depth} requests in parallel. The first request +starts at the position given by @var{offset}, each following request increases +the current position by @var{step_size}. If @var{step_size} is not given, +@var{buffer_size} is used for its value. + +If @var{flush_interval} is specified for a write test, the request queue is +drained and a flush is issued before new writes are made whenever the number of +remaining requests is a multiple of @var{flush_interval}. If additionally +@code{--no-drain} is specified, a flush is issued without draining the request +queue first. + +If @code{-n} is specified, the native AIO backend is used if possible. On +Linux, this option only works if @code{-t none} or @code{-t directsync} is +specified as well. + +For write tests, by default a buffer filled with zeros is written. This can be +overridden with a pattern byte specified by @var{pattern}. + @item check [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename} Perform a consistency check on the disk image @var{filename}. The command can diff --git a/qemu-options.hx b/qemu-options.hx index 9f33361876..0e42ba55be 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " kernel_irqchip=on|off controls accelerated irqchip support\n" " kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n" " vmport=on|off|auto controls emulation of vmport (default: auto)\n" - " kvm_shadow_mem=size of KVM shadow MMU\n" + " kvm_shadow_mem=size of KVM shadow MMU in bytes\n" " dump-guest-core=on|off include guest memory in a core dump (default=on)\n" " mem-merge=on|off controls memory merge support (default: on)\n" " iommu=on|off controls emulated Intel IOMMU (VT-d) support (default=off)\n" @@ -569,7 +569,7 @@ These options have the same definition as they have in @option{-hdachs}. @var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and controls whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap}) requests are ignored or passed to the filesystem. Some machine types may not support discard requests. @item format=@var{format} Specify which disk @var{format} will be used rather than detecting -the format. Can be used to specifiy format=raw to avoid interpreting +the format. Can be used to specify format=raw to avoid interpreting an untrusted format header. @item serial=@var{serial} This option specifies the serial number to assign to the device. @@ -894,7 +894,7 @@ mouse. Also overrides the PS/2 mouse emulation when activated. @item disk:[format=@var{format}]:@var{file} Mass storage device based on file. The optional @var{format} argument -will be used rather than detecting the format. Can be used to specifiy +will be used rather than detecting the format. Can be used to specify @code{format=raw} to avoid interpreting an untrusted format header. @item host:@var{bus}.@var{addr} @@ -1241,6 +1241,13 @@ syntax for the @var{display} is @table @option +@item to=@var{L} + +With this option, QEMU will try next available VNC @var{display}s, until the +number @var{L}, if the origianlly defined "-vnc @var{display}" is not +available, e.g. port 5900+@var{display} is already used by another +application. By default, to=0. + @item @var{host}:@var{d} TCP connections will only be allowed from @var{host} on display @var{d}. diff --git a/qemu-timer.c b/qemu-timer.c index 4441fe66ff..eb22e9218b 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -292,7 +292,7 @@ int qemu_timeout_ns_to_ms(int64_t ns) /* Always round up, because it's better to wait too long than to wait too * little and effectively busy-wait */ - ms = (ns + SCALE_MS - 1) / SCALE_MS; + ms = DIV_ROUND_UP(ns, SCALE_MS); /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */ if (ms > (int64_t) INT32_MAX) { diff --git a/qga/channel-posix.c b/qga/channel-posix.c index 63458c6632..bb65d8ba17 100644 --- a/qga/channel-posix.c +++ b/qga/channel-posix.c @@ -1,5 +1,4 @@ #include "qemu/osdep.h" -#include <glib.h> #include <termios.h> #include "qapi/error.h" #include "qemu/sockets.h" diff --git a/qga/channel-win32.c b/qga/channel-win32.c index 68168d14a5..21f9deedf6 100644 --- a/qga/channel-win32.c +++ b/qga/channel-win32.c @@ -1,5 +1,4 @@ #include "qemu/osdep.h" -#include <glib.h> #include <windows.h> #include <io.h> #include "qga/guest-agent-core.h" diff --git a/qga/channel.h b/qga/channel.h index 3704ea9c86..ae8cf0f7e0 100644 --- a/qga/channel.h +++ b/qga/channel.h @@ -12,7 +12,6 @@ #ifndef QGA_CHANNEL_H #define QGA_CHANNEL_H -#include <glib.h> typedef struct GAChannel GAChannel; diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 2ae37255d4..eaef7be42e 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <dirent.h> @@ -1242,8 +1241,8 @@ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, goto error; } - /* we try to cull filesytems we know won't work in advance, but other - * filesytems may not implement fsfreeze for less obvious reasons. + /* we try to cull filesystems we know won't work in advance, but other + * filesystems may not implement fsfreeze for less obvious reasons. * these will report EOPNOTSUPP. we simply ignore these when tallying * the number of frozen filesystems. * @@ -1392,10 +1391,10 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) continue; } - /* We try to cull filesytems we know won't work in advance, but other - * filesytems may not implement fstrim for less obvious reasons. These - * will report EOPNOTSUPP; while in some other cases ENOTTY will be - * reported (e.g. CD-ROMs). + /* We try to cull filesystems we know won't work in advance, but other + * filesystems may not implement fstrim for less obvious reasons. + * These will report EOPNOTSUPP; while in some other cases ENOTTY + * will be reported (e.g. CD-ROMs). * Any other error means an unexpected error. */ r.start = 0; diff --git a/qga/commands-win32.c b/qga/commands-win32.c index d76327f5a3..c1a8588206 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <wtypes.h> #include <powrprof.h> #include <winsock2.h> diff --git a/qga/commands.c b/qga/commands.c index 31444643e2..50fd26a817 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qga/guest-agent-core.h" #include "qga-qmp-commands.h" #include "qapi/qmp/qerror.h" diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c index 20b9b22224..4de229cd78 100644 --- a/qga/guest-agent-command-state.c +++ b/qga/guest-agent-command-state.c @@ -10,7 +10,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qga/guest-agent-core.h" struct GACommandState { diff --git a/qga/main.c b/qga/main.c index c552782101..4c3b2c772b 100644 --- a/qga/main.c +++ b/qga/main.c @@ -11,7 +11,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include <getopt.h> #include <glib/gstdio.h> #ifndef _WIN32 diff --git a/qga/service-win32.c b/qga/service-win32.c index 72437587b0..fd434e3f49 100644 --- a/qga/service-win32.c +++ b/qga/service-win32.c @@ -11,7 +11,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include <windows.h> #include "qga/service-win32.h" @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qemu-version.h" #include "qemu/cutils.h" #include "monitor/monitor.h" #include "sysemu/sysemu.h" diff --git a/replay/replay-char.c b/replay/replay-char.c index 23b6922977..edf46ab9df 100755 --- a/replay/replay-char.c +++ b/replay/replay-char.c @@ -9,10 +9,6 @@ * */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - #include "qemu/osdep.h" #include "qemu/error-report.h" #include "sysemu/replay.h" @@ -95,7 +95,7 @@ module-common.o: CFLAGS += $(DSO_OBJ_CFLAGS) $(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), " CP $(subst /,-,$@)")) -LD_REL := $(CC) -nostdlib -Wl,-r +LD_REL := $(CC) -nostdlib -Wl,-r $(LD_REL_FLAGS) %.mo: $(call quiet-command,$(LD_REL) -o $@ $^," LD -r $(TARGET_DIR)$@") @@ -172,7 +172,7 @@ TRACETOOL=$(PYTHON) $(SRC_PATH)/scripts/tracetool.py config-%.h: config-%.h-timestamp @cmp $< $@ >/dev/null 2>&1 || cp $< $@ -config-%.h-timestamp: config-%.mak +config-%.h-timestamp: config-%.mak $(SRC_PATH)/scripts/create_config $(call quiet-command, sh $(SRC_PATH)/scripts/create_config < $< > $@, " GEN $(TARGET_DIR)config-$*.h") .PHONY: clean-timestamp diff --git a/scripts/clean-includes b/scripts/clean-includes index 72b47f17f9..37b73b5433 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -39,7 +39,7 @@ # However some caution is required regarding files that might be part # of the guest agent or standalone tests. -# for i in `git ls-tree --name-only HEAD` ; do test -f $i && \ +# for i in $(git ls-tree --name-only HEAD) ; do test -f $i && \ # grep -E '^# *include' $i | head -1 | grep 'osdep.h' ; test $? != 0 && \ # echo $i ; done @@ -104,6 +104,7 @@ for f in "$@"; do ;; *include/qemu/osdep.h | \ *include/qemu/compiler.h | \ + *include/glib-compat.h | \ *include/standard-headers/ ) # Removing include lines from osdep.h itself would be counterproductive. echo "SKIPPING $f (special case header)" @@ -143,7 +144,7 @@ for f in "$@"; do <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h> <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h> <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h> - <sys/stat.h> <sys/time.h> <assert.h> <signal.h> + <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h" "qemu/typedefs.h" ))' "$f" diff --git a/scripts/coccinelle/overflow_muldiv64.cocci b/scripts/coccinelle/overflow_muldiv64.cocci new file mode 100644 index 0000000000..08ec4a8de0 --- /dev/null +++ b/scripts/coccinelle/overflow_muldiv64.cocci @@ -0,0 +1,16 @@ +// Find muldiv64(i64, i64, x) for potential overflow +@filter@ +typedef uint64_t; +typedef int64_t; +{ uint64_t, int64_t, long, unsigned long } a, b; +expression c; +position p; +@@ + +muldiv64(a,b,c)@p + +@script:python@ +p << filter.p; +@@ + +cocci.print_main("potential muldiv64() overflow", p) diff --git a/scripts/coccinelle/remove_muldiv64.cocci b/scripts/coccinelle/remove_muldiv64.cocci new file mode 100644 index 0000000000..4c10bd57dd --- /dev/null +++ b/scripts/coccinelle/remove_muldiv64.cocci @@ -0,0 +1,6 @@ +// replace muldiv64(a, 1, b) by "a / b" +@@ +expression a, b; +@@ +-muldiv64(a, 1, b) ++a / b diff --git a/scripts/coccinelle/round.cocci b/scripts/coccinelle/round.cocci new file mode 100644 index 0000000000..ed06773289 --- /dev/null +++ b/scripts/coccinelle/round.cocci @@ -0,0 +1,19 @@ +// Use macro DIV_ROUND_UP instead of (((n) + (d) - 1) /(d)) +@@ +expression e1; +expression e2; +@@ +( +- ((e1) + e2 - 1) / (e2) ++ DIV_ROUND_UP(e1,e2) +| +- ((e1) + (e2 - 1)) / (e2) ++ DIV_ROUND_UP(e1,e2) +) + +@@ +expression e1; +expression e2; +@@ +-(DIV_ROUND_UP(e1,e2)) ++DIV_ROUND_UP(e1,e2) diff --git a/scripts/coccinelle/simplify_muldiv64.cocci b/scripts/coccinelle/simplify_muldiv64.cocci new file mode 100644 index 0000000000..3d7c9744aa --- /dev/null +++ b/scripts/coccinelle/simplify_muldiv64.cocci @@ -0,0 +1,11 @@ +// replace muldiv64(i32, i32, x) by (uint64_t)i32 * i32 / x +@@ +typedef uint32_t; +typedef int32_t; +{ uint32_t, int32_t, int, unsigned int } a, b; +typedef uint64_t; +expression c; +@@ + +-muldiv64(a,b,c) ++(uint64_t) a * b / c diff --git a/scripts/coccinelle/swap_muldiv64.cocci b/scripts/coccinelle/swap_muldiv64.cocci new file mode 100644 index 0000000000..b48b0d084a --- /dev/null +++ b/scripts/coccinelle/swap_muldiv64.cocci @@ -0,0 +1,13 @@ +// replace muldiv64(i32, i64, x) by muldiv64(i64, i32, x) +@@ +typedef uint64_t; +typedef int64_t; +typedef uint32_t; +typedef int32_t; +{ uint32_t, int32_t, int, unsigned int } a; +{ uint64_t, int64_t, long, unsigned long } b; +expression c; +@@ + +-muldiv64(a,b,c) ++muldiv64(b,a,c) diff --git a/scripts/create_config b/scripts/create_config index b2d2ebb452..1dd6a354f5 100755 --- a/scripts/create_config +++ b/scripts/create_config @@ -9,14 +9,10 @@ case $line in version=${line#*=} echo "#define QEMU_VERSION \"$version\"" ;; - PKGVERSION=*) # configuration - pkgversion=${line#*=} - echo "#define QEMU_PKGVERSION \"$pkgversion\"" - ;; qemu_*dir=*) # qemu-specific directory configuration name=${line%=*} value=${line#*=} - define_name=`echo $name | LC_ALL=C tr '[a-z]' '[A-Z]'` + define_name=$(echo $name | LC_ALL=C tr '[a-z]' '[A-Z]') eval "define_value=\"$value\"" echo "#define CONFIG_$define_name \"$define_value\"" # save for the next definitions @@ -72,7 +68,7 @@ case $line in ;; ARCH=*) # configuration arch=${line#*=} - arch_name=`echo $arch | LC_ALL=C tr '[a-z]' '[A-Z]'` + arch_name=$(echo $arch | LC_ALL=C tr '[a-z]' '[A-Z]') echo "#define HOST_$arch_name 1" ;; HOST_USB=*) @@ -92,7 +88,7 @@ case $line in ;; TARGET_BASE_ARCH=*) # configuration target_base_arch=${line#*=} - base_arch_name=`echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]'` + base_arch_name=$(echo $target_base_arch | LC_ALL=C tr '[a-z]' '[A-Z]') echo "#define TARGET_$base_arch_name 1" ;; TARGET_XML_FILES=*) diff --git a/scripts/feature_to_c.sh b/scripts/feature_to_c.sh index e4387b7fcf..c8ce9b88f6 100644 --- a/scripts/feature_to_c.sh +++ b/scripts/feature_to_c.sh @@ -33,7 +33,7 @@ if test -e "$output"; then fi for input; do - arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'` + arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g') ${AWK:-awk} 'BEGIN { n = 0 printf "#include \"qemu/osdep.h\"\n" @@ -67,8 +67,8 @@ echo >> $output echo "const char *const xml_builtin[][2] = {" >> $output for input; do - basename=`echo $input | sed 's,.*/,,'` - arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'` + basename=$(echo $input | sed 's,.*/,,') + arrayname=xml_feature_$(echo $input | sed 's,.*/,,; s/[-.]/_/g') echo " { \"$basename\", $arrayname }," >> $output done diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh index c1afb3ffaa..354af317b3 100644 --- a/scripts/make_device_config.sh +++ b/scripts/make_device_config.sh @@ -7,7 +7,7 @@ src=$1 dep=$2 target=$3 -src_dir=`dirname $src` +src_dir=$(dirname $src) all_includes= process_includes () { @@ -20,7 +20,7 @@ process_includes () { f=$src while [ -n "$f" ] ; do - f=`cat $f | tr -d '\r' | awk '/^include / {printf "'$src_dir'/%s ", $2}'` + f=$(cat $f | tr -d '\r' | awk '/^include / {printf "'$src_dir'/%s ", $2}') [ $? = 0 ] || exit 1 all_includes="$all_includes $f" done diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index f7d62d974f..08c4c4ae54 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -10,7 +10,7 @@ # This work is licensed under the terms of the GNU GPL version 2. # See the COPYING file in the top-level directory. -tmpdir=`mktemp -d` +tmpdir=$(mktemp -d) linux="$1" output="$2" diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c index aed2f13af5..8fb563321b 100644 --- a/slirp/dnssearch.c +++ b/slirp/dnssearch.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "slirp.h" static const uint8_t RFC3397_OPT_DOMAIN_SEARCH = 119; @@ -262,7 +261,7 @@ int translate_dnssearch(Slirp *s, const char **names) } /* reserve extra 2 header bytes for each 255 bytes of output */ - memreq += ((memreq + MAX_OPT_LEN - 1) / MAX_OPT_LEN) * OPT_HEADER_LEN; + memreq += DIV_ROUND_UP(memreq, MAX_OPT_LEN) * OPT_HEADER_LEN; result = g_malloc(memreq * sizeof(*result)); outptr = result; @@ -289,7 +288,7 @@ int translate_dnssearch(Slirp *s, const char **names) domain_mkxrefs(domains, domains + num_domains - 1, 0); memreq = domain_compactify(domains, num_domains); - blocks = (memreq + MAX_OPT_LEN - 1) / MAX_OPT_LEN; + blocks = DIV_ROUND_UP(memreq, MAX_OPT_LEN); bsrc_end = memreq; bsrc_start = (blocks - 1) * MAX_OPT_LEN; bdst_start = bsrc_start + blocks * OPT_HEADER_LEN; diff --git a/slirp/slirp.h b/slirp/slirp.h index 5df755e697..e3641f9eba 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -69,7 +69,6 @@ typedef char *caddr_t; #include <sys/stropts.h> #endif -#include <glib.h> #include "debug.h" diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 401955f825..17d80510da 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -29,8 +29,6 @@ # define TARGET_LONG_BITS 32 #endif -#define TARGET_IS_BIENDIAN 1 - #define CPUArchState struct CPUARMState #include "qemu-common.h" diff --git a/target-moxie/mmu.h b/target-moxie/mmu.h index abc79297cd..284a44d18e 100644 --- a/target-moxie/mmu.h +++ b/target-moxie/mmu.h @@ -6,11 +6,6 @@ typedef struct { uint32_t phy; uint32_t pfn; - unsigned g:1; - unsigned v:1; - unsigned k:1; - unsigned w:1; - unsigned e:1; int cause_op; } MoxieMMUResult; diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 98a24a50f3..cb8b9122f3 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -28,8 +28,6 @@ #define TARGET_LONG_BITS 64 #define TARGET_PAGE_BITS 12 -#define TARGET_IS_BIENDIAN 1 - /* Note that the official physical address space bits is 62-M where M is implementation dependent. I've not looked up M for the set of cpus we emulate at the system level. */ @@ -959,7 +957,6 @@ struct CPUPPCState { ppc_slb_t slb[MAX_SLB_ENTRIES]; int32_t slb_nr; /* tcg TLB needs flush (deferred slb inval instruction typically) */ - uint32_t tlb_need_flush; #endif /* segment registers */ hwaddr htab_base; @@ -985,6 +982,7 @@ struct CPUPPCState { target_ulong pb[4]; bool tlb_dirty; /* Set to non-zero when modifying TLB */ bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active */ + uint32_t tlb_need_flush; /* Delayed flush needed */ #endif /* Other registers */ @@ -1050,6 +1048,10 @@ struct CPUPPCState { hwaddr mpic_iack; /* true when the external proxy facility mode is enabled */ bool mpic_proxy; + /* set when the processor has an HV mode, thus HV priv + * instructions and SPRs are diallowed if MSR:HV is 0 + */ + bool has_hv_mode; #endif /* Those resources are used only during code translation */ diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c index a37009eb25..30e960e30b 100644 --- a/target-ppc/excp_helper.c +++ b/target-ppc/excp_helper.c @@ -709,8 +709,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } } #endif - /* XXX: we don't use hreg_store_msr here as already have treated - * any special case that could occur. Just store MSR and update hflags + /* We don't use hreg_store_msr here as already have treated + * any special case that could occur. Just store MSR and update hflags + * + * Note: We *MUST* not use hreg_store_msr() as-is anyway because it + * will prevent setting of the HV bit which some exceptions might need + * to do. */ env->msr = new_msr & env->msr_mask; hreg_compute_hflags(env); diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index b67ebca126..6fd56a868d 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1442,7 +1442,7 @@ static inline uint32_t efststeq(CPUPPCState *env, uint32_t op1, uint32_t op2) #define HELPER_SINGLE_SPE_CMP(name) \ uint32_t helper_e##name(CPUPPCState *env, uint32_t op1, uint32_t op2) \ { \ - return e##name(env, op1, op2) << 2; \ + return e##name(env, op1, op2); \ } /* efststlt */ HELPER_SINGLE_SPE_CMP(fststlt); diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 0526322f4d..f4410a8369 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -550,6 +550,7 @@ DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(load_slb_esid, tl, env, tl) DEF_HELPER_2(load_slb_vsid, tl, env, tl) +DEF_HELPER_2(find_slb_vsid, tl, env, tl) DEF_HELPER_FLAGS_1(slbia, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl) #endif diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h index 57da931e3c..8fc09344db 100644 --- a/target-ppc/helper_regs.h +++ b/target-ppc/helper_regs.h @@ -95,7 +95,7 @@ static inline void hreg_compute_hflags(CPUPPCState *env) /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */ hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) | (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | - (1 << MSR_LE) | (1 << MSR_VSX); + (1 << MSR_LE) | (1 << MSR_VSX) | (1 << MSR_IR) | (1 << MSR_DR); hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; hreg_compute_mem_idx(env); env->hflags = env->msr & hflags_mask; @@ -114,8 +114,8 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, excp = 0; value &= env->msr_mask; #if !defined(CONFIG_USER_ONLY) - if (!alter_hv) { - /* mtmsr cannot alter the hypervisor state */ + /* Neither mtmsr nor guest state can alter HV */ + if (!alter_hv || !(env->msr & MSR_HVB)) { value &= ~MSR_HVB; value |= env->msr & MSR_HVB; } @@ -151,7 +151,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, return excp; } -#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) +#if !defined(CONFIG_USER_ONLY) static inline void check_tlb_flush(CPUPPCState *env) { CPUState *cs = CPU(ppc_env_get_cpu(env)); diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index ea6e99acd1..668da5e226 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -219,6 +219,24 @@ static int ppc_load_slb_vsid(PowerPCCPU *cpu, target_ulong rb, return 0; } +static int ppc_find_slb_vsid(PowerPCCPU *cpu, target_ulong rb, + target_ulong *rt) +{ + CPUPPCState *env = &cpu->env; + ppc_slb_t *slb; + + if (!msr_is_64bit(env, env->msr)) { + rb &= 0xffffffff; + } + slb = slb_lookup(cpu, rb); + if (slb == NULL) { + *rt = (target_ulong)-1ul; + } else { + *rt = slb->vsid; + } + return 0; +} + void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) { PowerPCCPU *cpu = ppc_env_get_cpu(env); @@ -241,6 +259,18 @@ target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) return rt; } +target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb) +{ + PowerPCCPU *cpu = ppc_env_get_cpu(env); + target_ulong rt = 0; + + if (ppc_find_slb_vsid(cpu, rb, &rt) < 0) { + helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_INVAL); + } + return rt; +} + target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) { PowerPCCPU *cpu = ppc_env_get_cpu(env); diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 1499af72a0..485d5b8fde 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -512,18 +512,20 @@ static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx, /* Software TLB search */ ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); #if defined(DUMP_PAGE_TABLES) - if (qemu_log_mask(CPU_LOG_MMU)) { + if (qemu_loglevel_mask(CPU_LOG_MMU)) { + CPUState *cs = ENV_GET_CPU(env); hwaddr curaddr; uint32_t a0, a1, a2, a3; qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx - "\n", sdr, mask + 0x80); - for (curaddr = sdr; curaddr < (sdr + mask + 0x80); + "\n", env->htab_base, env->htab_mask + 0x80); + for (curaddr = env->htab_base; + curaddr < (env->htab_base + env->htab_mask + 0x80); curaddr += 16) { - a0 = ldl_phys(curaddr); - a1 = ldl_phys(curaddr + 4); - a2 = ldl_phys(curaddr + 8); - a3 = ldl_phys(curaddr + 12); + a0 = ldl_phys(cs->as, curaddr); + a1 = ldl_phys(cs->as, curaddr + 4); + a2 = ldl_phys(cs->as, curaddr + 8); + a3 = ldl_phys(cs->as, curaddr + 12); if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n", curaddr, a0, a1, a2, a3); @@ -894,9 +896,9 @@ static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%" - PRIx64 " mask=0x" TARGET_FMT_lx " MAS7_3=0x%" PRIx64 " MAS8=%x\n", - __func__, address, pid, tlb->mas1, tlb->mas2, mask, tlb->mas7_3, - tlb->mas8); + PRIx64 " mask=0x%" HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%" + PRIx32 "\n", __func__, address, pid, tlb->mas1, tlb->mas2, mask, + tlb->mas7_3, tlb->mas8); /* Check PID */ tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT; @@ -1746,6 +1748,9 @@ static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr, void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value) { target_ulong mask; +#if defined(FLUSH_ALL_TLBS) + PowerPCCPU *cpu = ppc_env_get_cpu(env); +#endif dump_store_bat(env, 'I', 0, nr, value); if (env->IBAT[0][nr] != value) { @@ -1764,7 +1769,7 @@ void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value) #if !defined(FLUSH_ALL_TLBS) do_invalidate_BAT(env, env->IBAT[0][nr], mask); #else - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); #endif } } @@ -1778,6 +1783,9 @@ void helper_store_ibatl(CPUPPCState *env, uint32_t nr, target_ulong value) void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value) { target_ulong mask; +#if defined(FLUSH_ALL_TLBS) + PowerPCCPU *cpu = ppc_env_get_cpu(env); +#endif dump_store_bat(env, 'D', 0, nr, value); if (env->DBAT[0][nr] != value) { @@ -1796,7 +1804,7 @@ void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value) #if !defined(FLUSH_ALL_TLBS) do_invalidate_BAT(env, env->DBAT[0][nr], mask); #else - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); #endif } } @@ -1811,6 +1819,7 @@ void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value) { target_ulong mask; #if defined(FLUSH_ALL_TLBS) + PowerPCCPU *cpu = ppc_env_get_cpu(env); int do_inval; #endif @@ -1843,7 +1852,7 @@ void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value) } #if defined(FLUSH_ALL_TLBS) if (do_inval) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } #endif } @@ -1854,6 +1863,7 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value) #if !defined(FLUSH_ALL_TLBS) target_ulong mask; #else + PowerPCCPU *cpu = ppc_env_get_cpu(env); int do_inval; #endif @@ -1882,7 +1892,7 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value) env->DBAT[1][nr] = value; #if defined(FLUSH_ALL_TLBS) if (do_inval) { - tlb_flush(env, 1); + tlb_flush(CPU(cpu), 1); } #endif } @@ -1925,8 +1935,8 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) case POWERPC_MMU_2_06a: case POWERPC_MMU_2_07: case POWERPC_MMU_2_07a: - env->tlb_need_flush = 0; #endif /* defined(TARGET_PPC64) */ + env->tlb_need_flush = 0; tlb_flush(CPU(cpu), 1); break; default: @@ -1939,9 +1949,6 @@ void ppc_tlb_invalidate_all(CPUPPCState *env) void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) { #if !defined(FLUSH_ALL_TLBS) - PowerPCCPU *cpu = ppc_env_get_cpu(env); - CPUState *cs; - addr &= TARGET_PAGE_MASK; switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: @@ -1953,28 +1960,12 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) break; case POWERPC_MMU_32B: case POWERPC_MMU_601: - /* tlbie invalidate TLBs for all segments */ - addr &= ~((target_ulong)-1ULL << 28); - cs = CPU(cpu); - /* XXX: this case should be optimized, - * giving a mask to tlb_flush_page + /* Actual CPUs invalidate entire congruence classes based on the + * geometry of their TLBs and some OSes take that into account, + * we just mark the TLB to be flushed later (context synchronizing + * event or sync instruction on 32-bit). */ - tlb_flush_page(cs, addr | (0x0 << 28)); - tlb_flush_page(cs, addr | (0x1 << 28)); - tlb_flush_page(cs, addr | (0x2 << 28)); - tlb_flush_page(cs, addr | (0x3 << 28)); - tlb_flush_page(cs, addr | (0x4 << 28)); - tlb_flush_page(cs, addr | (0x5 << 28)); - tlb_flush_page(cs, addr | (0x6 << 28)); - tlb_flush_page(cs, addr | (0x7 << 28)); - tlb_flush_page(cs, addr | (0x8 << 28)); - tlb_flush_page(cs, addr | (0x9 << 28)); - tlb_flush_page(cs, addr | (0xA << 28)); - tlb_flush_page(cs, addr | (0xB << 28)); - tlb_flush_page(cs, addr | (0xC << 28)); - tlb_flush_page(cs, addr | (0xD << 28)); - tlb_flush_page(cs, addr | (0xE << 28)); - tlb_flush_page(cs, addr | (0xF << 28)); + env->tlb_need_flush = 1; break; #if defined(TARGET_PPC64) case POWERPC_MMU_64B: @@ -2040,13 +2031,12 @@ target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num) void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) { - PowerPCCPU *cpu = ppc_env_get_cpu(env); - qemu_log_mask(CPU_LOG_MMU, "%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, (int)srnum, value, env->sr[srnum]); #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { + PowerPCCPU *cpu = ppc_env_get_cpu(env); uint64_t esid, vsid; /* ESID = srnum */ @@ -2075,7 +2065,7 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value) } } #else - tlb_flush(CPU(cpu), 1); + env->tlb_need_flush = 1; #endif } } diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 123e42fe6b..b6894751e8 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -193,6 +193,7 @@ struct DisasContext { uint32_t exception; /* Routine used to access memory */ bool pr, hv; + bool lazy_tlb_flush; int mem_idx; int access_type; /* Translation flags */ @@ -3046,10 +3047,13 @@ static void gen_std(DisasContext *ctx) rs = rS(ctx->opcode); if ((ctx->opcode & 0x3) == 0x2) { /* stq */ - bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; + if (!(ctx->insns_flags & PPC_64BX)) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); + } + if (!legal_in_user_mode && ctx->pr) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; @@ -3290,12 +3294,17 @@ static void gen_eieio(DisasContext *ctx) { } -#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) +#if !defined(CONFIG_USER_ONLY) static inline void gen_check_tlb_flush(DisasContext *ctx) { - TCGv_i32 t = tcg_temp_new_i32(); - TCGLabel *l = gen_new_label(); + TCGv_i32 t; + TCGLabel *l; + if (!ctx->lazy_tlb_flush) { + return; + } + l = gen_new_label(); + t = tcg_temp_new_i32(); tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l); gen_helper_check_tlb_flush(cpu_env); @@ -3475,10 +3484,14 @@ static void gen_sync(DisasContext *ctx) uint32_t l = (ctx->opcode >> 21) & 3; /* - * For l == 2, it's a ptesync, We need to check for a pending TLB flush. - * This can only happen in kernel mode however so check MSR_PR as well. + * We may need to check for a pending TLB flush. + * + * We do this on ptesync (l == 2) on ppc64 and any sync pn ppc32. + * + * Additionally, this can only happen in kernel mode however so + * check MSR_PR as well. */ - if (l == 2 && !ctx->pr) { + if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) { gen_check_tlb_flush(ctx); } } @@ -4108,7 +4121,7 @@ static void gen_hrfid(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else /* Restore CPU state */ - if (unlikely(!ctx->hv)) { + if (unlikely(ctx->pr || !ctx->hv)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } @@ -4338,7 +4351,10 @@ static inline void gen_op_mfspr(DisasContext *ctx) qemu_log("Trying to read invalid spr %d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4); } - gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR); + /* Only generate an exception in user space, otherwise this is a nop */ + if (ctx->pr) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR); + } } } @@ -4490,7 +4506,11 @@ static void gen_mtspr(DisasContext *ctx) } fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4); - gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR); + + /* Only generate an exception in user space, otherwise this is a nop */ + if (ctx->pr) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR); + } } } @@ -4834,6 +4854,31 @@ static void gen_slbmfev(DisasContext *ctx) cpu_gpr[rB(ctx->opcode)]); #endif } + +static void gen_slbfee_(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); +#else + TCGLabel *l1, *l2; + + if (unlikely(ctx->pr)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + return; + } + gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, + cpu_gpr[rB(ctx->opcode)]); + l1 = gen_new_label(); + l2 = gen_new_label(); + tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1); + tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0); + gen_set_label(l2); +#endif +} #endif /* defined(TARGET_PPC64) */ /*** Lookaside buffer management ***/ @@ -4845,7 +4890,7 @@ static void gen_tlbia(DisasContext *ctx) #if defined(CONFIG_USER_ONLY) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else - if (unlikely(ctx->pr)) { + if (unlikely(ctx->pr || !ctx->hv)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } @@ -4913,7 +4958,7 @@ static void gen_slbia(DisasContext *ctx) #if defined(CONFIG_USER_ONLY) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else - if (unlikely(ctx->pr || !ctx->hv)) { + if (unlikely(ctx->pr)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } @@ -9931,7 +9976,7 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC), #if defined(TARGET_PPC64) GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B), #endif -GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC), +GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC), GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC), GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE), GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE), @@ -9959,6 +10004,7 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B), +GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), /* XXX Those instructions will need to be handled differently for @@ -9967,7 +10013,7 @@ GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE), GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE), GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), #if defined(TARGET_PPC64) -GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI), +GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI), GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI), #endif GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN), @@ -11478,8 +11524,10 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb) ctx.exception = POWERPC_EXCP_NONE; ctx.spr_cb = env->spr_cb; ctx.pr = msr_pr; - ctx.hv = !msr_pr && msr_hv; ctx.mem_idx = env->dmmu_idx; +#if !defined(CONFIG_USER_ONLY) + ctx.hv = msr_hv || !env->has_hv_mode; +#endif ctx.insns_flags = env->insns_flags; ctx.insns_flags2 = env->insns_flags2; ctx.access_type = -1; @@ -11489,6 +11537,11 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb) ctx.sf_mode = msr_is_64bit(env, env->msr); ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); #endif + if (env->mmu_model == POWERPC_MMU_32B || + env->mmu_model == POWERPC_MMU_601 || + (env->mmu_model & POWERPC_MMU_64B)) + ctx.lazy_tlb_flush = true; + ctx.fpu_enabled = msr_fp; if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) ctx.spe_enabled = msr_spe; diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 83010768ea..a1db5009c4 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8024,6 +8024,21 @@ static void gen_spr_power8_book4(CPUPPCState *env) #endif } +static void gen_spr_power7_book4(CPUPPCState *env) +{ + /* Add a number of P7 book4 registers */ +#if !defined(CONFIG_USER_ONLY) + spr_register_kvm(env, SPR_ACOP, "ACOP", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_ACOP, 0); + spr_register_kvm(env, SPR_BOOKS_PID, "PID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PID, 0); +#endif +} + static void init_proc_book3s_64(CPUPPCState *env, int version) { gen_spr_ne_601(env); @@ -8066,6 +8081,9 @@ static void init_proc_book3s_64(CPUPPCState *env, int version) gen_spr_power6_common(env); gen_spr_power6_dbg(env); } + if (version == BOOK3S_CPU_POWER7) { + gen_spr_power7_book4(env); + } if (version >= BOOK3S_CPU_POWER8) { gen_spr_power8_tce_address_control(env); gen_spr_power8_ids(env); @@ -8359,7 +8377,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | PPC_64H | PPC_ALTIVEC | + PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 | @@ -8450,6 +8468,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM; pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_SHV) | (1ull << MSR_TM) | (1ull << MSR_VR) | (1ull << MSR_VSX) | @@ -9854,10 +9873,7 @@ static void ppc_cpu_reset(CPUState *s) pcc->parent_reset(s); msr = (target_ulong)0; - if (0) { - /* XXX: find a suitable condition to enable the hypervisor mode */ - msr |= (target_ulong)MSR_HVB; - } + msr |= (target_ulong)MSR_HVB; msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */ msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */ msr |= (target_ulong)1 << MSR_EP; @@ -9958,6 +9974,19 @@ static void ppc_cpu_initfn(Object *obj) env->bfd_mach = pcc->bfd_mach; env->check_pow = pcc->check_pow; + /* Mark HV mode as supported if the CPU has an MSR_HV bit + * in the msr_mask. The mask can later be cleared by PAPR + * mode but the hv mode support will remain, thus enforcing + * that we cannot use priv. instructions in guest in PAPR + * mode. For 970 we currently simply don't set HV in msr_mask + * thus simulating an "Apple mode" 970. If we ever want to + * support 970 HV mode, we'll have to add a processor attribute + * of some sort. + */ +#if !defined(CONFIG_USER_ONLY) + env->has_hv_mode = !!(env->msr_mask & MSR_HVB); +#endif + #if defined(TARGET_PPC64) if (pcc->sps) { env->sps = *pcc->sps; diff --git a/tests/Makefile b/tests/Makefile.include index a3e20e39ec..a3e20e39ec 100644 --- a/tests/Makefile +++ b/tests/Makefile.include diff --git a/tests/ac97-test.c b/tests/ac97-test.c index 75cab8f98f..e0d177bd9c 100644 --- a/tests/ac97-test.c +++ b/tests/ac97-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT Binary files differindex 9d1274d3c2..8b4f1a09b8 100644 --- a/tests/acpi-test-data/pc/DSDT +++ b/tests/acpi-test-data/pc/DSDT diff --git a/tests/acpi-test-data/pc/DSDT.bridge b/tests/acpi-test-data/pc/DSDT.bridge Binary files differindex cf48c62aa7..0d09b5cc61 100644 --- a/tests/acpi-test-data/pc/DSDT.bridge +++ b/tests/acpi-test-data/pc/DSDT.bridge diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT Binary files differindex 1c089c34b0..67445428d9 100644 --- a/tests/acpi-test-data/q35/DSDT +++ b/tests/acpi-test-data/q35/DSDT diff --git a/tests/acpi-test-data/q35/DSDT.bridge b/tests/acpi-test-data/q35/DSDT.bridge Binary files differindex b29fcda0bb..e85f5b1af9 100644 --- a/tests/acpi-test-data/q35/DSDT.bridge +++ b/tests/acpi-test-data/q35/DSDT.bridge diff --git a/tests/ahci-test.c b/tests/ahci-test.c index 6869f7f46d..57dc44cf3b 100644 --- a/tests/ahci-test.c +++ b/tests/ahci-test.c @@ -24,7 +24,6 @@ #include "qemu/osdep.h" #include <getopt.h> -#include <glib.h> #include "libqtest.h" #include "libqos/libqos-pc.h" diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 03528140c1..16d11aa854 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <glib/gstdio.h> #include "qemu-common.h" #include "libqtest.h" @@ -464,7 +463,6 @@ static GArray *load_expected_aml(test_data *data) { int i; AcpiSdtTable *sdt; - gchar *aml_file = NULL; GError *error = NULL; gboolean ret; @@ -472,6 +470,7 @@ static GArray *load_expected_aml(test_data *data) for (i = 0; i < data->tables->len; ++i) { AcpiSdtTable exp_sdt; uint32_t signature; + gchar *aml_file = NULL; const char *ext = data->variant ? data->variant : ""; sdt = &g_array_index(data->tables, AcpiSdtTable, i); @@ -484,13 +483,21 @@ static GArray *load_expected_aml(test_data *data) try_again: aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, (gchar *)&signature, ext); - if (data->variant && !g_file_test(aml_file, G_FILE_TEST_EXISTS)) { - g_free(aml_file); + if (getenv("V")) { + fprintf(stderr, "\nLooking for expected file '%s'\n", aml_file); + } + if (g_file_test(aml_file, G_FILE_TEST_EXISTS)) { + exp_sdt.aml_file = aml_file; + } else if (*ext != '\0') { + /* try fallback to generic (extention less) expected file */ ext = ""; + g_free(aml_file); goto try_again; } - exp_sdt.aml_file = aml_file; - g_assert(g_file_test(aml_file, G_FILE_TEST_EXISTS)); + g_assert(exp_sdt.aml_file); + if (getenv("V")) { + fprintf(stderr, "\nUsing expected file '%s'\n", aml_file); + } ret = g_file_get_contents(aml_file, &exp_sdt.aml, &exp_sdt.aml_len, &error); g_assert(ret); diff --git a/tests/boot-order-test.c b/tests/boot-order-test.c index a6d8bd5cbf..fc1e7941f7 100644 --- a/tests/boot-order-test.c +++ b/tests/boot-order-test.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqos/fw_cfg.h" #include "libqtest.h" diff --git a/tests/check-qdict.c b/tests/check-qdict.c index a43056c5de..42da1e65a5 100644 --- a/tests/check-qdict.c +++ b/tests/check-qdict.c @@ -10,7 +10,6 @@ * See the COPYING.LIB file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qint.h" #include "qapi/qmp/qdict.h" diff --git a/tests/check-qfloat.c b/tests/check-qfloat.c index 3102608f55..1da2cdae08 100644 --- a/tests/check-qfloat.c +++ b/tests/check-qfloat.c @@ -11,7 +11,6 @@ * */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qfloat.h" #include "qemu-common.h" diff --git a/tests/check-qint.c b/tests/check-qint.c index c86f7dfa38..b6e4555115 100644 --- a/tests/check-qint.c +++ b/tests/check-qint.c @@ -10,7 +10,6 @@ * See the COPYING.LIB file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qint.h" #include "qemu-common.h" diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 99de6f5252..0e158f6eac 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -11,7 +11,6 @@ * */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qstring.h" #include "qapi/qmp/qint.h" diff --git a/tests/check-qlist.c b/tests/check-qlist.c index f231d5fa97..e16da5e5c6 100644 --- a/tests/check-qlist.c +++ b/tests/check-qlist.c @@ -10,7 +10,6 @@ * See the COPYING.LIB file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qint.h" #include "qapi/qmp/qlist.h" diff --git a/tests/check-qnull.c b/tests/check-qnull.c index fd9c68f7e1..05d562d494 100644 --- a/tests/check-qnull.c +++ b/tests/check-qnull.c @@ -7,7 +7,6 @@ * See the COPYING.LIB file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qobject.h" #include "qemu-common.h" diff --git a/tests/check-qom-interface.c b/tests/check-qom-interface.c index 09354deb70..719ddcf2e0 100644 --- a/tests/check-qom-interface.c +++ b/tests/check-qom-interface.c @@ -10,7 +10,6 @@ * See the COPYING.LIB file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qom/object.h" #include "qemu/module.h" diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index ffffd872f2..42defe7128 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/error.h" #include "qom/object.h" diff --git a/tests/check-qstring.c b/tests/check-qstring.c index 9877b42c89..239e9d9da3 100644 --- a/tests/check-qstring.c +++ b/tests/check-qstring.c @@ -10,7 +10,6 @@ * See the COPYING.LIB file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/qmp/qstring.h" #include "qemu-common.h" diff --git a/tests/device-introspect-test.c b/tests/device-introspect-test.c index 4477926014..37debc11f9 100644 --- a/tests/device-introspect-test.c +++ b/tests/device-introspect-test.c @@ -18,7 +18,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/qmp/qstring.h" #include "libqtest.h" diff --git a/tests/display-vga-test.c b/tests/display-vga-test.c index 5706d338a1..06b244ed9a 100644 --- a/tests/display-vga-test.c +++ b/tests/display-vga-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" static void pci_cirrus(void) diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 2fd2ca3057..f88c0a7309 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -21,15 +21,14 @@ IMAGES ?= % make-archive-maybe = $(if $(wildcard $1/*), \ $(call quiet-command, \ (cd $1; if git diff-index --quiet HEAD -- &>/dev/null; then \ - git archive -1 HEAD --format=tar.gz -o $2; \ + git archive -1 HEAD --format=tar.gz; \ else \ - git archive -1 $$(git stash create) --format=tar.gz -o $2; \ - fi), \ + git archive -1 $$(git stash create) --format=tar.gz; \ + fi) > $2, \ " ARCHIVE $(notdir $2)")) CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.$$$$) -# Makes the definition constant after the first expansion -DOCKER_SRC_COPY = $(eval DOCKER_SRC_COPY := docker-src.$(CUR_TIME))$(DOCKER_SRC_COPY) +DOCKER_SRC_COPY := docker-src.$(CUR_TIME) $(DOCKER_SRC_COPY): @mkdir $@ diff --git a/tests/docker/common.rc b/tests/docker/common.rc index c493eebd45..77069e1285 100755 --- a/tests/docker/common.rc +++ b/tests/docker/common.rc @@ -24,7 +24,7 @@ requires() build_qemu() { $QEMU_SRC/configure \ - --target-list="${TARGET_LIST}" \ + ${TARGET_LIST:+"--target-list=${TARGET_LIST}"} \ --prefix="$PWD/install" \ $EXTRA_CONFIGURE_OPTS \ "$@" diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index 6251e45137..1d26a8e98a 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -1,7 +1,7 @@ FROM fedora:23 RUN dnf install -y \ - ccache git tar \ + ccache git tar PyYAML sparse flex bison \ glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \ gcc gcc-c++ clang make perl which bc findutils \ mingw{32,64}-{pixman,glib2,gmp,SDL,pkg-config,gtk2,gtk3,gnutls,nettle,libtasn1,libjpeg-turbo,libpng,curl,libssh2,bzip2} -ENV FEATURES mingw clang +ENV FEATURES mingw clang pyyaml diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker index 725a7ca5d0..a8b88c318c 100644 --- a/tests/docker/dockerfiles/ubuntu.docker +++ b/tests/docker/dockerfiles/ubuntu.docker @@ -2,10 +2,10 @@ FROM ubuntu:14.04 RUN echo "deb http://archive.ubuntu.com/ubuntu/ trusty universe multiverse" >> \ /etc/apt/sources.list RUN apt-get update -RUN apt-get -y install \ +RUN apt-get -y install flex bison \ libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev \ libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev \ libspice-protocol-dev libnss3-dev libfdt-dev \ libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev \ git make ccache python-yaml gcc clang sparse -ENV FEATURES clang ccache pyyaml +ENV FEATURES clang pyyaml diff --git a/tests/docker/test-clang b/tests/docker/test-clang index 6745dbeb83..60e4e976b3 100755 --- a/tests/docker/test-clang +++ b/tests/docker/test-clang @@ -20,7 +20,5 @@ OPTS="--enable-debug --cxx=clang++ --cc=clang --host-cc=clang" # See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834 #OPTS="$OPTS --extra-cflags=-fsanitize=undefined \ #--extra-cflags=-fno-sanitize=float-divide-by-zero" -DEF_TARGET_LIST="$(echo {x86_64,aarch64}-softmmu)" -TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \ build_qemu $OPTS make $MAKEFLAGS check diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c index fe03236f3a..74e43c248b 100644 --- a/tests/drive_del-test.c +++ b/tests/drive_del-test.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" static void drive_add(void) diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c index 2792415841..26968bc82a 100644 --- a/tests/ds1338-test.c +++ b/tests/ds1338-test.c @@ -21,8 +21,6 @@ #include "libqtest.h" #include "libqos/i2c.h" -#include <glib.h> - #define IMX25_I2C_0_BASE 0x43F80000 #define DS1338_ADDR 0x68 diff --git a/tests/e1000-test.c b/tests/e1000-test.c index a42b3810c1..59cab68a60 100644 --- a/tests/e1000-test.c +++ b/tests/e1000-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/eepro100-test.c b/tests/eepro100-test.c index e17eed0b7a..ed23258b0f 100644 --- a/tests/eepro100-test.c +++ b/tests/eepro100-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" static void test_device(gconstpointer data) diff --git a/tests/endianness-test.c b/tests/endianness-test.c index cc5bccd88e..2197972e55 100644 --- a/tests/endianness-test.c +++ b/tests/endianness-test.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu/bswap.h" diff --git a/tests/es1370-test.c b/tests/es1370-test.c index 824dc31c64..199fe193ce 100644 --- a/tests/es1370-test.c +++ b/tests/es1370-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/fdc-test.c b/tests/fdc-test.c index 53df1d0d88..738c6b4a5e 100644 --- a/tests/fdc-test.c +++ b/tests/fdc-test.c @@ -24,7 +24,6 @@ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu-common.h" diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c index b4392c2d38..688342bed5 100644 --- a/tests/fw_cfg-test.c +++ b/tests/fw_cfg-test.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "hw/nvram/fw_cfg_keys.h" diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c index c8e669ac26..12ee3929da 100644 --- a/tests/hd-geo-test.c +++ b/tests/hd-geo-test.c @@ -16,7 +16,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "libqtest.h" diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c index 05029e90b2..bff999cf12 100644 --- a/tests/i440fx-test.c +++ b/tests/i440fx-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <sys/mman.h> #include "libqtest.h" diff --git a/tests/i82801b11-test.c b/tests/i82801b11-test.c index c3b5ebbca1..a6e31594c9 100644 --- a/tests/i82801b11-test.c +++ b/tests/i82801b11-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/ide-test.c b/tests/ide-test.c index 67e5c1f5cc..fed1b2ec2e 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c @@ -24,7 +24,6 @@ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/libqos.h" diff --git a/tests/intel-hda-test.c b/tests/intel-hda-test.c index 1be6add9b5..b0ca7e042a 100644 --- a/tests/intel-hda-test.c +++ b/tests/intel-hda-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #define HDA_ID "hda0" diff --git a/tests/ioh3420-test.c b/tests/ioh3420-test.c index 93eb2f7506..b54c4b9f11 100644 --- a/tests/ioh3420-test.c +++ b/tests/ioh3420-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/ipmi-bt-test.c b/tests/ipmi-bt-test.c index 812907fb7b..be9005eb85 100644 --- a/tests/ipmi-bt-test.c +++ b/tests/ipmi-bt-test.c @@ -29,7 +29,6 @@ #include <netinet/ip.h> #include <netinet/tcp.h> -#include <glib.h> #include "libqtest.h" #include "qemu-common.h" diff --git a/tests/ipmi-kcs-test.c b/tests/ipmi-kcs-test.c index 42c4b974c5..3750389651 100644 --- a/tests/ipmi-kcs-test.c +++ b/tests/ipmi-kcs-test.c @@ -24,7 +24,6 @@ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" diff --git a/tests/ipoctal232-test.c b/tests/ipoctal232-test.c index 846aaf5711..684914164d 100644 --- a/tests/ipoctal232-test.c +++ b/tests/ipoctal232-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c index c027ff1e09..010860a5b7 100644 --- a/tests/ivshmem-test.c +++ b/tests/ivshmem-test.c @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <glib/gstdio.h> #include <sys/mman.h> #include "contrib/ivshmem-server/ivshmem-server.h" diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c index ac6c155c83..f3be5500e1 100644 --- a/tests/libqos/ahci.c +++ b/tests/libqos/ahci.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/ahci.h" diff --git a/tests/libqos/fw_cfg.c b/tests/libqos/fw_cfg.c index 76894d5759..4d9dc3fd0b 100644 --- a/tests/libqos/fw_cfg.c +++ b/tests/libqos/fw_cfg.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqos/fw_cfg.h" #include "libqtest.h" #include "qemu/bswap.h" diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c index 51c3468f97..1c4b4314ba 100644 --- a/tests/libqos/i2c-imx.c +++ b/tests/libqos/i2c-imx.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include "libqos/i2c.h" -#include <glib.h> #include "libqtest.h" diff --git a/tests/libqos/i2c-omap.c b/tests/libqos/i2c-omap.c index 2028f2f146..f603fdf43c 100644 --- a/tests/libqos/i2c-omap.c +++ b/tests/libqos/i2c-omap.c @@ -9,7 +9,6 @@ #include "qemu/osdep.h" #include "libqos/i2c.h" -#include <glib.h> #include "qemu/bswap.h" #include "libqtest.h" diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c index 79b0b29b4d..c7ba441d0b 100644 --- a/tests/libqos/libqos.c +++ b/tests/libqos/libqos.c @@ -1,5 +1,4 @@ #include "qemu/osdep.h" -#include <glib.h> #include <sys/wait.h> #include "libqtest.h" diff --git a/tests/libqos/malloc-generic.c b/tests/libqos/malloc-generic.c index 6000df2b82..33ce90b925 100644 --- a/tests/libqos/malloc-generic.c +++ b/tests/libqos/malloc-generic.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqos/malloc-generic.h" #include "libqos/malloc.h" diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c index eee706bd63..dd2b900c5f 100644 --- a/tests/libqos/malloc-pc.c +++ b/tests/libqos/malloc-pc.c @@ -17,7 +17,6 @@ #include "hw/nvram/fw_cfg_keys.h" #include "qemu-common.h" -#include <glib.h> #define PAGE_SIZE (4096) diff --git a/tests/libqos/malloc.c b/tests/libqos/malloc.c index 793fe69c2f..b8eff5f495 100644 --- a/tests/libqos/malloc.c +++ b/tests/libqos/malloc.c @@ -14,7 +14,6 @@ #include "libqos/malloc.h" #include "qemu-common.h" #include "qemu/host-utils.h" -#include <glib.h> typedef QTAILQ_HEAD(MemList, MemBlock) MemList; diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c index 77f15e5a0e..1ae2d3780f 100644 --- a/tests/libqos/pci-pc.c +++ b/tests/libqos/pci-pc.c @@ -19,7 +19,6 @@ #include "qemu-common.h" #include "qemu/host-utils.h" -#include <glib.h> #define ACPI_PCIHP_ADDR 0xae00 #define PCI_EJ_BASE 0x0008 diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c index 0e104e14ed..ed78d91cea 100644 --- a/tests/libqos/pci.c +++ b/tests/libqos/pci.c @@ -14,7 +14,6 @@ #include "libqos/pci.h" #include "hw/pci/pci_regs.h" -#include <glib.h> void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id, void (*func)(QPCIDevice *dev, int devfn, void *data), diff --git a/tests/libqos/usb.c b/tests/libqos/usb.c index 87efb90782..f794d92da5 100644 --- a/tests/libqos/usb.c +++ b/tests/libqos/usb.c @@ -12,7 +12,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "hw/usb/uhci-regs.h" #include "libqos/usb.h" diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c index a4382f3660..e15b480ab8 100644 --- a/tests/libqos/virtio-mmio.c +++ b/tests/libqos/virtio-mmio.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/virtio.h" #include "libqos/virtio-mmio.h" diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index fde2ff0bcb..9d45e2028e 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/virtio.h" #include "libqos/virtio-pci.h" diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index 613decea5a..d792635340 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/virtio.h" diff --git a/tests/libqtest.c b/tests/libqtest.c index b12a9e4ca9..5c82348265 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -17,7 +17,6 @@ #include "qemu/osdep.h" #include "libqtest.h" -#include <glib.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/un.h> diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c index a751fd350e..0f921ef38a 100644 --- a/tests/m48t59-test.c +++ b/tests/m48t59-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" diff --git a/tests/ne2000-test.c b/tests/ne2000-test.c index 3727875f2e..b7cf3dd2f5 100644 --- a/tests/ne2000-test.c +++ b/tests/ne2000-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/nvme-test.c b/tests/nvme-test.c index ec06893eee..c8bece4434 100644 --- a/tests/nvme-test.c +++ b/tests/nvme-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/pc-cpu-test.c b/tests/pc-cpu-test.c index 6b34ca588b..4428cea5f1 100644 --- a/tests/pc-cpu-test.c +++ b/tests/pc-cpu-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "libqtest.h" diff --git a/tests/pcnet-test.c b/tests/pcnet-test.c index 2ddf4965c6..efb1ef44e9 100644 --- a/tests/pcnet-test.c +++ b/tests/pcnet-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/pvpanic-test.c b/tests/pvpanic-test.c index d435833f79..3bfa678667 100644 --- a/tests/pvpanic-test.c +++ b/tests/pvpanic-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" static void test_panic(void) diff --git a/tests/pxe-test.c b/tests/pxe-test.c index 875e4c4a26..b2cc355a95 100644 --- a/tests/pxe-test.c +++ b/tests/pxe-test.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <glib/gstdio.h> #include "qemu-common.h" #include "libqtest.h" diff --git a/tests/q35-test.c b/tests/q35-test.c index a105f10782..71538fc17c 100644 --- a/tests/q35-test.c +++ b/tests/q35-test.c @@ -10,7 +10,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/pci.h" #include "libqos/pci-pc.h" diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034 index c711cfce94..1b28bdae63 100755 --- a/tests/qemu-iotests/034 +++ b/tests/qemu-iotests/034 @@ -1,6 +1,6 @@ #!/bin/bash # -# Test bdrv_write_zeroes with backing files +# Test bdrv_pwrite_zeroes with backing files (see also 154) # # Copyright (C) 2012 Red Hat, Inc. # diff --git a/tests/qemu-iotests/077 b/tests/qemu-iotests/077 index 4dc680b7fc..d2d2a2d687 100755 --- a/tests/qemu-iotests/077 +++ b/tests/qemu-iotests/077 @@ -60,7 +60,7 @@ EOF # Sequential RMW requests on the same physical sector off=0x1000 -for ev in "head" "after_head" "tail" "after_tail"; do +for ev in "head" "after_head"; do cat <<EOF break pwritev_rmw_$ev A aio_write -P 10 $((off + 0x200)) 0x200 @@ -211,16 +211,6 @@ function verify_io() echo read -P 11 0x2400 0x200 echo read -P 0 0x2600 0xa00 - echo read -P 0 0x3000 0x200 - echo read -P 10 0x3200 0x200 - echo read -P 11 0x3400 0x200 - echo read -P 0 0x3600 0xa00 - - echo read -P 0 0x4000 0x200 - echo read -P 10 0x4200 0x200 - echo read -P 11 0x4400 0x200 - echo read -P 0 0x4600 0xa00 - # Chained dependencies echo read -P 10 0x5000 0x200 echo read -P 11 0x5200 0x200 diff --git a/tests/qemu-iotests/077.out b/tests/qemu-iotests/077.out index eab14ae2e1..16f951fd3d 100644 --- a/tests/qemu-iotests/077.out +++ b/tests/qemu-iotests/077.out @@ -19,16 +19,6 @@ wrote XXX/XXX bytes at offset XXX XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote XXX/XXX bytes at offset XXX XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -blkdebug: Resuming request 'A' -wrote XXX/XXX bytes at offset XXX -XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -wrote XXX/XXX bytes at offset XXX -XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -blkdebug: Resuming request 'A' -wrote XXX/XXX bytes at offset XXX -XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -wrote XXX/XXX bytes at offset XXX -XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote XXX/XXX bytes at offset XXX XXX bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote XXX/XXX bytes at offset XXX @@ -114,22 +104,6 @@ read 512/512 bytes at offset 9216 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 2560/2560 bytes at offset 9728 2.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 512/512 bytes at offset 12288 -512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 512/512 bytes at offset 12800 -512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 512/512 bytes at offset 13312 -512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 2560/2560 bytes at offset 13824 -2.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 512/512 bytes at offset 16384 -512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 512/512 bytes at offset 16896 -512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 512/512 bytes at offset 17408 -512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -read 2560/2560 bytes at offset 17920 -2.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 512/512 bytes at offset 20480 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 512/512 bytes at offset 20992 diff --git a/tests/qemu-iotests/154 b/tests/qemu-iotests/154 index 23f1b3ab16..7ca7219f08 100755 --- a/tests/qemu-iotests/154 +++ b/tests/qemu-iotests/154 @@ -1,6 +1,6 @@ #!/bin/bash # -# qcow2 specific bdrv_write_zeroes tests with backing files (complements 034) +# qcow2 specific bdrv_pwrite_zeroes tests with backing files (complements 034) # # Copyright (C) 2016 Red Hat, Inc. # @@ -115,6 +115,46 @@ $QEMU_IO -c "read -P 0 40k 3k" "$TEST_IMG" | _filter_qemu_io $QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map echo +echo == write_zeroes covers non-zero data == + +CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size +_make_test_img -b "$TEST_IMG.base" + +# non-zero data at front of request +# Backing file: -- XX -- -- +# Active layer: -- 00 00 -- + +$QEMU_IO -c "write -P 0x11 5k 1k" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -z 5k 2k" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "read -P 0 4k 4k" "$TEST_IMG" | _filter_qemu_io + +# non-zero data at end of request +# Backing file: -- -- XX -- +# Active layer: -- 00 00 -- + +$QEMU_IO -c "write -P 0x11 14k 1k" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -z 13k 2k" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "read -P 0 12k 4k" "$TEST_IMG" | _filter_qemu_io + +# non-zero data matches size of request +# Backing file: -- XX XX -- +# Active layer: -- 00 00 -- + +$QEMU_IO -c "write -P 0x11 21k 2k" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -z 21k 2k" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "read -P 0 20k 4k" "$TEST_IMG" | _filter_qemu_io + +# non-zero data smaller than request +# Backing file: -- -X X- -- +# Active layer: -- 00 00 -- + +$QEMU_IO -c "write -P 0x11 30208 1k" "$TEST_IMG.base" | _filter_qemu_io +$QEMU_IO -c "write -z 29k 2k" "$TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "read -P 0 28k 4k" "$TEST_IMG" | _filter_qemu_io + +$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map + +echo echo == spanning two clusters, non-zero before request == CLUSTER_SIZE=512 TEST_IMG="$TEST_IMG.base" _make_test_img $size diff --git a/tests/qemu-iotests/154.out b/tests/qemu-iotests/154.out index 8946b734ac..da9eabdda8 100644 --- a/tests/qemu-iotests/154.out +++ b/tests/qemu-iotests/154.out @@ -74,6 +74,43 @@ read 3072/3072 bytes at offset 40960 { "start": 40960, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576}, { "start": 45056, "length": 134172672, "depth": 1, "zero": true, "data": false}] +== write_zeroes covers non-zero data == +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base +wrote 1024/1024 bytes at offset 5120 +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 2048/2048 bytes at offset 5120 +2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 4096 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1024/1024 bytes at offset 14336 +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 2048/2048 bytes at offset 13312 +2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 12288 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 2048/2048 bytes at offset 21504 +2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 2048/2048 bytes at offset 21504 +2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 20480 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1024/1024 bytes at offset 30208 +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 2048/2048 bytes at offset 29696 +2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 28672 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[{ "start": 0, "length": 4096, "depth": 1, "zero": true, "data": false}, +{ "start": 4096, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 8192, "length": 4096, "depth": 1, "zero": true, "data": false}, +{ "start": 12288, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 16384, "length": 4096, "depth": 1, "zero": true, "data": false}, +{ "start": 20480, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 24576, "length": 4096, "depth": 1, "zero": true, "data": false}, +{ "start": 28672, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 32768, "length": 134184960, "depth": 1, "zero": true, "data": false}] + == spanning two clusters, non-zero before request == Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base @@ -106,11 +143,14 @@ read 1024/1024 bytes at offset 67584 read 5120/5120 bytes at offset 68608 5 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) [{ "start": 0, "length": 32768, "depth": 1, "zero": true, "data": false}, -{ "start": 32768, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 20480}, +{ "start": 32768, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480}, +{ "start": 36864, "length": 4096, "depth": 0, "zero": true, "data": false}, { "start": 40960, "length": 8192, "depth": 1, "zero": true, "data": false}, -{ "start": 49152, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 28672}, +{ "start": 49152, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576}, +{ "start": 53248, "length": 4096, "depth": 0, "zero": true, "data": false}, { "start": 57344, "length": 8192, "depth": 1, "zero": true, "data": false}, -{ "start": 65536, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 36864}, +{ "start": 65536, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 28672}, +{ "start": 69632, "length": 4096, "depth": 0, "zero": true, "data": false}, { "start": 73728, "length": 134144000, "depth": 1, "zero": true, "data": false}] == spanning two clusters, non-zero after request == @@ -145,11 +185,14 @@ read 7168/7168 bytes at offset 65536 read 1024/1024 bytes at offset 72704 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) [{ "start": 0, "length": 32768, "depth": 1, "zero": true, "data": false}, -{ "start": 32768, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 20480}, +{ "start": 32768, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 36864, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 20480}, { "start": 40960, "length": 8192, "depth": 1, "zero": true, "data": false}, -{ "start": 49152, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 28672}, +{ "start": 49152, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 53248, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 24576}, { "start": 57344, "length": 8192, "depth": 1, "zero": true, "data": false}, -{ "start": 65536, "length": 8192, "depth": 0, "zero": false, "data": true, "offset": 36864}, +{ "start": 65536, "length": 4096, "depth": 0, "zero": true, "data": false}, +{ "start": 69632, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 28672}, { "start": 73728, "length": 134144000, "depth": 1, "zero": true, "data": false}] == spanning two clusters, partially overwriting backing file == diff --git a/tests/qom-test.c b/tests/qom-test.c index bd5cdde261..23493a2b0a 100644 --- a/tests/qom-test.c +++ b/tests/qom-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/cutils.h" diff --git a/tests/rcutorture.c b/tests/rcutorture.c index 244f0f28b2..4002ecf123 100644 --- a/tests/rcutorture.c +++ b/tests/rcutorture.c @@ -61,7 +61,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/atomic.h" #include "qemu/rcu.h" #include "qemu/thread.h" diff --git a/tests/rtc-test.c b/tests/rtc-test.c index fa7029aa8a..a086efd120 100644 --- a/tests/rtc-test.c +++ b/tests/rtc-test.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "hw/timer/mc146818rtc_regs.h" diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c index 54e5aa7d0e..13de7eeafd 100644 --- a/tests/rtl8139-test.c +++ b/tests/rtl8139-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/pci-pc.h" #include "qemu/timer.h" diff --git a/tests/spapr-phb-test.c b/tests/spapr-phb-test.c index f53911d9f7..21004a76ec 100644 --- a/tests/spapr-phb-test.c +++ b/tests/spapr-phb-test.c @@ -8,7 +8,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" diff --git a/tests/tco-test.c b/tests/tco-test.c index ac11175e90..0d13aa8d63 100644 --- a/tests/tco-test.c +++ b/tests/tco-test.c @@ -7,7 +7,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/pci.h" diff --git a/tests/test-aio.c b/tests/test-aio.c index 687dfa062e..982339c801 100644 --- a/tests/test-aio.c +++ b/tests/test-aio.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "block/aio.h" #include "qapi/error.h" #include "qemu/timer.h" diff --git a/tests/test-base64.c b/tests/test-base64.c index 922e839dd6..ec122ceba5 100644 --- a/tests/test-base64.c +++ b/tests/test-base64.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/error.h" #include "qemu/base64.h" diff --git a/tests/test-bitops.c b/tests/test-bitops.c index 5050950607..eb19a36a36 100644 --- a/tests/test-bitops.c +++ b/tests/test-bitops.c @@ -7,7 +7,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/bitops.h" typedef struct { diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c index 828389bb45..d3030f1566 100644 --- a/tests/test-blockjob-txn.c +++ b/tests/test-blockjob-txn.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qapi/error.h" #include "qemu/main-loop.h" #include "block/blockjob.h" diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c index dd4ced946c..215b92e636 100644 --- a/tests/test-coroutine.c +++ b/tests/test-coroutine.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/coroutine.h" #include "qemu/coroutine_int.h" @@ -369,7 +368,15 @@ static void perf_cost(void) int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); - g_test_add_func("/basic/co_queue", test_co_queue); + + /* This test assumes there is a freelist and marks freed coroutine memory + * with a sentinel value. If there is no freelist this would legitimately + * crash, so skip it. + */ + if (CONFIG_COROUTINE_POOL) { + g_test_add_func("/basic/co_queue", test_co_queue); + } + g_test_add_func("/basic/lifecycle", test_lifecycle); g_test_add_func("/basic/yield", test_yield); g_test_add_func("/basic/nesting", test_nesting); diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c index 66d1c63fd5..1b5130d5f6 100644 --- a/tests/test-crypto-cipher.c +++ b/tests/test-crypto-cipher.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "crypto/init.h" #include "crypto/cipher.h" diff --git a/tests/test-crypto-hash.c b/tests/test-crypto-hash.c index 735d6d7e0b..6e0e89f7d6 100644 --- a/tests/test-crypto-hash.c +++ b/tests/test-crypto-hash.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "crypto/init.h" #include "crypto/hash.h" diff --git a/tests/test-crypto-secret.c b/tests/test-crypto-secret.c index aa26c20499..0b1fe8dd37 100644 --- a/tests/test-crypto-secret.c +++ b/tests/test-crypto-secret.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "crypto/init.h" #include "crypto/secret.h" diff --git a/tests/test-cutils.c b/tests/test-cutils.c index fb8f5b5321..64e3e95ce2 100644 --- a/tests/test-cutils.c +++ b/tests/test-cutils.c @@ -26,7 +26,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/cutils.h" diff --git a/tests/test-filter-mirror.c b/tests/test-filter-mirror.c index f60bf2adbe..ffaaffabd0 100644 --- a/tests/test-filter-mirror.c +++ b/tests/test-filter-mirror.c @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu/iov.h" #include "qemu/sockets.h" diff --git a/tests/test-filter-redirector.c b/tests/test-filter-redirector.c index b93012ceae..280e4b68ab 100644 --- a/tests/test-filter-redirector.c +++ b/tests/test-filter-redirector.c @@ -51,7 +51,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu/iov.h" #include "qemu/sockets.h" diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c index abe1427917..c0e9895fb9 100644 --- a/tests/test-hbitmap.c +++ b/tests/test-hbitmap.c @@ -10,7 +10,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/hbitmap.h" #define LOG_BITS_PER_LONG (BITS_PER_LONG == 32 ? 5 : 6) @@ -80,7 +79,7 @@ static void hbitmap_test_init(TestHBitmapData *data, size_t n; data->hb = hbitmap_alloc(size, granularity); - n = (size + BITS_PER_LONG - 1) / BITS_PER_LONG; + n = DIV_ROUND_UP(size, BITS_PER_LONG); if (n == 0) { n = 1; } @@ -94,7 +93,7 @@ static void hbitmap_test_init(TestHBitmapData *data, static inline size_t hbitmap_test_array_size(size_t bits) { - size_t n = (bits + BITS_PER_LONG - 1) / BITS_PER_LONG; + size_t n = DIV_ROUND_UP(bits, BITS_PER_LONG); return n ? n : 1; } @@ -186,7 +185,7 @@ static void hbitmap_test_reset_all(TestHBitmapData *data) hbitmap_reset_all(data->hb); - n = (data->size + BITS_PER_LONG - 1) / BITS_PER_LONG; + n = DIV_ROUND_UP(data->size, BITS_PER_LONG); if (n == 0) { n = 1; } diff --git a/tests/test-int128.c b/tests/test-int128.c index cacf6beac8..4390123bd3 100644 --- a/tests/test-int128.c +++ b/tests/test-int128.c @@ -7,7 +7,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/int128.h" /* clang doesn't support __noclone__ but it does have a mechanism for diff --git a/tests/test-io-task.c b/tests/test-io-task.c index 5a9775086c..a36cb824eb 100644 --- a/tests/test-io-task.c +++ b/tests/test-io-task.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "io/task.h" #include "qapi/error.h" diff --git a/tests/test-iov.c b/tests/test-iov.c index 3f25268dd4..46ae25efd6 100644 --- a/tests/test-iov.c +++ b/tests/test-iov.c @@ -1,5 +1,4 @@ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/iov.h" #include "qemu/sockets.h" diff --git a/tests/test-logging.c b/tests/test-logging.c index ac8deedc9a..5ef5bb887d 100644 --- a/tests/test-logging.c +++ b/tests/test-logging.c @@ -25,7 +25,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "include/qemu/log.h" diff --git a/tests/test-mul64.c b/tests/test-mul64.c index 1282ec5a22..9be775d084 100644 --- a/tests/test-mul64.c +++ b/tests/test-mul64.c @@ -7,7 +7,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/host-utils.h" diff --git a/tests/test-netfilter.c b/tests/test-netfilter.c index 7d105c3232..8b5a9b21b5 100644 --- a/tests/test-netfilter.c +++ b/tests/test-netfilter.c @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* add a netfilter to a netdev and then remove it */ diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c index 008e677388..d75b114c15 100644 --- a/tests/test-opts-visitor.c +++ b/tests/test-opts-visitor.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/config-file.h" /* qemu_add_opts() */ #include "qemu/option.h" /* qemu_opts_parse() */ diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c index f0cc31e113..48e5b7315f 100644 --- a/tests/test-qdev-global-props.c +++ b/tests/test-qdev-global-props.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "hw/qdev.h" #include "qom/object.h" diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c index 32abed5ea1..a505a3e059 100644 --- a/tests/test-qemu-opts.c +++ b/tests/test-qemu-opts.c @@ -12,7 +12,6 @@ #include "qapi/qmp/qstring.h" #include "qemu/config-file.h" -#include <glib.h> static QemuOptsList opts_list_01 = { .name = "opts_list_01", diff --git a/tests/test-qga.c b/tests/test-qga.c index 72a89dec23..251b20190c 100644 --- a/tests/test-qga.c +++ b/tests/test-qga.c @@ -1,6 +1,5 @@ #include "qemu/osdep.h" #include <locale.h> -#include <glib.h> #include <glib/gstdio.h> #include <sys/socket.h> #include <sys/un.h> @@ -823,6 +822,84 @@ static void test_qga_fsfreeze_and_thaw(gconstpointer fix) QDECREF(ret); } +static void test_qga_guest_exec(gconstpointer fix) +{ + const TestFixture *fixture = fix; + QDict *ret, *val; + const gchar *out; + guchar *decoded; + int64_t pid, now, exitcode; + gsize len; + bool exited; + + /* exec 'echo foo bar' */ + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ]," + " 'capture-output': true } }"); + g_assert_nonnull(ret); + qmp_assert_no_error(ret); + val = qdict_get_qdict(ret, "return"); + pid = qdict_get_int(val, "pid"); + g_assert_cmpint(pid, >, 0); + QDECREF(ret); + + /* wait for completion */ + now = g_get_monotonic_time(); + do { + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status'," + " 'arguments': { 'pid': %" PRId64 " } }", pid); + g_assert_nonnull(ret); + val = qdict_get_qdict(ret, "return"); + exited = qdict_get_bool(val, "exited"); + if (!exited) { + QDECREF(ret); + } + } while (!exited && + g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); + g_assert(exited); + + /* check stdout */ + exitcode = qdict_get_int(val, "exitcode"); + g_assert_cmpint(exitcode, ==, 0); + out = qdict_get_str(val, "out-data"); + decoded = g_base64_decode(out, &len); + g_assert_cmpint(len, ==, 12); + g_assert_cmpstr((char *)decoded, ==, "\" test_str \""); + g_free(decoded); + QDECREF(ret); +} + +static void test_qga_guest_exec_invalid(gconstpointer fix) +{ + const TestFixture *fixture = fix; + QDict *ret, *error; + const gchar *class, *desc; + + /* invalid command */ + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" + " 'path': '/bin/invalid-cmd42' } }"); + g_assert_nonnull(ret); + error = qdict_get_qdict(ret, "error"); + g_assert_nonnull(error); + class = qdict_get_str(error, "class"); + desc = qdict_get_str(error, "desc"); + g_assert_cmpstr(class, ==, "GenericError"); + g_assert_cmpint(strlen(desc), >, 0); + QDECREF(ret); + + /* invalid pid */ + ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status'," + " 'arguments': { 'pid': 0 } }"); + g_assert_nonnull(ret); + error = qdict_get_qdict(ret, "error"); + g_assert_nonnull(error); + class = qdict_get_str(error, "class"); + desc = qdict_get_str(error, "desc"); + g_assert_cmpstr(class, ==, "GenericError"); + g_assert_cmpint(strlen(desc), >, 0); + QDECREF(ret); +} + int main(int argc, char **argv) { TestFixture fix; @@ -853,6 +930,9 @@ int main(int argc, char **argv) g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist); g_test_add_data_func("/qga/config", NULL, test_qga_config); + g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec); + g_test_add_data_func("/qga/guest-exec-invalid", &fix, + test_qga_guest_exec_invalid); if (g_getenv("QGA_TEST_SIDE_EFFECTING")) { g_test_add_data_func("/qga/fsfreeze-and-thaw", &fix, diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index 5c3edd753a..e8f619d331 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -1,5 +1,4 @@ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/qmp/types.h" #include "test-qmp-commands.h" diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c index a296fdbac2..633dc87402 100644 --- a/tests/test-qmp-event.c +++ b/tests/test-qmp-event.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "test-qapi-types.h" diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c index 4602529ea0..d5f57c583a 100644 --- a/tests/test-qmp-input-strict.c +++ b/tests/test-qmp-input-strict.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/error.h" diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index cee07ce8dd..3b6b39e297 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/error.h" diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index 1f80e696ea..f8a7a271a9 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/error.h" diff --git a/tests/test-rcu-list.c b/tests/test-rcu-list.c index 79d3750144..1514d7ec97 100644 --- a/tests/test-rcu-list.c +++ b/tests/test-rcu-list.c @@ -21,7 +21,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/atomic.h" #include "qemu/rcu.h" #include "qemu/thread.h" diff --git a/tests/test-rfifolock.c b/tests/test-rfifolock.c index 9a3cb243ba..471a81114d 100644 --- a/tests/test-rfifolock.c +++ b/tests/test-rfifolock.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/rfifolock.h" diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 5a56920222..7fe7a9c270 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/error.h" diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index 1ecd75b853..edff5235fe 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qapi/error.h" diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c index 88dc7316b3..b0e1f3290f 100644 --- a/tests/test-thread-pool.c +++ b/tests/test-thread-pool.c @@ -1,5 +1,4 @@ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "block/aio.h" #include "block/thread-pool.h" diff --git a/tests/test-throttle.c b/tests/test-throttle.c index c02be805f7..afe094bcc4 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <math.h> #include "block/aio.h" #include "qapi/error.h" @@ -398,6 +397,14 @@ static void test_max_is_missing_limit(void) } } +static void test_iops_size_is_missing_limit(void) +{ + /* A total/read/write iops limit is required */ + throttle_config_init(&cfg); + cfg.op_size = 4096; + g_assert(!throttle_is_valid(&cfg, NULL)); +} + static void test_have_timer(void) { /* zero structures */ @@ -653,6 +660,8 @@ int main(int argc, char **argv) g_test_add_func("/throttle/config/conflicting", test_conflicting_config); g_test_add_func("/throttle/config/is_valid", test_is_valid); g_test_add_func("/throttle/config/max", test_max_is_missing_limit); + g_test_add_func("/throttle/config/iops_size", + test_iops_size_is_missing_limit); g_test_add_func("/throttle/config_functions", test_config_functions); g_test_add_func("/throttle/accounting", test_accounting); g_test_add_func("/throttle/groups", test_groups); diff --git a/tests/test-timed-average.c b/tests/test-timed-average.c index 1cc4ab3027..e2bcf5fe13 100644 --- a/tests/test-timed-average.c +++ b/tests/test-timed-average.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/timed-average.h" diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index 7b14b5a7af..777469f114 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -12,7 +12,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include <float.h> #include "qemu-common.h" diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c index d19b16a60e..41fd841aed 100644 --- a/tests/test-vmstate.c +++ b/tests/test-vmstate.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "migration/migration.h" diff --git a/tests/test-write-threshold.c b/tests/test-write-threshold.c index fdbc8020fd..97ca12f710 100644 --- a/tests/test-write-threshold.c +++ b/tests/test-write-threshold.c @@ -7,7 +7,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "block/block_int.h" #include "block/write-threshold.h" diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c index 8eb0bc6ad5..ff225006e4 100644 --- a/tests/test-x86-cpuid.c +++ b/tests/test-x86-cpuid.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "hw/i386/topology.h" diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c index 235cae0137..a7940a4639 100644 --- a/tests/tmp105-test.c +++ b/tests/tmp105-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/i2c.h" diff --git a/tests/tpci200-test.c b/tests/tpci200-test.c index cb2b00ca8b..0321ec27ec 100644 --- a/tests/tpci200-test.c +++ b/tests/tpci200-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/usb-hcd-ehci-test.c b/tests/usb-hcd-ehci-test.c index a0f13ef40a..eb247ad453 100644 --- a/tests/usb-hcd-ehci-test.c +++ b/tests/usb-hcd-ehci-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/pci-pc.h" #include "hw/usb/uhci-regs.h" diff --git a/tests/usb-hcd-ohci-test.c b/tests/usb-hcd-ohci-test.c index efd6669c7c..4758813d78 100644 --- a/tests/usb-hcd-ohci-test.c +++ b/tests/usb-hcd-ohci-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/usb.h" diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c index 71ff2ea189..5cd59ad91f 100644 --- a/tests/usb-hcd-uhci-test.c +++ b/tests/usb-hcd-uhci-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/usb.h" #include "hw/usb/uhci-regs.h" diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c index 7e2e212df3..22513e9eb5 100644 --- a/tests/usb-hcd-xhci-test.c +++ b/tests/usb-hcd-xhci-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/usb.h" diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 69615968ce..2724fe9755 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu/option.h" diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c index 59d0f1fa9b..1e39335a79 100644 --- a/tests/virtio-9p-test.c +++ b/tests/virtio-9p-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu-common.h" diff --git a/tests/virtio-balloon-test.c b/tests/virtio-balloon-test.c index b010ce98e8..0d0046bf25 100644 --- a/tests/virtio-balloon-test.c +++ b/tests/virtio-balloon-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 3a66630d79..8272ba8c42 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/virtio.h" #include "libqos/virtio-pci.h" diff --git a/tests/virtio-console-test.c b/tests/virtio-console-test.c index 0b9c2a55ef..6d6414dc8e 100644 --- a/tests/virtio-console-test.c +++ b/tests/virtio-console-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c index 04cfcd594e..e5c144818e 100644 --- a/tests/virtio-net-test.c +++ b/tests/virtio-net-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu-common.h" #include "qemu/sockets.h" diff --git a/tests/virtio-rng-test.c b/tests/virtio-rng-test.c index 771dbd73af..e1b26401f9 100644 --- a/tests/virtio-rng-test.c +++ b/tests/virtio-rng-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "libqos/pci.h" diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c index d78747a466..5f1a8aefeb 100644 --- a/tests/virtio-scsi-test.c +++ b/tests/virtio-scsi-test.c @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "block/scsi.h" #include "libqos/virtio.h" diff --git a/tests/virtio-serial-test.c b/tests/virtio-serial-test.c index 480d4abb2d..b14d943ada 100644 --- a/tests/virtio-serial-test.c +++ b/tests/virtio-serial-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/vmxnet3-test.c b/tests/vmxnet3-test.c index 6ef0e2f043..159c0ad728 100644 --- a/tests/vmxnet3-test.c +++ b/tests/vmxnet3-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" /* Tests only initialization so far. TODO: Replace with functional tests */ diff --git a/tests/wdt_ib700-test.c b/tests/wdt_ib700-test.c index efe3370453..9c1d78b1bc 100644 --- a/tests/wdt_ib700-test.c +++ b/tests/wdt_ib700-test.c @@ -8,7 +8,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu/timer.h" @@ -273,37 +273,36 @@ const argtype *thunk_convert(void *dst, const void *src, /* from em86 */ /* Utility function: Table-driven functions to translate bitmasks - * between X86 and Alpha formats... + * between host and target formats */ -unsigned int target_to_host_bitmask(unsigned int x86_mask, +unsigned int target_to_host_bitmask(unsigned int target_mask, const bitmask_transtbl * trans_tbl) { const bitmask_transtbl *btp; - unsigned int alpha_mask = 0; + unsigned int host_mask = 0; - for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { - if((x86_mask & btp->x86_mask) == btp->x86_bits) { - alpha_mask |= btp->alpha_bits; - } + for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) { + if ((target_mask & btp->target_mask) == btp->target_bits) { + host_mask |= btp->host_bits; + } } - return(alpha_mask); + return host_mask; } -unsigned int host_to_target_bitmask(unsigned int alpha_mask, +unsigned int host_to_target_bitmask(unsigned int host_mask, const bitmask_transtbl * trans_tbl) { const bitmask_transtbl *btp; - unsigned int x86_mask = 0; + unsigned int target_mask = 0; - for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) { - if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) { - x86_mask |= btp->x86_bits; - } + for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) { + if ((host_mask & btp->host_mask) == btp->host_bits) { + target_mask |= btp->target_bits; + } } - return(x86_mask); + return target_mask; } -#ifndef NO_THUNK_TYPE_SIZE int thunk_type_size_array(const argtype *type_ptr, int is_host) { return thunk_type_size(type_ptr, is_host); @@ -313,7 +312,6 @@ int thunk_type_align_array(const argtype *type_ptr, int is_host) { return thunk_type_align(type_ptr, is_host); } -#endif /* ndef NO_THUNK_TYPE_SIZE */ void thunk_init(unsigned int max_structs) { diff --git a/trace-events b/trace-events index c50b8705c1..421d89f476 100644 --- a/trace-events +++ b/trace-events @@ -70,10 +70,9 @@ bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p" bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p" bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p" -bdrv_aio_write_zeroes(void *bs, int64_t sector_num, int nb_sectors, int flags, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x opaque %p" bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d" bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d" -bdrv_co_write_zeroes(void *bs, int64_t sector_num, int nb_sector, int flags) "bs %p sector_num %"PRId64" nb_sectors %d flags %#x" +bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags %#x" bdrv_co_do_copy_on_readv(void *bs, int64_t sector_num, int nb_sectors, int64_t cluster_sector_num, int cluster_nb_sectors) "bs %p sector_num %"PRId64" nb_sectors %d cluster_sector_num %"PRId64" cluster_nb_sectors %d" # block/stream.c @@ -132,7 +131,7 @@ thread_pool_cancel(void *req, void *opaque) "req %p opaque %p" # block/raw-win32.c # block/raw-posix.c -paio_submit_co(int64_t sector_num, int nb_sectors, int type) "sector_num %"PRId64" nb_sectors %d type %d" +paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d" paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d" # ioport.c @@ -612,6 +611,8 @@ qcow2_writev_done_req(void *co, int ret) "co %p ret %d" qcow2_writev_start_part(void *co) "co %p" qcow2_writev_done_part(void *co, int cur_nr_sectors) "co %p cur_nr_sectors %d" qcow2_writev_data(void *co, uint64_t offset) "co %p offset %" PRIx64 +qcow2_pwrite_zeroes_start_req(void *co, int64_t offset, int count) "co %p offset %" PRIx64 " count %d" +qcow2_pwrite_zeroes(void *co, int64_t offset, int count) "co %p offset %" PRIx64 " count %d" # block/qcow2-cluster.c qcow2_alloc_clusters_offset(void *co, uint64_t offset, int num) "co %p offset %" PRIx64 " num %d" @@ -1431,6 +1432,8 @@ spapr_iommu_pci_indirect(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t i spapr_iommu_pci_stuff(uint64_t liobn, uint64_t ioba, uint64_t tce_value, uint64_t npages, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tcevalue=0x%"PRIx64" npages=%"PRId64" ret=%"PRId64 spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x" spapr_iommu_new_table(uint64_t liobn, void *table, int fd) "liobn=%"PRIx64" table=%p fd=%d" +spapr_iommu_pre_save(uint64_t liobn, uint32_t nb, uint64_t offs, uint32_t ps) "liobn=%"PRIx64" %"PRIx32" bus_offset=%"PRIx64" ps=%"PRIu32 +spapr_iommu_post_load(uint64_t liobn, uint32_t pre_nb, uint32_t post_nb, uint64_t offs, uint32_t ps) "liobn=%"PRIx64" %"PRIx32" => %"PRIx32" bus_offset=%"PRIx64" ps=%"PRIu32 # hw/ppc/ppc.c ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t diff, int64_t seconds) "adjusted from 0x%"PRIx64" to 0x%"PRIx64", diff %"PRId64" (%"PRId64"s)" diff --git a/ui/sdl_zoom.c b/ui/sdl_zoom.c index 72622c2647..b96196bac5 100644 --- a/ui/sdl_zoom.c +++ b/ui/sdl_zoom.c @@ -13,7 +13,6 @@ #include "qemu/osdep.h" #include "sdl_zoom.h" -#include <glib.h> static void sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth, SDL_Rect *dst_rect); diff --git a/ui/spice-display.c b/ui/spice-display.c index 0553c5e5b0..34095fbc8c 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -197,7 +197,7 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) { static const int blksize = 32; - int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize; + int blocks = DIV_ROUND_UP(surface_width(ssd->ds), blksize); int dirty_top[blocks]; int y, yoff1, yoff2, x, xoff, blk, bw; int bpp = surface_bytes_per_pixel(ssd->ds); diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c index 3b89d1af25..dc7c0ba997 100644 --- a/ui/vnc-palette.c +++ b/ui/vnc-palette.c @@ -28,7 +28,6 @@ #include "qemu/osdep.h" #include "vnc-palette.h" -#include <glib.h> static VncPaletteEntry *palette_find(const VncPalette *palette, uint32_t color, unsigned int hash) diff --git a/util/coroutine-gthread.c b/util/coroutine-gthread.c index fb697eb0b7..62bfb4015d 100644 --- a/util/coroutine-gthread.c +++ b/util/coroutine-gthread.c @@ -19,7 +19,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/coroutine_int.h" diff --git a/util/hbitmap.c b/util/hbitmap.c index b22b87d0a6..7121b11c01 100644 --- a/util/hbitmap.c +++ b/util/hbitmap.c @@ -10,7 +10,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/hbitmap.h" #include "qemu/host-utils.h" #include "trace.h" diff --git a/util/memfd.c b/util/memfd.c index 7c406914c5..b374238a59 100644 --- a/util/memfd.c +++ b/util/memfd.c @@ -27,7 +27,6 @@ #include "qemu/osdep.h" -#include <glib.h> #include <glib/gprintf.h> #include <sys/mman.h> diff --git a/util/oslib-win32.c b/util/oslib-win32.c index c926db4a5c..6debc2b8a6 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -31,7 +31,6 @@ */ #include "qemu/osdep.h" #include <windows.h> -#include <glib.h> #include "qapi/error.h" #include "sysemu/sysemu.h" #include "qemu/main-loop.h" diff --git a/util/throttle.c b/util/throttle.c index 71246b2343..654f95caf2 100644 --- a/util/throttle.c +++ b/util/throttle.c @@ -315,6 +315,14 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp) return false; } + if (cfg->op_size && + !cfg->buckets[THROTTLE_OPS_TOTAL].avg && + !cfg->buckets[THROTTLE_OPS_READ].avg && + !cfg->buckets[THROTTLE_OPS_WRITE].avg) { + error_setg(errp, "iops size requires an iops value to be set"); + return false; + } + for (i = 0; i < BUCKETS_COUNT; i++) { if (cfg->buckets[i].avg < 0 || cfg->buckets[i].max < 0 || diff --git a/util/uri.c b/util/uri.c index d109d6c01d..70a9cbcbd2 100644 --- a/util/uri.c +++ b/util/uri.c @@ -52,7 +52,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/uri.h" @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qemu-version.h" #include "qemu/cutils.h" #include "qemu/help_option.h" @@ -51,7 +52,6 @@ int main(int argc, char **argv) #define main qemu_main #endif /* CONFIG_COCOA */ -#include <glib.h> #include "qemu/error-report.h" #include "qemu/sockets.h" @@ -567,7 +567,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state, { hwaddr npages = size >> TARGET_PAGE_BITS; const int width = sizeof(unsigned long) * 8; - unsigned long bitmap[(npages + width - 1) / width]; + unsigned long bitmap[DIV_ROUND_UP(npages, width)]; int rc, i, j; const XenPhysmap *physmap = NULL; |