summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--Makefile.target4
-rw-r--r--block.c17
-rw-r--r--block/iscsi.c20
-rw-r--r--block/nbd.c3
-rw-r--r--block/qcow2.c5
-rw-r--r--block/vvfat.c5
-rw-r--r--blockdev.c25
-rw-r--r--bootdevice.c13
-rw-r--r--cpus.c12
-rw-r--r--default-configs/arm-softmmu.mak5
-rw-r--r--default-configs/i386-softmmu.mak3
-rw-r--r--default-configs/pci.mak1
-rw-r--r--default-configs/ppc-softmmu.mak1
-rw-r--r--default-configs/ppc64-softmmu.mak1
-rw-r--r--default-configs/x86_64-softmmu.mak3
-rw-r--r--hw/core/Makefile.objs2
-rw-r--r--hw/i386/pc.c46
-rw-r--r--hw/misc/Makefile.objs4
-rw-r--r--hw/pci-bridge/Makefile.objs5
-rw-r--r--hw/pci/pci-hotplug-old.c2
-rw-r--r--hw/scsi/scsi-bus.c5
-rw-r--r--hw/scsi/virtio-scsi-dataplane.c4
-rw-r--r--hw/scsi/virtio-scsi.c19
-rw-r--r--hw/usb/dev-network.c4
-rw-r--r--hw/usb/dev-storage.c6
-rw-r--r--hw/vfio/common.c10
-rw-r--r--hw/vfio/pci.c101
-rw-r--r--hw/watchdog/watchdog.c2
-rw-r--r--include/block/block.h3
-rw-r--r--include/hw/vfio/vfio-common.h4
-rw-r--r--include/qemu/option.h18
-rw-r--r--linux-headers/linux/vfio.h1
-rw-r--r--linux-user/main.c9
-rw-r--r--migration/rdma.c24
-rw-r--r--net/net.c6
-rw-r--r--qdev-monitor.c6
-rw-r--r--qemu-char.c68
-rw-r--r--qemu-img.c44
-rw-r--r--qtest.c11
-rw-r--r--scripts/make_device_config.sh2
-rw-r--r--scripts/tracetool/format/d.py26
-rw-r--r--target-i386/cpu-qom.h1
-rw-r--r--target-i386/cpu.c146
-rw-r--r--target-i386/cpu.h13
-rw-r--r--target-i386/kvm.c2
-rw-r--r--target-i386/topology.h (renamed from include/hw/i386/topology.h)6
-rw-r--r--tests/Makefile2
-rw-r--r--tests/test-qemu-opts.c38
-rw-r--r--tests/test-x86-cpuid.c2
-rw-r--r--trace-events4
-rw-r--r--util/qemu-config.c9
-rw-r--r--util/qemu-option.c100
-rw-r--r--util/qemu-sockets.c42
-rw-r--r--vl.c120
55 files changed, 621 insertions, 424 deletions
diff --git a/Makefile b/Makefile
index 6817c6f715..d92d4cd573 100644
--- a/Makefile
+++ b/Makefile
@@ -109,8 +109,8 @@ endif
-include $(SUBDIR_DEVICES_MAK_DEP)
%/config-devices.mak: default-configs/%.mak
- $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $@ $<, " GEN $@")
- @if test -f $@; then \
+ $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/make_device_config.sh $@.tmp $<, " GEN $@.tmp")
+ $(call quiet-command, if test -f $@; then \
if cmp -s $@.old $@; then \
mv $@.tmp $@; \
cp -p $@ $@.old; \
@@ -126,7 +126,7 @@ endif
else \
mv $@.tmp $@; \
cp -p $@ $@.old; \
- fi
+ fi, " GEN $@");
defconfig:
rm -f config-all-devices.mak $(SUBDIR_DEVICES_MAK)
@@ -197,9 +197,9 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS))
recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
-$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
+$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc config-host.h | $(BUILD_DIR)/version.lo
$(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<," RC version.o")
-$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
+$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc config-host.h
$(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<," RC version.lo")
Makefile: $(version-obj-y) $(version-lobj-y)
diff --git a/Makefile.target b/Makefile.target
index 58c6ae1d69..2262d89354 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -175,9 +175,11 @@ all-obj-y += $(common-obj-y)
all-obj-y += $(target-obj-y)
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
+$(QEMU_PROG_BUILD): config-devices.mak
+
# build either PROG or PROGW
$(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
- $(call LINK,$^)
+ $(call LINK, $(filter-out %.mak, $^))
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)$@")
diff --git a/block.c b/block.c
index 9b707e3d1b..28ea19aafb 100644
--- a/block.c
+++ b/block.c
@@ -1364,7 +1364,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0,
&error_abort);
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size, &error_abort);
ret = bdrv_create(&bdrv_qcow2, tmp_filename, opts, &local_err);
qemu_opts_del(opts);
if (ret < 0) {
@@ -5649,18 +5649,22 @@ void bdrv_img_create(const char *filename, const char *fmt,
/* Create parameter list with default values */
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, &error_abort);
/* Parse -o options */
if (options) {
- if (qemu_opts_do_parse(opts, options, NULL) != 0) {
+ qemu_opts_do_parse(opts, options, NULL, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ local_err = NULL;
error_setg(errp, "Invalid options for file format '%s'", fmt);
goto out;
}
}
if (base_filename) {
- if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename, &local_err);
+ if (local_err) {
error_setg(errp, "Backing file not supported for file format '%s'",
fmt);
goto out;
@@ -5668,7 +5672,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
if (base_fmt) {
- if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, &local_err);
+ if (local_err) {
error_setg(errp, "Backing file format not supported for file "
"format '%s'", fmt);
goto out;
@@ -5731,7 +5736,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
goto out;
}
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort);
bdrv_unref(bs);
} else {
diff --git a/block/iscsi.c b/block/iscsi.c
index 12ddbfb095..1fa855acdd 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -65,6 +65,7 @@ typedef struct IscsiLun {
unsigned long *allocationmap;
int cluster_sectors;
bool use_16_for_rw;
+ bool write_protected;
} IscsiLun;
typedef struct IscsiTask {
@@ -1268,10 +1269,6 @@ out:
/*
* We support iscsi url's on the form
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
- *
- * Note: flags are currently not used by iscsi_open. If this function
- * is changed such that flags are used, please examine iscsi_reopen_prepare()
- * to see if needs to be changed as well.
*/
static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
@@ -1385,9 +1382,10 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
scsi_free_scsi_task(task);
task = NULL;
+ iscsilun->write_protected = iscsi_is_write_protected(iscsilun);
/* Check the write protect flag of the LUN if we want to write */
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
- iscsi_is_write_protected(iscsilun)) {
+ iscsilun->write_protected) {
error_setg(errp, "Cannot open a write protected LUN as read-write");
ret = -EACCES;
goto out;
@@ -1541,13 +1539,17 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
sector_limits_lun2qemu(iscsilun->bl.opt_xfer_len, iscsilun);
}
-/* Since iscsi_open() ignores bdrv_flags, there is nothing to do here in
- * prepare. Note that this will not re-establish a connection with an iSCSI
- * target - it is effectively a NOP. */
+/* Note that this will not re-establish a connection with an iSCSI target - it
+ * is effectively a NOP. */
static int iscsi_reopen_prepare(BDRVReopenState *state,
BlockReopenQueue *queue, Error **errp)
{
- /* NOP */
+ IscsiLun *iscsilun = state->bs->opaque;
+
+ if (state->flags & BDRV_O_RDWR && iscsilun->write_protected) {
+ error_setg(errp, "Cannot open a write protected LUN as read-write");
+ return -EACCES;
+ }
return 0;
}
diff --git a/block/nbd.c b/block/nbd.c
index 2f3b9adf72..697c0219b4 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -215,7 +215,8 @@ static void nbd_config(BDRVNBDState *s, QDict *options, char **export,
}
if (!qemu_opt_get(s->socket_opts, "port")) {
- qemu_opt_set_number(s->socket_opts, "port", NBD_DEFAULT_PORT);
+ qemu_opt_set_number(s->socket_opts, "port", NBD_DEFAULT_PORT,
+ &error_abort);
}
*export = g_strdup(qdict_get_try_str(options, "export"));
diff --git a/block/qcow2.c b/block/qcow2.c
index 2ed8d95b1f..50e0a947df 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1858,8 +1858,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
meta_size += nreftablee * sizeof(uint64_t);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
- aligned_total_size + meta_size);
- qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc]);
+ aligned_total_size + meta_size, &error_abort);
+ qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc],
+ &error_abort);
}
ret = bdrv_create_file(filename, opts, &local_err);
diff --git a/block/vvfat.c b/block/vvfat.c
index a1a44f0ef5..9be632f404 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2924,8 +2924,9 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
}
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
- qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512,
+ &error_abort);
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:", &error_abort);
ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
qemu_opts_del(opts);
diff --git a/blockdev.c b/blockdev.c
index ae73539551..b9c1c0cc1a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -180,21 +180,19 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
const char *optstr)
{
QemuOpts *opts;
- char buf[32];
opts = drive_def(optstr);
if (!opts) {
return NULL;
}
if (type != IF_DEFAULT) {
- qemu_opt_set(opts, "if", if_name[type]);
+ qemu_opt_set(opts, "if", if_name[type], &error_abort);
}
if (index >= 0) {
- snprintf(buf, sizeof(buf), "%d", index);
- qemu_opt_set(opts, "index", buf);
+ qemu_opt_set_number(opts, "index", index, &error_abort);
}
if (file)
- qemu_opt_set(opts, "file", file);
+ qemu_opt_set(opts, "file", file, &error_abort);
return opts;
}
@@ -584,7 +582,7 @@ static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
/* rename all items in opts */
while ((value = qemu_opt_get(opts, from))) {
- qemu_opt_set(opts, to, value);
+ qemu_opt_set(opts, to, value, &error_abort);
qemu_opt_unset(opts, from);
}
}
@@ -737,15 +735,15 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
/* Specific options take precedence */
if (!qemu_opt_get(all_opts, "cache.writeback")) {
qemu_opt_set_bool(all_opts, "cache.writeback",
- !!(flags & BDRV_O_CACHE_WB));
+ !!(flags & BDRV_O_CACHE_WB), &error_abort);
}
if (!qemu_opt_get(all_opts, "cache.direct")) {
qemu_opt_set_bool(all_opts, "cache.direct",
- !!(flags & BDRV_O_NOCACHE));
+ !!(flags & BDRV_O_NOCACHE), &error_abort);
}
if (!qemu_opt_get(all_opts, "cache.no-flush")) {
qemu_opt_set_bool(all_opts, "cache.no-flush",
- !!(flags & BDRV_O_NO_FLUSH));
+ !!(flags & BDRV_O_NO_FLUSH), &error_abort);
}
qemu_opt_unset(all_opts, "cache");
}
@@ -935,13 +933,14 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
if (arch_type == QEMU_ARCH_S390X) {
- qemu_opt_set(devopts, "driver", "virtio-blk-s390");
+ qemu_opt_set(devopts, "driver", "virtio-blk-s390", &error_abort);
} else {
- qemu_opt_set(devopts, "driver", "virtio-blk-pci");
+ qemu_opt_set(devopts, "driver", "virtio-blk-pci", &error_abort);
}
- qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"));
+ qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),
+ &error_abort);
if (devaddr) {
- qemu_opt_set(devopts, "addr", devaddr);
+ qemu_opt_set(devopts, "addr", devaddr, &error_abort);
}
}
diff --git a/bootdevice.c b/bootdevice.c
index c3a010c094..eacd8c88c2 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -221,10 +221,15 @@ char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
}
if (!ignore_suffixes) {
- d = qdev_get_own_fw_dev_path_from_handler(i->dev->parent_bus, i->dev);
- if (d) {
- assert(!i->suffix);
- suffix = d;
+ if (i->dev) {
+ d = qdev_get_own_fw_dev_path_from_handler(i->dev->parent_bus,
+ i->dev);
+ if (d) {
+ assert(!i->suffix);
+ suffix = d;
+ } else {
+ suffix = g_strdup(i->suffix);
+ }
} else {
suffix = g_strdup(i->suffix);
}
diff --git a/cpus.c b/cpus.c
index 1cd9867893..0fac143355 100644
--- a/cpus.c
+++ b/cpus.c
@@ -778,7 +778,7 @@ static void qemu_tcg_init_cpu_signals(void)
static QemuMutex qemu_global_mutex;
static QemuCond qemu_io_proceeded_cond;
-static bool iothread_requesting_mutex;
+static unsigned iothread_requesting_mutex;
static QemuThread io_thread;
@@ -1025,6 +1025,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
}
+ /* process any pending work */
+ exit_request = 1;
+
while (1) {
tcg_exec_all();
@@ -1115,15 +1118,16 @@ bool qemu_in_vcpu_thread(void)
void qemu_mutex_lock_iothread(void)
{
- if (!tcg_enabled()) {
+ atomic_inc(&iothread_requesting_mutex);
+ if (!tcg_enabled() || !first_cpu) {
qemu_mutex_lock(&qemu_global_mutex);
+ atomic_dec(&iothread_requesting_mutex);
} else {
- iothread_requesting_mutex = true;
if (qemu_mutex_trylock(&qemu_global_mutex)) {
qemu_cpu_kick_thread(first_cpu);
qemu_mutex_lock(&qemu_global_mutex);
}
- iothread_requesting_mutex = false;
+ atomic_dec(&iothread_requesting_mutex);
qemu_cond_broadcast(&qemu_io_proceeded_cond);
}
}
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b00c2e150e..149ae1b595 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -34,6 +34,7 @@ CONFIG_PFLASH_CFI02=y
CONFIG_MICRODRIVE=y
CONFIG_USB_MUSB=y
CONFIG_USB_EHCI_SYSBUS=y
+CONFIG_PLATFORM_BUS=y
CONFIG_ARM11MPCORE=y
CONFIG_A9MPCORE=y
@@ -91,3 +92,7 @@ CONFIG_INTEGRATOR_DEBUG=y
CONFIG_ALLWINNER_A10_PIT=y
CONFIG_ALLWINNER_A10_PIC=y
CONFIG_ALLWINNER_A10=y
+
+CONFIG_XIO3130=y
+CONFIG_IOH3420=y
+CONFIG_I82801B11=y
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index bd99af9942..0b8ce4bbf8 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -43,3 +43,6 @@ CONFIG_IOAPIC=y
CONFIG_ICC_BUS=y
CONFIG_PVPANIC=y
CONFIG_MEM_HOTPLUG=y
+CONFIG_XIO3130=y
+CONFIG_IOH3420=y
+CONFIG_I82801B11=y
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index bea6b01553..58a2c0ace1 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -35,3 +35,4 @@ CONFIG_SDHCI=y
CONFIG_EDU=y
CONFIG_VGA=y
CONFIG_VGA_PCI=y
+CONFIG_IVSHMEM=$(CONFIG_KVM)
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index aebfab92eb..4b60e699ff 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -43,6 +43,7 @@ CONFIG_PREP=y
CONFIG_MAC=y
CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
+CONFIG_PLATFORM_BUS=y
CONFIG_ETSEC=y
CONFIG_LIBDECNUMBER=y
# For PReP
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index f195a8721a..de71e41b00 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -44,6 +44,7 @@ CONFIG_PREP=y
CONFIG_MAC=y
CONFIG_E500=y
CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
+CONFIG_PLATFORM_BUS=y
CONFIG_ETSEC=y
CONFIG_LIBDECNUMBER=y
# For pSeries
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index e7c273417b..6add04a2f6 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -43,3 +43,6 @@ CONFIG_IOAPIC=y
CONFIG_ICC_BUS=y
CONFIG_PVPANIC=y
CONFIG_MEM_HOTPLUG=y
+CONFIG_XIO3130=y
+CONFIG_IOH3420=y
+CONFIG_I82801B11=y
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 9dce1bc53c..abb3560bea 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -14,4 +14,4 @@ common-obj-$(CONFIG_SOFTMMU) += machine.o
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
common-obj-$(CONFIG_SOFTMMU) += loader.o
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
-common-obj-$(CONFIG_SOFTMMU) += platform-bus.o
+common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d2e07ca981..b229856a26 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -25,8 +25,6 @@
#include "hw/i386/pc.h"
#include "hw/char/serial.h"
#include "hw/i386/apic.h"
-#include "hw/i386/topology.h"
-#include "sysemu/cpus.h"
#include "hw/block/fdc.h"
#include "hw/ide.h"
#include "hw/pci/pci.h"
@@ -631,39 +629,6 @@ bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t *length)
return false;
}
-/* Enables contiguous-apic-ID mode, for compatibility */
-static bool compat_apic_id_mode;
-
-void enable_compat_apic_id_mode(void)
-{
- compat_apic_id_mode = true;
-}
-
-/* Calculates initial APIC ID for a specific CPU index
- *
- * Currently we need to be able to calculate the APIC ID from the CPU index
- * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
- * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
- * all CPUs up to max_cpus.
- */
-uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
-{
- uint32_t correct_id;
- static bool warned;
-
- correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
- if (compat_apic_id_mode) {
- if (cpu_index != correct_id && !warned) {
- error_report("APIC IDs set in compatibility mode, "
- "CPU topology won't match the configuration");
- warned = true;
- }
- return cpu_index;
- } else {
- return correct_id;
- }
-}
-
/* Calculates the limit to CPU APIC ID values
*
* This function returns the limit for the APIC ID value, so that all
@@ -1173,15 +1138,11 @@ void pc_acpi_init(const char *default_dsdt)
if (filename == NULL) {
fprintf(stderr, "WARNING: failed to find %s\n", default_dsdt);
} else {
- char *arg;
- QemuOpts *opts;
+ QemuOpts *opts = qemu_opts_create(qemu_find_opts("acpi"), NULL, 0,
+ &error_abort);
Error *err = NULL;
- arg = g_strdup_printf("file=%s", filename);
-
- /* creates a deep copy of "arg" */
- opts = qemu_opts_parse(qemu_find_opts("acpi"), arg, 0);
- g_assert(opts != NULL);
+ qemu_opt_set(opts, "file", filename, &error_abort);
acpi_table_add_builtin(opts, &err);
if (err) {
@@ -1189,7 +1150,6 @@ void pc_acpi_init(const char *default_dsdt)
error_get_pretty(err));
error_free(err);
}
- g_free(arg);
g_free(filename);
}
}
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 029a56f279..6c6e29681a 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -19,9 +19,7 @@ common-obj-$(CONFIG_PUV3) += puv3_pm.o
common-obj-$(CONFIG_MACIO) += macio/
-ifeq ($(CONFIG_PCI), y)
-obj-$(CONFIG_KVM) += ivshmem.o
-endif
+obj-$(CONFIG_IVSHMEM) += ivshmem.o
obj-$(CONFIG_REALVIEW) += arm_sysctl.o
obj-$(CONFIG_NSERIES) += cbus.o
diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index 968b3694ab..96c596eb31 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -1,5 +1,6 @@
common-obj-y += pci_bridge_dev.o
-common-obj-y += ioh3420.o xio3130_upstream.o xio3130_downstream.o
-common-obj-y += i82801b11.o
+common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
+common-obj-$(CONFIG_IOH3420) += ioh3420.o
+common-obj-$(CONFIG_I82801B11) += i82801b11.o
# NewWorld PowerMac
common-obj-$(CONFIG_DEC_PCI) += dec.o
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index beea6d2b02..501a918b89 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -87,7 +87,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
return NULL;
}
- qemu_opt_set(opts, "type", "nic");
+ qemu_opt_set(opts, "type", "nic", &error_abort);
ret = net_client_init(opts, 0, &local_err);
if (local_err) {
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index db39ae0e23..dca9576828 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -221,11 +221,16 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
const char *serial, Error **errp)
{
const char *driver;
+ char *name;
DeviceState *dev;
Error *err = NULL;
driver = blk_is_sg(blk) ? "scsi-generic" : "scsi-disk";
dev = qdev_create(&bus->qbus, driver);
+ name = g_strdup_printf("legacy[%d]", unit);
+ object_property_add_child(OBJECT(bus), name, OBJECT(dev), NULL);
+ g_free(name);
+
qdev_prop_set_uint32(dev, "scsi-id", unit);
if (bootindex >= 0) {
object_property_set_int(OBJECT(dev), bootindex, "bootindex",
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 418d73b1b4..3f40ff090f 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -211,8 +211,6 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s)
s->dataplane_starting = true;
- assert(!s->blocker);
- error_setg(&s->blocker, "block device is in use by data plane");
/* Set up guest notifier (irq) */
rc = k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, true);
if (rc != 0) {
@@ -279,8 +277,6 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s)
if (!s->dataplane_started || s->dataplane_stopping) {
return;
}
- error_free(s->blocker);
- s->blocker = NULL;
s->dataplane_stopping = true;
assert(s->ctx == iothread_get_aio_context(vs->conf.iothread));
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 9e2c718be7..4db3b23ea3 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -254,10 +254,8 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
int target;
int ret = 0;
- if (s->dataplane_started && blk_get_aio_context(d->conf.blk) != s->ctx) {
- aio_context_acquire(s->ctx);
- blk_set_aio_context(d->conf.blk, s->ctx);
- aio_context_release(s->ctx);
+ if (s->dataplane_started) {
+ assert(blk_get_aio_context(d->conf.blk) == s->ctx);
}
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
@@ -540,10 +538,8 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
virtio_scsi_complete_cmd_req(req);
return false;
}
- if (s->dataplane_started && blk_get_aio_context(d->conf.blk) != s->ctx) {
- aio_context_acquire(s->ctx);
- blk_set_aio_context(d->conf.blk, s->ctx);
- aio_context_release(s->ctx);
+ if (s->dataplane_started) {
+ assert(blk_get_aio_context(d->conf.blk) == s->ctx);
}
req->sreq = scsi_req_new(d, req->req.cmd.tag,
virtio_scsi_get_lun(req->req.cmd.lun),
@@ -767,6 +763,9 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
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);
}
if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
@@ -904,6 +903,8 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
virtio_scsi_save, virtio_scsi_load, s);
s->migration_state_notifier.notify = virtio_scsi_migration_state_changed;
add_migration_state_change_notifier(&s->migration_state_notifier);
+
+ error_setg(&s->blocker, "block device is in use by data plane");
}
static void virtio_scsi_instance_init(Object *obj)
@@ -929,6 +930,8 @@ 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);
remove_migration_state_change_notifier(&s->migration_state_notifier);
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index b27b1f441e..18669917f5 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1394,8 +1394,8 @@ static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
if (!opts) {
return NULL;
}
- qemu_opt_set(opts, "type", "nic");
- qemu_opt_set(opts, "model", "usb");
+ qemu_opt_set(opts, "type", "nic", &error_abort);
+ qemu_opt_set(opts, "model", "usb", &error_abort);
idx = net_client_init(opts, 0, &local_err);
if (local_err) {
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index af2e1b915d..65d9aa6147 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -683,7 +683,7 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
if (strstart(filename, "format=", &p2)) {
int len = MIN(p1 - p2, sizeof(fmt));
pstrcpy(fmt, len, p2);
- qemu_opt_set(opts, "format", fmt);
+ qemu_opt_set(opts, "format", fmt, &error_abort);
} else if (*filename != ':') {
error_report("unrecognized USB mass-storage option %s", filename);
return NULL;
@@ -694,8 +694,8 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename)
error_report("block device specification needed");
return NULL;
}
- qemu_opt_set(opts, "file", filename);
- qemu_opt_set(opts, "if", "none");
+ qemu_opt_set(opts, "file", filename, &error_abort);
+ qemu_opt_set(opts, "if", "none", &error_abort);
/* create host drive */
dinfo = drive_new(opts, 0);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index c5d15510dd..9db7d8da17 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -475,12 +475,12 @@ static void vfio_listener_region_del(MemoryListener *listener,
}
}
-const MemoryListener vfio_memory_listener = {
+static const MemoryListener vfio_memory_listener = {
.region_add = vfio_listener_region_add,
.region_del = vfio_listener_region_del,
};
-void vfio_listener_release(VFIOContainer *container)
+static void vfio_listener_release(VFIOContainer *container)
{
memory_listener_unregister(&container->iommu_data.type1.listener);
}
@@ -493,7 +493,7 @@ int vfio_mmap_region(Object *obj, VFIORegion *region,
int ret = 0;
VFIODevice *vbasedev = region->vbasedev;
- if (VFIO_ALLOW_MMAP && size && region->flags &
+ if (vbasedev->allow_mmap && size && region->flags &
VFIO_REGION_INFO_FLAG_MMAP) {
int prot = 0;
@@ -932,8 +932,8 @@ static int vfio_container_do_ioctl(AddressSpace *as, int32_t groupid,
if (group->container) {
ret = ioctl(container->fd, req, param);
if (ret < 0) {
- error_report("vfio: failed to ioctl container: ret=%d, %s",
- ret, strerror(errno));
+ error_report("vfio: failed to ioctl %d to container: ret=%d, %s",
+ _IOC_NR(req) - VFIO_BASE, ret, strerror(errno));
}
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 84e9d995aa..6b80539c1f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -153,13 +153,17 @@ typedef struct VFIOPCIDevice {
VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */
PCIHostDeviceAddress host;
EventNotifier err_notifier;
+ EventNotifier req_notifier;
uint32_t features;
#define VFIO_FEATURE_ENABLE_VGA_BIT 0
#define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
+#define VFIO_FEATURE_ENABLE_REQ_BIT 1
+#define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT)
int32_t bootindex;
uint8_t pm_cap;
bool has_vga;
bool pci_aer;
+ bool req_enabled;
bool has_flr;
bool has_pm_reset;
bool rom_read_failed;
@@ -3088,6 +3092,7 @@ static int vfio_populate_device(VFIOPCIDevice *vdev)
vdev->has_vga = true;
}
+
irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;
ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);
@@ -3223,6 +3228,97 @@ static void vfio_unregister_err_notifier(VFIOPCIDevice *vdev)
event_notifier_cleanup(&vdev->err_notifier);
}
+static void vfio_req_notifier_handler(void *opaque)
+{
+ VFIOPCIDevice *vdev = opaque;
+
+ if (!event_notifier_test_and_clear(&vdev->req_notifier)) {
+ return;
+ }
+
+ qdev_unplug(&vdev->pdev.qdev, NULL);
+}
+
+static void vfio_register_req_notifier(VFIOPCIDevice *vdev)
+{
+ struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info),
+ .index = VFIO_PCI_REQ_IRQ_INDEX };
+ int argsz;
+ struct vfio_irq_set *irq_set;
+ int32_t *pfd;
+
+ if (!(vdev->features & VFIO_FEATURE_ENABLE_REQ)) {
+ return;
+ }
+
+ if (ioctl(vdev->vbasedev.fd,
+ VFIO_DEVICE_GET_IRQ_INFO, &irq_info) < 0 || irq_info.count < 1) {
+ return;
+ }
+
+ if (event_notifier_init(&vdev->req_notifier, 0)) {
+ error_report("vfio: Unable to init event notifier for device request");
+ return;
+ }
+
+ argsz = sizeof(*irq_set) + sizeof(*pfd);
+
+ irq_set = g_malloc0(argsz);
+ irq_set->argsz = argsz;
+ irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+ VFIO_IRQ_SET_ACTION_TRIGGER;
+ irq_set->index = VFIO_PCI_REQ_IRQ_INDEX;
+ irq_set->start = 0;
+ irq_set->count = 1;
+ pfd = (int32_t *)&irq_set->data;
+
+ *pfd = event_notifier_get_fd(&vdev->req_notifier);
+ qemu_set_fd_handler(*pfd, vfio_req_notifier_handler, NULL, vdev);
+
+ if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+ error_report("vfio: Failed to set up device request notification");
+ qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
+ event_notifier_cleanup(&vdev->req_notifier);
+ } else {
+ vdev->req_enabled = true;
+ }
+
+ g_free(irq_set);
+}
+
+static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev)
+{
+ int argsz;
+ struct vfio_irq_set *irq_set;
+ int32_t *pfd;
+
+ if (!vdev->req_enabled) {
+ return;
+ }
+
+ argsz = sizeof(*irq_set) + sizeof(*pfd);
+
+ irq_set = g_malloc0(argsz);
+ irq_set->argsz = argsz;
+ irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+ VFIO_IRQ_SET_ACTION_TRIGGER;
+ irq_set->index = VFIO_PCI_REQ_IRQ_INDEX;
+ irq_set->start = 0;
+ irq_set->count = 1;
+ pfd = (int32_t *)&irq_set->data;
+ *pfd = -1;
+
+ if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+ error_report("vfio: Failed to de-assign device request fd: %m");
+ }
+ g_free(irq_set);
+ qemu_set_fd_handler(event_notifier_get_fd(&vdev->req_notifier),
+ NULL, NULL, vdev);
+ event_notifier_cleanup(&vdev->req_notifier);
+
+ vdev->req_enabled = false;
+}
+
static int vfio_initfn(PCIDevice *pdev)
{
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
@@ -3370,6 +3466,7 @@ static int vfio_initfn(PCIDevice *pdev)
}
vfio_register_err_notifier(vdev);
+ vfio_register_req_notifier(vdev);
return 0;
@@ -3397,6 +3494,7 @@ static void vfio_exitfn(PCIDevice *pdev)
{
VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+ vfio_unregister_req_notifier(vdev);
vfio_unregister_err_notifier(vdev);
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
vfio_disable_interrupts(vdev);
@@ -3455,7 +3553,10 @@ static Property vfio_pci_dev_properties[] = {
intx.mmap_timeout, 1100),
DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
VFIO_FEATURE_ENABLE_VGA_BIT, false),
+ DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
+ VFIO_FEATURE_ENABLE_REQ_BIT, true),
DEFINE_PROP_INT32("bootindex", VFIOPCIDevice, bootindex, -1),
+ DEFINE_PROP_BOOL("x-mmap", VFIOPCIDevice, vbasedev.allow_mmap, true),
/*
* TODO - support passed fds... is this necessary?
* DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name),
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index c307f9b57e..54440c91c5 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -68,7 +68,7 @@ int select_watchdog(const char *p)
/* add the device */
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
- qemu_opt_set(opts, "driver", p);
+ qemu_opt_set(opts, "driver", p, &error_abort);
return 0;
}
}
diff --git a/include/block/block.h b/include/block/block.h
index 471d11dbbe..649c269ecd 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -547,8 +547,7 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs);
* Changes the #AioContext used for fd handlers, timers, and BHs by this
* BlockDriverState and all its children.
*
- * This function must be called from the old #AioContext or with a lock held so
- * the old #AioContext is not executing.
+ * This function must be called with iothread lock held.
*/
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 5f3679b7b2..0d1fb805bb 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -36,7 +36,6 @@
#endif
/* Extra debugging, trap acceleration paths for more logging */
-#define VFIO_ALLOW_MMAP 1
#define VFIO_ALLOW_KVM_INTX 1
#define VFIO_ALLOW_KVM_MSI 1
#define VFIO_ALLOW_KVM_MSIX 1
@@ -102,6 +101,7 @@ typedef struct VFIODevice {
int type;
bool reset_works;
bool needs_reset;
+ bool allow_mmap;
VFIODeviceOps *ops;
unsigned int num_irqs;
unsigned int num_regions;
@@ -131,7 +131,6 @@ void vfio_region_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size);
uint64_t vfio_region_read(void *opaque,
hwaddr addr, unsigned size);
-void vfio_listener_release(VFIOContainer *container);
int vfio_mmap_region(Object *vdev, VFIORegion *region,
MemoryRegion *mem, MemoryRegion *submem,
void **map, size_t size, off_t offset,
@@ -143,7 +142,6 @@ int vfio_get_device(VFIOGroup *group, const char *name,
VFIODevice *vbasedev);
extern const MemoryRegionOps vfio_region_ops;
-extern const MemoryListener vfio_memory_listener;
extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list;
extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces;
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 58c0157ed5..f88b545dfc 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -94,11 +94,12 @@ uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name,
uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
uint64_t defval);
int qemu_opt_unset(QemuOpts *opts, const char *name);
-int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
-void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
- Error **errp);
-int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
-int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val);
+void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
+ Error **errp);
+void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
+ Error **errp);
+void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
+ Error **errp);
typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
int abort_on_failure);
@@ -108,13 +109,14 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
void qemu_opts_reset(QemuOptsList *list);
void qemu_opts_loc_restore(QemuOpts *opts);
-int qemu_opts_set(QemuOptsList *list, const char *id,
- const char *name, const char *value);
+void qemu_opts_set(QemuOptsList *list, const char *id,
+ const char *name, const char *value, Error **errp);
const char *qemu_opts_id(QemuOpts *opts);
void qemu_opts_set_id(QemuOpts *opts, char *id);
void qemu_opts_del(QemuOpts *opts);
void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
-int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
+void qemu_opts_do_parse(QemuOpts *opts, const char *params,
+ const char *firstname, Error **errp);
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
int permit_abbrev);
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 0f21aa6266..95ba870302 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -333,6 +333,7 @@ enum {
VFIO_PCI_MSI_IRQ_INDEX,
VFIO_PCI_MSIX_IRQ_INDEX,
VFIO_PCI_ERR_IRQ_INDEX,
+ VFIO_PCI_REQ_IRQ_INDEX,
VFIO_PCI_NUM_IRQS
};
diff --git a/linux-user/main.c b/linux-user/main.c
index 111c1ffafc..d92702a734 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3453,17 +3453,10 @@ CPUArchState *cpu_copy(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
CPUArchState *new_env = cpu_init(cpu_model);
- CPUState *new_cpu;
+ CPUState *new_cpu = ENV_GET_CPU(new_env);
CPUBreakpoint *bp;
CPUWatchpoint *wp;
- if (!new_env) {
- fprintf(stderr, "cpu_copy: Failed to create new CPU\n");
- exit(1);
- }
-
- new_cpu = ENV_GET_CPU(new_env);
-
/* Reset non arch specific state */
cpu_reset(new_cpu);
diff --git a/migration/rdma.c b/migration/rdma.c
index 6bee30c6c1..17d00351b1 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -510,7 +510,7 @@ static inline uint8_t *ram_chunk_end(const RDMALocalBlock *rdma_ram_block,
return result;
}
-static int __qemu_rdma_add_block(RDMAContext *rdma, void *host_addr,
+static int rdma_add_block(RDMAContext *rdma, void *host_addr,
ram_addr_t block_offset, uint64_t length)
{
RDMALocalBlocks *local = &rdma->local_ram_blocks;
@@ -551,13 +551,12 @@ static int __qemu_rdma_add_block(RDMAContext *rdma, void *host_addr,
g_hash_table_insert(rdma->blockmap, (void *) block_offset, block);
- trace___qemu_rdma_add_block(local->nb_blocks,
- (uint64_t) block->local_host_addr, block->offset,
- block->length,
- (uint64_t) (block->local_host_addr + block->length),
- BITS_TO_LONGS(block->nb_chunks) *
- sizeof(unsigned long) * 8,
- block->nb_chunks);
+ trace_rdma_add_block(local->nb_blocks, (uint64_t) block->local_host_addr,
+ block->offset, block->length,
+ (uint64_t) (block->local_host_addr + block->length),
+ BITS_TO_LONGS(block->nb_chunks) *
+ sizeof(unsigned long) * 8,
+ block->nb_chunks);
local->nb_blocks++;
@@ -572,7 +571,7 @@ static int __qemu_rdma_add_block(RDMAContext *rdma, void *host_addr,
static void qemu_rdma_init_one_block(void *host_addr,
ram_addr_t block_offset, ram_addr_t length, void *opaque)
{
- __qemu_rdma_add_block(opaque, host_addr, block_offset, length);
+ rdma_add_block(opaque, host_addr, block_offset, length);
}
/*
@@ -595,7 +594,7 @@ static int qemu_rdma_init_ram_blocks(RDMAContext *rdma)
return 0;
}
-static int __qemu_rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset)
+static int rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset)
{
RDMALocalBlocks *local = &rdma->local_ram_blocks;
RDMALocalBlock *block = g_hash_table_lookup(rdma->blockmap,
@@ -657,7 +656,7 @@ static int __qemu_rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset)
local->block = NULL;
}
- trace___qemu_rdma_delete_block(local->nb_blocks,
+ trace_rdma_delete_block(local->nb_blocks,
(uint64_t)block->local_host_addr,
block->offset, block->length,
(uint64_t)(block->local_host_addr + block->length),
@@ -2187,8 +2186,7 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
if (rdma->local_ram_blocks.block) {
while (rdma->local_ram_blocks.nb_blocks) {
- __qemu_rdma_delete_block(rdma,
- rdma->local_ram_blocks.block->offset);
+ rdma_delete_block(rdma, rdma->local_ram_blocks.block->offset);
}
}
diff --git a/net/net.c b/net/net.c
index 5146361f07..11fb769dff 100644
--- a/net/net.c
+++ b/net/net.c
@@ -970,7 +970,7 @@ void hmp_host_net_add(Monitor *mon, const QDict *qdict)
return;
}
- qemu_opt_set(opts, "type", device);
+ qemu_opt_set(opts, "type", device, &error_abort);
net_client_init(opts, 0, &local_err);
if (local_err) {
@@ -1296,9 +1296,9 @@ int net_init_clients(void)
if (default_net) {
/* if no clients, we use a default config */
- qemu_opts_set(net, NULL, "type", "nic");
+ qemu_opts_set(net, NULL, "type", "nic", &error_abort);
#ifdef CONFIG_SLIRP
- qemu_opts_set(net, NULL, "type", "user");
+ qemu_opts_set(net, NULL, "type", "user", &error_abort);
#endif
}
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 0c25b823f2..5d30ac534c 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -772,8 +772,8 @@ int qemu_global_option(const char *str)
}
opts = qemu_opts_create(&qemu_global_opts, NULL, 0, &error_abort);
- qemu_opt_set(opts, "driver", driver);
- qemu_opt_set(opts, "property", property);
- qemu_opt_set(opts, "value", str+offset+1);
+ qemu_opt_set(opts, "driver", driver, &error_abort);
+ qemu_opt_set(opts, "property", property, &error_abort);
+ qemu_opt_set(opts, "value", str + offset + 1, &error_abort);
return 0;
}
diff --git a/qemu-char.c b/qemu-char.c
index 8159462fc0..a405d76c31 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3312,14 +3312,14 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
if (strstart(filename, "mon:", &p)) {
filename = p;
- qemu_opt_set(opts, "mux", "on");
+ qemu_opt_set(opts, "mux", "on", &error_abort);
if (strcmp(filename, "stdio") == 0) {
/* Monitor is muxed to stdio: do not exit on Ctrl+C by default
* but pass it to the guest. Handle this only for compat syntax,
* for -chardev syntax we have special option for this.
* This is what -nographic did, redirecting+muxing serial+monitor
* to stdio causing Ctrl+C to be passed to guest. */
- qemu_opt_set(opts, "signal", "off");
+ qemu_opt_set(opts, "signal", "off", &error_abort);
}
}
@@ -3329,20 +3329,20 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
strcmp(filename, "braille") == 0 ||
strcmp(filename, "testdev") == 0 ||
strcmp(filename, "stdio") == 0) {
- qemu_opt_set(opts, "backend", filename);
+ qemu_opt_set(opts, "backend", filename, &error_abort);
return opts;
}
if (strstart(filename, "vc", &p)) {
- qemu_opt_set(opts, "backend", "vc");
+ qemu_opt_set(opts, "backend", "vc", &error_abort);
if (*p == ':') {
if (sscanf(p+1, "%7[0-9]x%7[0-9]", width, height) == 2) {
/* pixels */
- qemu_opt_set(opts, "width", width);
- qemu_opt_set(opts, "height", height);
+ qemu_opt_set(opts, "width", width, &error_abort);
+ qemu_opt_set(opts, "height", height, &error_abort);
} else if (sscanf(p+1, "%7[0-9]Cx%7[0-9]C", width, height) == 2) {
/* chars */
- qemu_opt_set(opts, "cols", width);
- qemu_opt_set(opts, "rows", height);
+ qemu_opt_set(opts, "cols", width, &error_abort);
+ qemu_opt_set(opts, "rows", height, &error_abort);
} else {
goto fail;
}
@@ -3350,22 +3350,22 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
return opts;
}
if (strcmp(filename, "con:") == 0) {
- qemu_opt_set(opts, "backend", "console");
+ qemu_opt_set(opts, "backend", "console", &error_abort);
return opts;
}
if (strstart(filename, "COM", NULL)) {
- qemu_opt_set(opts, "backend", "serial");
- qemu_opt_set(opts, "path", filename);
+ qemu_opt_set(opts, "backend", "serial", &error_abort);
+ qemu_opt_set(opts, "path", filename, &error_abort);
return opts;
}
if (strstart(filename, "file:", &p)) {
- qemu_opt_set(opts, "backend", "file");
- qemu_opt_set(opts, "path", p);
+ qemu_opt_set(opts, "backend", "file", &error_abort);
+ qemu_opt_set(opts, "path", p, &error_abort);
return opts;
}
if (strstart(filename, "pipe:", &p)) {
- qemu_opt_set(opts, "backend", "pipe");
- qemu_opt_set(opts, "path", p);
+ qemu_opt_set(opts, "backend", "pipe", &error_abort);
+ qemu_opt_set(opts, "path", p, &error_abort);
return opts;
}
if (strstart(filename, "tcp:", &p) ||
@@ -3375,27 +3375,30 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)
goto fail;
}
- qemu_opt_set(opts, "backend", "socket");
- qemu_opt_set(opts, "host", host);
- qemu_opt_set(opts, "port", port);
+ qemu_opt_set(opts, "backend", "socket", &error_abort);
+ qemu_opt_set(opts, "host", host, &error_abort);
+ qemu_opt_set(opts, "port", port, &error_abort);
if (p[pos] == ',') {
- if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)
+ qemu_opts_do_parse(opts, p+pos+1, NULL, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
goto fail;
+ }
}
if (strstart(filename, "telnet:", &p))
- qemu_opt_set(opts, "telnet", "on");
+ qemu_opt_set(opts, "telnet", "on", &error_abort);
return opts;
}
if (strstart(filename, "udp:", &p)) {
- qemu_opt_set(opts, "backend", "udp");
+ qemu_opt_set(opts, "backend", "udp", &error_abort);
if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {
host[0] = 0;
if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {
goto fail;
}
}
- qemu_opt_set(opts, "host", host);
- qemu_opt_set(opts, "port", port);
+ qemu_opt_set(opts, "host", host, &error_abort);
+ qemu_opt_set(opts, "port", port, &error_abort);
if (p[pos] == '@') {
p += pos + 1;
if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {
@@ -3404,26 +3407,29 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
goto fail;
}
}
- qemu_opt_set(opts, "localaddr", host);
- qemu_opt_set(opts, "localport", port);
+ qemu_opt_set(opts, "localaddr", host, &error_abort);
+ qemu_opt_set(opts, "localport", port, &error_abort);
}
return opts;
}
if (strstart(filename, "unix:", &p)) {
- qemu_opt_set(opts, "backend", "socket");
- if (qemu_opts_do_parse(opts, p, "path") != 0)
+ qemu_opt_set(opts, "backend", "socket", &error_abort);
+ qemu_opts_do_parse(opts, p, "path", &local_err);
+ if (local_err) {
+ error_report_err(local_err);
goto fail;
+ }
return opts;
}
if (strstart(filename, "/dev/parport", NULL) ||
strstart(filename, "/dev/ppi", NULL)) {
- qemu_opt_set(opts, "backend", "parport");
- qemu_opt_set(opts, "path", filename);
+ qemu_opt_set(opts, "backend", "parport", &error_abort);
+ qemu_opt_set(opts, "path", filename, &error_abort);
return opts;
}
if (strstart(filename, "/dev/", NULL)) {
- qemu_opt_set(opts, "backend", "tty");
- qemu_opt_set(opts, "path", filename);
+ qemu_opt_set(opts, "backend", "tty", &error_abort);
+ qemu_opt_set(opts, "path", filename, &error_abort);
return opts;
}
diff --git a/qemu-img.c b/qemu-img.c
index fcdfb6719e..7ac7f56c5d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -332,17 +332,23 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts,
const char *base_filename,
const char *base_fmt)
{
+ Error *err = NULL;
+
if (base_filename) {
- if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename, &err);
+ if (err) {
error_report("Backing file not supported for file format '%s'",
fmt);
+ error_free(err);
return -1;
}
}
if (base_fmt) {
- if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt, &err);
+ if (err) {
error_report("Backing file format not supported for file "
"format '%s'", fmt);
+ error_free(err);
return -1;
}
}
@@ -1544,13 +1550,18 @@ static int img_convert(int argc, char **argv)
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
- if (options && qemu_opts_do_parse(opts, options, NULL)) {
- error_report("Invalid options for file format '%s'", out_fmt);
- ret = -1;
- goto out;
+ if (options) {
+ qemu_opts_do_parse(opts, options, NULL, &local_err);
+ if (local_err) {
+ error_report("Invalid options for file format '%s'", out_fmt);
+ error_free(local_err);
+ ret = -1;
+ goto out;
+ }
}
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512,
+ &error_abort);
ret = add_old_style_options(out_fmt, opts, out_baseimg, NULL);
if (ret < 0) {
goto out;
@@ -2749,6 +2760,7 @@ out:
static int img_resize(int argc, char **argv)
{
+ Error *err = NULL;
int c, ret, relative;
const char *filename, *fmt, *size;
int64_t n, total_size;
@@ -2820,8 +2832,9 @@ static int img_resize(int argc, char **argv)
/* Parse size */
param = qemu_opts_create(&resize_options, NULL, 0, &error_abort);
- if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
- /* Error message already printed when size parsing fails */
+ qemu_opt_set(param, BLOCK_OPT_SIZE, size, &err);
+ if (err) {
+ error_report_err(err);
ret = -1;
qemu_opts_del(param);
goto out;
@@ -2878,6 +2891,7 @@ static void amend_status_cb(BlockDriverState *bs,
static int img_amend(int argc, char **argv)
{
+ Error *err = NULL;
int c, ret = 0;
char *options = NULL;
QemuOptsList *create_opts = NULL;
@@ -2983,10 +2997,14 @@ static int img_amend(int argc, char **argv)
create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
- if (options && qemu_opts_do_parse(opts, options, NULL)) {
- error_report("Invalid options for file format '%s'", fmt);
- ret = -1;
- goto out;
+ if (options) {
+ qemu_opts_do_parse(opts, options, NULL, &err);
+ if (err) {
+ error_report("Invalid options for file format '%s'", fmt);
+ error_free(err);
+ ret = -1;
+ goto out;
+ }
}
/* In case the driver does not call amend_status_cb() */
diff --git a/qtest.c b/qtest.c
index 2bca04ed4c..8d1e66caa3 100644
--- a/qtest.c
+++ b/qtest.c
@@ -520,16 +520,13 @@ static void qtest_event(void *opaque, int event)
}
}
-static void configure_qtest_icount(const char *options)
+static int qtest_init_accel(MachineState *ms)
{
- QemuOpts *opts = qemu_opts_parse(qemu_find_opts("icount"), options, 1);
+ QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0,
+ &error_abort);
+ qemu_opt_set(opts, "shift", "0", &error_abort);
configure_icount(opts, &error_abort);
qemu_opts_del(opts);
-}
-
-static int qtest_init_accel(MachineState *ms)
-{
- configure_qtest_icount("0");
return 0;
}
diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh
index 7242707819..7958086132 100644
--- a/scripts/make_device_config.sh
+++ b/scripts/make_device_config.sh
@@ -2,7 +2,7 @@
# Construct a target device config file from a default, pulling in any
# files from include directives.
-dest=$1.tmp
+dest=$1
dep=`dirname $1`-`basename $1`.d
src=$2
src_dir=`dirname $src`
diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
index 46eebb128b..c77d5b7ab0 100644
--- a/scripts/tracetool/format/d.py
+++ b/scripts/tracetool/format/d.py
@@ -16,6 +16,19 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
+# Reserved keywords from
+# https://wikis.oracle.com/display/DTrace/Types,+Operators+and+Expressions
+RESERVED_WORDS = (
+ 'auto', 'goto', 'sizeof', 'break', 'if', 'static', 'case', 'import',
+ 'string', 'char', 'inline', 'stringof', 'const', 'int', 'struct',
+ 'continue', 'long', 'switch', 'counter', 'offsetof', 'this',
+ 'default', 'probe', 'translator', 'do', 'provider', 'typedef',
+ 'double', 'register', 'union', 'else', 'restrict', 'unsigned',
+ 'enum', 'return', 'void', 'extern', 'self', 'volatile', 'float',
+ 'short', 'while', 'for', 'signed', 'xlate',
+)
+
+
def generate(events, backend):
events = [e for e in events
if "disable" not in e.properties]
@@ -25,18 +38,17 @@ def generate(events, backend):
'provider qemu {')
for e in events:
- args = str(e.args)
-
- # DTrace provider syntax expects foo() for empty
- # params, not foo(void)
- if args == 'void':
- args = ''
+ args = []
+ for type_, name in e.args:
+ if name in RESERVED_WORDS:
+ name += '_'
+ args.append(type_ + ' ' + name)
# Define prototype for probe arguments
out('',
'probe %(name)s(%(args)s);',
name=e.name,
- args=args)
+ args=','.join(args))
out('',
'};')
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 31a0c1e776..b557b619cf 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -93,7 +93,6 @@ typedef struct X86CPU {
bool expose_kvm;
bool migratable;
bool host_features;
- int64_t apic_id;
/* if true the CPUID code directly forward host cache leaves to the guest */
bool cache_info_passthrough;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 14c6c4abaf..d543e2b537 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -25,6 +25,7 @@
#include "sysemu/kvm.h"
#include "sysemu/cpus.h"
#include "kvm_i386.h"
+#include "topology.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
@@ -1689,7 +1690,7 @@ static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
X86CPU *cpu = X86_CPU(obj);
- int64_t value = cpu->apic_id;
+ int64_t value = cpu->env.cpuid_apic_id;
visit_type_int(v, &value, name, errp);
}
@@ -1722,11 +1723,11 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
return;
}
- if ((value != cpu->apic_id) && cpu_exists(value)) {
+ if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
return;
}
- cpu->apic_id = value;
+ cpu->env.cpuid_apic_id = value;
}
/* Generic getter for "feature-words" and "filtered-features" properties */
@@ -1910,19 +1911,34 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
}
}
-/* Print all cpuid feature names in featureset
+/* generate a composite string into buf of all cpuid names in featureset
+ * selected by fbits. indicate truncation at bufsize in the event of overflow.
+ * if flags, suppress names undefined in featureset.
*/
-static void listflags(FILE *f, fprintf_function print, const char **featureset)
-{
- int bit;
- bool first = true;
-
- for (bit = 0; bit < 32; bit++) {
- if (featureset[bit]) {
- print(f, "%s%s", first ? "" : " ", featureset[bit]);
- first = false;
+static void listflags(char *buf, int bufsize, uint32_t fbits,
+ const char **featureset, uint32_t flags)
+{
+ const char **p = &featureset[31];
+ char *q, *b, bit;
+ int nc;
+
+ b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
+ *buf = '\0';
+ for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
+ if (fbits & 1 << bit && (*p || !flags)) {
+ if (*p)
+ nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
+ else
+ nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
+ if (bufsize <= nc) {
+ if (b) {
+ memcpy(b, "...", sizeof("..."));
+ }
+ return;
+ }
+ q += nc;
+ bufsize -= nc;
}
- }
}
/* generate CPU information. */
@@ -1947,9 +1963,8 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
FeatureWordInfo *fw = &feature_word_info[i];
- (*cpu_fprintf)(f, " ");
- listflags(f, cpu_fprintf, fw->feat_names);
- (*cpu_fprintf)(f, "\n");
+ listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
+ (*cpu_fprintf)(f, " %s\n", buf);
}
}
@@ -2134,35 +2149,27 @@ out:
return cpu;
}
-CPUX86State *cpu_x86_init_user(const char *cpu_model)
+X86CPU *cpu_x86_init(const char *cpu_model)
{
Error *error = NULL;
X86CPU *cpu;
cpu = cpu_x86_create(cpu_model, NULL, &error);
if (error) {
- goto error;
- }
-
- object_property_set_int(OBJECT(cpu), CPU(cpu)->cpu_index, "apic-id",
- &error);
- if (error) {
- goto error;
+ goto out;
}
object_property_set_bool(OBJECT(cpu), true, "realized", &error);
- if (error) {
- goto error;
- }
- return &cpu->env;
-
-error:
- error_report_err(error);
- if (cpu != NULL) {
- object_unref(OBJECT(cpu));
+out:
+ if (error) {
+ error_report_err(error);
+ if (cpu != NULL) {
+ object_unref(OBJECT(cpu));
+ cpu = NULL;
+ }
}
- return NULL;
+ return cpu;
}
static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
@@ -2220,6 +2227,14 @@ void x86_cpudef_setup(void)
}
}
+static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ *ebx = env->cpuid_vendor1;
+ *edx = env->cpuid_vendor2;
+ *ecx = env->cpuid_vendor3;
+}
+
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
@@ -2253,14 +2268,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
switch(index) {
case 0:
*eax = env->cpuid_level;
- *ebx = env->cpuid_vendor1;
- *edx = env->cpuid_vendor2;
- *ecx = env->cpuid_vendor3;
+ get_cpuid_vendor(env, ebx, ecx, edx);
break;
case 1:
*eax = env->cpuid_version;
- *ebx = (cpu->apic_id << 24) |
- 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+ *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
*ecx = env->features[FEAT_1_ECX];
*edx = env->features[FEAT_1_EDX];
if (cs->nr_cores * cs->nr_threads > 1) {
@@ -2449,9 +2461,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
* So dont set it here for Intel to make Linux guests happy.
*/
if (cs->nr_cores * cs->nr_threads > 1) {
- if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
- env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
- env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
+ uint32_t tebx, tecx, tedx;
+ get_cpuid_vendor(env, &tebx, &tecx, &tedx);
+ if (tebx != CPUID_VENDOR_INTEL_1 ||
+ tedx != CPUID_VENDOR_INTEL_2 ||
+ tecx != CPUID_VENDOR_INTEL_3) {
*ecx |= 1 << 1; /* CmpLegacy bit */
}
}
@@ -2707,6 +2721,7 @@ static void mce_init(X86CPU *cpu)
#ifndef CONFIG_USER_ONLY
static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
{
+ CPUX86State *env = &cpu->env;
DeviceState *dev = DEVICE(cpu);
APICCommonState *apic;
const char *apic_type = "apic";
@@ -2725,7 +2740,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
object_property_add_child(OBJECT(cpu), "apic",
OBJECT(cpu->apic_state), NULL);
- qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
+ qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
/* TODO: convert to link<> */
apic = APIC_COMMON(cpu->apic_state);
apic->cpu = cpu;
@@ -2765,11 +2780,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
Error *local_err = NULL;
static bool ht_warned;
- if (cpu->apic_id < 0) {
- error_setg(errp, "apic-id property was not initialized properly");
- return;
- }
-
if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
env->cpuid_level = 7;
}
@@ -2834,6 +2844,39 @@ out:
}
}
+/* Enables contiguous-apic-ID mode, for compatibility */
+static bool compat_apic_id_mode;
+
+void enable_compat_apic_id_mode(void)
+{
+ compat_apic_id_mode = true;
+}
+
+/* Calculates initial APIC ID for a specific CPU index
+ *
+ * Currently we need to be able to calculate the APIC ID from the CPU index
+ * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
+ * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
+ * all CPUs up to max_cpus.
+ */
+uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
+{
+ uint32_t correct_id;
+ static bool warned;
+
+ correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
+ if (compat_apic_id_mode) {
+ if (cpu_index != correct_id && !warned) {
+ error_report("APIC IDs set in compatibility mode, "
+ "CPU topology won't match the configuration");
+ warned = true;
+ }
+ return cpu_index;
+ } else {
+ return correct_id;
+ }
+}
+
static void x86_cpu_initfn(Object *obj)
{
CPUState *cs = CPU(obj);
@@ -2880,7 +2923,7 @@ static void x86_cpu_initfn(Object *obj)
NULL, NULL, (void *)cpu->filtered_features, NULL);
cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
- cpu->apic_id = -1;
+ env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
@@ -2894,8 +2937,9 @@ static void x86_cpu_initfn(Object *obj)
static int64_t x86_cpu_get_arch_id(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
- return cpu->apic_id;
+ return env->cpuid_apic_id;
}
static bool x86_cpu_get_paging_enabled(const CPUState *cs)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index f0e6ca4843..478450cfb6 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -944,6 +944,7 @@ typedef struct CPUX86State {
uint32_t cpuid_version;
FeatureWordArray features;
uint32_t cpuid_model[12];
+ uint32_t cpuid_apic_id;
/* MTRRs */
uint64_t mtrr_fixed[11];
@@ -981,6 +982,7 @@ typedef struct CPUX86State {
#include "cpu-qom.h"
+X86CPU *cpu_x86_init(const char *cpu_model);
X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
Error **errp);
int cpu_x86_exec(CPUX86State *s);
@@ -1169,9 +1171,14 @@ uint64_t cpu_get_tsc(CPUX86State *env);
# define PHYS_ADDR_MASK 0xfffffffffLL
# endif
-/* CPU creation function for *-user */
-CPUX86State *cpu_x86_init_user(const char *cpu_model);
-#define cpu_init cpu_x86_init_user
+static inline CPUX86State *cpu_init(const char *cpu_model)
+{
+ X86CPU *cpu = cpu_x86_init(cpu_model);
+ if (cpu == NULL) {
+ return NULL;
+ }
+ return &cpu->env;
+}
#define cpu_exec cpu_x86_exec
#define cpu_gen_code cpu_x86_gen_code
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 27fe2be653..40d6a14c85 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -430,7 +430,7 @@ static void cpu_update_state(void *opaque, int running, RunState state)
unsigned long kvm_arch_vcpu_id(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
- return cpu->apic_id;
+ return cpu->env.cpuid_apic_id;
}
#ifndef KVM_CPUID_SIGNATURE_NEXT
diff --git a/include/hw/i386/topology.h b/target-i386/topology.h
index 9c6f3a937a..07a6c5fb55 100644
--- a/include/hw/i386/topology.h
+++ b/target-i386/topology.h
@@ -21,8 +21,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#ifndef HW_I386_TOPOLOGY_H
-#define HW_I386_TOPOLOGY_H
+#ifndef TARGET_I386_TOPOLOGY_H
+#define TARGET_I386_TOPOLOGY_H
/* This file implements the APIC-ID-based CPU topology enumeration logic,
* documented at the following document:
@@ -131,4 +131,4 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_cores,
return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
}
-#endif /* HW_I386_TOPOLOGY_H */
+#endif /* TARGET_I386_TOPOLOGY_H */
diff --git a/tests/Makefile b/tests/Makefile
index 7d4b96d4fd..307035c26c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -239,6 +239,8 @@ $(test-obj-y): QEMU_INCLUDES += -Itests
QEMU_CFLAGS += -I$(SRC_PATH)/tests
qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o
+tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386
+
tests/check-qint$(EXESUF): tests/check-qint.o libqemuutil.a
tests/check-qstring$(EXESUF): tests/check-qstring.o libqemuutil.a
tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
index ca08ac523d..da564923d0 100644
--- a/tests/test-qemu-opts.c
+++ b/tests/test-qemu-opts.c
@@ -148,13 +148,13 @@ static void test_qemu_opt_get(void)
opt = qemu_opt_get(opts, "str2");
g_assert(opt == NULL);
- qemu_opt_set(opts, "str2", "value");
+ qemu_opt_set(opts, "str2", "value", &error_abort);
/* now we have set str2, should know about it */
opt = qemu_opt_get(opts, "str2");
g_assert_cmpstr(opt, ==, "value");
- qemu_opt_set(opts, "str2", "value2");
+ qemu_opt_set(opts, "str2", "value2", &error_abort);
/* having reset the value, the returned should be the reset one */
opt = qemu_opt_get(opts, "str2");
@@ -169,10 +169,10 @@ static void test_qemu_opt_get(void)
static void test_qemu_opt_get_bool(void)
{
+ Error *err = NULL;
QemuOptsList *list;
QemuOpts *opts;
bool opt;
- int ret;
list = qemu_find_opts("opts_list_02");
g_assert(list != NULL);
@@ -192,16 +192,16 @@ static void test_qemu_opt_get_bool(void)
opt = qemu_opt_get_bool(opts, "bool1", false);
g_assert(opt == false);
- ret = qemu_opt_set_bool(opts, "bool1", true);
- g_assert(ret == 0);
+ qemu_opt_set_bool(opts, "bool1", true, &err);
+ g_assert(!err);
/* now we have set bool1, should know about it */
opt = qemu_opt_get_bool(opts, "bool1", false);
g_assert(opt == true);
/* having reset the value, opt should be the reset one not defval */
- ret = qemu_opt_set_bool(opts, "bool1", false);
- g_assert(ret == 0);
+ qemu_opt_set_bool(opts, "bool1", false, &err);
+ g_assert(!err);
opt = qemu_opt_get_bool(opts, "bool1", true);
g_assert(opt == false);
@@ -215,10 +215,10 @@ static void test_qemu_opt_get_bool(void)
static void test_qemu_opt_get_number(void)
{
+ Error *err = NULL;
QemuOptsList *list;
QemuOpts *opts;
uint64_t opt;
- int ret;
list = qemu_find_opts("opts_list_01");
g_assert(list != NULL);
@@ -238,16 +238,16 @@ static void test_qemu_opt_get_number(void)
opt = qemu_opt_get_number(opts, "number1", 5);
g_assert(opt == 5);
- ret = qemu_opt_set_number(opts, "number1", 10);
- g_assert(ret == 0);
+ qemu_opt_set_number(opts, "number1", 10, &err);
+ g_assert(!err);
/* now we have set number1, should know about it */
opt = qemu_opt_get_number(opts, "number1", 5);
g_assert(opt == 10);
/* having reset it, the returned should be the reset one not defval */
- ret = qemu_opt_set_number(opts, "number1", 15);
- g_assert(ret == 0);
+ qemu_opt_set_number(opts, "number1", 15, &err);
+ g_assert(!err);
opt = qemu_opt_get_number(opts, "number1", 5);
g_assert(opt == 15);
@@ -331,7 +331,7 @@ static void test_qemu_opt_unset(void)
g_assert_cmpstr(value, ==, "value");
/* reset it to value2 */
- qemu_opt_set(opts, "key", "value2");
+ qemu_opt_set(opts, "key", "value2", &error_abort);
value = qemu_opt_get(opts, "key");
g_assert_cmpstr(value, ==, "value2");
@@ -349,10 +349,10 @@ static void test_qemu_opt_unset(void)
static void test_qemu_opts_reset(void)
{
+ Error *err = NULL;
QemuOptsList *list;
QemuOpts *opts;
uint64_t opt;
- int ret;
list = qemu_find_opts("opts_list_01");
g_assert(list != NULL);
@@ -372,8 +372,8 @@ static void test_qemu_opts_reset(void)
opt = qemu_opt_get_number(opts, "number1", 5);
g_assert(opt == 5);
- ret = qemu_opt_set_number(opts, "number1", 10);
- g_assert(ret == 0);
+ qemu_opt_set_number(opts, "number1", 10, &err);
+ g_assert(!err);
/* now we have set number1, should know about it */
opt = qemu_opt_get_number(opts, "number1", 5);
@@ -388,9 +388,9 @@ static void test_qemu_opts_reset(void)
static void test_qemu_opts_set(void)
{
+ Error *err = NULL;
QemuOptsList *list;
QemuOpts *opts;
- int ret;
const char *opt;
list = qemu_find_opts("opts_list_01");
@@ -403,8 +403,8 @@ static void test_qemu_opts_set(void)
g_assert(opts == NULL);
/* implicitly create opts and set str3 value */
- ret = qemu_opts_set(list, NULL, "str3", "value");
- g_assert(ret == 0);
+ qemu_opts_set(list, NULL, "str3", "value", &err);
+ g_assert(!err);
g_assert(!QTAILQ_EMPTY(&list->head));
/* get the just created opts */
diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c
index 6cd20d4a23..8d9f96a113 100644
--- a/tests/test-x86-cpuid.c
+++ b/tests/test-x86-cpuid.c
@@ -24,7 +24,7 @@
#include <glib.h>
-#include "hw/i386/topology.h"
+#include "topology.h"
static void test_topo_bits(void)
{
diff --git a/trace-events b/trace-events
index f87b077805..9c6b15b010 100644
--- a/trace-events
+++ b/trace-events
@@ -1378,8 +1378,6 @@ migrate_pending(uint64_t size, uint64_t max) "pending size %" PRIu64 " max %" PR
migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %g max_size %" PRId64
# migration/rdma.c
-__qemu_rdma_add_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Added Block: %d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
-__qemu_rdma_delete_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Deleted Block: %d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
qemu_dma_accept_incoming_migration(void) ""
qemu_dma_accept_incoming_migration_accepted(void) ""
qemu_rdma_accept_pin_state(bool pin) "%d"
@@ -1433,6 +1431,8 @@ qemu_rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) "Receive
qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) "Sending registration request chunk %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)"
qemu_rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) "Entire chunk is zero, sending compress: %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
+rdma_add_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Added Block: %d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
+rdma_delete_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Deleted Block: %d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
rdma_start_incoming_migration(void) ""
rdma_start_incoming_migration_after_dest_init(void) ""
rdma_start_incoming_migration_after_rdma_listen(void) ""
diff --git a/util/qemu-config.c b/util/qemu-config.c
index b13efe2788..f3463df678 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -219,6 +219,7 @@ void qemu_add_opts(QemuOptsList *list)
int qemu_set_option(const char *str)
{
+ Error *local_err = NULL;
char group[64], id[64], arg[64];
QemuOptsList *list;
QemuOpts *opts;
@@ -242,7 +243,9 @@ int qemu_set_option(const char *str)
return -1;
}
- if (qemu_opt_set(opts, arg, str+offset+1) == -1) {
+ qemu_opt_set(opts, arg, str + offset + 1, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
return -1;
}
return 0;
@@ -335,7 +338,9 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
error_report("no group defined");
goto out;
}
- if (qemu_opt_set(opts, arg, value) != 0) {
+ qemu_opt_set(opts, arg, value, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
goto out;
}
continue;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index d3ab65d24f..fda4e5fcbf 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -548,27 +548,14 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
}
}
-int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
-{
- Error *local_err = NULL;
-
- opt_set(opts, name, value, false, &local_err);
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
-
- return 0;
-}
-
-void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
- Error **errp)
+void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
+ Error **errp)
{
opt_set(opts, name, value, false, errp);
}
-int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
+void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
+ Error **errp)
{
QemuOpt *opt;
const QemuOptDesc *desc = opts->list->desc;
@@ -576,9 +563,9 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
opt = g_malloc0(sizeof(*opt));
opt->desc = find_desc_by_name(desc, name);
if (!opt->desc && !opts_accepts_any(opts)) {
- qerror_report(QERR_INVALID_PARAMETER, name);
+ error_set(errp, QERR_INVALID_PARAMETER, name);
g_free(opt);
- return -1;
+ return;
}
opt->name = g_strdup(name);
@@ -586,11 +573,10 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
opt->value.boolean = !!val;
opt->str = g_strdup(val ? "on" : "off");
QTAILQ_INSERT_TAIL(&opts->head, opt, next);
-
- return 0;
}
-int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
+void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
+ Error **errp)
{
QemuOpt *opt;
const QemuOptDesc *desc = opts->list->desc;
@@ -598,9 +584,9 @@ int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
opt = g_malloc0(sizeof(*opt));
opt->desc = find_desc_by_name(desc, name);
if (!opt->desc && !opts_accepts_any(opts)) {
- qerror_report(QERR_INVALID_PARAMETER, name);
+ error_set(errp, QERR_INVALID_PARAMETER, name);
g_free(opt);
- return -1;
+ return;
}
opt->name = g_strdup(name);
@@ -608,8 +594,6 @@ int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
opt->value.uint = val;
opt->str = g_strdup_printf("%" PRId64, val);
QTAILQ_INSERT_TAIL(&opts->head, opt, next);
-
- return 0;
}
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
@@ -692,19 +676,18 @@ void qemu_opts_loc_restore(QemuOpts *opts)
loc_restore(&opts->loc);
}
-int qemu_opts_set(QemuOptsList *list, const char *id,
- const char *name, const char *value)
+void qemu_opts_set(QemuOptsList *list, const char *id,
+ const char *name, const char *value, Error **errp)
{
QemuOpts *opts;
Error *local_err = NULL;
opts = qemu_opts_create(list, id, 1, &local_err);
if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
+ error_propagate(errp, local_err);
+ return;
}
- return qemu_opt_set(opts, name, value);
+ qemu_opt_set(opts, name, value, errp);
}
const char *qemu_opts_id(QemuOpts *opts)
@@ -767,8 +750,8 @@ void qemu_opts_print(QemuOpts *opts, const char *sep)
}
}
-static int opts_do_parse(QemuOpts *opts, const char *params,
- const char *firstname, bool prepend)
+static void opts_do_parse(QemuOpts *opts, const char *params,
+ const char *firstname, bool prepend, Error **errp)
{
char option[128], value[1024];
const char *p,*pe,*pc;
@@ -806,25 +789,30 @@ static int opts_do_parse(QemuOpts *opts, const char *params,
/* store and parse */
opt_set(opts, option, value, prepend, &local_err);
if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
+ error_propagate(errp, local_err);
+ return;
}
}
if (*p != ',') {
break;
}
}
- return 0;
}
-int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
+/**
+ * Store options parsed from @params into @opts.
+ * If @firstname is non-null, the first key=value in @params may omit
+ * key=, and is treated as if key was @firstname.
+ * On error, store an error object through @errp if non-null.
+ */
+void qemu_opts_do_parse(QemuOpts *opts, const char *params,
+ const char *firstname, Error **errp)
{
- return opts_do_parse(opts, params, firstname, false);
+ opts_do_parse(opts, params, firstname, false, errp);
}
static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
- int permit_abbrev, bool defaults)
+ int permit_abbrev, bool defaults, Error **errp)
{
const char *firstname;
char value[1024], *id = NULL;
@@ -853,14 +841,13 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
assert(!defaults || list->merge_lists);
opts = qemu_opts_create(list, id, !defaults, &local_err);
if (opts == NULL) {
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- }
+ error_propagate(errp, local_err);
return NULL;
}
- if (opts_do_parse(opts, params, firstname, defaults) != 0) {
+ opts_do_parse(opts, params, firstname, defaults, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
qemu_opts_del(opts);
return NULL;
}
@@ -868,10 +855,25 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
return opts;
}
+/**
+ * Create a QemuOpts in @list and with options parsed from @params.
+ * If @permit_abbrev, the first key=value in @params may omit key=,
+ * and is treated as if key was @list->implied_opt_name.
+ * Report errors with qerror_report_err().
+ * Return the new QemuOpts on success, null pointer on error.
+ */
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
int permit_abbrev)
{
- return opts_parse(list, params, permit_abbrev, false);
+ Error *err = NULL;
+ QemuOpts *opts;
+
+ opts = opts_parse(list, params, permit_abbrev, false, &err);
+ if (!opts) {
+ qerror_report_err(err);
+ error_free(err);
+ }
+ return opts;
}
void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
@@ -879,7 +881,7 @@ void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
{
QemuOpts *opts;
- opts = opts_parse(list, params, permit_abbrev, true);
+ opts = opts_parse(list, params, permit_abbrev, true, NULL);
assert(opts);
}
@@ -924,7 +926,7 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
return;
}
- qemu_opt_set_err(state->opts, key, value, state->errp);
+ qemu_opt_set(state->opts, key, value, state->errp);
}
/*
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 61fc3c1364..87c9bc6c68 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -199,11 +199,13 @@ listen:
freeaddrinfo(res);
return -1;
}
- snprintf(uport, sizeof(uport), "%d", inet_getport(e) - port_offset);
- qemu_opt_set(opts, "host", uaddr);
- qemu_opt_set(opts, "port", uport);
- qemu_opt_set(opts, "ipv6", (e->ai_family == PF_INET6) ? "on" : "off");
- qemu_opt_set(opts, "ipv4", (e->ai_family != PF_INET6) ? "on" : "off");
+ qemu_opt_set(opts, "host", uaddr, &error_abort);
+ qemu_opt_set_number(opts, "port", inet_getport(e) - port_offset,
+ &error_abort);
+ qemu_opt_set_bool(opts, "ipv6", e->ai_family == PF_INET6,
+ &error_abort);
+ qemu_opt_set_bool(opts, "ipv4", e->ai_family != PF_INET6,
+ &error_abort);
freeaddrinfo(res);
return slisten;
}
@@ -580,16 +582,14 @@ static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr)
bool ipv6 = addr->ipv6 || !addr->has_ipv6;
if (!ipv4 || !ipv6) {
- qemu_opt_set_bool(opts, "ipv4", ipv4);
- qemu_opt_set_bool(opts, "ipv6", ipv6);
+ qemu_opt_set_bool(opts, "ipv4", ipv4, &error_abort);
+ qemu_opt_set_bool(opts, "ipv6", ipv6, &error_abort);
}
if (addr->has_to) {
- char to[20];
- snprintf(to, sizeof(to), "%d", addr->to);
- qemu_opt_set(opts, "to", to);
+ qemu_opt_set_number(opts, "to", addr->to, &error_abort);
}
- qemu_opt_set(opts, "host", addr->host);
- qemu_opt_set(opts, "port", addr->port);
+ qemu_opt_set(opts, "host", addr->host, &error_abort);
+ qemu_opt_set(opts, "port", addr->port, &error_abort);
}
int inet_listen(const char *str, char *ostr, int olen,
@@ -726,7 +726,7 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
goto err;
}
close(fd);
- qemu_opt_set(opts, "path", un.sun_path);
+ qemu_opt_set(opts, "path", un.sun_path, &error_abort);
}
unlink(un.sun_path);
@@ -838,11 +838,11 @@ int unix_listen(const char *str, char *ostr, int olen, Error **errp)
if (len) {
path = g_malloc(len+1);
snprintf(path, len+1, "%.*s", len, str);
- qemu_opt_set(opts, "path", path);
+ qemu_opt_set(opts, "path", path, &error_abort);
g_free(path);
}
} else {
- qemu_opt_set(opts, "path", str);
+ qemu_opt_set(opts, "path", str, &error_abort);
}
sock = unix_listen_opts(opts, errp);
@@ -859,7 +859,7 @@ int unix_connect(const char *path, Error **errp)
int sock;
opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
- qemu_opt_set(opts, "path", path);
+ qemu_opt_set(opts, "path", path, &error_abort);
sock = unix_connect_opts(opts, errp, NULL, NULL);
qemu_opts_del(opts);
return sock;
@@ -876,7 +876,7 @@ int unix_nonblocking_connect(const char *path,
g_assert(callback != NULL);
opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
- qemu_opt_set(opts, "path", path);
+ qemu_opt_set(opts, "path", path, &error_abort);
sock = unix_connect_opts(opts, errp, callback, opaque);
qemu_opts_del(opts);
return sock;
@@ -933,7 +933,7 @@ int socket_connect(SocketAddress *addr, Error **errp,
break;
case SOCKET_ADDRESS_KIND_UNIX:
- qemu_opt_set(opts, "path", addr->q_unix->path);
+ qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort);
fd = unix_connect_opts(opts, errp, callback, opaque);
break;
@@ -965,7 +965,7 @@ int socket_listen(SocketAddress *addr, Error **errp)
break;
case SOCKET_ADDRESS_KIND_UNIX:
- qemu_opt_set(opts, "path", addr->q_unix->path);
+ qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort);
fd = unix_listen_opts(opts, errp);
break;
@@ -990,8 +990,8 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
case SOCKET_ADDRESS_KIND_INET:
inet_addr_to_opts(opts, remote->inet);
if (local) {
- qemu_opt_set(opts, "localaddr", local->inet->host);
- qemu_opt_set(opts, "localport", local->inet->port);
+ qemu_opt_set(opts, "localaddr", local->inet->host, &error_abort);
+ qemu_opt_set(opts, "localport", local->inet->port, &error_abort);
}
fd = inet_dgram_opts(opts, errp);
break;
diff --git a/vl.c b/vl.c
index 86bdce07e3..801d48709c 100644
--- a/vl.c
+++ b/vl.c
@@ -707,13 +707,17 @@ void vm_start(void)
/***********************************************************/
/* real time host monotonic timer */
+static time_t qemu_time(void)
+{
+ return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
+}
+
/***********************************************************/
/* host time/date access */
void qemu_get_timedate(struct tm *tm, int offset)
{
- time_t ti;
+ time_t ti = qemu_time();
- time(&ti);
ti += offset;
if (rtc_date_offset == -1) {
if (rtc_utc)
@@ -741,7 +745,7 @@ int qemu_timedate_diff(struct tm *tm)
else
seconds = mktimegm(tm) + rtc_date_offset;
- return seconds - time(NULL);
+ return seconds - qemu_time();
}
static void configure_rtc_date_offset(const char *startdate, int legacy)
@@ -779,7 +783,7 @@ static void configure_rtc_date_offset(const char *startdate, int legacy)
"'2006-06-17T16:01:21' or '2006-06-17'\n");
exit(1);
}
- rtc_date_offset = time(NULL) - rtc_start_date;
+ rtc_date_offset = qemu_time() - rtc_start_date;
}
}
@@ -1093,7 +1097,7 @@ static int drive_init_func(QemuOpts *opts, void *opaque)
static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
{
if (qemu_opt_get(opts, "snapshot") == NULL) {
- qemu_opt_set(opts, "snapshot", "on");
+ qemu_opt_set(opts, "snapshot", "on", &error_abort);
}
return 0;
}
@@ -2071,7 +2075,7 @@ static int balloon_parse(const char *arg)
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
}
- qemu_opt_set(opts, "driver", "virtio-balloon");
+ qemu_opt_set(opts, "driver", "virtio-balloon", &error_abort);
return 0;
}
@@ -2217,11 +2221,11 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty)
error_report_err(local_err);
exit(1);
}
- qemu_opt_set(opts, "mode", mode);
- qemu_opt_set(opts, "chardev", label);
- qemu_opt_set_bool(opts, "pretty", pretty);
+ qemu_opt_set(opts, "mode", mode, &error_abort);
+ qemu_opt_set(opts, "chardev", label, &error_abort);
+ qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
if (def)
- qemu_opt_set(opts, "default", "on");
+ qemu_opt_set(opts, "default", "on", &error_abort);
monitor_device_index++;
}
@@ -2333,13 +2337,13 @@ static int virtcon_parse(const char *devname)
bus_opts = qemu_opts_create(device, NULL, 0, &error_abort);
if (arch_type == QEMU_ARCH_S390X) {
- qemu_opt_set(bus_opts, "driver", "virtio-serial-s390");
+ qemu_opt_set(bus_opts, "driver", "virtio-serial-s390", &error_abort);
} else {
- qemu_opt_set(bus_opts, "driver", "virtio-serial-pci");
+ qemu_opt_set(bus_opts, "driver", "virtio-serial-pci", &error_abort);
}
dev_opts = qemu_opts_create(device, NULL, 0, &error_abort);
- qemu_opt_set(dev_opts, "driver", "virtconsole");
+ qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort);
snprintf(label, sizeof(label), "virtcon%d", index);
virtcon_hds[index] = qemu_chr_new(label, devname, NULL);
@@ -2348,7 +2352,7 @@ static int virtcon_parse(const char *devname)
" to character backend '%s'\n", devname);
return -1;
}
- qemu_opt_set(dev_opts, "chardev", label);
+ qemu_opt_set(dev_opts, "chardev", label, &error_abort);
index++;
return 0;
@@ -2372,7 +2376,7 @@ static int sclp_parse(const char *devname)
assert(arch_type == QEMU_ARCH_S390X);
dev_opts = qemu_opts_create(device, NULL, 0, NULL);
- qemu_opt_set(dev_opts, "driver", "sclpconsole");
+ qemu_opt_set(dev_opts, "driver", "sclpconsole", &error_abort);
snprintf(label, sizeof(label), "sclpcon%d", index);
sclp_hds[index] = qemu_chr_new(label, devname, NULL);
@@ -2381,7 +2385,7 @@ static int sclp_parse(const char *devname)
" to character backend '%s'\n", devname);
return -1;
}
- qemu_opt_set(dev_opts, "chardev", label);
+ qemu_opt_set(dev_opts, "chardev", label, &error_abort);
index++;
return 0;
@@ -2399,8 +2403,8 @@ static int debugcon_parse(const char *devname)
fprintf(stderr, "qemu: already have a debugcon device\n");
exit(1);
}
- qemu_opt_set(opts, "driver", "isa-debugcon");
- qemu_opt_set(opts, "chardev", "debugcon");
+ qemu_opt_set(opts, "driver", "isa-debugcon", &error_abort);
+ qemu_opt_set(opts, "chardev", "debugcon", &error_abort);
return 0;
}
@@ -2681,7 +2685,7 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size)
}
/* store value for the future use */
- qemu_opt_set_number(opts, "size", ram_size);
+ qemu_opt_set_number(opts, "size", ram_size, &error_abort);
*maxram_size = ram_size;
maxmem_str = qemu_opt_get(opts, "maxmem");
@@ -2763,6 +2767,9 @@ int main(int argc, char **argv, char **envp)
FILE *vmstate_dump_file = NULL;
Error *main_loop_err = NULL;
+ qemu_init_cpu_loop();
+ qemu_mutex_lock_iothread();
+
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
qemu_init_exec_dir(argv[0]);
@@ -2960,21 +2967,24 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
if (hda_opts != NULL) {
- char num[16];
- snprintf(num, sizeof(num), "%d", cyls);
- qemu_opt_set(hda_opts, "cyls", num);
- snprintf(num, sizeof(num), "%d", heads);
- qemu_opt_set(hda_opts, "heads", num);
- snprintf(num, sizeof(num), "%d", secs);
- qemu_opt_set(hda_opts, "secs", num);
+ qemu_opt_set_number(hda_opts, "cyls", cyls,
+ &error_abort);
+ qemu_opt_set_number(hda_opts, "heads", heads,
+ &error_abort);
+ qemu_opt_set_number(hda_opts, "secs", secs,
+ &error_abort);
if (translation == BIOS_ATA_TRANSLATION_LARGE) {
- qemu_opt_set(hda_opts, "trans", "large");
+ qemu_opt_set(hda_opts, "trans", "large",
+ &error_abort);
} else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
- qemu_opt_set(hda_opts, "trans", "rechs");
+ qemu_opt_set(hda_opts, "trans", "rechs",
+ &error_abort);
} else if (translation == BIOS_ATA_TRANSLATION_LBA) {
- qemu_opt_set(hda_opts, "trans", "lba");
+ qemu_opt_set(hda_opts, "trans", "lba",
+ &error_abort);
} else if (translation == BIOS_ATA_TRANSLATION_NONE) {
- qemu_opt_set(hda_opts, "trans", "none");
+ qemu_opt_set(hda_opts, "trans", "none",
+ &error_abort);
}
}
}
@@ -3012,16 +3022,20 @@ int main(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_kernel:
- qemu_opts_set(qemu_find_opts("machine"), 0, "kernel", optarg);
+ qemu_opts_set(qemu_find_opts("machine"), 0, "kernel", optarg,
+ &error_abort);
break;
case QEMU_OPTION_initrd:
- qemu_opts_set(qemu_find_opts("machine"), 0, "initrd", optarg);
+ qemu_opts_set(qemu_find_opts("machine"), 0, "initrd", optarg,
+ &error_abort);
break;
case QEMU_OPTION_append:
- qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg);
+ qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg,
+ &error_abort);
break;
case QEMU_OPTION_dtb:
- qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg);
+ qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg,
+ &error_abort);
break;
case QEMU_OPTION_cdrom:
drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
@@ -3125,7 +3139,8 @@ int main(int argc, char **argv, char **envp)
}
break;
case QEMU_OPTION_bios:
- qemu_opts_set(qemu_find_opts("machine"), 0, "firmware", optarg);
+ qemu_opts_set(qemu_find_opts("machine"), 0, "firmware", optarg,
+ &error_abort);
break;
case QEMU_OPTION_singlestep:
singlestep = 1;
@@ -3255,35 +3270,39 @@ int main(int argc, char **argv, char **envp)
writeout = qemu_opt_get(opts, "writeout");
if (writeout) {
#ifdef CONFIG_SYNC_FILE_RANGE
- qemu_opt_set(fsdev, "writeout", writeout);
+ qemu_opt_set(fsdev, "writeout", writeout, &error_abort);
#else
fprintf(stderr, "writeout=immediate not supported on "
"this platform\n");
exit(1);
#endif
}
- qemu_opt_set(fsdev, "fsdriver", qemu_opt_get(opts, "fsdriver"));
- qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"));
+ qemu_opt_set(fsdev, "fsdriver",
+ qemu_opt_get(opts, "fsdriver"), &error_abort);
+ qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"),
+ &error_abort);
qemu_opt_set(fsdev, "security_model",
- qemu_opt_get(opts, "security_model"));
+ qemu_opt_get(opts, "security_model"),
+ &error_abort);
socket = qemu_opt_get(opts, "socket");
if (socket) {
- qemu_opt_set(fsdev, "socket", socket);
+ qemu_opt_set(fsdev, "socket", socket, &error_abort);
}
sock_fd = qemu_opt_get(opts, "sock_fd");
if (sock_fd) {
- qemu_opt_set(fsdev, "sock_fd", sock_fd);
+ qemu_opt_set(fsdev, "sock_fd", sock_fd, &error_abort);
}
qemu_opt_set_bool(fsdev, "readonly",
- qemu_opt_get_bool(opts, "readonly", 0));
+ qemu_opt_get_bool(opts, "readonly", 0),
+ &error_abort);
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
- qemu_opt_set(device, "driver", "virtio-9p-pci");
+ qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
qemu_opt_set(device, "fsdev",
- qemu_opt_get(opts, "mount_tag"));
+ qemu_opt_get(opts, "mount_tag"), &error_abort);
qemu_opt_set(device, "mount_tag",
- qemu_opt_get(opts, "mount_tag"));
+ qemu_opt_get(opts, "mount_tag"), &error_abort);
break;
}
case QEMU_OPTION_virtfs_synth: {
@@ -3296,13 +3315,13 @@ int main(int argc, char **argv, char **envp)
fprintf(stderr, "duplicate option: %s\n", "virtfs_synth");
exit(1);
}
- qemu_opt_set(fsdev, "fsdriver", "synth");
+ qemu_opt_set(fsdev, "fsdriver", "synth", &error_abort);
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
- qemu_opt_set(device, "driver", "virtio-9p-pci");
- qemu_opt_set(device, "fsdev", "v_synth");
- qemu_opt_set(device, "mount_tag", "v_synth");
+ qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
+ qemu_opt_set(device, "fsdev", "v_synth", &error_abort);
+ qemu_opt_set(device, "mount_tag", "v_synth", &error_abort);
break;
}
case QEMU_OPTION_serial:
@@ -4086,9 +4105,6 @@ int main(int argc, char **argv, char **envp)
os_set_line_buffering();
- qemu_init_cpu_loop();
- qemu_mutex_lock_iothread();
-
#ifdef CONFIG_SPICE
/* spice needs the timers to be initialized by this point */
qemu_spice_init();