summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure48
-rw-r--r--device_tree.c27
-rw-r--r--exec.c13
-rw-r--r--fsdev/qemu-fsdev.c2
-rw-r--r--hw/9pfs/virtio-9p-device.c26
-rw-r--r--hw/arm/boot.c8
-rw-r--r--hw/i2c/pm_smbus.c25
-rw-r--r--hw/microblaze/boot.c27
-rw-r--r--hw/ppc/e500.c25
-rw-r--r--hw/ppc/spapr.c28
-rw-r--r--include/exec/cpu-all.h1
-rw-r--r--include/sysemu/sysemu.h2
-rw-r--r--kvm-all.c5
-rw-r--r--qemu-char.c13
-rw-r--r--qemu-options.hx8
-rw-r--r--qom/object.c6
-rw-r--r--target-i386/kvm.c17
-rw-r--r--util/qemu-option.c22
-rw-r--r--vl.c51
19 files changed, 176 insertions, 178 deletions
diff --git a/configure b/configure
index 0e0adde410..cb0f870b95 100755
--- a/configure
+++ b/configure
@@ -3445,6 +3445,36 @@ if test "$cpu" = "s390x" ; then
roms="$roms s390-ccw"
fi
+# Probe for the need for relocating the user-only binary.
+if test "$pie" = "no" ; then
+ textseg_addr=
+ case "$cpu" in
+ arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64)
+ textseg_addr=0x60000000
+ ;;
+ mips)
+ textseg_addr=0x400000
+ ;;
+ esac
+ if [ -n "$textseg_addr" ]; then
+ cat > $TMPC <<EOF
+ int main(void) { return 0; }
+EOF
+ textseg_ldflags="-Wl,-Ttext-segment=$textseg_addr"
+ if ! compile_prog "" "$textseg_ldflags"; then
+ # In case ld does not support -Ttext-segment, edit the default linker
+ # script via sed to set the .text start addr. This is needed on FreeBSD
+ # at least.
+ $ld --verbose | sed \
+ -e '1,/==================================================/d' \
+ -e '/==================================================/,$d' \
+ -e "s/[.] = [0-9a-fx]* [+] SIZEOF_HEADERS/. = $textseg_addr + SIZEOF_HEADERS/" \
+ -e "s/__executable_start = [0-9a-fx]*/__executable_start = $textseg_addr/" > config-host.ld
+ textseg_ldflags="-Wl,-T../config-host.ld"
+ fi
+ fi
+fi
+
# add pixman flags after all config tests are done
QEMU_CFLAGS="$QEMU_CFLAGS $pixman_cflags $fdt_cflags"
libs_softmmu="$libs_softmmu $pixman_libs"
@@ -4073,9 +4103,6 @@ if test "$gcov" = "yes" ; then
echo "GCOV=$gcov_tool" >> $config_host_mak
fi
-# generate list of library paths for linker script
-$ld --verbose -v 2> /dev/null | grep SEARCH_DIR > config-host.ld
-
# use included Linux headers
if test "$linux" = "yes" ; then
mkdir -p linux-headers
@@ -4438,21 +4465,8 @@ if test "$gprof" = "yes" ; then
fi
fi
-if test "$ARCH" = "tci"; then
- linker_script=""
-else
- linker_script="-Wl,-T../config-host.ld -Wl,-T,\$(SRC_PATH)/ldscripts/\$(ARCH).ld"
-fi
-
if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
- case "$ARCH" in
- alpha | s390x | aarch64)
- # The default placement of the application is fine.
- ;;
- *)
- ldflags="$linker_script $ldflags"
- ;;
- esac
+ ldflags="$ldflags $textseg_ldflags"
fi
echo "LDFLAGS+=$ldflags" >> $config_target_mak
diff --git a/device_tree.c b/device_tree.c
index 69be9da8e4..10cf3d0b60 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -21,6 +21,7 @@
#include "config.h"
#include "qemu-common.h"
#include "sysemu/device_tree.h"
+#include "sysemu/sysemu.h"
#include "hw/loader.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
@@ -239,15 +240,8 @@ uint32_t qemu_devtree_alloc_phandle(void *fdt)
* which phandle id to start allocting phandles.
*/
if (!phandle) {
- QemuOpts *machine_opts;
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- const char *phandle_start;
- phandle_start = qemu_opt_get(machine_opts, "phandle_start");
- if (phandle_start) {
- phandle = strtoul(phandle_start, NULL, 0);
- }
- }
+ phandle = qemu_opt_get_number(qemu_get_machine_opts(),
+ "phandle_start", 0);
}
if (!phandle) {
@@ -307,15 +301,10 @@ int qemu_devtree_add_subnode(void *fdt, const char *name)
void qemu_devtree_dumpdtb(void *fdt, int size)
{
- QemuOpts *machine_opts;
-
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- const char *dumpdtb = qemu_opt_get(machine_opts, "dumpdtb");
- if (dumpdtb) {
- /* Dump the dtb to a file and quit */
- exit(g_file_set_contents(dumpdtb, fdt, size, NULL) ? 0 : 1);
- }
- }
+ const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
+ if (dumpdtb) {
+ /* Dump the dtb to a file and quit */
+ exit(g_file_set_contents(dumpdtb, fdt, size, NULL) ? 0 : 1);
+ }
}
diff --git a/exec.c b/exec.c
index 03fdf7e730..e150935e72 100644
--- a/exec.c
+++ b/exec.c
@@ -31,6 +31,7 @@
#include "hw/qdev.h"
#include "qemu/osdep.h"
#include "sysemu/kvm.h"
+#include "sysemu/sysemu.h"
#include "hw/xen/xen.h"
#include "qemu/timer.h"
#include "qemu/config-file.h"
@@ -53,7 +54,6 @@
//#define DEBUG_SUBPAGE
#if !defined(CONFIG_USER_ONLY)
-int phys_ram_fd;
static int in_migration;
RAMList ram_list = { .blocks = QTAILQ_HEAD_INITIALIZER(ram_list.blocks) };
@@ -1044,12 +1044,10 @@ ram_addr_t last_ram_offset(void)
static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
{
int ret;
- QemuOpts *machine_opts;
/* Use MADV_DONTDUMP, if user doesn't want the guest memory in the core */
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts &&
- !qemu_opt_get_bool(machine_opts, "dump-guest-core", true)) {
+ if (!qemu_opt_get_bool(qemu_get_machine_opts(),
+ "dump-guest-core", true)) {
ret = qemu_madvise(addr, size, QEMU_MADV_DONTDUMP);
if (ret) {
perror("qemu_madvise");
@@ -1096,10 +1094,7 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
static int memory_try_enable_merging(void *addr, size_t len)
{
- QemuOpts *opts;
-
- opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (opts && !qemu_opt_get_bool(opts, "mem-merge", true)) {
+ if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
/* disabled by the user */
return 0;
}
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 6eaf36dbfa..ccfec139ab 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -76,6 +76,8 @@ int qemu_fsdev_add(QemuOpts *opts)
if (fsle->fse.ops->parse_opts) {
if (fsle->fse.ops->parse_opts(opts, &fsle->fse)) {
+ g_free(fsle->fse.fsdev_id);
+ g_free(fsle);
return -1;
}
}
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index dc6f4e404f..35e2af47b2 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -68,14 +68,14 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
"id = %s\n",
s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL");
- return -1;
+ goto out;
}
if (!s->fsconf.tag) {
/* we haven't specified a mount_tag */
fprintf(stderr, "fsdev with id %s needs mount_tag arguments\n",
s->fsconf.fsdev_id);
- return -1;
+ goto out;
}
s->ctx.export_flags = fse->export_flags;
@@ -85,10 +85,10 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
if (len > MAX_TAG_LEN - 1) {
fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
"maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1);
- return -1;
+ goto out;
}
- s->tag = strdup(s->fsconf.tag);
+ s->tag = g_strdup(s->fsconf.tag);
s->ctx.uid = -1;
s->ops = fse->ops;
@@ -99,11 +99,11 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
if (s->ops->init(&s->ctx) < 0) {
fprintf(stderr, "Virtio-9p Failed to initialize fs-driver with id:%s"
" and export path:%s\n", s->fsconf.fsdev_id, s->ctx.fs_root);
- return -1;
+ goto out;
}
if (v9fs_init_worker_threads() < 0) {
fprintf(stderr, "worker thread initialization failed\n");
- return -1;
+ goto out;
}
/*
@@ -115,18 +115,26 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
fprintf(stderr,
"error in converting name to path %s", strerror(errno));
- return -1;
+ goto out;
}
if (s->ops->lstat(&s->ctx, &path, &stat)) {
fprintf(stderr, "share path %s does not exist\n", fse->path);
- return -1;
+ goto out;
} else if (!S_ISDIR(stat.st_mode)) {
fprintf(stderr, "share path %s is not a directory\n", fse->path);
- return -1;
+ goto out;
}
v9fs_path_free(&path);
return 0;
+out:
+ g_free(s->ctx.fs_root);
+ g_free(s->tag);
+ virtio_cleanup(vdev);
+ v9fs_path_free(&path);
+
+ return -1;
+
}
/* virtio-9p device */
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 7c0090ff4e..3e8741e015 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -359,7 +359,6 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
uint64_t elf_entry;
hwaddr entry;
int big_endian;
- QemuOpts *machine_opts;
/* Load the kernel. */
if (!info->kernel_filename) {
@@ -367,12 +366,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
exit(1);
}
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- info->dtb_filename = qemu_opt_get(machine_opts, "dtb");
- } else {
- info->dtb_filename = NULL;
- }
+ info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
if (!info->secondary_cpu_reset_hook) {
info->secondary_cpu_reset_hook = default_reset_secondary;
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index 6df0fa916d..c98e447533 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -32,6 +32,18 @@
#define SMBHSTDAT1 0x06
#define SMBBLKDAT 0x07
+#define STS_HOST_BUSY (1)
+#define STS_INTR (1<<1)
+#define STS_DEV_ERR (1<<2)
+#define STS_BUS_ERR (1<<3)
+#define STS_FAILED (1<<4)
+#define STS_SMBALERT (1<<5)
+#define STS_INUSE_STS (1<<6)
+#define STS_BYTE_DONE (1<<7)
+/* Signs of successfully transaction end :
+* ByteDoneStatus = 1 (STS_BYTE_DONE) and INTR = 1 (STS_INTR )
+*/
+
//#define DEBUG
#ifdef DEBUG
@@ -50,9 +62,14 @@ static void smb_transaction(PMSMBus *s)
i2c_bus *bus = s->smbus;
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
+ /* Transaction isn't exec if STS_DEV_ERR bit set */
+ if ((s->smb_stat & STS_DEV_ERR) != 0) {
+ goto error;
+ }
switch(prot) {
case 0x0:
smbus_quick_command(bus, addr, read);
+ s->smb_stat |= STS_BYTE_DONE | STS_INTR;
break;
case 0x1:
if (read) {
@@ -60,6 +77,7 @@ static void smb_transaction(PMSMBus *s)
} else {
smbus_send_byte(bus, addr, cmd);
}
+ s->smb_stat |= STS_BYTE_DONE | STS_INTR;
break;
case 0x2:
if (read) {
@@ -67,6 +85,7 @@ static void smb_transaction(PMSMBus *s)
} else {
smbus_write_byte(bus, addr, cmd, s->smb_data0);
}
+ s->smb_stat |= STS_BYTE_DONE | STS_INTR;
break;
case 0x3:
if (read) {
@@ -77,6 +96,7 @@ static void smb_transaction(PMSMBus *s)
} else {
smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
}
+ s->smb_stat |= STS_BYTE_DONE | STS_INTR;
break;
case 0x5:
if (read) {
@@ -84,6 +104,7 @@ static void smb_transaction(PMSMBus *s)
} else {
smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
}
+ s->smb_stat |= STS_BYTE_DONE | STS_INTR;
break;
default:
goto error;
@@ -91,7 +112,7 @@ static void smb_transaction(PMSMBus *s)
return;
error:
- s->smb_stat |= 0x04;
+ s->smb_stat |= STS_DEV_ERR;
}
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
@@ -102,7 +123,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
SMBUS_DPRINTF("SMB writeb port=0x%04x val=0x%02x\n", addr, val);
switch(addr) {
case SMBHSTSTS:
- s->smb_stat = 0;
+ s->smb_stat = (~(val & 0xff)) & s->smb_stat;
s->smb_index = 0;
break;
case SMBHSTCNT:
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 3f1d70ef9b..5b057f7880 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -28,6 +28,7 @@
#include "qemu/config-file.h"
#include "qemu-common.h"
#include "sysemu/device_tree.h"
+#include "sysemu/sysemu.h"
#include "hw/loader.h"
#include "elf.h"
@@ -93,20 +94,18 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
void (*machine_cpu_reset)(MicroBlazeCPU *))
{
QemuOpts *machine_opts;
- const char *kernel_filename = NULL;
- const char *kernel_cmdline = NULL;
-
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- const char *dtb_arg;
- kernel_filename = qemu_opt_get(machine_opts, "kernel");
- kernel_cmdline = qemu_opt_get(machine_opts, "append");
- dtb_arg = qemu_opt_get(machine_opts, "dtb");
- if (dtb_arg) { /* Preference a -dtb argument */
- dtb_filename = dtb_arg;
- } else { /* default to pcbios dtb as passed by machine_init */
- dtb_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
- }
+ const char *kernel_filename;
+ const char *kernel_cmdline;
+ const char *dtb_arg;
+
+ machine_opts = qemu_get_machine_opts();
+ kernel_filename = qemu_opt_get(machine_opts, "kernel");
+ kernel_cmdline = qemu_opt_get(machine_opts, "append");
+ dtb_arg = qemu_opt_get(machine_opts, "dtb");
+ if (dtb_arg) { /* Preference a -dtb argument */
+ dtb_filename = dtb_arg;
+ } else { /* default to pcbios dtb as passed by machine_init */
+ dtb_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
}
boot_info.machine_cpu_reset = machine_cpu_reset;
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 69837a5fb8..ee7e49a959 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -137,7 +137,6 @@ static int ppce500_load_device_tree(CPUPPCState *env,
uint32_t clock_freq = 400000000;
uint32_t tb_freq = 400000000;
int i;
- const char *toplevel_compat = NULL; /* user override */
char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
char soc[128];
char mpic[128];
@@ -158,14 +157,9 @@ static int ppce500_load_device_tree(CPUPPCState *env,
0x0, 0xe1000000,
0x0, 0x10000,
};
- QemuOpts *machine_opts;
- const char *dtb_file = NULL;
-
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- dtb_file = qemu_opt_get(machine_opts, "dtb");
- toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible");
- }
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ const char *dtb_file = qemu_opt_get(machine_opts, "dtb");
+ const char *toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible");
if (dtb_file) {
char *filename;
@@ -528,7 +522,6 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
qemu_irq **irqs)
{
- QemuOptsList *list;
qemu_irq *mpic;
DeviceState *dev = NULL;
SysBusDevice *s;
@@ -537,15 +530,11 @@ static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
mpic = g_new(qemu_irq, 256);
if (kvm_enabled()) {
- bool irqchip_allowed = true, irqchip_required = false;
-
- list = qemu_find_opts("machine");
- if (!QTAILQ_EMPTY(&list->head)) {
- irqchip_allowed = qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
+ QemuOpts *machine_opts = qemu_get_machine_opts();
+ bool irqchip_allowed = qemu_opt_get_bool(machine_opts,
"kernel_irqchip", true);
- irqchip_required = qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
- "kernel_irqchip", false);
- }
+ bool irqchip_required = qemu_opt_get_bool(machine_opts,
+ "kernel_irqchip", false);
if (irqchip_allowed) {
dev = ppce500_init_mpic_kvm(params, irqs);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c040794081..226ae70ae3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -676,27 +676,19 @@ static void spapr_cpu_reset(void *opaque)
static void spapr_create_nvram(sPAPREnvironment *spapr)
{
- QemuOpts *machine_opts;
- DeviceState *dev;
+ DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
+ const char *drivename = qemu_opt_get(qemu_get_machine_opts(), "nvram");
- dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
+ if (drivename) {
+ BlockDriverState *bs;
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- const char *drivename;
-
- drivename = qemu_opt_get(machine_opts, "nvram");
- if (drivename) {
- BlockDriverState *bs;
-
- bs = bdrv_find(drivename);
- if (!bs) {
- fprintf(stderr, "No such block device \"%s\" for nvram\n",
- drivename);
- exit(1);
- }
- qdev_prop_set_drive_nofail(dev, "drive", bs);
+ bs = bdrv_find(drivename);
+ if (!bs) {
+ fprintf(stderr, "No such block device \"%s\" for nvram\n",
+ drivename);
+ exit(1);
}
+ qdev_prop_set_drive_nofail(dev, "drive", bs);
}
qdev_init_nofail(dev);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 35bdf858f2..e791c05c4d 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -447,7 +447,6 @@ hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
/* memory API */
-extern int phys_ram_fd;
extern ram_addr_t ram_size;
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 2fb71afa25..d85bdc0cac 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -185,6 +185,8 @@ char *get_boot_devices_list(size_t *size);
DeviceState *get_boot_device(uint32_t position);
+QemuOpts *qemu_get_machine_opts(void);
+
bool usb_enabled(bool default_usb);
extern QemuOptsList qemu_drive_opts;
diff --git a/kvm-all.c b/kvm-all.c
index de658de98f..a5cd3d3340 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1288,12 +1288,9 @@ int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
static int kvm_irqchip_create(KVMState *s)
{
- QemuOptsList *list = qemu_find_opts("machine");
int ret;
- if (QTAILQ_EMPTY(&list->head) ||
- !qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
- "kernel_irqchip", true) ||
+ if (!qemu_opt_get_bool(qemu_get_machine_opts(), "kernel_irqchip", true) ||
!kvm_check_extension(s, KVM_CAP_IRQCHIP)) {
return 0;
}
diff --git a/qemu-char.c b/qemu-char.c
index 6cec5d7114..18c42a39da 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -926,7 +926,6 @@ static void qemu_chr_set_echo_stdio(CharDriverState *chr, bool echo)
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
}
- /* if graphical mode, we allow Ctrl-C handling */
if (!stdio_allow_signal)
tty.c_lflag &= ~ISIG;
@@ -955,7 +954,6 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts)
chr = qemu_chr_open_fd(0, 1);
chr->chr_close = qemu_chr_close_stdio;
chr->chr_set_echo = qemu_chr_set_echo_stdio;
- stdio_allow_signal = display_type != DT_NOGRAPHIC;
if (opts->has_signal) {
stdio_allow_signal = opts->signal;
}
@@ -2932,6 +2930,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");
+ 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");
+ }
}
if (strcmp(filename, "null") == 0 ||
@@ -3060,8 +3066,7 @@ static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
{
backend->stdio = g_new0(ChardevStdio, 1);
backend->stdio->has_signal = true;
- backend->stdio->signal =
- qemu_opt_get_bool(opts, "signal", display_type != DT_NOGRAPHIC);
+ backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true);
}
static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
diff --git a/qemu-options.hx b/qemu-options.hx
index 137a39b7ad..7cc4d8ef25 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -842,7 +842,8 @@ STEXI
Normally, QEMU uses SDL to display the VGA output. With this option,
you can totally disable graphical output so that QEMU is a simple
command line application. The emulated serial port is redirected on
-the console. Therefore, you can still use QEMU to debug a Linux kernel
+the console and muxed with the monitor (unless redirected elsewhere
+explicitly). Therefore, you can still use QEMU to debug a Linux kernel
with a serial console.
ETEXI
@@ -2485,14 +2486,15 @@ same as if you had specified @code{-serial tcp} except the unix domain socket
@item mon:@var{dev_string}
This is a special option to allow the monitor to be multiplexed onto
another serial port. The monitor is accessed with key sequence of
-@key{Control-a} and then pressing @key{c}. See monitor access
-@ref{pcsys_keys} in the -nographic section for more keys.
+@key{Control-a} and then pressing @key{c}.
@var{dev_string} should be any one of the serial devices specified
above. An example to multiplex the monitor onto a telnet server
listening on port 4444 would be:
@table @code
@item -serial mon:telnet::4444,server,nowait
@end table
+When monitor is multiplexed to stdio this way, Ctrl+C will not terminate
+QEMU anymore but will be passed to the guest instead.
@item braille
Braille device. This will use BrlAPI to display the braille output on a real
diff --git a/qom/object.c b/qom/object.c
index cbd7e86033..b2479d1c06 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -531,14 +531,14 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
#ifdef CONFIG_QOM_CAST_DEBUG
int i;
- for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) {
+ for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
if (class->cast_cache[i] == typename) {
ret = class;
goto out;
}
}
#else
- if (!class->interfaces) {
+ if (!class || !class->interfaces) {
return class;
}
#endif
@@ -551,7 +551,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
}
#ifdef CONFIG_QOM_CAST_DEBUG
- if (ret == class) {
+ if (class && ret == class) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
class->cast_cache[i - 1] = class->cast_cache[i];
}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 4b557b3a38..15da3d7baf 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -741,7 +741,6 @@ static int kvm_get_supported_msrs(KVMState *s)
int kvm_arch_init(KVMState *s)
{
- QemuOptsList *list = qemu_find_opts("machine");
uint64_t identity_base = 0xfffbc000;
uint64_t shadow_mem;
int ret;
@@ -790,15 +789,13 @@ int kvm_arch_init(KVMState *s)
}
qemu_register_reset(kvm_unpoison_all, NULL);
- if (!QTAILQ_EMPTY(&list->head)) {
- shadow_mem = qemu_opt_get_size(QTAILQ_FIRST(&list->head),
- "kvm_shadow_mem", -1);
- if (shadow_mem != -1) {
- shadow_mem /= 4096;
- ret = kvm_vm_ioctl(s, KVM_SET_NR_MMU_PAGES, shadow_mem);
- if (ret < 0) {
- return ret;
- }
+ shadow_mem = qemu_opt_get_size(qemu_get_machine_opts(),
+ "kvm_shadow_mem", -1);
+ if (shadow_mem != -1) {
+ shadow_mem /= 4096;
+ ret = kvm_vm_ioctl(s, KVM_SET_NR_MMU_PAGES, shadow_mem);
+ if (ret < 0) {
+ return ret;
}
}
return 0;
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 412c425518..e0ef426daa 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -706,16 +706,12 @@ QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
QemuOpts *opts;
QTAILQ_FOREACH(opts, &list->head, next) {
- if (!opts->id) {
- if (!id) {
- return opts;
- }
- continue;
+ if (!opts->id && !id) {
+ return opts;
}
- if (strcmp(opts->id, id) != 0) {
- continue;
+ if (opts->id && id && !strcmp(opts->id, id)) {
+ return opts;
}
- return opts;
}
return NULL;
}
@@ -918,15 +914,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
get_opt_value(value, sizeof(value), p+4);
id = value;
}
- if (defaults) {
- if (!id && !QTAILQ_EMPTY(&list->head)) {
- opts = qemu_opts_find(list, NULL);
- } else {
- opts = qemu_opts_create(list, id, 0, &local_err);
- }
- } else {
- opts = qemu_opts_create(list, id, 1, &local_err);
- }
+ opts = qemu_opts_create(list, id, !defaults, &local_err);
if (opts == NULL) {
if (error_is_set(&local_err)) {
qerror_report_err(local_err);
diff --git a/vl.c b/vl.c
index 6d9fd7d807..bea1a10cc6 100644
--- a/vl.c
+++ b/vl.c
@@ -409,7 +409,7 @@ static QemuOptsList qemu_machine_opts = {
.help = "Dump current dtb to a file and quit",
}, {
.name = "phandle_start",
- .type = QEMU_OPT_STRING,
+ .type = QEMU_OPT_NUMBER,
.help = "The first phandle ID we may generate dynamically",
}, {
.name = "dt_compatible",
@@ -516,6 +516,25 @@ static QemuOptsList qemu_realtime_opts = {
},
};
+/**
+ * Get machine options
+ *
+ * Returns: machine options (never null).
+ */
+QemuOpts *qemu_get_machine_opts(void)
+{
+ QemuOptsList *list;
+ QemuOpts *opts;
+
+ list = qemu_find_opts("machine");
+ assert(list);
+ opts = qemu_opts_find(list, NULL);
+ if (!opts) {
+ opts = qemu_opts_create_nofail(list);
+ }
+ return opts;
+}
+
const char *qemu_get_vm_name(void)
{
return qemu_name;
@@ -1017,15 +1036,9 @@ static int parse_sandbox(QemuOpts *opts, void *opaque)
return 0;
}
-/*********QEMU USB setting******/
bool usb_enabled(bool default_usb)
{
- QemuOpts *mach_opts;
- mach_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (mach_opts) {
- return qemu_opt_get_bool(mach_opts, "usb", default_usb);
- }
- return default_usb;
+ return qemu_opt_get_bool(qemu_get_machine_opts(), "usb", default_usb);
}
#ifndef _WIN32
@@ -2672,17 +2685,13 @@ static struct {
static int configure_accelerator(void)
{
- const char *p = NULL;
+ const char *p;
char buf[10];
int i, ret;
bool accel_initialised = false;
bool init_failed = false;
- QemuOptsList *list = qemu_find_opts("machine");
- if (!QTAILQ_EMPTY(&list->head)) {
- p = qemu_opt_get(QTAILQ_FIRST(&list->head), "accel");
- }
-
+ p = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (p == NULL) {
/* Use the default "accelerator", tcg */
p = "tcg";
@@ -4080,14 +4089,10 @@ int main(int argc, char **argv, char **envp)
qtest_init();
}
- machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
- if (machine_opts) {
- kernel_filename = qemu_opt_get(machine_opts, "kernel");
- initrd_filename = qemu_opt_get(machine_opts, "initrd");
- kernel_cmdline = qemu_opt_get(machine_opts, "append");
- } else {
- kernel_filename = initrd_filename = kernel_cmdline = NULL;
- }
+ machine_opts = qemu_get_machine_opts();
+ kernel_filename = qemu_opt_get(machine_opts, "kernel");
+ initrd_filename = qemu_opt_get(machine_opts, "initrd");
+ kernel_cmdline = qemu_opt_get(machine_opts, "append");
if (!boot_order) {
boot_order = machine->boot_order;
@@ -4130,7 +4135,7 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
- if (!linux_boot && machine_opts && qemu_opt_get(machine_opts, "dtb")) {
+ if (!linux_boot && qemu_opt_get(machine_opts, "dtb")) {
fprintf(stderr, "-dtb only allowed with -kernel option\n");
exit(1);
}